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