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