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*33423Sbostic SCCSID(@(#)scv.c 4.7);
172151Seric
182160Seric
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;
576173Seric char Dpgmr[SZLNAM];
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
main(argc,argv)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
conv(ofile)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'));
26119943Ssam bzero(&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;
273*33423Sbostic sprintf(line,"%c%c00000\n",CTLCHAR,HEAD);
274*33423Sbostic putline(&npkt,line);
2752151Seric statstr[0] = 0;
2762151Seric for (n = ndels; n; n--) {
2772151Seric if (!statstr[0])
2782151Seric newstats(&npkt,statstr,"?");
2792151Seric else
2802151Seric putline(&npkt,statstr);
2812151Seric putline(&npkt,del_ba(&dt[n],line));
282*33423Sbostic sprintf(line,"%c%c %s\n",CTLCHAR,COMMENTS,hists[n]);
283*33423Sbostic putline(&npkt,line);
284*33423Sbostic sprintf(line,CTLSTR,CTLCHAR,EDELTAB);
285*33423Sbostic putline(&npkt,line);
2862151Seric }
287*33423Sbostic sprintf(line,CTLSTR,CTLCHAR,BUSERNAM);
288*33423Sbostic putline(&npkt,line);
2892151Seric dousers(opkt.Phdr.Hulist,&npkt);
290*33423Sbostic sprintf(line,CTLSTR,CTLCHAR,EUSERNAM);
291*33423Sbostic putline(&npkt,line);
292*33423Sbostic if (*(p = opkt.Phdr.Htype)) {
293*33423Sbostic sprintf(line,"%c%c %c %s\n",CTLCHAR,FLAG,TYPEFLAG,p);
294*33423Sbostic putline(&npkt,line);
295*33423Sbostic }
296*33423Sbostic if (n = opkt.Phdr.Hfloor) {
297*33423Sbostic sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG,FLORFLAG,n);
298*33423Sbostic putline(&npkt,line);
299*33423Sbostic }
300*33423Sbostic if (n = opkt.Phdr.Hceil) {
301*33423Sbostic sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG,CEILFLAG,n);
302*33423Sbostic putline(&npkt,line);
303*33423Sbostic }
304*33423Sbostic if (n = opkt.Phdr.Hrdef) {
305*33423Sbostic sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG,DEFTFLAG,n);
306*33423Sbostic putline(&npkt,line);
307*33423Sbostic }
308*33423Sbostic sprintf(line,CTLSTR,CTLCHAR,BUSERTXT);
309*33423Sbostic putline(&npkt,line);
310*33423Sbostic if (*(p = opkt.Phdr.Hpers)) {
311*33423Sbostic sprintf(line,"%s\n",p);
312*33423Sbostic putline(&npkt,line);
313*33423Sbostic }
314*33423Sbostic if (*(p = opkt.Phdr.Hdesc)) {
315*33423Sbostic sprintf(line,"%s\n",p);
316*33423Sbostic putline(&npkt,line);
317*33423Sbostic }
318*33423Sbostic sprintf(line,CTLSTR,CTLCHAR,EUSERTXT);
319*33423Sbostic putline(&npkt,line);
3202151Seric dobod(&opkt,&npkt,rlp,line);
3212151Seric convflush(&npkt);
3222151Seric close(opkt.Pibuf.Ifildes);
3232151Seric for (n = ndels; n; n--)
3242151Seric free(hists[n]);
3252151Seric free(hists);
3262151Seric free(dt);
3272151Seric /* [compiler bug, ignore this for now ]
3282151Seric if (rlp) {
3292151Seric for (n = (short) (*rlp); n; n--)
3302151Seric if (rlp[n])
3312151Seric free(rlp[n]);
3322151Seric free(rlp);
3332151Seric }
3342151Seric */
3352151Seric rename(auxf(npkt.p_file,'x'),npkt.p_file);
3362151Seric xrm(&npkt);
3372151Seric }
3382151Seric
3392151Seric
getline()3402151Seric getline()
3412151Seric {
3422151Seric }
3432151Seric
3442151Seric
clean_up()3452151Seric clean_up()
3462151Seric {
3472151Seric xrm(&npkt);
3482151Seric }
3492151Seric
3502151Seric
3512151Seric
3522151Seric fixup(dt,ndels,rlp)
3532151Seric struct deltab *dt;
3542151Seric short ndels;
3552151Seric short **rlp;
3562151Seric {
3572151Seric short m, n;
3582151Seric short maxr;
3592151Seric short seqcnt;
3602151Seric short pred;
3612151Seric register struct deltab *p1, *p2;
3622151Seric register short *brp;
3632151Seric
3642151Seric for (m = ndels; m; m--) {
3652151Seric p1 = &dt[m];
3662151Seric if (p1->d_sid.s_lev > 1) {
3672151Seric for (n = m - 1; n; n--) {
3682151Seric if (p1->d_sid.s_rel == dt[n].d_sid.s_rel)
3692151Seric break;
3702151Seric }
3712151Seric pred = n;
3722151Seric }
3732151Seric else {
3742151Seric maxr = pred = 0;
3752151Seric for (n = m - 1; n; n--) {
3762151Seric p2 = &dt[n];
3772151Seric if (p1->d_sid.s_rel > p2->d_sid.s_rel &&
3782151Seric p2->d_type == 'D' &&
3792151Seric p2->d_sid.s_rel > maxr) {
3802151Seric maxr = p2->d_sid.s_rel;
3812151Seric pred = n;
3822151Seric }
3832151Seric }
3842151Seric }
3852151Seric p1->d_pred = pred;
3862151Seric rlp[p1->d_sid.s_rel][p1->d_sid.s_lev] = m;
3872151Seric }
3882151Seric brp = alloca(n = (ndels + 1) * sizeof(*brp));
38919943Ssam bzero(brp,n);
3902151Seric for (m = 1; m <= ndels; m++) {
3912151Seric p1 = &dt[m];
3922151Seric if (p1->d_type != 'D') {
3932151Seric seqcnt = 0;
3942151Seric p2 = &dt[p1->d_pred];
3952151Seric p1->d_type = 'D';
3962151Seric p1->d_sid.s_rel = p2->d_sid.s_rel;
3972151Seric p1->d_sid.s_lev = p2->d_sid.s_lev;
3982151Seric p1->d_sid.s_br = ++brp[p1->d_pred];
3992151Seric p1->d_sid.s_seq = ++seqcnt;
4002151Seric pred = m;
4012151Seric for (n = m + 1; n <= ndels; n++) {
4022151Seric if (dt[n].d_pred == pred) {
4032151Seric p2 = &dt[n];
4042151Seric p2->d_type = 'D';
4052151Seric p2->d_sid.s_rel = p1->d_sid.s_rel;
4062151Seric p2->d_sid.s_lev = p1->d_sid.s_lev;
4072151Seric p2->d_sid.s_br = p1->d_sid.s_br;
4082151Seric p2->d_sid.s_seq = ++seqcnt;
4092151Seric pred = n;
4102151Seric }
4112151Seric }
4122151Seric }
4132151Seric }
4142151Seric }
4152151Seric
4162151Seric
4172151Seric
4182151Seric struct names {
4192151Seric struct names *n_next;
4202151Seric char n_name[SZLNAM];
4212151Seric short n_uid;
4222151Seric };
4232151Seric
4242151Seric struct names *names;
4252151Seric
dousers(up,pkt)4262151Seric dousers(up,pkt)
4272151Seric register char *up;
4282151Seric struct packet *pkt;
4292151Seric {
4302151Seric short i, j;
4312151Seric register char mask, c;
4322151Seric char *p;
4332151Seric char str[16];
4342151Seric
4352151Seric for (i = 0; i < 32; i++)
4362151Seric if (c = *up++) {
4372151Seric j = 0;
43832772Sbostic for (mask = 1; mask; mask <<= 1) {
439*33423Sbostic if ((c & mask) && (p = getlnam(i * SZLNAM + j))) {
440*33423Sbostic sprintf(str,"%s\n",p);
441*33423Sbostic putline(pkt,str);
442*33423Sbostic }
4432151Seric j++;
4442151Seric }
4452151Seric }
4462151Seric }
4472151Seric
4482151Seric
getlnam(uid)4492151Seric getlnam(uid)
4502151Seric short uid;
4512151Seric {
4522151Seric char str[128];
4532151Seric register struct names *cur, *prev;
4542151Seric register char *p;
4552151Seric
4562151Seric for (cur = &names; cur = (prev = cur)->n_next; )
4572151Seric if (cur->n_uid == uid)
4582151Seric return(cur->n_name);
4592151Seric if (getpw(uid,str))
4602151Seric return(0);
4612151Seric prev->n_next = cur = alloc(sizeof(*cur));
4622151Seric cur->n_next = 0;
4632151Seric cur->n_uid = uid;
4642151Seric for (p = str; *p++ != ':'; )
4652151Seric ;
4662151Seric *--p = 0;
4672151Seric str[SZLNAM] = 0;
4682151Seric copy(str,cur->n_name);
4692151Seric return(cur->n_name);
4702151Seric }
4712151Seric
4722151Seric
4732151Seric
4742151Seric /*
4752151Seric Routine to process the module header. All that's necessary is
4762151Seric to slide it shorto the packet.
4772151Seric */
4782151Seric
dohead(pkt)4792151Seric dohead(pkt)
4802151Seric register struct Packet *pkt;
4812151Seric {
4822151Seric register struct Header *hdr;
4832151Seric
4842151Seric if(rdrec(pkt) == 1) fatal("premature eof (58)");
4852151Seric hdr = pkt->Pibuf.Irecptr;
4862151Seric if(hdr->Hmagicno != MAGICNO) fatal("not an SCCS file (53)");
48719943Ssam bcopy(hdr,&pkt->Phdr,sizeof(*hdr));
4882151Seric }
4892151Seric
4902151Seric
doreltab(pkt,rlp)4912151Seric doreltab(pkt,rlp)
4922151Seric register struct Packet *pkt;
4932151Seric register short ***rlp;
4942151Seric {
4952151Seric short n;
4962151Seric short sz;
4972151Seric register struct Reltab *rt;
4982151Seric
4992151Seric n = 0;
5002151Seric while (rdrec(pkt) != 1 && (rt = pkt->Pibuf.Irecptr)->Rrel) {
5012151Seric if (n == 0) {
5022151Seric *rlp = alloc(sz = (rt->Rrel + 1) * sizeof(**rlp));
50319943Ssam bzero(*rlp,sz);
5042151Seric **rlp = rt->Rrel;
5052151Seric }
5062151Seric (*rlp)[rt->Rrel] = alloc((rt->Rlevs + 1) * sizeof(***rlp));
5072151Seric (*rlp)[rt->Rrel][0] = rt->Rlevs;
50832772Sbostic n += rt->Rlevs;
5092151Seric }
5102151Seric return(n);
5112151Seric }
5122151Seric
5132151Seric
5142151Seric dodelt(pkt,dt,hists,ndels)
5152151Seric struct Packet *pkt;
5162151Seric register struct deltab *dt;
5172151Seric char **hists;
5182151Seric short ndels;
5192151Seric {
5202151Seric short n;
5212151Seric register struct deltab *ndt;
5222151Seric register struct Deltab *odt;
5232151Seric
5242151Seric for (; rdrec(pkt) != 1 && (odt = pkt->Pibuf.Irecptr)->Drel; --ndels) {
5252151Seric if (!(odt->Dtype == 'D' || odt->Dtype == 'P' || odt->Dtype == 'U')) {
5262151Seric ++ndels;
5272151Seric continue;
5282151Seric }
5292151Seric if (!ndels)
5302151Seric return(fatal("internal error in dodeltab"));
5312151Seric ndt = &dt[ndels];
5322151Seric ndt->d_type = odt->Dtype;
53319943Ssam bcopy(odt->Dpgmr,ndt->d_pgmr,sizeof(ndt->d_pgmr));
5342151Seric ndt->d_datetime = (odt->Ddthi<<16)+(unsigned)odt->Ddtlo;
5352151Seric ndt->d_sid.s_rel = odt->Drel;
5362151Seric ndt->d_sid.s_lev = odt->Dlev;
5372151Seric ndt->d_sid.s_br = 0;
5382151Seric ndt->d_sid.s_seq = 0;
5392151Seric ndt->d_serial = ndels;
5402151Seric ndt->d_pred = 0;
5412151Seric n = size(odt->Dhist);
5422151Seric n++;
54332772Sbostic n &= ~1;
5442151Seric if (odt->Dtype == 'P' || odt->Dtype == 'U') {
5452151Seric hists[ndels] = alloc(n + 16);
5462151Seric sprintf(hists[ndels],"[was %d.%d] ",odt->Drel,odt->Dlev);
5472151Seric }
5482151Seric else {
5492151Seric hists[ndels] = alloc(n);
5502151Seric hists[ndels][0] = 0;
5512151Seric }
55219943Ssam bcopy(odt->Dhist,index(hists[ndels], '\0'),n);
5532151Seric }
5542151Seric if (ndels) {
5552151Seric fatal("in dodelt");
5562151Seric }
5572151Seric }
5582151Seric
5592151Seric
5602151Seric dobod(opkt,npkt,rlp,line)
5612151Seric struct Packet *opkt;
5622151Seric struct packet *npkt;
5632151Seric short **rlp;
5642151Seric char *line;
5652151Seric {
5662151Seric register struct Control *octl;
5672151Seric register char *p, c;
5682151Seric
5692151Seric while (rdrec(opkt) != 1 && (octl = opkt->Pibuf.Irecptr)->Crel) {
570*33423Sbostic if (octlrec(octl,opkt->Pibuf.Ilen)) {
571*33423Sbostic sprintf(line,"%c%c %u\n",CTLCHAR,"EDI"[octl->Cctl-OEND],rlp[octl->Crel][octl->Clev]);
572*33423Sbostic putline(npkt,line);
573*33423Sbostic }
5742151Seric else {
5752151Seric c = (p = octl)[opkt->Pibuf.Ilen];
5762151Seric p[opkt->Pibuf.Ilen] = 0;
577*33423Sbostic sprintf(line,"%s\n",p);
578*33423Sbostic putline(npkt,line);
5792151Seric p[opkt->Pibuf.Ilen] = c;
5802151Seric }
5812151Seric }
5822151Seric }
5832151Seric
5842151Seric
octlrec(ctl,len)5852151Seric octlrec(ctl,len)
5862151Seric register struct Control *ctl;
5872151Seric short len;
5882151Seric {
5892151Seric register short ch;
5902151Seric
5912151Seric if (len==SIZEOFCONTROL &&
5922151Seric ((ch=ctl->Cctl)==OINS || ch==ODEL || ch==OEND))
5932151Seric return(1);
5942151Seric return(0);
5952151Seric }
5962151Seric
5972151Seric
rdrec(pkt)5982151Seric rdrec(pkt)
5992151Seric register struct Packet *pkt;
6002151Seric {
6012151Seric register n;
6022151Seric
6032151Seric if ((n = getr(&pkt->Pibuf)) != 1)
6042151Seric pkt->Precno++;
6052151Seric return(n);
6062151Seric }
6072151Seric
6082151Seric
xwrite(a,b,c)6092151Seric xwrite(a,b,c)
6102151Seric {
6112151Seric return(write(a,b,c));
6122151Seric }
6132151Seric
6142151Seric
6152151Seric
6162151Seric
6172151Seric # define CALL(p,func,cnt) Ffile=p; (*func)(p); cnt++;
6182151Seric short nfiles;
6192151Seric char had_dir;
6202151Seric char had_standinp;
6212151Seric
6222151Seric
odo_file(p,func)6232151Seric odo_file(p,func)
6242151Seric register char *p;
6252151Seric short (*func)();
6262151Seric {
6272151Seric extern char *Ffile;
6282151Seric char str[FILESIZE];
6292151Seric char ibuf[FILESIZE];
6302151Seric FILE *iop;
6312151Seric struct dir dir[2];
6322151Seric register char *s;
6332151Seric short fd;
6342151Seric
6352151Seric if (p[0] == '-') {
6362151Seric had_standinp = 1;
6372151Seric while (gets(ibuf) != NULL) {
6382151Seric if (osccsfile(ibuf)) {
6392151Seric CALL(ibuf,func,nfiles);
6402151Seric }
6412151Seric }
6422151Seric }
6432151Seric else if (exists(p) && (Statbuf.st_mode & S_IFMT) == S_IFDIR) {
6442151Seric had_dir = 1;
6452151Seric Ffile = p;
6462151Seric if((iop = fopen(p,"r")) == NULL)
6472151Seric return;
6482151Seric dir[1].d_ino = 0;
6492151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip "." */
6502151Seric fread(dir,sizeof(dir[0]),1,iop); /* skip ".." */
6512151Seric while(fread(dir,sizeof(dir[0]),1,iop) == 1) {
6522151Seric if(dir[0].d_ino == 0) continue;
6532151Seric sprintf(str,"%s/%s",p,dir[0].d_name);
6542151Seric if(osccsfile(str)) {
6552151Seric CALL(str,func,nfiles);
6562151Seric }
6572151Seric }
6582151Seric fclose(iop);
6592151Seric }
6602151Seric else {
6612151Seric CALL(p,func,nfiles);
6622151Seric }
6632151Seric }
6642151Seric
6652151Seric
osccsfile(file)6662151Seric osccsfile(file)
6672151Seric register char *file;
6682151Seric {
6692151Seric register short ff, result;
6702151Seric short magic[2];
6712151Seric
6722151Seric result = (ff=open(file,0)) > 0
6732151Seric && read(ff,magic,4) == 4
6742151Seric && magic[1] == MAGICNO;
6752151Seric close(ff);
6762151Seric return(result);
6772151Seric }
6782151Seric
6792151Seric
6802151Seric
6812151Seric /*
6822151Seric Routine to write out either the current line in the packet
6832151Seric (if newline is zero) or the line specified by newline.
6842151Seric A line is actually written (and the x-file is only
6852151Seric opened) if pkt->p_upd is non-zero. When the current line from
6862151Seric the packet is written, pkt->p_wrttn is set non-zero, and
6872151Seric further attempts to write it are ignored. When a line is
6882151Seric read shorto the packet, pkt->p_wrttn must be turned off.
6892151Seric */
6902151Seric
6912151Seric short Xcreate;
6922151Seric FILE *Xiop;
6932151Seric
6942151Seric
putline(pkt,newline)6952151Seric putline(pkt,newline)
6962151Seric register struct packet *pkt;
6972151Seric char *newline;
6982151Seric {
6992151Seric static char obf[BUFSIZ];
7002151Seric char *xf;
7012151Seric register char *p;
7022151Seric
7032151Seric if(pkt->p_upd == 0) return;
7042151Seric
7052151Seric if(!Xcreate) {
7062151Seric stat(pkt->p_file,&Statbuf);
7072151Seric xf = auxf(pkt->p_file,'x');
7082151Seric Xiop = xfcreat(xf,Statbuf.st_mode);
7092151Seric setbuf(Xiop,obf);
7102151Seric chown(xf,(Statbuf.st_gid<<8)|Statbuf.st_uid);
7112151Seric }
7122151Seric if (newline)
7132151Seric p = newline;
7142151Seric else {
7152151Seric if(!pkt->p_wrttn++)
7162151Seric p = pkt->p_line;
7172151Seric else
7182151Seric p = 0;
7192151Seric }
7202151Seric if (p) {
7212151Seric fputs(p,Xiop);
7222151Seric if (Xcreate)
7232151Seric while (*p)
72432772Sbostic pkt->p_nhash += *p++;
7252151Seric }
7262151Seric Xcreate = 1;
7272151Seric }
7282151Seric
7292151Seric
convflush(pkt)7302151Seric convflush(pkt)
7312151Seric register struct packet *pkt;
7322151Seric {
7332151Seric register char *p;
7342151Seric char hash[6];
7352151Seric
7362151Seric if (pkt->p_upd == 0)
7372151Seric return;
7382151Seric putline(pkt,0);
7392151Seric rewind(Xiop);
7402151Seric sprintf(hash,"%5u",pkt->p_nhash&0xFFFF);
7412151Seric zeropad(hash);
7422151Seric fprintf(Xiop,"%c%c%s\n",CTLCHAR,HEAD,hash);
7432151Seric fclose(Xiop);
7442151Seric }
7452151Seric
7462151Seric
7472151Seric xrm(pkt)
7482151Seric struct packet *pkt;
7492151Seric {
7502151Seric if (Xiop)
7512151Seric fclose(Xiop);
7522151Seric if(Xcreate)
7532151Seric unlink(auxf(pkt,'x'));
7542151Seric Xiop = Xcreate = 0;
7552151Seric }
7562151Seric
7572151Seric
7582151Seric char bpf[] "bad p-file (216)";
7592151Seric
rdpfile(f,rp,un)7602151Seric rdpfile(f,rp,un)
7612151Seric char f[], un[];
7622151Seric short *rp;
7632151Seric {
7642151Seric register short fd, i;
7652151Seric register char *p;
7662151Seric char s[65], *name;
7672151Seric
7682151Seric fd = xopen(f,0);
7692151Seric if ((i=read(fd,s,64))<=0)
7702151Seric fatal(bpf);
7712151Seric close(fd);
7722151Seric p = s;
7732151Seric p[i] = 0;
7742151Seric for (; *p != ' '; p++)
7752151Seric if (*p == 0)
7762151Seric fatal(bpf);
7772151Seric *p = 0;
7782151Seric if ((*rp=patoi(s)) == -1)
7792151Seric fatal(bpf);
7802151Seric ++p;
7812151Seric while (*p++ == ' ') ;
7822151Seric name = --p;
7832151Seric for (; *p != '\n'; p++)
7842151Seric if (*p == 0)
7852151Seric fatal(bpf);
7862151Seric *p = 0;
7872151Seric if ((p-name)>SZLNAM)
7882151Seric fatal(bpf);
7892151Seric copy(name,un);
7902151Seric }
7912151Seric
7922151Seric
ckpfile(file)7932151Seric ckpfile(file)
7942151Seric register char *file;
7952151Seric {
7962151Seric short r;
7972151Seric char un[SZLNAM];
7982151Seric
7992151Seric if(exists(file)) {
8002151Seric rdpfile(file,&r,un);
801*33423Sbostic sprintf(Error,"being edited at release %d by `%s' (scv1)",r,un));
802*33423Sbostic fatal(Error);
8032151Seric }
8042151Seric }
8052151Seric
8062151Seric
8072151Seric /*
8082151Seric Bottom level read routines for release 3 SCCS files.
8092151Seric
8102151Seric Usage:
8112151Seric struct Ibufr ib;
8122151Seric ...
8132151Seric opnr(&ib,"filename");
8142151Seric ...
8152151Seric if(getr(&ib) == 1) [end-of-file];
8162151Seric [ib.Irecptr is addr of record (always on word boundary)]
8172151Seric [ib.Ilen is length]
8182151Seric
8192151Seric Address HASHADDR of the file must contain a 1-word stored hash count.
8202151Seric If this count is non-zero, then on end-of-file a computed hash count
8212151Seric is compared with it and a fatal error is issued if they aren't equal.
8222151Seric */
8232151Seric
opnr(buf,file)8242151Seric opnr(buf,file)
8252151Seric register struct Ibufr *buf;
8262151Seric char file[];
8272151Seric {
8282151Seric buf->Ifildes = xopen(file,0);
8292151Seric buf->Irecptr = buf->Ibuff2 + 2;
8302151Seric buf->Iend = buf->Irecptr + 510;
8312151Seric buf->Ilen = 510;
8322151Seric buf->Ibuff3[1] = -128;
8332151Seric buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0;
8342151Seric }
8352151Seric
8362151Seric
getr(buf)8372151Seric getr(buf)
8382151Seric register struct Ibufr *buf;
8392151Seric {
8402151Seric register char *p, *q;
8412151Seric short *w;
8422151Seric short i, n;
8432151Seric
84432772Sbostic buf->Irecptr += buf->Ilen + !(buf->Ilen & 1);
8452151Seric
8462151Seric i = 0;
8472151Seric while(1) {
8482151Seric buf->Ilen = 0;
8492151Seric buf->Ilen = *buf->Irecptr + 128;
8502151Seric
8512151Seric if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1)))
8522151Seric return(++buf->Irecptr);
8532151Seric
8542151Seric if(i++ == 1) return(1);
8552151Seric
8562151Seric q = buf->Irecptr;
85732772Sbostic p = buf->Irecptr -= 512;
8582151Seric
8592151Seric while(q <= buf->Iend) *p++ = *q++;
8602151Seric
8612151Seric if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0)
8622151Seric return(1);
8632151Seric
8642151Seric buf->Iend = buf->Ibuff2 + n - 1;
8652151Seric *(buf->Iend + 1) = -128;
8662151Seric
8672151Seric w = buf->Ibuff2;
8682151Seric if(buf->Ihflag == 0) {
8692151Seric buf->Ihflag = 1;
8702151Seric buf->Ihtot = w[HASHADDR>>1];
8712151Seric w[HASHADDR>>1] = 0;
8722151Seric }
8732151Seric if(n < 512) buf->Ibuff2[n] = 0;
8742151Seric
87532772Sbostic buf->Ihcnt += sumr(w,&w[(n&1?n-1:n-2)>>1]);
8762151Seric
8772151Seric if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot)
8782151Seric fatal("corrupted file (201)");
8792151Seric }
8802151Seric }
8812151Seric
8822151Seric
sumr(from,to)8832151Seric sumr(from,to)
8842151Seric register short *from, *to;
8852151Seric {
8862151Seric register short sum;
8872151Seric
8882151Seric for (sum=0; from<=to; )
88932772Sbostic sum += *from++;
8902151Seric return(sum);
8912151Seric }
892