#include <hsubs.h>
static char pbuf[512], lbuf[512], used[NHENT], tbuf[128];
static short utab[NHENT];
static int fdo0, fdo1, nent;
static int gfd = -1;

static char *tail0 = "nm";
static char *tail1 = "ud";
static char hfname[64];


makehash(input, output)
char *input, *output;
{
	register char *s, *t, *l;
	int fd, r;

	if((fd = open(input, 0)) == -1){
		printf("makehash: Can't open %s as input\n", input);
		return(-1);
	}

	for(r = 0; r < NHENT; r++)
		utab[r] = -1;
	strcpy(hfname, output);
	strcat(hfname, tail0);
	if((fdo0 = creat(hfname, 0600)) == -1 || chmod(hfname, 0644) == -1){
herr:
		printf("makehash: Can not %s file %s (output)\n",
			fdo0 == -1 ? "create" : "chmod on", hfname);
		return(-1);
	}
	strcpy(hfname, output);
	strcat(hfname, tail1);
	if((fdo1 = creat(hfname, 0600)) == -1 || chmod(hfname, 0644) == -1)
		goto herr;
	close(fdo1);
	if((fdo1 = open(hfname, 2)) == -1)goto herr;
	lseek(fdo0, (long)(NHENT-1) << 7, 0);
	lseek(fdo1, (long)(NHENT-1) << 7, 0);
	write(fdo0, lbuf, 128);
	write(fdo1, lbuf, 128);
	t = lbuf;
	nent = 0;
	while((r = read(fd, s = pbuf, 512)) > 0){
		l = s + r;
		while(s < l){
			if((*t++ = *s++) != '\n') continue;
			henter(t);
			t = lbuf;
		}
	}
	close(fd);
	close(fdo0);
	close(fdo1);
#ifdef DIAGNOSTICS
	printf("\n%d entries.\n", nent);
#endif
	return(0);
}

henter(t)
char *t;
{
	register char *p;
	register h, h1;
	long h2;

	p = t;
	if(p >= &lbuf[128]){
		printf("henter: Line too long: %s -- Deleted.\n", lbuf);
		return;
	}
	while(p < &lbuf[128])
		*p++ = 0;
	p = lbuf;
	while(*p && *p != ':')p++;
	if(*p == 0){
uerr:
		printf("henter: Illegal data encountered (zero) at: %s\n", lbuf);
		return;
	}
	*p = 0;
	nent++;
	if(nent >= NHENT){
		printf("henter: Hash table full, %u not big enough, increase.\n",
			NHENT);
		return;
	}
	h = hkey(lbuf);
try:
	if(used[h]){
#ifdef DIAGNOSTICS
		printf("Hit:%u,%s  ", h, lbuf);
#endif
		if(h++ >= NHENT)h = 0;
		goto try;
	}
	used[h] = 1;
	lseek(fdo0, (long)(h) << 7L, 0);
	*p = ':';
	write(fdo0, lbuf, 128);
	while(*++p != ':' && *p);
	if(*p++ != ':')goto uerr;
	h = 0;
	while(*p >= '0' && *p <= '9')
		h = h * 10 + (*p++) - '0';
	if(*p != ':')goto uerr;
	h1 = ukey(h);
utry:
	if(utab[h1] >= 0){
		if(utab[h1] == h){
#ifdef	DIAGNOSTICS
			printf("henter: UID %d already entered.\n", h);
#endif
			return;
		}
#ifdef	DIAGNOSTICS
		printf("Hit(uid): %u, %u	", h%NHENT, h);
#endif
		if(++h1 >= NHENT)
			h1 = 0;
		goto utry;
	}
	lseek(fdo1, (long)(h1) << 7, 0);
	write(fdo1, lbuf, 128);
	utab[h1] = h;
	return;
}


scanhash(input)
char *input;
{
	register short i;
	short fd;
	register short ent;
	register char *s;

	for(i = 0; i < NHENT; i++){
		used[i] = 0;
		utab[i] = -1;
	}
	if((fd = open(input, 0)) == -1){
		printf("scanhash: Can't open %s as input\n", input);
		return(-1);
	}
	while((i = read(fd, lbuf, 512)) > 0 && i%128 == 0){
		i -= 128;
		do {
			s = &lbuf[i];
			if(*s){
				used[ent] = 1;
				while(*s && *s != ':')s++;
				if(*s++ == 0){
bad:
					printf("scanhash: bad line in hashed file:%s\n", &lbuf[i]);
					exit(1);
				}
				while(*s && *s != ':')s++;
				if(*s++ == 0)goto bad;
				utab[ukey(?)]=?;
			ent++;
			s += 128;
			i -= 128;
		}
	}
	close(fd);
	if(i)
		printf("scanhash: Warning: %s read() did not finish right\n",
			input);
	return(0);
}
