I asked:
< Can someone point me to or provide me with a procedure (Perl, C, I
< don't care what) to dump the /var/adm/lastlog file in some
< formatted way?
Sean Watson <swatson_at_ultrix6.cs.csubak.edu>, provided me with
a small C program that does exactly what I needed. It's reposted
below with his kind permission.
Thanks also to:
Peter Clark <pclark_at_p90.pclark.com
"Robert B. Reinhardt" <breinhar_at_access.digex.net>
Paul A Sand <pas_at_keokuk.unh.edu>
Ian Piumarta <piumarta_at_prof.inria.fr>
"Anthony D'Atri" <aad_at_nwnet.net>
Winfried Huber <win_at_tukan.ffb.eunet.de>
Benoit Maillard - Digital France-<maillard_at_atyisa.enet.dec.com>0
Note: A number of replies suggested that I use "last". last does
not dump lastlog, it dumps wtmp, which is only the last day's data.
- Saul
Sean Watson's comments and code:
I wrote a sample program in C. I cut a bunch of stuff out that has
nothing to do with lastlog (so you can see how lastlog works and not be
bothered with quota files utmp/wtmp, etc). First a few comments are in
order
because even though the program is obvious to me, it may not be to someone
else (since I wrote it quickly and didn't comment it a whole lot).
There is a file /usr/include/lastlog.h which has a definition for
a struct that include:
time_t ll_time
char ll_line[8]
char ll_host[16]
There's no telling what other "useful" stuff people may have put in lastlog
so
you should just include the header file and hope they didn't take out what
you need. (Both Ultrix and Linux have just those three things, and I
haven't
tried it elsewhere but you never know ....)
The offset of a particular user's lastlog entry is at that users UID
times the size of a lastlog struct. (It is a unix sparse file.... if you
start your UID at 10000, you're still OK because bytes between the last
system lastlog entry and the first user aren't allocated on the disk.)
Whenever a user logs in, "login" writes an entry to lastlog (if it
exists), so records for users who don't exist or haven't logged in will
have lastlog records that are all 0's (you can usually just check to see if
the time is zero unless you have something else that writes to garbage to
lastlog or someone actually last logged in at the epoch (midnight 1/1/1970
GMT)
-- long before Digital UNIX or OSF/1 or your computer existed :).
Ok, now for the sample code. The attached program will show the tty
name, the host (if it was a telnet or rlogin, etc), and the time of the
last
login of a list of users given on the command line. If a number is given,
it is taken to be a user id. If no arguments are given, the program
dumps that information for all users in /etc/passwd.
#include <stdio.h>
#include <pwd.h>
#include <lastlog.h>
/*
* The format of /var/adm/lastlog is a bunch of fixed length records
* with "struct lastlog" written for each uid.
*/
struct lastlog *get_lastlog(lastfile, uid, ll)
FILE *lastfile;
uid_t uid;
struct lastlog *ll;
{
fseek(lastfile, uid*sizeof(struct lastlog), SEEK_SET);
fread(ll, sizeof(struct lastlog), 1, lastfile);
if (ll->ll_time == 0)
return(NULL);
return(ll);
}
void dumplastlog(p, lastlog)
struct passwd *p;
FILE *lastlog;
{
struct lastlog l[1];
printf("%16.16s: ", p->pw_name);
if (get_lastlog(lastlog, p->pw_uid, l) == NULL)
printf("never logged in\n");
else
printf("%*.*s %*.*s %s",
sizeof(l->ll_line), sizeof(l->ll_line), l->ll_line,
sizeof(l->ll_host), sizeof(l->ll_host), l->ll_host,
ctime(&(l->ll_time)));
}
void main(argc, argv)
int argc;
char *argv[];
{
FILE *lastlog;
struct passwd *p;
lastlog = fopen("/var/adm/lastlog", "r");
if (lastlog == NULL)
{
perror("Could not open /var/adm/lastlog");
exit(1);
}
if (argc == 1)
{
setpwent();
for (p = getpwent(); p != NULL; p = getpwent())
dumplastlog(p, lastlog);
}
else
for (argv ++; *argv != NULL; argv ++)
{
p = NULL;
if (isdigit(**argv))
p = getpwuid(atoi(*argv));
if (p == NULL)
p = getpwnam(*argv);
if (p == NULL)
fprintf(stderr, "%s is not in /etc/passwd file\n", *argv);
else
dumplastlog(p, lastlog);
}
endpwent();
fclose(lastlog);
exit(0);
}
--
Saul Tannenbaum, Manager, Academic Systems | "It's still rocket
stannenb_at_emerald.tufts.edu | science" - Vint Cerf
Tufts University Computing and |
Communications Services |http://www.tufts.edu/~stannenb
Received on Wed Dec 20 1995 - 23:43:13 NZDT