12151Seric # 22151Seric /* 32151Seric Program to convert release 3 (or release 2 or even 1) SCCS files 42151Seric to release 4 SCCS files. 52151Seric Usage: 62151Seric scv arg ... 72151Seric arg is any argument acceptable as an SCCS file 82151Seric name argument to the get command. E.g.: 92151Seric scv mysccsdir 102151Seric will convert every release 3 (or 2 or 1 but NOT 4) SCCS file in the 112151Seric directory "mysccsdir". 122151Seric */ 132151Seric # include "../hdr/defines.h" 142151Seric # include "dir.h" 152151Seric 16*2160Seric SCCSID(@(#)scv.c 4.2); 172151Seric 18*2160Seric 192151Seric /* 202151Seric Release 3 SCCS File Structures (2.1 78/06/05 17:31:17) 212151Seric See osccsfile(V). 222151Seric */ 232151Seric 242151Seric struct Header { 252151Seric short Hmagicno; 262151Seric char Htype[10]; 272151Seric char Hpers[14]; 282151Seric char Hdesc[100]; 292151Seric short Hfloor; 302151Seric short Hceil; 312151Seric short Hsw[5]; 322151Seric short Hrdef; 332151Seric char Hulist[32]; 342151Seric char Hexpand[50]; 352151Seric short Hash; 362151Seric }; 372151Seric #define MAGICNO (7) 382151Seric #define HASHADDR (226) 392151Seric 402151Seric 412151Seric struct Reltab { 422151Seric short Rrel; 432151Seric short Rlevs; 442151Seric }; 452151Seric 462151Seric 472151Seric struct Deltab { 482151Seric short Drel; 492151Seric short Dlev; 502151Seric char Dtype; /*'D': delta,'P','U': non-prop,'I': incl,'E': excl */ 512151Seric char Dfill; /* Used to be option letter */ 522151Seric /* compiler once forced unfortunate alignment here. 532151Seric /* also, fp-11c high/low long goof strikes again. 542151Seric /* long Ddatetime; 552151Seric */ 562151Seric short Ddthi,Ddtlo; 572151Seric char Dpgmr[8]; 582151Seric char Dhist[200]; 592151Seric }; 602151Seric 612151Seric 622151Seric struct Control { 632151Seric short Crel; 642151Seric short Clev; 652151Seric char Cctl; /* -11: ins, -12: del, -13: end */ 662151Seric }; 672151Seric #define SIZEOFCONTROL (5) 682151Seric #define OINS (-11) 692151Seric #define ODEL (-12) 702151Seric #define OEND (-13) 712151Seric 722151Seric 732151Seric struct Line { 742151Seric char Lline [256]; 752151Seric }; 762151Seric 772151Seric 782151Seric /* 792151Seric Structure for use with buffered I/O routines opnl, opnr, 802151Seric getl and getr. 812151Seric */ 822151Seric struct Ibufr { 832151Seric short Ifildes; 842151Seric char *Irecptr; 852151Seric char *Iend; 862151Seric char Ibuff1[256]; 872151Seric char Ibuff2[512]; 882151Seric char Ibuff3[2]; 892151Seric short Ilen; 902151Seric short Ihflag; 912151Seric short Ihcnt; 922151Seric short Ihtot; 932151Seric }; 942151Seric 952151Seric 962151Seric /* 972151Seric Structure for use with buffered I/O routines crtr, crtl, putl, 982151Seric putr, flshr and buflsh. 992151Seric */ 1002151Seric struct Obufr { 1012151Seric short Ofildes; 1022151Seric char *Orecptr; 1032151Seric char *Oend; 1042151Seric char Obuff1[512]; 1052151Seric short Ohflag; 1062151Seric short Ohcnt; 1072151Seric }; 1082151Seric 1092151Seric 1102151Seric /* 1112151Seric * structure to access an 1122151Seric * shorteger in bytes 1132151Seric */ 1142151Seric struct 1152151Seric { 1162151Seric char lobyte; 1172151Seric char hibyte; 1182151Seric }; 1192151Seric 1202151Seric 1212151Seric /* 1222151Seric * structure to access an shorteger 1232151Seric */ 1242151Seric struct 1252151Seric { 1262151Seric short shorteg; 1272151Seric }; 1282151Seric 1292151Seric 1302151Seric /* 1312151Seric * structure to access a long as shortegers 1322151Seric */ 1332151Seric struct { 1342151Seric short hiword; 1352151Seric short loword; 1362151Seric }; 1372151Seric 1382151Seric 1392151Seric /* 1402151Seric Structure for referencing pieces of localtime(). 1412151Seric */ 1422151Seric struct Time { 1432151Seric short Tseconds; 1442151Seric short Tminutes; 1452151Seric short Thours; 1462151Seric short Tday_month; 1472151Seric short Tmonth; 1482151Seric short Tyear; 1492151Seric short Tday_week; 1502151Seric short Tday_year; 1512151Seric short Tflag; 1522151Seric }; 1532151Seric /* 1542151Seric SCCS Internal Structures (used by get and delta). (2.1) 1552151Seric */ 1562151Seric 1572151Seric struct Apply { 1582151Seric short Adt; /* pseudo date-time */ 1592151Seric short Acode; /* APPLY, NOAPPLY or EMPTY */ 1602151Seric }; 1612151Seric #define APPLY (1) 1622151Seric #define NOAPPLY (-1) 1632151Seric #define EMPTY (0) 1642151Seric 1652151Seric 1662151Seric struct Queue { 1672151Seric struct Queue *Qnext; 1682151Seric short Qrel; /* release */ 1692151Seric short Qlev; /* level */ 1702151Seric short Qdt; /* pseudo date-time */ 1712151Seric short Qkeep; /* keep switch setting */ 1722151Seric }; 1732151Seric #define YES (1) 1742151Seric #define NO (-1) 1752151Seric 1762151Seric #define SIZEOFPfile (50) 1772151Seric 1782151Seric 1792151Seric struct Packet { 1802151Seric char Pfile[SIZEOFPfile]; /* file name containing module */ 1812151Seric /* 1822151Seric Note: the order of the next two words 1832151Seric can not___ be changed! 1842151Seric This is because the release and level together 1852151Seric are treated as a long. 1862151Seric */ 1872151Seric short Prel; /* specified release (-1 = not spec.) */ 1882151Seric short Plev; /* specified level (-1 = not spec.)*/ 1892151Seric char Pverbose; /* verbose flags (see #define's below) */ 1902151Seric char Pupd; /* update flag (!0 = update mode) */ 1912151Seric long Pcutoff; /* specified cutoff date-time */ 1922151Seric struct Header Phdr; /* header from module */ 1932151Seric short Plnno; /* line number of current line */ 1942151Seric short Precno; /* record number of current rec */ 1952151Seric char Pwrttn; /* written flag (!0 = written) */ 1962151Seric char Pkeep; /* keep switch for readmod() */ 1972151Seric struct Apply **Papply; /* ptr to apply array */ 1982151Seric struct Queue *Pq; /* ptr to control queue */ 1992151Seric struct Ibufr Pibuf; /* input buffer */ 2002151Seric long Pcdt; /* date/time of newest applied delta */ 2012151Seric char *Plfile; /* 0 = no l-file; else ptr to l arg */ 2022151Seric char Punack; /* !0 if unacknowledged non-prop deltas */ 2032151Seric char Pnoprop; /* !0 if new delta is to be non-prop */ 2042151Seric short Pirel; /* rel which inserted current rec */ 2052151Seric short Pilev; /* lev which inserted current rec */ 2062151Seric }; 2072151Seric /* 2082151Seric Masks for Pverbose 2092151Seric */ 2102151Seric 2112151Seric # define RLACCESS (1) 2122151Seric # define NLINES (2) 2132151Seric # define DOLIST (4) 2142151Seric # define UNACK (8) 2152151Seric # define NEWRL (16) 2162151Seric # define WARNING (32) 2172151Seric 2182151Seric /* 2192151Seric size of login name 2202151Seric */ 2212151Seric 2222151Seric 2232151Seric USXALLOC(); 2242151Seric 2252151Seric main(argc,argv) 2262151Seric char **argv; 2272151Seric { 2282151Seric register short i; 2292151Seric register char *p; 2302151Seric extern conv(); 2312151Seric extern short Fcnt; 2322151Seric 2332151Seric setsig(); 2342151Seric Fflags = FTLMSG | FTLCLN | FTLJMP; 2352151Seric for (i = 1; i < argc; i++) 2362151Seric if (p = argv[i]) 2372151Seric odo_file(p,conv); 2382151Seric exit(Fcnt ? 1 : 0); 2392151Seric } 2402151Seric 2412151Seric 2422151Seric struct packet npkt; 2432151Seric 2442151Seric conv(ofile) 2452151Seric char *ofile; 2462151Seric { 2472151Seric struct Packet opkt; 2482151Seric struct deltab *dt; 2492151Seric char **hists; 2502151Seric short **rlp; 2512151Seric char statstr[32]; 2522151Seric short ndels; 2532151Seric char *line; 2542151Seric short n; 2552151Seric char *p; 2562151Seric 2572151Seric if (setjmp(Fjmp)) 2582151Seric return; 2592151Seric printf("%s:\n",ofile); 2602151Seric ckpfile(auxf(ofile,'p')); 2612151Seric zero(&opkt,sizeof(opkt)); 2622151Seric opnr(&opkt.Pibuf,ofile); 2632151Seric dohead(&opkt); 2642151Seric rlp = 0; 2652151Seric ndels = doreltab(&opkt,&rlp); 2662151Seric hists = alloc((ndels + 1) * sizeof(*hists)); 2672151Seric dt = alloc((ndels + 1) * sizeof(*dt)); 2682151Seric dodelt(&opkt,dt,hists,ndels); 2692151Seric fixup(dt,ndels,rlp); 2702151Seric sinit(&npkt,ofile,0); 2712151Seric npkt.p_upd = 1; 2722151Seric line = npkt.p_line; 2732151Seric putline(&npkt,sprintf(line,"%c%c00000\n",CTLCHAR,HEAD),0); 2742151Seric statstr[0] = 0; 2752151Seric for (n = ndels; n; n--) { 2762151Seric if (!statstr[0]) 2772151Seric newstats(&npkt,statstr,"?"); 2782151Seric else 2792151Seric putline(&npkt,statstr); 2802151Seric putline(&npkt,del_ba(&dt[n],line)); 2812151Seric putline(&npkt,sprintf(line,"%c%c %s\n",CTLCHAR,COMMENTS, 2822151Seric hists[n])); 2832151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EDELTAB)); 2842151Seric } 2852151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERNAM)); 2862151Seric dousers(opkt.Phdr.Hulist,&npkt); 2872151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERNAM)); 2882151Seric if (*(p = opkt.Phdr.Htype)) 2892151Seric putline(&npkt,sprintf(line,"%c%c %c %s\n",CTLCHAR,FLAG, 2902151Seric TYPEFLAG,p)); 2912151Seric if (n = opkt.Phdr.Hfloor) 2922151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 2932151Seric FLORFLAG,n)); 2942151Seric if (n = opkt.Phdr.Hceil) 2952151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 2962151Seric CEILFLAG,n)); 2972151Seric if (n = opkt.Phdr.Hrdef) 2982151Seric putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 2992151Seric DEFTFLAG,n)); 3002151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERTXT)); 3012151Seric if (*(p = opkt.Phdr.Hpers)) 3022151Seric putline(&npkt,sprintf(line,"%s\n",p)); 3032151Seric if (*(p = opkt.Phdr.Hdesc)) 3042151Seric putline(&npkt,sprintf(line,"%s\n",p)); 3052151Seric putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERTXT)); 3062151Seric dobod(&opkt,&npkt,rlp,line); 3072151Seric convflush(&npkt); 3082151Seric close(opkt.Pibuf.Ifildes); 3092151Seric for (n = ndels; n; n--) 3102151Seric free(hists[n]); 3112151Seric free(hists); 3122151Seric free(dt); 3132151Seric /* [compiler bug, ignore this for now ] 3142151Seric if (rlp) { 3152151Seric for (n = (short) (*rlp); n; n--) 3162151Seric if (rlp[n]) 3172151Seric free(rlp[n]); 3182151Seric free(rlp); 3192151Seric } 3202151Seric */ 3212151Seric rename(auxf(npkt.p_file,'x'),npkt.p_file); 3222151Seric xrm(&npkt); 3232151Seric } 3242151Seric 3252151Seric 3262151Seric getline() 3272151Seric { 3282151Seric } 3292151Seric 3302151Seric 3312151Seric clean_up() 3322151Seric { 3332151Seric xrm(&npkt); 3342151Seric } 3352151Seric 3362151Seric 3372151Seric 3382151Seric fixup(dt,ndels,rlp) 3392151Seric struct deltab *dt; 3402151Seric short ndels; 3412151Seric short **rlp; 3422151Seric { 3432151Seric short m, n; 3442151Seric short maxr; 3452151Seric short seqcnt; 3462151Seric short pred; 3472151Seric register struct deltab *p1, *p2; 3482151Seric register short *brp; 3492151Seric 3502151Seric for (m = ndels; m; m--) { 3512151Seric p1 = &dt[m]; 3522151Seric if (p1->d_sid.s_lev > 1) { 3532151Seric for (n = m - 1; n; n--) { 3542151Seric if (p1->d_sid.s_rel == dt[n].d_sid.s_rel) 3552151Seric break; 3562151Seric } 3572151Seric pred = n; 3582151Seric } 3592151Seric else { 3602151Seric maxr = pred = 0; 3612151Seric for (n = m - 1; n; n--) { 3622151Seric p2 = &dt[n]; 3632151Seric if (p1->d_sid.s_rel > p2->d_sid.s_rel && 3642151Seric p2->d_type == 'D' && 3652151Seric p2->d_sid.s_rel > maxr) { 3662151Seric maxr = p2->d_sid.s_rel; 3672151Seric pred = n; 3682151Seric } 3692151Seric } 3702151Seric } 3712151Seric p1->d_pred = pred; 3722151Seric rlp[p1->d_sid.s_rel][p1->d_sid.s_lev] = m; 3732151Seric } 3742151Seric brp = alloca(n = (ndels + 1) * sizeof(*brp)); 3752151Seric zero(brp,n); 3762151Seric for (m = 1; m <= ndels; m++) { 3772151Seric p1 = &dt[m]; 3782151Seric if (p1->d_type != 'D') { 3792151Seric seqcnt = 0; 3802151Seric p2 = &dt[p1->d_pred]; 3812151Seric p1->d_type = 'D'; 3822151Seric p1->d_sid.s_rel = p2->d_sid.s_rel; 3832151Seric p1->d_sid.s_lev = p2->d_sid.s_lev; 3842151Seric p1->d_sid.s_br = ++brp[p1->d_pred]; 3852151Seric p1->d_sid.s_seq = ++seqcnt; 3862151Seric pred = m; 3872151Seric for (n = m + 1; n <= ndels; n++) { 3882151Seric if (dt[n].d_pred == pred) { 3892151Seric p2 = &dt[n]; 3902151Seric p2->d_type = 'D'; 3912151Seric p2->d_sid.s_rel = p1->d_sid.s_rel; 3922151Seric p2->d_sid.s_lev = p1->d_sid.s_lev; 3932151Seric p2->d_sid.s_br = p1->d_sid.s_br; 3942151Seric p2->d_sid.s_seq = ++seqcnt; 3952151Seric pred = n; 3962151Seric } 3972151Seric } 3982151Seric } 3992151Seric } 4002151Seric } 4012151Seric 4022151Seric 4032151Seric 4042151Seric struct names { 4052151Seric struct names *n_next; 4062151Seric char n_name[SZLNAM]; 4072151Seric short n_uid; 4082151Seric }; 4092151Seric 4102151Seric struct names *names; 4112151Seric 4122151Seric dousers(up,pkt) 4132151Seric register char *up; 4142151Seric struct packet *pkt; 4152151Seric { 4162151Seric short i, j; 4172151Seric register char mask, c; 4182151Seric char *p; 4192151Seric char str[16]; 4202151Seric 4212151Seric for (i = 0; i < 32; i++) 4222151Seric if (c = *up++) { 4232151Seric j = 0; 4242151Seric for (mask = 1; mask; mask =<< 1) { 4252151Seric if ((c & mask) && (p = getlnam(i * 8 + j))) 4262151Seric putline(pkt,sprintf(str,"%s\n",p)); 4272151Seric j++; 4282151Seric } 4292151Seric } 4302151Seric } 4312151Seric 4322151Seric 4332151Seric getlnam(uid) 4342151Seric short uid; 4352151Seric { 4362151Seric char str[128]; 4372151Seric register struct names *cur, *prev; 4382151Seric register char *p; 4392151Seric 4402151Seric for (cur = &names; cur = (prev = cur)->n_next; ) 4412151Seric if (cur->n_uid == uid) 4422151Seric return(cur->n_name); 4432151Seric if (getpw(uid,str)) 4442151Seric return(0); 4452151Seric prev->n_next = cur = alloc(sizeof(*cur)); 4462151Seric cur->n_next = 0; 4472151Seric cur->n_uid = uid; 4482151Seric for (p = str; *p++ != ':'; ) 4492151Seric ; 4502151Seric *--p = 0; 4512151Seric str[SZLNAM] = 0; 4522151Seric copy(str,cur->n_name); 4532151Seric return(cur->n_name); 4542151Seric } 4552151Seric 4562151Seric 4572151Seric 4582151Seric /* 4592151Seric Routine to process the module header. All that's necessary is 4602151Seric to slide it shorto the packet. 4612151Seric */ 4622151Seric 4632151Seric dohead(pkt) 4642151Seric register struct Packet *pkt; 4652151Seric { 4662151Seric register struct Header *hdr; 4672151Seric 4682151Seric if(rdrec(pkt) == 1) fatal("premature eof (58)"); 4692151Seric hdr = pkt->Pibuf.Irecptr; 4702151Seric if(hdr->Hmagicno != MAGICNO) fatal("not an SCCS file (53)"); 4712151Seric move(hdr,&pkt->Phdr,sizeof(*hdr)); 4722151Seric } 4732151Seric 4742151Seric 4752151Seric doreltab(pkt,rlp) 4762151Seric register struct Packet *pkt; 4772151Seric register short ***rlp; 4782151Seric { 4792151Seric short n; 4802151Seric short sz; 4812151Seric register struct Reltab *rt; 4822151Seric 4832151Seric n = 0; 4842151Seric while (rdrec(pkt) != 1 && (rt = pkt->Pibuf.Irecptr)->Rrel) { 4852151Seric if (n == 0) { 4862151Seric *rlp = alloc(sz = (rt->Rrel + 1) * sizeof(**rlp)); 4872151Seric zero(*rlp,sz); 4882151Seric **rlp = rt->Rrel; 4892151Seric } 4902151Seric (*rlp)[rt->Rrel] = alloc((rt->Rlevs + 1) * sizeof(***rlp)); 4912151Seric (*rlp)[rt->Rrel][0] = rt->Rlevs; 4922151Seric n =+ rt->Rlevs; 4932151Seric } 4942151Seric return(n); 4952151Seric } 4962151Seric 4972151Seric 4982151Seric dodelt(pkt,dt,hists,ndels) 4992151Seric struct Packet *pkt; 5002151Seric register struct deltab *dt; 5012151Seric char **hists; 5022151Seric short ndels; 5032151Seric { 5042151Seric short n; 5052151Seric register struct deltab *ndt; 5062151Seric register struct Deltab *odt; 5072151Seric 5082151Seric for (; rdrec(pkt) != 1 && (odt = pkt->Pibuf.Irecptr)->Drel; --ndels) { 5092151Seric if (!(odt->Dtype == 'D' || odt->Dtype == 'P' || odt->Dtype == 'U')) { 5102151Seric ++ndels; 5112151Seric continue; 5122151Seric } 5132151Seric if (!ndels) 5142151Seric return(fatal("internal error in dodeltab")); 5152151Seric ndt = &dt[ndels]; 5162151Seric ndt->d_type = odt->Dtype; 5172151Seric move(odt->Dpgmr,ndt->d_pgmr,sizeof(ndt->d_pgmr)); 5182151Seric ndt->d_datetime = (odt->Ddthi<<16)+(unsigned)odt->Ddtlo; 5192151Seric ndt->d_sid.s_rel = odt->Drel; 5202151Seric ndt->d_sid.s_lev = odt->Dlev; 5212151Seric ndt->d_sid.s_br = 0; 5222151Seric ndt->d_sid.s_seq = 0; 5232151Seric ndt->d_serial = ndels; 5242151Seric ndt->d_pred = 0; 5252151Seric n = size(odt->Dhist); 5262151Seric n++; 5272151Seric n =& ~1; 5282151Seric if (odt->Dtype == 'P' || odt->Dtype == 'U') { 5292151Seric hists[ndels] = alloc(n + 16); 5302151Seric sprintf(hists[ndels],"[was %d.%d] ",odt->Drel,odt->Dlev); 5312151Seric } 5322151Seric else { 5332151Seric hists[ndels] = alloc(n); 5342151Seric hists[ndels][0] = 0; 5352151Seric } 5362151Seric move(odt->Dhist,strend(hists[ndels]),n); 5372151Seric } 5382151Seric if (ndels) { 5392151Seric fatal("in dodelt"); 5402151Seric } 5412151Seric } 5422151Seric 5432151Seric 5442151Seric dobod(opkt,npkt,rlp,line) 5452151Seric struct Packet *opkt; 5462151Seric struct packet *npkt; 5472151Seric short **rlp; 5482151Seric char *line; 5492151Seric { 5502151Seric register struct Control *octl; 5512151Seric register char *p, c; 5522151Seric 5532151Seric while (rdrec(opkt) != 1 && (octl = opkt->Pibuf.Irecptr)->Crel) { 5542151Seric if (octlrec(octl,opkt->Pibuf.Ilen)) 5552151Seric putline(npkt,sprintf(line,"%c%c %u\n",CTLCHAR, 5562151Seric "EDI"[octl->Cctl-OEND], 5572151Seric rlp[octl->Crel][octl->Clev])); 5582151Seric else { 5592151Seric c = (p = octl)[opkt->Pibuf.Ilen]; 5602151Seric p[opkt->Pibuf.Ilen] = 0; 5612151Seric putline(npkt,sprintf(line,"%s\n",p)); 5622151Seric p[opkt->Pibuf.Ilen] = c; 5632151Seric } 5642151Seric } 5652151Seric } 5662151Seric 5672151Seric 5682151Seric octlrec(ctl,len) 5692151Seric register struct Control *ctl; 5702151Seric short len; 5712151Seric { 5722151Seric register short ch; 5732151Seric 5742151Seric if (len==SIZEOFCONTROL && 5752151Seric ((ch=ctl->Cctl)==OINS || ch==ODEL || ch==OEND)) 5762151Seric return(1); 5772151Seric return(0); 5782151Seric } 5792151Seric 5802151Seric 5812151Seric rdrec(pkt) 5822151Seric register struct Packet *pkt; 5832151Seric { 5842151Seric register n; 5852151Seric 5862151Seric if ((n = getr(&pkt->Pibuf)) != 1) 5872151Seric pkt->Precno++; 5882151Seric return(n); 5892151Seric } 5902151Seric 5912151Seric 5922151Seric xwrite(a,b,c) 5932151Seric { 5942151Seric return(write(a,b,c)); 5952151Seric } 5962151Seric 5972151Seric 5982151Seric 5992151Seric SCCSID(@(#)scv 2.1.1.2); 6002151Seric 6012151Seric # define CALL(p,func,cnt) Ffile=p; (*func)(p); cnt++; 6022151Seric short nfiles; 6032151Seric char had_dir; 6042151Seric char had_standinp; 6052151Seric 6062151Seric 6072151Seric odo_file(p,func) 6082151Seric register char *p; 6092151Seric short (*func)(); 6102151Seric { 6112151Seric extern char *Ffile; 6122151Seric char str[FILESIZE]; 6132151Seric char ibuf[FILESIZE]; 6142151Seric FILE *iop; 6152151Seric struct dir dir[2]; 6162151Seric register char *s; 6172151Seric short fd; 6182151Seric 6192151Seric if (p[0] == '-') { 6202151Seric had_standinp = 1; 6212151Seric while (gets(ibuf) != NULL) { 6222151Seric if (osccsfile(ibuf)) { 6232151Seric CALL(ibuf,func,nfiles); 6242151Seric } 6252151Seric } 6262151Seric } 6272151Seric else if (exists(p) && (Statbuf.st_mode & S_IFMT) == S_IFDIR) { 6282151Seric had_dir = 1; 6292151Seric Ffile = p; 6302151Seric if((iop = fopen(p,"r")) == NULL) 6312151Seric return; 6322151Seric dir[1].d_ino = 0; 6332151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip "." */ 6342151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip ".." */ 6352151Seric while(fread(dir,sizeof(dir[0]),1,iop) == 1) { 6362151Seric if(dir[0].d_ino == 0) continue; 6372151Seric sprintf(str,"%s/%s",p,dir[0].d_name); 6382151Seric if(osccsfile(str)) { 6392151Seric CALL(str,func,nfiles); 6402151Seric } 6412151Seric } 6422151Seric fclose(iop); 6432151Seric } 6442151Seric else { 6452151Seric CALL(p,func,nfiles); 6462151Seric } 6472151Seric } 6482151Seric 6492151Seric 6502151Seric osccsfile(file) 6512151Seric register char *file; 6522151Seric { 6532151Seric register short ff, result; 6542151Seric short magic[2]; 6552151Seric 6562151Seric result = (ff=open(file,0)) > 0 6572151Seric && read(ff,magic,4) == 4 6582151Seric && magic[1] == MAGICNO; 6592151Seric close(ff); 6602151Seric return(result); 6612151Seric } 6622151Seric 6632151Seric 6642151Seric 6652151Seric /* 6662151Seric Routine to write out either the current line in the packet 6672151Seric (if newline is zero) or the line specified by newline. 6682151Seric A line is actually written (and the x-file is only 6692151Seric opened) if pkt->p_upd is non-zero. When the current line from 6702151Seric the packet is written, pkt->p_wrttn is set non-zero, and 6712151Seric further attempts to write it are ignored. When a line is 6722151Seric read shorto the packet, pkt->p_wrttn must be turned off. 6732151Seric */ 6742151Seric 6752151Seric short Xcreate; 6762151Seric FILE *Xiop; 6772151Seric 6782151Seric 6792151Seric putline(pkt,newline) 6802151Seric register struct packet *pkt; 6812151Seric char *newline; 6822151Seric { 6832151Seric static char obf[BUFSIZ]; 6842151Seric char *xf; 6852151Seric register char *p; 6862151Seric 6872151Seric if(pkt->p_upd == 0) return; 6882151Seric 6892151Seric if(!Xcreate) { 6902151Seric stat(pkt->p_file,&Statbuf); 6912151Seric xf = auxf(pkt->p_file,'x'); 6922151Seric Xiop = xfcreat(xf,Statbuf.st_mode); 6932151Seric setbuf(Xiop,obf); 6942151Seric chown(xf,(Statbuf.st_gid<<8)|Statbuf.st_uid); 6952151Seric } 6962151Seric if (newline) 6972151Seric p = newline; 6982151Seric else { 6992151Seric if(!pkt->p_wrttn++) 7002151Seric p = pkt->p_line; 7012151Seric else 7022151Seric p = 0; 7032151Seric } 7042151Seric if (p) { 7052151Seric fputs(p,Xiop); 7062151Seric if (Xcreate) 7072151Seric while (*p) 7082151Seric pkt->p_nhash =+ *p++; 7092151Seric } 7102151Seric Xcreate = 1; 7112151Seric } 7122151Seric 7132151Seric 7142151Seric convflush(pkt) 7152151Seric register struct packet *pkt; 7162151Seric { 7172151Seric register char *p; 7182151Seric char hash[6]; 7192151Seric 7202151Seric if (pkt->p_upd == 0) 7212151Seric return; 7222151Seric putline(pkt,0); 7232151Seric rewind(Xiop); 7242151Seric sprintf(hash,"%5u",pkt->p_nhash&0xFFFF); 7252151Seric zeropad(hash); 7262151Seric fprintf(Xiop,"%c%c%s\n",CTLCHAR,HEAD,hash); 7272151Seric fclose(Xiop); 7282151Seric } 7292151Seric 7302151Seric 7312151Seric xrm(pkt) 7322151Seric struct packet *pkt; 7332151Seric { 7342151Seric if (Xiop) 7352151Seric fclose(Xiop); 7362151Seric if(Xcreate) 7372151Seric unlink(auxf(pkt,'x')); 7382151Seric Xiop = Xcreate = 0; 7392151Seric } 7402151Seric 7412151Seric 7422151Seric char bpf[] "bad p-file (216)"; 7432151Seric 7442151Seric rdpfile(f,rp,un) 7452151Seric char f[], un[]; 7462151Seric short *rp; 7472151Seric { 7482151Seric register short fd, i; 7492151Seric register char *p; 7502151Seric char s[65], *name; 7512151Seric 7522151Seric fd = xopen(f,0); 7532151Seric if ((i=read(fd,s,64))<=0) 7542151Seric fatal(bpf); 7552151Seric close(fd); 7562151Seric p = s; 7572151Seric p[i] = 0; 7582151Seric for (; *p != ' '; p++) 7592151Seric if (*p == 0) 7602151Seric fatal(bpf); 7612151Seric *p = 0; 7622151Seric if ((*rp=patoi(s)) == -1) 7632151Seric fatal(bpf); 7642151Seric ++p; 7652151Seric while (*p++ == ' ') ; 7662151Seric name = --p; 7672151Seric for (; *p != '\n'; p++) 7682151Seric if (*p == 0) 7692151Seric fatal(bpf); 7702151Seric *p = 0; 7712151Seric if ((p-name)>SZLNAM) 7722151Seric fatal(bpf); 7732151Seric copy(name,un); 7742151Seric } 7752151Seric 7762151Seric 7772151Seric ckpfile(file) 7782151Seric register char *file; 7792151Seric { 7802151Seric short r; 7812151Seric char un[SZLNAM]; 7822151Seric 7832151Seric if(exists(file)) { 7842151Seric rdpfile(file,&r,un); 7852151Seric fatal(sprintf(Error,"being edited at release %d by `%s' (scv1)", 7862151Seric r,un)); 7872151Seric } 7882151Seric } 7892151Seric 7902151Seric 7912151Seric /* 7922151Seric Bottom level read routines for release 3 SCCS files. 7932151Seric 7942151Seric Usage: 7952151Seric struct Ibufr ib; 7962151Seric ... 7972151Seric opnr(&ib,"filename"); 7982151Seric ... 7992151Seric if(getr(&ib) == 1) [end-of-file]; 8002151Seric [ib.Irecptr is addr of record (always on word boundary)] 8012151Seric [ib.Ilen is length] 8022151Seric 8032151Seric Address HASHADDR of the file must contain a 1-word stored hash count. 8042151Seric If this count is non-zero, then on end-of-file a computed hash count 8052151Seric is compared with it and a fatal error is issued if they aren't equal. 8062151Seric */ 8072151Seric 8082151Seric opnr(buf,file) 8092151Seric register struct Ibufr *buf; 8102151Seric char file[]; 8112151Seric { 8122151Seric buf->Ifildes = xopen(file,0); 8132151Seric buf->Irecptr = buf->Ibuff2 + 2; 8142151Seric buf->Iend = buf->Irecptr + 510; 8152151Seric buf->Ilen = 510; 8162151Seric buf->Ibuff3[1] = -128; 8172151Seric buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0; 8182151Seric } 8192151Seric 8202151Seric 8212151Seric getr(buf) 8222151Seric register struct Ibufr *buf; 8232151Seric { 8242151Seric register char *p, *q; 8252151Seric short *w; 8262151Seric short i, n; 8272151Seric 8282151Seric buf->Irecptr =+ buf->Ilen + !(buf->Ilen & 1); 8292151Seric 8302151Seric i = 0; 8312151Seric while(1) { 8322151Seric buf->Ilen = 0; 8332151Seric buf->Ilen = *buf->Irecptr + 128; 8342151Seric 8352151Seric if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1))) 8362151Seric return(++buf->Irecptr); 8372151Seric 8382151Seric if(i++ == 1) return(1); 8392151Seric 8402151Seric q = buf->Irecptr; 8412151Seric p = buf->Irecptr =- 512; 8422151Seric 8432151Seric while(q <= buf->Iend) *p++ = *q++; 8442151Seric 8452151Seric if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0) 8462151Seric return(1); 8472151Seric 8482151Seric buf->Iend = buf->Ibuff2 + n - 1; 8492151Seric *(buf->Iend + 1) = -128; 8502151Seric 8512151Seric w = buf->Ibuff2; 8522151Seric if(buf->Ihflag == 0) { 8532151Seric buf->Ihflag = 1; 8542151Seric buf->Ihtot = w[HASHADDR>>1]; 8552151Seric w[HASHADDR>>1] = 0; 8562151Seric } 8572151Seric if(n < 512) buf->Ibuff2[n] = 0; 8582151Seric 8592151Seric buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]); 8602151Seric 8612151Seric if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot) 8622151Seric fatal("corrupted file (201)"); 8632151Seric } 8642151Seric } 8652151Seric 8662151Seric 8672151Seric sumr(from,to) 8682151Seric register short *from, *to; 8692151Seric { 8702151Seric register short sum; 8712151Seric 8722151Seric for (sum=0; from<=to; ) 8732151Seric sum =+ *from++; 8742151Seric return(sum); 8752151Seric } 876