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