|
|
1.1 ! root 1: static char *sccsid = "@(#)last.c 4.2 (Berkeley) 10/9/80"; ! 2: /* ! 3: * last ! 4: */ ! 5: #include <sys/types.h> ! 6: #include <stdio.h> ! 7: #include <signal.h> ! 8: #include <sys/stat.h> ! 9: #include <utmp.h> ! 10: ! 11: #define NMAX sizeof(buf[0].ut_name) ! 12: #define LMAX sizeof(buf[0].ut_line) ! 13: #define SECDAY (24*60*60) ! 14: ! 15: #define lineq(a,b) (!strncmp(a,b,LMAX)) ! 16: #define nameq(a,b) (!strncmp(a,b,NMAX)) ! 17: ! 18: #define MAXTTYS 256 ! 19: ! 20: char **argv; ! 21: int argc; ! 22: ! 23: struct utmp buf[128]; ! 24: char ttnames[MAXTTYS][LMAX+1]; ! 25: long logouts[MAXTTYS]; ! 26: ! 27: char *wfile = "/usr/adm/wtmp"; ! 28: ! 29: char *ctime(), *strspl(); ! 30: int onintr(); ! 31: ! 32: main(ac, av) ! 33: char **av; ! 34: { ! 35: register int i, k; ! 36: int bl, wtmp; ! 37: char *ct; ! 38: register struct utmp *bp; ! 39: long otime; ! 40: struct stat stb; ! 41: int print; ! 42: ! 43: time(&buf[0].ut_time); ! 44: ac--, av++; ! 45: argc = ac; ! 46: argv = av; ! 47: if (argc >= 2 && strcmp(argv[0], "-f") == 0) { ! 48: wfile = argv[1]; ! 49: argv += 2; ! 50: argc -= 2; ! 51: } ! 52: for (i = 0; i < argc; i++) { ! 53: if (strlen(argv[i])>2) ! 54: continue; ! 55: if (!strcmp(argv[i], "~")) ! 56: continue; ! 57: if (getpwnam(argv[i])) ! 58: continue; ! 59: argv[i] = strspl("tty", argv[i]); ! 60: } ! 61: wtmp = open(wfile, 0); ! 62: if (wtmp < 0) { ! 63: perror(wfile); ! 64: exit(1); ! 65: } ! 66: fstat(wtmp, &stb); ! 67: bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf); ! 68: if (signal(SIGINT, SIG_IGN) != SIG_IGN) { ! 69: signal(SIGINT, onintr); ! 70: signal(SIGQUIT, onintr); ! 71: } ! 72: for (bl--; bl >= 0; bl--) { ! 73: lseek(wtmp, bl * sizeof (buf), 0); ! 74: bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1]; ! 75: for ( ; bp >= buf; bp--) { ! 76: print = want(bp); ! 77: if (print) { ! 78: ct = ctime(&bp->ut_time); ! 79: printf("%-*.*s %-*.*s %10.10s %5.5s ", ! 80: NMAX, NMAX, bp->ut_name, ! 81: LMAX, LMAX, bp->ut_line, ct, 11+ct); ! 82: } ! 83: for (i = 0; i < MAXTTYS; i++) { ! 84: if (ttnames[i][0] == 0) { ! 85: strncpy(ttnames[i], bp->ut_line, ! 86: sizeof(bp->ut_line)); ! 87: otime = logouts[i]; ! 88: logouts[i] = bp->ut_time; ! 89: break; ! 90: } ! 91: if (lineq(ttnames[i], bp->ut_line)) { ! 92: otime = logouts[i]; ! 93: logouts[i] = bp->ut_time; ! 94: break; ! 95: } ! 96: } ! 97: if (print) { ! 98: if (otime == 0) ! 99: printf(" still logged in\n"); ! 100: else { ! 101: long delta; ! 102: if (otime < 0) { ! 103: otime = -otime; ! 104: printf("- crash"); ! 105: } else ! 106: printf("- %5.5s", ! 107: ctime(&otime)+11); ! 108: delta = otime - bp->ut_time; ! 109: if (delta < SECDAY) ! 110: printf(" (%5.5s)\n", ! 111: asctime(gmtime(&delta))+11); ! 112: else ! 113: printf(" (%ld+%5.5s)\n", ! 114: delta / SECDAY, ! 115: asctime(gmtime(&delta))+11); ! 116: } ! 117: fflush(stdout); ! 118: } ! 119: if (!strcmp(bp->ut_name, "reboot")) ! 120: for (i = 0; i < MAXTTYS; i++) ! 121: logouts[i] = -bp->ut_time; ! 122: } ! 123: } ! 124: ct = ctime(&buf[0].ut_time); ! 125: printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11); ! 126: exit(0); ! 127: } ! 128: ! 129: onintr(signo) ! 130: int signo; ! 131: { ! 132: char *ct; ! 133: ! 134: if (signo == SIGQUIT) ! 135: signal(SIGQUIT, onintr); ! 136: ct = ctime(&buf[0].ut_time); ! 137: printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11); ! 138: if (signo == SIGINT) ! 139: exit(1); ! 140: } ! 141: ! 142: want(bp) ! 143: struct utmp *bp; ! 144: { ! 145: register char **av; ! 146: register int ac; ! 147: ! 148: if (bp->ut_line[0] == '~') ! 149: strcpy(bp->ut_name, "reboot"); /* bandaid */ ! 150: if (bp->ut_name[0] == 0) ! 151: return (0); ! 152: if (argc == 0) ! 153: return (1); ! 154: av = argv; ! 155: for (ac = 0; ac < argc; ac++) { ! 156: if (nameq(*av, bp->ut_name) || lineq(*av, bp->ut_line)) ! 157: return (1); ! 158: av++; ! 159: } ! 160: return (0); ! 161: } ! 162: ! 163: char * ! 164: strspl(left, right) ! 165: char *left, *right; ! 166: { ! 167: char *res = (char *)malloc(strlen(left)+strlen(right)+1); ! 168: ! 169: strcpy(res, left); ! 170: strcat(res, right); ! 171: return (res); ! 172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.