12-17-04 12:45 AM
In article <32darnF3jtj8rU1@individual.net>,
"Tom Brehony" <tombrehony.nospam@eircom.nospam.net> wrote:
> The subject lines says it all. I am looking for a script (ideally Korn
> Shell)
> to extract from /etc/security/lastlog a list of users and their last login
> time
> in human readable format.
>
> I have seen PERL scripts to convert the Unix time in seconds to a human
> readable form, but I do not have PERL installed on the AIX 4.2 box
> I am using and I am not familiar with PERL anyway and would not be
> able to modify the script to do what I need.
>
> Anyone have something that will do this?
>
> Tom.
Is the format of lastlog documented in a manpage? You could write perl
or c code to read the file and extract this information. Some kind soul
posted this, which I saved.
/ ****************************************
****************************
* lastlog.c: look up /var/adm/lastlog entries by name or uid *
* *
* Usage: *
* lastlog name_or_uid ... *
* *
* Return codes: *
* 0: ok *
* 1: usage *
* 2: fopen() of /var/adm/lastlog failed *
* 3: fseeko() of /var/adm/lastlog failed *
* > 10: 10 + number of entries not found *
* *
* Designed specifically for Solaris; portability uncertain. *
* *
* NOTE: this will need to be (re)compiled as 64-bit prior to the *
* fateful day in 2038 when 32-bit signed twos-complement time_t's *
* overflow, or whenever /var/adm/lastlog is redefined to use 64-bit *
* rather than 32-bit time values. Prior to that, it can be 32-bit, *
* although if so one might want to compile it with large file *
* support. *
* *
* For those who haven't figured it out yet, /var/adm/lastlog is *
* simply an array of struct lastlog (lastlog.h), indexed by uid. *
* Since not all consecutive uids may have been assigned or have *
* logged in, the file could be sparse, but we really don't care. *
* *
* 28 Apr 2000 rlhamil@mindwarp.smart.net initial version *
* *
* 29 Apr 2000 rlhamil@mindwarp.smart.net now lists everything *
* when no args are given *
* (no more usage error) *
* *
****************************************
****************************/
#include <stdio.h>
#include <sys/types.h>
#include <lastlog.h>
#include <pwd.h>
#include <stdlib.h>
#define LASTLOG "/var/adm/lastlog"
uid_t name_to_uid(const char *name)
{
register struct passwd *p;
register uid_t u;
char *ep;
if ((p=getpwnam(name)) != NULL)
return p->pw_uid;
else if ((u=(uid_t)strtol(name,&ep,10)),(ep!=name && *ep=='\0'))
return u;
else
return -1;
}
const char *uid_to_string(uid_t uid)
{
register struct passwd *p;
static char buf[40]; /* could hold 128+ bits in base 10, so quite
generous */
if ((p=getpwuid(uid)) != NULL)
return p->pw_name;
else {
sprintf(buf,"%d",uid);
return buf;
}
}
void print_lastlog(const char *name, const struct lastlog *l)
{
time_t t; /* on 64 bit, need to promote to a time_t; harmless
elsewhere */
t = l->ll_time;
printf("%-10s %-*.*s %-.24s %.*s\n",
name,
sizeof l->ll_line,
sizeof l->ll_line,
l->ll_line,
ctime(&t),
sizeof l->ll_host,
l->ll_host);
}
int notzeros(const void *buf, size_t size)
{
register size_t x;
register const unsigned char *p;
p=buf;
for (x=0;x<size;x++)
if (*p++)
return 1;
return 0;
}
int main(int argc, char **argv)
{
FILE *fp;
struct lastlog l;
int x,notfound=0;
uid_t u;
if ((fp=fopen(LASTLOG,"r")) == NULL) {
perror(LASTLOG);
return 2;
}
if (argc<2) {
for (u=0,notfound=1;fread(&l, sizeof l, 1, fp)==1;u++)
if (notzeros(&l, sizeof l)) {
print_lastlog(uid_to_string(u),&l);
notfound=0;
}
}
else {
for (x=1;x<argc;x++) {
if ((u=name_to_uid(argv[x]))<0) {
fprintf(stderr,"%s: \"%s\" not an account name or numeric
UID\n",
argv[0], argv[x]);
notfound++;
continue;
}
if (fseeko(fp,(off_t) u*sizeof(struct lastlog),SEEK_SET) == -1)
{
perror(LASTLOG);
fclose(fp);
return 3;
}
if (fread(&l, sizeof l, 1, fp) == 1 && notzeros(&l,sizeof l))
print_lastlog(argv[x],&l);
else {
fprintf(stderr,"%s: \"%s\" not found\n",argv[0],argv[x]);
notfound++;
}
}
}
fclose(fp);
endpwent();
return (notfound?notfound+10:0);
}
--
DeeDee, don't press that button! DeeDee! NO! Dee...
[ Post a follow-up to this message ]
|