xref: /csrg-svn/usr.sbin/ac/ac.c (revision 61770)
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