[comp.unix.questions] When does wtmp reset?

tpm@uunet.uu.net (Terence P. Ma) (05/22/91)

UNIX-gurus:

While looking over the earlier question of how to look up when someone was
last logged in, I see that the command "last" (on my SS1+; SunOS4.1.1) is
appropriate.  However, whenever I type "last" I note that wtmp is started at
the same time as the earliest login of that particular day.  I am suspecting
that this is because I have the accounting program run in the middle of the
night and it resets wtmp (is this correct? -- couldn't find it in the any
manual entry).

I know that the last login date is in /var/adm/lastlog.  Is there an easy
way to get the lastlogin date and time of all users or groups of users
without using "finger -s user1 user2 ..." to get at it?

Thanks!
Tere

***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
Terence P. Ma, Ph.D.				
Department of Anatomy				If it were easy, some one
University of Mississippi Medical Center	would have done it already.
2500 North State Street					-- anonymous
Jackson, MS 39216				
VOICE:	601-984-1654			UUCP:	tpm-sprl!tpm@uunet.uu.net
***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****

tchrist@convex.COM (Tom Christiansen) (05/22/91)

From the keyboard of tpm-sprl!tpm@uunet.uu.net (Terence P. Ma):
:I know that the last login date is in /var/adm/lastlog.  Is there an easy
:way to get the lastlogin date and time of all users or groups of users
:without using "finger -s user1 user2 ..." to get at it?

Here's a C program to do that.  Perl version (runs 3x slower; sigh)
available upon request.  

--tom

/*
 * lastlog - print last login time for all users, based on times
 *            stored in /usr/adm/lastlog.
 *
 * Lines are printed oldest first, with name, date/time, and gecos
 * field on each line.
 *
 * No command line options. Runs on VAX/4.2 BSD Unix.
 *
 * compile with:  cc -O -o lastlog lastlog.c
 *
 * Rex Sanders, US Geological Survey, Pacific Marine Geology, 12/19/85
 */

#include <stdio.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/types.h>
#include <lastlog.h>
#include <pwd.h>
#include <sysexits.h>

/* maximum number of users/entries in /etc/passwd */
#define MAXU       5000
/* maximum length of the gecos field in /etc/passwd */
#define MAXG        100

char   *ctime ();
long    lseek ();

struct info_s {
    int     time;
    char    name[9];
    char    gecos[MAXG];
};
struct info_s   info[MAXU];

main (argc, argv) char **argv; {
    int     infocmp ();
    struct lastlog  ll;
    struct passwd  *pw;
    char    lastdate[25];
    int     llfd;
    register int    nusers = 0;
    register int    i;

    if ((llfd = open ("/usr/adm/lastlog", O_RDONLY)) < 0) {
         perror ("lastlog: /usr/adm/lastlog");
         exit (EX_OSFILE);
    }

/*
 * For each user in password file, grab password info
 */
    while (pw = getpwent ()) {
    /* 
     * Grab info from lastlog file
     */
	 if (!strcmp(pw->pw_passwd,"*"))
		continue;
         if (lseek (llfd, (long) pw -> pw_uid * sizeof ll, 0) == -1) {
	    fprintf(stderr,"%s: lseek for uid %d failed\n", *argv, pw->pw_uid);
	    continue;
	 } 
         if (read (llfd, (char *) & ll, sizeof ll) != sizeof ll) {
	    fprintf(stderr, "%s: read for uid %d failed\n", *argv, pw->pw_uid);
	    continue;
	 } 


         info[nusers].time = ll.ll_time;
         strncpy (info[nusers].name, pw -> pw_name, 9);
         strncpy (info[nusers].gecos, pw -> pw_gecos, MAXG);
         if (nusers++ == MAXU) {
	    fprintf(stderr, "%s: recompile with MAXU > %d\n",
		*argv, MAXU);
	    exit(EX_SOFTWARE);
	 } 
    }

/*
 * Sort users by last login time
 */
    qsort ((char *) info, nusers, sizeof (struct info_s), infocmp);

/*
 * Print info for each user
 */
    for (i = 0; i < nusers; i++) {
         if (info[i].time) {
             strncpy (lastdate, ctime (&info[i].time), 24);
             lastdate[24] = '\0';
         }
         else
             strcpy (lastdate, "never logged in");

         printf ("%-8s %-24s    %s\n", info[i].name, lastdate,
                   info[i].gecos);
    }

    close (llfd);
    endpwent ();
}

/*
 * infocmp - compare 2 info entries for qsort
 */

infocmp (info1, info2)
struct info_s  *info1,
               *info2;
{
    register int    r;

    if (info1 -> time == info2 -> time)
         r = 0;
    else
         r = (info1 -> time > info2 -> time) ? 1 : -1;

    return (r);
}
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time." 

czahl@opal.cs.tu-berlin.de (Christian Zahl) (05/24/91)

tpm-sprl!tpm@uunet.uu.net (Terence P. Ma) writes:

>UNIX-gurus:

>While looking over the earlier question of how to look up when someone was
>last logged in, I see that the command "last" (on my SS1+; SunOS4.1.1) is
>appropriate.  However, whenever I type "last" I note that wtmp is started at
>the same time as the earliest login of that particular day.  I am suspecting
>that this is because I have the accounting program run in the middle of the
>night and it resets wtmp (is this correct? -- couldn't find it in the any
>manual entry).

The fact is quiet right. There is no automatic mechanism to remove old
entries. The only way is to remove it with an own written program or by
removing the wtmp and creating a new empty one.

helps?, Chris