Commit | Line | Data |
---|---|---|
8db15ac0 KB |
1 | /*- |
2 | * Copyright (c) 1982 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * %sccs.include.proprietary.c% | |
6 | */ | |
7 | ||
ce4fd43b | 8 | #ifndef lint |
8db15ac0 KB |
9 | char copyright[] = |
10 | "@(#) Copyright (c) 1982 The Regents of the University of California.\n\ | |
11 | All rights reserved.\n"; | |
12 | #endif /* not lint */ | |
13 | ||
14 | #ifndef lint | |
15 | static char sccsid[] = "@(#)ac.c 4.10 (Berkeley) %G%"; | |
16 | #endif /* not lint */ | |
17 | ||
d8722c26 | 18 | /* |
3faa52c2 | 19 | * ac [ -w wtmp ] [ -d ] [ -p ] [ people ] |
d8722c26 | 20 | */ |
d8722c26 | 21 | |
ce4fd43b | 22 | #include <sys/time.h> |
d8722c26 BJ |
23 | #include <sys/types.h> |
24 | #include <sys/timeb.h> | |
a47e4255 KB |
25 | #include <stdio.h> |
26 | #include <ctype.h> | |
27 | #include <utmp.h> | |
d8722c26 | 28 | |
a47e4255 KB |
29 | #define NMAX UT_NAMESIZE |
30 | #define LMAX UT_LINESIZE | |
d8722c26 | 31 | |
9ca9f840 | 32 | /* |
d8722c26 | 33 | #define TSIZE 1000 |
9ca9f840 BJ |
34 | */ |
35 | #define TSIZE 6242 | |
d8722c26 BJ |
36 | #define USIZE 500 |
37 | struct utmp ibuf; | |
38 | ||
39 | struct ubuf { | |
40 | char uname[NMAX]; | |
41 | long utime; | |
42 | } ubuf[USIZE]; | |
43 | ||
44 | struct tbuf { | |
45 | struct ubuf *userp; | |
46 | long ttime; | |
47 | } tbuf[TSIZE]; | |
48 | ||
49 | char *wtmp; | |
50 | int pflag, byday; | |
51 | long dtime; | |
52 | long midnight; | |
53 | long lastime; | |
54 | long day = 86400L; | |
55 | int pcount; | |
56 | char **pptr; | |
57 | ||
58 | main(argc, argv) | |
59 | char **argv; | |
60 | { | |
61 | int c, fl; | |
62 | register i; | |
63 | FILE *wf; | |
64 | ||
a47e4255 | 65 | wtmp = _PATH_WTMP; |
d8722c26 BJ |
66 | while (--argc > 0 && **++argv == '-') |
67 | switch(*++*argv) { | |
68 | case 'd': | |
69 | byday++; | |
70 | continue; | |
71 | ||
72 | case 'w': | |
73 | if (--argc>0) | |
74 | wtmp = *++argv; | |
75 | continue; | |
76 | ||
77 | case 'p': | |
78 | pflag++; | |
79 | continue; | |
80 | } | |
81 | pcount = argc; | |
82 | pptr = argv; | |
83 | if ((wf = fopen(wtmp, "r")) == NULL) { | |
84 | printf("No %s\n", wtmp); | |
85 | exit(1); | |
86 | } | |
87 | for(;;) { | |
88 | if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1) | |
89 | break; | |
90 | fl = 0; | |
91 | for (i=0; i<NMAX; i++) { | |
92 | c = ibuf.ut_name[i]; | |
d1dda358 | 93 | if (isprint(c) && c != ' ') { |
d8722c26 BJ |
94 | if (fl) |
95 | goto skip; | |
96 | continue; | |
97 | } | |
98 | if (c==' ' || c=='\0') { | |
99 | fl++; | |
100 | ibuf.ut_name[i] = '\0'; | |
101 | } else | |
102 | goto skip; | |
103 | } | |
104 | loop(); | |
105 | skip:; | |
106 | } | |
107 | ibuf.ut_name[0] = '\0'; | |
108 | ibuf.ut_line[0] = '~'; | |
109 | time(&ibuf.ut_time); | |
110 | loop(); | |
111 | print(); | |
112 | exit(0); | |
113 | } | |
114 | ||
115 | loop() | |
116 | { | |
117 | register i; | |
118 | register struct tbuf *tp; | |
119 | register struct ubuf *up; | |
120 | ||
121 | if(ibuf.ut_line[0] == '|') { | |
122 | dtime = ibuf.ut_time; | |
123 | return; | |
124 | } | |
da7adf06 | 125 | if(ibuf.ut_line[0] == '{') { |
d8722c26 BJ |
126 | if(dtime == 0) |
127 | return; | |
128 | for(tp = tbuf; tp < &tbuf[TSIZE]; tp++) | |
129 | tp->ttime += ibuf.ut_time-dtime; | |
130 | dtime = 0; | |
131 | return; | |
132 | } | |
133 | if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time) | |
134 | midnight = 0; | |
135 | if (midnight==0) | |
136 | newday(); | |
137 | lastime = ibuf.ut_time; | |
138 | if (byday && ibuf.ut_time > midnight) { | |
139 | upall(1); | |
140 | print(); | |
141 | newday(); | |
142 | for (up=ubuf; up < &ubuf[USIZE]; up++) | |
143 | up->utime = 0; | |
144 | } | |
145 | if (ibuf.ut_line[0] == '~') { | |
146 | ibuf.ut_name[0] = '\0'; | |
147 | upall(0); | |
148 | return; | |
149 | } | |
9ca9f840 | 150 | /* |
d8722c26 BJ |
151 | if (ibuf.ut_line[0]=='t') |
152 | i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0'); | |
153 | else | |
154 | i = TSIZE-1; | |
155 | if (i<0 || i>=TSIZE) | |
156 | i = TSIZE-1; | |
9ca9f840 BJ |
157 | */ |
158 | ||
159 | /* | |
160 | * Correction contributed by Phyllis Kantar @ Rand-unix | |
161 | * | |
162 | * Fixes long standing problem with tty names other than 00-99 | |
163 | */ | |
164 | if (ibuf.ut_line[0]=='t') { | |
165 | i = (ibuf.ut_line[3]-'0'); | |
166 | if(ibuf.ut_line[4]) | |
167 | i = i*79 + (ibuf.ut_line[4]-'0'); | |
168 | } else | |
169 | i = TSIZE-1; | |
170 | if (i<0 || i>=TSIZE) { | |
171 | i = TSIZE-1; | |
172 | printf("ac: Bad tty name: %s\n", ibuf.ut_line); | |
173 | } | |
174 | ||
d8722c26 BJ |
175 | tp = &tbuf[i]; |
176 | update(tp, 0); | |
177 | } | |
178 | ||
179 | print() | |
180 | { | |
181 | int i; | |
182 | long ttime, t; | |
183 | ||
184 | ttime = 0; | |
185 | for (i=0; i<USIZE; i++) { | |
186 | if(!among(i)) | |
187 | continue; | |
188 | t = ubuf[i].utime; | |
189 | if (t>0) | |
190 | ttime += t; | |
191 | if (pflag && ubuf[i].utime > 0) { | |
b02f6ab1 | 192 | printf("\t%-*.*s %6.2f\n", NMAX, NMAX, |
d8722c26 BJ |
193 | ubuf[i].uname, ubuf[i].utime/3600.); |
194 | } | |
195 | } | |
196 | if (ttime > 0) { | |
197 | pdate(); | |
b02f6ab1 | 198 | printf("\ttotal %9.2f\n", ttime/3600.); |
d8722c26 BJ |
199 | } |
200 | } | |
201 | ||
202 | upall(f) | |
203 | { | |
204 | register struct tbuf *tp; | |
205 | ||
206 | for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) | |
207 | update(tp, f); | |
208 | } | |
209 | ||
210 | update(tp, f) | |
211 | struct tbuf *tp; | |
212 | { | |
213 | int j; | |
214 | struct ubuf *up; | |
215 | long t, t1; | |
216 | ||
217 | if (f) | |
218 | t = midnight; | |
219 | else | |
220 | t = ibuf.ut_time; | |
221 | if (tp->userp) { | |
222 | t1 = t - tp->ttime; | |
bfcd1904 | 223 | if (t1 > 0) |
d8722c26 BJ |
224 | tp->userp->utime += t1; |
225 | } | |
226 | tp->ttime = t; | |
227 | if (f) | |
228 | return; | |
229 | if (ibuf.ut_name[0]=='\0') { | |
230 | tp->userp = 0; | |
231 | return; | |
232 | } | |
233 | for (up=ubuf; up < &ubuf[USIZE]; up++) { | |
234 | if (up->uname[0] == '\0') | |
235 | break; | |
236 | for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++); | |
237 | if (j>=NMAX) | |
238 | break; | |
239 | } | |
240 | for (j=0; j<NMAX; j++) | |
241 | up->uname[j] = ibuf.ut_name[j]; | |
242 | tp->userp = up; | |
243 | } | |
244 | ||
245 | among(i) | |
246 | { | |
247 | register j, k; | |
248 | register char *p; | |
249 | ||
250 | if (pcount==0) | |
251 | return(1); | |
252 | for (j=0; j<pcount; j++) { | |
253 | p = pptr[j]; | |
254 | for (k=0; k<NMAX; k++) { | |
255 | if (*p == ubuf[i].uname[k]) { | |
d1dda358 | 256 | if (*p++ == '\0' || k == NMAX-1) |
d8722c26 BJ |
257 | return(1); |
258 | } else | |
259 | break; | |
260 | } | |
261 | } | |
262 | return(0); | |
263 | } | |
264 | ||
265 | newday() | |
266 | { | |
267 | long ttime; | |
268 | struct timeb tb; | |
269 | struct tm *localtime(); | |
270 | ||
271 | time(&ttime); | |
272 | if (midnight == 0) { | |
273 | ftime(&tb); | |
274 | midnight = 60*(long)tb.timezone; | |
275 | if (localtime(&ttime)->tm_isdst) | |
276 | midnight -= 3600; | |
277 | } | |
278 | while (midnight <= ibuf.ut_time) | |
279 | midnight += day; | |
280 | } | |
281 | ||
282 | pdate() | |
283 | { | |
284 | long x; | |
285 | char *ctime(); | |
286 | ||
287 | if (byday==0) | |
288 | return; | |
289 | x = midnight-1; | |
290 | printf("%.6s", ctime(&x)+4); | |
291 | } |