# 2.11BSD#431 - /usr/src/ucb/last.c

##### Functions

    main              X
    onintr            X
    strspl            X
    usage             X
    want              X

##### Variables

    argc              X
    argv              X
    buf               X
    copyright         X
    logouts           X
    nameargs          X
    ttnames           X

##### Macros

    HMAX              X
    LMAX              X
    MAXTTYS           X
    NMAX              X
    SECDAY            X
    hosteq            X
    lineq             X
    nameq             X

       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  ((long)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 wtmp;
      53:     off_t bl;
      54:     char *ct;
      55:     char wtmpfile[256];
      56:     char progname[256];
      57:     register struct utmp *bp;
      58:     long otime;
      59:     struct stat stb;
      60:     int print;
      61:     int sinput = 0;
      62:     char * crmsg = (char *)0;
      63:     long crtime;
      64:     long outrec = 0;
      65:     long maxrec = 0x7fffffffL;
      66:
      67:     time(&buf[0].ut_time);
      68:     strcpy(wtmpfile,"/usr/adm/wtmp");
      69:     strcpy(progname,av[0]);
      70:     ac--, av++;
      71:     nameargs = argc = ac;
      72:     argv = av;
      73:     for (i = 0; i < argc; i++) {
      74:         if (argv[i][0] == '-' ) {
      75:             if ( argv[i][1] >= '0' && argv[i][1] <= '9') {
      76:                 maxrec = atoi(argv[i]+1);
      77:                 nameargs--;
      78:                 continue;
      79:             } else {
      80:                 if (argv[i][1] == 'f') {
      81:                     i++;
      82:                     if ( i < argc) {
      83:                         strcpy(wtmpfile,argv[i]);
      84:                         nameargs = nameargs -2;
      85:                         continue;
      86:                     } else {
      87:                         usage(progname);
      88:                     }
      89:                 } else {
      90:                     usage(progname);
      91:                 }
      92:             }
      93:         }
      94:         if (strlen(argv[i])>2)
      95:             continue;
      96:         if (!strcmp(argv[i], "~"))
      97:             continue;
      98:         if (!strcmp(argv[i], "ftp"))
      99:             continue;
     100:         if (!strcmp(argv[i], "uucp"))
     101:             continue;
     102:         if (getpwnam(argv[i]))
     103:             continue;
     104:         argv[i] = strspl("tty", argv[i]);
     105:     }
     106:     wtmp = open(wtmpfile, 0);
     107:     if (wtmp < 0) {
     108:         perror(wtmpfile);
     109:         exit(1);
     110:     }
     111:     fstat(wtmp, &stb);
     112:     bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf);
     113:     if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
     114:         signal(SIGINT, onintr);
     115:         signal(SIGQUIT, onintr);
     116:     }
     117:     for (bl--; bl >= 0; bl--) {
     118:         lseek(wtmp, bl * sizeof (buf), 0);
     119:         bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1];
     120:         for ( ; bp >= buf; bp--) {
     121:             print = want(bp);
     122:             if (print) {
     123:                 ct = ctime(&bp->ut_time);
     124:                 printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s ",
     125:                     NMAX, NMAX, bp->ut_name,
     126:                     LMAX, LMAX, bp->ut_line,
     127:                     HMAX, HMAX, bp->ut_host,
     128:                     ct, 11+ct);
     129:             }
     130:             for (i = 0; i < MAXTTYS; i++) {
     131:                 if (ttnames[i][0] == 0) {
     132:                     strncpy(ttnames[i], bp->ut_line,
     133:                         sizeof(bp->ut_line));
     134:                     otime = logouts[i];
     135:                     logouts[i] = bp->ut_time;
     136:                     break;
     137:                 }
     138:                 if (lineq(ttnames[i], bp->ut_line)) {
     139:                     otime = logouts[i];
     140:                     logouts[i] = bp->ut_time;
     141:                     break;
     142:                 }
     143:             }
     144:             if (print) {
     145:                 if (lineq(bp->ut_line, "~"))
     146:                     printf("\n");
     147:                 else if (otime == 0)
     148:                     printf("  still logged in\n");
     149:                 else {
     150:                     long delta;
     151:                     if (otime < 0) {
     152:                         otime = -otime;
     153:                         printf("- %s", crmsg);
     154:                     } else
     155:                         printf("- %5.5s",
     156:                             ctime(&otime)+11);
     157:                     delta = otime - bp->ut_time;
     158:                     if (delta < SECDAY)
     159:                         printf("  (%5.5s)\n",
     160:                         asctime(gmtime(&delta))+11);
     161:                     else
     162:                         printf(" (%ld+%5.5s)\n",
     163:                         delta / SECDAY,
     164:                         asctime(gmtime(&delta))+11);
     165:                 }
     166:                 fflush(stdout);
     167:                 if (++outrec >= maxrec)
     168:                     exit(0);
     169:             }
     170:             if (lineq(bp->ut_line, "~")) {
     171:                 for (i = 0; i < MAXTTYS; i++)
     172:                     logouts[i] = -bp->ut_time;
     173:                 if (nameq(bp->ut_name, "shutdown"))
     174:                     crmsg = "down ";
     175:                 else
     176:                     crmsg = "crash";
     177:             }
     178:         }
     179:     }
     180:     ct = ctime(&buf[0].ut_time);
     181:     printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
     182:     exit(0);
     183: }
     184:
     185: onintr(signo)
     186:     int signo;
     187: {
     188:     char *ct;
     189:
     190:     if (signo == SIGQUIT)
     191:         signal(SIGQUIT, onintr);
     192:     ct = ctime(&buf[0].ut_time);
     193:     printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
     194:     fflush(stdout);
     195:     if (signo == SIGINT)
     196:         exit(1);
     197: }
     198:
     199: want(bp)
     200:     struct utmp *bp;
     201: {
     202:     register char **av;
     203:     register int ac;
     204:
     205:     if (bp->ut_line[0] == '~' && bp->ut_name[0] == '\0')
     206:         strcpy(bp->ut_name, "reboot");      /* bandaid */
     207:     if (strncmp(bp->ut_line, "ftp", 3) == 0)
     208:         bp->ut_line[3] = '\0';
     209:     if (strncmp(bp->ut_line, "uucp", 4) == 0)
     210:         bp->ut_line[4] = '\0';
     211:     if (bp->ut_name[0] == 0)
     212:         return (0);
     213:     if (nameargs == 0)
     214:         return (1);
     215:     av = argv;
     216:     for (ac = 0; ac < argc; ac++, av++) {
     217:         if (av[0][0] == '-')
     218:             continue;
     219:         if (nameq(*av, bp->ut_name) || lineq(*av, bp->ut_line))
     220:             return (1);
     221:     }
     222:     return (0);
     223: }
     224:
     225: char *
     226: strspl(left, right)
     227:     char *left, *right;
     228: {
     229:     char *res = (char *)malloc(strlen(left)+strlen(right)+1);
     230:
     231:     strcpy(res, left);
     232:     strcat(res, right);
     233:     return (res);
     234: }
     235:
     236: void
     237: usage(progname)
     238:     char *progname;
     239: {
     240:     printf("Usage: %s [ -f filename ] [-number] [name...] [tty...]\n",
     241:         progname);
     242:     exit(1);
     243: }

