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