1 /* 2 * ac [ -w wtmp ] [ -d ] [ -p ] [ people ] 3 */ 4 static char *sccsid = "@(#)ac.c 4.6 (Berkeley) 06/27/82"; 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 /* 17 #define TSIZE 1000 18 */ 19 #define TSIZE 6242 20 #define USIZE 500 21 struct utmp ibuf; 22 23 struct ubuf { 24 char uname[NMAX]; 25 long utime; 26 } ubuf[USIZE]; 27 28 struct tbuf { 29 struct ubuf *userp; 30 long ttime; 31 } tbuf[TSIZE]; 32 33 char *wtmp; 34 int pflag, byday; 35 long dtime; 36 long midnight; 37 long lastime; 38 long day = 86400L; 39 int pcount; 40 char **pptr; 41 42 main(argc, argv) 43 char **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]; 77 if (isprint(c) && c != ' ') { 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 99 loop() 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 } 109 if(ibuf.ut_line[0] == '{') { 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 } 134 /* 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; 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 159 tp = &tbuf[i]; 160 update(tp, 0); 161 } 162 163 print() 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 186 upall(f) 187 { 188 register struct tbuf *tp; 189 190 for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) 191 update(tp, f); 192 } 193 194 update(tp, f) 195 struct 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; 207 if (t1 > 0) 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 229 among(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]) { 240 if (*p++ == '\0' || k == NMAX-1) 241 return(1); 242 } else 243 break; 244 } 245 } 246 return(0); 247 } 248 249 newday() 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 266 pdate() 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 } 276