12154Seric /************************************************************************/
22154Seric /*									*/
32154Seric /*  val -                                                               */
42154Seric /*  val [-mname] [-rSID] [-s] [-ytype] file ...                         */
52154Seric /*                                                                      */
62154Seric /************************************************************************/
72154Seric 
82154Seric # include	"../hdr/defines.h"
92154Seric # include	"../hdr/had.h"
102154Seric 
112154Seric # define	FILARG_ERR	0200	/* no file name given */
122154Seric # define	UNKDUP_ERR	0100	/* unknown or duplicate keyletter */
132154Seric # define	CORRUPT_ERR	040	/* corrupt file error code */
142154Seric # define	FILENAM_ERR	020	/* file name error code */
152154Seric # define	INVALSID_ERR	010	/* invalid or ambiguous SID error  */
162154Seric # define	NONEXSID_ERR	04	/* non-existent SID error code */
172154Seric # define	TYPE_ERR	02	/* type arg value error code */
182154Seric # define	NAME_ERR	01	/* name arg value error code */
192154Seric # define	TRUE		1
202154Seric # define	FALSE		0
212154Seric # define	BLANK(l)	while (!(*l == ' ' || *l == '\t')) l++;
222154Seric 
232154Seric int	ret_code;	/* prime return code from 'main' program */
242154Seric int	inline_err;	/* input line error code (from 'process') */
252154Seric int	infile_err;	/* file error code (from 'validate') */
262154Seric int	inpstd;		/* TRUE = args from standard input */
272154Seric 
282154Seric struct packet gpkt;
292154Seric 
302154Seric char	had[26];	/* had flag used in 'process' function */
312154Seric char	path[50];	/* storage for file name value */
322154Seric char	sid[50];	/* storage for sid (-r) value */
332154Seric char	type[50];	/* storage for type (-y) value */
342154Seric char	name[50];	/* storage for name (-m) value */
352154Seric char	line[BUFSIZ];
362154Seric char	*get_line();	/* function returning ptr to line read */
372154Seric char	*getval();	/* function returning adjusted ptr to line */
382154Seric char	*alloc();	/* function returning ptr */
392154Seric char	*fgets();	/* function returning i/o ptr */
402154Seric 
412154Seric struct delent {		/* structure for delta table entry */
422154Seric 	char type;
432154Seric 	char *osid;
442154Seric 	char *datetime;
452154Seric 	char *pgmr;
462154Seric 	char *serial;
472154Seric 	char *pred;
482154Seric } del;
492154Seric 
50*30500Slepreau static char Sccsid[] = "@(#)val.c	4.3	02/15/87";
512154Seric 
522154Seric /* This is the main program that determines whether the command line
532154Seric  * comes from the standard input or read off the original command
542154Seric  * line.  See VAL(I) for more information.
552154Seric */
main(argc,argv)562154Seric main(argc,argv)
572154Seric int argc;
582154Seric char	*argv[];
592154Seric {
602154Seric 	FILE	*iop;
612154Seric 	register int j;
622154Seric 
632154Seric 	ret_code = 0;
642154Seric 	if (argc == 2 && argv[1][0] == '-' && !(argv[1][1])) {
652154Seric 		inpstd = TRUE;
662154Seric 		iop = stdin;		/* read from standard input */
672154Seric 		while (fgets(line,BUFSIZ,iop) != NULL) {
682154Seric 			if (line[0] != '\n') {
692154Seric 				repl (line,'\n','\0');
702154Seric 				process(line);
71*30500Slepreau 				ret_code |= inline_err;
722154Seric 			}
732154Seric 		}
742154Seric 	}
752154Seric 	else {
762154Seric 		inpstd = FALSE;
772154Seric 		for (j = 1; j < argc; j++)
782154Seric 			sprintf(&(line[strlen(line)]),"%s ",argv[j]);
792154Seric 		j = strlen(line) - 1;
802154Seric 		line[j > 0 ? j : 0] = NULL;
812154Seric 		process(line);
822154Seric 		ret_code = inline_err;
832154Seric 	}
842154Seric 	exit(ret_code);
852154Seric }
862154Seric 
872154Seric 
882154Seric /* This function processes the line sent by the main routine.  It
892154Seric  * determines which keyletter values are present on the command
902154Seric  * line and assigns the values to the correct storage place.  It
912154Seric  * then calls validate for each file name on the command line
922154Seric  * It will return to main if the input line contains an error,
932154Seric  * otherwise it returns any error code found by validate.
942154Seric */
process(p_line)952154Seric process(p_line)
962154Seric char	*p_line;
972154Seric {
982154Seric 	register int	j;
992154Seric 	register int	testklt;
1002154Seric 	register int	line_sw;
1012154Seric 
1022154Seric 	int	silent;
1032154Seric 	int	num_files;
1042154Seric 
1052154Seric 	char	filelist[50][50];
1062154Seric 	char	*savelinep;
1072154Seric 	char	c;
1082154Seric 
1092154Seric 	silent = FALSE;
1102154Seric 	path[0] = sid[0] = type[0] = name[0] = 0;
1112154Seric 	num_files = inline_err = 0;
1122154Seric 
1132154Seric 	/*
1142154Seric 	make copy of 'line' for use later
1152154Seric 	*/
1162154Seric 	savelinep = p_line;
1172154Seric 	/*
1182154Seric 	clear out had flags for each 'line' processed
1192154Seric 	*/
1202154Seric 	for (j = 0; j < 27; j++)
1212154Seric 		had[j] = 0;
1222154Seric 	/*
1232154Seric 	execute loop until all characters in 'line' are checked.
1242154Seric 	*/
1252154Seric 	while (*p_line) {
1262154Seric 		testklt = 1;
1272154Seric 		NONBLANK(p_line);
1282154Seric 		if (*p_line == '-') {
129*30500Slepreau 			p_line += 1;
1302154Seric 			c = *p_line;
1312154Seric 			p_line++;
1322154Seric 			switch (c) {
1332154Seric 				case 's':
1342154Seric 					testklt = 0;
1352154Seric 					/*
1362154Seric 					turn on 'silent' flag.
1372154Seric 					*/
1382154Seric 					silent = TRUE;
1392154Seric 					break;
1402154Seric 				case 'r':
1412154Seric 					p_line = getval(p_line,sid);
1422154Seric 					break;
1432154Seric 				case 'y':
1442154Seric 					p_line = getval(p_line,type);
1452154Seric 					break;
1462154Seric 				case 'm':
1472154Seric 					p_line = getval(p_line,name);
1482154Seric 					break;
1492154Seric 				default:
150*30500Slepreau 					inline_err |= UNKDUP_ERR;
1512154Seric 			}
1522154Seric 			/*
1532154Seric 			use 'had' array and determine if the keyletter
1542154Seric 			was given twice.
1552154Seric 			*/
1562154Seric 			if (had[c - 'a']++ && testklt++)
157*30500Slepreau 				inline_err |= UNKDUP_ERR;
1582154Seric 		}
1592154Seric 		else {
1602154Seric 			/*
1612154Seric 			assume file name if no '-' preceeded argument
1622154Seric 			*/
1632154Seric 			p_line = getval(p_line,filelist[num_files]);
1642154Seric 			num_files++;
1652154Seric 		}
1662154Seric 	}
1672154Seric 	/*
1682154Seric 	check if any files were named as arguments
1692154Seric 	*/
1702154Seric 	if (num_files == 0)
171*30500Slepreau 		inline_err |= FILARG_ERR;
1722154Seric 	/*
1732154Seric 	check for error in command line.
1742154Seric 	*/
1752154Seric 	if (inline_err && !silent) {
1762154Seric 		if (inpstd)
1772154Seric 			report(inline_err,savelinep,"");
1782154Seric 		else report(inline_err,"","");
1792154Seric 		return;		/* return to 'main' routine */
1802154Seric 	}
1812154Seric 	line_sw = 1;		/* print command line flag */
1822154Seric 	/*
1832154Seric 	loop through 'validate' for each file on command line.
1842154Seric 	*/
1852154Seric 	for (j = 0; j < num_files; j++) {
1862154Seric 		/*
1872154Seric 		read a file from 'filelist' and place into 'path'.
1882154Seric 		*/
1892154Seric 		sprintf(path,"%s",filelist[j]);
1902154Seric 		validate(path,sid,type,name);
191*30500Slepreau 		inline_err |= infile_err;
1922154Seric 		/*
1932154Seric 		check for error from 'validate' and call 'report'
1942154Seric 		depending on 'silent' flag.
1952154Seric 		*/
1962154Seric 		if (infile_err && !silent) {
1972154Seric 			if (line_sw && inpstd) {
1982154Seric 				report(infile_err,savelinep,path);
1992154Seric 				line_sw = 0;
2002154Seric 			}
2012154Seric 			else report(infile_err,"",path);
2022154Seric 		}
2032154Seric 	}
2042154Seric 	return;		/* return to 'main' routine */
2052154Seric }
2062154Seric 
2072154Seric 
2082154Seric /* This function actually does the validation on the named file.
2092154Seric  * It determines whether the file is an SCCS-file or if the file
2102154Seric  * exists.  It also determines if the values given for type, SID,
2112154Seric  * and name match those in the named file.  An error code is returned
2122154Seric  * if any mismatch occurs.  See VAL(I) for more information.
2132154Seric */
validate(c_path,c_sid,c_type,c_name)2142154Seric validate(c_path,c_sid,c_type,c_name)
2152154Seric char	*c_path;
2162154Seric char	*c_sid;
2172154Seric char	*c_type;
2182154Seric char	*c_name;
2192154Seric {
2202154Seric 	register char	*l;
2212154Seric 	int	goods,goodt,goodn,hadmflag;
2222154Seric 
2232154Seric 	infile_err = goods = goodt = goodn = hadmflag = 0;
2242154Seric 	sinit(&gpkt,c_path);
2252154Seric 	if (!sccsfile(c_path) || (gpkt.p_iop = fopen(c_path,"r")) == NULL)
226*30500Slepreau 		infile_err |= FILENAM_ERR;
2272154Seric 	else {
2282154Seric 		l = get_line(&gpkt);		/* read first line in file */
2292154Seric 		/*
2302154Seric 		check that it is header line.
2312154Seric 		*/
2322154Seric 		if (*l++ != CTLCHAR || *l++ != HEAD)
233*30500Slepreau 			infile_err |= CORRUPT_ERR;
2342154Seric 
2352154Seric 		else {
2362154Seric 			/*
2372154Seric 			get old file checksum count
2382154Seric 			*/
2392154Seric 			satoi(l,&gpkt.p_ihash);
2402154Seric 			gpkt.p_chash = 0;
2412154Seric 			if (HADR)
2422154Seric 				/*
2432154Seric 				check for invalid or ambiguous SID.
2442154Seric 				*/
2452154Seric 				if (invalid(c_sid))
246*30500Slepreau 					infile_err |= INVALSID_ERR;
2472154Seric 			/*
2482154Seric 			read delta table checking for errors and/or
2492154Seric 			SID.
2502154Seric 			*/
2512154Seric 			if (do_delt(&gpkt,goods,c_sid)) {
2522154Seric 				fclose(gpkt.p_iop);
253*30500Slepreau 				infile_err |= CORRUPT_ERR;
2542154Seric 				return;
2552154Seric 			}
2562154Seric 
2572154Seric 			read_to(EUSERNAM,&gpkt);
2582154Seric 
2592154Seric 			if (HADY || HADM) {
2602154Seric 				/*
2612154Seric 				read flag section of delta table.
2622154Seric 				*/
2632154Seric 				while ((l = get_line(&gpkt)) &&
2642154Seric 					*l++ == CTLCHAR &&
2652154Seric 					*l++ == FLAG) {
2662154Seric 					NONBLANK(l);
2672154Seric 					repl(l,'\n','\0');
2682154Seric 					if (*l == TYPEFLAG) {
269*30500Slepreau 						l += 2;
2702154Seric 						if (equal(c_type,l))
2712154Seric 							goodt++;
2722154Seric 					}
2732154Seric 					else if (*l == MODFLAG) {
2742154Seric 						hadmflag++;
275*30500Slepreau 						l += 2;
2762154Seric 						if (equal(c_name,l))
2772154Seric 							goodn++;
2782154Seric 					}
2792154Seric 				}
2802154Seric 				if (*(--l) != BUSERTXT) {
2812154Seric 					fclose(gpkt.p_iop);
282*30500Slepreau 					infile_err |= CORRUPT_ERR;
2832154Seric 					return;
2842154Seric 				}
2852154Seric 				/*
2862154Seric 				check if 'y' flag matched '-y' arg value.
2872154Seric 				*/
2882154Seric 				if (!goodt && HADY)
289*30500Slepreau 					infile_err |= TYPE_ERR;
2902154Seric 				/*
2912154Seric 				check if 'm' flag matched '-m' arg value.
2922154Seric 				*/
2932154Seric 				if (HADM && !hadmflag) {
2942154Seric 					if (!equal(auxf(sname(c_path),'g'),c_name))
295*30500Slepreau 						infile_err |= NAME_ERR;
2962154Seric 				}
2972154Seric 				else if (HADM && hadmflag && !goodn)
298*30500Slepreau 						infile_err |= NAME_ERR;
2992154Seric 			}
3002154Seric 			else read_to(BUSERTXT,&gpkt);
3012154Seric 			read_to(EUSERTXT,&gpkt);
3022154Seric 			gpkt.p_chkeof = 1;
3032154Seric 			/*
3042154Seric 			read remainder of file so 'read_mod'
3052154Seric 			can check for corruptness.
3062154Seric 			*/
3072154Seric 			while (read_mod(&gpkt))
3082154Seric 				;
3092154Seric 		}
3102154Seric 	fclose(gpkt.p_iop);	/* close file pointer */
3112154Seric 	}
3122154Seric 	return;		/* return to 'process' function */
3132154Seric }
3142154Seric 
3152154Seric 
3162154Seric /* This function reads the 'delta' line from the named file and stores
3172154Seric  * the information into the structure 'del'.
3182154Seric */
getdel(delp,lp)3192154Seric getdel(delp,lp)
3202154Seric register struct delent *delp;
3212154Seric register char *lp;
3222154Seric {
3232154Seric 	NONBLANK(lp);
3242154Seric 	delp->type = *lp++;
3252154Seric 	NONBLANK(lp);
3262154Seric 	delp->osid = lp;
3272154Seric 	BLANK(lp);
3282154Seric 	*lp++ = '\0';
3292154Seric 	NONBLANK(lp);
3302154Seric 	delp->datetime = lp;
3312154Seric 	BLANK(lp);
3322154Seric 	NONBLANK(lp);
3332154Seric 	BLANK(lp);
3342154Seric 	*lp++ = '\0';
3352154Seric 	NONBLANK(lp);
3362154Seric 	delp->pgmr = lp;
3372154Seric 	BLANK(lp);
3382154Seric 	*lp++ = '\0';
3392154Seric 	NONBLANK(lp);
3402154Seric 	delp->serial = lp;
3412154Seric 	BLANK(lp);
3422154Seric 	*lp++ = '\0';
3432154Seric 	NONBLANK(lp);
3442154Seric 	delp->pred = lp;
3452154Seric 	repl(lp,'\n','\0');
3462154Seric }
3472154Seric 
3482154Seric 
3492154Seric /* This function does a read through the named file until it finds
3502154Seric  * the character sent over as an argument.
3512154Seric */
read_to(ch,pkt)3522154Seric read_to(ch,pkt)
3532154Seric register char ch;
3542154Seric register struct packet *pkt;
3552154Seric {
3562154Seric 	register char *n;
3572154Seric 	while ((n = get_line(pkt)) &&
3582154Seric 			!(*n++ == CTLCHAR && *n == ch))
3592154Seric 		;
3602154Seric 	return;
3612154Seric }
3622154Seric 
3632154Seric 
3642154Seric /* This function places into a specified destination characters  which
3652154Seric  * are delimited by either a space, tab or 0.  It obtains the char-
3662154Seric  * acters from a line of characters.
3672154Seric */
getval(sourcep,destp)3682154Seric char	*getval(sourcep,destp)
3692154Seric register char	*sourcep;
3702154Seric register char	*destp;
3712154Seric {
3722154Seric 	while (*sourcep != ' ' && *sourcep != '\t' && *sourcep != '\0')
3732154Seric 		*destp++ = *sourcep++;
3742154Seric 	*destp = 0;
3752154Seric 	return(sourcep);
3762154Seric }
3772154Seric 
3782154Seric 
3792154Seric /* This function will report the error that occured on the command
3802154Seric  * line.  It will print one diagnostic message for each error that
3812154Seric  * was found in the named file.
3822154Seric */
report(code,inp_line,file)3832154Seric report(code,inp_line,file)
3842154Seric register int	code;
3852154Seric register char	*inp_line;
3862154Seric register char	*file;
3872154Seric {
3882154Seric 	char	percent;
3892154Seric 	percent = '%';		/* '%' for -m and/or -y messages */
3902154Seric 	if (*inp_line)
3912154Seric 		printf("%s\n\n",inp_line);
3922154Seric 	if (code & NAME_ERR)
3932154Seric 		printf("    %s: %cM%c, -m mismatch\n",file,percent,percent);
3942154Seric 	if (code & TYPE_ERR)
3952154Seric 		printf("    %s: %cY%c, -y mismatch\n",file,percent,percent);
3962154Seric 	if (code & NONEXSID_ERR)
3972154Seric 		printf("    %s: SID nonexistent\n",file);
3982154Seric 	if (code & INVALSID_ERR)
3992154Seric 		printf("    %s: SID invalid or ambiguous\n",file);
4002154Seric 	if (code & FILENAM_ERR)
4012154Seric 		printf("    %s: can't open file or file not SCCS\n",file);
4022154Seric 	if (code & CORRUPT_ERR)
4032154Seric 		printf("    %s: corrupted SCCS file\n",file);
4042154Seric 	if (code & UNKDUP_ERR)
4052154Seric 		printf("    %s: Unknown or dupilcate keyletter argument\n",file);
4062154Seric 	if (code & FILARG_ERR)
4072154Seric 		printf("    %s: missing file argument\n",file);
4082154Seric 	return;
4092154Seric }
4102154Seric 
4112154Seric 
4122154Seric /* This function takes as it's argument the SID inputed and determines
4132154Seric  * whether or not it is valid (e. g. not ambiguous or illegal).
4142154Seric */
invalid(i_sid)4152154Seric invalid(i_sid)
4162154Seric register char	*i_sid;
4172154Seric {
4182154Seric 	register int count;
4192154Seric 	register int digits;
4202154Seric 	count = digits = 0;
4212154Seric 	if (*i_sid == '0' || *i_sid == '.')
4222154Seric 		return (1);
4232154Seric 	i_sid++;
4242154Seric 	digits++;
4252154Seric 	while (*i_sid != '\0') {
4262154Seric 		if (*i_sid++ == '.') {
4272154Seric 			digits = 0;
4282154Seric 			count++;
4292154Seric 			if (*i_sid == '0' || *i_sid == '.')
4302154Seric 				return (1);
4312154Seric 		}
4322154Seric 		digits++;
4332154Seric 		if (digits > 5)
4342154Seric 			return (1);
4352154Seric 	}
4362154Seric 	if (*(--i_sid) == '.' )
4372154Seric 		return (1);
4382154Seric 	if (count == 1 || count == 3)
4392154Seric 		return (0);
4402154Seric 	return (1);
4412154Seric }
4422154Seric 
4432154Seric 
4442154Seric /*
4452154Seric 	Routine to read a line into the packet.  The main reason for
4462154Seric 	it is to make sure that pkt->p_wrttn gets turned off,
4472154Seric 	and to increment pkt->p_slnno.
4482154Seric */
4492154Seric 
get_line(pkt)4502154Seric char	*get_line(pkt)
4512154Seric register struct packet *pkt;
4522154Seric {
4532154Seric 	register char *n;
4542154Seric 	register char *p;
4552154Seric 
4562154Seric 	if ((n = fgets(pkt->p_line,sizeof(pkt->p_line),pkt->p_iop)) != NULL) {
4572154Seric 		pkt->p_slnno++;
4582154Seric 		for (p = pkt->p_line; *p; )
459*30500Slepreau 			pkt->p_chash += *p++;
4602154Seric 	}
4612154Seric 	else {
4622154Seric 		if (!pkt->p_chkeof)
463*30500Slepreau 			infile_err |= CORRUPT_ERR;
4642154Seric 		if (pkt->do_chksum && (pkt->p_chash ^ pkt->p_ihash)&0xFFFF)
465*30500Slepreau 			infile_err |= CORRUPT_ERR;
4662154Seric 	}
4672154Seric 	return(n);
4682154Seric }
4692154Seric 
4702154Seric 
4712154Seric /*
4722154Seric 	Does initialization for sccs files and packet.
4732154Seric */
4742154Seric 
sinit(pkt,file)4752154Seric sinit(pkt,file)
4762154Seric register struct packet *pkt;
4772154Seric register char *file;
4782154Seric {
4792154Seric 
48019944Ssam 	bzero(pkt,sizeof(*pkt));
4812154Seric 	copy(file,pkt->p_file);
4822154Seric 	pkt->p_wrttn = 1;
4832154Seric 	pkt->do_chksum = 1;	/* turn on checksum check for getline */
4842154Seric }
4852154Seric 
4862154Seric 
read_mod(pkt)4872154Seric read_mod(pkt)
4882154Seric register struct packet *pkt;
4892154Seric {
4902154Seric 	register char *p;
4912154Seric 	int ser;
4922154Seric 	int iord;
4932154Seric 	register struct apply *ap;
4942154Seric 
4952154Seric 	while (get_line(pkt) != NULL) {
4962154Seric 		p = pkt->p_line;
4972154Seric 		if (*p++ != CTLCHAR)
4982154Seric 			continue;
4992154Seric 		else {
5002154Seric 			if (!((iord = *p++) == INS || iord == DEL || iord == END)) {
501*30500Slepreau 				infile_err |= CORRUPT_ERR;
5022154Seric 				return(0);
5032154Seric 			}
5042154Seric 			NONBLANK(p);
5052154Seric 			satoi(p,&ser);
5062154Seric 			if (iord == END)
5072154Seric 				remq(pkt,ser);
5082154Seric 			else if ((ap = &pkt->p_apply[ser])->a_code == APPLY)
5092154Seric 				addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER);
5102154Seric 			else
5112154Seric 				addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER);
5122154Seric 		}
5132154Seric 	}
5142154Seric 	if (pkt->p_q)
515*30500Slepreau 		infile_err |= CORRUPT_ERR;
5162154Seric 	return(0);
5172154Seric }
5182154Seric 
5192154Seric 
5202154Seric addq(pkt,ser,keep,iord,user)
5212154Seric struct packet *pkt;
5222154Seric int ser;
5232154Seric int keep;
5242154Seric int iord;
5252154Seric {
5262154Seric 	register struct queue *cur, *prev, *q;
5272154Seric 
5282154Seric 	for (cur = &pkt->p_q; cur = (prev = cur)->q_next; )
5292154Seric 		if (cur->q_sernum <= ser)
5302154Seric 			break;
5312154Seric 	if (cur->q_sernum == ser)
532*30500Slepreau 		infile_err |= CORRUPT_ERR;
5332154Seric 	prev->q_next = q = alloc(sizeof(*q));
5342154Seric 	q->q_next = cur;
5352154Seric 	q->q_sernum = ser;
5362154Seric 	q->q_keep = keep;
5372154Seric 	q->q_iord = iord;
5382154Seric 	q->q_user = user;
5392154Seric 	if (pkt->p_ixuser && (q->q_ixmsg = chkix(q,&pkt->p_q)))
5402154Seric 		++(pkt->p_ixmsg);
5412154Seric 	else
5422154Seric 		q->q_ixmsg = 0;
5432154Seric 
5442154Seric 	setkeep(pkt);
5452154Seric }
5462154Seric 
5472154Seric 
remq(pkt,ser)5482154Seric remq(pkt,ser)
5492154Seric register struct packet *pkt;
5502154Seric int ser;
5512154Seric {
5522154Seric 	register struct queue *cur, *prev;
5532154Seric 
5542154Seric 	for (cur = &pkt->p_q; cur = (prev = cur)->q_next; )
5552154Seric 		if (cur->q_sernum == ser)
5562154Seric 			break;
5572154Seric 	if (cur) {
5582154Seric 		if (cur->q_ixmsg)
5592154Seric 			--(pkt->p_ixmsg);
5602154Seric 		prev->q_next = cur->q_next;
5612154Seric 		free(cur);
5622154Seric 		setkeep(pkt);
5632154Seric 	}
5642154Seric 	else
565*30500Slepreau 		infile_err |= CORRUPT_ERR;
5662154Seric }
5672154Seric 
5682154Seric 
setkeep(pkt)5692154Seric setkeep(pkt)
5702154Seric register struct packet *pkt;
5712154Seric {
5722154Seric 	register struct queue *q;
5732154Seric 	register struct sid *sp;
5742154Seric 
5752154Seric 	for (q = &pkt->p_q; q = q->q_next; )
5762154Seric 		if (q->q_keep != NULL) {
5772154Seric 			if ((pkt->p_keep = q->q_keep) == YES) {
5782154Seric 				sp = &pkt->p_idel[q->q_sernum].i_sid;
5792154Seric 				pkt->p_inssid.s_rel = sp->s_rel;
5802154Seric 				pkt->p_inssid.s_lev = sp->s_lev;
5812154Seric 				pkt->p_inssid.s_br = sp->s_br;
5822154Seric 				pkt->p_inssid.s_seq = sp->s_seq;
5832154Seric 			}
5842154Seric 			return;
5852154Seric 		}
5862154Seric 	pkt->p_keep = NO;
5872154Seric }
5882154Seric 
5892154Seric 
5902154Seric # define apply(qp)	((qp->q_iord == INS && qp->q_keep == YES) || (qp->q_iord == DEL && qp->q_keep == NO))
5912154Seric 
chkix(new,head)5922154Seric chkix(new,head)
5932154Seric register struct queue *new;
5942154Seric struct queue *head;
5952154Seric {
5962154Seric 	register int retval;
5972154Seric 	register struct queue *cur;
5982154Seric 	int firstins, lastdel;
5992154Seric 
6002154Seric 	if (!apply(new))
6012154Seric 		return(0);
6022154Seric 	for (cur = head; cur = cur->q_next; )
6032154Seric 		if (cur->q_user)
6042154Seric 			break;
6052154Seric 	if (!cur)
6062154Seric 		return(0);
6072154Seric 	retval = 0;
6082154Seric 	firstins = 0;
6092154Seric 	lastdel = 0;
6102154Seric 	for (cur = head; cur = cur->q_next; ) {
6112154Seric 		if (apply(cur)) {
6122154Seric 			if (cur->q_iord == DEL)
6132154Seric 				lastdel = cur->q_sernum;
6142154Seric 			else if (firstins == 0)
6152154Seric 				firstins = cur->q_sernum;
6162154Seric 		}
6172154Seric 		else if (cur->q_iord == INS)
6182154Seric 			retval++;
6192154Seric 	}
6202154Seric 	if (retval == 0) {
6212154Seric 		if (lastdel && (new->q_sernum > lastdel))
6222154Seric 			retval++;
6232154Seric 		if (firstins && (new->q_sernum < firstins))
6242154Seric 			retval++;
6252154Seric 	}
6262154Seric 	return(retval);
6272154Seric }
6282154Seric 
6292154Seric 
6302154Seric /* This function reads the delta table entries and checks for the format
6312154Seric  * as specifed in sccsfile(V).  If the format is incorrect, a corrupt
6322154Seric  * error will be issued by 'val'.  This function also checks
6332154Seric  * if the sid requested is in the file (depending if '-r' was specified).
6342154Seric */
do_delt(pkt,goods,d_sid)6352154Seric do_delt(pkt,goods,d_sid)
6362154Seric register struct packet *pkt;
6372154Seric register int goods;
6382154Seric register char *d_sid;
6392154Seric {
6402154Seric 	char *l;
6412154Seric 
6422154Seric 	while(getstats(pkt)) {
6432154Seric 		if ((l = get_line(pkt)) && *l++ != CTLCHAR || *l++ != BDELTAB)
6442154Seric 			return(1);
6452154Seric 		if (HADR && !(infile_err & INVALSID_ERR)) {
6462154Seric 			getdel(&del,l);
6472154Seric 			if (equal(d_sid,del.osid) && del.type == 'D')
6482154Seric 				goods++;
6492154Seric 		}
6502154Seric 		while ((l = get_line(pkt)) != NULL)
6512154Seric 			if (pkt->p_line[0] != CTLCHAR)
6522154Seric 				break;
6532154Seric 			else {
6542154Seric 				switch(pkt->p_line[1]) {
6552154Seric 				case EDELTAB:
6562154Seric 					break;
6572154Seric 				case COMMENTS:
6582154Seric 				case MRNUM:
6592154Seric 				case INCLUDE:
6602154Seric 				case EXCLUDE:
6612154Seric 				case IGNORE:
6622154Seric 					continue;
6632154Seric 				default:
6642154Seric 					return(1);
6652154Seric 				}
6662154Seric 				break;
6672154Seric 			}
6682154Seric 		if (l == NULL || pkt->p_line[0] != CTLCHAR)
6692154Seric 			return(1);
6702154Seric 	}
6712154Seric 	if (pkt->p_line[1] != BUSERNAM)
6722154Seric 		return(1);
6732154Seric 	if (HADR && !goods && !(infile_err & INVALSID_ERR))
674*30500Slepreau 		infile_err |= NONEXSID_ERR;
6752154Seric 	return(0);
6762154Seric }
6772154Seric 
6782154Seric 
6792154Seric /* This function reads the stats line from the sccsfile */
getstats(pkt)6802154Seric getstats(pkt)
6812154Seric register struct packet *pkt;
6822154Seric {
6832154Seric 	register char *p;
6842154Seric 	p = pkt->p_line;
6852154Seric 	if (get_line(pkt) == NULL || *p++ != CTLCHAR || *p != STATS)
6862154Seric 		return(0);
6872154Seric 	return(1);
6882154Seric }
689