1*2151Seric # 2*2151Seric /* 3*2151Seric Program to convert release 3 (or release 2 or even 1) SCCS files 4*2151Seric to release 4 SCCS files. 5*2151Seric Usage: 6*2151Seric scv arg ... 7*2151Seric arg is any argument acceptable as an SCCS file 8*2151Seric name argument to the get command. E.g.: 9*2151Seric scv mysccsdir 10*2151Seric will convert every release 3 (or 2 or 1 but NOT 4) SCCS file in the 11*2151Seric directory "mysccsdir". 12*2151Seric */ 13*2151Seric # include "../hdr/defines.h" 14*2151Seric # include "dir.h" 15*2151Seric 16*2151Seric 17*2151Seric /* 18*2151Seric Release 3 SCCS File Structures (2.1 78/06/05 17:31:17) 19*2151Seric See osccsfile(V). 20*2151Seric */ 21*2151Seric 22*2151Seric struct Header { 23*2151Seric short Hmagicno; 24*2151Seric char Htype[10]; 25*2151Seric char Hpers[14]; 26*2151Seric char Hdesc[100]; 27*2151Seric short Hfloor; 28*2151Seric short Hceil; 29*2151Seric short Hsw[5]; 30*2151Seric short Hrdef; 31*2151Seric char Hulist[32]; 32*2151Seric char Hexpand[50]; 33*2151Seric short Hash; 34*2151Seric }; 35*2151Seric #define MAGICNO (7) 36*2151Seric #define HASHADDR (226) 37*2151Seric 38*2151Seric 39*2151Seric struct Reltab { 40*2151Seric short Rrel; 41*2151Seric short Rlevs; 42*2151Seric }; 43*2151Seric 44*2151Seric 45*2151Seric struct Deltab { 46*2151Seric short Drel; 47*2151Seric short Dlev; 48*2151Seric char Dtype; /*'D': delta,'P','U': non-prop,'I': incl,'E': excl */ 49*2151Seric char Dfill; /* Used to be option letter */ 50*2151Seric /* compiler once forced unfortunate alignment here. 51*2151Seric /* also, fp-11c high/low long goof strikes again. 52*2151Seric /* long Ddatetime; 53*2151Seric */ 54*2151Seric short Ddthi,Ddtlo; 55*2151Seric char Dpgmr[8]; 56*2151Seric char Dhist[200]; 57*2151Seric }; 58*2151Seric 59*2151Seric 60*2151Seric struct Control { 61*2151Seric short Crel; 62*2151Seric short Clev; 63*2151Seric char Cctl; /* -11: ins, -12: del, -13: end */ 64*2151Seric }; 65*2151Seric #define SIZEOFCONTROL (5) 66*2151Seric #define OINS (-11) 67*2151Seric #define ODEL (-12) 68*2151Seric #define OEND (-13) 69*2151Seric 70*2151Seric 71*2151Seric struct Line { 72*2151Seric char Lline [256]; 73*2151Seric }; 74*2151Seric 75*2151Seric 76*2151Seric /* 77*2151Seric Structure for use with buffered I/O routines opnl, opnr, 78*2151Seric getl and getr. 79*2151Seric */ 80*2151Seric struct Ibufr { 81*2151Seric short Ifildes; 82*2151Seric char *Irecptr; 83*2151Seric char *Iend; 84*2151Seric char Ibuff1[256]; 85*2151Seric char Ibuff2[512]; 86*2151Seric char Ibuff3[2]; 87*2151Seric short Ilen; 88*2151Seric short Ihflag; 89*2151Seric short Ihcnt; 90*2151Seric short Ihtot; 91*2151Seric }; 92*2151Seric 93*2151Seric 94*2151Seric /* 95*2151Seric Structure for use with buffered I/O routines crtr, crtl, putl, 96*2151Seric putr, flshr and buflsh. 97*2151Seric */ 98*2151Seric struct Obufr { 99*2151Seric short Ofildes; 100*2151Seric char *Orecptr; 101*2151Seric char *Oend; 102*2151Seric char Obuff1[512]; 103*2151Seric short Ohflag; 104*2151Seric short Ohcnt; 105*2151Seric }; 106*2151Seric 107*2151Seric 108*2151Seric /* 109*2151Seric * structure to access an 110*2151Seric * shorteger in bytes 111*2151Seric */ 112*2151Seric struct 113*2151Seric { 114*2151Seric char lobyte; 115*2151Seric char hibyte; 116*2151Seric }; 117*2151Seric 118*2151Seric 119*2151Seric /* 120*2151Seric * structure to access an shorteger 121*2151Seric */ 122*2151Seric struct 123*2151Seric { 124*2151Seric short shorteg; 125*2151Seric }; 126*2151Seric 127*2151Seric 128*2151Seric /* 129*2151Seric * structure to access a long as shortegers 130*2151Seric */ 131*2151Seric struct { 132*2151Seric short hiword; 133*2151Seric short loword; 134*2151Seric }; 135*2151Seric 136*2151Seric 137*2151Seric /* 138*2151Seric Structure for referencing pieces of localtime(). 139*2151Seric */ 140*2151Seric struct Time { 141*2151Seric short Tseconds; 142*2151Seric short Tminutes; 143*2151Seric short Thours; 144*2151Seric short Tday_month; 145*2151Seric short Tmonth; 146*2151Seric short Tyear; 147*2151Seric short Tday_week; 148*2151Seric short Tday_year; 149*2151Seric short Tflag; 150*2151Seric }; 151*2151Seric /* 152*2151Seric SCCS Internal Structures (used by get and delta). (2.1) 153*2151Seric */ 154*2151Seric 155*2151Seric struct Apply { 156*2151Seric short Adt; /* pseudo date-time */ 157*2151Seric short Acode; /* APPLY, NOAPPLY or EMPTY */ 158*2151Seric }; 159*2151Seric #define APPLY (1) 160*2151Seric #define NOAPPLY (-1) 161*2151Seric #define EMPTY (0) 162*2151Seric 163*2151Seric 164*2151Seric struct Queue { 165*2151Seric struct Queue *Qnext; 166*2151Seric short Qrel; /* release */ 167*2151Seric short Qlev; /* level */ 168*2151Seric short Qdt; /* pseudo date-time */ 169*2151Seric short Qkeep; /* keep switch setting */ 170*2151Seric }; 171*2151Seric #define YES (1) 172*2151Seric #define NO (-1) 173*2151Seric 174*2151Seric #define SIZEOFPfile (50) 175*2151Seric 176*2151Seric 177*2151Seric struct Packet { 178*2151Seric char Pfile[SIZEOFPfile]; /* file name containing module */ 179*2151Seric /* 180*2151Seric Note: the order of the next two words 181*2151Seric can not___ be changed! 182*2151Seric This is because the release and level together 183*2151Seric are treated as a long. 184*2151Seric */ 185*2151Seric short Prel; /* specified release (-1 = not spec.) */ 186*2151Seric short Plev; /* specified level (-1 = not spec.)*/ 187*2151Seric char Pverbose; /* verbose flags (see #define's below) */ 188*2151Seric char Pupd; /* update flag (!0 = update mode) */ 189*2151Seric long Pcutoff; /* specified cutoff date-time */ 190*2151Seric struct Header Phdr; /* header from module */ 191*2151Seric short Plnno; /* line number of current line */ 192*2151Seric short Precno; /* record number of current rec */ 193*2151Seric char Pwrttn; /* written flag (!0 = written) */ 194*2151Seric char Pkeep; /* keep switch for readmod() */ 195*2151Seric struct Apply **Papply; /* ptr to apply array */ 196*2151Seric struct Queue *Pq; /* ptr to control queue */ 197*2151Seric struct Ibufr Pibuf; /* input buffer */ 198*2151Seric long Pcdt; /* date/time of newest applied delta */ 199*2151Seric char *Plfile; /* 0 = no l-file; else ptr to l arg */ 200*2151Seric char Punack; /* !0 if unacknowledged non-prop deltas */ 201*2151Seric char Pnoprop; /* !0 if new delta is to be non-prop */ 202*2151Seric short Pirel; /* rel which inserted current rec */ 203*2151Seric short Pilev; /* lev which inserted current rec */ 204*2151Seric }; 205*2151Seric /* 206*2151Seric Masks for Pverbose 207*2151Seric */ 208*2151Seric 209*2151Seric # define RLACCESS (1) 210*2151Seric # define NLINES (2) 211*2151Seric # define DOLIST (4) 212*2151Seric # define UNACK (8) 213*2151Seric # define NEWRL (16) 214*2151Seric # define WARNING (32) 215*2151Seric 216*2151Seric /* 217*2151Seric size of login name 218*2151Seric */ 219*2151Seric 220*2151Seric 221*2151Seric USXALLOC(); 222*2151Seric 223*2151Seric main(argc,argv) 224*2151Seric char **argv; 225*2151Seric { 226*2151Seric register short i; 227*2151Seric register char *p; 228*2151Seric extern conv(); 229*2151Seric extern short Fcnt; 230*2151Seric 231*2151Seric setsig(); 232*2151Seric Fflags = FTLMSG | FTLCLN | FTLJMP; 233*2151Seric for (i = 1; i < argc; i++) 234*2151Seric if (p = argv[i]) 235*2151Seric odo_file(p,conv); 236*2151Seric exit(Fcnt ? 1 : 0); 237*2151Seric } 238*2151Seric 239*2151Seric 240*2151Seric struct packet npkt; 241*2151Seric 242*2151Seric conv(ofile) 243*2151Seric char *ofile; 244*2151Seric { 245*2151Seric struct Packet opkt; 246*2151Seric struct deltab *dt; 247*2151Seric char **hists; 248*2151Seric short **rlp; 249*2151Seric char statstr[32]; 250*2151Seric short ndels; 251*2151Seric char *line; 252*2151Seric short n; 253*2151Seric char *p; 254*2151Seric 255*2151Seric if (setjmp(Fjmp)) 256*2151Seric return; 257*2151Seric printf("%s:\n",ofile); 258*2151Seric ckpfile(auxf(ofile,'p')); 259*2151Seric zero(&opkt,sizeof(opkt)); 260*2151Seric opnr(&opkt.Pibuf,ofile); 261*2151Seric dohead(&opkt); 262*2151Seric rlp = 0; 263*2151Seric ndels = doreltab(&opkt,&rlp); 264*2151Seric hists = alloc((ndels + 1) * sizeof(*hists)); 265*2151Seric dt = alloc((ndels + 1) * sizeof(*dt)); 266*2151Seric dodelt(&opkt,dt,hists,ndels); 267*2151Seric fixup(dt,ndels,rlp); 268*2151Seric sinit(&npkt,ofile,0); 269*2151Seric npkt.p_upd = 1; 270*2151Seric line = npkt.p_line; 271*2151Seric putline(&npkt,sprintf(line,"%c%c00000\n",CTLCHAR,HEAD),0); 272*2151Seric statstr[0] = 0; 273*2151Seric for (n = ndels; n; n--) { 274*2151Seric if (!statstr[0]) 275*2151Seric newstats(&npkt,statstr,"?"); 276*2151Seric else 277*2151Seric putline(&npkt,statstr); 278*2151Seric putline(&npkt,del_ba(&dt[n],line)); 279*2151Seric putline(&npkt,sprintf(line,"%c%c %s\n",CTLCHAR,COMMENTS, 280*2151Seric hists[n])); 281*2151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EDELTAB)); 282*2151Seric } 283*2151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERNAM)); 284*2151Seric dousers(opkt.Phdr.Hulist,&npkt); 285*2151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERNAM)); 286*2151Seric if (*(p = opkt.Phdr.Htype)) 287*2151Seric putline(&npkt,sprintf(line,"%c%c %c %s\n",CTLCHAR,FLAG, 288*2151Seric TYPEFLAG,p)); 289*2151Seric if (n = opkt.Phdr.Hfloor) 290*2151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 291*2151Seric FLORFLAG,n)); 292*2151Seric if (n = opkt.Phdr.Hceil) 293*2151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 294*2151Seric CEILFLAG,n)); 295*2151Seric if (n = opkt.Phdr.Hrdef) 296*2151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 297*2151Seric DEFTFLAG,n)); 298*2151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERTXT)); 299*2151Seric if (*(p = opkt.Phdr.Hpers)) 300*2151Seric putline(&npkt,sprintf(line,"%s\n",p)); 301*2151Seric if (*(p = opkt.Phdr.Hdesc)) 302*2151Seric putline(&npkt,sprintf(line,"%s\n",p)); 303*2151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERTXT)); 304*2151Seric dobod(&opkt,&npkt,rlp,line); 305*2151Seric convflush(&npkt); 306*2151Seric close(opkt.Pibuf.Ifildes); 307*2151Seric for (n = ndels; n; n--) 308*2151Seric free(hists[n]); 309*2151Seric free(hists); 310*2151Seric free(dt); 311*2151Seric /* [compiler bug, ignore this for now ] 312*2151Seric if (rlp) { 313*2151Seric for (n = (short) (*rlp); n; n--) 314*2151Seric if (rlp[n]) 315*2151Seric free(rlp[n]); 316*2151Seric free(rlp); 317*2151Seric } 318*2151Seric */ 319*2151Seric rename(auxf(npkt.p_file,'x'),npkt.p_file); 320*2151Seric xrm(&npkt); 321*2151Seric } 322*2151Seric 323*2151Seric 324*2151Seric getline() 325*2151Seric { 326*2151Seric } 327*2151Seric 328*2151Seric 329*2151Seric clean_up() 330*2151Seric { 331*2151Seric xrm(&npkt); 332*2151Seric } 333*2151Seric 334*2151Seric 335*2151Seric 336*2151Seric fixup(dt,ndels,rlp) 337*2151Seric struct deltab *dt; 338*2151Seric short ndels; 339*2151Seric short **rlp; 340*2151Seric { 341*2151Seric short m, n; 342*2151Seric short maxr; 343*2151Seric short seqcnt; 344*2151Seric short pred; 345*2151Seric register struct deltab *p1, *p2; 346*2151Seric register short *brp; 347*2151Seric 348*2151Seric for (m = ndels; m; m--) { 349*2151Seric p1 = &dt[m]; 350*2151Seric if (p1->d_sid.s_lev > 1) { 351*2151Seric for (n = m - 1; n; n--) { 352*2151Seric if (p1->d_sid.s_rel == dt[n].d_sid.s_rel) 353*2151Seric break; 354*2151Seric } 355*2151Seric pred = n; 356*2151Seric } 357*2151Seric else { 358*2151Seric maxr = pred = 0; 359*2151Seric for (n = m - 1; n; n--) { 360*2151Seric p2 = &dt[n]; 361*2151Seric if (p1->d_sid.s_rel > p2->d_sid.s_rel && 362*2151Seric p2->d_type == 'D' && 363*2151Seric p2->d_sid.s_rel > maxr) { 364*2151Seric maxr = p2->d_sid.s_rel; 365*2151Seric pred = n; 366*2151Seric } 367*2151Seric } 368*2151Seric } 369*2151Seric p1->d_pred = pred; 370*2151Seric rlp[p1->d_sid.s_rel][p1->d_sid.s_lev] = m; 371*2151Seric } 372*2151Seric brp = alloca(n = (ndels + 1) * sizeof(*brp)); 373*2151Seric zero(brp,n); 374*2151Seric for (m = 1; m <= ndels; m++) { 375*2151Seric p1 = &dt[m]; 376*2151Seric if (p1->d_type != 'D') { 377*2151Seric seqcnt = 0; 378*2151Seric p2 = &dt[p1->d_pred]; 379*2151Seric p1->d_type = 'D'; 380*2151Seric p1->d_sid.s_rel = p2->d_sid.s_rel; 381*2151Seric p1->d_sid.s_lev = p2->d_sid.s_lev; 382*2151Seric p1->d_sid.s_br = ++brp[p1->d_pred]; 383*2151Seric p1->d_sid.s_seq = ++seqcnt; 384*2151Seric pred = m; 385*2151Seric for (n = m + 1; n <= ndels; n++) { 386*2151Seric if (dt[n].d_pred == pred) { 387*2151Seric p2 = &dt[n]; 388*2151Seric p2->d_type = 'D'; 389*2151Seric p2->d_sid.s_rel = p1->d_sid.s_rel; 390*2151Seric p2->d_sid.s_lev = p1->d_sid.s_lev; 391*2151Seric p2->d_sid.s_br = p1->d_sid.s_br; 392*2151Seric p2->d_sid.s_seq = ++seqcnt; 393*2151Seric pred = n; 394*2151Seric } 395*2151Seric } 396*2151Seric } 397*2151Seric } 398*2151Seric } 399*2151Seric 400*2151Seric 401*2151Seric 402*2151Seric struct names { 403*2151Seric struct names *n_next; 404*2151Seric char n_name[SZLNAM]; 405*2151Seric short n_uid; 406*2151Seric }; 407*2151Seric 408*2151Seric struct names *names; 409*2151Seric 410*2151Seric dousers(up,pkt) 411*2151Seric register char *up; 412*2151Seric struct packet *pkt; 413*2151Seric { 414*2151Seric short i, j; 415*2151Seric register char mask, c; 416*2151Seric char *p; 417*2151Seric char str[16]; 418*2151Seric 419*2151Seric for (i = 0; i < 32; i++) 420*2151Seric if (c = *up++) { 421*2151Seric j = 0; 422*2151Seric for (mask = 1; mask; mask =<< 1) { 423*2151Seric if ((c & mask) && (p = getlnam(i * 8 + j))) 424*2151Seric putline(pkt,sprintf(str,"%s\n",p)); 425*2151Seric j++; 426*2151Seric } 427*2151Seric } 428*2151Seric } 429*2151Seric 430*2151Seric 431*2151Seric getlnam(uid) 432*2151Seric short uid; 433*2151Seric { 434*2151Seric char str[128]; 435*2151Seric register struct names *cur, *prev; 436*2151Seric register char *p; 437*2151Seric 438*2151Seric for (cur = &names; cur = (prev = cur)->n_next; ) 439*2151Seric if (cur->n_uid == uid) 440*2151Seric return(cur->n_name); 441*2151Seric if (getpw(uid,str)) 442*2151Seric return(0); 443*2151Seric prev->n_next = cur = alloc(sizeof(*cur)); 444*2151Seric cur->n_next = 0; 445*2151Seric cur->n_uid = uid; 446*2151Seric for (p = str; *p++ != ':'; ) 447*2151Seric ; 448*2151Seric *--p = 0; 449*2151Seric str[SZLNAM] = 0; 450*2151Seric copy(str,cur->n_name); 451*2151Seric return(cur->n_name); 452*2151Seric } 453*2151Seric 454*2151Seric 455*2151Seric 456*2151Seric /* 457*2151Seric Routine to process the module header. All that's necessary is 458*2151Seric to slide it shorto the packet. 459*2151Seric */ 460*2151Seric 461*2151Seric dohead(pkt) 462*2151Seric register struct Packet *pkt; 463*2151Seric { 464*2151Seric register struct Header *hdr; 465*2151Seric 466*2151Seric if(rdrec(pkt) == 1) fatal("premature eof (58)"); 467*2151Seric hdr = pkt->Pibuf.Irecptr; 468*2151Seric if(hdr->Hmagicno != MAGICNO) fatal("not an SCCS file (53)"); 469*2151Seric move(hdr,&pkt->Phdr,sizeof(*hdr)); 470*2151Seric } 471*2151Seric 472*2151Seric 473*2151Seric doreltab(pkt,rlp) 474*2151Seric register struct Packet *pkt; 475*2151Seric register short ***rlp; 476*2151Seric { 477*2151Seric short n; 478*2151Seric short sz; 479*2151Seric register struct Reltab *rt; 480*2151Seric 481*2151Seric n = 0; 482*2151Seric while (rdrec(pkt) != 1 && (rt = pkt->Pibuf.Irecptr)->Rrel) { 483*2151Seric if (n == 0) { 484*2151Seric *rlp = alloc(sz = (rt->Rrel + 1) * sizeof(**rlp)); 485*2151Seric zero(*rlp,sz); 486*2151Seric **rlp = rt->Rrel; 487*2151Seric } 488*2151Seric (*rlp)[rt->Rrel] = alloc((rt->Rlevs + 1) * sizeof(***rlp)); 489*2151Seric (*rlp)[rt->Rrel][0] = rt->Rlevs; 490*2151Seric n =+ rt->Rlevs; 491*2151Seric } 492*2151Seric return(n); 493*2151Seric } 494*2151Seric 495*2151Seric 496*2151Seric dodelt(pkt,dt,hists,ndels) 497*2151Seric struct Packet *pkt; 498*2151Seric register struct deltab *dt; 499*2151Seric char **hists; 500*2151Seric short ndels; 501*2151Seric { 502*2151Seric short n; 503*2151Seric register struct deltab *ndt; 504*2151Seric register struct Deltab *odt; 505*2151Seric 506*2151Seric for (; rdrec(pkt) != 1 && (odt = pkt->Pibuf.Irecptr)->Drel; --ndels) { 507*2151Seric if (!(odt->Dtype == 'D' || odt->Dtype == 'P' || odt->Dtype == 'U')) { 508*2151Seric ++ndels; 509*2151Seric continue; 510*2151Seric } 511*2151Seric if (!ndels) 512*2151Seric return(fatal("internal error in dodeltab")); 513*2151Seric ndt = &dt[ndels]; 514*2151Seric ndt->d_type = odt->Dtype; 515*2151Seric move(odt->Dpgmr,ndt->d_pgmr,sizeof(ndt->d_pgmr)); 516*2151Seric ndt->d_datetime = (odt->Ddthi<<16)+(unsigned)odt->Ddtlo; 517*2151Seric ndt->d_sid.s_rel = odt->Drel; 518*2151Seric ndt->d_sid.s_lev = odt->Dlev; 519*2151Seric ndt->d_sid.s_br = 0; 520*2151Seric ndt->d_sid.s_seq = 0; 521*2151Seric ndt->d_serial = ndels; 522*2151Seric ndt->d_pred = 0; 523*2151Seric n = size(odt->Dhist); 524*2151Seric n++; 525*2151Seric n =& ~1; 526*2151Seric if (odt->Dtype == 'P' || odt->Dtype == 'U') { 527*2151Seric hists[ndels] = alloc(n + 16); 528*2151Seric sprintf(hists[ndels],"[was %d.%d] ",odt->Drel,odt->Dlev); 529*2151Seric } 530*2151Seric else { 531*2151Seric hists[ndels] = alloc(n); 532*2151Seric hists[ndels][0] = 0; 533*2151Seric } 534*2151Seric move(odt->Dhist,strend(hists[ndels]),n); 535*2151Seric } 536*2151Seric if (ndels) { 537*2151Seric fatal("in dodelt"); 538*2151Seric } 539*2151Seric } 540*2151Seric 541*2151Seric 542*2151Seric dobod(opkt,npkt,rlp,line) 543*2151Seric struct Packet *opkt; 544*2151Seric struct packet *npkt; 545*2151Seric short **rlp; 546*2151Seric char *line; 547*2151Seric { 548*2151Seric register struct Control *octl; 549*2151Seric register char *p, c; 550*2151Seric 551*2151Seric while (rdrec(opkt) != 1 && (octl = opkt->Pibuf.Irecptr)->Crel) { 552*2151Seric if (octlrec(octl,opkt->Pibuf.Ilen)) 553*2151Seric putline(npkt,sprintf(line,"%c%c %u\n",CTLCHAR, 554*2151Seric "EDI"[octl->Cctl-OEND], 555*2151Seric rlp[octl->Crel][octl->Clev])); 556*2151Seric else { 557*2151Seric c = (p = octl)[opkt->Pibuf.Ilen]; 558*2151Seric p[opkt->Pibuf.Ilen] = 0; 559*2151Seric putline(npkt,sprintf(line,"%s\n",p)); 560*2151Seric p[opkt->Pibuf.Ilen] = c; 561*2151Seric } 562*2151Seric } 563*2151Seric } 564*2151Seric 565*2151Seric 566*2151Seric octlrec(ctl,len) 567*2151Seric register struct Control *ctl; 568*2151Seric short len; 569*2151Seric { 570*2151Seric register short ch; 571*2151Seric 572*2151Seric if (len==SIZEOFCONTROL && 573*2151Seric ((ch=ctl->Cctl)==OINS || ch==ODEL || ch==OEND)) 574*2151Seric return(1); 575*2151Seric return(0); 576*2151Seric } 577*2151Seric 578*2151Seric 579*2151Seric rdrec(pkt) 580*2151Seric register struct Packet *pkt; 581*2151Seric { 582*2151Seric register n; 583*2151Seric 584*2151Seric if ((n = getr(&pkt->Pibuf)) != 1) 585*2151Seric pkt->Precno++; 586*2151Seric return(n); 587*2151Seric } 588*2151Seric 589*2151Seric 590*2151Seric xwrite(a,b,c) 591*2151Seric { 592*2151Seric return(write(a,b,c)); 593*2151Seric } 594*2151Seric 595*2151Seric 596*2151Seric 597*2151Seric SCCSID(@(#)scv 2.1.1.2); 598*2151Seric 599*2151Seric # define CALL(p,func,cnt) Ffile=p; (*func)(p); cnt++; 600*2151Seric short nfiles; 601*2151Seric char had_dir; 602*2151Seric char had_standinp; 603*2151Seric 604*2151Seric 605*2151Seric odo_file(p,func) 606*2151Seric register char *p; 607*2151Seric short (*func)(); 608*2151Seric { 609*2151Seric extern char *Ffile; 610*2151Seric char str[FILESIZE]; 611*2151Seric char ibuf[FILESIZE]; 612*2151Seric FILE *iop; 613*2151Seric struct dir dir[2]; 614*2151Seric register char *s; 615*2151Seric short fd; 616*2151Seric 617*2151Seric if (p[0] == '-') { 618*2151Seric had_standinp = 1; 619*2151Seric while (gets(ibuf) != NULL) { 620*2151Seric if (osccsfile(ibuf)) { 621*2151Seric CALL(ibuf,func,nfiles); 622*2151Seric } 623*2151Seric } 624*2151Seric } 625*2151Seric else if (exists(p) && (Statbuf.st_mode & S_IFMT) == S_IFDIR) { 626*2151Seric had_dir = 1; 627*2151Seric Ffile = p; 628*2151Seric if((iop = fopen(p,"r")) == NULL) 629*2151Seric return; 630*2151Seric dir[1].d_ino = 0; 631*2151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip "." */ 632*2151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip ".." */ 633*2151Seric while(fread(dir,sizeof(dir[0]),1,iop) == 1) { 634*2151Seric if(dir[0].d_ino == 0) continue; 635*2151Seric sprintf(str,"%s/%s",p,dir[0].d_name); 636*2151Seric if(osccsfile(str)) { 637*2151Seric CALL(str,func,nfiles); 638*2151Seric } 639*2151Seric } 640*2151Seric fclose(iop); 641*2151Seric } 642*2151Seric else { 643*2151Seric CALL(p,func,nfiles); 644*2151Seric } 645*2151Seric } 646*2151Seric 647*2151Seric 648*2151Seric osccsfile(file) 649*2151Seric register char *file; 650*2151Seric { 651*2151Seric register short ff, result; 652*2151Seric short magic[2]; 653*2151Seric 654*2151Seric result = (ff=open(file,0)) > 0 655*2151Seric && read(ff,magic,4) == 4 656*2151Seric && magic[1] == MAGICNO; 657*2151Seric close(ff); 658*2151Seric return(result); 659*2151Seric } 660*2151Seric 661*2151Seric 662*2151Seric 663*2151Seric /* 664*2151Seric Routine to write out either the current line in the packet 665*2151Seric (if newline is zero) or the line specified by newline. 666*2151Seric A line is actually written (and the x-file is only 667*2151Seric opened) if pkt->p_upd is non-zero. When the current line from 668*2151Seric the packet is written, pkt->p_wrttn is set non-zero, and 669*2151Seric further attempts to write it are ignored. When a line is 670*2151Seric read shorto the packet, pkt->p_wrttn must be turned off. 671*2151Seric */ 672*2151Seric 673*2151Seric short Xcreate; 674*2151Seric FILE *Xiop; 675*2151Seric 676*2151Seric 677*2151Seric putline(pkt,newline) 678*2151Seric register struct packet *pkt; 679*2151Seric char *newline; 680*2151Seric { 681*2151Seric static char obf[BUFSIZ]; 682*2151Seric char *xf; 683*2151Seric register char *p; 684*2151Seric 685*2151Seric if(pkt->p_upd == 0) return; 686*2151Seric 687*2151Seric if(!Xcreate) { 688*2151Seric stat(pkt->p_file,&Statbuf); 689*2151Seric xf = auxf(pkt->p_file,'x'); 690*2151Seric Xiop = xfcreat(xf,Statbuf.st_mode); 691*2151Seric setbuf(Xiop,obf); 692*2151Seric chown(xf,(Statbuf.st_gid<<8)|Statbuf.st_uid); 693*2151Seric } 694*2151Seric if (newline) 695*2151Seric p = newline; 696*2151Seric else { 697*2151Seric if(!pkt->p_wrttn++) 698*2151Seric p = pkt->p_line; 699*2151Seric else 700*2151Seric p = 0; 701*2151Seric } 702*2151Seric if (p) { 703*2151Seric fputs(p,Xiop); 704*2151Seric if (Xcreate) 705*2151Seric while (*p) 706*2151Seric pkt->p_nhash =+ *p++; 707*2151Seric } 708*2151Seric Xcreate = 1; 709*2151Seric } 710*2151Seric 711*2151Seric 712*2151Seric convflush(pkt) 713*2151Seric register struct packet *pkt; 714*2151Seric { 715*2151Seric register char *p; 716*2151Seric char hash[6]; 717*2151Seric 718*2151Seric if (pkt->p_upd == 0) 719*2151Seric return; 720*2151Seric putline(pkt,0); 721*2151Seric rewind(Xiop); 722*2151Seric sprintf(hash,"%5u",pkt->p_nhash&0xFFFF); 723*2151Seric zeropad(hash); 724*2151Seric fprintf(Xiop,"%c%c%s\n",CTLCHAR,HEAD,hash); 725*2151Seric fclose(Xiop); 726*2151Seric } 727*2151Seric 728*2151Seric 729*2151Seric xrm(pkt) 730*2151Seric struct packet *pkt; 731*2151Seric { 732*2151Seric if (Xiop) 733*2151Seric fclose(Xiop); 734*2151Seric if(Xcreate) 735*2151Seric unlink(auxf(pkt,'x')); 736*2151Seric Xiop = Xcreate = 0; 737*2151Seric } 738*2151Seric 739*2151Seric 740*2151Seric char bpf[] "bad p-file (216)"; 741*2151Seric 742*2151Seric rdpfile(f,rp,un) 743*2151Seric char f[], un[]; 744*2151Seric short *rp; 745*2151Seric { 746*2151Seric register short fd, i; 747*2151Seric register char *p; 748*2151Seric char s[65], *name; 749*2151Seric 750*2151Seric fd = xopen(f,0); 751*2151Seric if ((i=read(fd,s,64))<=0) 752*2151Seric fatal(bpf); 753*2151Seric close(fd); 754*2151Seric p = s; 755*2151Seric p[i] = 0; 756*2151Seric for (; *p != ' '; p++) 757*2151Seric if (*p == 0) 758*2151Seric fatal(bpf); 759*2151Seric *p = 0; 760*2151Seric if ((*rp=patoi(s)) == -1) 761*2151Seric fatal(bpf); 762*2151Seric ++p; 763*2151Seric while (*p++ == ' ') ; 764*2151Seric name = --p; 765*2151Seric for (; *p != '\n'; p++) 766*2151Seric if (*p == 0) 767*2151Seric fatal(bpf); 768*2151Seric *p = 0; 769*2151Seric if ((p-name)>SZLNAM) 770*2151Seric fatal(bpf); 771*2151Seric copy(name,un); 772*2151Seric } 773*2151Seric 774*2151Seric 775*2151Seric ckpfile(file) 776*2151Seric register char *file; 777*2151Seric { 778*2151Seric short r; 779*2151Seric char un[SZLNAM]; 780*2151Seric 781*2151Seric if(exists(file)) { 782*2151Seric rdpfile(file,&r,un); 783*2151Seric fatal(sprintf(Error,"being edited at release %d by `%s' (scv1)", 784*2151Seric r,un)); 785*2151Seric } 786*2151Seric } 787*2151Seric 788*2151Seric 789*2151Seric /* 790*2151Seric Bottom level read routines for release 3 SCCS files. 791*2151Seric 792*2151Seric Usage: 793*2151Seric struct Ibufr ib; 794*2151Seric ... 795*2151Seric opnr(&ib,"filename"); 796*2151Seric ... 797*2151Seric if(getr(&ib) == 1) [end-of-file]; 798*2151Seric [ib.Irecptr is addr of record (always on word boundary)] 799*2151Seric [ib.Ilen is length] 800*2151Seric 801*2151Seric Address HASHADDR of the file must contain a 1-word stored hash count. 802*2151Seric If this count is non-zero, then on end-of-file a computed hash count 803*2151Seric is compared with it and a fatal error is issued if they aren't equal. 804*2151Seric */ 805*2151Seric 806*2151Seric opnr(buf,file) 807*2151Seric register struct Ibufr *buf; 808*2151Seric char file[]; 809*2151Seric { 810*2151Seric buf->Ifildes = xopen(file,0); 811*2151Seric buf->Irecptr = buf->Ibuff2 + 2; 812*2151Seric buf->Iend = buf->Irecptr + 510; 813*2151Seric buf->Ilen = 510; 814*2151Seric buf->Ibuff3[1] = -128; 815*2151Seric buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0; 816*2151Seric } 817*2151Seric 818*2151Seric 819*2151Seric getr(buf) 820*2151Seric register struct Ibufr *buf; 821*2151Seric { 822*2151Seric register char *p, *q; 823*2151Seric short *w; 824*2151Seric short i, n; 825*2151Seric 826*2151Seric buf->Irecptr =+ buf->Ilen + !(buf->Ilen & 1); 827*2151Seric 828*2151Seric i = 0; 829*2151Seric while(1) { 830*2151Seric buf->Ilen = 0; 831*2151Seric buf->Ilen = *buf->Irecptr + 128; 832*2151Seric 833*2151Seric if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1))) 834*2151Seric return(++buf->Irecptr); 835*2151Seric 836*2151Seric if(i++ == 1) return(1); 837*2151Seric 838*2151Seric q = buf->Irecptr; 839*2151Seric p = buf->Irecptr =- 512; 840*2151Seric 841*2151Seric while(q <= buf->Iend) *p++ = *q++; 842*2151Seric 843*2151Seric if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0) 844*2151Seric return(1); 845*2151Seric 846*2151Seric buf->Iend = buf->Ibuff2 + n - 1; 847*2151Seric *(buf->Iend + 1) = -128; 848*2151Seric 849*2151Seric w = buf->Ibuff2; 850*2151Seric if(buf->Ihflag == 0) { 851*2151Seric buf->Ihflag = 1; 852*2151Seric buf->Ihtot = w[HASHADDR>>1]; 853*2151Seric w[HASHADDR>>1] = 0; 854*2151Seric } 855*2151Seric if(n < 512) buf->Ibuff2[n] = 0; 856*2151Seric 857*2151Seric buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]); 858*2151Seric 859*2151Seric if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot) 860*2151Seric fatal("corrupted file (201)"); 861*2151Seric } 862*2151Seric } 863*2151Seric 864*2151Seric 865*2151Seric sumr(from,to) 866*2151Seric register short *from, *to; 867*2151Seric { 868*2151Seric register short sum; 869*2151Seric 870*2151Seric for (sum=0; from<=to; ) 871*2151Seric sum =+ *from++; 872*2151Seric return(sum); 873*2151Seric } 874