1abc16d2cSsam #include <sys/param.h> /* for MAXPATHLEN */
2abc16d2cSsam #undef MAX
3349ae6eaSeric # include "../hdr/defines.h"
4349ae6eaSeric # include "../hdr/had.h"
54ecffa3aSsam # include <sys/dir.h>
66d6ffe57Sbostic # include "pathnames.h"
7349ae6eaSeric
8*1383a7efSbostic static char Sccsid[] = "@(#)get.c 4.12 04/09/90";
9349ae6eaSeric
1012139005Slepreau int Debug = 0;
11349ae6eaSeric struct packet gpkt;
12349ae6eaSeric struct sid sid;
13349ae6eaSeric unsigned Ser;
14349ae6eaSeric int num_files;
15349ae6eaSeric char had[26];
16349ae6eaSeric char *ilist, *elist, *lfile;
1712139005Slepreau long cutoff = 0X7FFFFFFFL; /* max positive long */
18349ae6eaSeric int verbosity;
19b0bb49d8Ssam char Gfile[MAXNAMLEN + 3];
20f63c8b05Smckusick char Mod[MAXNAMLEN + 3]; /* should be as large as Gfile? */
21349ae6eaSeric char *Type;
22349ae6eaSeric int Did_id;
23349ae6eaSeric
main(argc,argv)24349ae6eaSeric main(argc,argv)
25349ae6eaSeric int argc;
26349ae6eaSeric register char *argv[];
27349ae6eaSeric {
28349ae6eaSeric register int i;
29349ae6eaSeric register char *p;
30349ae6eaSeric char c;
31349ae6eaSeric int testmore;
32349ae6eaSeric extern int Fcnt;
33349ae6eaSeric extern get();
34349ae6eaSeric
35349ae6eaSeric Fflags = FTLEXIT | FTLMSG | FTLCLN;
36349ae6eaSeric for(i=1; i<argc; i++)
37349ae6eaSeric if(argv[i][0] == '-' && (c=argv[i][1])) {
38349ae6eaSeric p = &argv[i][2];
39349ae6eaSeric testmore = 0;
40349ae6eaSeric switch (c) {
41349ae6eaSeric
42349ae6eaSeric case 'a':
43349ae6eaSeric if (!p[0]) {
44349ae6eaSeric argv[i] = 0;
45349ae6eaSeric continue;
46349ae6eaSeric }
47349ae6eaSeric Ser = patoi(p);
48349ae6eaSeric break;
49349ae6eaSeric case 'r':
50349ae6eaSeric if (!p[0]) {
51349ae6eaSeric argv[i] = 0;
52349ae6eaSeric continue;
53349ae6eaSeric }
54349ae6eaSeric chksid(sid_ab(p,&sid),&sid);
55349ae6eaSeric break;
56349ae6eaSeric case 'c':
57349ae6eaSeric if (!p[0]) {
58349ae6eaSeric argv[i] = 0;
59349ae6eaSeric continue;
60349ae6eaSeric }
61349ae6eaSeric if (date_ab(p,&cutoff))
62349ae6eaSeric fatal("bad date/time (cm5)");
63349ae6eaSeric break;
64349ae6eaSeric case 'l':
65349ae6eaSeric lfile = p;
66349ae6eaSeric break;
67349ae6eaSeric case 'i':
68349ae6eaSeric if (!p[0]) {
69349ae6eaSeric argv[i] = 0;
70349ae6eaSeric continue;
71349ae6eaSeric }
72349ae6eaSeric ilist = p;
73349ae6eaSeric break;
74349ae6eaSeric case 'x':
75349ae6eaSeric if (!p[0]) {
76349ae6eaSeric argv[i] = 0;
77349ae6eaSeric continue;
78349ae6eaSeric }
79349ae6eaSeric elist = p;
80349ae6eaSeric break;
81349ae6eaSeric case 'b':
82349ae6eaSeric case 'g':
83349ae6eaSeric case 'e':
84349ae6eaSeric case 'p':
85349ae6eaSeric case 'k':
86349ae6eaSeric case 'm':
87349ae6eaSeric case 'n':
88349ae6eaSeric case 's':
89349ae6eaSeric case 't':
90349ae6eaSeric testmore++;
91349ae6eaSeric break;
92349ae6eaSeric default:
93349ae6eaSeric fatal("unknown key letter (cm1)");
94349ae6eaSeric }
95349ae6eaSeric
96349ae6eaSeric if (testmore) {
97349ae6eaSeric testmore = 0;
98824dd99bSbostic if (*p) {
99824dd99bSbostic sprintf(Error,"value after %c arg (cm8)",c);
100824dd99bSbostic fatal(Error);
101824dd99bSbostic }
102349ae6eaSeric }
103349ae6eaSeric if (had[c - 'a']++)
104349ae6eaSeric fatal("key letter twice (cm2)");
105349ae6eaSeric argv[i] = 0;
106349ae6eaSeric }
107349ae6eaSeric else num_files++;
108349ae6eaSeric
109349ae6eaSeric if(num_files == 0)
110349ae6eaSeric fatal("missing file arg (cm3)");
111349ae6eaSeric if (HADE && HADM)
112349ae6eaSeric fatal("e not allowed with m (ge3)");
113349ae6eaSeric if (HADE || HADI || HADX)
114349ae6eaSeric HADK = 1;
115349ae6eaSeric if (!HADS)
116349ae6eaSeric verbosity = -1;
117349ae6eaSeric setsig();
11812139005Slepreau Fflags &= ~FTLEXIT;
11912139005Slepreau Fflags |= FTLJMP;
120349ae6eaSeric for (i=1; i<argc; i++)
121349ae6eaSeric if (p=argv[i])
122349ae6eaSeric do_file(p,get);
123349ae6eaSeric exit(Fcnt ? 1 : 0);
124349ae6eaSeric }
125349ae6eaSeric
126349ae6eaSeric
get(file)127349ae6eaSeric get(file)
128349ae6eaSeric {
129349ae6eaSeric register char *p;
130349ae6eaSeric register unsigned ser;
131349ae6eaSeric extern char had_dir, had_standinp;
132349ae6eaSeric extern char *Sflags[];
133349ae6eaSeric struct stats stats;
134349ae6eaSeric char str[32];
135349ae6eaSeric
136349ae6eaSeric if (setjmp(Fjmp))
137349ae6eaSeric return;
138349ae6eaSeric sinit(&gpkt,file,1);
139349ae6eaSeric gpkt.p_ixuser = (HADI | HADX);
140349ae6eaSeric gpkt.p_reqsid.s_rel = sid.s_rel;
141349ae6eaSeric gpkt.p_reqsid.s_lev = sid.s_lev;
142349ae6eaSeric gpkt.p_reqsid.s_br = sid.s_br;
143349ae6eaSeric gpkt.p_reqsid.s_seq = sid.s_seq;
144349ae6eaSeric gpkt.p_verbose = verbosity;
145349ae6eaSeric gpkt.p_stdout = (HADP ? stderr : stdout);
146349ae6eaSeric gpkt.p_cutoff = cutoff;
147349ae6eaSeric gpkt.p_lfile = lfile;
148349ae6eaSeric copy(auxf(gpkt.p_file,'g'),Gfile);
149349ae6eaSeric
150349ae6eaSeric if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
151349ae6eaSeric fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
152349ae6eaSeric if (dodelt(&gpkt,&stats,0,0) == 0)
153349ae6eaSeric fmterr(&gpkt);
154349ae6eaSeric finduser(&gpkt);
155349ae6eaSeric doflags(&gpkt);
156349ae6eaSeric if (!HADA)
157349ae6eaSeric ser = getser(&gpkt);
158349ae6eaSeric else {
159349ae6eaSeric if ((ser = Ser) > maxser(&gpkt))
160349ae6eaSeric fatal("serial number too large (ge19)");
161abc16d2cSsam bcopy(&gpkt.p_idel[ser].i_sid, &gpkt.p_gotsid, sizeof(sid));
162349ae6eaSeric if (HADR && sid.s_rel != gpkt.p_gotsid.s_rel) {
163abc16d2cSsam bzero(&gpkt.p_reqsid, sizeof(gpkt.p_reqsid));
164349ae6eaSeric gpkt.p_reqsid.s_rel = sid.s_rel;
165349ae6eaSeric }
166349ae6eaSeric else
167abc16d2cSsam bcopy(&gpkt.p_gotsid, &gpkt.p_reqsid, sizeof(sid));
168349ae6eaSeric }
169349ae6eaSeric doie(&gpkt,ilist,elist,0);
170349ae6eaSeric setup(&gpkt,ser);
171349ae6eaSeric if (!(Type = Sflags[TYPEFLAG - 'a']))
172349ae6eaSeric Type = Null;
173824dd99bSbostic if (!(HADP || HADG) && writable(Gfile)) {
174824dd99bSbostic sprintf(Error,"writable `%s' exists (ge4)",Gfile);
175824dd99bSbostic fatal(Error);
176824dd99bSbostic }
177349ae6eaSeric if (gpkt.p_verbose) {
178349ae6eaSeric sid_ba(&gpkt.p_gotsid,str);
179349ae6eaSeric fprintf(gpkt.p_stdout,"%s\n",str);
180349ae6eaSeric }
181349ae6eaSeric if (HADE) {
182349ae6eaSeric if (!HADR)
183abc16d2cSsam bcopy(&gpkt.p_gotsid,&gpkt.p_reqsid,
184349ae6eaSeric sizeof(gpkt.p_reqsid));
185349ae6eaSeric newsid(&gpkt,Sflags[BRCHFLAG - 'a'] && HADB);
186349ae6eaSeric permiss(&gpkt);
187349ae6eaSeric wrtpfile(&gpkt,ilist,elist);
188349ae6eaSeric }
189349ae6eaSeric setuid(getuid());
190349ae6eaSeric if (HADL)
191349ae6eaSeric gen_lfile(&gpkt);
192349ae6eaSeric if (HADG) {
193349ae6eaSeric fclose(gpkt.p_iop);
194349ae6eaSeric xfreeall();
195349ae6eaSeric return;
196349ae6eaSeric }
197349ae6eaSeric flushto(&gpkt,EUSERTXT,1);
198349ae6eaSeric idsetup(&gpkt);
199349ae6eaSeric gpkt.p_chkeof = 1;
200349ae6eaSeric Did_id = 0;
201349ae6eaSeric while(readmod(&gpkt)) {
202349ae6eaSeric if (gpkt.p_gout == 0) {
203349ae6eaSeric if (HADP)
204349ae6eaSeric gpkt.p_gout = stdout;
205349ae6eaSeric else
206d15e2020Seric gpkt.p_gout = xfcreat(Gfile,HADK ? 0666 : 0444);
207349ae6eaSeric }
208f63c8b05Smckusick if (HADN)
209f63c8b05Smckusick fprintf(gpkt.p_gout,"%s\t",Mod);
210f63c8b05Smckusick if (HADM) {
211f63c8b05Smckusick sid_ba(&gpkt.p_inssid,str);
212f63c8b05Smckusick fprintf(gpkt.p_gout,"%s\t",str);
213f63c8b05Smckusick }
214f63c8b05Smckusick p = gpkt.p_line;
215f63c8b05Smckusick if (!HADK && any('%',p))
216f63c8b05Smckusick p = idsubst(&gpkt,p);
217349ae6eaSeric fputs(p,gpkt.p_gout);
218349ae6eaSeric }
219349ae6eaSeric fflush(gpkt.p_gout);
220349ae6eaSeric if (gpkt.p_gout && gpkt.p_gout != stdout)
221349ae6eaSeric fclose(gpkt.p_gout);
222349ae6eaSeric if (gpkt.p_verbose)
223349ae6eaSeric fprintf(gpkt.p_stdout,"%u lines\n",gpkt.p_glnno);
224349ae6eaSeric if (!Did_id && !HADK)
225349ae6eaSeric if (Sflags[IDFLAG - 'a'])
226349ae6eaSeric fatal("no id keywords (cm6)");
227349ae6eaSeric else if (gpkt.p_verbose)
228349ae6eaSeric fprintf(stderr,"No id keywords (cm7)\n");
229349ae6eaSeric xfreeall();
230349ae6eaSeric }
231349ae6eaSeric
writable(fn)232024721e9Seric writable(fn)
233024721e9Seric char *fn;
234024721e9Seric {
235024721e9Seric struct stat s;
236024721e9Seric
237024721e9Seric return (stat(fn, &s) >= 0 && (s.st_mode & 0222) != 0);
238024721e9Seric }
239024721e9Seric
240349ae6eaSeric
newsid(pkt,branch)241349ae6eaSeric newsid(pkt,branch)
242349ae6eaSeric register struct packet *pkt;
243349ae6eaSeric int branch;
244349ae6eaSeric {
245349ae6eaSeric int chkbr;
246349ae6eaSeric
247349ae6eaSeric chkbr = 0;
248349ae6eaSeric if (pkt->p_reqsid.s_br == 0) {
24912139005Slepreau pkt->p_reqsid.s_lev += 1;
250349ae6eaSeric if (sidtoser(&pkt->p_reqsid,pkt) ||
251349ae6eaSeric pkt->p_maxr > pkt->p_reqsid.s_rel || branch) {
252349ae6eaSeric pkt->p_reqsid.s_rel = pkt->p_gotsid.s_rel;
253349ae6eaSeric pkt->p_reqsid.s_lev = pkt->p_gotsid.s_lev;
254349ae6eaSeric pkt->p_reqsid.s_br = pkt->p_gotsid.s_br + 1;
255349ae6eaSeric pkt->p_reqsid.s_seq = 1;
256349ae6eaSeric chkbr++;
257349ae6eaSeric }
258349ae6eaSeric }
259349ae6eaSeric else if (pkt->p_reqsid.s_seq == 0 && !branch)
260349ae6eaSeric pkt->p_reqsid.s_seq = pkt->p_gotsid.s_seq + 1;
261349ae6eaSeric else {
26212139005Slepreau pkt->p_reqsid.s_seq += 1;
263349ae6eaSeric if (branch || sidtoser(&pkt->p_reqsid,pkt)) {
26412139005Slepreau pkt->p_reqsid.s_br += 1;
265349ae6eaSeric pkt->p_reqsid.s_seq = 1;
266349ae6eaSeric chkbr++;
267349ae6eaSeric }
268349ae6eaSeric }
269349ae6eaSeric if (chkbr)
270349ae6eaSeric while (sidtoser(&pkt->p_reqsid,pkt))
27112139005Slepreau pkt->p_reqsid.s_br += 1;
272349ae6eaSeric if (sidtoser(&pkt->p_reqsid,pkt))
273349ae6eaSeric fatal("internal error in newsid()");
274349ae6eaSeric }
275349ae6eaSeric
276349ae6eaSeric
277349ae6eaSeric enter(pkt,ch,n,sidp)
278349ae6eaSeric struct packet *pkt;
279349ae6eaSeric char ch;
280349ae6eaSeric int n;
281349ae6eaSeric struct sid *sidp;
282349ae6eaSeric {
283349ae6eaSeric char str[32];
284349ae6eaSeric register struct apply *ap;
285349ae6eaSeric
286349ae6eaSeric sid_ba(sidp,str);
287349ae6eaSeric if (pkt->p_verbose)
288349ae6eaSeric fprintf(pkt->p_stdout,"%s\n",str);
289349ae6eaSeric ap = &pkt->p_apply[n];
290349ae6eaSeric switch(ap->a_code) {
291349ae6eaSeric
292349ae6eaSeric case EMPTY:
293349ae6eaSeric if (ch == INCLUDE)
294349ae6eaSeric condset(ap,APPLY,INCLUSER);
295349ae6eaSeric else
296349ae6eaSeric condset(ap,NOAPPLY,EXCLUSER);
297349ae6eaSeric break;
298349ae6eaSeric case APPLY:
299349ae6eaSeric sid_ba(sidp,str);
300824dd99bSbostic sprintf(Error,"%s already included (ge9)",str);
301824dd99bSbostic fatal(Error);
302349ae6eaSeric break;
303349ae6eaSeric case NOAPPLY:
304349ae6eaSeric sid_ba(sidp,str);
305824dd99bSbostic sprintf(Error,"%s already excluded (ge10)",str);
306824dd99bSbostic fatal(Error);
307349ae6eaSeric break;
308349ae6eaSeric default:
309349ae6eaSeric fatal("internal error in get/enter() (ge11)");
310349ae6eaSeric break;
311349ae6eaSeric }
312349ae6eaSeric }
313349ae6eaSeric
314349ae6eaSeric
gen_lfile(pkt)315349ae6eaSeric gen_lfile(pkt)
316349ae6eaSeric register struct packet *pkt;
317349ae6eaSeric {
318349ae6eaSeric int n;
319349ae6eaSeric int reason;
320349ae6eaSeric char str[32];
321349ae6eaSeric char line[BUFSIZ];
322349ae6eaSeric struct deltab dt;
323349ae6eaSeric FILE *in;
324349ae6eaSeric FILE *out;
325349ae6eaSeric
326349ae6eaSeric in = xfopen(pkt->p_file,0);
327349ae6eaSeric if (*pkt->p_lfile)
328349ae6eaSeric out = stdout;
329349ae6eaSeric else
330349ae6eaSeric out = xfcreat(auxf(pkt->p_file,'l'),0444);
331349ae6eaSeric fgets(line,sizeof(line),in);
332349ae6eaSeric while (fgets(line,sizeof(line),in) != NULL && line[0] == CTLCHAR && line[1] == STATS) {
333349ae6eaSeric fgets(line,sizeof(line),in);
334349ae6eaSeric del_ab(line,&dt);
335349ae6eaSeric if (dt.d_type == 'D') {
336349ae6eaSeric reason = pkt->p_apply[dt.d_serial].a_reason;
337349ae6eaSeric if (pkt->p_apply[dt.d_serial].a_code == APPLY) {
338349ae6eaSeric putc(' ',out);
339349ae6eaSeric putc(' ',out);
340349ae6eaSeric }
341349ae6eaSeric else {
342349ae6eaSeric putc('*',out);
343349ae6eaSeric if (reason & IGNR)
344349ae6eaSeric putc(' ',out);
345349ae6eaSeric else
346349ae6eaSeric putc('*',out);
347349ae6eaSeric }
348349ae6eaSeric switch (reason & (INCL | EXCL | CUTOFF)) {
349349ae6eaSeric
350349ae6eaSeric case INCL:
351349ae6eaSeric putc('I',out);
352349ae6eaSeric break;
353349ae6eaSeric case EXCL:
354349ae6eaSeric putc('X',out);
355349ae6eaSeric break;
356349ae6eaSeric case CUTOFF:
357349ae6eaSeric putc('C',out);
358349ae6eaSeric break;
359349ae6eaSeric default:
360349ae6eaSeric putc(' ',out);
361349ae6eaSeric break;
362349ae6eaSeric }
363349ae6eaSeric putc(' ',out);
364349ae6eaSeric sid_ba(&dt.d_sid,str);
365349ae6eaSeric fprintf(out,"%s\t",str);
366349ae6eaSeric date_ba(&dt.d_datetime,str);
367349ae6eaSeric fprintf(out,"%s %s\n",str,dt.d_pgmr);
368349ae6eaSeric }
369349ae6eaSeric while ((n = fgets(line,sizeof(line),in)) != NULL)
370349ae6eaSeric if (line[0] != CTLCHAR)
371349ae6eaSeric break;
372349ae6eaSeric else {
373349ae6eaSeric switch (line[1]) {
374349ae6eaSeric
375349ae6eaSeric case EDELTAB:
376349ae6eaSeric break;
377349ae6eaSeric default:
378349ae6eaSeric continue;
379349ae6eaSeric case MRNUM:
380349ae6eaSeric case COMMENTS:
381349ae6eaSeric if (dt.d_type == 'D')
382349ae6eaSeric fprintf(out,"\t%s",&line[3]);
383349ae6eaSeric continue;
384349ae6eaSeric }
385349ae6eaSeric break;
386349ae6eaSeric }
387349ae6eaSeric if (n == NULL || line[0] != CTLCHAR)
388349ae6eaSeric break;
389349ae6eaSeric putc('\n',out);
390349ae6eaSeric }
391349ae6eaSeric fclose(in);
392349ae6eaSeric if (out != stdout)
393349ae6eaSeric fclose(out);
394349ae6eaSeric }
395349ae6eaSeric
396349ae6eaSeric char Curdate[18];
397349ae6eaSeric char *Curtime;
398349ae6eaSeric char Gdate[9];
399349ae6eaSeric char Chgdate[18];
400349ae6eaSeric char *Chgtime;
401349ae6eaSeric char Gchgdate[9];
402abc16d2cSsam char Qchgdate[30];
403349ae6eaSeric char Sid[32];
404abc16d2cSsam char Olddir[MAXPATHLEN+1];
405abc16d2cSsam char Pname[MAXPATHLEN+1];
406abc16d2cSsam char Dir[MAXPATHLEN+1];
407349ae6eaSeric
idsetup(pkt)408349ae6eaSeric idsetup(pkt)
409349ae6eaSeric register struct packet *pkt;
410349ae6eaSeric {
411349ae6eaSeric extern long Timenow;
412349ae6eaSeric register int n;
413349ae6eaSeric register char *p;
414349ae6eaSeric
415349ae6eaSeric date_ba(&Timenow,Curdate);
416349ae6eaSeric Curtime = &Curdate[9];
417349ae6eaSeric Curdate[8] = 0;
418349ae6eaSeric copy(pkt->p_file,Dir);
419349ae6eaSeric dname(Dir);
420abc16d2cSsam if(getwd(Olddir) == 0)
421abc16d2cSsam fatal("getwd failed (ge20)");
422349ae6eaSeric if(chdir(Dir) != 0)
423349ae6eaSeric fatal("cannot change directory (ge22)");
424abc16d2cSsam if(getwd(Pname) == 0)
425abc16d2cSsam fatal("getwd failed (ge21)");
426349ae6eaSeric if(chdir(Olddir) != 0)
427349ae6eaSeric fatal("cannot change directory (ge23)");
428349ae6eaSeric makgdate(Curdate,Gdate);
429349ae6eaSeric for (n = maxser(pkt); n; n--)
430349ae6eaSeric if (pkt->p_apply[n].a_code == APPLY)
431349ae6eaSeric break;
432349ae6eaSeric if (n)
433349ae6eaSeric date_ba(&pkt->p_idel[n].i_datetime,Chgdate);
434349ae6eaSeric Chgtime = &Chgdate[9];
435349ae6eaSeric Chgdate[8] = 0;
436349ae6eaSeric makgdate(Chgdate,Gchgdate);
437abc16d2cSsam makqdate(Gchgdate,Qchgdate);
438349ae6eaSeric sid_ba(&pkt->p_gotsid,Sid);
439349ae6eaSeric if (p = Sflags[MODFLAG - 'a'])
440349ae6eaSeric copy(p,Mod);
441349ae6eaSeric else
442349ae6eaSeric copy(Gfile,Mod);
443349ae6eaSeric }
444349ae6eaSeric
445349ae6eaSeric
makgdate(old,new)446349ae6eaSeric makgdate(old,new)
447349ae6eaSeric register char *old, *new;
448349ae6eaSeric {
449349ae6eaSeric if ((*new = old[3]) != '0')
450349ae6eaSeric new++;
451349ae6eaSeric *new++ = old[4];
452349ae6eaSeric *new++ = '/';
453349ae6eaSeric if ((*new = old[6]) != '0')
454349ae6eaSeric new++;
455349ae6eaSeric *new++ = old[7];
456349ae6eaSeric *new++ = '/';
457349ae6eaSeric *new++ = old[0];
458349ae6eaSeric *new++ = old[1];
459349ae6eaSeric *new = 0;
460349ae6eaSeric }
461349ae6eaSeric
makqdate(old,new)462abc16d2cSsam makqdate(old,new)
463abc16d2cSsam register char *old, *new;
464abc16d2cSsam {
465abc16d2cSsam static char *months[12] =
466abc16d2cSsam { "January", "February", "March", "April", "May", "June", "July",
467abc16d2cSsam "August", "September", "October", "November", "December" };
468abc16d2cSsam
469abc16d2cSsam strcpy(new, months[atoi(old)-1]);
470abc16d2cSsam while (*new != '\0')
471abc16d2cSsam new++;
472abc16d2cSsam while (*old++ != '/')
473abc16d2cSsam ;
474abc16d2cSsam *new++ = ' ';
475abc16d2cSsam *new++ = *old++;
476abc16d2cSsam if (*old != '/')
477abc16d2cSsam *new++ = *old++;
478abc16d2cSsam *new++ = ',';
479abc16d2cSsam *new++ = ' ';
480abc16d2cSsam *new++ = '1'; *new++ = '9'; /* works for this century at least */
481abc16d2cSsam *new++ = *++old;
482abc16d2cSsam *new++ = *++old;
483abc16d2cSsam *new = '\0';
484abc16d2cSsam }
485349ae6eaSeric
48612139005Slepreau static char Zkeywd[5] = "@(#)";
487349ae6eaSeric
488abc16d2cSsam
idsubst(pkt,line)489349ae6eaSeric idsubst(pkt,line)
490349ae6eaSeric register struct packet *pkt;
491349ae6eaSeric char line[];
492349ae6eaSeric {
493349ae6eaSeric static char tline[BUFSIZ];
494349ae6eaSeric static char str[32];
4956d6ffe57Sbostic register char *lp, *tp, *p;
496349ae6eaSeric extern char *Type;
497349ae6eaSeric extern char *Sflags[];
498349ae6eaSeric
499349ae6eaSeric tp = tline;
500349ae6eaSeric for(lp=line; *lp != 0; lp++) {
5016d6ffe57Sbostic if (lp[0] != '%' || !lp[1] || !lp[2]) {
5026d6ffe57Sbostic *tp++ = *lp;
5036d6ffe57Sbostic continue;
5046d6ffe57Sbostic }
5056d6ffe57Sbostic if (lp[2] == '%') {
506349ae6eaSeric switch(*++lp) {
507349ae6eaSeric case 'M':
508349ae6eaSeric tp = trans(tp,Mod);
509349ae6eaSeric break;
510349ae6eaSeric case 'R':
511349ae6eaSeric sprintf(str,"%u",pkt->p_gotsid.s_rel);
512349ae6eaSeric tp = trans(tp,str);
513349ae6eaSeric break;
514349ae6eaSeric case 'L':
515349ae6eaSeric sprintf(str,"%u",pkt->p_gotsid.s_lev);
516349ae6eaSeric tp = trans(tp,str);
517349ae6eaSeric break;
518349ae6eaSeric case 'B':
519349ae6eaSeric sprintf(str,"%u",pkt->p_gotsid.s_br);
520349ae6eaSeric tp = trans(tp,str);
521349ae6eaSeric break;
522349ae6eaSeric case 'S':
523349ae6eaSeric sprintf(str,"%u",pkt->p_gotsid.s_seq);
524349ae6eaSeric tp = trans(tp,str);
525349ae6eaSeric break;
526349ae6eaSeric case 'D':
527349ae6eaSeric tp = trans(tp,Curdate);
528349ae6eaSeric break;
529349ae6eaSeric case 'H':
530349ae6eaSeric tp = trans(tp,Gdate);
531349ae6eaSeric break;
532349ae6eaSeric case 'T':
533349ae6eaSeric tp = trans(tp,Curtime);
534349ae6eaSeric break;
535349ae6eaSeric case 'E':
536349ae6eaSeric tp = trans(tp,Chgdate);
537349ae6eaSeric break;
538349ae6eaSeric case 'G':
539349ae6eaSeric tp = trans(tp,Gchgdate);
540349ae6eaSeric break;
541abc16d2cSsam case 'Q':
542abc16d2cSsam tp = trans(tp,Qchgdate);
543abc16d2cSsam break;
544349ae6eaSeric case 'U':
545349ae6eaSeric tp = trans(tp,Chgtime);
546349ae6eaSeric break;
547349ae6eaSeric case 'Z':
548349ae6eaSeric tp = trans(tp,Zkeywd);
549349ae6eaSeric break;
550349ae6eaSeric case 'Y':
551349ae6eaSeric tp = trans(tp,Type);
552349ae6eaSeric break;
553349ae6eaSeric case 'W':
554349ae6eaSeric tp = trans(tp,Zkeywd);
555349ae6eaSeric tp = trans(tp,Mod);
556349ae6eaSeric *tp++ = '\t';
557349ae6eaSeric case 'I':
558349ae6eaSeric tp = trans(tp,Sid);
559349ae6eaSeric break;
560349ae6eaSeric case 'P':
561349ae6eaSeric tp = trans(tp,Pname);
562349ae6eaSeric *tp++ = '/';
563349ae6eaSeric tp = trans(tp,(sname(pkt->p_file)));
564349ae6eaSeric break;
565349ae6eaSeric case 'F':
566349ae6eaSeric tp = trans(tp,pkt->p_file);
567349ae6eaSeric break;
568349ae6eaSeric case 'C':
569349ae6eaSeric sprintf(str,"%u",pkt->p_glnno);
570349ae6eaSeric tp = trans(tp,str);
571349ae6eaSeric break;
572349ae6eaSeric case 'A':
573349ae6eaSeric tp = trans(tp,Zkeywd);
574349ae6eaSeric tp = trans(tp,Type);
575349ae6eaSeric *tp++ = ' ';
576349ae6eaSeric tp = trans(tp,Mod);
577349ae6eaSeric *tp++ = ' ';
578349ae6eaSeric tp = trans(tp,Sid);
579349ae6eaSeric tp = trans(tp,Zkeywd);
580349ae6eaSeric break;
581349ae6eaSeric default:
582349ae6eaSeric *tp++ = '%';
583349ae6eaSeric *tp++ = *lp;
584349ae6eaSeric continue;
585349ae6eaSeric }
586349ae6eaSeric lp++;
5876d6ffe57Sbostic continue;
588349ae6eaSeric }
5896d6ffe57Sbostic if (!strncmp(lp, "%sccs.include.", 14)) {
5906d6ffe57Sbostic for (p = lp + 14; *p && *p != '%'; ++p);
591*1383a7efSbostic if (*p == '%') {
5926d6ffe57Sbostic *p = '\0';
593*1383a7efSbostic readcopy(lp + 14, tline);
594*1383a7efSbostic return(tline);
5956d6ffe57Sbostic }
596*1383a7efSbostic }
5977cdb0a06Sbostic *tp++ = '%';
598349ae6eaSeric }
599349ae6eaSeric
600349ae6eaSeric *tp = 0;
601349ae6eaSeric return(tline);
602349ae6eaSeric }
603349ae6eaSeric
604349ae6eaSeric
trans(tp,str)605349ae6eaSeric trans(tp,str)
606349ae6eaSeric register char *tp, *str;
607349ae6eaSeric {
608349ae6eaSeric Did_id = 1;
609349ae6eaSeric while(*tp++ = *str++)
610349ae6eaSeric ;
611349ae6eaSeric return(tp-1);
612349ae6eaSeric }
613349ae6eaSeric
readcopy(name,p)614*1383a7efSbostic readcopy(name, p)
6156d6ffe57Sbostic register char *name;
616*1383a7efSbostic register char *p;
6176d6ffe57Sbostic {
6186d6ffe57Sbostic register FILE *fp;
6196d6ffe57Sbostic register int ch;
6206d6ffe57Sbostic char path[MAXPATHLEN];
6216d6ffe57Sbostic
6226d6ffe57Sbostic (void)sprintf(path, "%s/%s", _PATH_SCCSINCLUDE, name);
6236d6ffe57Sbostic if (!(fp = fopen(path, "r"))) {
6246d6ffe57Sbostic (void)sprintf(Error,"can't read %s", path);
6256d6ffe57Sbostic fatal(Error);
6266d6ffe57Sbostic }
6276d6ffe57Sbostic while ((ch = getc(fp)) != EOF)
628*1383a7efSbostic *p++ = ch;
6296d6ffe57Sbostic (void)fclose(fp);
6306d6ffe57Sbostic }
631349ae6eaSeric
clean_up(n)632349ae6eaSeric clean_up(n)
633349ae6eaSeric {
634349ae6eaSeric if (gpkt.p_file[0])
635349ae6eaSeric unlockit(auxf(gpkt.p_file,'z'),getpid());
636349ae6eaSeric if (gpkt.p_iop)
637349ae6eaSeric fclose(gpkt.p_iop);
638349ae6eaSeric xfreeall();
639349ae6eaSeric }
640349ae6eaSeric
641349ae6eaSeric
wrtpfile(pkt,inc,exc)642349ae6eaSeric wrtpfile(pkt,inc,exc)
643349ae6eaSeric register struct packet *pkt;
644349ae6eaSeric char *inc, *exc;
645349ae6eaSeric {
646349ae6eaSeric char line[64], str1[32], str2[32];
647349ae6eaSeric char *user;
648349ae6eaSeric FILE *in, *out;
649349ae6eaSeric struct pfile pf;
650349ae6eaSeric register char *p;
651349ae6eaSeric int fd;
652349ae6eaSeric int i;
653349ae6eaSeric extern long Timenow;
654349ae6eaSeric
655349ae6eaSeric user = logname();
656349ae6eaSeric if (lockit(auxf(pkt->p_file,'z'),2,getpid()))
657349ae6eaSeric fatal("cannot create lock file (cm4)");
658349ae6eaSeric if (exists(p = auxf(pkt->p_file,'p'))) {
659349ae6eaSeric fd = xopen(p,2);
660abc16d2cSsam in = fdopen(fd,"r");
661349ae6eaSeric while (fgets(line,sizeof(line),in) != NULL) {
662349ae6eaSeric p = line;
663349ae6eaSeric p[length(p) - 1] = 0;
664349ae6eaSeric pf_ab(p,&pf,0);
665349ae6eaSeric if ((pf.pf_gsid.s_rel == pkt->p_gotsid.s_rel &&
666349ae6eaSeric pf.pf_gsid.s_lev == pkt->p_gotsid.s_lev &&
667349ae6eaSeric pf.pf_gsid.s_br == pkt->p_gotsid.s_br &&
668349ae6eaSeric pf.pf_gsid.s_seq == pkt->p_gotsid.s_seq) ||
669349ae6eaSeric (pf.pf_nsid.s_rel == pkt->p_reqsid.s_rel &&
670349ae6eaSeric pf.pf_nsid.s_lev == pkt->p_reqsid.s_lev &&
671349ae6eaSeric pf.pf_nsid.s_br == pkt->p_reqsid.s_br &&
672349ae6eaSeric pf.pf_nsid.s_seq == pkt->p_reqsid.s_seq)) {
673349ae6eaSeric fclose(in);
674824dd99bSbostic sprintf(Error,"being edited: `%s' (ge17)",line);
675824dd99bSbostic fatal(Error);
676349ae6eaSeric }
677349ae6eaSeric if (!equal(pf.pf_user,user))
678349ae6eaSeric fprintf(stderr,"WARNING: being edited: `%s' (ge18)\n",line);
679349ae6eaSeric }
680abc16d2cSsam out = fdopen(dup(fd),"w");
681349ae6eaSeric fclose(in);
682349ae6eaSeric }
683349ae6eaSeric else
684d15e2020Seric out = xfcreat(p,0666);
685349ae6eaSeric fseek(out,0L,2);
686349ae6eaSeric sid_ba(&pkt->p_gotsid,str1);
687349ae6eaSeric sid_ba(&pkt->p_reqsid,str2);
688349ae6eaSeric date_ba(&Timenow,line);
689349ae6eaSeric fprintf(out,"%s %s %s %s",str1,str2,user,line);
690349ae6eaSeric if (inc)
691349ae6eaSeric fprintf(out," -i%s",inc);
692349ae6eaSeric if (exc)
693349ae6eaSeric fprintf(out," -x%s",exc);
694349ae6eaSeric fprintf(out,"\n");
695349ae6eaSeric fclose(out);
696349ae6eaSeric if (pkt->p_verbose)
697349ae6eaSeric fprintf(pkt->p_stdout,"new delta %s\n",str2);
698349ae6eaSeric unlockit(auxf(pkt->p_file,'z'),getpid());
699349ae6eaSeric }
700349ae6eaSeric
701349ae6eaSeric
getser(pkt)702349ae6eaSeric getser(pkt)
703349ae6eaSeric register struct packet *pkt;
704349ae6eaSeric {
705349ae6eaSeric register struct idel *rdp;
706349ae6eaSeric int n, ser, def;
707349ae6eaSeric char *p;
708349ae6eaSeric extern char *Sflags[];
709349ae6eaSeric
710349ae6eaSeric def = 0;
711349ae6eaSeric if (pkt->p_reqsid.s_rel == 0) {
712349ae6eaSeric if (p = Sflags[DEFTFLAG - 'a'])
713349ae6eaSeric chksid(sid_ab(p, &pkt->p_reqsid), &pkt->p_reqsid);
714349ae6eaSeric else {
715349ae6eaSeric pkt->p_reqsid.s_rel = MAX;
716349ae6eaSeric def = 1;
717349ae6eaSeric }
718349ae6eaSeric }
719349ae6eaSeric ser = 0;
720349ae6eaSeric if (pkt->p_reqsid.s_lev == 0) {
721349ae6eaSeric for (n = maxser(pkt); n; n--) {
722349ae6eaSeric rdp = &pkt->p_idel[n];
723349ae6eaSeric if ((rdp->i_sid.s_br == 0 || HADT) &&
724349ae6eaSeric pkt->p_reqsid.s_rel >= rdp->i_sid.s_rel &&
725349ae6eaSeric rdp->i_sid.s_rel > pkt->p_gotsid.s_rel) {
726349ae6eaSeric ser = n;
727349ae6eaSeric pkt->p_gotsid.s_rel = rdp->i_sid.s_rel;
728349ae6eaSeric }
729349ae6eaSeric }
730349ae6eaSeric }
731349ae6eaSeric else if (pkt->p_reqsid.s_br && pkt->p_reqsid.s_seq == 0) {
732349ae6eaSeric for (n = maxser(pkt); n; n--) {
733349ae6eaSeric rdp = &pkt->p_idel[n];
734349ae6eaSeric if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel &&
735349ae6eaSeric rdp->i_sid.s_lev == pkt->p_reqsid.s_lev &&
736349ae6eaSeric rdp->i_sid.s_br == pkt->p_reqsid.s_br)
737349ae6eaSeric break;
738349ae6eaSeric }
739349ae6eaSeric ser = n;
740349ae6eaSeric }
741349ae6eaSeric else {
742349ae6eaSeric ser = sidtoser(&pkt->p_reqsid,pkt);
743349ae6eaSeric }
744349ae6eaSeric if (ser == 0)
745349ae6eaSeric fatal("nonexistent sid (ge5)");
746349ae6eaSeric rdp = &pkt->p_idel[ser];
747abc16d2cSsam bcopy(&rdp->i_sid, &pkt->p_gotsid, sizeof(pkt->p_gotsid));
748349ae6eaSeric if (def || (pkt->p_reqsid.s_lev == 0 && pkt->p_reqsid.s_rel == pkt->p_gotsid.s_rel))
749abc16d2cSsam bcopy(&pkt->p_gotsid, &pkt->p_reqsid, sizeof(pkt->p_gotsid));
750349ae6eaSeric return(ser);
751349ae6eaSeric }
752349ae6eaSeric
753349ae6eaSeric
754349ae6eaSeric /* Null routine to satisfy external reference from dodelt() */
755349ae6eaSeric
escdodelt()756349ae6eaSeric escdodelt()
757349ae6eaSeric {
758349ae6eaSeric }
759