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