12131Seric /*************************************************************************/
22131Seric /*									 */
32131Seric /*	prs [-d<dataspec>] [-r<sid>] [-c<cutoff>] [-a]			 */
42131Seric /*	    [-y<reverse-cutoff>] file ...				 */
52131Seric /*									 */
62131Seric /*************************************************************************/
72131Seric 
82131Seric /*
92131Seric 	Program to print parts or all of an SCCS file
102131Seric 	in user supplied format.
112131Seric 	Arguments to the program may appear in any order
122131Seric 	and consist of keyletters, which begin with '-',
132131Seric 	and named files.
142131Seric 
152131Seric 	If a direcory is given as an argument, each
162131Seric 	SCCS file within the directory is processed as if
172131Seric 	it had been specifically named. If a name of '-'
182131Seric 	is given, the standard input is read for a list
192131Seric 	of names of SCCS files to be processed.
202131Seric 	Non-SCCS files are ignored.
212131Seric */
222131Seric 
232131Seric # include "../hdr/defines.h"
242131Seric # include "../hdr/had.h"
252131Seric 
26*2135Seric SCCSID(@(#)prs.c	1.2);
272131Seric 
282131Seric char	had[26];
292131Seric char	Getpgm[]	"/usr/local/get";
302131Seric char	Sid[32];
312131Seric char	Mod[16];
322131Seric char	*Type;
332131Seric char	Deltadate[18];
342131Seric char	*Deltatime;
352131Seric char	tempskel[]	"/tmp/prXXXXXX";	/* used to generate temp
362131Seric 						   file names
372131Seric 						*/
382131Seric char	untmp[32], uttmp[32], cmtmp[32];
392131Seric char	mrtmp[32], bdtmp[32];
402131Seric FILE	*UNiop;
412131Seric FILE	*UTiop;
422131Seric FILE	*CMiop;
432131Seric FILE	*MRiop;
442131Seric FILE	*BDiop;
452131Seric char	line[BUFSIZ];
462131Seric int	num_files;
472131Seric long	cutoff;
482131Seric long	revcut;
492131Seric char	*dataspec;
502131Seric char	iline[BUFSIZ], xline[BUFSIZ], gline[BUFSIZ];
512131Seric char	*maket();
522131Seric struct	packet	gpkt;
532131Seric struct	sid	sid;
54*2135Seric struct	tm	*Dtime;
552131Seric 
562131Seric main(argc,argv)
572131Seric int argc;
582131Seric char *argv[];
592131Seric {
602131Seric 	register int j;
612131Seric 	register char *p;
622131Seric 	char c;
632131Seric 	extern prs();
642131Seric 	extern int Fcnt;
652131Seric 
662131Seric 	/*
672131Seric 	Set flags for 'fatal' to issue message, call clean-up
682131Seric 	routine, and terminate processing.
692131Seric 	*/
702131Seric 	Fflags = FTLMSG | FTLCLN | FTLEXIT;
712131Seric 
722131Seric 
732131Seric 	/*
742131Seric 	The following loop processes keyletters and arguments.
752131Seric 	Note that these are processed only once for each
762131Seric 	invocation of 'main'.
772131Seric 	*/
782131Seric 	for (j = 1; j < argc; j++)
792131Seric 		if (argv[j][0] == '-' && (c = argv[j][1])) {
802131Seric 			p = &argv[j][2];
812131Seric 			switch (c) {
822131Seric 
832131Seric 			case 'r':	/* delta cutoff */
842131Seric 				if (*p) {
852131Seric 					if (invalid(p))
862131Seric 						fatal("invalid sid (co8)");
872131Seric 					sid_ab(p,&sid);
882131Seric 				}
892131Seric 				break;
902131Seric 
912131Seric 			case 'c':	/* time cutoff */
922131Seric 				if (*p && date_ab(p,&cutoff))
932131Seric 					fatal("bad date/time (cm5)");
942131Seric 				break;
952131Seric 
962131Seric 			case 'y':	/* reverse time cutoff */
972131Seric 				if (*p && date_ab(p,&revcut))
982131Seric 					fatal ("bad date/time (cm5)");
992131Seric 				break;
1002131Seric 
1012131Seric 			case 'a':
1022131Seric 				if (*p)
1032131Seric 					fatal("value after a arg (cm7)");
1042131Seric 				break;
1052131Seric 			case 'd':	/* dataspec line */
1062131Seric 				dataspec = p;
1072131Seric 				break;
1082131Seric 			default:
1092131Seric 				fatal("unknown key letter (cm1)");
1102131Seric 			}
1112131Seric 
1122131Seric 			if (had[c - 'a']++)
1132131Seric 				fatal("key letter twice (cm2)");
1142131Seric 			argv[j] = 0;
1152131Seric 		}
1162131Seric 		else
1172131Seric 			num_files++;
1182131Seric 
1192131Seric 	if (num_files == 0)
1202131Seric 		fatal("missing file arg (cm3)");
1212131Seric 
1222131Seric 	if (!HADD)
1232131Seric 		exit(0);
1242131Seric 	if (HADC && HADY)
1252131Seric 		fatal("both 'c' and 'y' keyletters specified (prs2)");
1262131Seric 
1272131Seric 	setsig();
1282131Seric 
1292131Seric 	/*
1302131Seric 	Change flags for 'fatal' so that it will return to this
1312131Seric 	routine (main) instead of terminating processing.
1322131Seric 	*/
1332131Seric 	Fflags =& ~FTLEXIT;
1342131Seric 	Fflags =| FTLJMP;
1352131Seric 
1362131Seric 	/*
1372131Seric 	Call 'prs' routine for each file argument.
1382131Seric 	*/
1392131Seric 	for (j = 1; j < argc; j++)
1402131Seric 		if (p = argv[j])
1412131Seric 			do_file(p,prs);
1422131Seric 
1432131Seric 	exit(Fcnt ? 1 : 0);
1442131Seric }
1452131Seric 
1462131Seric 
1472131Seric prs(file)
1482131Seric register	char	*file;
1492131Seric {
1502131Seric 	int	n;
1512131Seric 	extern	char	had_dir, had_standinp;
1522131Seric 
1532131Seric 	if (setjmp(Fjmp))
1542131Seric 		return;
1552131Seric 	sinit(&gpkt,file,1);	/* init packet and open SCCS file */
1562131Seric 
1572131Seric 	gpkt.p_reqsid.s_rel = sid.s_rel;
1582131Seric 	gpkt.p_reqsid.s_lev = sid.s_lev;
1592131Seric 	gpkt.p_reqsid.s_br = sid.s_br;
1602131Seric 	gpkt.p_reqsid.s_seq = sid.s_seq;
1612131Seric 	gpkt.p_cutoff = cutoff;
1622131Seric 	gpkt.p_reopen = 1;
1632131Seric 
1642131Seric 	/*
1652131Seric 	read delta table entries checking only for format error
1662131Seric 	*/
1672131Seric 	deltblchk(&gpkt);
1682131Seric 
1692131Seric 	/*
1702131Seric 	create auxiliary file for User Name Section
1712131Seric 	*/
1722131Seric 
1732131Seric 	aux_create(UNiop,untmp,EUSERNAM);
1742131Seric 
1752131Seric 	doflags(&gpkt);
1762131Seric 
1772131Seric 	/*
1782131Seric 	create auxiliary file for the User Text section
1792131Seric 	*/
1802131Seric 
1812131Seric 	aux_create(UTiop,uttmp,EUSERTXT);
1822131Seric 
1832131Seric 	/*
1842131Seric 	indicate to 'getline' that EOF is okay
1852131Seric 	*/
1862131Seric 	gpkt.p_chkeof = 1;
1872131Seric 
1882131Seric 	/*
1892131Seric 	read body of SCCS file and create temp file for it
1902131Seric 	*/
1912131Seric 	while(read_mod(&gpkt))
1922131Seric 		;
1932131Seric 
1942131Seric 	if (num_files > 1 || had_dir || had_standinp)
1952131Seric 		printf("\n%s:\n",gpkt.p_file);
1962131Seric 	/*
1972131Seric 	Here, file has already been re-opened (by 'getline')
1982131Seric 	*/
1992131Seric 	getline(&gpkt);		/* skip over header line */
2002131Seric 
2012131Seric 	/*
2022131Seric 	call dodeltbl to read delta table entries
2032131Seric 	*/
2042131Seric 
2052131Seric 	dodeltbl(&gpkt);
2062131Seric 
2072131Seric 	clean_up();
2082131Seric 
2092131Seric 	return;
2102131Seric }
2112131Seric 
2122131Seric 
2132131Seric dodeltbl(pkt)
2142131Seric register struct packet *pkt;
2152131Seric {
2162131Seric 	int	n;
2172131Seric 	struct	deltab	dt;
2182131Seric 	struct	stats	stats;
2192131Seric 
2202131Seric 	/*
2212131Seric 	Read entire delta table.
2222131Seric 	*/
2232131Seric 	while (getstats(pkt,&stats)) {
2242131Seric 		if (getadel(pkt,&dt) != BDELTAB)
2252131Seric 			fmterr(pkt);
2262131Seric 
2272131Seric 		/*
2282131Seric 		Read rest of delta entry.
2292131Seric 		*/
2302131Seric 		while ((n = getline(pkt)) != NULL)
2312131Seric 			if (pkt->p_line[0] != CTLCHAR)
2322131Seric 				break;
2332131Seric 			else {
2342131Seric 				switch (pkt->p_line[1]) {
2352131Seric 				case EDELTAB:
2362131Seric 					scanspec(dataspec,&dt,&stats);
2372131Seric 					break;
2382131Seric 				case INCLUDE:
2392131Seric 					getit(iline,n);
2402131Seric 					continue;
2412131Seric 				case EXCLUDE:
2422131Seric 					getit(xline,n);
2432131Seric 					continue;
2442131Seric 				case IGNORE:
2452131Seric 					getit(gline,n);
2462131Seric 					continue;
2472131Seric 				case MRNUM:
2482131Seric 				case COMMENTS:
2492131Seric 					continue;
2502131Seric 				default:
2512131Seric 					fmterr(pkt);
2522131Seric 				}
2532131Seric 				break;
2542131Seric 			}
2552131Seric 		if (n == NULL || pkt->p_line[0] != CTLCHAR)
2562131Seric 			fmterr(pkt);
2572131Seric 	}
2582131Seric }
2592131Seric 
2602131Seric 
2612131Seric /*
2622131Seric  * The scanspec procedure scans the dataspec searching for ID keywords.
2632131Seric  * When a keyword is found the value is replaced and printed on the
2642131Seric  * standard output. Any character that is not an ID keyword is printed
2652131Seric  * immediately.
2662131Seric */
2672131Seric 
2682131Seric static	char	Zkeywd[5]	"@(#)";
2692131Seric scanspec(spec,dtp,statp)
2702131Seric char spec[];
2712131Seric struct	deltab	*dtp;
2722131Seric struct	stats	*statp;
2732131Seric {
2742131Seric 
2752131Seric 	extern	char	*Sflags[];
2762131Seric 	register char *lp;
2772131Seric 	register char	*k;
2782131Seric 	union {
2792131Seric 		char	str[2];
280*2135Seric 		short	istr;
2812131Seric 	} u;
2822131Seric 	register	char	c;
2832131Seric 
2842131Seric 	idsetup(&dtp->d_sid,&gpkt,&dtp->d_datetime);
2852131Seric 	for(lp = spec; *lp != 0; lp++) {
2862131Seric 		if(lp[0] == ':' && lp[1] != 0 && lp[2] == ':') {
2872131Seric 			c = *++lp;
2882131Seric 			switch (c) {
2892131Seric 			case 'I':	/* SID */
2902131Seric 				printf("%s",Sid);
2912131Seric 				break;
2922131Seric 			case 'R':	/* Release number */
2932131Seric 				printf("%u",dtp->d_sid.s_rel);
2942131Seric 				break;
2952131Seric 			case 'L':	/* Level number */
2962131Seric 				printf("%u",dtp->d_sid.s_lev);
2972131Seric 				break;
2982131Seric 			case 'B':	/* Branch number */
2992131Seric 				if (dtp->d_sid.s_br != 0)
3002131Seric 					printf("%u",dtp->d_sid.s_br);
3012131Seric 				break;
3022131Seric 			case 'S':	/* Sequence number */
3032131Seric 				if (dtp->d_sid.s_seq != 0)
3042131Seric 					printf("%u",dtp->d_sid.s_seq);
3052131Seric 				break;
3062131Seric 			case 'D':	/* Date delta created */
3072131Seric 				printf("%s",Deltadate);
3082131Seric 				break;
3092131Seric 			case 'T':	/* Time delta created */
3102131Seric 				printf("%s",Deltatime);
3112131Seric 				break;
3122131Seric 			case 'P':	/* Programmer who created delta */
3132131Seric 				printf("%s",dtp->d_pgmr);
3142131Seric 				break;
3152131Seric 			case 'C':	/* Comments */
3162131Seric 				break;
3172131Seric 			case 'Y':	/* Type flag */
3182131Seric 				printf("%s",Type);
3192131Seric 				break;
3202131Seric 			case 'M':	/* Module name */
3212131Seric 				printf("%s",Mod);
3222131Seric 				break;
3232131Seric 			case 'W':	/* Form of what string */
3242131Seric 				printf("%s",Zkeywd);
3252131Seric 				printf("%s",Mod);
3262131Seric 				putchar('\t');
3272131Seric 				printf("%s",Sid);
3282131Seric 				break;
3292131Seric 			case 'A':	/* Form of what string */
3302131Seric 				printf("%s",Zkeywd);
3312131Seric 				printf("%s ",Type);
3322131Seric 				printf("%s ",Mod);
3332131Seric 				printf("%s",Sid);
3342131Seric 				printf("%s",Zkeywd);
3352131Seric 				break;
3362131Seric 			case 'Z':	/* what string constructor */
3372131Seric 				printf("%s",Zkeywd);
3382131Seric 				break;
3392131Seric 			case 'F':	/* File name */
3402131Seric 				printf("%s",sname(gpkt.p_file));
3412131Seric 				break;
3422131Seric 			default:
3432131Seric 				putchar(':');
3442131Seric 				putchar(c);
3452131Seric 				putchar(':');
3462131Seric 				break;
3472131Seric 			}
3482131Seric 			lp++;
3492131Seric 		}
3502131Seric 		else if(lp[0] == ':' && lp[1] != 0 && lp[2] !=0 && lp[3] == ':') {
3512131Seric 			if (lp[1] == ':') {
3522131Seric 				putchar(':');
3532131Seric 				*lp =+ 2;
3542131Seric 				continue;
3552131Seric 			}
356*2135Seric 			u.str[1] = *++lp;
3572131Seric 			u.str[0] = *++lp;
3582131Seric 			switch (u.istr) {
3592131Seric 			case 'Dl':	/* Delta line statistics */
3602131Seric 				printf("%05d",statp->s_ins);
3612131Seric 				putchar('/');
3622131Seric 				printf("%05d",statp->s_del);
3632131Seric 				putchar('/');
3642131Seric 				printf("%05d",statp->s_unc);
3652131Seric 				break;
3662131Seric 			case 'Li':	/* Lines inserted by delta */
3672131Seric 				printf("%05d",statp->s_ins);
3682131Seric 				break;
3692131Seric 			case 'Ld':	/* Lines deleted by delta */
3702131Seric 				printf("%05d",statp->s_del);
3712131Seric 				break;
3722131Seric 			case 'Lu':	/* Lines unchanged by delta */
3732131Seric 				printf("%05d",statp->s_unc);
3742131Seric 				break;
3752131Seric 			case 'DT':	/* Delta type */
3762131Seric 				printf("%c",dtp->d_type);
3772131Seric 				break;
3782131Seric 			case 'Dy':	/* Year delta created */
379*2135Seric 				printf("%02d",Dtime->tm_year);
3802131Seric 				break;
3812131Seric 			case 'Dm':	/* Month delta created */
382*2135Seric 				printf("%02d",(Dtime->tm_mon + 1));
3832131Seric 				break;
3842131Seric 			case 'Dd':	/* Day delta created */
385*2135Seric 				printf("%02d",Dtime->tm_mday);
3862131Seric 				break;
3872131Seric 			case 'Th':	/* Hour delta created */
388*2135Seric 				printf("%02d",Dtime->tm_hour);
3892131Seric 				break;
3902131Seric 			case 'Tm':	/* Minutes delta created */
391*2135Seric 				printf("%02d",Dtime->tm_min);
3922131Seric 				break;
3932131Seric 			case 'Ts':	/* Seconds delta created */
394*2135Seric 				printf("%02d",Dtime->tm_sec);
3952131Seric 				break;
3962131Seric 			case 'DS':	/* Delta sequence number */
3972131Seric 				printf("%d",dtp->d_serial);
3982131Seric 				break;
3992131Seric 			case 'DP':	/* Predecessor delta sequence number */
4002131Seric 				printf("%d",dtp->d_pred);
4012131Seric 				break;
4022131Seric 			case 'DI':	/* Deltas included,excluded,ignored */
4032131Seric 				printf("%s",iline);
4042131Seric 				putchar('/');
4052131Seric 				printf("%s",xline);
4062131Seric 				putchar('/');
4072131Seric 				printf("%s",gline);
4082131Seric 				break;
4092131Seric 			case 'Di':	/* Deltas included */
4102131Seric 				printf("%s",iline);
4112131Seric 				break;
4122131Seric 			case 'Dx':	/* Deltas excluded */
4132131Seric 				printf("%s",xline);
4142131Seric 				break;
4152131Seric 			case 'Dg':	/* Deltas ignored */
4162131Seric 				printf("%s",gline);
4172131Seric 				break;
4182131Seric 			case 'MR':	/* MR numbers */
4192131Seric 				break;
4202131Seric 			case 'UN':	/* User names */
4212131Seric 				printfile(untmp);
4222131Seric 				break;
4232131Seric 			case 'MF':	/* MR validation flag */
4242131Seric 				if (Sflags[VALFLAG - 'a'])
4252131Seric 					printf("yes");
4262131Seric 				else printf("no");
4272131Seric 				break;
4282131Seric 			case 'MP':	/* MR validation program */
4292131Seric 				if (!(k = Sflags[VALFLAG - 'a']))
4302131Seric 					printf("none");
4312131Seric 				else printf("%s",k);
4322131Seric 				break;
4332131Seric 			case 'KF':	/* Keyword err/warn flag */
4342131Seric 				if (Sflags[IDFLAG - 'a'])
4352131Seric 					printf("yes");
4362131Seric 				else printf("no");
4372131Seric 				break;
4382131Seric 			case 'BF':	/* Branch flag */
4392131Seric 				if (Sflags[BRCHFLAG - 'a'])
4402131Seric 					printf("yes");
4412131Seric 				else printf("no");
4422131Seric 				break;
4432131Seric 			case 'FB':	/* Floor Boundry */
4442131Seric 				if (k = Sflags[FLORFLAG - 'a'])
4452131Seric 					printf("%s",k);
4462131Seric 				else printf("none");
4472131Seric 				break;
4482131Seric 			case 'CB':	/* Ceiling Boundry */
4492131Seric 				if (k = Sflags[CEILFLAG - 'a'])
4502131Seric 					printf("%s",k);
4512131Seric 				else printf("none");
4522131Seric 				break;
4532131Seric 			case 'Ds':	/* Default SID */
4542131Seric 				if (k = Sflags[DEFTFLAG - 'a'])
4552131Seric 					printf("%s",k);
4562131Seric 				else printf("none");
4572131Seric 				break;
4582131Seric 			case 'ND':	/* Null delta */
4592131Seric 				if (Sflags[NULLFLAG - 'a'])
4602131Seric 					printf("yes");
4612131Seric 				else printf("no");
4622131Seric 				break;
4632131Seric 			case 'FD':	/* File descriptive text */
4642131Seric 				printfile(uttmp);
4652131Seric 				break;
4662131Seric 			case 'BD':	/* Entire file body */
4672131Seric 				printfile(bdtmp);
4682131Seric 				break;
4692131Seric 			case 'GB':	/* Gotten body from 'get' */
4702131Seric 				getbody(&dtp->d_sid,&gpkt);
4712131Seric 				break;
4722131Seric 			default:
4732131Seric 				putchar(':');
4742131Seric 				printf("%c",u.istr);
4752131Seric 				putchar(':');
4762131Seric 				break;
4772131Seric 			}
4782131Seric 			lp++;
4792131Seric 		}
4802131Seric 		else {
4812131Seric 			c = *lp;
4822131Seric 			if (c == '\\') {
4832131Seric 				switch(*++lp) {
4842131Seric 				case 'n':	/* for newline */
4852131Seric 					putchar('\n');
4862131Seric 					break;
4872131Seric 				case ':':	/* for wanted colon */
4882131Seric 					putchar(':');
4892131Seric 					break;
4902131Seric 				case 't':	/* for tab */
4912131Seric 					putchar('\t');
4922131Seric 					break;
4932131Seric 				case 'b':	/* for backspace */
4942131Seric 					putchar('\b');
4952131Seric 					break;
4962131Seric 				case 'r':	/* for carriage return */
4972131Seric 					putchar('\r');
4982131Seric 					break;
4992131Seric 				case 'f':	/* for form feed */
5002131Seric 					putchar('\f');
5012131Seric 					break;
5022131Seric 				case '\\':	/* for backslash */
5032131Seric 					putchar('\\');
5042131Seric 					break;
5052131Seric 				case '\'':	/* for single quote */
5062131Seric 					putchar('\'');
5072131Seric 					break;
5082131Seric 				default:	/* unknown case */
5092131Seric 					putchar('\\');
5102131Seric 					putchar(*lp);
5112131Seric 					break;
5122131Seric 				}
5132131Seric 			}
5142131Seric 			else putchar(*lp);
5152131Seric 		}
5162131Seric 	}
5172131Seric 	/*
5182131Seric 	zero out first char of global string lines in case
5192131Seric 	a value is not gotten in next delta table entry
5202131Seric 	*/
5212131Seric 	iline[0] = xline[0] = gline[0] = 0;
5222131Seric 	putchar('\n');
5232131Seric 	return;
5242131Seric }
5252131Seric 
5262131Seric 
5272131Seric clean_up()
5282131Seric {
5292131Seric 	unlink(untmp);
5302131Seric 	unlink(uttmp);
5312131Seric 	unlink(bdtmp);
532*2135Seric 	if (gpkt.p_iop)
533*2135Seric 		fclose(gpkt.p_iop);
5342131Seric }
5352131Seric 
5362131Seric 
5372131Seric /* This function takes as it's argument the SID inputed and determines
5382131Seric  * whether or not it is valid (e. g. not ambiguous or illegal).
5392131Seric */
5402131Seric invalid(i_sid)
5412131Seric register char	*i_sid;
5422131Seric {
5432131Seric 	register int count;
5442131Seric 	register int digits;
5452131Seric 	count = digits = 0;
5462131Seric 	if (*i_sid == '0' || *i_sid == '.')
5472131Seric 		return (1);
5482131Seric 	i_sid++;
5492131Seric 	digits++;
5502131Seric 	while (*i_sid != '\0') {
5512131Seric 		if (*i_sid++ == '.') {
5522131Seric 			digits = 0;
5532131Seric 			count++;
5542131Seric 			if (*i_sid == '0' || *i_sid == '.')
5552131Seric 				return (1);
5562131Seric 		}
5572131Seric 		digits++;
5582131Seric 		if (digits > 5)
5592131Seric 			return (1);
5602131Seric 	}
5612131Seric 	if (*(--i_sid) == '.' )
5622131Seric 		return (1);
5632131Seric 	if (count == 1 || count == 3)
5642131Seric 		return (0);
5652131Seric 	return (1);
5662131Seric }
5672131Seric 
5682131Seric 
5692131Seric deltblchk(pkt)
5702131Seric register struct packet *pkt;
5712131Seric {
5722131Seric 	int	n;
5732131Seric 	struct	deltab	dt;
5742131Seric 	struct	stats	stats;
5752131Seric 
5762131Seric 	/*
5772131Seric 	Read entire delta table.
5782131Seric 	*/
5792131Seric 	while (getstats(pkt,&stats)) {
5802131Seric 		if (getadel(pkt,&dt) != BDELTAB)
5812131Seric 			fmterr(pkt);
5822131Seric 
5832131Seric 		/*
5842131Seric 		Read rest of delta entry.
5852131Seric 		*/
5862131Seric 		while ((n = getline(pkt)) != NULL)
5872131Seric 			if (pkt->p_line[0] != CTLCHAR)
5882131Seric 				break;
5892131Seric 			else {
5902131Seric 				switch (pkt->p_line[1]) {
5912131Seric 				case EDELTAB:
5922131Seric 					break;
5932131Seric 				case INCLUDE:
5942131Seric 				case EXCLUDE:
5952131Seric 				case IGNORE:
5962131Seric 				case MRNUM:
5972131Seric 				case COMMENTS:
5982131Seric 					continue;
5992131Seric 				default:
6002131Seric 					fmterr(pkt);
6012131Seric 				}
6022131Seric 				break;
6032131Seric 			}
6042131Seric 		if (n == NULL || pkt->p_line[0] != CTLCHAR)
6052131Seric 			fmterr(pkt);
6062131Seric 	}
6072131Seric 	if (pkt->p_line[1] != BUSERNAM)
6082131Seric 		fmterr(pkt);
6092131Seric }
6102131Seric 
6112131Seric 
6122131Seric getstats(pkt,statp)
6132131Seric register struct packet *pkt;
6142131Seric register struct stats *statp;
6152131Seric {
6162131Seric 	register char *p;
6172131Seric 
6182131Seric 	p = pkt->p_line;
6192131Seric 	if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS)
6202131Seric 		return(0);
6212131Seric 	NONBLANK(p);
6222131Seric 	p = satoi(p,&statp->s_ins);
6232131Seric 	p = satoi(++p,&statp->s_del);
6242131Seric 	satoi(++p,&statp->s_unc);
6252131Seric 	return(1);
6262131Seric }
6272131Seric 
6282131Seric 
6292131Seric getadel(pkt,dt)
6302131Seric register struct packet *pkt;
6312131Seric register struct deltab *dt;
6322131Seric {
6332131Seric 	if (getline(pkt) == NULL)
6342131Seric 		fmterr(pkt);
6352131Seric 	return(del_ab(pkt->p_line,dt,pkt));
6362131Seric }
6372131Seric 
6382131Seric 
6392131Seric 
6402131Seric char	*maket(file)
6412131Seric char	*file;
6422131Seric {
6432131Seric 	FILE *iop;
6442131Seric 
6452131Seric 	copy(tempskel,file);
6462131Seric 	iop = xfcreat(mktemp(file),0644);
6472131Seric 
6482131Seric 	return(iop);
6492131Seric }
6502131Seric 
6512131Seric 
6522131Seric printfile(file)
6532131Seric register	char	*file;
6542131Seric {
6552131Seric 	register	char	*p;
6562131Seric 	FILE	*iop;
6572131Seric 
6582131Seric 	iop = xfopen(file,0);
6592131Seric 	while ((p = fgets(line,sizeof(line),iop)) != NULL)
6602131Seric 		printf("%s",p);
6612131Seric 	fclose(iop);
6622131Seric }
6632131Seric 
6642131Seric 
6652131Seric read_mod(pkt)
6662131Seric register struct packet *pkt;
6672131Seric {
6682131Seric 	register char *p;
6692131Seric 	int ser;
6702131Seric 	int iord;
6712131Seric 	register struct apply *ap;
6722131Seric 
6732131Seric 	BDiop = maket(bdtmp);
6742131Seric 	while (getline(pkt) != NULL) {
6752131Seric 		p = pkt->p_line;
6762131Seric 		fputs(p,BDiop);
6772131Seric 		if (*p++ != CTLCHAR)
6782131Seric 			continue;
6792131Seric 		else {
6802131Seric 			if (!((iord = *p++) == INS || iord == DEL || iord == END))
6812131Seric 				fmterr(pkt);
6822131Seric 			NONBLANK(p);
6832131Seric 			satoi(p,&ser);
6842131Seric 			if (iord == END)
6852131Seric 				remq(pkt,ser);
6862131Seric 			else if ((ap = &pkt->p_apply[ser])->a_code == APPLY)
6872131Seric 				addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER);
6882131Seric 			else
6892131Seric 				addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER);
6902131Seric 		}
6912131Seric 	}
6922131Seric 	fclose(BDiop);
6932131Seric 	if (pkt->p_q)
6942131Seric 		fatal("premature eof (co5)");
6952131Seric 	return(0);
6962131Seric }
6972131Seric 
6982131Seric 
6992131Seric getbody(gsid,pkt)
7002131Seric struct	sid	*gsid;
7012131Seric struct packet *pkt;
7022131Seric {
7032131Seric 	int	i;
7042131Seric 	int	status;
7052131Seric 	extern	char	Getpgm[];
7062131Seric 	char	str[128];
7072131Seric 	char	rarg[20];
7082131Seric 	char	filearg[80];
7092131Seric 
7102131Seric 	sid_ba(gsid,str);
7112131Seric 	sprintf(rarg,"%s",str);
7122131Seric 	sprintf(filearg,"%s",pkt->p_file);
7132131Seric 	/*
7142131Seric 	fork here so 'getbody' can execute 'get' to
7152131Seric 	print out gotten body :GB:
7162131Seric 	*/
7172131Seric 	if ((i = fork()) < 0)
7182131Seric 		fatal("cannot fork, try again");
7192131Seric 	if (i = 0) {
7202131Seric 		/*
7212131Seric 		perform 'get' and redirect output
7222131Seric 		to standard output
7232131Seric 		*/
7242131Seric 		execl(Getpgm,Getpgm,"-s","-p","-r",rarg,filearg,0);
7252131Seric 		fatal(sprintf(Error,"cannot execute '%s'",Getpgm));
7262131Seric 	}
7272131Seric 	else {
7282131Seric 		wait(&status);
7292131Seric 		return;
7302131Seric 	}
7312131Seric }
7322131Seric 
7332131Seric 
7342131Seric getit(str,cp)
7352131Seric register	char	*str, *cp;
7362131Seric {
7372131Seric 	cp =+ 2;
7382131Seric 	NONBLANK(cp);
7392131Seric 	cp[length(cp) - 1] = '\0';
7402131Seric 	sprintf(str,"%s",cp);
7412131Seric }
7422131Seric 
7432131Seric 
7442131Seric aux_create(iop,file,delchar)
7452131Seric FILE	*iop;
7462131Seric char	*file;
7472131Seric char	delchar;
7482131Seric {
7492131Seric 
7502131Seric 	int	n;
7512131Seric 	int	text;
7522131Seric 	/*
7532131Seric 	create auxiliary file for the named section
7542131Seric 	*/
7552131Seric 
7562131Seric 	text = 0;
7572131Seric 	iop = maket(file);
7582131Seric 	while ((n = getline(&gpkt)) != NULL && gpkt.p_line[0] != CTLCHAR) {
7592131Seric 		text = 1;
7602131Seric 		fputs(n,iop);
7612131Seric 	}
7622131Seric 	/*
7632131Seric 	check to see that delimiter found is correct
7642131Seric 	*/
7652131Seric 	if (n == NULL || gpkt.p_line[0] != CTLCHAR || gpkt.p_line[1] != delchar)
7662131Seric 		fmterr(&gpkt);
7672131Seric 	if (!text)
7682131Seric 		fprintf(iop,"No entries\n");
7692131Seric 	fclose(iop);
7702131Seric }
7712131Seric 
7722131Seric 
7732131Seric idsetup(gsid,pkt,bdate)
7742131Seric struct	sid	*gsid;
7752131Seric struct	packet	*pkt;
7762131Seric long	*bdate;
7772131Seric {
7782131Seric 
7792131Seric 	register	char	*p;
780*2135Seric 	extern	struct	tm	*localtime();
7812131Seric 
7822131Seric 	date_ba(bdate,Deltadate);
7832131Seric 
7842131Seric 	Deltatime = &Deltadate[9];
7852131Seric 	Deltadate[8] = 0;
7862131Seric 
7872131Seric 	sid_ba(gsid,Sid);
7882131Seric 
7892131Seric 	Dtime = localtime(bdate);
7902131Seric 
7912131Seric 	if (p = Sflags[MODFLAG - 'a'])
7922131Seric 		copy(p,Mod);
7932131Seric 	else sprintf(Mod,"%s",sname(pkt->p_file));
7942131Seric 
7952131Seric 	if (!(Type = Sflags[TYPEFLAG - 'a']))
7962131Seric 		Type = "none";
7972131Seric }
798