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