xref: /original-bsd/usr.sbin/ac/ac.c (revision 1a52a219)
16254407bSbostic /*-
2*1a52a219Sbostic  * Copyright (c) 1982, 1993
3*1a52a219Sbostic  *	The Regents of the University of California.  All rights reserved.
46254407bSbostic  *
56254407bSbostic  * %sccs.include.proprietary.c%
66254407bSbostic  */
76254407bSbostic 
81bbff716Ssam #ifndef lint
9*1a52a219Sbostic static char copyright[] =
10*1a52a219Sbostic "@(#) Copyright (c) 1982, 1993\n\
11*1a52a219Sbostic 	The Regents of the University of California.  All rights reserved.\n";
126254407bSbostic #endif /* not lint */
136254407bSbostic 
146254407bSbostic #ifndef lint
15*1a52a219Sbostic static char sccsid[] = "@(#)ac.c	8.1 (Berkeley) 06/06/93";
166254407bSbostic #endif /* not lint */
176254407bSbostic 
189d6523e4Sbill /*
19750da0faSwnj  * ac [ -w wtmp ] [ -d ] [ -p ] [ people ]
209d6523e4Sbill  */
219d6523e4Sbill 
221bbff716Ssam #include <sys/time.h>
239d6523e4Sbill #include <sys/types.h>
249d6523e4Sbill #include <sys/timeb.h>
25afe232bfSbostic #include <stdio.h>
26afe232bfSbostic #include <ctype.h>
27afe232bfSbostic #include <utmp.h>
289d6523e4Sbill 
29afe232bfSbostic #define NMAX UT_NAMESIZE
30afe232bfSbostic #define LMAX UT_LINESIZE
319d6523e4Sbill 
32cf16ede5Sroot /*
339d6523e4Sbill #define	TSIZE	1000
34cf16ede5Sroot */
35cf16ede5Sroot #define TSIZE  6242
369d6523e4Sbill #define	USIZE	500
379d6523e4Sbill struct  utmp ibuf;
389d6523e4Sbill 
399d6523e4Sbill struct ubuf {
409d6523e4Sbill 	char	uname[NMAX];
419d6523e4Sbill 	long	utime;
429d6523e4Sbill } ubuf[USIZE];
439d6523e4Sbill 
449d6523e4Sbill struct tbuf {
459d6523e4Sbill 	struct	ubuf	*userp;
469d6523e4Sbill 	long	ttime;
479d6523e4Sbill } tbuf[TSIZE];
489d6523e4Sbill 
499d6523e4Sbill char	*wtmp;
509d6523e4Sbill int	pflag, byday;
519d6523e4Sbill long	dtime;
529d6523e4Sbill long	midnight;
539d6523e4Sbill long	lastime;
549d6523e4Sbill long	day	= 86400L;
559d6523e4Sbill int	pcount;
569d6523e4Sbill char	**pptr;
579d6523e4Sbill 
main(argc,argv)589d6523e4Sbill main(argc, argv)
599d6523e4Sbill char **argv;
609d6523e4Sbill {
619d6523e4Sbill 	int c, fl;
629d6523e4Sbill 	register i;
639d6523e4Sbill 	FILE *wf;
649d6523e4Sbill 
65afe232bfSbostic 	wtmp = _PATH_WTMP;
669d6523e4Sbill 	while (--argc > 0 && **++argv == '-')
679d6523e4Sbill 	switch(*++*argv) {
689d6523e4Sbill 	case 'd':
699d6523e4Sbill 		byday++;
709d6523e4Sbill 		continue;
719d6523e4Sbill 
729d6523e4Sbill 	case 'w':
739d6523e4Sbill 		if (--argc>0)
749d6523e4Sbill 			wtmp = *++argv;
759d6523e4Sbill 		continue;
769d6523e4Sbill 
779d6523e4Sbill 	case 'p':
789d6523e4Sbill 		pflag++;
799d6523e4Sbill 		continue;
809d6523e4Sbill 	}
819d6523e4Sbill 	pcount = argc;
829d6523e4Sbill 	pptr = argv;
839d6523e4Sbill 	if ((wf = fopen(wtmp, "r")) == NULL) {
849d6523e4Sbill 		printf("No %s\n", wtmp);
859d6523e4Sbill 		exit(1);
869d6523e4Sbill 	}
879d6523e4Sbill 	for(;;) {
889d6523e4Sbill 		if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1)
899d6523e4Sbill 			break;
909d6523e4Sbill 		fl = 0;
919d6523e4Sbill 		for (i=0; i<NMAX; i++) {
929d6523e4Sbill 			c = ibuf.ut_name[i];
93eadc6437Sbugs 			if (isprint(c) && c != ' ') {
949d6523e4Sbill 				if (fl)
959d6523e4Sbill 					goto skip;
969d6523e4Sbill 				continue;
979d6523e4Sbill 			}
989d6523e4Sbill 			if (c==' ' || c=='\0') {
999d6523e4Sbill 				fl++;
1009d6523e4Sbill 				ibuf.ut_name[i] = '\0';
1019d6523e4Sbill 			} else
1029d6523e4Sbill 				goto skip;
1039d6523e4Sbill 		}
1049d6523e4Sbill 		loop();
1059d6523e4Sbill     skip:;
1069d6523e4Sbill 	}
1079d6523e4Sbill 	ibuf.ut_name[0] = '\0';
1089d6523e4Sbill 	ibuf.ut_line[0] = '~';
1099d6523e4Sbill 	time(&ibuf.ut_time);
1109d6523e4Sbill 	loop();
1119d6523e4Sbill 	print();
1129d6523e4Sbill 	exit(0);
1139d6523e4Sbill }
1149d6523e4Sbill 
loop()1159d6523e4Sbill loop()
1169d6523e4Sbill {
1179d6523e4Sbill 	register i;
1189d6523e4Sbill 	register struct tbuf *tp;
1199d6523e4Sbill 	register struct ubuf *up;
1209d6523e4Sbill 
1219d6523e4Sbill 	if(ibuf.ut_line[0] == '|') {
1229d6523e4Sbill 		dtime = ibuf.ut_time;
1239d6523e4Sbill 		return;
1249d6523e4Sbill 	}
125e4f5d788Sroot 	if(ibuf.ut_line[0] == '{') {
1269d6523e4Sbill 		if(dtime == 0)
1279d6523e4Sbill 			return;
1289d6523e4Sbill 		for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)
1299d6523e4Sbill 			tp->ttime += ibuf.ut_time-dtime;
1309d6523e4Sbill 		dtime = 0;
1319d6523e4Sbill 		return;
1329d6523e4Sbill 	}
1339d6523e4Sbill 	if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time)
1349d6523e4Sbill 		midnight = 0;
1359d6523e4Sbill 	if (midnight==0)
1369d6523e4Sbill 		newday();
1379d6523e4Sbill 	lastime = ibuf.ut_time;
1389d6523e4Sbill 	if (byday && ibuf.ut_time > midnight) {
1399d6523e4Sbill 		upall(1);
1409d6523e4Sbill 		print();
1419d6523e4Sbill 		newday();
1429d6523e4Sbill 		for (up=ubuf; up < &ubuf[USIZE]; up++)
1439d6523e4Sbill 			up->utime = 0;
1449d6523e4Sbill 	}
1459d6523e4Sbill 	if (ibuf.ut_line[0] == '~') {
1469d6523e4Sbill 		ibuf.ut_name[0] = '\0';
1479d6523e4Sbill 		upall(0);
1489d6523e4Sbill 		return;
1499d6523e4Sbill 	}
150cf16ede5Sroot 	/*
1519d6523e4Sbill 	if (ibuf.ut_line[0]=='t')
1529d6523e4Sbill 		i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0');
1539d6523e4Sbill 	else
1549d6523e4Sbill 		i = TSIZE-1;
1559d6523e4Sbill 	if (i<0 || i>=TSIZE)
1569d6523e4Sbill 		i = TSIZE-1;
157cf16ede5Sroot 	*/
158cf16ede5Sroot 
159cf16ede5Sroot 	/*
160cf16ede5Sroot 	 * Correction contributed by Phyllis Kantar @ Rand-unix
161cf16ede5Sroot 	 *
162cf16ede5Sroot 	 * Fixes long standing problem with tty names other than 00-99
163cf16ede5Sroot 	 */
164cf16ede5Sroot 	if (ibuf.ut_line[0]=='t') {
165cf16ede5Sroot 		i = (ibuf.ut_line[3]-'0');
166cf16ede5Sroot 		if(ibuf.ut_line[4])
167cf16ede5Sroot 			i = i*79 + (ibuf.ut_line[4]-'0');
168cf16ede5Sroot 	} else
169cf16ede5Sroot 		i = TSIZE-1;
170cf16ede5Sroot 	if (i<0 || i>=TSIZE) {
171cf16ede5Sroot 		i = TSIZE-1;
172cf16ede5Sroot 		printf("ac: Bad tty name: %s\n", ibuf.ut_line);
173cf16ede5Sroot 	}
174cf16ede5Sroot 
1759d6523e4Sbill 	tp = &tbuf[i];
1769d6523e4Sbill 	update(tp, 0);
1779d6523e4Sbill }
1789d6523e4Sbill 
print()1799d6523e4Sbill print()
1809d6523e4Sbill {
1819d6523e4Sbill 	int i;
1829d6523e4Sbill 	long ttime, t;
1839d6523e4Sbill 
1849d6523e4Sbill 	ttime = 0;
1859d6523e4Sbill 	for (i=0; i<USIZE; i++) {
1869d6523e4Sbill 		if(!among(i))
1879d6523e4Sbill 			continue;
1889d6523e4Sbill 		t = ubuf[i].utime;
1899d6523e4Sbill 		if (t>0)
1909d6523e4Sbill 			ttime += t;
1919d6523e4Sbill 		if (pflag && ubuf[i].utime > 0) {
1929d6523e4Sbill 			printf("\t%-*.*s %6.2f\n", NMAX, NMAX,
1939d6523e4Sbill 			    ubuf[i].uname, ubuf[i].utime/3600.);
1949d6523e4Sbill 		}
1959d6523e4Sbill 	}
1969d6523e4Sbill 	if (ttime > 0) {
1979d6523e4Sbill 		pdate();
1989d6523e4Sbill 		printf("\ttotal %9.2f\n", ttime/3600.);
1999d6523e4Sbill 	}
2009d6523e4Sbill }
2019d6523e4Sbill 
upall(f)2029d6523e4Sbill upall(f)
2039d6523e4Sbill {
2049d6523e4Sbill 	register struct tbuf *tp;
2059d6523e4Sbill 
2069d6523e4Sbill 	for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
2079d6523e4Sbill 		update(tp, f);
2089d6523e4Sbill }
2099d6523e4Sbill 
2109d6523e4Sbill update(tp, f)
2119d6523e4Sbill struct tbuf *tp;
2129d6523e4Sbill {
2139d6523e4Sbill 	int j;
2149d6523e4Sbill 	struct ubuf *up;
2159d6523e4Sbill 	long t, t1;
2169d6523e4Sbill 
2179d6523e4Sbill 	if (f)
2189d6523e4Sbill 		t = midnight;
2199d6523e4Sbill 	else
2209d6523e4Sbill 		t = ibuf.ut_time;
2219d6523e4Sbill 	if (tp->userp) {
2229d6523e4Sbill 		t1 = t - tp->ttime;
2232b67554cSroot 		if (t1 > 0)
2249d6523e4Sbill 			tp->userp->utime += t1;
2259d6523e4Sbill 	}
2269d6523e4Sbill 	tp->ttime = t;
2279d6523e4Sbill 	if (f)
2289d6523e4Sbill 		return;
2299d6523e4Sbill 	if (ibuf.ut_name[0]=='\0') {
2309d6523e4Sbill 		tp->userp = 0;
2319d6523e4Sbill 		return;
2329d6523e4Sbill 	}
2339d6523e4Sbill 	for (up=ubuf; up < &ubuf[USIZE]; up++) {
2349d6523e4Sbill 		if (up->uname[0] == '\0')
2359d6523e4Sbill 			break;
2369d6523e4Sbill 		for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++);
2379d6523e4Sbill 		if (j>=NMAX)
2389d6523e4Sbill 			break;
2399d6523e4Sbill 	}
2409d6523e4Sbill 	for (j=0; j<NMAX; j++)
2419d6523e4Sbill 		up->uname[j] = ibuf.ut_name[j];
2429d6523e4Sbill 	tp->userp = up;
2439d6523e4Sbill }
2449d6523e4Sbill 
among(i)2459d6523e4Sbill among(i)
2469d6523e4Sbill {
2479d6523e4Sbill 	register j, k;
2489d6523e4Sbill 	register char *p;
2499d6523e4Sbill 
2509d6523e4Sbill 	if (pcount==0)
2519d6523e4Sbill 		return(1);
2529d6523e4Sbill 	for (j=0; j<pcount; j++) {
2539d6523e4Sbill 		p = pptr[j];
2549d6523e4Sbill 		for (k=0; k<NMAX; k++) {
2559d6523e4Sbill 			if (*p == ubuf[i].uname[k]) {
256eadc6437Sbugs 				if (*p++ == '\0' || k == NMAX-1)
2579d6523e4Sbill 					return(1);
2589d6523e4Sbill 			} else
2599d6523e4Sbill 				break;
2609d6523e4Sbill 		}
2619d6523e4Sbill 	}
2629d6523e4Sbill 	return(0);
2639d6523e4Sbill }
2649d6523e4Sbill 
newday()2659d6523e4Sbill newday()
2669d6523e4Sbill {
2679d6523e4Sbill 	long ttime;
2689d6523e4Sbill 	struct timeb tb;
2699d6523e4Sbill 	struct tm *localtime();
2709d6523e4Sbill 
2719d6523e4Sbill 	time(&ttime);
2729d6523e4Sbill 	if (midnight == 0) {
2739d6523e4Sbill 		ftime(&tb);
2749d6523e4Sbill 		midnight = 60*(long)tb.timezone;
2759d6523e4Sbill 		if (localtime(&ttime)->tm_isdst)
2769d6523e4Sbill 			midnight -= 3600;
2779d6523e4Sbill 	}
2789d6523e4Sbill 	while (midnight <= ibuf.ut_time)
2799d6523e4Sbill 		midnight += day;
2809d6523e4Sbill }
2819d6523e4Sbill 
pdate()2829d6523e4Sbill pdate()
2839d6523e4Sbill {
2849d6523e4Sbill 	long x;
2859d6523e4Sbill 	char *ctime();
2869d6523e4Sbill 
2879d6523e4Sbill 	if (byday==0)
2889d6523e4Sbill 		return;
2899d6523e4Sbill 	x = midnight-1;
2909d6523e4Sbill 	printf("%.6s", ctime(&x)+4);
2919d6523e4Sbill }
292