BSD 4 release
[unix-history] / usr / src / cmd / last.c
CommitLineData
31cef89c 1static char *sccsid = "@(#)last.c 4.2 (Berkeley) 10/9/80";
c9af8668
BJ
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
20char **argv;
21int argc;
22
23struct utmp buf[128];
24char ttnames[MAXTTYS][LMAX+1];
25long logouts[MAXTTYS];
26
27char *ctime(), *strspl();
28int onintr();
29
30main(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));
cf779ba2 80 otime = logouts[i];
c9af8668
BJ
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 }
cf779ba2
BJ
112 if (!strcmp(bp->ut_name, "reboot"))
113 for (i = 0; i < MAXTTYS; i++)
c9af8668
BJ
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
122onintr(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
135want(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
156char *
157strspl(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}