1bfa18a87Seric /************************************************************************/
2bfa18a87Seric /* */
3bfa18a87Seric /* val - */
4bfa18a87Seric /* val [-mname] [-rSID] [-s] [-ytype] file ... */
5bfa18a87Seric /* */
6bfa18a87Seric /************************************************************************/
7bfa18a87Seric
8bfa18a87Seric # include "../hdr/defines.h"
9bfa18a87Seric # include "../hdr/had.h"
10bfa18a87Seric
11bfa18a87Seric # define FILARG_ERR 0200 /* no file name given */
12bfa18a87Seric # define UNKDUP_ERR 0100 /* unknown or duplicate keyletter */
13bfa18a87Seric # define CORRUPT_ERR 040 /* corrupt file error code */
14bfa18a87Seric # define FILENAM_ERR 020 /* file name error code */
15bfa18a87Seric # define INVALSID_ERR 010 /* invalid or ambiguous SID error */
16bfa18a87Seric # define NONEXSID_ERR 04 /* non-existent SID error code */
17bfa18a87Seric # define TYPE_ERR 02 /* type arg value error code */
18bfa18a87Seric # define NAME_ERR 01 /* name arg value error code */
19bfa18a87Seric # define TRUE 1
20bfa18a87Seric # define FALSE 0
21bfa18a87Seric # define BLANK(l) while (!(*l == ' ' || *l == '\t')) l++;
22bfa18a87Seric
23bfa18a87Seric int ret_code; /* prime return code from 'main' program */
24bfa18a87Seric int inline_err; /* input line error code (from 'process') */
25bfa18a87Seric int infile_err; /* file error code (from 'validate') */
26bfa18a87Seric int inpstd; /* TRUE = args from standard input */
27bfa18a87Seric
28bfa18a87Seric struct packet gpkt;
29bfa18a87Seric
30bfa18a87Seric char had[26]; /* had flag used in 'process' function */
31bfa18a87Seric char path[50]; /* storage for file name value */
32bfa18a87Seric char sid[50]; /* storage for sid (-r) value */
33bfa18a87Seric char type[50]; /* storage for type (-y) value */
34bfa18a87Seric char name[50]; /* storage for name (-m) value */
35bfa18a87Seric char line[BUFSIZ];
36bfa18a87Seric char *get_line(); /* function returning ptr to line read */
37bfa18a87Seric char *getval(); /* function returning adjusted ptr to line */
38bfa18a87Seric char *alloc(); /* function returning ptr */
39bfa18a87Seric char *fgets(); /* function returning i/o ptr */
40bfa18a87Seric
41bfa18a87Seric struct delent { /* structure for delta table entry */
42bfa18a87Seric char type;
43bfa18a87Seric char *osid;
44bfa18a87Seric char *datetime;
45bfa18a87Seric char *pgmr;
46bfa18a87Seric char *serial;
47bfa18a87Seric char *pred;
48bfa18a87Seric } del;
49bfa18a87Seric
50*d75847e8Slepreau static char Sccsid[] = "@(#)val.c 4.3 02/15/87";
51bfa18a87Seric
52bfa18a87Seric /* This is the main program that determines whether the command line
53bfa18a87Seric * comes from the standard input or read off the original command
54bfa18a87Seric * line. See VAL(I) for more information.
55bfa18a87Seric */
main(argc,argv)56bfa18a87Seric main(argc,argv)
57bfa18a87Seric int argc;
58bfa18a87Seric char *argv[];
59bfa18a87Seric {
60bfa18a87Seric FILE *iop;
61bfa18a87Seric register int j;
62bfa18a87Seric
63bfa18a87Seric ret_code = 0;
64bfa18a87Seric if (argc == 2 && argv[1][0] == '-' && !(argv[1][1])) {
65bfa18a87Seric inpstd = TRUE;
66bfa18a87Seric iop = stdin; /* read from standard input */
67bfa18a87Seric while (fgets(line,BUFSIZ,iop) != NULL) {
68bfa18a87Seric if (line[0] != '\n') {
69bfa18a87Seric repl (line,'\n','\0');
70bfa18a87Seric process(line);
71*d75847e8Slepreau ret_code |= inline_err;
72bfa18a87Seric }
73bfa18a87Seric }
74bfa18a87Seric }
75bfa18a87Seric else {
76bfa18a87Seric inpstd = FALSE;
77bfa18a87Seric for (j = 1; j < argc; j++)
78bfa18a87Seric sprintf(&(line[strlen(line)]),"%s ",argv[j]);
79bfa18a87Seric j = strlen(line) - 1;
80bfa18a87Seric line[j > 0 ? j : 0] = NULL;
81bfa18a87Seric process(line);
82bfa18a87Seric ret_code = inline_err;
83bfa18a87Seric }
84bfa18a87Seric exit(ret_code);
85bfa18a87Seric }
86bfa18a87Seric
87bfa18a87Seric
88bfa18a87Seric /* This function processes the line sent by the main routine. It
89bfa18a87Seric * determines which keyletter values are present on the command
90bfa18a87Seric * line and assigns the values to the correct storage place. It
91bfa18a87Seric * then calls validate for each file name on the command line
92bfa18a87Seric * It will return to main if the input line contains an error,
93bfa18a87Seric * otherwise it returns any error code found by validate.
94bfa18a87Seric */
process(p_line)95bfa18a87Seric process(p_line)
96bfa18a87Seric char *p_line;
97bfa18a87Seric {
98bfa18a87Seric register int j;
99bfa18a87Seric register int testklt;
100bfa18a87Seric register int line_sw;
101bfa18a87Seric
102bfa18a87Seric int silent;
103bfa18a87Seric int num_files;
104bfa18a87Seric
105bfa18a87Seric char filelist[50][50];
106bfa18a87Seric char *savelinep;
107bfa18a87Seric char c;
108bfa18a87Seric
109bfa18a87Seric silent = FALSE;
110bfa18a87Seric path[0] = sid[0] = type[0] = name[0] = 0;
111bfa18a87Seric num_files = inline_err = 0;
112bfa18a87Seric
113bfa18a87Seric /*
114bfa18a87Seric make copy of 'line' for use later
115bfa18a87Seric */
116bfa18a87Seric savelinep = p_line;
117bfa18a87Seric /*
118bfa18a87Seric clear out had flags for each 'line' processed
119bfa18a87Seric */
120bfa18a87Seric for (j = 0; j < 27; j++)
121bfa18a87Seric had[j] = 0;
122bfa18a87Seric /*
123bfa18a87Seric execute loop until all characters in 'line' are checked.
124bfa18a87Seric */
125bfa18a87Seric while (*p_line) {
126bfa18a87Seric testklt = 1;
127bfa18a87Seric NONBLANK(p_line);
128bfa18a87Seric if (*p_line == '-') {
129*d75847e8Slepreau p_line += 1;
130bfa18a87Seric c = *p_line;
131bfa18a87Seric p_line++;
132bfa18a87Seric switch (c) {
133bfa18a87Seric case 's':
134bfa18a87Seric testklt = 0;
135bfa18a87Seric /*
136bfa18a87Seric turn on 'silent' flag.
137bfa18a87Seric */
138bfa18a87Seric silent = TRUE;
139bfa18a87Seric break;
140bfa18a87Seric case 'r':
141bfa18a87Seric p_line = getval(p_line,sid);
142bfa18a87Seric break;
143bfa18a87Seric case 'y':
144bfa18a87Seric p_line = getval(p_line,type);
145bfa18a87Seric break;
146bfa18a87Seric case 'm':
147bfa18a87Seric p_line = getval(p_line,name);
148bfa18a87Seric break;
149bfa18a87Seric default:
150*d75847e8Slepreau inline_err |= UNKDUP_ERR;
151bfa18a87Seric }
152bfa18a87Seric /*
153bfa18a87Seric use 'had' array and determine if the keyletter
154bfa18a87Seric was given twice.
155bfa18a87Seric */
156bfa18a87Seric if (had[c - 'a']++ && testklt++)
157*d75847e8Slepreau inline_err |= UNKDUP_ERR;
158bfa18a87Seric }
159bfa18a87Seric else {
160bfa18a87Seric /*
161bfa18a87Seric assume file name if no '-' preceeded argument
162bfa18a87Seric */
163bfa18a87Seric p_line = getval(p_line,filelist[num_files]);
164bfa18a87Seric num_files++;
165bfa18a87Seric }
166bfa18a87Seric }
167bfa18a87Seric /*
168bfa18a87Seric check if any files were named as arguments
169bfa18a87Seric */
170bfa18a87Seric if (num_files == 0)
171*d75847e8Slepreau inline_err |= FILARG_ERR;
172bfa18a87Seric /*
173bfa18a87Seric check for error in command line.
174bfa18a87Seric */
175bfa18a87Seric if (inline_err && !silent) {
176bfa18a87Seric if (inpstd)
177bfa18a87Seric report(inline_err,savelinep,"");
178bfa18a87Seric else report(inline_err,"","");
179bfa18a87Seric return; /* return to 'main' routine */
180bfa18a87Seric }
181bfa18a87Seric line_sw = 1; /* print command line flag */
182bfa18a87Seric /*
183bfa18a87Seric loop through 'validate' for each file on command line.
184bfa18a87Seric */
185bfa18a87Seric for (j = 0; j < num_files; j++) {
186bfa18a87Seric /*
187bfa18a87Seric read a file from 'filelist' and place into 'path'.
188bfa18a87Seric */
189bfa18a87Seric sprintf(path,"%s",filelist[j]);
190bfa18a87Seric validate(path,sid,type,name);
191*d75847e8Slepreau inline_err |= infile_err;
192bfa18a87Seric /*
193bfa18a87Seric check for error from 'validate' and call 'report'
194bfa18a87Seric depending on 'silent' flag.
195bfa18a87Seric */
196bfa18a87Seric if (infile_err && !silent) {
197bfa18a87Seric if (line_sw && inpstd) {
198bfa18a87Seric report(infile_err,savelinep,path);
199bfa18a87Seric line_sw = 0;
200bfa18a87Seric }
201bfa18a87Seric else report(infile_err,"",path);
202bfa18a87Seric }
203bfa18a87Seric }
204bfa18a87Seric return; /* return to 'main' routine */
205bfa18a87Seric }
206bfa18a87Seric
207bfa18a87Seric
208bfa18a87Seric /* This function actually does the validation on the named file.
209bfa18a87Seric * It determines whether the file is an SCCS-file or if the file
210bfa18a87Seric * exists. It also determines if the values given for type, SID,
211bfa18a87Seric * and name match those in the named file. An error code is returned
212bfa18a87Seric * if any mismatch occurs. See VAL(I) for more information.
213bfa18a87Seric */
validate(c_path,c_sid,c_type,c_name)214bfa18a87Seric validate(c_path,c_sid,c_type,c_name)
215bfa18a87Seric char *c_path;
216bfa18a87Seric char *c_sid;
217bfa18a87Seric char *c_type;
218bfa18a87Seric char *c_name;
219bfa18a87Seric {
220bfa18a87Seric register char *l;
221bfa18a87Seric int goods,goodt,goodn,hadmflag;
222bfa18a87Seric
223bfa18a87Seric infile_err = goods = goodt = goodn = hadmflag = 0;
224bfa18a87Seric sinit(&gpkt,c_path);
225bfa18a87Seric if (!sccsfile(c_path) || (gpkt.p_iop = fopen(c_path,"r")) == NULL)
226*d75847e8Slepreau infile_err |= FILENAM_ERR;
227bfa18a87Seric else {
228bfa18a87Seric l = get_line(&gpkt); /* read first line in file */
229bfa18a87Seric /*
230bfa18a87Seric check that it is header line.
231bfa18a87Seric */
232bfa18a87Seric if (*l++ != CTLCHAR || *l++ != HEAD)
233*d75847e8Slepreau infile_err |= CORRUPT_ERR;
234bfa18a87Seric
235bfa18a87Seric else {
236bfa18a87Seric /*
237bfa18a87Seric get old file checksum count
238bfa18a87Seric */
239bfa18a87Seric satoi(l,&gpkt.p_ihash);
240bfa18a87Seric gpkt.p_chash = 0;
241bfa18a87Seric if (HADR)
242bfa18a87Seric /*
243bfa18a87Seric check for invalid or ambiguous SID.
244bfa18a87Seric */
245bfa18a87Seric if (invalid(c_sid))
246*d75847e8Slepreau infile_err |= INVALSID_ERR;
247bfa18a87Seric /*
248bfa18a87Seric read delta table checking for errors and/or
249bfa18a87Seric SID.
250bfa18a87Seric */
251bfa18a87Seric if (do_delt(&gpkt,goods,c_sid)) {
252bfa18a87Seric fclose(gpkt.p_iop);
253*d75847e8Slepreau infile_err |= CORRUPT_ERR;
254bfa18a87Seric return;
255bfa18a87Seric }
256bfa18a87Seric
257bfa18a87Seric read_to(EUSERNAM,&gpkt);
258bfa18a87Seric
259bfa18a87Seric if (HADY || HADM) {
260bfa18a87Seric /*
261bfa18a87Seric read flag section of delta table.
262bfa18a87Seric */
263bfa18a87Seric while ((l = get_line(&gpkt)) &&
264bfa18a87Seric *l++ == CTLCHAR &&
265bfa18a87Seric *l++ == FLAG) {
266bfa18a87Seric NONBLANK(l);
267bfa18a87Seric repl(l,'\n','\0');
268bfa18a87Seric if (*l == TYPEFLAG) {
269*d75847e8Slepreau l += 2;
270bfa18a87Seric if (equal(c_type,l))
271bfa18a87Seric goodt++;
272bfa18a87Seric }
273bfa18a87Seric else if (*l == MODFLAG) {
274bfa18a87Seric hadmflag++;
275*d75847e8Slepreau l += 2;
276bfa18a87Seric if (equal(c_name,l))
277bfa18a87Seric goodn++;
278bfa18a87Seric }
279bfa18a87Seric }
280bfa18a87Seric if (*(--l) != BUSERTXT) {
281bfa18a87Seric fclose(gpkt.p_iop);
282*d75847e8Slepreau infile_err |= CORRUPT_ERR;
283bfa18a87Seric return;
284bfa18a87Seric }
285bfa18a87Seric /*
286bfa18a87Seric check if 'y' flag matched '-y' arg value.
287bfa18a87Seric */
288bfa18a87Seric if (!goodt && HADY)
289*d75847e8Slepreau infile_err |= TYPE_ERR;
290bfa18a87Seric /*
291bfa18a87Seric check if 'm' flag matched '-m' arg value.
292bfa18a87Seric */
293bfa18a87Seric if (HADM && !hadmflag) {
294bfa18a87Seric if (!equal(auxf(sname(c_path),'g'),c_name))
295*d75847e8Slepreau infile_err |= NAME_ERR;
296bfa18a87Seric }
297bfa18a87Seric else if (HADM && hadmflag && !goodn)
298*d75847e8Slepreau infile_err |= NAME_ERR;
299bfa18a87Seric }
300bfa18a87Seric else read_to(BUSERTXT,&gpkt);
301bfa18a87Seric read_to(EUSERTXT,&gpkt);
302bfa18a87Seric gpkt.p_chkeof = 1;
303bfa18a87Seric /*
304bfa18a87Seric read remainder of file so 'read_mod'
305bfa18a87Seric can check for corruptness.
306bfa18a87Seric */
307bfa18a87Seric while (read_mod(&gpkt))
308bfa18a87Seric ;
309bfa18a87Seric }
310bfa18a87Seric fclose(gpkt.p_iop); /* close file pointer */
311bfa18a87Seric }
312bfa18a87Seric return; /* return to 'process' function */
313bfa18a87Seric }
314bfa18a87Seric
315bfa18a87Seric
316bfa18a87Seric /* This function reads the 'delta' line from the named file and stores
317bfa18a87Seric * the information into the structure 'del'.
318bfa18a87Seric */
getdel(delp,lp)319bfa18a87Seric getdel(delp,lp)
320bfa18a87Seric register struct delent *delp;
321bfa18a87Seric register char *lp;
322bfa18a87Seric {
323bfa18a87Seric NONBLANK(lp);
324bfa18a87Seric delp->type = *lp++;
325bfa18a87Seric NONBLANK(lp);
326bfa18a87Seric delp->osid = lp;
327bfa18a87Seric BLANK(lp);
328bfa18a87Seric *lp++ = '\0';
329bfa18a87Seric NONBLANK(lp);
330bfa18a87Seric delp->datetime = lp;
331bfa18a87Seric BLANK(lp);
332bfa18a87Seric NONBLANK(lp);
333bfa18a87Seric BLANK(lp);
334bfa18a87Seric *lp++ = '\0';
335bfa18a87Seric NONBLANK(lp);
336bfa18a87Seric delp->pgmr = lp;
337bfa18a87Seric BLANK(lp);
338bfa18a87Seric *lp++ = '\0';
339bfa18a87Seric NONBLANK(lp);
340bfa18a87Seric delp->serial = lp;
341bfa18a87Seric BLANK(lp);
342bfa18a87Seric *lp++ = '\0';
343bfa18a87Seric NONBLANK(lp);
344bfa18a87Seric delp->pred = lp;
345bfa18a87Seric repl(lp,'\n','\0');
346bfa18a87Seric }
347bfa18a87Seric
348bfa18a87Seric
349bfa18a87Seric /* This function does a read through the named file until it finds
350bfa18a87Seric * the character sent over as an argument.
351bfa18a87Seric */
read_to(ch,pkt)352bfa18a87Seric read_to(ch,pkt)
353bfa18a87Seric register char ch;
354bfa18a87Seric register struct packet *pkt;
355bfa18a87Seric {
356bfa18a87Seric register char *n;
357bfa18a87Seric while ((n = get_line(pkt)) &&
358bfa18a87Seric !(*n++ == CTLCHAR && *n == ch))
359bfa18a87Seric ;
360bfa18a87Seric return;
361bfa18a87Seric }
362bfa18a87Seric
363bfa18a87Seric
364bfa18a87Seric /* This function places into a specified destination characters which
365bfa18a87Seric * are delimited by either a space, tab or 0. It obtains the char-
366bfa18a87Seric * acters from a line of characters.
367bfa18a87Seric */
getval(sourcep,destp)368bfa18a87Seric char *getval(sourcep,destp)
369bfa18a87Seric register char *sourcep;
370bfa18a87Seric register char *destp;
371bfa18a87Seric {
372bfa18a87Seric while (*sourcep != ' ' && *sourcep != '\t' && *sourcep != '\0')
373bfa18a87Seric *destp++ = *sourcep++;
374bfa18a87Seric *destp = 0;
375bfa18a87Seric return(sourcep);
376bfa18a87Seric }
377bfa18a87Seric
378bfa18a87Seric
379bfa18a87Seric /* This function will report the error that occured on the command
380bfa18a87Seric * line. It will print one diagnostic message for each error that
381bfa18a87Seric * was found in the named file.
382bfa18a87Seric */
report(code,inp_line,file)383bfa18a87Seric report(code,inp_line,file)
384bfa18a87Seric register int code;
385bfa18a87Seric register char *inp_line;
386bfa18a87Seric register char *file;
387bfa18a87Seric {
388bfa18a87Seric char percent;
389bfa18a87Seric percent = '%'; /* '%' for -m and/or -y messages */
390bfa18a87Seric if (*inp_line)
391bfa18a87Seric printf("%s\n\n",inp_line);
392bfa18a87Seric if (code & NAME_ERR)
393bfa18a87Seric printf(" %s: %cM%c, -m mismatch\n",file,percent,percent);
394bfa18a87Seric if (code & TYPE_ERR)
395bfa18a87Seric printf(" %s: %cY%c, -y mismatch\n",file,percent,percent);
396bfa18a87Seric if (code & NONEXSID_ERR)
397bfa18a87Seric printf(" %s: SID nonexistent\n",file);
398bfa18a87Seric if (code & INVALSID_ERR)
399bfa18a87Seric printf(" %s: SID invalid or ambiguous\n",file);
400bfa18a87Seric if (code & FILENAM_ERR)
401bfa18a87Seric printf(" %s: can't open file or file not SCCS\n",file);
402bfa18a87Seric if (code & CORRUPT_ERR)
403bfa18a87Seric printf(" %s: corrupted SCCS file\n",file);
404bfa18a87Seric if (code & UNKDUP_ERR)
405bfa18a87Seric printf(" %s: Unknown or dupilcate keyletter argument\n",file);
406bfa18a87Seric if (code & FILARG_ERR)
407bfa18a87Seric printf(" %s: missing file argument\n",file);
408bfa18a87Seric return;
409bfa18a87Seric }
410bfa18a87Seric
411bfa18a87Seric
412bfa18a87Seric /* This function takes as it's argument the SID inputed and determines
413bfa18a87Seric * whether or not it is valid (e. g. not ambiguous or illegal).
414bfa18a87Seric */
invalid(i_sid)415bfa18a87Seric invalid(i_sid)
416bfa18a87Seric register char *i_sid;
417bfa18a87Seric {
418bfa18a87Seric register int count;
419bfa18a87Seric register int digits;
420bfa18a87Seric count = digits = 0;
421bfa18a87Seric if (*i_sid == '0' || *i_sid == '.')
422bfa18a87Seric return (1);
423bfa18a87Seric i_sid++;
424bfa18a87Seric digits++;
425bfa18a87Seric while (*i_sid != '\0') {
426bfa18a87Seric if (*i_sid++ == '.') {
427bfa18a87Seric digits = 0;
428bfa18a87Seric count++;
429bfa18a87Seric if (*i_sid == '0' || *i_sid == '.')
430bfa18a87Seric return (1);
431bfa18a87Seric }
432bfa18a87Seric digits++;
433bfa18a87Seric if (digits > 5)
434bfa18a87Seric return (1);
435bfa18a87Seric }
436bfa18a87Seric if (*(--i_sid) == '.' )
437bfa18a87Seric return (1);
438bfa18a87Seric if (count == 1 || count == 3)
439bfa18a87Seric return (0);
440bfa18a87Seric return (1);
441bfa18a87Seric }
442bfa18a87Seric
443bfa18a87Seric
444bfa18a87Seric /*
445bfa18a87Seric Routine to read a line into the packet. The main reason for
446bfa18a87Seric it is to make sure that pkt->p_wrttn gets turned off,
447bfa18a87Seric and to increment pkt->p_slnno.
448bfa18a87Seric */
449bfa18a87Seric
get_line(pkt)450bfa18a87Seric char *get_line(pkt)
451bfa18a87Seric register struct packet *pkt;
452bfa18a87Seric {
453bfa18a87Seric register char *n;
454bfa18a87Seric register char *p;
455bfa18a87Seric
456bfa18a87Seric if ((n = fgets(pkt->p_line,sizeof(pkt->p_line),pkt->p_iop)) != NULL) {
457bfa18a87Seric pkt->p_slnno++;
458bfa18a87Seric for (p = pkt->p_line; *p; )
459*d75847e8Slepreau pkt->p_chash += *p++;
460bfa18a87Seric }
461bfa18a87Seric else {
462bfa18a87Seric if (!pkt->p_chkeof)
463*d75847e8Slepreau infile_err |= CORRUPT_ERR;
464bfa18a87Seric if (pkt->do_chksum && (pkt->p_chash ^ pkt->p_ihash)&0xFFFF)
465*d75847e8Slepreau infile_err |= CORRUPT_ERR;
466bfa18a87Seric }
467bfa18a87Seric return(n);
468bfa18a87Seric }
469bfa18a87Seric
470bfa18a87Seric
471bfa18a87Seric /*
472bfa18a87Seric Does initialization for sccs files and packet.
473bfa18a87Seric */
474bfa18a87Seric
sinit(pkt,file)475bfa18a87Seric sinit(pkt,file)
476bfa18a87Seric register struct packet *pkt;
477bfa18a87Seric register char *file;
478bfa18a87Seric {
479bfa18a87Seric
4806123ee97Ssam bzero(pkt,sizeof(*pkt));
481bfa18a87Seric copy(file,pkt->p_file);
482bfa18a87Seric pkt->p_wrttn = 1;
483bfa18a87Seric pkt->do_chksum = 1; /* turn on checksum check for getline */
484bfa18a87Seric }
485bfa18a87Seric
486bfa18a87Seric
read_mod(pkt)487bfa18a87Seric read_mod(pkt)
488bfa18a87Seric register struct packet *pkt;
489bfa18a87Seric {
490bfa18a87Seric register char *p;
491bfa18a87Seric int ser;
492bfa18a87Seric int iord;
493bfa18a87Seric register struct apply *ap;
494bfa18a87Seric
495bfa18a87Seric while (get_line(pkt) != NULL) {
496bfa18a87Seric p = pkt->p_line;
497bfa18a87Seric if (*p++ != CTLCHAR)
498bfa18a87Seric continue;
499bfa18a87Seric else {
500bfa18a87Seric if (!((iord = *p++) == INS || iord == DEL || iord == END)) {
501*d75847e8Slepreau infile_err |= CORRUPT_ERR;
502bfa18a87Seric return(0);
503bfa18a87Seric }
504bfa18a87Seric NONBLANK(p);
505bfa18a87Seric satoi(p,&ser);
506bfa18a87Seric if (iord == END)
507bfa18a87Seric remq(pkt,ser);
508bfa18a87Seric else if ((ap = &pkt->p_apply[ser])->a_code == APPLY)
509bfa18a87Seric addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER);
510bfa18a87Seric else
511bfa18a87Seric addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER);
512bfa18a87Seric }
513bfa18a87Seric }
514bfa18a87Seric if (pkt->p_q)
515*d75847e8Slepreau infile_err |= CORRUPT_ERR;
516bfa18a87Seric return(0);
517bfa18a87Seric }
518bfa18a87Seric
519bfa18a87Seric
520bfa18a87Seric addq(pkt,ser,keep,iord,user)
521bfa18a87Seric struct packet *pkt;
522bfa18a87Seric int ser;
523bfa18a87Seric int keep;
524bfa18a87Seric int iord;
525bfa18a87Seric {
526bfa18a87Seric register struct queue *cur, *prev, *q;
527bfa18a87Seric
528bfa18a87Seric for (cur = &pkt->p_q; cur = (prev = cur)->q_next; )
529bfa18a87Seric if (cur->q_sernum <= ser)
530bfa18a87Seric break;
531bfa18a87Seric if (cur->q_sernum == ser)
532*d75847e8Slepreau infile_err |= CORRUPT_ERR;
533bfa18a87Seric prev->q_next = q = alloc(sizeof(*q));
534bfa18a87Seric q->q_next = cur;
535bfa18a87Seric q->q_sernum = ser;
536bfa18a87Seric q->q_keep = keep;
537bfa18a87Seric q->q_iord = iord;
538bfa18a87Seric q->q_user = user;
539bfa18a87Seric if (pkt->p_ixuser && (q->q_ixmsg = chkix(q,&pkt->p_q)))
540bfa18a87Seric ++(pkt->p_ixmsg);
541bfa18a87Seric else
542bfa18a87Seric q->q_ixmsg = 0;
543bfa18a87Seric
544bfa18a87Seric setkeep(pkt);
545bfa18a87Seric }
546bfa18a87Seric
547bfa18a87Seric
remq(pkt,ser)548bfa18a87Seric remq(pkt,ser)
549bfa18a87Seric register struct packet *pkt;
550bfa18a87Seric int ser;
551bfa18a87Seric {
552bfa18a87Seric register struct queue *cur, *prev;
553bfa18a87Seric
554bfa18a87Seric for (cur = &pkt->p_q; cur = (prev = cur)->q_next; )
555bfa18a87Seric if (cur->q_sernum == ser)
556bfa18a87Seric break;
557bfa18a87Seric if (cur) {
558bfa18a87Seric if (cur->q_ixmsg)
559bfa18a87Seric --(pkt->p_ixmsg);
560bfa18a87Seric prev->q_next = cur->q_next;
561bfa18a87Seric free(cur);
562bfa18a87Seric setkeep(pkt);
563bfa18a87Seric }
564bfa18a87Seric else
565*d75847e8Slepreau infile_err |= CORRUPT_ERR;
566bfa18a87Seric }
567bfa18a87Seric
568bfa18a87Seric
setkeep(pkt)569bfa18a87Seric setkeep(pkt)
570bfa18a87Seric register struct packet *pkt;
571bfa18a87Seric {
572bfa18a87Seric register struct queue *q;
573bfa18a87Seric register struct sid *sp;
574bfa18a87Seric
575bfa18a87Seric for (q = &pkt->p_q; q = q->q_next; )
576bfa18a87Seric if (q->q_keep != NULL) {
577bfa18a87Seric if ((pkt->p_keep = q->q_keep) == YES) {
578bfa18a87Seric sp = &pkt->p_idel[q->q_sernum].i_sid;
579bfa18a87Seric pkt->p_inssid.s_rel = sp->s_rel;
580bfa18a87Seric pkt->p_inssid.s_lev = sp->s_lev;
581bfa18a87Seric pkt->p_inssid.s_br = sp->s_br;
582bfa18a87Seric pkt->p_inssid.s_seq = sp->s_seq;
583bfa18a87Seric }
584bfa18a87Seric return;
585bfa18a87Seric }
586bfa18a87Seric pkt->p_keep = NO;
587bfa18a87Seric }
588bfa18a87Seric
589bfa18a87Seric
590bfa18a87Seric # define apply(qp) ((qp->q_iord == INS && qp->q_keep == YES) || (qp->q_iord == DEL && qp->q_keep == NO))
591bfa18a87Seric
chkix(new,head)592bfa18a87Seric chkix(new,head)
593bfa18a87Seric register struct queue *new;
594bfa18a87Seric struct queue *head;
595bfa18a87Seric {
596bfa18a87Seric register int retval;
597bfa18a87Seric register struct queue *cur;
598bfa18a87Seric int firstins, lastdel;
599bfa18a87Seric
600bfa18a87Seric if (!apply(new))
601bfa18a87Seric return(0);
602bfa18a87Seric for (cur = head; cur = cur->q_next; )
603bfa18a87Seric if (cur->q_user)
604bfa18a87Seric break;
605bfa18a87Seric if (!cur)
606bfa18a87Seric return(0);
607bfa18a87Seric retval = 0;
608bfa18a87Seric firstins = 0;
609bfa18a87Seric lastdel = 0;
610bfa18a87Seric for (cur = head; cur = cur->q_next; ) {
611bfa18a87Seric if (apply(cur)) {
612bfa18a87Seric if (cur->q_iord == DEL)
613bfa18a87Seric lastdel = cur->q_sernum;
614bfa18a87Seric else if (firstins == 0)
615bfa18a87Seric firstins = cur->q_sernum;
616bfa18a87Seric }
617bfa18a87Seric else if (cur->q_iord == INS)
618bfa18a87Seric retval++;
619bfa18a87Seric }
620bfa18a87Seric if (retval == 0) {
621bfa18a87Seric if (lastdel && (new->q_sernum > lastdel))
622bfa18a87Seric retval++;
623bfa18a87Seric if (firstins && (new->q_sernum < firstins))
624bfa18a87Seric retval++;
625bfa18a87Seric }
626bfa18a87Seric return(retval);
627bfa18a87Seric }
628bfa18a87Seric
629bfa18a87Seric
630bfa18a87Seric /* This function reads the delta table entries and checks for the format
631bfa18a87Seric * as specifed in sccsfile(V). If the format is incorrect, a corrupt
632bfa18a87Seric * error will be issued by 'val'. This function also checks
633bfa18a87Seric * if the sid requested is in the file (depending if '-r' was specified).
634bfa18a87Seric */
do_delt(pkt,goods,d_sid)635bfa18a87Seric do_delt(pkt,goods,d_sid)
636bfa18a87Seric register struct packet *pkt;
637bfa18a87Seric register int goods;
638bfa18a87Seric register char *d_sid;
639bfa18a87Seric {
640bfa18a87Seric char *l;
641bfa18a87Seric
642bfa18a87Seric while(getstats(pkt)) {
643bfa18a87Seric if ((l = get_line(pkt)) && *l++ != CTLCHAR || *l++ != BDELTAB)
644bfa18a87Seric return(1);
645bfa18a87Seric if (HADR && !(infile_err & INVALSID_ERR)) {
646bfa18a87Seric getdel(&del,l);
647bfa18a87Seric if (equal(d_sid,del.osid) && del.type == 'D')
648bfa18a87Seric goods++;
649bfa18a87Seric }
650bfa18a87Seric while ((l = get_line(pkt)) != NULL)
651bfa18a87Seric if (pkt->p_line[0] != CTLCHAR)
652bfa18a87Seric break;
653bfa18a87Seric else {
654bfa18a87Seric switch(pkt->p_line[1]) {
655bfa18a87Seric case EDELTAB:
656bfa18a87Seric break;
657bfa18a87Seric case COMMENTS:
658bfa18a87Seric case MRNUM:
659bfa18a87Seric case INCLUDE:
660bfa18a87Seric case EXCLUDE:
661bfa18a87Seric case IGNORE:
662bfa18a87Seric continue;
663bfa18a87Seric default:
664bfa18a87Seric return(1);
665bfa18a87Seric }
666bfa18a87Seric break;
667bfa18a87Seric }
668bfa18a87Seric if (l == NULL || pkt->p_line[0] != CTLCHAR)
669bfa18a87Seric return(1);
670bfa18a87Seric }
671bfa18a87Seric if (pkt->p_line[1] != BUSERNAM)
672bfa18a87Seric return(1);
673bfa18a87Seric if (HADR && !goods && !(infile_err & INVALSID_ERR))
674*d75847e8Slepreau infile_err |= NONEXSID_ERR;
675bfa18a87Seric return(0);
676bfa18a87Seric }
677bfa18a87Seric
678bfa18a87Seric
679bfa18a87Seric /* This function reads the stats line from the sccsfile */
getstats(pkt)680bfa18a87Seric getstats(pkt)
681bfa18a87Seric register struct packet *pkt;
682bfa18a87Seric {
683bfa18a87Seric register char *p;
684bfa18a87Seric p = pkt->p_line;
685bfa18a87Seric if (get_line(pkt) == NULL || *p++ != CTLCHAR || *p != STATS)
686bfa18a87Seric return(0);
687bfa18a87Seric return(1);
688bfa18a87Seric }
689