home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- # A lastlog record format for use by pack and unpack.
-
- $lastlog_t = "L a8 a16"; # (Your machine's may differ.)
-
- # Find the length of the fixed-length record.
-
- $LEN = length(pack($lastlog_t, 0, '', ''));
-
- # Open the database of last logins. Fixed length records.
-
- open(LASTLOG, "/usr/adm/lastlog")
- || die "Can't open lastlog file: $!\n";
-
- # Open the database of accounts. Variable length records.
-
- open(PASSWD, "/etc/passwd")
- || die "Can't open passwd file: $!\n";
-
- # So we can look up month names later.
-
- @month = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
-
- # Now we iterate through variable length records by using
- # the <> input symbol. In this particular database, the
- # delimiter just happens to be \n. How lucky can you get?
-
- while ($varrec = <PASSWD>) {
-
- # And the field delimiter happens to be a colon. Amazing!
-
- ($login, $pass, $uid, $gid, $gcos) = split(/:/, $varrec);
-
- # Extract name from gcos field portably.
-
- $fullname = $gcos;
- $fullname =~ s/^[^,]*-(.*)\(.*/$1/ || $fullname =~ s/,.*//;
- if ($fullname =~ /&/) { # You don't want to know.
- $name = $login;
- substr($name,0,1) =~ tr/a-z/A-Z/;
- $fullname =~ s/&/$name/;
- }
-
- # Now we random access the lastlog database. It's keyed
- # by position based on the user id we want to look up.
- # Note that we multiply by the record length, since Unix
- # always wants byte offsets.
-
- seek(LASTLOG, $uid * $LEN, 0);
- read(LASTLOG, $lastlog, $LEN);
-
- # Now that we've fetched the lastlog record, we can
- # break it out into its fields. Note that variable-
- # length fields above are separated with the split
- # operator, while these fixed-length fields are separated
- # using unpack.
-
- ($time, $line, $host) = unpack($lastlog_t, $lastlog);
-
- # Now remember it so we can sort easily.
-
- push(@records, "$time:$login:$uid:$fullname");
- }
-
- # Now sort the records, oldest first. See the
- # "numerically" subroutine below.
-
- @records = sort numerically @records;
-
- foreach $record (@records) {
- ($time,$login,$uid,$fullname) = split(/:/, $record);
-
- # Break out the login time, stored as seconds since
- # January 1, 1970, into normal date numbers.
-
- if ($time) {
- ($sec,$min,$hour,$mday,$mon,$year) = localtime($time);
- $year += 1900;
- $date = "$mday $month[$mon] $year";
- }
- else {
- $date = "Never";
- }
-
- # Write using the format below.
-
- write;
- }
-
- sub numerically { $a <=> $b; }
-
- format top =
- Uid Login Full Name Last Login
-
- .
-
- format STDOUT =
- @>>>> @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @||||||||||
- $uid, $login, $fullname, $date
- .
-