1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)last.c	5.3 (Berkeley) 5/15/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * last
  19:  */
  20: #include <sys/types.h>
  21: #include <stdio.h>
  22: #include <signal.h>
  23: #include <sys/stat.h>
  24: #include <utmp.h>
  25: 
  26: #define NMAX    sizeof(buf[0].ut_name)
  27: #define LMAX    sizeof(buf[0].ut_line)
  28: #define HMAX    sizeof(buf[0].ut_host)
  29: #define SECDAY  (24*60*60)
  30: 
  31: #define lineq(a,b)  (!strncmp(a,b,LMAX))
  32: #define nameq(a,b)  (!strncmp(a,b,NMAX))
  33: #define hosteq(a,b) (!strncmp(a,b,HMAX))
  34: 
  35: #define MAXTTYS 256
  36: 
  37: char    **argv;
  38: int argc;
  39: int nameargs;
  40: 
  41: struct  utmp buf[128];
  42: char    ttnames[MAXTTYS][LMAX+1];
  43: long    logouts[MAXTTYS];
  44: 
  45: char    *ctime(), *strspl();
  46: int onintr();
  47: 
  48: main(ac, av)
  49:     char **av;
  50: {
  51:     register int i, k;
  52:     int bl, wtmp;
  53:     char *ct;
  54:     register struct utmp *bp;
  55:     long otime;
  56:     struct stat stb;
  57:     int print;
  58:     char * crmsg = (char *)0;
  59:     long crtime;
  60:     long outrec = 0;
  61:     long maxrec = 0x7fffffffL;
  62: 
  63:     time(&buf[0].ut_time);
  64:     ac--, av++;
  65:     nameargs = argc = ac;
  66:     argv = av;
  67:     for (i = 0; i < argc; i++) {
  68:         if (argv[i][0] == '-' &&
  69:             argv[i][1] >= '0' && argv[i][1] <= '9') {
  70:             maxrec = atoi(argv[i]+1);
  71:             nameargs--;
  72:             continue;
  73:         }
  74:         if (strlen(argv[i])>2)
  75:             continue;
  76:         if (!strcmp(argv[i], "~"))
  77:             continue;
  78:         if (!strcmp(argv[i], "ftp"))
  79:             continue;
  80:         if (!strcmp(argv[i], "uucp"))
  81:             continue;
  82:         if (getpwnam(argv[i]))
  83:             continue;
  84:         argv[i] = strspl("tty", argv[i]);
  85:     }
  86:     wtmp = open("/usr/adm/wtmp", 0);
  87:     if (wtmp < 0) {
  88:         perror("/usr/adm/wtmp");
  89:         exit(1);
  90:     }
  91:     fstat(wtmp, &stb);
  92:     bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf);
  93:     if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
  94:         signal(SIGINT, onintr);
  95:         signal(SIGQUIT, onintr);
  96:     }
  97:     for (bl--; bl >= 0; bl--) {
  98:         lseek(wtmp, bl * sizeof (buf), 0);
  99:         bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1];
 100:         for ( ; bp >= buf; bp--) {
 101:             print = want(bp);
 102:             if (print) {
 103:                 ct = ctime(&bp->ut_time);
 104:                 printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s ",
 105:                     NMAX, NMAX, bp->ut_name,
 106:                     LMAX, LMAX, bp->ut_line,
 107:                     HMAX, HMAX, bp->ut_host,
 108:                     ct, 11+ct);
 109:             }
 110:             for (i = 0; i < MAXTTYS; i++) {
 111:                 if (ttnames[i][0] == 0) {
 112:                     strncpy(ttnames[i], bp->ut_line,
 113:                         sizeof(bp->ut_line));
 114:                     otime = logouts[i];
 115:                     logouts[i] = bp->ut_time;
 116:                     break;
 117:                 }
 118:                 if (lineq(ttnames[i], bp->ut_line)) {
 119:                     otime = logouts[i];
 120:                     logouts[i] = bp->ut_time;
 121:                     break;
 122:                 }
 123:             }
 124:             if (print) {
 125:                 if (lineq(bp->ut_line, "~"))
 126:                     printf("\n");
 127:                 else if (otime == 0)
 128:                     printf("  still logged in\n");
 129:                 else {
 130:                     long delta;
 131:                     if (otime < 0) {
 132:                         otime = -otime;
 133:                         printf("- %s", crmsg);
 134:                     } else
 135:                         printf("- %5.5s",
 136:                             ctime(&otime)+11);
 137:                     delta = otime - bp->ut_time;
 138:                     if (delta < SECDAY)
 139:                         printf("  (%5.5s)\n",
 140:                         asctime(gmtime(&delta))+11);
 141:                     else
 142:                         printf(" (%ld+%5.5s)\n",
 143:                         delta / SECDAY,
 144:                         asctime(gmtime(&delta))+11);
 145:                 }
 146:                 fflush(stdout);
 147:                 if (++outrec >= maxrec)
 148:                     exit(0);
 149:             }
 150:             if (lineq(bp->ut_line, "~")) {
 151:                 for (i = 0; i < MAXTTYS; i++)
 152:                     logouts[i] = -bp->ut_time;
 153:                 if (nameq(bp->ut_name, "shutdown"))
 154:                     crmsg = "down ";
 155:                 else
 156:                     crmsg = "crash";
 157:             }
 158:         }
 159:     }
 160:     ct = ctime(&buf[0].ut_time);
 161:     printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
 162:     exit(0);
 163: }
 164: 
 165: onintr(signo)
 166:     int signo;
 167: {
 168:     char *ct;
 169: 
 170:     if (signo == SIGQUIT)
 171:         signal(SIGQUIT, onintr);
 172:     ct = ctime(&buf[0].ut_time);
 173:     printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
 174:     fflush(stdout);
 175:     if (signo == SIGINT)
 176:         exit(1);
 177: }
 178: 
 179: want(bp)
 180:     struct utmp *bp;
 181: {
 182:     register char **av;
 183:     register int ac;
 184: 
 185:     if (bp->ut_line[0] == '~' && bp->ut_name[0] == '\0')
 186:         strcpy(bp->ut_name, "reboot");      /* bandaid */
 187:     if (strncmp(bp->ut_line, "ftp", 3) == 0)
 188:         bp->ut_line[3] = '\0';
 189:     if (strncmp(bp->ut_line, "uucp", 4) == 0)
 190:         bp->ut_line[4] = '\0';
 191:     if (bp->ut_name[0] == 0)
 192:         return (0);
 193:     if (nameargs == 0)
 194:         return (1);
 195:     av = argv;
 196:     for (ac = 0; ac < argc; ac++, av++) {
 197:         if (av[0][0] == '-')
 198:             continue;
 199:         if (nameq(*av, bp->ut_name) || lineq(*av, bp->ut_line))
 200:             return (1);
 201:     }
 202:     return (0);
 203: }
 204: 
 205: char *
 206: strspl(left, right)
 207:     char *left, *right;
 208: {
 209:     char *res = (char *)malloc(strlen(left)+strlen(right)+1);
 210: 
 211:     strcpy(res, left);
 212:     strcat(res, right);
 213:     return (res);
 214: }

Defined functions

main defined in line 48; never used
onintr defined in line 165; used 4 times
strspl defined in line 205; used 2 times
want defined in line 179; used 1 times

Defined variables

argc defined in line 38; used 3 times
argv defined in line 37; used 13 times
buf defined in line 41; used 14 times
copyright defined in line 8; never used
logouts defined in line 43; used 5 times
nameargs defined in line 39; used 3 times
sccsid defined in line 14; never used
ttnames defined in line 42; used 3 times

Defined macros

HMAX defined in line 28; used 3 times
LMAX defined in line 27; used 4 times
MAXTTYS defined in line 35; used 4 times
NMAX defined in line 26; used 3 times
SECDAY defined in line 29; used 2 times
hosteq defined in line 33; never used
lineq defined in line 31; used 4 times
nameq defined in line 32; used 2 times
Last modified: 1986-05-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 902
Valid CSS Valid XHTML 1.0 Strict