#include "../sccshead/sfile.h"
char inbuf__[] "~|^`inbuf.c:	3.2";
/*
	Bottom level read routines for SCCS files.

	Usage:
		struct Ibufr ib;
		...
		opnr(&ib,"filename");
		...
		if(getr(&ib) == 1) [end-of-file];
		[ib.Irecptr is addr of record (always on word boundary)]
		[ib.Ilen is length]

	Address HASHADDR of the file must contain a 1-word stored hash count.
	If this count is non-zero, then on end-of-file a computed hash count
	is compared with it and a fatal error is issued if they aren't equal.
*/

opnr(buf,file)
register struct Ibufr *buf;
char file[];
{
	buf->Ifildes = xopen(file,0);
	buf->Irecptr = buf->Ibuff2 + 2;
	buf->Iend = buf->Irecptr + 510;
	buf->Ilen = 510;
	buf->Ibuff3[1] = -128;
	buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0;
}


getr(buf)
register struct Ibufr *buf;
{
	register char *p, *q;
	int *w;
	int i, n;

	buf->Irecptr =+ buf->Ilen + !(buf->Ilen & 1);

	i = 0;
	while(1) {
		buf->Ilen = 0;
		buf->Ilen = *buf->Irecptr + 128;

		if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1)))
			return(++buf->Irecptr);

		if(i++ == 1) return(1);

		q = buf->Irecptr;
		p = buf->Irecptr =- 512;

		while(q <= buf->Iend) *p++ = *q++;

		if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0)
			return(1);

		buf->Iend = buf->Ibuff2 + n - 1;
		*(buf->Iend + 1) = -128;

		w = buf->Ibuff2;
		if(buf->Ihflag == 0) {
			buf->Ihflag = 1;
			buf->Ihtot = w[HASHADDR>>1];
			w[HASHADDR>>1] = 0;
		}
		if(n < 512) buf->Ibuff2[n] = 0;

		buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]);

		if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot)
			fatal("corrupted file (201)");
	}
}


sumr(from,to)
register int *from, *to;
{
	register int sum;

	for (sum=0; from<=to; )
		sum =+ *from++;
	return(sum);
}
