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