|
|
1.1 root 1: /* ac.c */
2: extern struct _iobuf {
3: int _cnt;
4: unsigned char *_ptr;
5: unsigned char *_base;
6: short _flag;
7: char _file;
8: } _iob[20];
9: struct _iobuf *fopen();
10: struct _iobuf *fdopen();
11: struct _iobuf *freopen();
12: long ftell();
13: char *fgets();
14: typedef unsigned char u_char;
15: typedef unsigned short u_short;
16: typedef unsigned int u_int;
17: typedef unsigned long u_long;
18: typedef struct _physadr { int r[1]; } *physadr;
19: typedef int daddr_t;
20: typedef char * caddr_t;
21: typedef u_short ino_t;
22: typedef int swblk_t;
23: typedef int size_t;
24: typedef int time_t;
25: typedef int label_t[14];
26: typedef short dev_t;
27: typedef int off_t;
28: typedef long portid_t;
29: typedef struct fd_set { int fds_bits[1]; } fd_set;
30: struct tm {
31: int tm_sec;
32: int tm_min;
33: int tm_hour;
34: int tm_mday;
35: int tm_mon;
36: int tm_year;
37: int tm_wday;
38: int tm_yday;
39: int tm_isdst;
40: };
41: struct utmp {
42: char ut_line[8];
43: char ut_name[8];
44: long ut_time;
45: };
46: struct utmp ibuf, ubuf[400 ], tbuf[101 ];
47: int nnames;
48: char *wtmp = "/usr/adm/wtmp";
49: char REBOOT[] = "~";
50: char OLDTIME[] = "|";
51: char NEWTIME[] = "{";
52: char DATERR[] = "ac: botched date change\n";
53: int pflag, byday, tflag;
54: time_t lasttime, dtime, starttime, stoptime;
55: int ncount;
56: char *SYSBUF[1024];
57: char **nptr;
58: char *ctime(), *strncpy();
59: time_t time(), nexttime(), prevtime();
60: struct tm *localtime();
61: main(argc, argv)
62: register int argc;
63: register char **argv;
64: {
65: register struct _iobuf *wf;
66: setbuf((&_iob[1]), SYSBUF);
67: while (--argc > 0 && **++argv == '-')
68: switch(*++*argv) {
69: case 'd':
70: byday++;
71: continue;
72: case 'w':
73: if (--argc > 0)
74: wtmp = *++argv;
75: continue;
76: case 'p':
77: pflag++;
78: continue;
79: case 't':
80: tflag++;
81: pflag++;
82: continue;
83: }
84: ncount = argc;
85: nptr = argv;
86: if ((wf = fopen(wtmp, "r")) == 0) {
87: fprintf((&_iob[2]), "ac: cannot open %s\n", wtmp);
88: exit(1);
89: }
90: while (fread((char *)&ibuf, sizeof(ibuf), 1, wf) == 1) {
91: loop();
92: lasttime = ibuf.ut_time;
93: }
94: *ibuf.ut_name = '\0';
95: (void)strncpy(ibuf.ut_line, REBOOT, sizeof(ibuf.ut_line));
96: time(&ibuf.ut_time);
97: loop();
98: print();
99: exit(0);
100: }
101: loop()
102: {
103: register struct utmp *tp;
104: register char *p;
105: register int n, i;
106: if (tflag && *ibuf.ut_name)
107: (void)strncpy(ibuf.ut_name, ibuf.ut_line, sizeof(ibuf.ut_name));
108: if ( (*ibuf.ut_line == * NEWTIME && strncmp(ibuf.ut_line, NEWTIME, sizeof(ibuf.ut_line)) == 0)) {
109: if (dtime == 0) {
110: fprintf((&_iob[2]), DATERR);
111: return;
112: }
113: for(tp = tbuf; tp < &tbuf[101 ]; tp++) if (*tp->ut_line)
114: tp->ut_time += ibuf.ut_time - dtime;
115: dtime = 0;
116: return;
117: }
118: if (dtime != 0) {
119: fprintf((&_iob[2]), DATERR);
120: dtime = 0;
121: }
122: if ( (*ibuf.ut_line == * OLDTIME && strncmp(ibuf.ut_line, OLDTIME, sizeof(ibuf.ut_line)) == 0)) {
123: dtime = ibuf.ut_time;
124: return;
125: }
126: if (lasttime > ibuf.ut_time + 10 )
127: fprintf((&_iob[2]), "ac: entry not in time sequence\n");
128: if (byday) {
129: if (starttime == 0 || starttime > ibuf.ut_time + 10 ) {
130: starttime = prevtime(ibuf.ut_time);
131: stoptime = nexttime(ibuf.ut_time);
132: }
133: while (ibuf.ut_time >= stoptime) {
134: for(tp = tbuf; tp < &tbuf[101 ]; tp++) if (*tp->ut_line) {
135: update(tp, stoptime);
136: tp->ut_time = stoptime;
137: }
138: print();
139: starttime = stoptime;
140: stoptime = nexttime(stoptime);
141: }
142: }
143: if ( (*ibuf.ut_line == * REBOOT && strncmp(ibuf.ut_line, REBOOT, sizeof(ibuf.ut_line)) == 0)) {
144: for(tp = tbuf; tp < &tbuf[101 ]; tp++) if (*tp->ut_line) {
145: update(tp, ibuf.ut_time);
146: *tp->ut_name = '\0';
147: tp->ut_time = 0;
148: }
149: return;
150: }
151: i = 0;
152: p = ibuf.ut_line;
153: while (n = *p++)
154: i += i+n;
155: tp = &tbuf[((unsigned)(i*2)) % 101 ];
156: n = 101 ; do {
157: if ( (*tp->ut_line == * ibuf.ut_line && strncmp(tp->ut_line, ibuf.ut_line, sizeof(tp->ut_line)) == 0)) {
158: if (*tp->ut_name)
159: update(tp, ibuf.ut_time);
160: *tp = ibuf;
161: return;
162: }
163: if (*tp->ut_line == '\0') {
164: *tp = ibuf;
165: return;
166: }
167: if (--tp < tbuf)
168: tp += 101 ;
169: } while (--n);
170: fprintf((&_iob[2]), "ac: tbuf table overflow\n");
171: exit(1);
172: }
173: update(tp, t)
174: register struct utmp *tp;
175: time_t t;
176: {
177: register struct utmp *up;
178: register int n;
179: if (*tp->ut_name && among(tp)) {
180: t -= tp->ut_time;
181: if (t < 0)
182: fprintf((&_iob[2]), "ac: strange login: %-8.8s%6.2f\n",
183: tp->ut_name, (double)t/3600);
184: up = ubuf;
185: if ((n = nnames) > 0) do {
186: if ( (*up->ut_name == * tp->ut_name && strncmp(up->ut_name, tp->ut_name, sizeof(up->ut_name)) == 0)) {
187: up->ut_time += t;
188: return;
189: }
190: up++;
191: } while (--n);
192: if (nnames < 400 ) {
193: (void)strncpy(up->ut_name, tp->ut_name, sizeof(up->ut_name));
194: up->ut_time = t;
195: nnames++;
196: return;
197: }
198: fprintf((&_iob[2]), "ac: ubuf table overflow\n");
199: exit(1);
200: }
201: }
202: among(up)
203: register struct utmp *up;
204: {
205: register int j;
206: if (ncount <= 0)
207: return(1);
208: for (j = 0; j < ncount; j++)
209: if ( (*up->ut_name == * nptr[j] && strncmp(up->ut_name, nptr[j], sizeof(up->ut_name)) == 0))
210: return(1);
211: return(0);
212: }
213: print()
214: {
215: register struct utmp *up;
216: register int n;
217: time_t ttime, t;
218: int namecomp();
219: qsort(ubuf, nnames, sizeof(ubuf[0]), namecomp);
220: ttime = 0;
221: up = ubuf;
222: if ((n = nnames) > 0) do {
223: ttime += up->ut_time;
224: if (pflag && up->ut_time != 0)
225: printf("\t%-8.8s%6.2f\n",
226: up->ut_name, (double)up->ut_time/3600);
227: *up->ut_name = '\0';
228: up++;
229: } while (--n);
230: nnames = 0;
231: if (ttime != 0) {
232: if (byday) {
233: t = stoptime-1;
234: printf("%.6s", ctime(&t)+4);
235: }
236: printf("\ttotal%9.2f\n", (double)ttime/3600);
237: }
238: fflush((&_iob[1]));
239: }
240: namecomp(up1, up2)
241: register struct utmp *up1, *up2;
242: {
243: return( strncmp(up1->ut_name, up2->ut_name, sizeof(up1->ut_name)));
244: }
245: time_t
246: nexttime(t)
247: time_t t;
248: {
249: register int curday;
250: time_t n;
251: curday = localtime(&t)->tm_yday;
252: for (n = 86400L; n; n >>= 1) {
253: do {
254: t += n;
255: } while (curday == localtime(&t)->tm_yday);
256: t -= n;
257: }
258: return(t+1);
259: }
260: time_t
261: prevtime(t)
262: time_t t;
263: {
264: register int curday;
265: time_t n;
266: curday = localtime(&t)->tm_yday;
267: for (n = 86400L; n; n >>= 1) {
268: do {
269: t -= n;
270: } while (curday == localtime(&t)->tm_yday);
271: t += n;
272: }
273: return(t);
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.