ANSI, minor cleanups
[unix-history] / usr / src / usr.sbin / ac / ac.c
CommitLineData
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
9char 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
15static 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
37struct utmp ibuf;
38
39struct ubuf {
40 char uname[NMAX];
41 long utime;
42} ubuf[USIZE];
43
44struct tbuf {
45 struct ubuf *userp;
46 long ttime;
47} tbuf[TSIZE];
48
49char *wtmp;
50int pflag, byday;
51long dtime;
52long midnight;
53long lastime;
54long day = 86400L;
55int pcount;
56char **pptr;
57
58main(argc, argv)
59char **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
115loop()
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
179print()
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
202upall(f)
203{
204 register struct tbuf *tp;
205
206 for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
207 update(tp, f);
208}
209
210update(tp, f)
211struct 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
245among(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
265newday()
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
282pdate()
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}