1349ae6eaSeric # include	"../hdr/defines.h"
2349ae6eaSeric # include	"../hdr/had.h"
3*b0bb49d8Ssam # include	<dir.h>
4349ae6eaSeric 
5*b0bb49d8Ssam SCCSID(@(#)get.c	4.4);
6349ae6eaSeric USXALLOC();
7349ae6eaSeric 
8349ae6eaSeric int	Debug	0;
9349ae6eaSeric struct packet gpkt;
10349ae6eaSeric struct sid sid;
11349ae6eaSeric unsigned	Ser;
12349ae6eaSeric int	num_files;
13349ae6eaSeric char	had[26];
14349ae6eaSeric char	*ilist, *elist, *lfile;
15349ae6eaSeric long	cutoff	0X7FFFFFFFL;	/* max positive long */
16349ae6eaSeric int verbosity;
17*b0bb49d8Ssam char	Gfile[MAXNAMLEN + 3];
18349ae6eaSeric char	*Type;
19349ae6eaSeric int	Did_id;
20349ae6eaSeric 
21349ae6eaSeric main(argc,argv)
22349ae6eaSeric int argc;
23349ae6eaSeric register char *argv[];
24349ae6eaSeric {
25349ae6eaSeric 	register int i;
26349ae6eaSeric 	register char *p;
27349ae6eaSeric 	char c;
28349ae6eaSeric 	int testmore;
29349ae6eaSeric 	extern int Fcnt;
30349ae6eaSeric 	extern get();
31349ae6eaSeric 
32349ae6eaSeric 	Fflags = FTLEXIT | FTLMSG | FTLCLN;
33349ae6eaSeric 	for(i=1; i<argc; i++)
34349ae6eaSeric 		if(argv[i][0] == '-' && (c=argv[i][1])) {
35349ae6eaSeric 			p = &argv[i][2];
36349ae6eaSeric 			testmore = 0;
37349ae6eaSeric 			switch (c) {
38349ae6eaSeric 
39349ae6eaSeric 			case 'a':
40349ae6eaSeric 				if (!p[0]) {
41349ae6eaSeric 					argv[i] = 0;
42349ae6eaSeric 					continue;
43349ae6eaSeric 				}
44349ae6eaSeric 				Ser = patoi(p);
45349ae6eaSeric 				break;
46349ae6eaSeric 			case 'r':
47349ae6eaSeric 				if (!p[0]) {
48349ae6eaSeric 					argv[i] = 0;
49349ae6eaSeric 					continue;
50349ae6eaSeric 				}
51349ae6eaSeric 				chksid(sid_ab(p,&sid),&sid);
52349ae6eaSeric 				break;
53349ae6eaSeric 			case 'c':
54349ae6eaSeric 				if (!p[0]) {
55349ae6eaSeric 					argv[i] = 0;
56349ae6eaSeric 					continue;
57349ae6eaSeric 				}
58349ae6eaSeric 				if (date_ab(p,&cutoff))
59349ae6eaSeric 					fatal("bad date/time (cm5)");
60349ae6eaSeric 				break;
61349ae6eaSeric 			case 'l':
62349ae6eaSeric 				lfile = p;
63349ae6eaSeric 				break;
64349ae6eaSeric 			case 'i':
65349ae6eaSeric 				if (!p[0]) {
66349ae6eaSeric 					argv[i] = 0;
67349ae6eaSeric 					continue;
68349ae6eaSeric 				}
69349ae6eaSeric 				ilist = p;
70349ae6eaSeric 				break;
71349ae6eaSeric 			case 'x':
72349ae6eaSeric 				if (!p[0]) {
73349ae6eaSeric 					argv[i] = 0;
74349ae6eaSeric 					continue;
75349ae6eaSeric 				}
76349ae6eaSeric 				elist = p;
77349ae6eaSeric 				break;
78349ae6eaSeric 			case 'b':
79349ae6eaSeric 			case 'g':
80349ae6eaSeric 			case 'e':
81349ae6eaSeric 			case 'p':
82349ae6eaSeric 			case 'k':
83349ae6eaSeric 			case 'm':
84349ae6eaSeric 			case 'n':
85349ae6eaSeric 			case 's':
86349ae6eaSeric 			case 't':
87349ae6eaSeric 				testmore++;
88349ae6eaSeric 				break;
89349ae6eaSeric 			default:
90349ae6eaSeric 				fatal("unknown key letter (cm1)");
91349ae6eaSeric 			}
92349ae6eaSeric 
93349ae6eaSeric 			if (testmore) {
94349ae6eaSeric 				testmore = 0;
95349ae6eaSeric 				if (*p)
96349ae6eaSeric 					fatal(sprintf(Error,
97349ae6eaSeric 					  "value after %c arg (cm8)",c));
98349ae6eaSeric 			}
99349ae6eaSeric 			if (had[c - 'a']++)
100349ae6eaSeric 				fatal("key letter twice (cm2)");
101349ae6eaSeric 			argv[i] = 0;
102349ae6eaSeric 		}
103349ae6eaSeric 		else num_files++;
104349ae6eaSeric 
105349ae6eaSeric 	if(num_files == 0)
106349ae6eaSeric 		fatal("missing file arg (cm3)");
107349ae6eaSeric 	if (HADE && HADM)
108349ae6eaSeric 		fatal("e not allowed with m (ge3)");
109349ae6eaSeric 	if (HADE || HADI || HADX)
110349ae6eaSeric 		HADK = 1;
111349ae6eaSeric 	if (!HADS)
112349ae6eaSeric 		verbosity = -1;
113349ae6eaSeric 	setsig();
114349ae6eaSeric 	Fflags =& ~FTLEXIT;
115349ae6eaSeric 	Fflags =| FTLJMP;
116349ae6eaSeric 	for (i=1; i<argc; i++)
117349ae6eaSeric 		if (p=argv[i])
118349ae6eaSeric 			do_file(p,get);
119349ae6eaSeric 	exit(Fcnt ? 1 : 0);
120349ae6eaSeric }
121349ae6eaSeric 
122349ae6eaSeric 
123349ae6eaSeric get(file)
124349ae6eaSeric {
125349ae6eaSeric 	register char *p;
126349ae6eaSeric 	register unsigned ser;
127349ae6eaSeric 	extern char had_dir, had_standinp;
128349ae6eaSeric 	extern char *Sflags[];
129349ae6eaSeric 	struct stats stats;
130349ae6eaSeric 	char	str[32];
131349ae6eaSeric 
132349ae6eaSeric 	if (setjmp(Fjmp))
133349ae6eaSeric 		return;
134349ae6eaSeric 	sinit(&gpkt,file,1);
135349ae6eaSeric 	gpkt.p_ixuser = (HADI | HADX);
136349ae6eaSeric 	gpkt.p_reqsid.s_rel = sid.s_rel;
137349ae6eaSeric 	gpkt.p_reqsid.s_lev = sid.s_lev;
138349ae6eaSeric 	gpkt.p_reqsid.s_br = sid.s_br;
139349ae6eaSeric 	gpkt.p_reqsid.s_seq = sid.s_seq;
140349ae6eaSeric 	gpkt.p_verbose = verbosity;
141349ae6eaSeric 	gpkt.p_stdout = (HADP ? stderr : stdout);
142349ae6eaSeric 	gpkt.p_cutoff = cutoff;
143349ae6eaSeric 	gpkt.p_lfile = lfile;
144349ae6eaSeric 	copy(auxf(gpkt.p_file,'g'),Gfile);
145349ae6eaSeric 
146349ae6eaSeric 	if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
147349ae6eaSeric 		fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
148349ae6eaSeric 	if (dodelt(&gpkt,&stats,0,0) == 0)
149349ae6eaSeric 		fmterr(&gpkt);
150349ae6eaSeric 	finduser(&gpkt);
151349ae6eaSeric 	doflags(&gpkt);
152349ae6eaSeric 	if (!HADA)
153349ae6eaSeric 		ser = getser(&gpkt);
154349ae6eaSeric 	else {
155349ae6eaSeric 		if ((ser = Ser) > maxser(&gpkt))
156349ae6eaSeric 			fatal("serial number too large (ge19)");
157349ae6eaSeric 		move(&gpkt.p_idel[ser].i_sid, &gpkt.p_gotsid, sizeof(sid));
158349ae6eaSeric 		if (HADR && sid.s_rel != gpkt.p_gotsid.s_rel) {
159349ae6eaSeric 			zero(&gpkt.p_reqsid, sizeof(gpkt.p_reqsid));
160349ae6eaSeric 			gpkt.p_reqsid.s_rel = sid.s_rel;
161349ae6eaSeric 		}
162349ae6eaSeric 		else
163349ae6eaSeric 			move(&gpkt.p_gotsid, &gpkt.p_reqsid, sizeof(sid));
164349ae6eaSeric 	}
165349ae6eaSeric 	doie(&gpkt,ilist,elist,0);
166349ae6eaSeric 	setup(&gpkt,ser);
167349ae6eaSeric 	if (!(Type = Sflags[TYPEFLAG - 'a']))
168349ae6eaSeric 		Type = Null;
169024721e9Seric 	if (!(HADP || HADG) && writable(Gfile))
170349ae6eaSeric 		fatal(sprintf(Error,"writable `%s' exists (ge4)",Gfile));
171349ae6eaSeric 	if (gpkt.p_verbose) {
172349ae6eaSeric 		sid_ba(&gpkt.p_gotsid,str);
173349ae6eaSeric 		fprintf(gpkt.p_stdout,"%s\n",str);
174349ae6eaSeric 	}
175349ae6eaSeric 	if (HADE) {
176349ae6eaSeric 		if (!HADR)
177349ae6eaSeric 			move(&gpkt.p_gotsid,&gpkt.p_reqsid,
178349ae6eaSeric 			     sizeof(gpkt.p_reqsid));
179349ae6eaSeric 		newsid(&gpkt,Sflags[BRCHFLAG - 'a'] && HADB);
180349ae6eaSeric 		permiss(&gpkt);
181349ae6eaSeric 		wrtpfile(&gpkt,ilist,elist);
182349ae6eaSeric 	}
183349ae6eaSeric 	setuid(getuid());
184349ae6eaSeric 	if (HADL)
185349ae6eaSeric 		gen_lfile(&gpkt);
186349ae6eaSeric 	if (HADG) {
187349ae6eaSeric 		fclose(gpkt.p_iop);
188349ae6eaSeric 		xfreeall();
189349ae6eaSeric 		return;
190349ae6eaSeric 	}
191349ae6eaSeric 	flushto(&gpkt,EUSERTXT,1);
192349ae6eaSeric 	idsetup(&gpkt);
193349ae6eaSeric 	gpkt.p_chkeof = 1;
194349ae6eaSeric 	Did_id = 0;
195349ae6eaSeric 	while(readmod(&gpkt)) {
196349ae6eaSeric 		if (gpkt.p_gout == 0) {
197349ae6eaSeric 			if (HADP)
198349ae6eaSeric 				gpkt.p_gout = stdout;
199349ae6eaSeric 			else
200d15e2020Seric 				gpkt.p_gout = xfcreat(Gfile,HADK ? 0666 : 0444);
201349ae6eaSeric 		}
202349ae6eaSeric 		prfx(&gpkt);
203349ae6eaSeric 		p = idsubst(&gpkt,gpkt.p_line);
204349ae6eaSeric 		fputs(p,gpkt.p_gout);
205349ae6eaSeric 	}
206349ae6eaSeric 	fflush(gpkt.p_gout);
207349ae6eaSeric 	if (gpkt.p_gout && gpkt.p_gout != stdout)
208349ae6eaSeric 		fclose(gpkt.p_gout);
209349ae6eaSeric 	if (gpkt.p_verbose)
210349ae6eaSeric 		fprintf(gpkt.p_stdout,"%u lines\n",gpkt.p_glnno);
211349ae6eaSeric 	if (!Did_id && !HADK)
212349ae6eaSeric 		if (Sflags[IDFLAG - 'a'])
213349ae6eaSeric 			fatal("no id keywords (cm6)");
214349ae6eaSeric 		else if (gpkt.p_verbose)
215349ae6eaSeric 			fprintf(stderr,"No id keywords (cm7)\n");
216349ae6eaSeric 	xfreeall();
217349ae6eaSeric }
218349ae6eaSeric 
219024721e9Seric writable(fn)
220024721e9Seric char *fn;
221024721e9Seric {
222024721e9Seric 	struct stat s;
223024721e9Seric 
224024721e9Seric 	return (stat(fn, &s) >= 0 && (s.st_mode & 0222) != 0);
225024721e9Seric }
226024721e9Seric 
227349ae6eaSeric 
228349ae6eaSeric newsid(pkt,branch)
229349ae6eaSeric register struct packet *pkt;
230349ae6eaSeric int branch;
231349ae6eaSeric {
232349ae6eaSeric 	int chkbr;
233349ae6eaSeric 
234349ae6eaSeric 	chkbr = 0;
235349ae6eaSeric 	if (pkt->p_reqsid.s_br == 0) {
236349ae6eaSeric 		pkt->p_reqsid.s_lev =+ 1;
237349ae6eaSeric 		if (sidtoser(&pkt->p_reqsid,pkt) ||
238349ae6eaSeric 			pkt->p_maxr > pkt->p_reqsid.s_rel || branch) {
239349ae6eaSeric 				pkt->p_reqsid.s_rel = pkt->p_gotsid.s_rel;
240349ae6eaSeric 				pkt->p_reqsid.s_lev = pkt->p_gotsid.s_lev;
241349ae6eaSeric 				pkt->p_reqsid.s_br = pkt->p_gotsid.s_br + 1;
242349ae6eaSeric 				pkt->p_reqsid.s_seq = 1;
243349ae6eaSeric 				chkbr++;
244349ae6eaSeric 		}
245349ae6eaSeric 	}
246349ae6eaSeric 	else if (pkt->p_reqsid.s_seq == 0 && !branch)
247349ae6eaSeric 		pkt->p_reqsid.s_seq = pkt->p_gotsid.s_seq + 1;
248349ae6eaSeric 	else {
249349ae6eaSeric 		pkt->p_reqsid.s_seq =+ 1;
250349ae6eaSeric 		if (branch || sidtoser(&pkt->p_reqsid,pkt)) {
251349ae6eaSeric 			pkt->p_reqsid.s_br =+ 1;
252349ae6eaSeric 			pkt->p_reqsid.s_seq = 1;
253349ae6eaSeric 			chkbr++;
254349ae6eaSeric 		}
255349ae6eaSeric 	}
256349ae6eaSeric 	if (chkbr)
257349ae6eaSeric 		while (sidtoser(&pkt->p_reqsid,pkt))
258349ae6eaSeric 			pkt->p_reqsid.s_br =+ 1;
259349ae6eaSeric 	if (sidtoser(&pkt->p_reqsid,pkt))
260349ae6eaSeric 		fatal("internal error in newsid()");
261349ae6eaSeric }
262349ae6eaSeric 
263349ae6eaSeric 
264349ae6eaSeric enter(pkt,ch,n,sidp)
265349ae6eaSeric struct packet *pkt;
266349ae6eaSeric char ch;
267349ae6eaSeric int n;
268349ae6eaSeric struct sid *sidp;
269349ae6eaSeric {
270349ae6eaSeric 	char str[32];
271349ae6eaSeric 	register struct apply *ap;
272349ae6eaSeric 
273349ae6eaSeric 	sid_ba(sidp,str);
274349ae6eaSeric 	if (pkt->p_verbose)
275349ae6eaSeric 		fprintf(pkt->p_stdout,"%s\n",str);
276349ae6eaSeric 	ap = &pkt->p_apply[n];
277349ae6eaSeric 	switch(ap->a_code) {
278349ae6eaSeric 
279349ae6eaSeric 	case EMPTY:
280349ae6eaSeric 		if (ch == INCLUDE)
281349ae6eaSeric 			condset(ap,APPLY,INCLUSER);
282349ae6eaSeric 		else
283349ae6eaSeric 			condset(ap,NOAPPLY,EXCLUSER);
284349ae6eaSeric 		break;
285349ae6eaSeric 	case APPLY:
286349ae6eaSeric 		sid_ba(sidp,str);
287349ae6eaSeric 		fatal(sprintf(Error,"%s already included (ge9)",str));
288349ae6eaSeric 		break;
289349ae6eaSeric 	case NOAPPLY:
290349ae6eaSeric 		sid_ba(sidp,str);
291349ae6eaSeric 		fatal(sprintf(Error,"%s already excluded (ge10)",str));
292349ae6eaSeric 		break;
293349ae6eaSeric 	default:
294349ae6eaSeric 		fatal("internal error in get/enter() (ge11)");
295349ae6eaSeric 		break;
296349ae6eaSeric 	}
297349ae6eaSeric }
298349ae6eaSeric 
299349ae6eaSeric 
300349ae6eaSeric gen_lfile(pkt)
301349ae6eaSeric register struct packet *pkt;
302349ae6eaSeric {
303349ae6eaSeric 	int n;
304349ae6eaSeric 	int reason;
305349ae6eaSeric 	char str[32];
306349ae6eaSeric 	char line[BUFSIZ];
307349ae6eaSeric 	struct deltab dt;
308349ae6eaSeric 	FILE *in;
309349ae6eaSeric 	FILE *out;
310349ae6eaSeric 
311349ae6eaSeric 	in = xfopen(pkt->p_file,0);
312349ae6eaSeric 	if (*pkt->p_lfile)
313349ae6eaSeric 		out = stdout;
314349ae6eaSeric 	else
315349ae6eaSeric 		out = xfcreat(auxf(pkt->p_file,'l'),0444);
316349ae6eaSeric 	fgets(line,sizeof(line),in);
317349ae6eaSeric 	while (fgets(line,sizeof(line),in) != NULL && line[0] == CTLCHAR && line[1] == STATS) {
318349ae6eaSeric 		fgets(line,sizeof(line),in);
319349ae6eaSeric 		del_ab(line,&dt);
320349ae6eaSeric 		if (dt.d_type == 'D') {
321349ae6eaSeric 			reason = pkt->p_apply[dt.d_serial].a_reason;
322349ae6eaSeric 			if (pkt->p_apply[dt.d_serial].a_code == APPLY) {
323349ae6eaSeric 				putc(' ',out);
324349ae6eaSeric 				putc(' ',out);
325349ae6eaSeric 			}
326349ae6eaSeric 			else {
327349ae6eaSeric 				putc('*',out);
328349ae6eaSeric 				if (reason & IGNR)
329349ae6eaSeric 					putc(' ',out);
330349ae6eaSeric 				else
331349ae6eaSeric 					putc('*',out);
332349ae6eaSeric 			}
333349ae6eaSeric 			switch (reason & (INCL | EXCL | CUTOFF)) {
334349ae6eaSeric 
335349ae6eaSeric 			case INCL:
336349ae6eaSeric 				putc('I',out);
337349ae6eaSeric 				break;
338349ae6eaSeric 			case EXCL:
339349ae6eaSeric 				putc('X',out);
340349ae6eaSeric 				break;
341349ae6eaSeric 			case CUTOFF:
342349ae6eaSeric 				putc('C',out);
343349ae6eaSeric 				break;
344349ae6eaSeric 			default:
345349ae6eaSeric 				putc(' ',out);
346349ae6eaSeric 				break;
347349ae6eaSeric 			}
348349ae6eaSeric 			putc(' ',out);
349349ae6eaSeric 			sid_ba(&dt.d_sid,str);
350349ae6eaSeric 			fprintf(out,"%s\t",str);
351349ae6eaSeric 			date_ba(&dt.d_datetime,str);
352349ae6eaSeric 			fprintf(out,"%s %s\n",str,dt.d_pgmr);
353349ae6eaSeric 		}
354349ae6eaSeric 		while ((n = fgets(line,sizeof(line),in)) != NULL)
355349ae6eaSeric 			if (line[0] != CTLCHAR)
356349ae6eaSeric 				break;
357349ae6eaSeric 			else {
358349ae6eaSeric 				switch (line[1]) {
359349ae6eaSeric 
360349ae6eaSeric 				case EDELTAB:
361349ae6eaSeric 					break;
362349ae6eaSeric 				default:
363349ae6eaSeric 					continue;
364349ae6eaSeric 				case MRNUM:
365349ae6eaSeric 				case COMMENTS:
366349ae6eaSeric 					if (dt.d_type == 'D')
367349ae6eaSeric 						fprintf(out,"\t%s",&line[3]);
368349ae6eaSeric 					continue;
369349ae6eaSeric 				}
370349ae6eaSeric 				break;
371349ae6eaSeric 			}
372349ae6eaSeric 		if (n == NULL || line[0] != CTLCHAR)
373349ae6eaSeric 			break;
374349ae6eaSeric 		putc('\n',out);
375349ae6eaSeric 	}
376349ae6eaSeric 	fclose(in);
377349ae6eaSeric 	if (out != stdout)
378349ae6eaSeric 		fclose(out);
379349ae6eaSeric }
380349ae6eaSeric 
381349ae6eaSeric 
382349ae6eaSeric char	Curdate[18];
383349ae6eaSeric char	*Curtime;
384349ae6eaSeric char	Gdate[9];
385349ae6eaSeric char	Chgdate[18];
386349ae6eaSeric char	*Chgtime;
387349ae6eaSeric char	Gchgdate[9];
388349ae6eaSeric char	Sid[32];
389*b0bb49d8Ssam char	Mod[MAXNAMLEN + 3];		/* should be as large as Gfile? */
390349ae6eaSeric char	Olddir[BUFSIZ];
391349ae6eaSeric char	Pname[BUFSIZ];
392349ae6eaSeric char	Dir[BUFSIZ];
393349ae6eaSeric 
394349ae6eaSeric idsetup(pkt)
395349ae6eaSeric register struct packet *pkt;
396349ae6eaSeric {
397349ae6eaSeric 	extern long Timenow;
398349ae6eaSeric 	register int n;
399349ae6eaSeric 	register char *p;
400349ae6eaSeric 
401349ae6eaSeric 	date_ba(&Timenow,Curdate);
402349ae6eaSeric 	Curtime = &Curdate[9];
403349ae6eaSeric 	Curdate[8] = 0;
404349ae6eaSeric 	copy(pkt->p_file,Dir);
405349ae6eaSeric 	dname(Dir);
406349ae6eaSeric 	if(curdir(Olddir) != 0)
407349ae6eaSeric 		fatal("curdir failed (ge20)");
408349ae6eaSeric 	if(chdir(Dir) != 0)
409349ae6eaSeric 		fatal("cannot change directory (ge22)");
410349ae6eaSeric 	if(curdir(Pname) != 0)
411349ae6eaSeric 		fatal("curdir failed (ge21)");
412349ae6eaSeric 	if(chdir(Olddir) != 0)
413349ae6eaSeric 		fatal("cannot change directory (ge23)");
414349ae6eaSeric 	makgdate(Curdate,Gdate);
415349ae6eaSeric 	for (n = maxser(pkt); n; n--)
416349ae6eaSeric 		if (pkt->p_apply[n].a_code == APPLY)
417349ae6eaSeric 			break;
418349ae6eaSeric 	if (n)
419349ae6eaSeric 		date_ba(&pkt->p_idel[n].i_datetime,Chgdate);
420349ae6eaSeric 	Chgtime = &Chgdate[9];
421349ae6eaSeric 	Chgdate[8] = 0;
422349ae6eaSeric 	makgdate(Chgdate,Gchgdate);
423349ae6eaSeric 	sid_ba(&pkt->p_gotsid,Sid);
424349ae6eaSeric 	if (p = Sflags[MODFLAG - 'a'])
425349ae6eaSeric 		copy(p,Mod);
426349ae6eaSeric 	else
427349ae6eaSeric 		copy(Gfile,Mod);
428349ae6eaSeric }
429349ae6eaSeric 
430349ae6eaSeric 
431349ae6eaSeric makgdate(old,new)
432349ae6eaSeric register char *old, *new;
433349ae6eaSeric {
434349ae6eaSeric 	if ((*new = old[3]) != '0')
435349ae6eaSeric 		new++;
436349ae6eaSeric 	*new++ = old[4];
437349ae6eaSeric 	*new++ = '/';
438349ae6eaSeric 	if ((*new = old[6]) != '0')
439349ae6eaSeric 		new++;
440349ae6eaSeric 	*new++ = old[7];
441349ae6eaSeric 	*new++ = '/';
442349ae6eaSeric 	*new++ = old[0];
443349ae6eaSeric 	*new++ = old[1];
444349ae6eaSeric 	*new = 0;
445349ae6eaSeric }
446349ae6eaSeric 
447349ae6eaSeric 
448349ae6eaSeric static char Zkeywd[5]	"@(#)";
449349ae6eaSeric 
450349ae6eaSeric idsubst(pkt,line)
451349ae6eaSeric register struct packet *pkt;
452349ae6eaSeric char line[];
453349ae6eaSeric {
454349ae6eaSeric 	static char tline[BUFSIZ];
455349ae6eaSeric 	static char str[32];
456349ae6eaSeric 	register char *lp, *tp;
457349ae6eaSeric 	extern char *Type;
458349ae6eaSeric 	extern char *Sflags[];
459349ae6eaSeric 
460349ae6eaSeric 	if (HADK || !any('%',line))
461349ae6eaSeric 		return(line);
462349ae6eaSeric 
463349ae6eaSeric 	tp = tline;
464349ae6eaSeric 	for(lp=line; *lp != 0; lp++) {
465349ae6eaSeric 		if(lp[0] == '%' && lp[1] != 0 && lp[2] == '%') {
466349ae6eaSeric 			switch(*++lp) {
467349ae6eaSeric 
468349ae6eaSeric 			case 'M':
469349ae6eaSeric 				tp = trans(tp,Mod);
470349ae6eaSeric 				break;
471349ae6eaSeric 			case 'R':
472349ae6eaSeric 				sprintf(str,"%u",pkt->p_gotsid.s_rel);
473349ae6eaSeric 				tp = trans(tp,str);
474349ae6eaSeric 				break;
475349ae6eaSeric 			case 'L':
476349ae6eaSeric 				sprintf(str,"%u",pkt->p_gotsid.s_lev);
477349ae6eaSeric 				tp = trans(tp,str);
478349ae6eaSeric 				break;
479349ae6eaSeric 			case 'B':
480349ae6eaSeric 				sprintf(str,"%u",pkt->p_gotsid.s_br);
481349ae6eaSeric 				tp = trans(tp,str);
482349ae6eaSeric 				break;
483349ae6eaSeric 			case 'S':
484349ae6eaSeric 				sprintf(str,"%u",pkt->p_gotsid.s_seq);
485349ae6eaSeric 				tp = trans(tp,str);
486349ae6eaSeric 				break;
487349ae6eaSeric 			case 'D':
488349ae6eaSeric 				tp = trans(tp,Curdate);
489349ae6eaSeric 				break;
490349ae6eaSeric 			case 'H':
491349ae6eaSeric 				tp = trans(tp,Gdate);
492349ae6eaSeric 				break;
493349ae6eaSeric 			case 'T':
494349ae6eaSeric 				tp = trans(tp,Curtime);
495349ae6eaSeric 				break;
496349ae6eaSeric 			case 'E':
497349ae6eaSeric 				tp = trans(tp,Chgdate);
498349ae6eaSeric 				break;
499349ae6eaSeric 			case 'G':
500349ae6eaSeric 				tp = trans(tp,Gchgdate);
501349ae6eaSeric 				break;
502349ae6eaSeric 			case 'U':
503349ae6eaSeric 				tp = trans(tp,Chgtime);
504349ae6eaSeric 				break;
505349ae6eaSeric 			case 'Z':
506349ae6eaSeric 				tp = trans(tp,Zkeywd);
507349ae6eaSeric 				break;
508349ae6eaSeric 			case 'Y':
509349ae6eaSeric 				tp = trans(tp,Type);
510349ae6eaSeric 				break;
511349ae6eaSeric 			case 'W':
512349ae6eaSeric 				tp = trans(tp,Zkeywd);
513349ae6eaSeric 				tp = trans(tp,Mod);
514349ae6eaSeric 				*tp++ = '\t';
515349ae6eaSeric 			case 'I':
516349ae6eaSeric 				tp = trans(tp,Sid);
517349ae6eaSeric 				break;
518349ae6eaSeric 			case 'P':
519349ae6eaSeric 				tp = trans(tp,Pname);
520349ae6eaSeric 				*tp++ = '/';
521349ae6eaSeric 				tp = trans(tp,(sname(pkt->p_file)));
522349ae6eaSeric 				break;
523349ae6eaSeric 			case 'F':
524349ae6eaSeric 				tp = trans(tp,pkt->p_file);
525349ae6eaSeric 				break;
526349ae6eaSeric 			case 'C':
527349ae6eaSeric 				sprintf(str,"%u",pkt->p_glnno);
528349ae6eaSeric 				tp = trans(tp,str);
529349ae6eaSeric 				break;
530349ae6eaSeric 			case 'A':
531349ae6eaSeric 				tp = trans(tp,Zkeywd);
532349ae6eaSeric 				tp = trans(tp,Type);
533349ae6eaSeric 				*tp++ = ' ';
534349ae6eaSeric 				tp = trans(tp,Mod);
535349ae6eaSeric 				*tp++ = ' ';
536349ae6eaSeric 				tp = trans(tp,Sid);
537349ae6eaSeric 				tp = trans(tp,Zkeywd);
538349ae6eaSeric 				break;
539349ae6eaSeric 			default:
540349ae6eaSeric 				*tp++ = '%';
541349ae6eaSeric 				*tp++ = *lp;
542349ae6eaSeric 				continue;
543349ae6eaSeric 			}
544349ae6eaSeric 			lp++;
545349ae6eaSeric 		}
546349ae6eaSeric 		else
547349ae6eaSeric 			*tp++ = *lp;
548349ae6eaSeric 	}
549349ae6eaSeric 
550349ae6eaSeric 	*tp = 0;
551349ae6eaSeric 	return(tline);
552349ae6eaSeric }
553349ae6eaSeric 
554349ae6eaSeric 
555349ae6eaSeric trans(tp,str)
556349ae6eaSeric register char *tp, *str;
557349ae6eaSeric {
558349ae6eaSeric 	Did_id = 1;
559349ae6eaSeric 	while(*tp++ = *str++)
560349ae6eaSeric 		;
561349ae6eaSeric 	return(tp-1);
562349ae6eaSeric }
563349ae6eaSeric 
564349ae6eaSeric 
565349ae6eaSeric prfx(pkt)
566349ae6eaSeric register struct packet *pkt;
567349ae6eaSeric {
568349ae6eaSeric 	char str[32];
569349ae6eaSeric 
570349ae6eaSeric 	if (HADN)
571349ae6eaSeric 		fprintf(pkt->p_gout,"%s\t",Mod);
572349ae6eaSeric 	if (HADM) {
573349ae6eaSeric 		sid_ba(&pkt->p_inssid,str);
574349ae6eaSeric 		fprintf(pkt->p_gout,"%s\t",str);
575349ae6eaSeric 	}
576349ae6eaSeric }
577349ae6eaSeric 
578349ae6eaSeric 
579349ae6eaSeric clean_up(n)
580349ae6eaSeric {
581349ae6eaSeric 	if (gpkt.p_file[0])
582349ae6eaSeric 		unlockit(auxf(gpkt.p_file,'z'),getpid());
583349ae6eaSeric 	if (gpkt.p_iop)
584349ae6eaSeric 		fclose(gpkt.p_iop);
585349ae6eaSeric 	xfreeall();
586349ae6eaSeric }
587349ae6eaSeric 
588349ae6eaSeric 
589349ae6eaSeric wrtpfile(pkt,inc,exc)
590349ae6eaSeric register struct packet *pkt;
591349ae6eaSeric char *inc, *exc;
592349ae6eaSeric {
593349ae6eaSeric 	char line[64], str1[32], str2[32];
594349ae6eaSeric 	char *user;
595349ae6eaSeric 	FILE *in, *out;
596349ae6eaSeric 	struct pfile pf;
597349ae6eaSeric 	register char *p;
598349ae6eaSeric 	int fd;
599349ae6eaSeric 	int i;
600349ae6eaSeric 	extern long Timenow;
601349ae6eaSeric 
602349ae6eaSeric 	user = logname();
603349ae6eaSeric 	if (lockit(auxf(pkt->p_file,'z'),2,getpid()))
604349ae6eaSeric 		fatal("cannot create lock file (cm4)");
605349ae6eaSeric 	if (exists(p = auxf(pkt->p_file,'p'))) {
606349ae6eaSeric 		fd = xopen(p,2);
607349ae6eaSeric 		in = fdfopen(fd,0);
608349ae6eaSeric 		while (fgets(line,sizeof(line),in) != NULL) {
609349ae6eaSeric 			p = line;
610349ae6eaSeric 			p[length(p) - 1] = 0;
611349ae6eaSeric 			pf_ab(p,&pf,0);
612349ae6eaSeric 			if ((pf.pf_gsid.s_rel == pkt->p_gotsid.s_rel &&
613349ae6eaSeric 				pf.pf_gsid.s_lev == pkt->p_gotsid.s_lev &&
614349ae6eaSeric 				pf.pf_gsid.s_br == pkt->p_gotsid.s_br &&
615349ae6eaSeric 				pf.pf_gsid.s_seq == pkt->p_gotsid.s_seq) ||
616349ae6eaSeric 				(pf.pf_nsid.s_rel == pkt->p_reqsid.s_rel &&
617349ae6eaSeric 				pf.pf_nsid.s_lev == pkt->p_reqsid.s_lev &&
618349ae6eaSeric 				pf.pf_nsid.s_br == pkt->p_reqsid.s_br &&
619349ae6eaSeric 				pf.pf_nsid.s_seq == pkt->p_reqsid.s_seq)) {
620349ae6eaSeric 				fclose(in);
621349ae6eaSeric 				fatal(sprintf(Error,"being edited: `%s' (ge17)",
622349ae6eaSeric 					line));
623349ae6eaSeric 				}
624349ae6eaSeric 			if (!equal(pf.pf_user,user))
625349ae6eaSeric 				fprintf(stderr,"WARNING: being edited: `%s' (ge18)\n",line);
626349ae6eaSeric 		}
627349ae6eaSeric 		out = fdfopen(dup(fd),1);
628349ae6eaSeric 		fclose(in);
629349ae6eaSeric 	}
630349ae6eaSeric 	else
631d15e2020Seric 		out = xfcreat(p,0666);
632349ae6eaSeric 	fseek(out,0L,2);
633349ae6eaSeric 	sid_ba(&pkt->p_gotsid,str1);
634349ae6eaSeric 	sid_ba(&pkt->p_reqsid,str2);
635349ae6eaSeric 	date_ba(&Timenow,line);
636349ae6eaSeric 	fprintf(out,"%s %s %s %s",str1,str2,user,line);
637349ae6eaSeric 	if (inc)
638349ae6eaSeric 		fprintf(out," -i%s",inc);
639349ae6eaSeric 	if (exc)
640349ae6eaSeric 		fprintf(out," -x%s",exc);
641349ae6eaSeric 	fprintf(out,"\n");
642349ae6eaSeric 	fclose(out);
643349ae6eaSeric 	if (pkt->p_verbose)
644349ae6eaSeric 		fprintf(pkt->p_stdout,"new delta %s\n",str2);
645349ae6eaSeric 	unlockit(auxf(pkt->p_file,'z'),getpid());
646349ae6eaSeric }
647349ae6eaSeric 
648349ae6eaSeric 
649349ae6eaSeric getser(pkt)
650349ae6eaSeric register struct packet *pkt;
651349ae6eaSeric {
652349ae6eaSeric 	register struct idel *rdp;
653349ae6eaSeric 	int n, ser, def;
654349ae6eaSeric 	char *p;
655349ae6eaSeric 	extern char *Sflags[];
656349ae6eaSeric 
657349ae6eaSeric 	def = 0;
658349ae6eaSeric 	if (pkt->p_reqsid.s_rel == 0) {
659349ae6eaSeric 		if (p = Sflags[DEFTFLAG - 'a'])
660349ae6eaSeric 			chksid(sid_ab(p, &pkt->p_reqsid), &pkt->p_reqsid);
661349ae6eaSeric 		else {
662349ae6eaSeric 			pkt->p_reqsid.s_rel = MAX;
663349ae6eaSeric 			def = 1;
664349ae6eaSeric 		}
665349ae6eaSeric 	}
666349ae6eaSeric 	ser = 0;
667349ae6eaSeric 	if (pkt->p_reqsid.s_lev == 0) {
668349ae6eaSeric 		for (n = maxser(pkt); n; n--) {
669349ae6eaSeric 			rdp = &pkt->p_idel[n];
670349ae6eaSeric 			if ((rdp->i_sid.s_br == 0 || HADT) &&
671349ae6eaSeric 				pkt->p_reqsid.s_rel >= rdp->i_sid.s_rel &&
672349ae6eaSeric 				rdp->i_sid.s_rel > pkt->p_gotsid.s_rel) {
673349ae6eaSeric 					ser = n;
674349ae6eaSeric 					pkt->p_gotsid.s_rel = rdp->i_sid.s_rel;
675349ae6eaSeric 			}
676349ae6eaSeric 		}
677349ae6eaSeric 	}
678349ae6eaSeric 	else if (pkt->p_reqsid.s_br && pkt->p_reqsid.s_seq == 0) {
679349ae6eaSeric 		for (n = maxser(pkt); n; n--) {
680349ae6eaSeric 			rdp = &pkt->p_idel[n];
681349ae6eaSeric 			if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel &&
682349ae6eaSeric 				rdp->i_sid.s_lev == pkt->p_reqsid.s_lev &&
683349ae6eaSeric 				rdp->i_sid.s_br == pkt->p_reqsid.s_br)
684349ae6eaSeric 					break;
685349ae6eaSeric 		}
686349ae6eaSeric 		ser = n;
687349ae6eaSeric 	}
688349ae6eaSeric 	else {
689349ae6eaSeric 		ser = sidtoser(&pkt->p_reqsid,pkt);
690349ae6eaSeric 	}
691349ae6eaSeric 	if (ser == 0)
692349ae6eaSeric 		fatal("nonexistent sid (ge5)");
693349ae6eaSeric 	rdp = &pkt->p_idel[ser];
694349ae6eaSeric 	move(&rdp->i_sid, &pkt->p_gotsid, sizeof(pkt->p_gotsid));
695349ae6eaSeric 	if (def || (pkt->p_reqsid.s_lev == 0 && pkt->p_reqsid.s_rel == pkt->p_gotsid.s_rel))
696349ae6eaSeric 		move(&pkt->p_gotsid, &pkt->p_reqsid, sizeof(pkt->p_gotsid));
697349ae6eaSeric 	return(ser);
698349ae6eaSeric }
699349ae6eaSeric 
700349ae6eaSeric 
701349ae6eaSeric /* Null routine to satisfy external reference from dodelt() */
702349ae6eaSeric 
703349ae6eaSeric escdodelt()
704349ae6eaSeric {
705349ae6eaSeric }
706