xref: /csrg-svn/usr.sbin/ac/ac.c (revision 946)
1*946Sbill /*
2*946Sbill  * acct [ -w wtmp ] [ -d ] [ -p ] [ people ]
3*946Sbill  */
4*946Sbill static char *sccsid = "@(#)ac.c	4.1 (Berkeley) 10/01/80";
5*946Sbill 
6*946Sbill #include <stdio.h>
7*946Sbill #include <ctype.h>
8*946Sbill #include <time.h>
9*946Sbill #include <utmp.h>
10*946Sbill #include <sys/types.h>
11*946Sbill #include <sys/timeb.h>
12*946Sbill 
13*946Sbill #define NMAX sizeof(ibuf.ut_name)
14*946Sbill #define LMAX sizeof(ibuf.ut_line)
15*946Sbill 
16*946Sbill #define	TSIZE	1000
17*946Sbill #define	USIZE	500
18*946Sbill struct  utmp ibuf;
19*946Sbill 
20*946Sbill struct ubuf {
21*946Sbill 	char	uname[NMAX];
22*946Sbill 	long	utime;
23*946Sbill } ubuf[USIZE];
24*946Sbill 
25*946Sbill struct tbuf {
26*946Sbill 	struct	ubuf	*userp;
27*946Sbill 	long	ttime;
28*946Sbill } tbuf[TSIZE];
29*946Sbill 
30*946Sbill char	*wtmp;
31*946Sbill int	pflag, byday;
32*946Sbill long	dtime;
33*946Sbill long	midnight;
34*946Sbill long	lastime;
35*946Sbill long	day	= 86400L;
36*946Sbill int	pcount;
37*946Sbill char	**pptr;
38*946Sbill 
39*946Sbill main(argc, argv)
40*946Sbill char **argv;
41*946Sbill {
42*946Sbill 	int c, fl;
43*946Sbill 	register i;
44*946Sbill 	FILE *wf;
45*946Sbill 
46*946Sbill 	wtmp = "/usr/adm/wtmp";
47*946Sbill 	while (--argc > 0 && **++argv == '-')
48*946Sbill 	switch(*++*argv) {
49*946Sbill 	case 'd':
50*946Sbill 		byday++;
51*946Sbill 		continue;
52*946Sbill 
53*946Sbill 	case 'w':
54*946Sbill 		if (--argc>0)
55*946Sbill 			wtmp = *++argv;
56*946Sbill 		continue;
57*946Sbill 
58*946Sbill 	case 'p':
59*946Sbill 		pflag++;
60*946Sbill 		continue;
61*946Sbill 	}
62*946Sbill 	pcount = argc;
63*946Sbill 	pptr = argv;
64*946Sbill 	if ((wf = fopen(wtmp, "r")) == NULL) {
65*946Sbill 		printf("No %s\n", wtmp);
66*946Sbill 		exit(1);
67*946Sbill 	}
68*946Sbill 	for(;;) {
69*946Sbill 		if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1)
70*946Sbill 			break;
71*946Sbill 		fl = 0;
72*946Sbill 		for (i=0; i<NMAX; i++) {
73*946Sbill 			c = ibuf.ut_name[i];
74*946Sbill 			if(isdigit(c) || isalpha(c)) {
75*946Sbill 				if (fl)
76*946Sbill 					goto skip;
77*946Sbill 				continue;
78*946Sbill 			}
79*946Sbill 			if (c==' ' || c=='\0') {
80*946Sbill 				fl++;
81*946Sbill 				ibuf.ut_name[i] = '\0';
82*946Sbill 			} else
83*946Sbill 				goto skip;
84*946Sbill 		}
85*946Sbill 		loop();
86*946Sbill     skip:;
87*946Sbill 	}
88*946Sbill 	ibuf.ut_name[0] = '\0';
89*946Sbill 	ibuf.ut_line[0] = '~';
90*946Sbill 	time(&ibuf.ut_time);
91*946Sbill 	loop();
92*946Sbill 	print();
93*946Sbill 	exit(0);
94*946Sbill }
95*946Sbill 
96*946Sbill loop()
97*946Sbill {
98*946Sbill 	register i;
99*946Sbill 	register struct tbuf *tp;
100*946Sbill 	register struct ubuf *up;
101*946Sbill 
102*946Sbill 	if(ibuf.ut_line[0] == '|') {
103*946Sbill 		dtime = ibuf.ut_time;
104*946Sbill 		return;
105*946Sbill 	}
106*946Sbill 	if(ibuf.ut_line[0] == '}') {
107*946Sbill 		if(dtime == 0)
108*946Sbill 			return;
109*946Sbill 		for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)
110*946Sbill 			tp->ttime += ibuf.ut_time-dtime;
111*946Sbill 		dtime = 0;
112*946Sbill 		return;
113*946Sbill 	}
114*946Sbill 	if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time)
115*946Sbill 		midnight = 0;
116*946Sbill 	if (midnight==0)
117*946Sbill 		newday();
118*946Sbill 	lastime = ibuf.ut_time;
119*946Sbill 	if (byday && ibuf.ut_time > midnight) {
120*946Sbill 		upall(1);
121*946Sbill 		print();
122*946Sbill 		newday();
123*946Sbill 		for (up=ubuf; up < &ubuf[USIZE]; up++)
124*946Sbill 			up->utime = 0;
125*946Sbill 	}
126*946Sbill 	if (ibuf.ut_line[0] == '~') {
127*946Sbill 		ibuf.ut_name[0] = '\0';
128*946Sbill 		upall(0);
129*946Sbill 		return;
130*946Sbill 	}
131*946Sbill 	if (ibuf.ut_line[0]=='t')
132*946Sbill 		i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0');
133*946Sbill 	else
134*946Sbill 		i = TSIZE-1;
135*946Sbill 	if (i<0 || i>=TSIZE)
136*946Sbill 		i = TSIZE-1;
137*946Sbill 	tp = &tbuf[i];
138*946Sbill 	update(tp, 0);
139*946Sbill }
140*946Sbill 
141*946Sbill print()
142*946Sbill {
143*946Sbill 	int i;
144*946Sbill 	long ttime, t;
145*946Sbill 
146*946Sbill 	ttime = 0;
147*946Sbill 	for (i=0; i<USIZE; i++) {
148*946Sbill 		if(!among(i))
149*946Sbill 			continue;
150*946Sbill 		t = ubuf[i].utime;
151*946Sbill 		if (t>0)
152*946Sbill 			ttime += t;
153*946Sbill 		if (pflag && ubuf[i].utime > 0) {
154*946Sbill 			printf("\t%-*.*s%6.2f\n", NMAX, NMAX,
155*946Sbill 			    ubuf[i].uname, ubuf[i].utime/3600.);
156*946Sbill 		}
157*946Sbill 	}
158*946Sbill 	if (ttime > 0) {
159*946Sbill 		pdate();
160*946Sbill 		printf("\ttotal%9.2f\n", ttime/3600.);
161*946Sbill 	}
162*946Sbill }
163*946Sbill 
164*946Sbill upall(f)
165*946Sbill {
166*946Sbill 	register struct tbuf *tp;
167*946Sbill 
168*946Sbill 	for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
169*946Sbill 		update(tp, f);
170*946Sbill }
171*946Sbill 
172*946Sbill update(tp, f)
173*946Sbill struct tbuf *tp;
174*946Sbill {
175*946Sbill 	int j;
176*946Sbill 	struct ubuf *up;
177*946Sbill 	long t, t1;
178*946Sbill 
179*946Sbill 	if (f)
180*946Sbill 		t = midnight;
181*946Sbill 	else
182*946Sbill 		t = ibuf.ut_time;
183*946Sbill 	if (tp->userp) {
184*946Sbill 		t1 = t - tp->ttime;
185*946Sbill 		if (t1>0 && t1 < 1.5*day)
186*946Sbill 			tp->userp->utime += t1;
187*946Sbill 	}
188*946Sbill 	tp->ttime = t;
189*946Sbill 	if (f)
190*946Sbill 		return;
191*946Sbill 	if (ibuf.ut_name[0]=='\0') {
192*946Sbill 		tp->userp = 0;
193*946Sbill 		return;
194*946Sbill 	}
195*946Sbill 	for (up=ubuf; up < &ubuf[USIZE]; up++) {
196*946Sbill 		if (up->uname[0] == '\0')
197*946Sbill 			break;
198*946Sbill 		for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++);
199*946Sbill 		if (j>=NMAX)
200*946Sbill 			break;
201*946Sbill 	}
202*946Sbill 	for (j=0; j<NMAX; j++)
203*946Sbill 		up->uname[j] = ibuf.ut_name[j];
204*946Sbill 	tp->userp = up;
205*946Sbill }
206*946Sbill 
207*946Sbill among(i)
208*946Sbill {
209*946Sbill 	register j, k;
210*946Sbill 	register char *p;
211*946Sbill 
212*946Sbill 	if (pcount==0)
213*946Sbill 		return(1);
214*946Sbill 	for (j=0; j<pcount; j++) {
215*946Sbill 		p = pptr[j];
216*946Sbill 		for (k=0; k<NMAX; k++) {
217*946Sbill 			if (*p == ubuf[i].uname[k]) {
218*946Sbill 				if (*p++ == '\0')
219*946Sbill 					return(1);
220*946Sbill 			} else
221*946Sbill 				break;
222*946Sbill 		}
223*946Sbill 	}
224*946Sbill 	return(0);
225*946Sbill }
226*946Sbill 
227*946Sbill newday()
228*946Sbill {
229*946Sbill 	long ttime;
230*946Sbill 	struct timeb tb;
231*946Sbill 	struct tm *localtime();
232*946Sbill 
233*946Sbill 	time(&ttime);
234*946Sbill 	if (midnight == 0) {
235*946Sbill 		ftime(&tb);
236*946Sbill 		midnight = 60*(long)tb.timezone;
237*946Sbill 		if (localtime(&ttime)->tm_isdst)
238*946Sbill 			midnight -= 3600;
239*946Sbill 	}
240*946Sbill 	while (midnight <= ibuf.ut_time)
241*946Sbill 		midnight += day;
242*946Sbill }
243*946Sbill 
244*946Sbill pdate()
245*946Sbill {
246*946Sbill 	long x;
247*946Sbill 	char *ctime();
248*946Sbill 
249*946Sbill 	if (byday==0)
250*946Sbill 		return;
251*946Sbill 	x = midnight-1;
252*946Sbill 	printf("%.6s", ctime(&x)+4);
253*946Sbill }
254