1*48342Sbostic /*- 2*48342Sbostic * Copyright (c) 1982 The Regents of the University of California. 3*48342Sbostic * All rights reserved. 4*48342Sbostic * 5*48342Sbostic * %sccs.include.proprietary.c% 6*48342Sbostic */ 7*48342Sbostic 813605Ssam #ifndef lint 9*48342Sbostic char copyright[] = 10*48342Sbostic "@(#) Copyright (c) 1982 The Regents of the University of California.\n\ 11*48342Sbostic All rights reserved.\n"; 12*48342Sbostic #endif /* not lint */ 13*48342Sbostic 14*48342Sbostic #ifndef lint 15*48342Sbostic static char sccsid[] = "@(#)ac.c 4.10 (Berkeley) 04/18/91"; 16*48342Sbostic #endif /* not lint */ 17*48342Sbostic 18946Sbill /* 197318Swnj * ac [ -w wtmp ] [ -d ] [ -p ] [ people ] 20946Sbill */ 21946Sbill 2237254Sbostic #include <sys/time.h> 2337254Sbostic #include <sys/types.h> 2437254Sbostic #include <sys/timeb.h> 25946Sbill #include <stdio.h> 26946Sbill #include <ctype.h> 27946Sbill #include <utmp.h> 28946Sbill 2937254Sbostic #define NMAX UT_NAMESIZE 3037254Sbostic #define LMAX UT_LINESIZE 31946Sbill 325781Sroot /* 33946Sbill #define TSIZE 1000 345781Sroot */ 355781Sroot #define TSIZE 6242 36946Sbill #define USIZE 500 37946Sbill struct utmp ibuf; 38946Sbill 39946Sbill struct ubuf { 40946Sbill char uname[NMAX]; 41946Sbill long utime; 42946Sbill } ubuf[USIZE]; 43946Sbill 44946Sbill struct tbuf { 45946Sbill struct ubuf *userp; 46946Sbill long ttime; 47946Sbill } tbuf[TSIZE]; 48946Sbill 49946Sbill char *wtmp; 50946Sbill int pflag, byday; 51946Sbill long dtime; 52946Sbill long midnight; 53946Sbill long lastime; 54946Sbill long day = 86400L; 55946Sbill int pcount; 56946Sbill char **pptr; 57946Sbill 58946Sbill main(argc, argv) 59946Sbill char **argv; 60946Sbill { 61946Sbill int c, fl; 62946Sbill register i; 63946Sbill FILE *wf; 64946Sbill 6537254Sbostic wtmp = _PATH_WTMP; 66946Sbill while (--argc > 0 && **++argv == '-') 67946Sbill switch(*++*argv) { 68946Sbill case 'd': 69946Sbill byday++; 70946Sbill continue; 71946Sbill 72946Sbill case 'w': 73946Sbill if (--argc>0) 74946Sbill wtmp = *++argv; 75946Sbill continue; 76946Sbill 77946Sbill case 'p': 78946Sbill pflag++; 79946Sbill continue; 80946Sbill } 81946Sbill pcount = argc; 82946Sbill pptr = argv; 83946Sbill if ((wf = fopen(wtmp, "r")) == NULL) { 84946Sbill printf("No %s\n", wtmp); 85946Sbill exit(1); 86946Sbill } 87946Sbill for(;;) { 88946Sbill if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1) 89946Sbill break; 90946Sbill fl = 0; 91946Sbill for (i=0; i<NMAX; i++) { 92946Sbill c = ibuf.ut_name[i]; 933922Sbugs if (isprint(c) && c != ' ') { 94946Sbill if (fl) 95946Sbill goto skip; 96946Sbill continue; 97946Sbill } 98946Sbill if (c==' ' || c=='\0') { 99946Sbill fl++; 100946Sbill ibuf.ut_name[i] = '\0'; 101946Sbill } else 102946Sbill goto skip; 103946Sbill } 104946Sbill loop(); 105946Sbill skip:; 106946Sbill } 107946Sbill ibuf.ut_name[0] = '\0'; 108946Sbill ibuf.ut_line[0] = '~'; 109946Sbill time(&ibuf.ut_time); 110946Sbill loop(); 111946Sbill print(); 112946Sbill exit(0); 113946Sbill } 114946Sbill 115946Sbill loop() 116946Sbill { 117946Sbill register i; 118946Sbill register struct tbuf *tp; 119946Sbill register struct ubuf *up; 120946Sbill 121946Sbill if(ibuf.ut_line[0] == '|') { 122946Sbill dtime = ibuf.ut_time; 123946Sbill return; 124946Sbill } 1257317Sroot if(ibuf.ut_line[0] == '{') { 126946Sbill if(dtime == 0) 127946Sbill return; 128946Sbill for(tp = tbuf; tp < &tbuf[TSIZE]; tp++) 129946Sbill tp->ttime += ibuf.ut_time-dtime; 130946Sbill dtime = 0; 131946Sbill return; 132946Sbill } 133946Sbill if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time) 134946Sbill midnight = 0; 135946Sbill if (midnight==0) 136946Sbill newday(); 137946Sbill lastime = ibuf.ut_time; 138946Sbill if (byday && ibuf.ut_time > midnight) { 139946Sbill upall(1); 140946Sbill print(); 141946Sbill newday(); 142946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++) 143946Sbill up->utime = 0; 144946Sbill } 145946Sbill if (ibuf.ut_line[0] == '~') { 146946Sbill ibuf.ut_name[0] = '\0'; 147946Sbill upall(0); 148946Sbill return; 149946Sbill } 1505781Sroot /* 151946Sbill if (ibuf.ut_line[0]=='t') 152946Sbill i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0'); 153946Sbill else 154946Sbill i = TSIZE-1; 155946Sbill if (i<0 || i>=TSIZE) 156946Sbill i = TSIZE-1; 1575781Sroot */ 1585781Sroot 1595781Sroot /* 1605781Sroot * Correction contributed by Phyllis Kantar @ Rand-unix 1615781Sroot * 1625781Sroot * Fixes long standing problem with tty names other than 00-99 1635781Sroot */ 1645781Sroot if (ibuf.ut_line[0]=='t') { 1655781Sroot i = (ibuf.ut_line[3]-'0'); 1665781Sroot if(ibuf.ut_line[4]) 1675781Sroot i = i*79 + (ibuf.ut_line[4]-'0'); 1685781Sroot } else 1695781Sroot i = TSIZE-1; 1705781Sroot if (i<0 || i>=TSIZE) { 1715781Sroot i = TSIZE-1; 1725781Sroot printf("ac: Bad tty name: %s\n", ibuf.ut_line); 1735781Sroot } 1745781Sroot 175946Sbill tp = &tbuf[i]; 176946Sbill update(tp, 0); 177946Sbill } 178946Sbill 179946Sbill print() 180946Sbill { 181946Sbill int i; 182946Sbill long ttime, t; 183946Sbill 184946Sbill ttime = 0; 185946Sbill for (i=0; i<USIZE; i++) { 186946Sbill if(!among(i)) 187946Sbill continue; 188946Sbill t = ubuf[i].utime; 189946Sbill if (t>0) 190946Sbill ttime += t; 191946Sbill if (pflag && ubuf[i].utime > 0) { 19236303Smckusick printf("\t%-*.*s %6.2f\n", NMAX, NMAX, 193946Sbill ubuf[i].uname, ubuf[i].utime/3600.); 194946Sbill } 195946Sbill } 196946Sbill if (ttime > 0) { 197946Sbill pdate(); 19836303Smckusick printf("\ttotal %9.2f\n", ttime/3600.); 199946Sbill } 200946Sbill } 201946Sbill 202946Sbill upall(f) 203946Sbill { 204946Sbill register struct tbuf *tp; 205946Sbill 206946Sbill for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) 207946Sbill update(tp, f); 208946Sbill } 209946Sbill 210946Sbill update(tp, f) 211946Sbill struct tbuf *tp; 212946Sbill { 213946Sbill int j; 214946Sbill struct ubuf *up; 215946Sbill long t, t1; 216946Sbill 217946Sbill if (f) 218946Sbill t = midnight; 219946Sbill else 220946Sbill t = ibuf.ut_time; 221946Sbill if (tp->userp) { 222946Sbill t1 = t - tp->ttime; 2233928Sroot if (t1 > 0) 224946Sbill tp->userp->utime += t1; 225946Sbill } 226946Sbill tp->ttime = t; 227946Sbill if (f) 228946Sbill return; 229946Sbill if (ibuf.ut_name[0]=='\0') { 230946Sbill tp->userp = 0; 231946Sbill return; 232946Sbill } 233946Sbill for (up=ubuf; up < &ubuf[USIZE]; up++) { 234946Sbill if (up->uname[0] == '\0') 235946Sbill break; 236946Sbill for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++); 237946Sbill if (j>=NMAX) 238946Sbill break; 239946Sbill } 240946Sbill for (j=0; j<NMAX; j++) 241946Sbill up->uname[j] = ibuf.ut_name[j]; 242946Sbill tp->userp = up; 243946Sbill } 244946Sbill 245946Sbill among(i) 246946Sbill { 247946Sbill register j, k; 248946Sbill register char *p; 249946Sbill 250946Sbill if (pcount==0) 251946Sbill return(1); 252946Sbill for (j=0; j<pcount; j++) { 253946Sbill p = pptr[j]; 254946Sbill for (k=0; k<NMAX; k++) { 255946Sbill if (*p == ubuf[i].uname[k]) { 2563922Sbugs if (*p++ == '\0' || k == NMAX-1) 257946Sbill return(1); 258946Sbill } else 259946Sbill break; 260946Sbill } 261946Sbill } 262946Sbill return(0); 263946Sbill } 264946Sbill 265946Sbill newday() 266946Sbill { 267946Sbill long ttime; 268946Sbill struct timeb tb; 269946Sbill struct tm *localtime(); 270946Sbill 271946Sbill time(&ttime); 272946Sbill if (midnight == 0) { 273946Sbill ftime(&tb); 274946Sbill midnight = 60*(long)tb.timezone; 275946Sbill if (localtime(&ttime)->tm_isdst) 276946Sbill midnight -= 3600; 277946Sbill } 278946Sbill while (midnight <= ibuf.ut_time) 279946Sbill midnight += day; 280946Sbill } 281946Sbill 282946Sbill pdate() 283946Sbill { 284946Sbill long x; 285946Sbill char *ctime(); 286946Sbill 287946Sbill if (byday==0) 288946Sbill return; 289946Sbill x = midnight-1; 290946Sbill printf("%.6s", ctime(&x)+4); 291946Sbill } 292