BSD 4_3_Reno release
[unix-history] / usr / src / usr.sbin / ac / ac.c
#ifndef lint
static char *sccsid = "@(#)ac.c 4.9 (Berkeley) 4/2/89";
#endif
/*
* ac [ -w wtmp ] [ -d ] [ -p ] [ people ]
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <ctype.h>
#include <utmp.h>
#define NMAX UT_NAMESIZE
#define LMAX UT_LINESIZE
/*
#define TSIZE 1000
*/
#define TSIZE 6242
#define USIZE 500
struct utmp ibuf;
struct ubuf {
char uname[NMAX];
long utime;
} ubuf[USIZE];
struct tbuf {
struct ubuf *userp;
long ttime;
} tbuf[TSIZE];
char *wtmp;
int pflag, byday;
long dtime;
long midnight;
long lastime;
long day = 86400L;
int pcount;
char **pptr;
main(argc, argv)
char **argv;
{
int c, fl;
register i;
FILE *wf;
wtmp = _PATH_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 i;
register struct tbuf *tp;
register struct ubuf *up;
if(ibuf.ut_line[0] == '|') {
dtime = ibuf.ut_time;
return;
}
if(ibuf.ut_line[0] == '{') {
if(dtime == 0)
return;
for(tp = tbuf; tp < &tbuf[TSIZE]; 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[USIZE]; up++)
up->utime = 0;
}
if (ibuf.ut_line[0] == '~') {
ibuf.ut_name[0] = '\0';
upall(0);
return;
}
/*
if (ibuf.ut_line[0]=='t')
i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0');
else
i = TSIZE-1;
if (i<0 || i>=TSIZE)
i = TSIZE-1;
*/
/*
* Correction contributed by Phyllis Kantar @ Rand-unix
*
* Fixes long standing problem with tty names other than 00-99
*/
if (ibuf.ut_line[0]=='t') {
i = (ibuf.ut_line[3]-'0');
if(ibuf.ut_line[4])
i = i*79 + (ibuf.ut_line[4]-'0');
} else
i = TSIZE-1;
if (i<0 || i>=TSIZE) {
i = TSIZE-1;
printf("ac: Bad tty name: %s\n", ibuf.ut_line);
}
tp = &tbuf[i];
update(tp, 0);
}
print()
{
int i;
long ttime, t;
ttime = 0;
for (i=0; i<USIZE; 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 < &tbuf[TSIZE]; tp++)
update(tp, f);
}
update(tp, f)
struct tbuf *tp;
{
int j;
struct ubuf *up;
long t, t1;
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')
break;
for (j=0; j<NMAX && up->uname[j]==ibuf.ut_name[j]; j++);
if (j>=NMAX)
break;
}
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()
{
long ttime;
struct timeb tb;
struct tm *localtime();
time(&ttime);
if (midnight == 0) {
ftime(&tb);
midnight = 60*(long)tb.timezone;
if (localtime(&ttime)->tm_isdst)
midnight -= 3600;
}
while (midnight <= ibuf.ut_time)
midnight += day;
}
pdate()
{
long x;
char *ctime();
if (byday==0)
return;
x = midnight-1;
printf("%.6s", ctime(&x)+4);
}