|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.