1 #ifndef lint 2 static char *sccsid = "@(#)ac.c 4.9 (Berkeley) 04/02/89"; 3 #endif 4 /* 5 * ac [ -w wtmp ] [ -d ] [ -p ] [ people ] 6 */ 7 8 #include <sys/time.h> 9 #include <sys/types.h> 10 #include <sys/timeb.h> 11 #include <stdio.h> 12 #include <ctype.h> 13 #include <utmp.h> 14 15 #define NMAX UT_NAMESIZE 16 #define LMAX UT_LINESIZE 17 18 /* 19 #define TSIZE 1000 20 */ 21 #define TSIZE 6242 22 #define USIZE 500 23 struct utmp ibuf; 24 25 struct ubuf { 26 char uname[NMAX]; 27 long utime; 28 } ubuf[USIZE]; 29 30 struct tbuf { 31 struct ubuf *userp; 32 long ttime; 33 } tbuf[TSIZE]; 34 35 char *wtmp; 36 int pflag, byday; 37 long dtime; 38 long midnight; 39 long lastime; 40 long day = 86400L; 41 int pcount; 42 char **pptr; 43 44 main(argc, argv) 45 char **argv; 46 { 47 int c, fl; 48 register i; 49 FILE *wf; 50 51 wtmp = _PATH_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]; 79 if (isprint(c) && c != ' ') { 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 101 loop() 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 } 111 if(ibuf.ut_line[0] == '{') { 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 } 136 /* 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; 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 161 tp = &tbuf[i]; 162 update(tp, 0); 163 } 164 165 print() 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 188 upall(f) 189 { 190 register struct tbuf *tp; 191 192 for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) 193 update(tp, f); 194 } 195 196 update(tp, f) 197 struct 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; 209 if (t1 > 0) 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 231 among(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]) { 242 if (*p++ == '\0' || k == NMAX-1) 243 return(1); 244 } else 245 break; 246 } 247 } 248 return(0); 249 } 250 251 newday() 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 268 pdate() 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 } 278