148342Sbostic /*-
2*61770Sbostic * Copyright (c) 1982, 1993
3*61770Sbostic * The Regents of the University of California. All rights reserved.
448342Sbostic *
548342Sbostic * %sccs.include.proprietary.c%
648342Sbostic */
748342Sbostic
813605Ssam #ifndef lint
9*61770Sbostic static char copyright[] =
10*61770Sbostic "@(#) Copyright (c) 1982, 1993\n\
11*61770Sbostic The Regents of the University of California. All rights reserved.\n";
1248342Sbostic #endif /* not lint */
1348342Sbostic
1448342Sbostic #ifndef lint
15*61770Sbostic static char sccsid[] = "@(#)ac.c 8.1 (Berkeley) 06/06/93";
1648342Sbostic #endif /* not lint */
1748342Sbostic
18946Sbill /*
197318Swnj * ac [ -w wtmp ] [ -d ] [ -p ] [ people ]
20946Sbill */
21946Sbill
2237254Sbostic #include <sys/time.h>
2337254Sbostic #include <sys/types.h>
2437254Sbostic #include <sys/timeb.h>
25946Sbill #include <stdio.h>
26946Sbill #include <ctype.h>
27946Sbill #include <utmp.h>
28946Sbill
2937254Sbostic #define NMAX UT_NAMESIZE
3037254Sbostic #define LMAX UT_LINESIZE
31946Sbill
325781Sroot /*
33946Sbill #define TSIZE 1000
345781Sroot */
355781Sroot #define TSIZE 6242
36946Sbill #define USIZE 500
37946Sbill struct utmp ibuf;
38946Sbill
39946Sbill struct ubuf {
40946Sbill char uname[NMAX];
41946Sbill long utime;
42946Sbill } ubuf[USIZE];
43946Sbill
44946Sbill struct tbuf {
45946Sbill struct ubuf *userp;
46946Sbill long ttime;
47946Sbill } tbuf[TSIZE];
48946Sbill
49946Sbill char *wtmp;
50946Sbill int pflag, byday;
51946Sbill long dtime;
52946Sbill long midnight;
53946Sbill long lastime;
54946Sbill long day = 86400L;
55946Sbill int pcount;
56946Sbill char **pptr;
57946Sbill
main(argc,argv)58946Sbill main(argc, argv)
59946Sbill char **argv;
60946Sbill {
61946Sbill int c, fl;
62946Sbill register i;
63946Sbill FILE *wf;
64946Sbill
6537254Sbostic wtmp = _PATH_WTMP;
66946Sbill while (--argc > 0 && **++argv == '-')
67946Sbill switch(*++*argv) {
68946Sbill case 'd':
69946Sbill byday++;
70946Sbill continue;
71946Sbill
72946Sbill case 'w':
73946Sbill if (--argc>0)
74946Sbill wtmp = *++argv;
75946Sbill continue;
76946Sbill
77946Sbill case 'p':
78946Sbill pflag++;
79946Sbill continue;
80946Sbill }
81946Sbill pcount = argc;
82946Sbill pptr = argv;
83946Sbill if ((wf = fopen(wtmp, "r")) == NULL) {
84946Sbill printf("No %s\n", wtmp);
85946Sbill exit(1);
86946Sbill }
87946Sbill for(;;) {
88946Sbill if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1)
89946Sbill break;
90946Sbill fl = 0;
91946Sbill for (i=0; i<NMAX; i++) {
92946Sbill c = ibuf.ut_name[i];
933922Sbugs if (isprint(c) && c != ' ') {
94946Sbill if (fl)
95946Sbill goto skip;
96946Sbill continue;
97946Sbill }
98946Sbill if (c==' ' || c=='\0') {
99946Sbill fl++;
100946Sbill ibuf.ut_name[i] = '\0';
101946Sbill } else
102946Sbill goto skip;
103946Sbill }
104946Sbill loop();
105946Sbill skip:;
106946Sbill }
107946Sbill ibuf.ut_name[0] = '\0';
108946Sbill ibuf.ut_line[0] = '~';
109946Sbill time(&ibuf.ut_time);
110946Sbill loop();
111946Sbill print();
112946Sbill exit(0);
113946Sbill }
114946Sbill
loop()115946Sbill loop()
116946Sbill {
117946Sbill register i;
118946Sbill register struct tbuf *tp;
119946Sbill register struct ubuf *up;
120946Sbill
121946Sbill if(ibuf.ut_line[0] == '|') {
122946Sbill dtime = ibuf.ut_time;
123946Sbill return;
124946Sbill }
1257317Sroot if(ibuf.ut_line[0] == '{') {
126946Sbill if(dtime == 0)
127946Sbill return;
128946Sbill for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)
129946Sbill tp->ttime += ibuf.ut_time-dtime;
130946Sbill dtime = 0;
131946Sbill return;
132946Sbill }
133946Sbill if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time)
134946Sbill midnight = 0;
135946Sbill if (midnight==0)
136946Sbill newday();
137946Sbill lastime = ibuf.ut_time;
138946Sbill if (byday && ibuf.ut_time > midnight) {
139946Sbill upall(1);
140946Sbill print();
141946Sbill newday();
142946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++)
143946Sbill up->utime = 0;
144946Sbill }
145946Sbill if (ibuf.ut_line[0] == '~') {
146946Sbill ibuf.ut_name[0] = '\0';
147946Sbill upall(0);
148946Sbill return;
149946Sbill }
1505781Sroot /*
151946Sbill if (ibuf.ut_line[0]=='t')
152946Sbill i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0');
153946Sbill else
154946Sbill i = TSIZE-1;
155946Sbill if (i<0 || i>=TSIZE)
156946Sbill i = TSIZE-1;
1575781Sroot */
1585781Sroot
1595781Sroot /*
1605781Sroot * Correction contributed by Phyllis Kantar @ Rand-unix
1615781Sroot *
1625781Sroot * Fixes long standing problem with tty names other than 00-99
1635781Sroot */
1645781Sroot if (ibuf.ut_line[0]=='t') {
1655781Sroot i = (ibuf.ut_line[3]-'0');
1665781Sroot if(ibuf.ut_line[4])
1675781Sroot i = i*79 + (ibuf.ut_line[4]-'0');
1685781Sroot } else
1695781Sroot i = TSIZE-1;
1705781Sroot if (i<0 || i>=TSIZE) {
1715781Sroot i = TSIZE-1;
1725781Sroot printf("ac: Bad tty name: %s\n", ibuf.ut_line);
1735781Sroot }
1745781Sroot
175946Sbill tp = &tbuf[i];
176946Sbill update(tp, 0);
177946Sbill }
178946Sbill
print()179946Sbill print()
180946Sbill {
181946Sbill int i;
182946Sbill long ttime, t;
183946Sbill
184946Sbill ttime = 0;
185946Sbill for (i=0; i<USIZE; i++) {
186946Sbill if(!among(i))
187946Sbill continue;
188946Sbill t = ubuf[i].utime;
189946Sbill if (t>0)
190946Sbill ttime += t;
191946Sbill if (pflag && ubuf[i].utime > 0) {
19236303Smckusick printf("\t%-*.*s %6.2f\n", NMAX, NMAX,
193946Sbill ubuf[i].uname, ubuf[i].utime/3600.);
194946Sbill }
195946Sbill }
196946Sbill if (ttime > 0) {
197946Sbill pdate();
19836303Smckusick printf("\ttotal %9.2f\n", ttime/3600.);
199946Sbill }
200946Sbill }
201946Sbill
upall(f)202946Sbill upall(f)
203946Sbill {
204946Sbill register struct tbuf *tp;
205946Sbill
206946Sbill for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
207946Sbill update(tp, f);
208946Sbill }
209946Sbill
210946Sbill update(tp, f)
211946Sbill struct tbuf *tp;
212946Sbill {
213946Sbill int j;
214946Sbill struct ubuf *up;
215946Sbill long t, t1;
216946Sbill
217946Sbill if (f)
218946Sbill t = midnight;
219946Sbill else
220946Sbill t = ibuf.ut_time;
221946Sbill if (tp->userp) {
222946Sbill t1 = t - tp->ttime;
2233928Sroot if (t1 > 0)
224946Sbill tp->userp->utime += t1;
225946Sbill }
226946Sbill tp->ttime = t;
227946Sbill if (f)
228946Sbill return;
229946Sbill if (ibuf.ut_name[0]=='\0') {
230946Sbill tp->userp = 0;
231946Sbill return;
232946Sbill }
233946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++) {
234946Sbill if (up->uname[0] == '\0')
235946Sbill break;
236946Sbill for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++);
237946Sbill if (j>=NMAX)
238946Sbill break;
239946Sbill }
240946Sbill for (j=0; j<NMAX; j++)
241946Sbill up->uname[j] = ibuf.ut_name[j];
242946Sbill tp->userp = up;
243946Sbill }
244946Sbill
among(i)245946Sbill among(i)
246946Sbill {
247946Sbill register j, k;
248946Sbill register char *p;
249946Sbill
250946Sbill if (pcount==0)
251946Sbill return(1);
252946Sbill for (j=0; j<pcount; j++) {
253946Sbill p = pptr[j];
254946Sbill for (k=0; k<NMAX; k++) {
255946Sbill if (*p == ubuf[i].uname[k]) {
2563922Sbugs if (*p++ == '\0' || k == NMAX-1)
257946Sbill return(1);
258946Sbill } else
259946Sbill break;
260946Sbill }
261946Sbill }
262946Sbill return(0);
263946Sbill }
264946Sbill
newday()265946Sbill newday()
266946Sbill {
267946Sbill long ttime;
268946Sbill struct timeb tb;
269946Sbill struct tm *localtime();
270946Sbill
271946Sbill time(&ttime);
272946Sbill if (midnight == 0) {
273946Sbill ftime(&tb);
274946Sbill midnight = 60*(long)tb.timezone;
275946Sbill if (localtime(&ttime)->tm_isdst)
276946Sbill midnight -= 3600;
277946Sbill }
278946Sbill while (midnight <= ibuf.ut_time)
279946Sbill midnight += day;
280946Sbill }
281946Sbill
pdate()282946Sbill pdate()
283946Sbill {
284946Sbill long x;
285946Sbill char *ctime();
286946Sbill
287946Sbill if (byday==0)
288946Sbill return;
289946Sbill x = midnight-1;
290946Sbill printf("%.6s", ctime(&x)+4);
291946Sbill }
292