1 #include <sys/param.h> /* for MAXPATHLEN */
2 #undef MAX
3 # include "../hdr/defines.h"
4 # include "../hdr/had.h"
5 # include <sys/dir.h>
6 # include "pathnames.h"
7
8 static char Sccsid[] = "@(#)get.c 4.12 04/09/90";
9
10 int Debug = 0;
11 struct packet gpkt;
12 struct sid sid;
13 unsigned Ser;
14 int num_files;
15 char had[26];
16 char *ilist, *elist, *lfile;
17 long cutoff = 0X7FFFFFFFL; /* max positive long */
18 int verbosity;
19 char Gfile[MAXNAMLEN + 3];
20 char Mod[MAXNAMLEN + 3]; /* should be as large as Gfile? */
21 char *Type;
22 int Did_id;
23
main(argc,argv)24 main(argc,argv)
25 int argc;
26 register char *argv[];
27 {
28 register int i;
29 register char *p;
30 char c;
31 int testmore;
32 extern int Fcnt;
33 extern get();
34
35 Fflags = FTLEXIT | FTLMSG | FTLCLN;
36 for(i=1; i<argc; i++)
37 if(argv[i][0] == '-' && (c=argv[i][1])) {
38 p = &argv[i][2];
39 testmore = 0;
40 switch (c) {
41
42 case 'a':
43 if (!p[0]) {
44 argv[i] = 0;
45 continue;
46 }
47 Ser = patoi(p);
48 break;
49 case 'r':
50 if (!p[0]) {
51 argv[i] = 0;
52 continue;
53 }
54 chksid(sid_ab(p,&sid),&sid);
55 break;
56 case 'c':
57 if (!p[0]) {
58 argv[i] = 0;
59 continue;
60 }
61 if (date_ab(p,&cutoff))
62 fatal("bad date/time (cm5)");
63 break;
64 case 'l':
65 lfile = p;
66 break;
67 case 'i':
68 if (!p[0]) {
69 argv[i] = 0;
70 continue;
71 }
72 ilist = p;
73 break;
74 case 'x':
75 if (!p[0]) {
76 argv[i] = 0;
77 continue;
78 }
79 elist = p;
80 break;
81 case 'b':
82 case 'g':
83 case 'e':
84 case 'p':
85 case 'k':
86 case 'm':
87 case 'n':
88 case 's':
89 case 't':
90 testmore++;
91 break;
92 default:
93 fatal("unknown key letter (cm1)");
94 }
95
96 if (testmore) {
97 testmore = 0;
98 if (*p) {
99 sprintf(Error,"value after %c arg (cm8)",c);
100 fatal(Error);
101 }
102 }
103 if (had[c - 'a']++)
104 fatal("key letter twice (cm2)");
105 argv[i] = 0;
106 }
107 else num_files++;
108
109 if(num_files == 0)
110 fatal("missing file arg (cm3)");
111 if (HADE && HADM)
112 fatal("e not allowed with m (ge3)");
113 if (HADE || HADI || HADX)
114 HADK = 1;
115 if (!HADS)
116 verbosity = -1;
117 setsig();
118 Fflags &= ~FTLEXIT;
119 Fflags |= FTLJMP;
120 for (i=1; i<argc; i++)
121 if (p=argv[i])
122 do_file(p,get);
123 exit(Fcnt ? 1 : 0);
124 }
125
126
get(file)127 get(file)
128 {
129 register char *p;
130 register unsigned ser;
131 extern char had_dir, had_standinp;
132 extern char *Sflags[];
133 struct stats stats;
134 char str[32];
135
136 if (setjmp(Fjmp))
137 return;
138 sinit(&gpkt,file,1);
139 gpkt.p_ixuser = (HADI | HADX);
140 gpkt.p_reqsid.s_rel = sid.s_rel;
141 gpkt.p_reqsid.s_lev = sid.s_lev;
142 gpkt.p_reqsid.s_br = sid.s_br;
143 gpkt.p_reqsid.s_seq = sid.s_seq;
144 gpkt.p_verbose = verbosity;
145 gpkt.p_stdout = (HADP ? stderr : stdout);
146 gpkt.p_cutoff = cutoff;
147 gpkt.p_lfile = lfile;
148 copy(auxf(gpkt.p_file,'g'),Gfile);
149
150 if (gpkt.p_verbose && (num_files > 1 || had_dir || had_standinp))
151 fprintf(gpkt.p_stdout,"\n%s:\n",gpkt.p_file);
152 if (dodelt(&gpkt,&stats,0,0) == 0)
153 fmterr(&gpkt);
154 finduser(&gpkt);
155 doflags(&gpkt);
156 if (!HADA)
157 ser = getser(&gpkt);
158 else {
159 if ((ser = Ser) > maxser(&gpkt))
160 fatal("serial number too large (ge19)");
161 bcopy(&gpkt.p_idel[ser].i_sid, &gpkt.p_gotsid, sizeof(sid));
162 if (HADR && sid.s_rel != gpkt.p_gotsid.s_rel) {
163 bzero(&gpkt.p_reqsid, sizeof(gpkt.p_reqsid));
164 gpkt.p_reqsid.s_rel = sid.s_rel;
165 }
166 else
167 bcopy(&gpkt.p_gotsid, &gpkt.p_reqsid, sizeof(sid));
168 }
169 doie(&gpkt,ilist,elist,0);
170 setup(&gpkt,ser);
171 if (!(Type = Sflags[TYPEFLAG - 'a']))
172 Type = Null;
173 if (!(HADP || HADG) && writable(Gfile)) {
174 sprintf(Error,"writable `%s' exists (ge4)",Gfile);
175 fatal(Error);
176 }
177 if (gpkt.p_verbose) {
178 sid_ba(&gpkt.p_gotsid,str);
179 fprintf(gpkt.p_stdout,"%s\n",str);
180 }
181 if (HADE) {
182 if (!HADR)
183 bcopy(&gpkt.p_gotsid,&gpkt.p_reqsid,
184 sizeof(gpkt.p_reqsid));
185 newsid(&gpkt,Sflags[BRCHFLAG - 'a'] && HADB);
186 permiss(&gpkt);
187 wrtpfile(&gpkt,ilist,elist);
188 }
189 setuid(getuid());
190 if (HADL)
191 gen_lfile(&gpkt);
192 if (HADG) {
193 fclose(gpkt.p_iop);
194 xfreeall();
195 return;
196 }
197 flushto(&gpkt,EUSERTXT,1);
198 idsetup(&gpkt);
199 gpkt.p_chkeof = 1;
200 Did_id = 0;
201 while(readmod(&gpkt)) {
202 if (gpkt.p_gout == 0) {
203 if (HADP)
204 gpkt.p_gout = stdout;
205 else
206 gpkt.p_gout = xfcreat(Gfile,HADK ? 0666 : 0444);
207 }
208 if (HADN)
209 fprintf(gpkt.p_gout,"%s\t",Mod);
210 if (HADM) {
211 sid_ba(&gpkt.p_inssid,str);
212 fprintf(gpkt.p_gout,"%s\t",str);
213 }
214 p = gpkt.p_line;
215 if (!HADK && any('%',p))
216 p = idsubst(&gpkt,p);
217 fputs(p,gpkt.p_gout);
218 }
219 fflush(gpkt.p_gout);
220 if (gpkt.p_gout && gpkt.p_gout != stdout)
221 fclose(gpkt.p_gout);
222 if (gpkt.p_verbose)
223 fprintf(gpkt.p_stdout,"%u lines\n",gpkt.p_glnno);
224 if (!Did_id && !HADK)
225 if (Sflags[IDFLAG - 'a'])
226 fatal("no id keywords (cm6)");
227 else if (gpkt.p_verbose)
228 fprintf(stderr,"No id keywords (cm7)\n");
229 xfreeall();
230 }
231
writable(fn)232 writable(fn)
233 char *fn;
234 {
235 struct stat s;
236
237 return (stat(fn, &s) >= 0 && (s.st_mode & 0222) != 0);
238 }
239
240
newsid(pkt,branch)241 newsid(pkt,branch)
242 register struct packet *pkt;
243 int branch;
244 {
245 int chkbr;
246
247 chkbr = 0;
248 if (pkt->p_reqsid.s_br == 0) {
249 pkt->p_reqsid.s_lev += 1;
250 if (sidtoser(&pkt->p_reqsid,pkt) ||
251 pkt->p_maxr > pkt->p_reqsid.s_rel || branch) {
252 pkt->p_reqsid.s_rel = pkt->p_gotsid.s_rel;
253 pkt->p_reqsid.s_lev = pkt->p_gotsid.s_lev;
254 pkt->p_reqsid.s_br = pkt->p_gotsid.s_br + 1;
255 pkt->p_reqsid.s_seq = 1;
256 chkbr++;
257 }
258 }
259 else if (pkt->p_reqsid.s_seq == 0 && !branch)
260 pkt->p_reqsid.s_seq = pkt->p_gotsid.s_seq + 1;
261 else {
262 pkt->p_reqsid.s_seq += 1;
263 if (branch || sidtoser(&pkt->p_reqsid,pkt)) {
264 pkt->p_reqsid.s_br += 1;
265 pkt->p_reqsid.s_seq = 1;
266 chkbr++;
267 }
268 }
269 if (chkbr)
270 while (sidtoser(&pkt->p_reqsid,pkt))
271 pkt->p_reqsid.s_br += 1;
272 if (sidtoser(&pkt->p_reqsid,pkt))
273 fatal("internal error in newsid()");
274 }
275
276
277 enter(pkt,ch,n,sidp)
278 struct packet *pkt;
279 char ch;
280 int n;
281 struct sid *sidp;
282 {
283 char str[32];
284 register struct apply *ap;
285
286 sid_ba(sidp,str);
287 if (pkt->p_verbose)
288 fprintf(pkt->p_stdout,"%s\n",str);
289 ap = &pkt->p_apply[n];
290 switch(ap->a_code) {
291
292 case EMPTY:
293 if (ch == INCLUDE)
294 condset(ap,APPLY,INCLUSER);
295 else
296 condset(ap,NOAPPLY,EXCLUSER);
297 break;
298 case APPLY:
299 sid_ba(sidp,str);
300 sprintf(Error,"%s already included (ge9)",str);
301 fatal(Error);
302 break;
303 case NOAPPLY:
304 sid_ba(sidp,str);
305 sprintf(Error,"%s already excluded (ge10)",str);
306 fatal(Error);
307 break;
308 default:
309 fatal("internal error in get/enter() (ge11)");
310 break;
311 }
312 }
313
314
gen_lfile(pkt)315 gen_lfile(pkt)
316 register struct packet *pkt;
317 {
318 int n;
319 int reason;
320 char str[32];
321 char line[BUFSIZ];
322 struct deltab dt;
323 FILE *in;
324 FILE *out;
325
326 in = xfopen(pkt->p_file,0);
327 if (*pkt->p_lfile)
328 out = stdout;
329 else
330 out = xfcreat(auxf(pkt->p_file,'l'),0444);
331 fgets(line,sizeof(line),in);
332 while (fgets(line,sizeof(line),in) != NULL && line[0] == CTLCHAR && line[1] == STATS) {
333 fgets(line,sizeof(line),in);
334 del_ab(line,&dt);
335 if (dt.d_type == 'D') {
336 reason = pkt->p_apply[dt.d_serial].a_reason;
337 if (pkt->p_apply[dt.d_serial].a_code == APPLY) {
338 putc(' ',out);
339 putc(' ',out);
340 }
341 else {
342 putc('*',out);
343 if (reason & IGNR)
344 putc(' ',out);
345 else
346 putc('*',out);
347 }
348 switch (reason & (INCL | EXCL | CUTOFF)) {
349
350 case INCL:
351 putc('I',out);
352 break;
353 case EXCL:
354 putc('X',out);
355 break;
356 case CUTOFF:
357 putc('C',out);
358 break;
359 default:
360 putc(' ',out);
361 break;
362 }
363 putc(' ',out);
364 sid_ba(&dt.d_sid,str);
365 fprintf(out,"%s\t",str);
366 date_ba(&dt.d_datetime,str);
367 fprintf(out,"%s %s\n",str,dt.d_pgmr);
368 }
369 while ((n = fgets(line,sizeof(line),in)) != NULL)
370 if (line[0] != CTLCHAR)
371 break;
372 else {
373 switch (line[1]) {
374
375 case EDELTAB:
376 break;
377 default:
378 continue;
379 case MRNUM:
380 case COMMENTS:
381 if (dt.d_type == 'D')
382 fprintf(out,"\t%s",&line[3]);
383 continue;
384 }
385 break;
386 }
387 if (n == NULL || line[0] != CTLCHAR)
388 break;
389 putc('\n',out);
390 }
391 fclose(in);
392 if (out != stdout)
393 fclose(out);
394 }
395
396 char Curdate[18];
397 char *Curtime;
398 char Gdate[9];
399 char Chgdate[18];
400 char *Chgtime;
401 char Gchgdate[9];
402 char Qchgdate[30];
403 char Sid[32];
404 char Olddir[MAXPATHLEN+1];
405 char Pname[MAXPATHLEN+1];
406 char Dir[MAXPATHLEN+1];
407
idsetup(pkt)408 idsetup(pkt)
409 register struct packet *pkt;
410 {
411 extern long Timenow;
412 register int n;
413 register char *p;
414
415 date_ba(&Timenow,Curdate);
416 Curtime = &Curdate[9];
417 Curdate[8] = 0;
418 copy(pkt->p_file,Dir);
419 dname(Dir);
420 if(getwd(Olddir) == 0)
421 fatal("getwd failed (ge20)");
422 if(chdir(Dir) != 0)
423 fatal("cannot change directory (ge22)");
424 if(getwd(Pname) == 0)
425 fatal("getwd failed (ge21)");
426 if(chdir(Olddir) != 0)
427 fatal("cannot change directory (ge23)");
428 makgdate(Curdate,Gdate);
429 for (n = maxser(pkt); n; n--)
430 if (pkt->p_apply[n].a_code == APPLY)
431 break;
432 if (n)
433 date_ba(&pkt->p_idel[n].i_datetime,Chgdate);
434 Chgtime = &Chgdate[9];
435 Chgdate[8] = 0;
436 makgdate(Chgdate,Gchgdate);
437 makqdate(Gchgdate,Qchgdate);
438 sid_ba(&pkt->p_gotsid,Sid);
439 if (p = Sflags[MODFLAG - 'a'])
440 copy(p,Mod);
441 else
442 copy(Gfile,Mod);
443 }
444
445
makgdate(old,new)446 makgdate(old,new)
447 register char *old, *new;
448 {
449 if ((*new = old[3]) != '0')
450 new++;
451 *new++ = old[4];
452 *new++ = '/';
453 if ((*new = old[6]) != '0')
454 new++;
455 *new++ = old[7];
456 *new++ = '/';
457 *new++ = old[0];
458 *new++ = old[1];
459 *new = 0;
460 }
461
makqdate(old,new)462 makqdate(old,new)
463 register char *old, *new;
464 {
465 static char *months[12] =
466 { "January", "February", "March", "April", "May", "June", "July",
467 "August", "September", "October", "November", "December" };
468
469 strcpy(new, months[atoi(old)-1]);
470 while (*new != '\0')
471 new++;
472 while (*old++ != '/')
473 ;
474 *new++ = ' ';
475 *new++ = *old++;
476 if (*old != '/')
477 *new++ = *old++;
478 *new++ = ',';
479 *new++ = ' ';
480 *new++ = '1'; *new++ = '9'; /* works for this century at least */
481 *new++ = *++old;
482 *new++ = *++old;
483 *new = '\0';
484 }
485
486 static char Zkeywd[5] = "@(#)";
487
488
idsubst(pkt,line)489 idsubst(pkt,line)
490 register struct packet *pkt;
491 char line[];
492 {
493 static char tline[BUFSIZ];
494 static char str[32];
495 register char *lp, *tp, *p;
496 extern char *Type;
497 extern char *Sflags[];
498
499 tp = tline;
500 for(lp=line; *lp != 0; lp++) {
501 if (lp[0] != '%' || !lp[1] || !lp[2]) {
502 *tp++ = *lp;
503 continue;
504 }
505 if (lp[2] == '%') {
506 switch(*++lp) {
507 case 'M':
508 tp = trans(tp,Mod);
509 break;
510 case 'R':
511 sprintf(str,"%u",pkt->p_gotsid.s_rel);
512 tp = trans(tp,str);
513 break;
514 case 'L':
515 sprintf(str,"%u",pkt->p_gotsid.s_lev);
516 tp = trans(tp,str);
517 break;
518 case 'B':
519 sprintf(str,"%u",pkt->p_gotsid.s_br);
520 tp = trans(tp,str);
521 break;
522 case 'S':
523 sprintf(str,"%u",pkt->p_gotsid.s_seq);
524 tp = trans(tp,str);
525 break;
526 case 'D':
527 tp = trans(tp,Curdate);
528 break;
529 case 'H':
530 tp = trans(tp,Gdate);
531 break;
532 case 'T':
533 tp = trans(tp,Curtime);
534 break;
535 case 'E':
536 tp = trans(tp,Chgdate);
537 break;
538 case 'G':
539 tp = trans(tp,Gchgdate);
540 break;
541 case 'Q':
542 tp = trans(tp,Qchgdate);
543 break;
544 case 'U':
545 tp = trans(tp,Chgtime);
546 break;
547 case 'Z':
548 tp = trans(tp,Zkeywd);
549 break;
550 case 'Y':
551 tp = trans(tp,Type);
552 break;
553 case 'W':
554 tp = trans(tp,Zkeywd);
555 tp = trans(tp,Mod);
556 *tp++ = '\t';
557 case 'I':
558 tp = trans(tp,Sid);
559 break;
560 case 'P':
561 tp = trans(tp,Pname);
562 *tp++ = '/';
563 tp = trans(tp,(sname(pkt->p_file)));
564 break;
565 case 'F':
566 tp = trans(tp,pkt->p_file);
567 break;
568 case 'C':
569 sprintf(str,"%u",pkt->p_glnno);
570 tp = trans(tp,str);
571 break;
572 case 'A':
573 tp = trans(tp,Zkeywd);
574 tp = trans(tp,Type);
575 *tp++ = ' ';
576 tp = trans(tp,Mod);
577 *tp++ = ' ';
578 tp = trans(tp,Sid);
579 tp = trans(tp,Zkeywd);
580 break;
581 default:
582 *tp++ = '%';
583 *tp++ = *lp;
584 continue;
585 }
586 lp++;
587 continue;
588 }
589 if (!strncmp(lp, "%sccs.include.", 14)) {
590 for (p = lp + 14; *p && *p != '%'; ++p);
591 if (*p == '%') {
592 *p = '\0';
593 readcopy(lp + 14, tline);
594 return(tline);
595 }
596 }
597 *tp++ = '%';
598 }
599
600 *tp = 0;
601 return(tline);
602 }
603
604
trans(tp,str)605 trans(tp,str)
606 register char *tp, *str;
607 {
608 Did_id = 1;
609 while(*tp++ = *str++)
610 ;
611 return(tp-1);
612 }
613
readcopy(name,p)614 readcopy(name, p)
615 register char *name;
616 register char *p;
617 {
618 register FILE *fp;
619 register int ch;
620 char path[MAXPATHLEN];
621
622 (void)sprintf(path, "%s/%s", _PATH_SCCSINCLUDE, name);
623 if (!(fp = fopen(path, "r"))) {
624 (void)sprintf(Error,"can't read %s", path);
625 fatal(Error);
626 }
627 while ((ch = getc(fp)) != EOF)
628 *p++ = ch;
629 (void)fclose(fp);
630 }
631
clean_up(n)632 clean_up(n)
633 {
634 if (gpkt.p_file[0])
635 unlockit(auxf(gpkt.p_file,'z'),getpid());
636 if (gpkt.p_iop)
637 fclose(gpkt.p_iop);
638 xfreeall();
639 }
640
641
wrtpfile(pkt,inc,exc)642 wrtpfile(pkt,inc,exc)
643 register struct packet *pkt;
644 char *inc, *exc;
645 {
646 char line[64], str1[32], str2[32];
647 char *user;
648 FILE *in, *out;
649 struct pfile pf;
650 register char *p;
651 int fd;
652 int i;
653 extern long Timenow;
654
655 user = logname();
656 if (lockit(auxf(pkt->p_file,'z'),2,getpid()))
657 fatal("cannot create lock file (cm4)");
658 if (exists(p = auxf(pkt->p_file,'p'))) {
659 fd = xopen(p,2);
660 in = fdopen(fd,"r");
661 while (fgets(line,sizeof(line),in) != NULL) {
662 p = line;
663 p[length(p) - 1] = 0;
664 pf_ab(p,&pf,0);
665 if ((pf.pf_gsid.s_rel == pkt->p_gotsid.s_rel &&
666 pf.pf_gsid.s_lev == pkt->p_gotsid.s_lev &&
667 pf.pf_gsid.s_br == pkt->p_gotsid.s_br &&
668 pf.pf_gsid.s_seq == pkt->p_gotsid.s_seq) ||
669 (pf.pf_nsid.s_rel == pkt->p_reqsid.s_rel &&
670 pf.pf_nsid.s_lev == pkt->p_reqsid.s_lev &&
671 pf.pf_nsid.s_br == pkt->p_reqsid.s_br &&
672 pf.pf_nsid.s_seq == pkt->p_reqsid.s_seq)) {
673 fclose(in);
674 sprintf(Error,"being edited: `%s' (ge17)",line);
675 fatal(Error);
676 }
677 if (!equal(pf.pf_user,user))
678 fprintf(stderr,"WARNING: being edited: `%s' (ge18)\n",line);
679 }
680 out = fdopen(dup(fd),"w");
681 fclose(in);
682 }
683 else
684 out = xfcreat(p,0666);
685 fseek(out,0L,2);
686 sid_ba(&pkt->p_gotsid,str1);
687 sid_ba(&pkt->p_reqsid,str2);
688 date_ba(&Timenow,line);
689 fprintf(out,"%s %s %s %s",str1,str2,user,line);
690 if (inc)
691 fprintf(out," -i%s",inc);
692 if (exc)
693 fprintf(out," -x%s",exc);
694 fprintf(out,"\n");
695 fclose(out);
696 if (pkt->p_verbose)
697 fprintf(pkt->p_stdout,"new delta %s\n",str2);
698 unlockit(auxf(pkt->p_file,'z'),getpid());
699 }
700
701
getser(pkt)702 getser(pkt)
703 register struct packet *pkt;
704 {
705 register struct idel *rdp;
706 int n, ser, def;
707 char *p;
708 extern char *Sflags[];
709
710 def = 0;
711 if (pkt->p_reqsid.s_rel == 0) {
712 if (p = Sflags[DEFTFLAG - 'a'])
713 chksid(sid_ab(p, &pkt->p_reqsid), &pkt->p_reqsid);
714 else {
715 pkt->p_reqsid.s_rel = MAX;
716 def = 1;
717 }
718 }
719 ser = 0;
720 if (pkt->p_reqsid.s_lev == 0) {
721 for (n = maxser(pkt); n; n--) {
722 rdp = &pkt->p_idel[n];
723 if ((rdp->i_sid.s_br == 0 || HADT) &&
724 pkt->p_reqsid.s_rel >= rdp->i_sid.s_rel &&
725 rdp->i_sid.s_rel > pkt->p_gotsid.s_rel) {
726 ser = n;
727 pkt->p_gotsid.s_rel = rdp->i_sid.s_rel;
728 }
729 }
730 }
731 else if (pkt->p_reqsid.s_br && pkt->p_reqsid.s_seq == 0) {
732 for (n = maxser(pkt); n; n--) {
733 rdp = &pkt->p_idel[n];
734 if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel &&
735 rdp->i_sid.s_lev == pkt->p_reqsid.s_lev &&
736 rdp->i_sid.s_br == pkt->p_reqsid.s_br)
737 break;
738 }
739 ser = n;
740 }
741 else {
742 ser = sidtoser(&pkt->p_reqsid,pkt);
743 }
744 if (ser == 0)
745 fatal("nonexistent sid (ge5)");
746 rdp = &pkt->p_idel[ser];
747 bcopy(&rdp->i_sid, &pkt->p_gotsid, sizeof(pkt->p_gotsid));
748 if (def || (pkt->p_reqsid.s_lev == 0 && pkt->p_reqsid.s_rel == pkt->p_gotsid.s_rel))
749 bcopy(&pkt->p_gotsid, &pkt->p_reqsid, sizeof(pkt->p_gotsid));
750 return(ser);
751 }
752
753
754 /* Null routine to satisfy external reference from dodelt() */
755
escdodelt()756 escdodelt()
757 {
758 }
759