USG_PG3/usr/source/sccscommon/outbuf.c
#include "../sccshead/sfile.h"
char outbuf_[] "~|^`outbuf.c: 3.1";
/*
Bottom level write routines for SCCS files.
Usage:
struct Obufr ob;
...
crtr(&ob,"filename",0666);
...
putr(&ob,recaddr,reclen);
...
flshr(&ob);
Recaddr need not be even, but it will be written to an even address
in the file anyhow. Putr automatically computes a hash count for
the written file and stores it in address HASHADDR.
Second (non-zero) argument to flshr if present suppresses
storing of the hash count. This argument must be used for
compatibility with Release 1 of SCCS.
*/
crtr(buf,file,mode)
register struct Obufr *buf;
char file[];
int mode;
{
buf->Ofildes = xcreat(file,mode);
buf->Obuff1[0] = '\0';
buf->Orecptr = buf->Obuff1 + 1;
buf->Oend = buf->Orecptr + 510;
buf->Ohcnt = buf->Ohflag = 0;
}
struct {int *ip;};
putr(buf,rec,len)
struct Obufr *buf;
char *rec;
int len;
{
register int l;
register char *p, *r;
int lsave;
char *rsave;
l = len;
p = buf->Orecptr;
r = rec;
if(l > 255) fatal("record too big (202)");
*p++ = l - 128;
if(!(l&1)) l++;
while(1) {
while(p <= buf->Oend) {
if(l-- == 0) {
buf->Orecptr = p;
return;
}
*p++ = *r++;
}
xwrite(buf->Ofildes,p=buf->Obuff1,512);
lsave = l;
rsave = r;
if(buf->Ohflag == 0) {
buf->Ohflag = 1;
p.ip[HASHADDR>>1] = 0;
}
r.ip = p.ip + 256;
for(l=0; p.ip<r.ip; p.ip++) l =+ *p.ip;
buf->Ohcnt =+ l;
l = lsave;
r = rsave;
p = buf->Obuff1;
}
}
flshr(buf,nohash)
struct Obufr *buf;
int nohash;
{
register int n, *p, *q;
n = buf->Orecptr - buf->Obuff1;
if(n < 512) buf->Obuff1[n] = 0;
xwrite(buf->Ofildes,buf->Orecptr=buf->Obuff1,n);
p = buf->Obuff1;
q = &p[(n&1?n-1:n-2)>>1];
for(n=0; p<=q; p++) n =+ *p;
buf->Ohcnt =+ n;
if(nohash) return;
seek(buf->Ofildes,HASHADDR,0);
write(buf->Ofildes,&buf->Ohcnt,2);
}