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> 6*6d6ffe57Sbostic # include "pathnames.h" 7349ae6eaSeric 8*6d6ffe57Sbostic static char Sccsid[] = "@(#)get.c 4.10 04/08/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 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 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 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 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 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 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 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 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 489349ae6eaSeric idsubst(pkt,line) 490349ae6eaSeric register struct packet *pkt; 491349ae6eaSeric char line[]; 492349ae6eaSeric { 493349ae6eaSeric static char tline[BUFSIZ]; 494349ae6eaSeric static char str[32]; 495*6d6ffe57Sbostic register char *lp, *tp, *p; 496349ae6eaSeric extern char *Type; 497349ae6eaSeric extern char *Sflags[]; 498349ae6eaSeric 499349ae6eaSeric tp = tline; 500349ae6eaSeric for(lp=line; *lp != 0; lp++) { 501*6d6ffe57Sbostic if (lp[0] != '%' || !lp[1] || !lp[2]) { 502*6d6ffe57Sbostic *tp++ = *lp; 503*6d6ffe57Sbostic continue; 504*6d6ffe57Sbostic } 505*6d6ffe57Sbostic 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++; 587*6d6ffe57Sbostic continue; 588349ae6eaSeric } 589*6d6ffe57Sbostic if (!strncmp(lp, "%sccs.include.", 14)) { 590*6d6ffe57Sbostic for (p = lp + 14; *p && *p != '%'; ++p); 591*6d6ffe57Sbostic if (*p != '%') 592*6d6ffe57Sbostic *tp++ = '%'; 593*6d6ffe57Sbostic else { 594*6d6ffe57Sbostic *p = '\0'; 595*6d6ffe57Sbostic tp = readcopy(lp + 14, tp); 596*6d6ffe57Sbostic lp = p + 1; 597*6d6ffe57Sbostic } 598*6d6ffe57Sbostic } 599349ae6eaSeric } 600349ae6eaSeric 601349ae6eaSeric *tp = 0; 602349ae6eaSeric return(tline); 603349ae6eaSeric } 604349ae6eaSeric 605349ae6eaSeric 606349ae6eaSeric trans(tp,str) 607349ae6eaSeric register char *tp, *str; 608349ae6eaSeric { 609349ae6eaSeric Did_id = 1; 610349ae6eaSeric while(*tp++ = *str++) 611349ae6eaSeric ; 612349ae6eaSeric return(tp-1); 613349ae6eaSeric } 614349ae6eaSeric 615*6d6ffe57Sbostic readcopy(name, tp) 616*6d6ffe57Sbostic register char *name; 617*6d6ffe57Sbostic register char *tp; 618*6d6ffe57Sbostic { 619*6d6ffe57Sbostic register FILE *fp; 620*6d6ffe57Sbostic register int ch; 621*6d6ffe57Sbostic char path[MAXPATHLEN]; 622*6d6ffe57Sbostic 623*6d6ffe57Sbostic (void)sprintf(path, "%s/%s", _PATH_SCCSINCLUDE, name); 624*6d6ffe57Sbostic if (!(fp = fopen(path, "r"))) { 625*6d6ffe57Sbostic (void)sprintf(Error,"can't read %s", path); 626*6d6ffe57Sbostic fatal(Error); 627*6d6ffe57Sbostic } 628*6d6ffe57Sbostic while ((ch = getc(fp)) != EOF) 629*6d6ffe57Sbostic *tp++ = ch; 630*6d6ffe57Sbostic (void)fclose(fp); 631*6d6ffe57Sbostic return(tp); 632*6d6ffe57Sbostic } 633349ae6eaSeric 634349ae6eaSeric clean_up(n) 635349ae6eaSeric { 636349ae6eaSeric if (gpkt.p_file[0]) 637349ae6eaSeric unlockit(auxf(gpkt.p_file,'z'),getpid()); 638349ae6eaSeric if (gpkt.p_iop) 639349ae6eaSeric fclose(gpkt.p_iop); 640349ae6eaSeric xfreeall(); 641349ae6eaSeric } 642349ae6eaSeric 643349ae6eaSeric 644349ae6eaSeric wrtpfile(pkt,inc,exc) 645349ae6eaSeric register struct packet *pkt; 646349ae6eaSeric char *inc, *exc; 647349ae6eaSeric { 648349ae6eaSeric char line[64], str1[32], str2[32]; 649349ae6eaSeric char *user; 650349ae6eaSeric FILE *in, *out; 651349ae6eaSeric struct pfile pf; 652349ae6eaSeric register char *p; 653349ae6eaSeric int fd; 654349ae6eaSeric int i; 655349ae6eaSeric extern long Timenow; 656349ae6eaSeric 657349ae6eaSeric user = logname(); 658349ae6eaSeric if (lockit(auxf(pkt->p_file,'z'),2,getpid())) 659349ae6eaSeric fatal("cannot create lock file (cm4)"); 660349ae6eaSeric if (exists(p = auxf(pkt->p_file,'p'))) { 661349ae6eaSeric fd = xopen(p,2); 662abc16d2cSsam in = fdopen(fd,"r"); 663349ae6eaSeric while (fgets(line,sizeof(line),in) != NULL) { 664349ae6eaSeric p = line; 665349ae6eaSeric p[length(p) - 1] = 0; 666349ae6eaSeric pf_ab(p,&pf,0); 667349ae6eaSeric if ((pf.pf_gsid.s_rel == pkt->p_gotsid.s_rel && 668349ae6eaSeric pf.pf_gsid.s_lev == pkt->p_gotsid.s_lev && 669349ae6eaSeric pf.pf_gsid.s_br == pkt->p_gotsid.s_br && 670349ae6eaSeric pf.pf_gsid.s_seq == pkt->p_gotsid.s_seq) || 671349ae6eaSeric (pf.pf_nsid.s_rel == pkt->p_reqsid.s_rel && 672349ae6eaSeric pf.pf_nsid.s_lev == pkt->p_reqsid.s_lev && 673349ae6eaSeric pf.pf_nsid.s_br == pkt->p_reqsid.s_br && 674349ae6eaSeric pf.pf_nsid.s_seq == pkt->p_reqsid.s_seq)) { 675349ae6eaSeric fclose(in); 676824dd99bSbostic sprintf(Error,"being edited: `%s' (ge17)",line); 677824dd99bSbostic fatal(Error); 678349ae6eaSeric } 679349ae6eaSeric if (!equal(pf.pf_user,user)) 680349ae6eaSeric fprintf(stderr,"WARNING: being edited: `%s' (ge18)\n",line); 681349ae6eaSeric } 682abc16d2cSsam out = fdopen(dup(fd),"w"); 683349ae6eaSeric fclose(in); 684349ae6eaSeric } 685349ae6eaSeric else 686d15e2020Seric out = xfcreat(p,0666); 687349ae6eaSeric fseek(out,0L,2); 688349ae6eaSeric sid_ba(&pkt->p_gotsid,str1); 689349ae6eaSeric sid_ba(&pkt->p_reqsid,str2); 690349ae6eaSeric date_ba(&Timenow,line); 691349ae6eaSeric fprintf(out,"%s %s %s %s",str1,str2,user,line); 692349ae6eaSeric if (inc) 693349ae6eaSeric fprintf(out," -i%s",inc); 694349ae6eaSeric if (exc) 695349ae6eaSeric fprintf(out," -x%s",exc); 696349ae6eaSeric fprintf(out,"\n"); 697349ae6eaSeric fclose(out); 698349ae6eaSeric if (pkt->p_verbose) 699349ae6eaSeric fprintf(pkt->p_stdout,"new delta %s\n",str2); 700349ae6eaSeric unlockit(auxf(pkt->p_file,'z'),getpid()); 701349ae6eaSeric } 702349ae6eaSeric 703349ae6eaSeric 704349ae6eaSeric getser(pkt) 705349ae6eaSeric register struct packet *pkt; 706349ae6eaSeric { 707349ae6eaSeric register struct idel *rdp; 708349ae6eaSeric int n, ser, def; 709349ae6eaSeric char *p; 710349ae6eaSeric extern char *Sflags[]; 711349ae6eaSeric 712349ae6eaSeric def = 0; 713349ae6eaSeric if (pkt->p_reqsid.s_rel == 0) { 714349ae6eaSeric if (p = Sflags[DEFTFLAG - 'a']) 715349ae6eaSeric chksid(sid_ab(p, &pkt->p_reqsid), &pkt->p_reqsid); 716349ae6eaSeric else { 717349ae6eaSeric pkt->p_reqsid.s_rel = MAX; 718349ae6eaSeric def = 1; 719349ae6eaSeric } 720349ae6eaSeric } 721349ae6eaSeric ser = 0; 722349ae6eaSeric if (pkt->p_reqsid.s_lev == 0) { 723349ae6eaSeric for (n = maxser(pkt); n; n--) { 724349ae6eaSeric rdp = &pkt->p_idel[n]; 725349ae6eaSeric if ((rdp->i_sid.s_br == 0 || HADT) && 726349ae6eaSeric pkt->p_reqsid.s_rel >= rdp->i_sid.s_rel && 727349ae6eaSeric rdp->i_sid.s_rel > pkt->p_gotsid.s_rel) { 728349ae6eaSeric ser = n; 729349ae6eaSeric pkt->p_gotsid.s_rel = rdp->i_sid.s_rel; 730349ae6eaSeric } 731349ae6eaSeric } 732349ae6eaSeric } 733349ae6eaSeric else if (pkt->p_reqsid.s_br && pkt->p_reqsid.s_seq == 0) { 734349ae6eaSeric for (n = maxser(pkt); n; n--) { 735349ae6eaSeric rdp = &pkt->p_idel[n]; 736349ae6eaSeric if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel && 737349ae6eaSeric rdp->i_sid.s_lev == pkt->p_reqsid.s_lev && 738349ae6eaSeric rdp->i_sid.s_br == pkt->p_reqsid.s_br) 739349ae6eaSeric break; 740349ae6eaSeric } 741349ae6eaSeric ser = n; 742349ae6eaSeric } 743349ae6eaSeric else { 744349ae6eaSeric ser = sidtoser(&pkt->p_reqsid,pkt); 745349ae6eaSeric } 746349ae6eaSeric if (ser == 0) 747349ae6eaSeric fatal("nonexistent sid (ge5)"); 748349ae6eaSeric rdp = &pkt->p_idel[ser]; 749abc16d2cSsam bcopy(&rdp->i_sid, &pkt->p_gotsid, sizeof(pkt->p_gotsid)); 750349ae6eaSeric if (def || (pkt->p_reqsid.s_lev == 0 && pkt->p_reqsid.s_rel == pkt->p_gotsid.s_rel)) 751abc16d2cSsam bcopy(&pkt->p_gotsid, &pkt->p_reqsid, sizeof(pkt->p_gotsid)); 752349ae6eaSeric return(ser); 753349ae6eaSeric } 754349ae6eaSeric 755349ae6eaSeric 756349ae6eaSeric /* Null routine to satisfy external reference from dodelt() */ 757349ae6eaSeric 758349ae6eaSeric escdodelt() 759349ae6eaSeric { 760349ae6eaSeric } 761