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