|
|
1.1 root 1: #include <stdio.h>
2: #include <utmp.h>
3:
4: struct utmp u, ulist[100], *ufreep = &ulist[0];
5:
6: int boot = 0; /* set to 1 when a boot is encountered */
7:
8: long t_final; /* end of a given period of up time */
9: long t_old, t_new; /* login session start and stop times */
10:
11: FILE *ufp; /* file pointer for wtmp file */
12:
13: int argc;
14: char **argv;
15:
16: char *WTMP = "/usr/adm/wtmp";
17:
18: struct {
19: char *flag;
20: char *title;
21: } spcl[] = {
22: "~", "Reboot",
23: "|", "Old time",
24: "{", "New time",
25: NULL, NULL,
26: };
27:
28: struct utmp *lookup();
29: char *ctime(), *strcpy();
30:
31: main(ac, av)
32: int ac;
33: char **av;
34: {
35: argc = ac-1;
36: argv = av+1;
37: time(&t_final);
38: if ((ufp = fopen(WTMP, "r")) == NULL) {
39: fprintf(stderr, "log: cannot open %s\n", WTMP);
40: exit(1);
41: }
42: fseek(ufp, 0L, 2);
43: uscan();
44: fclose(ufp);
45: exit(0);
46: }
47:
48: /*
49: * display info for current ufp
50: */
51: uscan()
52: {
53: register char *q;
54: register int i;
55:
56: while (revread()) {
57: if (strcmp(u.ut_line, "~") == 0) {
58: boot = 1;
59: ufreep = &ulist[0];
60: t_final = u.ut_time;
61: }
62: if (strcmp(u.ut_name, "") == 0)
63: *lookup() = u;
64: if (!okay())
65: continue;
66: t_old = u.ut_time;
67: q = ctime(&t_old);
68: if (strcmp(u.ut_name, "") == 0) {
69: for (i = 0; spcl[i].flag; i++)
70: if (strcmp(spcl[i].flag, u.ut_line) == 0)
71: printf("%s: %s", spcl[i].title, q);
72: continue;
73: } else {
74: printf("%-8.8s%-8.8s%16.16s - ",
75: u.ut_name, u.ut_line, q);
76: t_new = lookup()->ut_time;
77: if (t_new == 0) {
78: t_new = t_final;
79: if (boot)
80: printf("boot ");
81: else
82: printf(" now ");
83: }
84: else
85: printf("%5.5s", 11+ctime(&t_new));
86: printf(" ("); prelapse(t_new-t_old); printf(")\n");
87: }
88: }
89: }
90:
91: /*
92: * print elapsed time
93: */
94:
95: #define MINUTE (60L)
96: #define HOUR (60L * MINUTE)
97: #define DAY (24L * HOUR)
98:
99: prelapse(t)
100: long t;
101: {
102: register int days, hours, minutes;
103:
104: days = t/DAY;
105: t %= DAY;
106: hours = t/HOUR;
107: t %= HOUR;
108: minutes = t/MINUTE;
109: if (days)
110: printf("%d+", days);
111: printf("%d:%02d", hours, minutes);
112: }
113:
114: /*
115: * locate tty line entry in ulist; make one if necessary
116: */
117: struct utmp *
118: lookup()
119: {
120: register struct utmp *p;
121:
122: for (p = &ulist[0]; p < ufreep; p++)
123: if (strcmp(p->ut_line, u.ut_line) == 0)
124: return(p);
125: if (p >= &ulist[sizeof(ulist)]) {
126: fprintf(stderr, "log: ulist overflow\n");
127: exit(1);
128: }
129: ufreep++;
130: strcpy(p->ut_name, "");
131: strcpy(p->ut_line, "");
132: p->ut_time = 0L;
133: return(p);
134: }
135:
136: /*
137: * return 1 if this entry should be printed, else 0
138: */
139: okay()
140: {
141: register int count;
142: register char **pp;
143:
144: if (argc <= 0)
145: return(1);
146: for (count=argc, pp=argv; count>0; --count, pp++) {
147: if (strcmp(*pp, u.ut_line) == 0)
148: return(1);
149: if (strcmp(*pp, u.ut_name) == 0)
150: return(1);
151: }
152: return(0);
153: }
154:
155: /*
156: * buffered reverse read of next utmp entry.
157: */
158: revread()
159: {
160: static struct utmp ubuf[100];
161: static int nitems = 0;
162: long nbytes;
163:
164: if (nitems <= 0) {
165: fflush(stdout);
166: nbytes = ftell(ufp);
167: if (nbytes > sizeof(ubuf))
168: nbytes = sizeof(ubuf);
169: nitems = nbytes / sizeof(ubuf[0]);
170: if (fseek(ufp, -nbytes, 1) == -1)
171: return(0);
172: if (fread(&ubuf[0], sizeof(ubuf[0]), nitems, ufp) != nitems)
173: return(0);
174: if (fseek(ufp, -nbytes, 1) == -1)
175: return(0);
176: }
177: if (--nitems < 0)
178: return(0);
179: u = ubuf[nitems];
180: return(1);
181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.