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: mike@meiko.com (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: <2hk8ip$qb@burns.meiko.com> References: <1994Jan19.143326.11913@elsevier.nl> NNTP-Posting-Host: burns.meiko.com Keywords: lastlog, reading with Perl In article <1994Jan19.143326.11913@elsevier.nl>, Nico Poppelier 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, ' References: <1994Jan19.143326.11913@elsevier.nl> Reply-To: ceharris@vt.edu NNTP-Posting-Host: mal9000.async.vt.edu X-Newsreader: TIN [version 1.2 PL2] Nico Poppelier (nico@elsevier.nl) 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 ceharris@vt.edu 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 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: strat@cbs.ksu.ksu.edu (Steve Davis) Message-ID: <2hmgi3INN1c1@cbs.ksu.ksu.edu> References: <1994Jan19.143326.11913@elsevier.nl> Reply-To: strat@cis.ksu.edu (Steve Davis) NNTP-Posting-Host: cbs.ksu.ksu.edu Keywords: lastlog, reading with Perl n.poppelier@elsevier.nl 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 (strat@cis.ksu.edu) Kansas State University "What is truth? I don't know and I'm sorry I brought it up." -- Edward Abbey