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