Commit | Line | Data |
---|---|---|
d8722c26 BJ |
1 | /* |
2 | * acct [ -w wtmp ] [ -d ] [ -p ] [ people ] | |
3 | */ | |
4 | static char *sccsid = "@(#)ac.c 4.1 (Berkeley) %G%"; | |
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 | |
18 | struct utmp ibuf; | |
19 | ||
20 | struct ubuf { | |
21 | char uname[NMAX]; | |
22 | long utime; | |
23 | } ubuf[USIZE]; | |
24 | ||
25 | struct tbuf { | |
26 | struct ubuf *userp; | |
27 | long ttime; | |
28 | } tbuf[TSIZE]; | |
29 | ||
30 | char *wtmp; | |
31 | int pflag, byday; | |
32 | long dtime; | |
33 | long midnight; | |
34 | long lastime; | |
35 | long day = 86400L; | |
36 | int pcount; | |
37 | char **pptr; | |
38 | ||
39 | main(argc, argv) | |
40 | char **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]; | |
74 | if(isdigit(c) || isalpha(c)) { | |
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 | ||
96 | loop() | |
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 | ||
141 | print() | |
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 | ||
164 | upall(f) | |
165 | { | |
166 | register struct tbuf *tp; | |
167 | ||
168 | for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) | |
169 | update(tp, f); | |
170 | } | |
171 | ||
172 | update(tp, f) | |
173 | struct 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 | ||
207 | among(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]) { | |
218 | if (*p++ == '\0') | |
219 | return(1); | |
220 | } else | |
221 | break; | |
222 | } | |
223 | } | |
224 | return(0); | |
225 | } | |
226 | ||
227 | newday() | |
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 | ||
244 | pdate() | |
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 | } |