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