1946Sbill /* 2946Sbill * acct [ -w wtmp ] [ -d ] [ -p ] [ people ] 3946Sbill */ 4*5781Sroot static char *sccsid = "@(#)ac.c 4.4 (Berkeley) 02/13/82"; 5946Sbill 6946Sbill #include <stdio.h> 7946Sbill #include <ctype.h> 8946Sbill #include <time.h> 9946Sbill #include <utmp.h> 10946Sbill #include <sys/types.h> 11946Sbill #include <sys/timeb.h> 12946Sbill 13946Sbill #define NMAX sizeof(ibuf.ut_name) 14946Sbill #define LMAX sizeof(ibuf.ut_line) 15946Sbill 16*5781Sroot /* 17946Sbill #define TSIZE 1000 18*5781Sroot */ 19*5781Sroot #define TSIZE 6242 20946Sbill #define USIZE 500 21946Sbill struct utmp ibuf; 22946Sbill 23946Sbill struct ubuf { 24946Sbill char uname[NMAX]; 25946Sbill long utime; 26946Sbill } ubuf[USIZE]; 27946Sbill 28946Sbill struct tbuf { 29946Sbill struct ubuf *userp; 30946Sbill long ttime; 31946Sbill } tbuf[TSIZE]; 32946Sbill 33946Sbill char *wtmp; 34946Sbill int pflag, byday; 35946Sbill long dtime; 36946Sbill long midnight; 37946Sbill long lastime; 38946Sbill long day = 86400L; 39946Sbill int pcount; 40946Sbill char **pptr; 41946Sbill 42946Sbill main(argc, argv) 43946Sbill char **argv; 44946Sbill { 45946Sbill int c, fl; 46946Sbill register i; 47946Sbill FILE *wf; 48946Sbill 49946Sbill wtmp = "/usr/adm/wtmp"; 50946Sbill while (--argc > 0 && **++argv == '-') 51946Sbill switch(*++*argv) { 52946Sbill case 'd': 53946Sbill byday++; 54946Sbill continue; 55946Sbill 56946Sbill case 'w': 57946Sbill if (--argc>0) 58946Sbill wtmp = *++argv; 59946Sbill continue; 60946Sbill 61946Sbill case 'p': 62946Sbill pflag++; 63946Sbill continue; 64946Sbill } 65946Sbill pcount = argc; 66946Sbill pptr = argv; 67946Sbill if ((wf = fopen(wtmp, "r")) == NULL) { 68946Sbill printf("No %s\n", wtmp); 69946Sbill exit(1); 70946Sbill } 71946Sbill for(;;) { 72946Sbill if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1) 73946Sbill break; 74946Sbill fl = 0; 75946Sbill for (i=0; i<NMAX; i++) { 76946Sbill c = ibuf.ut_name[i]; 773922Sbugs if (isprint(c) && c != ' ') { 78946Sbill if (fl) 79946Sbill goto skip; 80946Sbill continue; 81946Sbill } 82946Sbill if (c==' ' || c=='\0') { 83946Sbill fl++; 84946Sbill ibuf.ut_name[i] = '\0'; 85946Sbill } else 86946Sbill goto skip; 87946Sbill } 88946Sbill loop(); 89946Sbill skip:; 90946Sbill } 91946Sbill ibuf.ut_name[0] = '\0'; 92946Sbill ibuf.ut_line[0] = '~'; 93946Sbill time(&ibuf.ut_time); 94946Sbill loop(); 95946Sbill print(); 96946Sbill exit(0); 97946Sbill } 98946Sbill 99946Sbill loop() 100946Sbill { 101946Sbill register i; 102946Sbill register struct tbuf *tp; 103946Sbill register struct ubuf *up; 104946Sbill 105946Sbill if(ibuf.ut_line[0] == '|') { 106946Sbill dtime = ibuf.ut_time; 107946Sbill return; 108946Sbill } 109946Sbill if(ibuf.ut_line[0] == '}') { 110946Sbill if(dtime == 0) 111946Sbill return; 112946Sbill for(tp = tbuf; tp < &tbuf[TSIZE]; tp++) 113946Sbill tp->ttime += ibuf.ut_time-dtime; 114946Sbill dtime = 0; 115946Sbill return; 116946Sbill } 117946Sbill if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time) 118946Sbill midnight = 0; 119946Sbill if (midnight==0) 120946Sbill newday(); 121946Sbill lastime = ibuf.ut_time; 122946Sbill if (byday && ibuf.ut_time > midnight) { 123946Sbill upall(1); 124946Sbill print(); 125946Sbill newday(); 126946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++) 127946Sbill up->utime = 0; 128946Sbill } 129946Sbill if (ibuf.ut_line[0] == '~') { 130946Sbill ibuf.ut_name[0] = '\0'; 131946Sbill upall(0); 132946Sbill return; 133946Sbill } 134*5781Sroot /* 135946Sbill if (ibuf.ut_line[0]=='t') 136946Sbill i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0'); 137946Sbill else 138946Sbill i = TSIZE-1; 139946Sbill if (i<0 || i>=TSIZE) 140946Sbill i = TSIZE-1; 141*5781Sroot */ 142*5781Sroot 143*5781Sroot /* 144*5781Sroot * Correction contributed by Phyllis Kantar @ Rand-unix 145*5781Sroot * 146*5781Sroot * Fixes long standing problem with tty names other than 00-99 147*5781Sroot */ 148*5781Sroot if (ibuf.ut_line[0]=='t') { 149*5781Sroot i = (ibuf.ut_line[3]-'0'); 150*5781Sroot if(ibuf.ut_line[4]) 151*5781Sroot i = i*79 + (ibuf.ut_line[4]-'0'); 152*5781Sroot } else 153*5781Sroot i = TSIZE-1; 154*5781Sroot if (i<0 || i>=TSIZE) { 155*5781Sroot i = TSIZE-1; 156*5781Sroot printf("ac: Bad tty name: %s\n", ibuf.ut_line); 157*5781Sroot } 158*5781Sroot 159946Sbill tp = &tbuf[i]; 160946Sbill update(tp, 0); 161946Sbill } 162946Sbill 163946Sbill print() 164946Sbill { 165946Sbill int i; 166946Sbill long ttime, t; 167946Sbill 168946Sbill ttime = 0; 169946Sbill for (i=0; i<USIZE; i++) { 170946Sbill if(!among(i)) 171946Sbill continue; 172946Sbill t = ubuf[i].utime; 173946Sbill if (t>0) 174946Sbill ttime += t; 175946Sbill if (pflag && ubuf[i].utime > 0) { 176946Sbill printf("\t%-*.*s%6.2f\n", NMAX, NMAX, 177946Sbill ubuf[i].uname, ubuf[i].utime/3600.); 178946Sbill } 179946Sbill } 180946Sbill if (ttime > 0) { 181946Sbill pdate(); 182946Sbill printf("\ttotal%9.2f\n", ttime/3600.); 183946Sbill } 184946Sbill } 185946Sbill 186946Sbill upall(f) 187946Sbill { 188946Sbill register struct tbuf *tp; 189946Sbill 190946Sbill for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) 191946Sbill update(tp, f); 192946Sbill } 193946Sbill 194946Sbill update(tp, f) 195946Sbill struct tbuf *tp; 196946Sbill { 197946Sbill int j; 198946Sbill struct ubuf *up; 199946Sbill long t, t1; 200946Sbill 201946Sbill if (f) 202946Sbill t = midnight; 203946Sbill else 204946Sbill t = ibuf.ut_time; 205946Sbill if (tp->userp) { 206946Sbill t1 = t - tp->ttime; 2073928Sroot if (t1 > 0) 208946Sbill tp->userp->utime += t1; 209946Sbill } 210946Sbill tp->ttime = t; 211946Sbill if (f) 212946Sbill return; 213946Sbill if (ibuf.ut_name[0]=='\0') { 214946Sbill tp->userp = 0; 215946Sbill return; 216946Sbill } 217946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++) { 218946Sbill if (up->uname[0] == '\0') 219946Sbill break; 220946Sbill for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++); 221946Sbill if (j>=NMAX) 222946Sbill break; 223946Sbill } 224946Sbill for (j=0; j<NMAX; j++) 225946Sbill up->uname[j] = ibuf.ut_name[j]; 226946Sbill tp->userp = up; 227946Sbill } 228946Sbill 229946Sbill among(i) 230946Sbill { 231946Sbill register j, k; 232946Sbill register char *p; 233946Sbill 234946Sbill if (pcount==0) 235946Sbill return(1); 236946Sbill for (j=0; j<pcount; j++) { 237946Sbill p = pptr[j]; 238946Sbill for (k=0; k<NMAX; k++) { 239946Sbill if (*p == ubuf[i].uname[k]) { 2403922Sbugs if (*p++ == '\0' || k == NMAX-1) 241946Sbill return(1); 242946Sbill } else 243946Sbill break; 244946Sbill } 245946Sbill } 246946Sbill return(0); 247946Sbill } 248946Sbill 249946Sbill newday() 250946Sbill { 251946Sbill long ttime; 252946Sbill struct timeb tb; 253946Sbill struct tm *localtime(); 254946Sbill 255946Sbill time(&ttime); 256946Sbill if (midnight == 0) { 257946Sbill ftime(&tb); 258946Sbill midnight = 60*(long)tb.timezone; 259946Sbill if (localtime(&ttime)->tm_isdst) 260946Sbill midnight -= 3600; 261946Sbill } 262946Sbill while (midnight <= ibuf.ut_time) 263946Sbill midnight += day; 264946Sbill } 265946Sbill 266946Sbill pdate() 267946Sbill { 268946Sbill long x; 269946Sbill char *ctime(); 270946Sbill 271946Sbill if (byday==0) 272946Sbill return; 273946Sbill x = midnight-1; 274946Sbill printf("%.6s", ctime(&x)+4); 275946Sbill } 276