/* * acct [ -w wtmp ] [ -d ] [ -p ] [ people ] */ static char *sccsid = "@(#)ac.c 4.3 (Berkeley) 7/2/81"; #include <stdio.h> #include <ctype.h> #include <time.h> #include <utmp.h> #include <sys/types.h> #include <sys/timeb.h> #define NMAX sizeof(ibuf.ut_name) #define LMAX sizeof(ibuf.ut_line) #define TSIZE 128 /* maximum number of ttys */ #define USIZE 500 struct utmp ibuf; struct ubuf { char uname[NMAX]; time_t utime; } ubuf[USIZE]; struct tbuf { struct ubuf *userp; char ttnames[LMAX]; time_t ttime; } tbuf[TSIZE]; int umax, tmax; char *wtmp; int pflag, byday; time_t dtime; time_t midnight; time_t lastime; time_t day = 86400L; int pcount; char **pptr; main(argc, argv) char **argv; { int c, fl; register i; FILE *wf; wtmp = "/usr/adm/wtmp"; while (--argc > 0 && **++argv == '-') switch(*++*argv) { case 'd': byday++; continue; case 'w': if (--argc>0) wtmp = *++argv; continue; case 'p': pflag++; continue; } pcount = argc; pptr = argv; if ((wf = fopen(wtmp, "r")) == NULL) { printf("No %s\n", wtmp); exit(1); } for(;;) { if (fread((char *)&ibuf, sizeof(ibuf), 1, wf) != 1) break; fl = 0; for (i=0; i<NMAX; i++) { c = ibuf.ut_name[i]; if (isprint(c) && c != ' ') { if (fl) goto skip; continue; } if (c==' ' || c=='\0') { fl++; ibuf.ut_name[i] = '\0'; } else goto skip; } loop(); skip:; } ibuf.ut_name[0] = '\0'; ibuf.ut_line[0] = '~'; time(&ibuf.ut_time); loop(); print(); exit(0); } loop() { register int i; register struct tbuf *tp; register struct ubuf *up; static int complained = 0; if(ibuf.ut_line[0] == '|') { dtime = ibuf.ut_time; return; } if(ibuf.ut_line[0] == '{') { if(dtime == 0) return; for(tp = tbuf; tp <= tmax; tp++) tp->ttime += ibuf.ut_time-dtime; dtime = 0; return; } if (lastime>ibuf.ut_time || lastime+(1.5*day)<ibuf.ut_time) midnight = 0; if (midnight==0) newday(); lastime = ibuf.ut_time; if (byday && ibuf.ut_time > midnight) { upall(1); print(); newday(); for (up=ubuf; up <= &ubuf[umax]; up++) up->utime = 0; } if (ibuf.ut_line[0] == '~') { ibuf.ut_name[0] = '\0'; upall(0); return; } for (i = 0; i < TSIZE; i++) { if (tbuf[i].ttnames[0] == 0) { strncpy(tbuf[i].ttnames, ibuf.ut_line, sizeof(ibuf.ut_line)); tmax = i; break; } if (!strncmp(tbuf[i].ttnames, ibuf.ut_line, sizeof(ibuf.ut_line))) break; } if (i == TSIZE) { if (!complained) fprintf(stderr, "Too many ttys, some ignored\n"); complained = 1; return; } tp = &tbuf[i]; update(tp, 0); } print() { register int i; time_t ttime, t; ttime = 0; for (i=0; i <= umax; i++) { if(!among(i)) continue; t = ubuf[i].utime; if (t>0) ttime += t; if (pflag && ubuf[i].utime > 0) { printf("\t%-*.*s%6.2f\n", NMAX, NMAX, ubuf[i].uname, ubuf[i].utime/3600.); } } if (ttime > 0) { pdate(); printf("\ttotal%9.2f\n", ttime/3600.); } } upall(f) { register struct tbuf *tp; for (tp=tbuf; tp <= tmax; tp++) update(tp, f); } update(tp, f) struct tbuf *tp; { register int j; register struct ubuf *up; time_t t, t1; static int complained; if (f) t = midnight; else t = ibuf.ut_time; if (tp->userp) { t1 = t - tp->ttime; if (t1 > 0) tp->userp->utime += t1; } tp->ttime = t; if (f) return; if (ibuf.ut_name[0]=='\0') { tp->userp = 0; return; } for (up=ubuf; up < &ubuf[USIZE]; up++) { if (up->uname[0] == '\0') { umax = up - ubuf; break; } for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++); if (j>=NMAX) break; } if (up == &ubuf[USIZE]) { if (!complained) fprintf(stderr, "Too many users, some omitted\n"); complained = 1; return; } for (j=0; j<NMAX; j++) up->uname[j] = ibuf.ut_name[j]; tp->userp = up; } among(i) { register j, k; register char *p; if (pcount==0) return(1); for (j=0; j<pcount; j++) { p = pptr[j]; for (k=0; k<NMAX; k++) { if (*p == ubuf[i].uname[k]) { if (*p++ == '\0' || k == NMAX-1) return(1); } else break; } } return(0); } newday() { time_t ttime; struct timeb tb; struct tm *localtime(); time(&ttime); if (midnight == 0) { ftime(&tb); midnight = 60*(time_t)tb.timezone; if (localtime(&ttime)->tm_isdst) midnight -= 3600; } while (midnight <= ibuf.ut_time) midnight += day; } pdate() { time_t x; char *ctime(); if (byday==0) return; x = midnight-1; printf("%.6s", ctime(&x)+4); }