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