#!/usr/bin/perl
use
POSIX
qw(:termios_h)
;
local
$main::Timeout
= 15;
my
$Password
= 0;
for
(
my
$i
= 0 ;
$i
<=
$#ARGV
; ++
$i
)
{
if
(
$ARGV
[
$i
] eq
"-n"
)
{
$main::Timeout
= 0;
}
elsif
(
$ARGV
[
$i
] eq
"-p"
)
{
$Password
= 1;
}
elsif
(
$ARGV
[
$i
] eq
"-t"
)
{
my
$j
=
$i
;
++
$i
;
if
(
$i
>
$#ARGV
)
{
print
STDERR
"lock: option requires an argument -- $ARGV[$j]\n"
;
usage();
}
elsif
(
$ARGV
[
$i
] !~ /^[1-9]\d*$/ )
{
print
STDERR
"lock: illegal timeout value\n"
;
usage();
}
$main::Timeout
=
$ARGV
[
$i
];
}
else
{
print
STDERR
"lock: illegal option -- $ARGV[$i]\n"
;
usage();
}
}
local
$main::fd_stdin
=
fileno
(STDIN);
local
$main::term
= POSIX::Termios->new;
$main::term
->getattr(
$main::fd_stdin
);
local
$main::oterm
=
$main::term
->getlflag();
local
$main::echo
=
&POSIX::ECHO
;
local
$main::noecho
=
$main::oterm
& ~
$main::echo
;
$| = 1;
my
$key
;
my
$again
;
if
(
$Password
)
{
$key
= (
getpwuid
($<))[1];
}
else
{
print
"Key: "
;
noecho();
$key
= <STDIN>;
echo();
print
"\n"
;
chomp
$key
;
print
"Again: "
;
noecho();
$again
= <STDIN>;
echo();
print
"\n"
;
chomp
$again
;
if
(
$key
ne
$again
)
{
print
"lock: passwords didn't match.\n"
;
exit
1;
}
}
my
$Tty
= tty();
my
$Host
= hostname();
my
$Date
=
localtime
(
time
);
print
"lock: $Tty on $Host. "
;
if
(
$main::Timeout
> 0 )
{
print
"timeout in $main::Timeout minutes\n"
;
}
else
{
print
"no timeout\n"
;
}
print
"time is now $Date"
;
foreach
my
$sig
(
keys
(
%SIG
) )
{
$SIG
{
$sig
} =
'handler'
;
}
if
(
$main::Timeout
> 0 )
{
alarm
( 60
*$main::Timeout
);
}
noecho();
do
{
print
"\nKey: "
;
$again
= <STDIN>;
chomp
$again
;
$again
= code(
$again
)
if
(
$Password
);
}
while
( !
defined
(
$again
) or (
$key
ne
$again
) );
echo();
print
"\n"
;
sub
noecho
{
$main::term
->setlflag(
$main::noecho
);
$main::term
->setattr(
$main::fd_stdin
, TCSANOW);
}
sub
echo
{
$main::term
->setlflag(
$main::oterm
);
$main::term
->setattr(
$main::fd_stdin
, TCSANOW);
}
sub
usage
{
print
STDERR
"usage: lock [-n] [-p] [-t timeout]\n"
;
exit
1;
}
sub
code
{
my
$word
=
shift
;
my
$pwd
= (
getpwuid
($<))[1];
my
$salt
=
substr
(
$pwd
,0,2);
return
crypt
(
$word
,
$salt
);
}
sub
handler
{
my
$sig
=
shift
;
if
(
$sig
eq
'ALRM'
)
{
print
"lock: timeout\n"
;
exit
0;
}
else
{
print
"lock: type in the unlock key."
;
if
(
$main::Timeout
> 0 )
{
my
$timeleft
=
alarm
(0);
my
$minleft
=
int
(
$timeleft
/60);
my
$secleft
=
$timeleft
%60;
printf
" timeout in %d:%s%d minutes"
,
$minleft
,
$secleft
< 10 ?
"0"
:
""
,
$secleft
;
alarm
(
$timeleft
);
}
print
"\n"
;
}
}
sub
tty
{
""
;
}