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