1*2152Seric # include	"../hdr/defines.h"
2*2152Seric # include	"../hdr/had.h"
3*2152Seric 
4*2152Seric SCCSID(@(#)snull.c	4.1);
5*2152Seric USXALLOC();
6*2152Seric 
7*2152Seric int	Debug	0;
8*2152Seric struct packet gpkt;
9*2152Seric struct sid sid;
10*2152Seric int	num_files;
11*2152Seric char	had[26];
12*2152Seric FILE	*Xiop;
13*2152Seric int	Xcreate;
14*2152Seric struct deltalist {
15*2152Seric 	struct deltalist *ds_olderdel;
16*2152Seric 	struct deltalist *ds_youngerdel;
17*2152Seric 	struct sid ds_sid;
18*2152Seric 	int ds_origser;
19*2152Seric 	int ds_ser;
20*2152Seric 	int ds_pred;
21*2152Seric 	long ds_datetime;
22*2152Seric 	char ds_pgmr[8];
23*2152Seric 	char ds_type;
24*2152Seric 	struct stats ds_stats;
25*2152Seric 	int ds_insnull;
26*2152Seric };
27*2152Seric struct deltalist *Dhead;
28*2152Seric struct deltalist *Dtail;
29*2152Seric char line[512];
30*2152Seric int *New_ser_ptr;
31*2152Seric int Max_old_ser;
32*2152Seric 
33*2152Seric main(argc,argv)
34*2152Seric int argc;
35*2152Seric register char *argv[];
36*2152Seric {
37*2152Seric 	register int i;
38*2152Seric 	register char *p;
39*2152Seric 	char c;
40*2152Seric 	extern snull();
41*2152Seric 	extern int Fcnt;
42*2152Seric 
43*2152Seric 	/*
44*2152Seric 	Flags for 'fatal'.
45*2152Seric 	*/
46*2152Seric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
47*2152Seric 
48*2152Seric 	/*
49*2152Seric 	Process arguments.
50*2152Seric 	*/
51*2152Seric 	for (i = 1; i < argc; i++)
52*2152Seric 		if (argv[i][0] == '-' && (c = argv[i][1])) {
53*2152Seric 			p = &argv[i][2];
54*2152Seric 			switch (c) {
55*2152Seric 			default:
56*2152Seric 				fatal("unknown key letter (cm1)");
57*2152Seric 			}
58*2152Seric 			if (had[c - 'a']++)
59*2152Seric 				fatal("key letter twice (cm2)");
60*2152Seric 			argv[i] = 0;
61*2152Seric 		}
62*2152Seric 		else num_files++;
63*2152Seric 
64*2152Seric 	if(num_files == 0)
65*2152Seric 		fatal("missing file arg (cm3)");
66*2152Seric 
67*2152Seric 	setsig();
68*2152Seric 	/*
69*2152Seric 	Reset flags for 'fatal' so that it will return to 'main'
70*2152Seric 	rather than exiting.
71*2152Seric 	*/
72*2152Seric 	Fflags =& ~FTLEXIT;
73*2152Seric 	Fflags =| FTLJMP;
74*2152Seric 
75*2152Seric 	/*
76*2152Seric 	Invoke 'snull' for each file argument.
77*2152Seric 	*/
78*2152Seric 	for (i = 1; i < argc; i++)
79*2152Seric 		if (p = argv[i])
80*2152Seric 			do_file(p,snull);
81*2152Seric 
82*2152Seric 	exit(Fcnt ? 1 : 0);
83*2152Seric }
84*2152Seric 
85*2152Seric 
86*2152Seric snull(file)
87*2152Seric {
88*2152Seric 	register char *p;
89*2152Seric 	register int ser;
90*2152Seric 	extern char had_dir, had_standinp;
91*2152Seric 	extern char *Sflags[];
92*2152Seric 	struct stats stats;
93*2152Seric 	int newser;
94*2152Seric 
95*2152Seric 	/*
96*2152Seric 	Set up to return to caller ('main') from 'fatal'.
97*2152Seric 	*/
98*2152Seric 	if (setjmp(Fjmp))
99*2152Seric 		return;
100*2152Seric 
101*2152Seric 	sinit(&gpkt,file,1);	/* init packet and open file */
102*2152Seric 
103*2152Seric 	if (exists(auxf(gpkt.p_file,'p')))
104*2152Seric 		fatal("p-file exists (sn3)");
105*2152Seric 
106*2152Seric 	if (lockit(auxf(gpkt.p_file,'z'),2,getpid()))
107*2152Seric 		fatal("cannot create lock file (cm4)");
108*2152Seric 
109*2152Seric 	/*
110*2152Seric 	Indicate that file is to be re-opened (from beginning)
111*2152Seric 	after it reaches EOF.
112*2152Seric 	The file is read once to get the delta table
113*2152Seric 	(without copying to x-file) and then again to make
114*2152Seric 	required modifications to it (using x-file).
115*2152Seric 	*/
116*2152Seric 	gpkt.p_reopen = 1;
117*2152Seric 
118*2152Seric 	dodeltbl(&gpkt);	/* get delta table */
119*2152Seric 	flushto(&gpkt,EUSERNAM,1);
120*2152Seric 	doflags(&gpkt);		/* get flags */
121*2152Seric 
122*2152Seric 	/*
123*2152Seric 	Indicate to 'getline' that EOF is allowable.
124*2152Seric 	*/
125*2152Seric 	gpkt.p_chkeof = 1;
126*2152Seric 
127*2152Seric 	/*
128*2152Seric 	Flush through rest of file.
129*2152Seric 	This checks for corruptions.
130*2152Seric 	*/
131*2152Seric 	while (getline(&gpkt))
132*2152Seric 		;
133*2152Seric 
134*2152Seric 	if (num_files > 1 || had_dir || had_standinp)
135*2152Seric 		printf("\n%s:\n",gpkt.p_file);
136*2152Seric 
137*2152Seric 	/*
138*2152Seric 	Here, file has already been re-opened (by 'getline').
139*2152Seric 	Indicate that x-file is to be used.
140*2152Seric 	*/
141*2152Seric 	gpkt.p_upd = 1;
142*2152Seric 
143*2152Seric 	gpkt.p_wrttn = 1;
144*2152Seric 	getline(&gpkt);		/* skip over old */
145*2152Seric 	gpkt.p_wrttn = 1;	/* header record */
146*2152Seric 
147*2152Seric 	/*
148*2152Seric 	Write new header.
149*2152Seric 	*/
150*2152Seric 	putline(&gpkt,sprintf(line,"%c%c00000\n",CTLCHAR,HEAD));
151*2152Seric 	mkdelt();		/* insert 'null' deltas */
152*2152Seric 	wrtdeltbl(&gpkt);	/* write out new delta table */
153*2152Seric 
154*2152Seric 	flushto(&gpkt,EUSERNAM,0);
155*2152Seric 	/*
156*2152Seric 	If file does not have the 'n' flag, put one in.
157*2152Seric 	*/
158*2152Seric 	if (!Sflags[NULLFLAG - 'a'])
159*2152Seric 		putline(&gpkt,sprintf(line,"%c%c %c\n",CTLCHAR,
160*2152Seric 						FLAG,NULLFLAG));
161*2152Seric 
162*2152Seric 	flushto(&gpkt,EUSERTXT,0);
163*2152Seric 
164*2152Seric 	/*
165*2152Seric 	Process body, changing control-line serial numbers
166*2152Seric 	appropriately.
167*2152Seric 	*/
168*2152Seric 	fixbody(&gpkt);
169*2152Seric 
170*2152Seric 	flushline(&gpkt,0);	/* flush buffer, fix header, and close */
171*2152Seric 	rename(auxf(gpkt.p_file,'x'),gpkt.p_file);
172*2152Seric 	clean_up(0);
173*2152Seric }
174*2152Seric 
175*2152Seric 
176*2152Seric dodeltbl(pkt)
177*2152Seric register struct packet *pkt;
178*2152Seric {
179*2152Seric 	struct deltab dt;
180*2152Seric 	struct stats stats;
181*2152Seric 	struct deltalist *newp;
182*2152Seric 	int n;
183*2152Seric 
184*2152Seric 	Dhead = Dtail = newp = 0;
185*2152Seric 
186*2152Seric 	/*
187*2152Seric 	Read entire delta table.
188*2152Seric 	*/
189*2152Seric 	while (getstats(pkt,&stats)) {
190*2152Seric 		if (getadel(pkt,&dt) != BDELTAB)
191*2152Seric 			fmterr(pkt);
192*2152Seric 		newp = alloc(n = sizeof(*Dhead));
193*2152Seric 		zero(newp,n);
194*2152Seric 		if (!Dhead) {
195*2152Seric 			Dhead = newp;
196*2152Seric 			New_ser_ptr = alloc(n = 2 * (dt.d_serial + 1));
197*2152Seric 			zero(New_ser_ptr,n);
198*2152Seric 			Max_old_ser = dt.d_serial;
199*2152Seric 		}
200*2152Seric 		else {
201*2152Seric 			Dtail->ds_olderdel = newp;
202*2152Seric 			newp->ds_youngerdel = Dtail;
203*2152Seric 		}
204*2152Seric 		newp->ds_sid.s_rel = dt.d_sid.s_rel;
205*2152Seric 		newp->ds_sid.s_lev = dt.d_sid.s_lev;
206*2152Seric 		newp->ds_sid.s_br = dt.d_sid.s_br;
207*2152Seric 		newp->ds_sid.s_seq = dt.d_sid.s_seq;
208*2152Seric 		newp->ds_origser = dt.d_serial;
209*2152Seric 		newp->ds_ser = dt.d_serial;
210*2152Seric 		newp->ds_pred = dt.d_pred;
211*2152Seric 		newp->ds_datetime = dt.d_datetime;
212*2152Seric 		move(&dt.d_pgmr,newp->ds_pgmr,sizeof(dt.d_pgmr));
213*2152Seric 		newp->ds_type = dt.d_type;
214*2152Seric 		newp->ds_stats.s_ins = stats.s_ins;
215*2152Seric 		newp->ds_stats.s_del = stats.s_del;
216*2152Seric 		newp->ds_stats.s_unc = stats.s_unc;
217*2152Seric 		Dtail = newp;
218*2152Seric 
219*2152Seric 		/*
220*2152Seric 		Skip over rest of delta entry.
221*2152Seric 		*/
222*2152Seric 		while ((n = getline(pkt)) != NULL)
223*2152Seric 			if (pkt->p_line[0] != CTLCHAR)
224*2152Seric 				break;
225*2152Seric 			else {
226*2152Seric 				switch (pkt->p_line[1]) {
227*2152Seric 				case EDELTAB:
228*2152Seric 					break;
229*2152Seric 				case INCLUDE:
230*2152Seric 				case EXCLUDE:
231*2152Seric 				case IGNORE:
232*2152Seric 				case MRNUM:
233*2152Seric 				case COMMENTS:
234*2152Seric 					continue;
235*2152Seric 				default:
236*2152Seric 					fmterr(pkt);
237*2152Seric 				}
238*2152Seric 				break;
239*2152Seric 			}
240*2152Seric 		if (n == NULL || pkt->p_line[0] != CTLCHAR)
241*2152Seric 			fmterr(pkt);
242*2152Seric 	}
243*2152Seric }
244*2152Seric 
245*2152Seric 
246*2152Seric getadel(pkt,dt)
247*2152Seric register struct packet *pkt;
248*2152Seric register struct deltab *dt;
249*2152Seric {
250*2152Seric 	if (getline(pkt) == NULL)
251*2152Seric 		fmterr(pkt);
252*2152Seric 	return(del_ab(pkt->p_line,dt,pkt));
253*2152Seric }
254*2152Seric 
255*2152Seric 
256*2152Seric getstats(pkt,statp)
257*2152Seric register struct packet *pkt;
258*2152Seric register struct stats *statp;
259*2152Seric {
260*2152Seric 	register char *p;
261*2152Seric 
262*2152Seric 	p = pkt->p_line;
263*2152Seric 	if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS)
264*2152Seric 		return(0);
265*2152Seric 	NONBLANK(p);
266*2152Seric 	p = satoi(p,&statp->s_ins);
267*2152Seric 	p = satoi(++p,&statp->s_del);
268*2152Seric 	satoi(++p,&statp->s_unc);
269*2152Seric 	return(1);
270*2152Seric }
271*2152Seric 
272*2152Seric 
273*2152Seric mkdelt()
274*2152Seric {
275*2152Seric 	struct deltalist *ptr;
276*2152Seric 	struct deltalist *nulldel;
277*2152Seric 	struct deltalist *oldp;
278*2152Seric 	struct deltalist *ptrtemp;
279*2152Seric 	int n;
280*2152Seric 	int currel;
281*2152Seric 	int reldiff, numnull;
282*2152Seric 	int serhold;
283*2152Seric 
284*2152Seric 	/*
285*2152Seric 	Set current release to that of oldest (first) delta.
286*2152Seric 	*/
287*2152Seric 	currel = Dtail->ds_sid.s_rel;
288*2152Seric 
289*2152Seric 	/*
290*2152Seric 	The following loop processes each delta, starting with the
291*2152Seric 	oldest one in the file (the last one read).
292*2152Seric 	*/
293*2152Seric 	ptr = Dtail;
294*2152Seric 	while (ptr) {
295*2152Seric 		reldiff = ptr->ds_sid.s_rel - currel;
296*2152Seric 
297*2152Seric 		/*
298*2152Seric 		Skip removed deltas, branch deltas, or any delta whose
299*2152Seric 		release number is the same as the current release number.
300*2152Seric 		*/
301*2152Seric 		if (ptr->ds_type == 'R' || ptr->ds_sid.s_br ||
302*2152Seric 				 ptr->ds_sid.s_seq || reldiff == 0) {
303*2152Seric 			ptr = ptr->ds_youngerdel;
304*2152Seric 			continue;
305*2152Seric 		}
306*2152Seric 
307*2152Seric 		/*
308*2152Seric 		Check if delta is the next trunk delta in sequence, and if so
309*2152Seric 		bump up current release number and continue.
310*2152Seric 		*/
311*2152Seric 		if (reldiff == 1) {
312*2152Seric 			currel++;
313*2152Seric 			ptr = ptr->ds_youngerdel;
314*2152Seric 			continue;
315*2152Seric 		}
316*2152Seric 
317*2152Seric 		/*
318*2152Seric 		Here, a trunk delta has been found, and its release
319*2152Seric 		number is greater (by at least 2) than the current
320*2152Seric 		release number.
321*2152Seric 		This requires insertion of 'null' deltas.
322*2152Seric 		First, check that this trunk delta's release
323*2152Seric 		number is greater than currel.
324*2152Seric 		(This catches deltas whose SIDs have been changed
325*2152Seric 		by the user to make them look like trunk deltas.)
326*2152Seric 		*/
327*2152Seric 		if (reldiff < 0)
328*2152Seric 			fatal("file has invalid trunk delta (sn1)");
329*2152Seric 
330*2152Seric 		currel =+ reldiff;	/* update currel */
331*2152Seric 
332*2152Seric 		/*
333*2152Seric 		Find pointer to ancestor delta.
334*2152Seric 		*/
335*2152Seric 		oldp = ser_to_ptr(ptr->ds_pred);
336*2152Seric 
337*2152Seric 		/*
338*2152Seric 		Retain serial number for later use in fixing
339*2152Seric 		other deltas' serial numbers.
340*2152Seric 		*/
341*2152Seric 		serhold = ptr->ds_ser;
342*2152Seric 
343*2152Seric 		ptrtemp = ptr;
344*2152Seric 		numnull = reldiff;	/* number of null deltas needed */
345*2152Seric 		while (--numnull) {	/* insert null deltas */
346*2152Seric 			nulldel = alloc(n = sizeof(*Dhead));
347*2152Seric 			zero(nulldel,n);
348*2152Seric 			nulldel->ds_youngerdel = ptrtemp;
349*2152Seric 			nulldel->ds_olderdel = ptrtemp->ds_olderdel;
350*2152Seric 			ptrtemp->ds_olderdel = nulldel;
351*2152Seric 			(nulldel->ds_olderdel)->ds_youngerdel = nulldel;
352*2152Seric 			nulldel->ds_sid.s_rel = ptrtemp->ds_sid.s_rel - 1;
353*2152Seric 			nulldel->ds_sid.s_lev = 1;
354*2152Seric 			nulldel->ds_sid.s_br = 0;
355*2152Seric 			nulldel->ds_sid.s_seq = 0;
356*2152Seric 			nulldel->ds_ser = serhold + numnull - 1;
357*2152Seric 			if (numnull != 1)
358*2152Seric 				nulldel->ds_pred = nulldel->ds_ser - 1;
359*2152Seric 			else
360*2152Seric 				nulldel->ds_pred = oldp->ds_ser;
361*2152Seric 			nulldel->ds_datetime = ptr->ds_datetime;
362*2152Seric 			substr(logname(),nulldel->ds_pgmr,0,7);
363*2152Seric 			nulldel->ds_type = 'D';
364*2152Seric 			nulldel->ds_stats.s_ins = 0;
365*2152Seric 			nulldel->ds_stats.s_del = 0;
366*2152Seric 			nulldel->ds_stats.s_unc = oldp->ds_stats.s_unc +
367*2152Seric 						oldp->ds_stats.s_ins;
368*2152Seric 			nulldel->ds_insnull = 1;     /* null delta indicator */
369*2152Seric 			ptrtemp = nulldel;
370*2152Seric 		}
371*2152Seric 
372*2152Seric 		/*
373*2152Seric 		Fix up sequence and predecessor numbers of those deltas
374*2152Seric 		which are younger than the ones just processed.
375*2152Seric 		*/
376*2152Seric 		ptrtemp = ptr;
377*2152Seric 		reldiff--;
378*2152Seric 		while (ptrtemp) {
379*2152Seric 			if (ptrtemp->ds_ser >= serhold)
380*2152Seric 				ptrtemp->ds_ser =+ reldiff;
381*2152Seric 			if (ptrtemp->ds_pred >= serhold)
382*2152Seric 				ptrtemp->ds_pred =+ reldiff;
383*2152Seric 
384*2152Seric 			ptrtemp = ptrtemp->ds_youngerdel;
385*2152Seric 		}
386*2152Seric 
387*2152Seric 		/*
388*2152Seric 		Fix predecessor of current delta.
389*2152Seric 		*/
390*2152Seric 		ptr->ds_pred = serhold + reldiff - 1;
391*2152Seric 
392*2152Seric 		/*
393*2152Seric 		Point to next (non-null) delta.
394*2152Seric 		*/
395*2152Seric 		ptr = ptr->ds_youngerdel;
396*2152Seric 	}
397*2152Seric 
398*2152Seric 	/*
399*2152Seric 	Create array of original values of serial numbers of
400*2152Seric 	the original deltas.
401*2152Seric 	*/
402*2152Seric 	ptr = Dtail;
403*2152Seric 	while (ptr) {
404*2152Seric 		if (ptr->ds_insnull != 1)
405*2152Seric 			New_ser_ptr[ptr->ds_origser] = ptr->ds_ser;
406*2152Seric 		ptr = ptr->ds_youngerdel;
407*2152Seric 	}
408*2152Seric }
409*2152Seric 
410*2152Seric 
411*2152Seric ser_to_ptr(ser)
412*2152Seric int ser;
413*2152Seric {
414*2152Seric 	struct deltalist *ptr;
415*2152Seric 
416*2152Seric 	ptr = Dtail;
417*2152Seric 	while (ptr) {
418*2152Seric 		if (ptr->ds_ser == ser)
419*2152Seric 			return(ptr);
420*2152Seric 		ptr = ptr->ds_youngerdel;
421*2152Seric 	}
422*2152Seric 	fatal("internal error -- ser_to_ptr (sn2)");
423*2152Seric }
424*2152Seric 
425*2152Seric 
426*2152Seric wrtdeltbl(pkt)
427*2152Seric register struct packet *pkt;
428*2152Seric {
429*2152Seric 	struct deltalist *ptr;
430*2152Seric 	char *p;
431*2152Seric 	int ser;
432*2152Seric 
433*2152Seric 	/*
434*2152Seric 	The following loop writes out the new delta table.
435*2152Seric 	*/
436*2152Seric 	ptr = Dhead;
437*2152Seric 	while (ptr) {
438*2152Seric 		if (ptr->ds_insnull) {		/* 'null' delta */
439*2152Seric 			/*
440*2152Seric 			Write out statistics line.
441*2152Seric 			*/
442*2152Seric 			putline(pkt,sprintf(line,"%c%c %05u/%05u/%05u\n",
443*2152Seric 				CTLCHAR,STATS,ptr->ds_stats.s_ins,
444*2152Seric 						ptr->ds_stats.s_del,
445*2152Seric 						ptr->ds_stats.s_unc));
446*2152Seric 
447*2152Seric 			/*
448*2152Seric 			Write 'delta' line, taken from
449*2152Seric 			in-core list.
450*2152Seric 			*/
451*2152Seric 			putdel(pkt,ptr);
452*2152Seric 
453*2152Seric 			putline(pkt,sprintf(line,"%c%c %s\n",CTLCHAR,COMMENTS,
454*2152Seric 					"INSERTED BY SNULL"));
455*2152Seric 			putline(pkt,sprintf(line,CTLSTR,CTLCHAR,EDELTAB));
456*2152Seric 		}
457*2152Seric 		else {
458*2152Seric 			getline(pkt);		/* statistics line */
459*2152Seric 			getline(pkt);		/* 'delta' line */
460*2152Seric 
461*2152Seric 			/*
462*2152Seric 			Indicate not to output previously read line.
463*2152Seric 			*/
464*2152Seric 			pkt->p_wrttn = 1;
465*2152Seric 
466*2152Seric 			/*
467*2152Seric 			Write 'delta' line from in-core list.
468*2152Seric 			*/
469*2152Seric 			putdel(pkt,ptr);
470*2152Seric 
471*2152Seric 			/*
472*2152Seric 			Process rest of entry, changeing serial
473*2152Seric 			numbers of deltas included, excluded,
474*2152Seric 			or ignored.
475*2152Seric 			*/
476*2152Seric 			while (getline(pkt))
477*2152Seric 				if (pkt->p_line[0] != CTLCHAR)
478*2152Seric 					break;
479*2152Seric 				else {
480*2152Seric 					switch (*(p = &pkt->p_line[1])) {
481*2152Seric 					case EDELTAB:
482*2152Seric 						putline(pkt,0);
483*2152Seric 						break;
484*2152Seric 					case INCLUDE:
485*2152Seric 					case EXCLUDE:
486*2152Seric 					case IGNORE:
487*2152Seric 						pkt->p_wrttn = 1;
488*2152Seric 						putline(pkt,sprintf(line,
489*2152Seric 							"%c%c",CTLCHAR,*p++));
490*2152Seric 						NONBLANK(p);
491*2152Seric 						while (numeric(*p)) {
492*2152Seric 							p = satoi(p,&ser);
493*2152Seric 
494*2152Seric 							if (!(ser > 0 &&
495*2152Seric 							ser <= Max_old_ser))
496*2152Seric 								fmterr(pkt);
497*2152Seric 
498*2152Seric 							putline(pkt,sprintf(
499*2152Seric 							line," %u",
500*2152Seric 							New_ser_ptr[ser]));
501*2152Seric 
502*2152Seric 							NONBLANK(p);
503*2152Seric 						}
504*2152Seric 						putline(pkt,"\n");
505*2152Seric 						continue;
506*2152Seric 					default:
507*2152Seric 						putline(pkt,0);
508*2152Seric 						continue;
509*2152Seric 					}
510*2152Seric 					break;
511*2152Seric 				}
512*2152Seric 		}
513*2152Seric 
514*2152Seric 		/*
515*2152Seric 		Point to next delta to be output.
516*2152Seric 		*/
517*2152Seric 		ptr = ptr->ds_olderdel;
518*2152Seric 	}
519*2152Seric }
520*2152Seric 
521*2152Seric 
522*2152Seric putdel(pkt,ptr)
523*2152Seric struct packet *pkt;
524*2152Seric struct deltalist *ptr;
525*2152Seric {
526*2152Seric 	struct deltab dt;
527*2152Seric 
528*2152Seric 	move(&ptr->ds_sid,&dt.d_sid,sizeof(dt.d_sid));
529*2152Seric 	dt.d_serial = ptr->ds_ser;
530*2152Seric 	dt.d_pred = ptr->ds_pred;
531*2152Seric 	dt.d_datetime = ptr->ds_datetime;
532*2152Seric 	move(ptr->ds_pgmr,&dt.d_pgmr,sizeof(dt.d_pgmr));
533*2152Seric 	dt.d_type = ptr->ds_type;
534*2152Seric 
535*2152Seric 	del_ba(&dt,line);
536*2152Seric 	putline(pkt,line);
537*2152Seric }
538*2152Seric 
539*2152Seric 
540*2152Seric fixbody(pkt)
541*2152Seric register struct packet *pkt;
542*2152Seric {
543*2152Seric 	int ser;
544*2152Seric 	char *p, type;
545*2152Seric 
546*2152Seric 	while (getline(pkt)) {
547*2152Seric 		p = pkt->p_line;
548*2152Seric 
549*2152Seric 		if (*p++ == CTLCHAR) {
550*2152Seric 			if (!((type = *p++) == INS || type == DEL ||
551*2152Seric 							type == END))
552*2152Seric 				fmterr(pkt);
553*2152Seric 			NONBLANK(p);
554*2152Seric 			satoi(p,&ser);
555*2152Seric 			if (!(ser > 0 && ser <= Max_old_ser))
556*2152Seric 				fmterr(pkt);
557*2152Seric 
558*2152Seric 			/*
559*2152Seric 			Indicate not to output line just read.
560*2152Seric 			*/
561*2152Seric 			pkt->p_wrttn = 1;
562*2152Seric 
563*2152Seric 			/*
564*2152Seric 			Output new value of sequence number.
565*2152Seric 			*/
566*2152Seric 			putline(pkt,sprintf(line,"%c%c %u\n",CTLCHAR,type,
567*2152Seric 						New_ser_ptr[ser]));
568*2152Seric 		}
569*2152Seric 	}
570*2152Seric }
571*2152Seric 
572*2152Seric 
573*2152Seric clean_up(n)
574*2152Seric {
575*2152Seric 	if (gpkt.p_file[0])
576*2152Seric 		unlockit(auxf(gpkt.p_file,'z'),getpid());
577*2152Seric 	if (gpkt.p_iop)
578*2152Seric 		fclose(gpkt.p_iop);
579*2152Seric 	xrm(&gpkt);
580*2152Seric 	xfreeall();
581*2152Seric }
582