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 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 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 340 getline() 341 { 342 } 343 344 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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