#!/usr/bin/perl open (LASTLOG, "< /usr/adm/lastlog") || die "can't open /usr/adm/lastlog: $!"; $lastlog_t = 'L A8 A16'; $lastlog_s = length(pack($lastlog_t, ())); # struct lastlog { # time_t ll_time; # char ll_line[8]; # char ll_host[16]; /* same as in utmp */ # }; if (!@ARGV) { for ( $uid = 0; sysread(LASTLOG, $buff, $lastlog_s) == $lastlog_s; $uid++ ) { next unless @p = getpwuid($uid); ($time, $line, $host) = unpack($lastlog_t, $buff); $uid = $p[2]; $user = $p[0]; $uid{$user} = $uid; ### print STDERR "read $user\n"; $time{$user} = $time || 0; $line{$user} = $line || ''; $host{$user} = $host || ''; } for $user ( sort { $time{$a} <=> $time{$b} || $uid{$a} <=> $uid{$b} } keys %time ) { $uid = $uid{$user}; $time = $time{$user}; $line = $line{$user}; $host = $host{$user}; write; } } USER: foreach $user ( @ARGV ) { if ($user =~ /^\d+$/) { unless (@p = getpwuid($user)) { warn "no such uid $user\n"; next; } $user = $p[0]; $uid = $p[2]; } elsif (!defined ($uid = getpwnam($user))) { warn "no user $user\n"; next; } seek(LASTLOG, $uid * $lastlog_s, 0) or die "seek failed: $!"; ($time, $line, $host) = sysread(LASTLOG, $buff, $lastlog_s) == $lastlog_s ? unpack($lastlog_t, $buff) : (); write; } format STDOUT_TOP = @<<<<<<< @>>>>> @<<<<<<< @<<<<<<<<<<<<<<<<<< @* 'user', 'uid', 'line', 'host', 'when' -------- ------ -------- ------------------- ----------------------- . format STDOUT = @<<<<<<< @>>>>> @<<<<<<< @<<<<<<<<<<<<<<<<<< @* $user, $uid, $line, $host, $time ? scalar localtime $time : "[ never logged in ]" .