#### Defined functions

main defined in line 48; never used
onintr defined in line 185; used 4 times

- in line 46, 114-115(2), 191

strspl defined in line 225; used 2 times

- in line 45, 104

usage defined in line 236; used 2 times

- in line 87-90(2)

want defined in line 199; used 1 times

- in line 121

#### Defined variables

argc defined in line 38; used 4 times

- in line 71-73(2), 82, 216

argv defined in line 37; used 15 times

- in line 72-83(7), 94-104(7), 215

buf defined in line 41; used 14 times

- in line 26-28(3), 67, 112(2), 118-120(6), 180, 192

copyright defined in line 8; never used
logouts defined in line 43; used 5 times

- in line 134-140(4), 172

nameargs defined in line 39; used 5 times

- in line 71, 77, 84(2), 213

sccsid defined in line 14; never used
ttnames defined in line 42; used 3 times

- in line 131-132(2), 138

#### Defined macros

HMAX defined in line 28; used 3 times

- in line 33, 127(2)

LMAX defined in line 27; used 4 times

- in line 31, 42, 126(2)

MAXTTYS defined in line 35; used 4 times

- in line 42-43(2), 130, 171

NMAX defined in line 26; used 3 times

- in line 32, 125(2)

SECDAY defined in line 29; used 2 times

- in line 158-163(2)

hosteq defined in line 33; never used
lineq defined in line 31; used 4 times

- in line 138, 145, 170, 219

nameq defined in line 32; used 2 times

- in line 173, 219

Last modified: 1993-01-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 904 |