1bac5051cSeric /*************************************************************************/
2bac5051cSeric /*									 */
3bac5051cSeric /*	prs [-d<dataspec>] [-r<sid>] [-c<cutoff>] [-a]			 */
4bac5051cSeric /*	    [-y<reverse-cutoff>] file ...				 */
5bac5051cSeric /*									 */
6bac5051cSeric /*************************************************************************/
7bac5051cSeric 
8bac5051cSeric /*
9bac5051cSeric 	Program to print parts or all of an SCCS file
10bac5051cSeric 	in user supplied format.
11bac5051cSeric 	Arguments to the program may appear in any order
12bac5051cSeric 	and consist of keyletters, which begin with '-',
13bac5051cSeric 	and named files.
14bac5051cSeric 
15bac5051cSeric 	If a direcory is given as an argument, each
16bac5051cSeric 	SCCS file within the directory is processed as if
17bac5051cSeric 	it had been specifically named. If a name of '-'
18bac5051cSeric 	is given, the standard input is read for a list
19bac5051cSeric 	of names of SCCS files to be processed.
20bac5051cSeric 	Non-SCCS files are ignored.
21bac5051cSeric */
22bac5051cSeric 
23bac5051cSeric # include "../hdr/defines.h"
24bac5051cSeric # include "../hdr/had.h"
25bac5051cSeric 
26*824dd99bSbostic static char Sccsid[] = "@(#)prs.c	4.3	02/02/88";
27bac5051cSeric 
28bac5051cSeric char	had[26];
295b29b8bcSlepreau char	Getpgm[] = "/usr/local/get";
30bac5051cSeric char	Sid[32];
31bac5051cSeric char	Mod[16];
32bac5051cSeric char	*Type;
33bac5051cSeric char	Deltadate[18];
34bac5051cSeric char	*Deltatime;
355b29b8bcSlepreau char	tempskel[] = "/tmp/prXXXXXX";	/* used to generate temp file names */
365b29b8bcSlepreau 
37bac5051cSeric char	untmp[32], uttmp[32], cmtmp[32];
38bac5051cSeric char	mrtmp[32], bdtmp[32];
39bac5051cSeric FILE	*UNiop;
40bac5051cSeric FILE	*UTiop;
41bac5051cSeric FILE	*CMiop;
42bac5051cSeric FILE	*MRiop;
43bac5051cSeric FILE	*BDiop;
44bac5051cSeric char	line[BUFSIZ];
45bac5051cSeric int	num_files;
46bac5051cSeric long	cutoff;
47bac5051cSeric long	revcut;
48bac5051cSeric char	*dataspec;
49bac5051cSeric char	iline[BUFSIZ], xline[BUFSIZ], gline[BUFSIZ];
50bac5051cSeric char	*maket();
51bac5051cSeric struct	packet	gpkt;
52bac5051cSeric struct	sid	sid;
534a6a95bbSeric struct	tm	*Dtime;
54bac5051cSeric 
main(argc,argv)55bac5051cSeric main(argc,argv)
56bac5051cSeric int argc;
57bac5051cSeric char *argv[];
58bac5051cSeric {
59bac5051cSeric 	register int j;
60bac5051cSeric 	register char *p;
61bac5051cSeric 	char c;
62bac5051cSeric 	extern prs();
63bac5051cSeric 	extern int Fcnt;
64bac5051cSeric 
65bac5051cSeric 	/*
66bac5051cSeric 	Set flags for 'fatal' to issue message, call clean-up
67bac5051cSeric 	routine, and terminate processing.
68bac5051cSeric 	*/
69bac5051cSeric 	Fflags = FTLMSG | FTLCLN | FTLEXIT;
70bac5051cSeric 
71bac5051cSeric 
72bac5051cSeric 	/*
73bac5051cSeric 	The following loop processes keyletters and arguments.
74bac5051cSeric 	Note that these are processed only once for each
75bac5051cSeric 	invocation of 'main'.
76bac5051cSeric 	*/
77bac5051cSeric 	for (j = 1; j < argc; j++)
78bac5051cSeric 		if (argv[j][0] == '-' && (c = argv[j][1])) {
79bac5051cSeric 			p = &argv[j][2];
80bac5051cSeric 			switch (c) {
81bac5051cSeric 
82bac5051cSeric 			case 'r':	/* delta cutoff */
83bac5051cSeric 				if (*p) {
84bac5051cSeric 					if (invalid(p))
85bac5051cSeric 						fatal("invalid sid (co8)");
86bac5051cSeric 					sid_ab(p,&sid);
87bac5051cSeric 				}
88bac5051cSeric 				break;
89bac5051cSeric 
90bac5051cSeric 			case 'c':	/* time cutoff */
91bac5051cSeric 				if (*p && date_ab(p,&cutoff))
92bac5051cSeric 					fatal("bad date/time (cm5)");
93bac5051cSeric 				break;
94bac5051cSeric 
95bac5051cSeric 			case 'y':	/* reverse time cutoff */
96bac5051cSeric 				if (*p && date_ab(p,&revcut))
97bac5051cSeric 					fatal ("bad date/time (cm5)");
98bac5051cSeric 				break;
99bac5051cSeric 
100bac5051cSeric 			case 'a':
101bac5051cSeric 				if (*p)
102bac5051cSeric 					fatal("value after a arg (cm7)");
103bac5051cSeric 				break;
104bac5051cSeric 			case 'd':	/* dataspec line */
105bac5051cSeric 				dataspec = p;
106bac5051cSeric 				break;
107bac5051cSeric 			default:
108bac5051cSeric 				fatal("unknown key letter (cm1)");
109bac5051cSeric 			}
110bac5051cSeric 
111bac5051cSeric 			if (had[c - 'a']++)
112bac5051cSeric 				fatal("key letter twice (cm2)");
113bac5051cSeric 			argv[j] = 0;
114bac5051cSeric 		}
115bac5051cSeric 		else
116bac5051cSeric 			num_files++;
117bac5051cSeric 
118bac5051cSeric 	if (num_files == 0)
119bac5051cSeric 		fatal("missing file arg (cm3)");
120bac5051cSeric 
121bac5051cSeric 	if (!HADD)
122bac5051cSeric 		exit(0);
123bac5051cSeric 	if (HADC && HADY)
124bac5051cSeric 		fatal("both 'c' and 'y' keyletters specified (prs2)");
125bac5051cSeric 
126bac5051cSeric 	setsig();
127bac5051cSeric 
128bac5051cSeric 	/*
129bac5051cSeric 	Change flags for 'fatal' so that it will return to this
130bac5051cSeric 	routine (main) instead of terminating processing.
131bac5051cSeric 	*/
1325b29b8bcSlepreau 	Fflags &= ~FTLEXIT;
1335b29b8bcSlepreau 	Fflags |= FTLJMP;
134bac5051cSeric 
135bac5051cSeric 	/*
136bac5051cSeric 	Call 'prs' routine for each file argument.
137bac5051cSeric 	*/
138bac5051cSeric 	for (j = 1; j < argc; j++)
139bac5051cSeric 		if (p = argv[j])
140bac5051cSeric 			do_file(p,prs);
141bac5051cSeric 
142bac5051cSeric 	exit(Fcnt ? 1 : 0);
143bac5051cSeric }
144bac5051cSeric 
145bac5051cSeric 
prs(file)146bac5051cSeric prs(file)
147bac5051cSeric register	char	*file;
148bac5051cSeric {
149bac5051cSeric 	int	n;
150bac5051cSeric 	extern	char	had_dir, had_standinp;
151bac5051cSeric 
152bac5051cSeric 	if (setjmp(Fjmp))
153bac5051cSeric 		return;
154bac5051cSeric 	sinit(&gpkt,file,1);	/* init packet and open SCCS file */
155bac5051cSeric 
156bac5051cSeric 	gpkt.p_reqsid.s_rel = sid.s_rel;
157bac5051cSeric 	gpkt.p_reqsid.s_lev = sid.s_lev;
158bac5051cSeric 	gpkt.p_reqsid.s_br = sid.s_br;
159bac5051cSeric 	gpkt.p_reqsid.s_seq = sid.s_seq;
160bac5051cSeric 	gpkt.p_cutoff = cutoff;
161bac5051cSeric 	gpkt.p_reopen = 1;
162bac5051cSeric 
163bac5051cSeric 	/*
164bac5051cSeric 	read delta table entries checking only for format error
165bac5051cSeric 	*/
166bac5051cSeric 	deltblchk(&gpkt);
167bac5051cSeric 
168bac5051cSeric 	/*
169bac5051cSeric 	create auxiliary file for User Name Section
170bac5051cSeric 	*/
171bac5051cSeric 
172bac5051cSeric 	aux_create(UNiop,untmp,EUSERNAM);
173bac5051cSeric 
174bac5051cSeric 	doflags(&gpkt);
175bac5051cSeric 
176bac5051cSeric 	/*
177bac5051cSeric 	create auxiliary file for the User Text section
178bac5051cSeric 	*/
179bac5051cSeric 
180bac5051cSeric 	aux_create(UTiop,uttmp,EUSERTXT);
181bac5051cSeric 
182bac5051cSeric 	/*
183bac5051cSeric 	indicate to 'getline' that EOF is okay
184bac5051cSeric 	*/
185bac5051cSeric 	gpkt.p_chkeof = 1;
186bac5051cSeric 
187bac5051cSeric 	/*
188bac5051cSeric 	read body of SCCS file and create temp file for it
189bac5051cSeric 	*/
190bac5051cSeric 	while(read_mod(&gpkt))
191bac5051cSeric 		;
192bac5051cSeric 
193bac5051cSeric 	if (num_files > 1 || had_dir || had_standinp)
194bac5051cSeric 		printf("\n%s:\n",gpkt.p_file);
195bac5051cSeric 	/*
196bac5051cSeric 	Here, file has already been re-opened (by 'getline')
197bac5051cSeric 	*/
198bac5051cSeric 	getline(&gpkt);		/* skip over header line */
199bac5051cSeric 
200bac5051cSeric 	/*
201bac5051cSeric 	call dodeltbl to read delta table entries
202bac5051cSeric 	*/
203bac5051cSeric 
204bac5051cSeric 	dodeltbl(&gpkt);
205bac5051cSeric 
206bac5051cSeric 	clean_up();
207bac5051cSeric 
208bac5051cSeric 	return;
209bac5051cSeric }
210bac5051cSeric 
211bac5051cSeric 
dodeltbl(pkt)212bac5051cSeric dodeltbl(pkt)
213bac5051cSeric register struct packet *pkt;
214bac5051cSeric {
215bac5051cSeric 	int	n;
216bac5051cSeric 	struct	deltab	dt;
217bac5051cSeric 	struct	stats	stats;
218bac5051cSeric 
219bac5051cSeric 	/*
220bac5051cSeric 	Read entire delta table.
221bac5051cSeric 	*/
222bac5051cSeric 	while (getstats(pkt,&stats)) {
223bac5051cSeric 		if (getadel(pkt,&dt) != BDELTAB)
224bac5051cSeric 			fmterr(pkt);
225bac5051cSeric 
226bac5051cSeric 		/*
227bac5051cSeric 		Read rest of delta entry.
228bac5051cSeric 		*/
229bac5051cSeric 		while ((n = getline(pkt)) != NULL)
230bac5051cSeric 			if (pkt->p_line[0] != CTLCHAR)
231bac5051cSeric 				break;
232bac5051cSeric 			else {
233bac5051cSeric 				switch (pkt->p_line[1]) {
234bac5051cSeric 				case EDELTAB:
235bac5051cSeric 					scanspec(dataspec,&dt,&stats);
236bac5051cSeric 					break;
237bac5051cSeric 				case INCLUDE:
238bac5051cSeric 					getit(iline,n);
239bac5051cSeric 					continue;
240bac5051cSeric 				case EXCLUDE:
241bac5051cSeric 					getit(xline,n);
242bac5051cSeric 					continue;
243bac5051cSeric 				case IGNORE:
244bac5051cSeric 					getit(gline,n);
245bac5051cSeric 					continue;
246bac5051cSeric 				case MRNUM:
247bac5051cSeric 				case COMMENTS:
248bac5051cSeric 					continue;
249bac5051cSeric 				default:
250bac5051cSeric 					fmterr(pkt);
251bac5051cSeric 				}
252bac5051cSeric 				break;
253bac5051cSeric 			}
254bac5051cSeric 		if (n == NULL || pkt->p_line[0] != CTLCHAR)
255bac5051cSeric 			fmterr(pkt);
256bac5051cSeric 	}
257bac5051cSeric }
258bac5051cSeric 
259bac5051cSeric 
260bac5051cSeric /*
261bac5051cSeric  * The scanspec procedure scans the dataspec searching for ID keywords.
262bac5051cSeric  * When a keyword is found the value is replaced and printed on the
263bac5051cSeric  * standard output. Any character that is not an ID keyword is printed
264bac5051cSeric  * immediately.
265bac5051cSeric */
266bac5051cSeric 
2675b29b8bcSlepreau static	char	Zkeywd[5] = "@(#)";
scanspec(spec,dtp,statp)268bac5051cSeric scanspec(spec,dtp,statp)
269bac5051cSeric char spec[];
270bac5051cSeric struct	deltab	*dtp;
271bac5051cSeric struct	stats	*statp;
272bac5051cSeric {
273bac5051cSeric 
274bac5051cSeric 	extern	char	*Sflags[];
275bac5051cSeric 	register char *lp;
276bac5051cSeric 	register char	*k;
277bac5051cSeric 	union {
278bac5051cSeric 		char	str[2];
2794a6a95bbSeric 		short	istr;
280bac5051cSeric 	} u;
281bac5051cSeric 	register	char	c;
282bac5051cSeric 
283bac5051cSeric 	idsetup(&dtp->d_sid,&gpkt,&dtp->d_datetime);
284bac5051cSeric 	for(lp = spec; *lp != 0; lp++) {
285bac5051cSeric 		if(lp[0] == ':' && lp[1] != 0 && lp[2] == ':') {
286bac5051cSeric 			c = *++lp;
287bac5051cSeric 			switch (c) {
288bac5051cSeric 			case 'I':	/* SID */
289bac5051cSeric 				printf("%s",Sid);
290bac5051cSeric 				break;
291bac5051cSeric 			case 'R':	/* Release number */
292bac5051cSeric 				printf("%u",dtp->d_sid.s_rel);
293bac5051cSeric 				break;
294bac5051cSeric 			case 'L':	/* Level number */
295bac5051cSeric 				printf("%u",dtp->d_sid.s_lev);
296bac5051cSeric 				break;
297bac5051cSeric 			case 'B':	/* Branch number */
298bac5051cSeric 				if (dtp->d_sid.s_br != 0)
299bac5051cSeric 					printf("%u",dtp->d_sid.s_br);
300bac5051cSeric 				break;
301bac5051cSeric 			case 'S':	/* Sequence number */
302bac5051cSeric 				if (dtp->d_sid.s_seq != 0)
303bac5051cSeric 					printf("%u",dtp->d_sid.s_seq);
304bac5051cSeric 				break;
305bac5051cSeric 			case 'D':	/* Date delta created */
306bac5051cSeric 				printf("%s",Deltadate);
307bac5051cSeric 				break;
308bac5051cSeric 			case 'T':	/* Time delta created */
309bac5051cSeric 				printf("%s",Deltatime);
310bac5051cSeric 				break;
311bac5051cSeric 			case 'P':	/* Programmer who created delta */
312bac5051cSeric 				printf("%s",dtp->d_pgmr);
313bac5051cSeric 				break;
314bac5051cSeric 			case 'C':	/* Comments */
315bac5051cSeric 				break;
316bac5051cSeric 			case 'Y':	/* Type flag */
317bac5051cSeric 				printf("%s",Type);
318bac5051cSeric 				break;
319bac5051cSeric 			case 'M':	/* Module name */
320bac5051cSeric 				printf("%s",Mod);
321bac5051cSeric 				break;
322bac5051cSeric 			case 'W':	/* Form of what string */
323bac5051cSeric 				printf("%s",Zkeywd);
324bac5051cSeric 				printf("%s",Mod);
325bac5051cSeric 				putchar('\t');
326bac5051cSeric 				printf("%s",Sid);
327bac5051cSeric 				break;
328bac5051cSeric 			case 'A':	/* Form of what string */
329bac5051cSeric 				printf("%s",Zkeywd);
330bac5051cSeric 				printf("%s ",Type);
331bac5051cSeric 				printf("%s ",Mod);
332bac5051cSeric 				printf("%s",Sid);
333bac5051cSeric 				printf("%s",Zkeywd);
334bac5051cSeric 				break;
335bac5051cSeric 			case 'Z':	/* what string constructor */
336bac5051cSeric 				printf("%s",Zkeywd);
337bac5051cSeric 				break;
338bac5051cSeric 			case 'F':	/* File name */
339bac5051cSeric 				printf("%s",sname(gpkt.p_file));
340bac5051cSeric 				break;
341bac5051cSeric 			default:
342bac5051cSeric 				putchar(':');
343bac5051cSeric 				putchar(c);
344bac5051cSeric 				putchar(':');
345bac5051cSeric 				break;
346bac5051cSeric 			}
347bac5051cSeric 			lp++;
348bac5051cSeric 		}
349bac5051cSeric 		else if(lp[0] == ':' && lp[1] != 0 && lp[2] !=0 && lp[3] == ':') {
350bac5051cSeric 			if (lp[1] == ':') {
351bac5051cSeric 				putchar(':');
3525b29b8bcSlepreau 				*lp += 2;
353bac5051cSeric 				continue;
354bac5051cSeric 			}
355bac5051cSeric 			u.str[1] = *++lp;
3564a6a95bbSeric 			u.str[0] = *++lp;
357bac5051cSeric 			switch (u.istr) {
358bac5051cSeric 			case 'Dl':	/* Delta line statistics */
359bac5051cSeric 				printf("%05d",statp->s_ins);
360bac5051cSeric 				putchar('/');
361bac5051cSeric 				printf("%05d",statp->s_del);
362bac5051cSeric 				putchar('/');
363bac5051cSeric 				printf("%05d",statp->s_unc);
364bac5051cSeric 				break;
365bac5051cSeric 			case 'Li':	/* Lines inserted by delta */
366bac5051cSeric 				printf("%05d",statp->s_ins);
367bac5051cSeric 				break;
368bac5051cSeric 			case 'Ld':	/* Lines deleted by delta */
369bac5051cSeric 				printf("%05d",statp->s_del);
370bac5051cSeric 				break;
371bac5051cSeric 			case 'Lu':	/* Lines unchanged by delta */
372bac5051cSeric 				printf("%05d",statp->s_unc);
373bac5051cSeric 				break;
374bac5051cSeric 			case 'DT':	/* Delta type */
375bac5051cSeric 				printf("%c",dtp->d_type);
376bac5051cSeric 				break;
377bac5051cSeric 			case 'Dy':	/* Year delta created */
3784a6a95bbSeric 				printf("%02d",Dtime->tm_year);
379bac5051cSeric 				break;
380bac5051cSeric 			case 'Dm':	/* Month delta created */
3814a6a95bbSeric 				printf("%02d",(Dtime->tm_mon + 1));
382bac5051cSeric 				break;
383bac5051cSeric 			case 'Dd':	/* Day delta created */
3844a6a95bbSeric 				printf("%02d",Dtime->tm_mday);
385bac5051cSeric 				break;
386bac5051cSeric 			case 'Th':	/* Hour delta created */
3874a6a95bbSeric 				printf("%02d",Dtime->tm_hour);
388bac5051cSeric 				break;
389bac5051cSeric 			case 'Tm':	/* Minutes delta created */
3904a6a95bbSeric 				printf("%02d",Dtime->tm_min);
391bac5051cSeric 				break;
392bac5051cSeric 			case 'Ts':	/* Seconds delta created */
3934a6a95bbSeric 				printf("%02d",Dtime->tm_sec);
394bac5051cSeric 				break;
395bac5051cSeric 			case 'DS':	/* Delta sequence number */
396bac5051cSeric 				printf("%d",dtp->d_serial);
397bac5051cSeric 				break;
398bac5051cSeric 			case 'DP':	/* Predecessor delta sequence number */
399bac5051cSeric 				printf("%d",dtp->d_pred);
400bac5051cSeric 				break;
401bac5051cSeric 			case 'DI':	/* Deltas included,excluded,ignored */
402bac5051cSeric 				printf("%s",iline);
403bac5051cSeric 				putchar('/');
404bac5051cSeric 				printf("%s",xline);
405bac5051cSeric 				putchar('/');
406bac5051cSeric 				printf("%s",gline);
407bac5051cSeric 				break;
408bac5051cSeric 			case 'Di':	/* Deltas included */
409bac5051cSeric 				printf("%s",iline);
410bac5051cSeric 				break;
411bac5051cSeric 			case 'Dx':	/* Deltas excluded */
412bac5051cSeric 				printf("%s",xline);
413bac5051cSeric 				break;
414bac5051cSeric 			case 'Dg':	/* Deltas ignored */
415bac5051cSeric 				printf("%s",gline);
416bac5051cSeric 				break;
417bac5051cSeric 			case 'MR':	/* MR numbers */
418bac5051cSeric 				break;
419bac5051cSeric 			case 'UN':	/* User names */
420bac5051cSeric 				printfile(untmp);
421bac5051cSeric 				break;
422bac5051cSeric 			case 'MF':	/* MR validation flag */
423bac5051cSeric 				if (Sflags[VALFLAG - 'a'])
424bac5051cSeric 					printf("yes");
425bac5051cSeric 				else printf("no");
426bac5051cSeric 				break;
427bac5051cSeric 			case 'MP':	/* MR validation program */
428bac5051cSeric 				if (!(k = Sflags[VALFLAG - 'a']))
429bac5051cSeric 					printf("none");
430bac5051cSeric 				else printf("%s",k);
431bac5051cSeric 				break;
432bac5051cSeric 			case 'KF':	/* Keyword err/warn flag */
433bac5051cSeric 				if (Sflags[IDFLAG - 'a'])
434bac5051cSeric 					printf("yes");
435bac5051cSeric 				else printf("no");
436bac5051cSeric 				break;
437bac5051cSeric 			case 'BF':	/* Branch flag */
438bac5051cSeric 				if (Sflags[BRCHFLAG - 'a'])
439bac5051cSeric 					printf("yes");
440bac5051cSeric 				else printf("no");
441bac5051cSeric 				break;
442bac5051cSeric 			case 'FB':	/* Floor Boundry */
443bac5051cSeric 				if (k = Sflags[FLORFLAG - 'a'])
444bac5051cSeric 					printf("%s",k);
445bac5051cSeric 				else printf("none");
446bac5051cSeric 				break;
447bac5051cSeric 			case 'CB':	/* Ceiling Boundry */
448bac5051cSeric 				if (k = Sflags[CEILFLAG - 'a'])
449bac5051cSeric 					printf("%s",k);
450bac5051cSeric 				else printf("none");
451bac5051cSeric 				break;
452bac5051cSeric 			case 'Ds':	/* Default SID */
453bac5051cSeric 				if (k = Sflags[DEFTFLAG - 'a'])
454bac5051cSeric 					printf("%s",k);
455bac5051cSeric 				else printf("none");
456bac5051cSeric 				break;
457bac5051cSeric 			case 'ND':	/* Null delta */
458bac5051cSeric 				if (Sflags[NULLFLAG - 'a'])
459bac5051cSeric 					printf("yes");
460bac5051cSeric 				else printf("no");
461bac5051cSeric 				break;
462bac5051cSeric 			case 'FD':	/* File descriptive text */
463bac5051cSeric 				printfile(uttmp);
464bac5051cSeric 				break;
465bac5051cSeric 			case 'BD':	/* Entire file body */
466bac5051cSeric 				printfile(bdtmp);
467bac5051cSeric 				break;
468bac5051cSeric 			case 'GB':	/* Gotten body from 'get' */
469bac5051cSeric 				getbody(&dtp->d_sid,&gpkt);
470bac5051cSeric 				break;
471bac5051cSeric 			default:
472bac5051cSeric 				putchar(':');
473bac5051cSeric 				printf("%c",u.istr);
474bac5051cSeric 				putchar(':');
475bac5051cSeric 				break;
476bac5051cSeric 			}
477bac5051cSeric 			lp++;
478bac5051cSeric 		}
479bac5051cSeric 		else {
480bac5051cSeric 			c = *lp;
481bac5051cSeric 			if (c == '\\') {
482bac5051cSeric 				switch(*++lp) {
483bac5051cSeric 				case 'n':	/* for newline */
484bac5051cSeric 					putchar('\n');
485bac5051cSeric 					break;
486bac5051cSeric 				case ':':	/* for wanted colon */
487bac5051cSeric 					putchar(':');
488bac5051cSeric 					break;
489bac5051cSeric 				case 't':	/* for tab */
490bac5051cSeric 					putchar('\t');
491bac5051cSeric 					break;
492bac5051cSeric 				case 'b':	/* for backspace */
493bac5051cSeric 					putchar('\b');
494bac5051cSeric 					break;
495bac5051cSeric 				case 'r':	/* for carriage return */
496bac5051cSeric 					putchar('\r');
497bac5051cSeric 					break;
498bac5051cSeric 				case 'f':	/* for form feed */
499bac5051cSeric 					putchar('\f');
500bac5051cSeric 					break;
501bac5051cSeric 				case '\\':	/* for backslash */
502bac5051cSeric 					putchar('\\');
503bac5051cSeric 					break;
504bac5051cSeric 				case '\'':	/* for single quote */
505bac5051cSeric 					putchar('\'');
506bac5051cSeric 					break;
507bac5051cSeric 				default:	/* unknown case */
508bac5051cSeric 					putchar('\\');
509bac5051cSeric 					putchar(*lp);
510bac5051cSeric 					break;
511bac5051cSeric 				}
512bac5051cSeric 			}
513bac5051cSeric 			else putchar(*lp);
514bac5051cSeric 		}
515bac5051cSeric 	}
516bac5051cSeric 	/*
517bac5051cSeric 	zero out first char of global string lines in case
518bac5051cSeric 	a value is not gotten in next delta table entry
519bac5051cSeric 	*/
520bac5051cSeric 	iline[0] = xline[0] = gline[0] = 0;
521bac5051cSeric 	putchar('\n');
522bac5051cSeric 	return;
523bac5051cSeric }
524bac5051cSeric 
525bac5051cSeric 
clean_up()526bac5051cSeric clean_up()
527bac5051cSeric {
528bac5051cSeric 	unlink(untmp);
529bac5051cSeric 	unlink(uttmp);
530bac5051cSeric 	unlink(bdtmp);
5314a6a95bbSeric 	if (gpkt.p_iop)
5324a6a95bbSeric 		fclose(gpkt.p_iop);
533bac5051cSeric }
534bac5051cSeric 
535bac5051cSeric 
536bac5051cSeric /* This function takes as it's argument the SID inputed and determines
537bac5051cSeric  * whether or not it is valid (e. g. not ambiguous or illegal).
538bac5051cSeric */
invalid(i_sid)539bac5051cSeric invalid(i_sid)
540bac5051cSeric register char	*i_sid;
541bac5051cSeric {
542bac5051cSeric 	register int count;
543bac5051cSeric 	register int digits;
544bac5051cSeric 	count = digits = 0;
545bac5051cSeric 	if (*i_sid == '0' || *i_sid == '.')
546bac5051cSeric 		return (1);
547bac5051cSeric 	i_sid++;
548bac5051cSeric 	digits++;
549bac5051cSeric 	while (*i_sid != '\0') {
550bac5051cSeric 		if (*i_sid++ == '.') {
551bac5051cSeric 			digits = 0;
552bac5051cSeric 			count++;
553bac5051cSeric 			if (*i_sid == '0' || *i_sid == '.')
554bac5051cSeric 				return (1);
555bac5051cSeric 		}
556bac5051cSeric 		digits++;
557bac5051cSeric 		if (digits > 5)
558bac5051cSeric 			return (1);
559bac5051cSeric 	}
560bac5051cSeric 	if (*(--i_sid) == '.' )
561bac5051cSeric 		return (1);
562bac5051cSeric 	if (count == 1 || count == 3)
563bac5051cSeric 		return (0);
564bac5051cSeric 	return (1);
565bac5051cSeric }
566bac5051cSeric 
567bac5051cSeric 
deltblchk(pkt)568bac5051cSeric deltblchk(pkt)
569bac5051cSeric register struct packet *pkt;
570bac5051cSeric {
571bac5051cSeric 	int	n;
572bac5051cSeric 	struct	deltab	dt;
573bac5051cSeric 	struct	stats	stats;
574bac5051cSeric 
575bac5051cSeric 	/*
576bac5051cSeric 	Read entire delta table.
577bac5051cSeric 	*/
578bac5051cSeric 	while (getstats(pkt,&stats)) {
579bac5051cSeric 		if (getadel(pkt,&dt) != BDELTAB)
580bac5051cSeric 			fmterr(pkt);
581bac5051cSeric 
582bac5051cSeric 		/*
583bac5051cSeric 		Read rest of delta entry.
584bac5051cSeric 		*/
585bac5051cSeric 		while ((n = getline(pkt)) != NULL)
586bac5051cSeric 			if (pkt->p_line[0] != CTLCHAR)
587bac5051cSeric 				break;
588bac5051cSeric 			else {
589bac5051cSeric 				switch (pkt->p_line[1]) {
590bac5051cSeric 				case EDELTAB:
591bac5051cSeric 					break;
592bac5051cSeric 				case INCLUDE:
593bac5051cSeric 				case EXCLUDE:
594bac5051cSeric 				case IGNORE:
595bac5051cSeric 				case MRNUM:
596bac5051cSeric 				case COMMENTS:
597bac5051cSeric 					continue;
598bac5051cSeric 				default:
599bac5051cSeric 					fmterr(pkt);
600bac5051cSeric 				}
601bac5051cSeric 				break;
602bac5051cSeric 			}
603bac5051cSeric 		if (n == NULL || pkt->p_line[0] != CTLCHAR)
604bac5051cSeric 			fmterr(pkt);
605bac5051cSeric 	}
606bac5051cSeric 	if (pkt->p_line[1] != BUSERNAM)
607bac5051cSeric 		fmterr(pkt);
608bac5051cSeric }
609bac5051cSeric 
610bac5051cSeric 
getstats(pkt,statp)611bac5051cSeric getstats(pkt,statp)
612bac5051cSeric register struct packet *pkt;
613bac5051cSeric register struct stats *statp;
614bac5051cSeric {
615bac5051cSeric 	register char *p;
616bac5051cSeric 
617bac5051cSeric 	p = pkt->p_line;
618bac5051cSeric 	if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS)
619bac5051cSeric 		return(0);
620bac5051cSeric 	NONBLANK(p);
621bac5051cSeric 	p = satoi(p,&statp->s_ins);
622bac5051cSeric 	p = satoi(++p,&statp->s_del);
623bac5051cSeric 	satoi(++p,&statp->s_unc);
624bac5051cSeric 	return(1);
625bac5051cSeric }
626bac5051cSeric 
627bac5051cSeric 
getadel(pkt,dt)628bac5051cSeric getadel(pkt,dt)
629bac5051cSeric register struct packet *pkt;
630bac5051cSeric register struct deltab *dt;
631bac5051cSeric {
632bac5051cSeric 	if (getline(pkt) == NULL)
633bac5051cSeric 		fmterr(pkt);
634bac5051cSeric 	return(del_ab(pkt->p_line,dt,pkt));
635bac5051cSeric }
636bac5051cSeric 
637bac5051cSeric 
638bac5051cSeric 
maket(file)639bac5051cSeric char	*maket(file)
640bac5051cSeric char	*file;
641bac5051cSeric {
642bac5051cSeric 	FILE *iop;
643bac5051cSeric 
644bac5051cSeric 	copy(tempskel,file);
645bac5051cSeric 	iop = xfcreat(mktemp(file),0644);
646bac5051cSeric 
647bac5051cSeric 	return(iop);
648bac5051cSeric }
649bac5051cSeric 
650bac5051cSeric 
printfile(file)651bac5051cSeric printfile(file)
652bac5051cSeric register	char	*file;
653bac5051cSeric {
654bac5051cSeric 	register	char	*p;
655bac5051cSeric 	FILE	*iop;
656bac5051cSeric 
657bac5051cSeric 	iop = xfopen(file,0);
658bac5051cSeric 	while ((p = fgets(line,sizeof(line),iop)) != NULL)
659bac5051cSeric 		printf("%s",p);
660bac5051cSeric 	fclose(iop);
661bac5051cSeric }
662bac5051cSeric 
663bac5051cSeric 
read_mod(pkt)664bac5051cSeric read_mod(pkt)
665bac5051cSeric register struct packet *pkt;
666bac5051cSeric {
667bac5051cSeric 	register char *p;
668bac5051cSeric 	int ser;
669bac5051cSeric 	int iord;
670bac5051cSeric 	register struct apply *ap;
671bac5051cSeric 
672bac5051cSeric 	BDiop = maket(bdtmp);
673bac5051cSeric 	while (getline(pkt) != NULL) {
674bac5051cSeric 		p = pkt->p_line;
675bac5051cSeric 		fputs(p,BDiop);
676bac5051cSeric 		if (*p++ != CTLCHAR)
677bac5051cSeric 			continue;
678bac5051cSeric 		else {
679bac5051cSeric 			if (!((iord = *p++) == INS || iord == DEL || iord == END))
680bac5051cSeric 				fmterr(pkt);
681bac5051cSeric 			NONBLANK(p);
682bac5051cSeric 			satoi(p,&ser);
683bac5051cSeric 			if (iord == END)
684bac5051cSeric 				remq(pkt,ser);
685bac5051cSeric 			else if ((ap = &pkt->p_apply[ser])->a_code == APPLY)
686bac5051cSeric 				addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER);
687bac5051cSeric 			else
688bac5051cSeric 				addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER);
689bac5051cSeric 		}
690bac5051cSeric 	}
691bac5051cSeric 	fclose(BDiop);
692bac5051cSeric 	if (pkt->p_q)
693bac5051cSeric 		fatal("premature eof (co5)");
694bac5051cSeric 	return(0);
695bac5051cSeric }
696bac5051cSeric 
697bac5051cSeric 
698bac5051cSeric getbody(gsid,pkt)
699bac5051cSeric struct	sid	*gsid;
700bac5051cSeric struct packet *pkt;
701bac5051cSeric {
702bac5051cSeric 	int	i;
703bac5051cSeric 	int	status;
704bac5051cSeric 	extern	char	Getpgm[];
705bac5051cSeric 	char	str[128];
706bac5051cSeric 	char	rarg[20];
707bac5051cSeric 	char	filearg[80];
708bac5051cSeric 
709bac5051cSeric 	sid_ba(gsid,str);
710bac5051cSeric 	sprintf(rarg,"%s",str);
711bac5051cSeric 	sprintf(filearg,"%s",pkt->p_file);
712bac5051cSeric 	/*
713bac5051cSeric 	fork here so 'getbody' can execute 'get' to
714bac5051cSeric 	print out gotten body :GB:
715bac5051cSeric 	*/
716bac5051cSeric 	if ((i = fork()) < 0)
717bac5051cSeric 		fatal("cannot fork, try again");
718bac5051cSeric 	if (i = 0) {
719bac5051cSeric 		/*
720bac5051cSeric 		perform 'get' and redirect output
721bac5051cSeric 		to standard output
722bac5051cSeric 		*/
723bac5051cSeric 		execl(Getpgm,Getpgm,"-s","-p","-r",rarg,filearg,0);
724*824dd99bSbostic 		sprintf(Error,"cannot execute '%s'",Getpgm);
725*824dd99bSbostic 		fatal(Error);
726bac5051cSeric 	}
727bac5051cSeric 	else {
728bac5051cSeric 		wait(&status);
729bac5051cSeric 		return;
730bac5051cSeric 	}
731bac5051cSeric }
732bac5051cSeric 
733bac5051cSeric 
getit(str,cp)734bac5051cSeric getit(str,cp)
735bac5051cSeric register	char	*str, *cp;
736bac5051cSeric {
7375b29b8bcSlepreau 	cp += 2;
738bac5051cSeric 	NONBLANK(cp);
739bac5051cSeric 	cp[length(cp) - 1] = '\0';
740bac5051cSeric 	sprintf(str,"%s",cp);
741bac5051cSeric }
742bac5051cSeric 
743bac5051cSeric 
aux_create(iop,file,delchar)744bac5051cSeric aux_create(iop,file,delchar)
745bac5051cSeric FILE	*iop;
746bac5051cSeric char	*file;
747bac5051cSeric char	delchar;
748bac5051cSeric {
749bac5051cSeric 
750bac5051cSeric 	int	n;
751bac5051cSeric 	int	text;
752bac5051cSeric 	/*
753bac5051cSeric 	create auxiliary file for the named section
754bac5051cSeric 	*/
755bac5051cSeric 
756bac5051cSeric 	text = 0;
757bac5051cSeric 	iop = maket(file);
758bac5051cSeric 	while ((n = getline(&gpkt)) != NULL && gpkt.p_line[0] != CTLCHAR) {
759bac5051cSeric 		text = 1;
760bac5051cSeric 		fputs(n,iop);
761bac5051cSeric 	}
762bac5051cSeric 	/*
763bac5051cSeric 	check to see that delimiter found is correct
764bac5051cSeric 	*/
765bac5051cSeric 	if (n == NULL || gpkt.p_line[0] != CTLCHAR || gpkt.p_line[1] != delchar)
766bac5051cSeric 		fmterr(&gpkt);
767bac5051cSeric 	if (!text)
768bac5051cSeric 		fprintf(iop,"No entries\n");
769bac5051cSeric 	fclose(iop);
770bac5051cSeric }
771bac5051cSeric 
772bac5051cSeric 
773bac5051cSeric idsetup(gsid,pkt,bdate)
774bac5051cSeric struct	sid	*gsid;
775bac5051cSeric struct	packet	*pkt;
776bac5051cSeric long	*bdate;
777bac5051cSeric {
778bac5051cSeric 
779bac5051cSeric 	register	char	*p;
7804a6a95bbSeric 	extern	struct	tm	*localtime();
781bac5051cSeric 
782bac5051cSeric 	date_ba(bdate,Deltadate);
783bac5051cSeric 
784bac5051cSeric 	Deltatime = &Deltadate[9];
785bac5051cSeric 	Deltadate[8] = 0;
786bac5051cSeric 
787bac5051cSeric 	sid_ba(gsid,Sid);
788bac5051cSeric 
789bac5051cSeric 	Dtime = localtime(bdate);
790bac5051cSeric 
791bac5051cSeric 	if (p = Sflags[MODFLAG - 'a'])
792bac5051cSeric 		copy(p,Mod);
793bac5051cSeric 	else sprintf(Mod,"%s",sname(pkt->p_file));
794bac5051cSeric 
795bac5051cSeric 	if (!(Type = Sflags[TYPEFLAG - 'a']))
796bac5051cSeric 		Type = "none";
797bac5051cSeric }
798