#include	"sys/types.h"
#include	"sys/acct.h"
#include	"actrecs.h"
#include	"hsubs.h"
#ifdef	DEBUG
#undef DFILE
#define	DFILE	"acctdata"
#endif


/*
 * Accounting structures
 */

struct	{
	short hid;
	short hgd;
	long	value1, value2;
} user[NHENT];

struct	acctrec arec;

char	buf[5120];
int	af, of;
long	tc();
long	lseek();

main(c,v)
char **v;
{
	register struct acct *pa, *pl;
	char *anm;
	register short hk;
	int r;

	anm = AFILE;
	if(c == 2)
		anm = v[1];

	if((af = open(anm, 0)) == -1 ||
	   (of = open(DFILE, 2)) == -1){
		printf("Accting file open error %d %d\n", af, of);
		exit(1);
	}

	while((r = read(af, buf, 5120))%(sizeof (struct acct)) == 0 && r){
		pl = &buf[r];
		for(pa = buf; pa < pl; pa++){
			hk = akey(pa->ac_uid);
lp:
			if(user[hk].hid != pa->ac_uid ||
				user[hk].hgd != pa->ac_gid){
				if(user[hk].hid == 0 && user[hk].hgd == 0){
					user[hk].hid = pa->ac_uid;
					user[hk].hgd = pa->ac_gid;
				} else {
					if(++hk >= NHENT)hk = 0;
					goto lp;
				}
			}
			user[hk].value1 += tc(pa->ac_utime);
			user[hk].value2 += tc(pa->ac_stime);
		}
	}
	close(af);
	writit();
	close(of);
}


writit()
{
	register int i, err, hk;

	for(i = 0; i < NHENT; i++){
		if(user[i].value1 == 0L && user[i].value2 == 0L)continue;
#ifdef	DEBUG1
		printf("u:%-5d g:%-5d  Usr:%7D Sys:%7D\n", user[i].hid,
			user[i].hgd, user[i].value1, user[i].value2);
#endif
		if(user[i].hgd == 0 && user[i].hid == 0)
			user[i].hgd = 255;
		hk = user[i].hid;
		lseek(of, (long)(akey(hk))*AREAD, 0);
		err = 0;
lp:
#ifdef	DEBUG1
		printf("Offset=%D\n", lseek(of, 0L, 1));
#endif
		if(read(of, &arec, AREAD) != AREAD){
			if(err++)error("read error");
			lseek(of, 0L, 0);
			goto lp;
		}
		if(arec.a_gid != user[i].hgd || arec.a_uid != user[i].hid)
			if(arec.a_uid == 0 && arec.a_gid == 0){
				arec.a_uid = user[i].hid;
				arec.a_gid = user[i].hgd;
			} else
				goto lp;
		arec.a_usrcpu += user[i].value1;
		arec.a_syscpu += user[i].value2;
		lseek(of, -(long)(AREAD), 1);
#ifdef	DEBUG1
		printf("Back seeked to %D\n", lseek(of, 0L, 1));
#endif
		write(of, &arec, AREAD);
#ifdef	DEBUG1
		printf("U:%-5d G:%-5d  Usr:%7D Sys:%7D\n", arec.a_uid, arec.a_gid,
			arec.a_usrcpu, arec.a_syscpu);
#endif
	}
}

error(s)
char *s;
{
	write(2, "cpu: ERROR: ", 12);
	write(2, s, strlen(s));
	write(2, "\n", 1);
	exit(7);
}

long tc(f)
unsigned short f;
{
	register long t;
	register exp;

	t = f & 017777;
	exp = (f >> 13) & 07;
	while(exp){
		t <<= 3;
		exp--;
	}
	return(t);
}

