USG_PG3/usr/source/sccscommon/wrtrec.c

#include "../sccshead/sfile.h"
#include "../sccshead/sint.h"
# include "../sccshead/statbuf.h"

char wrtrec__[] "~|^`wrtrec.c:	3.3";
/*
	Routine to write out either the current record in the packet
	(if nrec is zero) or the record specified by nrec and nlen.
	A record is actually written (and the x-file is only
	opened) if pkt->Pupd is non-zero.  When the current record from 
	the packet is written, pkt->Pwrttn is set non-zero, and
	further attempts to write it are ignored.  When a record is
	read into the packet, pkt->Pwrttn must be turned off.

	Call with nrec == 0 and nlen < 0 is signal to flush the buffer.

	Note that all control records which are not the current
	record in the packet (i.e., nrec != 0) are assumed to
	be in the same release and level (a reasonable assumption).

	In sequences of the form:
		I or D
		  .
		  .
		  .
		E
		I or D
		  .
		  .
		  .
	The E followed by the I or D are discarded.

	In sequences of the form:
		I or D
		E
	The I or D and the E are discarded.

*/

int x_create;


wrtrec(pkt,nrec,nlen)
register struct Packet *pkt;
register struct Control *nrec;
register int nlen;
{
	static struct Obufr obf;
	static struct Control prevctl;
	static char haveprev, lastiord;
	struct Statbuf sb;
	char *xf;

	if(pkt->Pupd == 0) return;

	if(!x_create) {
		stat(pkt->Pfile,&sb);
		xf = auxf(pkt,'x');
		crtr(&obf,xf,sb.flags);
		chown(xf,(sb.gid<<8)|sb.uid);
		x_create = 1;
		haveprev = 0;
	}
	if(haveprev) {
		haveprev = 0;
		if (ctlrec(nrec,nlen)) {
			if (nrec->Cctl==lastiord && prevctl.Cctl==END)
				return;
			if (nrec->Cctl==END &&
				(prevctl.Cctl==INS || prevctl.Cctl==DEL))
					return;
		}
		putr(&obf,&prevctl,SIZEOFCONTROL);
	}
	if (ctlrec(nrec,nlen)) {
		move(nrec,&prevctl,SIZEOFCONTROL);
		haveprev = 1;
		if(prevctl.Cctl == INS || prevctl.Cctl == DEL)
			lastiord = prevctl.Cctl;
		return;
	}
	if (nrec)
		putr(&obf,nrec,nlen);
	else {
		if(!pkt->Pwrttn++)
			putr(&obf,pkt->Pibuf.Irecptr,pkt->Pibuf.Ilen);
		if (nlen < 0) {
			flshr(&obf,0);
			close(obf.Ofildes);
		}
	}
}


xrm(pkt)
struct Packet *pkt;
{
	if(x_create) unlink(auxf(pkt,'x'));
	x_create = 0;
}