Article 9947 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:9947
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!uknet!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!transfer.stratus.com!noc.near.net!newshost.meiko.com!not-for-mail
From:
[email protected] (Mike Stok)
Newsgroups: comp.lang.perl
Subject: Re: analyzing /var/adm/lastlog
Date: 19 Jan 1994 16:26:49 -0500
Organization: Meiko Scientific, Inc., MA
Lines: 61
Message-ID: <
[email protected]>
References: <
[email protected]>
NNTP-Posting-Host: burns.meiko.com
Keywords: lastlog, reading with Perl
In article <
[email protected]>,
Nico Poppelier <
[email protected]> wrote:
>How do you analyze /var/adm/lastlog -- lastlog is the file
>that keeps track of the most recent login of every user on
>a Unix system, and /var/adm is where this file is stored
>in SunOS 4.1.x operating systems -- with a Perl program?
>
>I know that you need to an lseek using an offset that is
>related to the uid of a user, and that every record in the
>file consists of {long, char[8], char[16]}, so I've tried to
>accomplish this with seek and read, but without success.
>
>Has anyone already done this or can anyone provide pointers?
You can use seek & read to position the file & read a buffer of data, and
then unpack to unpack the data into perl variables...
This runs through the lastlog file on my Sun 4 running SunOS 4.1.3 OK:
#!/usr/bin/perl -w
require 'ctime.pl';
$utSize = 28;
$utTemplate = 'l A8 A16';
$utBuffer = ' ' x $utSize;
$uid = 0;
open (LASTLOG, '</var/adm/lastlog') || die "can't open lastlog ($!)\n";
while (sysread (LASTLOG, $utBuffer, $utSize) == $utSize)
{
($time, $line, $host) = unpack ($utTemplate, $utBuffer);
if ($time != 0)
{
$user = (getpwuid ($uid))[0];
print "$user on $line ";
print $host eq '' ? "(local)" : "from $host";
print " at ", &ctime ($time);
}
$uid++;
}
close (LASTLOG) || die "can't close lastlog ($!)\n";
I prefer sysread to read, but it doesn't make any difference which you
use here (but syswrite and write are different...). If you had a
particular uid then you can just do something like:
seek (LASTLOG, $uid * $utSize, 0) || die "seek failed ($!)\n";
read (LASTLOG, $utBuffer, $utSize) == $utSize || die "bad read\n";
($time, $line, $host) = unpack ($utTemplate, $utBuffer);
Hope this helps,
Mike
--
The "usual disclaimers" apply. | Meiko
Mike Stok | 130C Baker Ave. Ext
[email protected] | Concord, MA 01742
Meiko tel: (617) 890 7676 |
Article 9950 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:9950
Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!pipex!uunet!vtserf.cc.vt.edu!solaris.cc.vt.edu!ceharris
From:
[email protected] (Carl Harris)
Newsgroups: comp.lang.perl
Subject: Re: analyzing /var/adm/lastlog
Date: 19 Jan 1994 22:18:37 GMT
Organization: VPI & SU (Virginia Tech)
Lines: 20
Message-ID: <
[email protected]>
References: <
[email protected]>
Reply-To:
[email protected]
NNTP-Posting-Host: mal9000.async.vt.edu
X-Newsreader: TIN [version 1.2 PL2]
Nico Poppelier (
[email protected]) wrote:
: I know that you need to an lseek using an offset that is
: related to the uid of a user, and that every record in the
: file consists of {long, char[8], char[16]}, so I've tried to
: accomplish this with seek and read, but without success.
If you're getting garbage when you unpack from the reads, it likely means
that you've got alignment problems. i.e. there may be padding bytes in-
between fields to force a particular alignment, so that a given field in the
record doesn't necessarily follow at the next physical offset following a
preceding field. Scan the file carefully using a hexadecimal/character dump
can usually give you clues as to the physical layout of the fields.
I had this same problem trying to read the auth database in Ultrix.
--
Carl Harris
CSUGRAD Administrator
[email protected]
URL =
http://csugrad.cs.vt.edu/aboutus/ceharris.html
Article 9979 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:9979
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!pipex!howland.reston.ans.net!vixen.cso.uiuc.edu!moe.ksu.ksu.edu!cbs.ksu.ksu.edu!news
From: Steve Davis <
[email protected]>
Newsgroups: comp.lang.perl
Subject: Re: analyzing /var/adm/lastlog
Date: 20 Jan 1994 11:55:15 -0600
Organization: Kansas State University
Lines: 52
Sender:
[email protected] (Steve Davis)
Message-ID: <
[email protected]>
References: <
[email protected]>
Reply-To:
[email protected] (Steve Davis)
NNTP-Posting-Host: cbs.ksu.ksu.edu
Keywords: lastlog, reading with Perl
[email protected] writes:
:How do you analyze /var/adm/lastlog -- lastlog is the file
:that keeps track of the most recent login of every user on
:a Unix system, and /var/adm is where this file is stored
:in SunOS 4.1.x operating systems -- with a Perl program?
This code was posted recently:
#!/usr/local/bin/perl
# month names for common usage
@months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
'Sep', 'Oct', 'Nov', 'Dec');
$oneyear = 60*60*24*365.24/2;
setpwent;
while (($name, $junk, $uid) = getpwent) {
$names{$uid} = $name;
}
endpwent;
open(LASTL,'/var/adm/lastlog');
for ($uid = 0; read(LASTL, $record, 28); $uid++) {
($time, $line, $host) = unpack('l A8 A16', $record);
next unless $time;
$host = "($host)" if $host;
($sec, $min, $hour, $mday, $mon, $year) = localtime($time);
if (time - $time > $oneyear) {
printf "%-9s%-8s%s %2d %4d %s\n",
$names{$uid}, $line, $months[$mon], $mday, 1900+$year, $host;
} else {
printf "%-9s%-8s%s %2d %02d:%02d %s\n",
$names{$uid}, $line, $months[$mon], $mday, $hour, $min, $host;
}
}
:I know that you need to an lseek using an offset that is
:related to the uid of a user, and that every record in the
:file consists of {long, char[8], char[16]}, so I've tried to
:accomplish this with seek and read, but without success.
Sounds like an alignment problem. Good luck!
--
Steve Davis (
[email protected])
Kansas State University
"What is truth? I don't know and I'm sorry I brought it up." -- Edward Abbey