Hi Monks,

I am trying to understand lastlogin.pl (a sample code from book Unix Programming - Programming Perl).
This sample code is working fine in my linux SuSe (after i changed $lastlog_t = "L a8 a256" to $lastlog_t="L a32 a256", and i know this after i did the super search at perlmonks and found this View last login times of everyone on your system).

So i have a conclusion that each record (fixed length records database) in /usr/var/lastlog has a "fixed" length, and the length of each record is 292 bytes

$lastlog_t = "L a32 a256"; #(your machine maybe differ); $LEN = length(pack($lastlog_t,0, '', '')); print "length = $LEN \n";

Then, in my shell i did 'ls -l /var/log/lastlog', and i see that the size of lastlog is 146292 bytes.

So the sum of all records = 146292 / 292 = 501 records .

i am not sure about this, because when i ran lastlogin.pl there are only 16 UIDs.

i am curious, i used a sample script like this :

setpwent(); while(@list = getpwent()) { ($login,$home) = @list[0,7]; print "home directory for $login is $home \n"; } endpwent();
and still only display 16 records.

And now im confused, my /var/log/lastlog's size should be 4672 bytes not 146292 bytes !
or did i miss something ? (btw i am really new to this linux world)
Do you have any clues ?

You can see lastlogin.pl in Persib's scratchpad

Update : here's the lastlogin.pl

#!/usr/bin/perl $lastlog_t = "L a32 a256"; #(your machine maybe differ); $LEN = length(pack($lastlog_t,0, '', '')); open(LASTLOG,'/var/log/lastlog') || die "can't open lastlog file: $! \ +n"; open(PASSWD,'/etc/passwd') || die "can't open passwd file: $! \n"; @month=(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec); while($varrec = <PASSWD>) { ($login,$pass,$uid,$gid,$gcos) = split(/:/,$varrec); $fullname = $gcos; # $fullname = ~ s/^[^,]*--(.*)\(.*/$1/ || $fullname =~ s/,.*//; #try to uncomment code line above, cuz i got weird result if ($fullname =~ /&/) { #u dont want to know $name = $login; substr($name,0,1) = ~ tr/a-z/A-Z/; $fullname = ~ s/&/$name/; } seek(LASTLOG,$uid * $LEN, 0); read(LASTLOG,$lastlog,$LEN); ($time,$line,$host) = unpack($lastlog_t,$lastlog); push(@records, "$time:$login:$uid:$fullname"); } @records = sort numerically @records; foreach $record(@records) { ($time,$login,$uid,$fullname) = split(/:/,$record); if ($time) { ($sec,$min,$hour,$mday,$mon,$year) = localtime($time); $year +=1900; $date = "$mday $month[$mon] $year"; } else { $date = "never"; } write; } sub numerically {$a <=> $b; } format top = Uid Login Full Name Last Login . format STDOUT = @>>>>> @<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @|||||||||||| $uid $login $fullname $date

thanks, and sorry for my english


In reply to Fixed length record and lastlog's size by Persib

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.