SRI-NOSC/s1/ac.c

Compare this file to the similar file:
Show the results in this format:

#/*
Module Name:
	ac.c -- login accounting

Installation:
	if $1e = finale goto finale
	if -r a.out rm -f a.out
	cc ac.c
	if ! -r a.out -o $1x != testx exit
	echo testing....
	a.out -p -d
	exit
: finale
	cc -O -s ac.c
	if ! -r a.out exit
	su cp a.out /usr/bin/ac
	rm -f a.out

Synopsis:
	acct [ -w wtmp ] [ -d ] [ -p people ]

Function:

Restrictions:

Diagnostics:

Files:

See Also:

Bugs:

Compile time parameters and effects:

Module History:
	Original from Bell Labs.
	Modified Nov78 by Greg Noel to use long arithmetic instead of
	    floating point.
*/
#define	TSIZE	(10+26+26)
#define	USIZE	200

struct {
	char	name[8];
	char	tty;
	char	fill1;
	long	time;
	int	fill2;
} ibuf;

struct ubuf {
	char	name[8];
	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;
long	day1;	/* 1.5*day */
int	pcount;
char	**pptr;

main(argc, argv) 
char **argv;
{
	int c, fl;
	register i;
	register char *ip;
	extern fin;
	int f;

	day = 24;	day =* 60*60;
	day1 = 36;	day1 =* 60*60;
	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 (fopen(wtmp, &fin) < 0) {
		printf("No %s\n", wtmp);
		return;
	}
	for(;;) {
		ip = &ibuf;
		for (i=0; i<16; i++) {
			if ((c=getc(&fin)) < 0)
				goto brk;
			*ip++ = c;
		}
		if (ibuf.tty == 0) goto skip;
		fl = 0;
		for (i=0; i<8; i++) {
			c = ibuf.name[i];
			if ('0'<=c&&c<='9'||'a'<=c&&c<='z'||'A'<=c&&c<='Z') {
				if (fl)
					goto skip;
				continue;
			}
			if (c==' ' || c=='\0') {
				fl++;
				ibuf.name[i] = '\0';
			} else
				goto skip;
		}
		loop();
    skip:;
	}
    brk:
	ibuf.name[0] = '\0';
	ibuf.tty = '~';
	time(&ibuf.time);
	loop();
	print();
}

loop()
{
	register i;
	register struct tbuf *tp;
	register struct ubuf *up;

	if (ibuf.fill1||ibuf.fill2)
		return;
	if(ibuf.tty == '|') {
		dtime = ibuf.time;
		return;
	}
	if(ibuf.tty == '}') {
		if(dtime == 0)
			return;
		for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)
			tp->ttime =+ ibuf.time-dtime;
		dtime = 0;
		return;
	}
	if (lastime>ibuf.time || lastime+day1<ibuf.time)
		midnight = 0;
	if (midnight==0)
		newday();
	lastime = ibuf.time;
	if (byday && ibuf.time > midnight) {
		upall(1);
		print();
		newday();
		for (up=ubuf; up < &ubuf[USIZE]; up++)
			up->utime = 0;
	}
	if (ibuf.tty == '~') {
		ibuf.name[0] = '\0';
		upall(0);
		return;
	}
	if ((i = ibuf.tty) >= 'A' && i <= 'Z')
		i =+ 'z' - 'A' + 1;
	if (i >= 'a')
		i =+ '9' - 'a' + 1;
	i =- '0';
	if (i<0 || i>=TSIZE)
		i = TSIZE-1;
	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) {
				printf("\t%-8.8s%s\n", ubuf[i].name,
				    ptime(&ubuf[i].utime));
			}
		}
	}
	if (ttime > 0) {
		pdate();
		printf("\ttotal   %s\n\n", ptime(&ttime));
	}
}

upall(f)
{
	register struct tbuf *tp;

	for (tp=tbuf; tp < &tbuf[TSIZE]; tp++)
		update(tp, f);
}

char ttys[] "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?";

update(tp, f)
struct tbuf *tp;
{
	int i, j;
	struct ubuf *up;
	long t, t1;

	if (f)
		t = midnight;
	else
		t = ibuf.time;
	if (tp->userp) {
		t1 = t - tp->ttime;
		if (t1>0 && t1 < day1)
			tp->userp->utime =+ t1;
	}
	tp->ttime = t;
	if (f)
		return;
/*
if(tp->userp)
printf("logoff tty%c %-8.8s used %s\n", ttys[tp-tbuf], tp->userp->name,
    ptime(&t1));
*/
	if (ibuf.name[0]=='\0') {
		tp->userp = 0;
		return;
	}
	for (up=ubuf; up < &ubuf[USIZE]; up++) {
		if (up->name[0] == '\0')
			break;
		for (j=0; j<8 && up->name[j]==ibuf.name[j]; j++);
		if (j>=8)
			break;
	}
	for (j=0; j<8; j++)
		up->name[j] = ibuf.name[j];
	tp->userp = up;
/*
printf("login  tty%c %-8.8s at %s", ttys[tp-tbuf], ibuf.name,
    ctime(&ibuf.time));
*/
}

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<8; k++) {
			if (*p == ubuf[i].name[k]) {
				if (*p++ == '\0')
					return(1);
			} else
				break;
		}
	}
	return(0);
}

newday()
{
	register int *p;

	if(midnight == 0) {		/* Re-calculate midnight? */
		p = localtime(&ibuf.time);	/* Get current offsets */
		midnight = ibuf.time;	/* Starting point */
		midnight =- *p++;	/* Remove any seconds */
		midnight =- *p++*60;	/* Remove any minutes */
		while(--*p >= 0)	/* Remove any hours */
			midnight =- 60*60;
	}
	while (midnight <= ibuf.time)
		midnight =+ day;
}

char ans[] "0000.00";

ptime(val)
long *val;
{
	register int i, t, *p;

	*val =+ 18;	/* round off to nearest tick */
	t = (*val%3600)/36;
	ans[6] = t%10 + '0';
	ans[5] = t/10 + '0';
	t = *val/3600;
	for(i = 3; i >= 0; i--) {
		ans[i] = t%10 + '0';
		t =/ 10;
	}
	for(i = 0; i < 4 && ans[i] == '0'; i++)
		ans[i] = ' ';
	return(ans);
}

pdate()
{
	long priorday;

	if (byday==0)
		return;
	priorday = midnight - 1;
	printf("%-6.6s", ctime(&priorday)+4);
}