restore creation of y.tab.c
[unix-history] / usr / src / usr.bin / last / last.c
CommitLineData
fe6cb666 1static char *sccsid = "@(#)last.c 4.3 (Berkeley) %G%";
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;
fe6cb666
BJ
40 char * crmsg = (char *)0;
41 long crtime;
c9af8668
BJ
42
43 time(&buf[0].ut_time);
44 ac--, av++;
45 argc = ac;
46 argv = av;
47 for (i = 0; i < argc; i++) {
48 if (strlen(argv[i])>2)
49 continue;
50 if (!strcmp(argv[i], "~"))
51 continue;
52 if (getpwnam(argv[i]))
53 continue;
54 argv[i] = strspl("tty", argv[i]);
55 }
56 wtmp = open("/usr/adm/wtmp", 0);
57 if (wtmp < 0) {
58 perror("/usr/adm/wtmp");
59 exit(1);
60 }
61 fstat(wtmp, &stb);
62 bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf);
63 if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
64 signal(SIGINT, onintr);
65 signal(SIGQUIT, onintr);
66 }
67 for (bl--; bl >= 0; bl--) {
68 lseek(wtmp, bl * sizeof (buf), 0);
69 bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1];
70 for ( ; bp >= buf; bp--) {
71 print = want(bp);
72 if (print) {
73 ct = ctime(&bp->ut_time);
74 printf("%-*.*s %-*.*s %10.10s %5.5s ",
75 NMAX, NMAX, bp->ut_name,
76 LMAX, LMAX, bp->ut_line, ct, 11+ct);
77 }
78 for (i = 0; i < MAXTTYS; i++) {
79 if (ttnames[i][0] == 0) {
80 strncpy(ttnames[i], bp->ut_line,
81 sizeof(bp->ut_line));
cf779ba2 82 otime = logouts[i];
c9af8668
BJ
83 logouts[i] = bp->ut_time;
84 break;
85 }
86 if (lineq(ttnames[i], bp->ut_line)) {
87 otime = logouts[i];
88 logouts[i] = bp->ut_time;
89 break;
90 }
91 }
92 if (print) {
93 if (otime == 0)
94 printf(" still logged in\n");
95 else {
96 long delta;
97 if (otime < 0) {
98 otime = -otime;
fe6cb666 99 printf("- %s", crmsg);
c9af8668
BJ
100 } else
101 printf("- %5.5s",
102 ctime(&otime)+11);
103 delta = otime - bp->ut_time;
104 if (delta < SECDAY)
105 printf(" (%5.5s)\n",
106 asctime(gmtime(&delta))+11);
107 else
108 printf(" (%ld+%5.5s)\n",
109 delta / SECDAY,
110 asctime(gmtime(&delta))+11);
111 }
112 fflush(stdout);
113 }
fe6cb666 114 if (lineq(bp->ut_line, "~")) {
cf779ba2 115 for (i = 0; i < MAXTTYS; i++)
c9af8668 116 logouts[i] = -bp->ut_time;
fe6cb666
BJ
117 if (nameq(bp->ut_name, "shutdown"))
118 crmsg = "down ";
119 else
120 crmsg = "crash";
121 }
c9af8668
BJ
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
129onintr(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
142want(bp)
143 struct utmp *bp;
144{
145 register char **av;
146 register int ac;
147
fe6cb666 148 if (bp->ut_line[0] == '~' && bp->ut_name[0] == '\0')
c9af8668
BJ
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
163char *
164strspl(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}