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.2); 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[8]; 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 zero(&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 putline(&npkt,sprintf(line,"%c%c00000\n",CTLCHAR,HEAD),0); 274 statstr[0] = 0; 275 for (n = ndels; n; n--) { 276 if (!statstr[0]) 277 newstats(&npkt,statstr,"?"); 278 else 279 putline(&npkt,statstr); 280 putline(&npkt,del_ba(&dt[n],line)); 281 putline(&npkt,sprintf(line,"%c%c %s\n",CTLCHAR,COMMENTS, 282 hists[n])); 283 putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EDELTAB)); 284 } 285 putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERNAM)); 286 dousers(opkt.Phdr.Hulist,&npkt); 287 putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERNAM)); 288 if (*(p = opkt.Phdr.Htype)) 289 putline(&npkt,sprintf(line,"%c%c %c %s\n",CTLCHAR,FLAG, 290 TYPEFLAG,p)); 291 if (n = opkt.Phdr.Hfloor) 292 putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 293 FLORFLAG,n)); 294 if (n = opkt.Phdr.Hceil) 295 putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 296 CEILFLAG,n)); 297 if (n = opkt.Phdr.Hrdef) 298 putline(&npkt,sprintf(line,"%c%c %c %d\n",CTLCHAR,FLAG, 299 DEFTFLAG,n)); 300 putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,BUSERTXT)); 301 if (*(p = opkt.Phdr.Hpers)) 302 putline(&npkt,sprintf(line,"%s\n",p)); 303 if (*(p = opkt.Phdr.Hdesc)) 304 putline(&npkt,sprintf(line,"%s\n",p)); 305 putline(&npkt,sprintf(line,CTLSTR,CTLCHAR,EUSERTXT)); 306 dobod(&opkt,&npkt,rlp,line); 307 convflush(&npkt); 308 close(opkt.Pibuf.Ifildes); 309 for (n = ndels; n; n--) 310 free(hists[n]); 311 free(hists); 312 free(dt); 313 /* [compiler bug, ignore this for now ] 314 if (rlp) { 315 for (n = (short) (*rlp); n; n--) 316 if (rlp[n]) 317 free(rlp[n]); 318 free(rlp); 319 } 320 */ 321 rename(auxf(npkt.p_file,'x'),npkt.p_file); 322 xrm(&npkt); 323 } 324 325 326 getline() 327 { 328 } 329 330 331 clean_up() 332 { 333 xrm(&npkt); 334 } 335 336 337 338 fixup(dt,ndels,rlp) 339 struct deltab *dt; 340 short ndels; 341 short **rlp; 342 { 343 short m, n; 344 short maxr; 345 short seqcnt; 346 short pred; 347 register struct deltab *p1, *p2; 348 register short *brp; 349 350 for (m = ndels; m; m--) { 351 p1 = &dt[m]; 352 if (p1->d_sid.s_lev > 1) { 353 for (n = m - 1; n; n--) { 354 if (p1->d_sid.s_rel == dt[n].d_sid.s_rel) 355 break; 356 } 357 pred = n; 358 } 359 else { 360 maxr = pred = 0; 361 for (n = m - 1; n; n--) { 362 p2 = &dt[n]; 363 if (p1->d_sid.s_rel > p2->d_sid.s_rel && 364 p2->d_type == 'D' && 365 p2->d_sid.s_rel > maxr) { 366 maxr = p2->d_sid.s_rel; 367 pred = n; 368 } 369 } 370 } 371 p1->d_pred = pred; 372 rlp[p1->d_sid.s_rel][p1->d_sid.s_lev] = m; 373 } 374 brp = alloca(n = (ndels + 1) * sizeof(*brp)); 375 zero(brp,n); 376 for (m = 1; m <= ndels; m++) { 377 p1 = &dt[m]; 378 if (p1->d_type != 'D') { 379 seqcnt = 0; 380 p2 = &dt[p1->d_pred]; 381 p1->d_type = 'D'; 382 p1->d_sid.s_rel = p2->d_sid.s_rel; 383 p1->d_sid.s_lev = p2->d_sid.s_lev; 384 p1->d_sid.s_br = ++brp[p1->d_pred]; 385 p1->d_sid.s_seq = ++seqcnt; 386 pred = m; 387 for (n = m + 1; n <= ndels; n++) { 388 if (dt[n].d_pred == pred) { 389 p2 = &dt[n]; 390 p2->d_type = 'D'; 391 p2->d_sid.s_rel = p1->d_sid.s_rel; 392 p2->d_sid.s_lev = p1->d_sid.s_lev; 393 p2->d_sid.s_br = p1->d_sid.s_br; 394 p2->d_sid.s_seq = ++seqcnt; 395 pred = n; 396 } 397 } 398 } 399 } 400 } 401 402 403 404 struct names { 405 struct names *n_next; 406 char n_name[SZLNAM]; 407 short n_uid; 408 }; 409 410 struct names *names; 411 412 dousers(up,pkt) 413 register char *up; 414 struct packet *pkt; 415 { 416 short i, j; 417 register char mask, c; 418 char *p; 419 char str[16]; 420 421 for (i = 0; i < 32; i++) 422 if (c = *up++) { 423 j = 0; 424 for (mask = 1; mask; mask =<< 1) { 425 if ((c & mask) && (p = getlnam(i * 8 + j))) 426 putline(pkt,sprintf(str,"%s\n",p)); 427 j++; 428 } 429 } 430 } 431 432 433 getlnam(uid) 434 short uid; 435 { 436 char str[128]; 437 register struct names *cur, *prev; 438 register char *p; 439 440 for (cur = &names; cur = (prev = cur)->n_next; ) 441 if (cur->n_uid == uid) 442 return(cur->n_name); 443 if (getpw(uid,str)) 444 return(0); 445 prev->n_next = cur = alloc(sizeof(*cur)); 446 cur->n_next = 0; 447 cur->n_uid = uid; 448 for (p = str; *p++ != ':'; ) 449 ; 450 *--p = 0; 451 str[SZLNAM] = 0; 452 copy(str,cur->n_name); 453 return(cur->n_name); 454 } 455 456 457 458 /* 459 Routine to process the module header. All that's necessary is 460 to slide it shorto the packet. 461 */ 462 463 dohead(pkt) 464 register struct Packet *pkt; 465 { 466 register struct Header *hdr; 467 468 if(rdrec(pkt) == 1) fatal("premature eof (58)"); 469 hdr = pkt->Pibuf.Irecptr; 470 if(hdr->Hmagicno != MAGICNO) fatal("not an SCCS file (53)"); 471 move(hdr,&pkt->Phdr,sizeof(*hdr)); 472 } 473 474 475 doreltab(pkt,rlp) 476 register struct Packet *pkt; 477 register short ***rlp; 478 { 479 short n; 480 short sz; 481 register struct Reltab *rt; 482 483 n = 0; 484 while (rdrec(pkt) != 1 && (rt = pkt->Pibuf.Irecptr)->Rrel) { 485 if (n == 0) { 486 *rlp = alloc(sz = (rt->Rrel + 1) * sizeof(**rlp)); 487 zero(*rlp,sz); 488 **rlp = rt->Rrel; 489 } 490 (*rlp)[rt->Rrel] = alloc((rt->Rlevs + 1) * sizeof(***rlp)); 491 (*rlp)[rt->Rrel][0] = rt->Rlevs; 492 n =+ rt->Rlevs; 493 } 494 return(n); 495 } 496 497 498 dodelt(pkt,dt,hists,ndels) 499 struct Packet *pkt; 500 register struct deltab *dt; 501 char **hists; 502 short ndels; 503 { 504 short n; 505 register struct deltab *ndt; 506 register struct Deltab *odt; 507 508 for (; rdrec(pkt) != 1 && (odt = pkt->Pibuf.Irecptr)->Drel; --ndels) { 509 if (!(odt->Dtype == 'D' || odt->Dtype == 'P' || odt->Dtype == 'U')) { 510 ++ndels; 511 continue; 512 } 513 if (!ndels) 514 return(fatal("internal error in dodeltab")); 515 ndt = &dt[ndels]; 516 ndt->d_type = odt->Dtype; 517 move(odt->Dpgmr,ndt->d_pgmr,sizeof(ndt->d_pgmr)); 518 ndt->d_datetime = (odt->Ddthi<<16)+(unsigned)odt->Ddtlo; 519 ndt->d_sid.s_rel = odt->Drel; 520 ndt->d_sid.s_lev = odt->Dlev; 521 ndt->d_sid.s_br = 0; 522 ndt->d_sid.s_seq = 0; 523 ndt->d_serial = ndels; 524 ndt->d_pred = 0; 525 n = size(odt->Dhist); 526 n++; 527 n =& ~1; 528 if (odt->Dtype == 'P' || odt->Dtype == 'U') { 529 hists[ndels] = alloc(n + 16); 530 sprintf(hists[ndels],"[was %d.%d] ",odt->Drel,odt->Dlev); 531 } 532 else { 533 hists[ndels] = alloc(n); 534 hists[ndels][0] = 0; 535 } 536 move(odt->Dhist,strend(hists[ndels]),n); 537 } 538 if (ndels) { 539 fatal("in dodelt"); 540 } 541 } 542 543 544 dobod(opkt,npkt,rlp,line) 545 struct Packet *opkt; 546 struct packet *npkt; 547 short **rlp; 548 char *line; 549 { 550 register struct Control *octl; 551 register char *p, c; 552 553 while (rdrec(opkt) != 1 && (octl = opkt->Pibuf.Irecptr)->Crel) { 554 if (octlrec(octl,opkt->Pibuf.Ilen)) 555 putline(npkt,sprintf(line,"%c%c %u\n",CTLCHAR, 556 "EDI"[octl->Cctl-OEND], 557 rlp[octl->Crel][octl->Clev])); 558 else { 559 c = (p = octl)[opkt->Pibuf.Ilen]; 560 p[opkt->Pibuf.Ilen] = 0; 561 putline(npkt,sprintf(line,"%s\n",p)); 562 p[opkt->Pibuf.Ilen] = c; 563 } 564 } 565 } 566 567 568 octlrec(ctl,len) 569 register struct Control *ctl; 570 short len; 571 { 572 register short ch; 573 574 if (len==SIZEOFCONTROL && 575 ((ch=ctl->Cctl)==OINS || ch==ODEL || ch==OEND)) 576 return(1); 577 return(0); 578 } 579 580 581 rdrec(pkt) 582 register struct Packet *pkt; 583 { 584 register n; 585 586 if ((n = getr(&pkt->Pibuf)) != 1) 587 pkt->Precno++; 588 return(n); 589 } 590 591 592 xwrite(a,b,c) 593 { 594 return(write(a,b,c)); 595 } 596 597 598 599 SCCSID(@(#)scv 2.1.1.2); 600 601 # define CALL(p,func,cnt) Ffile=p; (*func)(p); cnt++; 602 short nfiles; 603 char had_dir; 604 char had_standinp; 605 606 607 odo_file(p,func) 608 register char *p; 609 short (*func)(); 610 { 611 extern char *Ffile; 612 char str[FILESIZE]; 613 char ibuf[FILESIZE]; 614 FILE *iop; 615 struct dir dir[2]; 616 register char *s; 617 short fd; 618 619 if (p[0] == '-') { 620 had_standinp = 1; 621 while (gets(ibuf) != NULL) { 622 if (osccsfile(ibuf)) { 623 CALL(ibuf,func,nfiles); 624 } 625 } 626 } 627 else if (exists(p) && (Statbuf.st_mode & S_IFMT) == S_IFDIR) { 628 had_dir = 1; 629 Ffile = p; 630 if((iop = fopen(p,"r")) == NULL) 631 return; 632 dir[1].d_ino = 0; 633 fread(dir,sizeof(dir[0]),1,iop); /* skip "." */ 634 fread(dir,sizeof(dir[0]),1,iop); /* skip ".." */ 635 while(fread(dir,sizeof(dir[0]),1,iop) == 1) { 636 if(dir[0].d_ino == 0) continue; 637 sprintf(str,"%s/%s",p,dir[0].d_name); 638 if(osccsfile(str)) { 639 CALL(str,func,nfiles); 640 } 641 } 642 fclose(iop); 643 } 644 else { 645 CALL(p,func,nfiles); 646 } 647 } 648 649 650 osccsfile(file) 651 register char *file; 652 { 653 register short ff, result; 654 short magic[2]; 655 656 result = (ff=open(file,0)) > 0 657 && read(ff,magic,4) == 4 658 && magic[1] == MAGICNO; 659 close(ff); 660 return(result); 661 } 662 663 664 665 /* 666 Routine to write out either the current line in the packet 667 (if newline is zero) or the line specified by newline. 668 A line is actually written (and the x-file is only 669 opened) if pkt->p_upd is non-zero. When the current line from 670 the packet is written, pkt->p_wrttn is set non-zero, and 671 further attempts to write it are ignored. When a line is 672 read shorto the packet, pkt->p_wrttn must be turned off. 673 */ 674 675 short Xcreate; 676 FILE *Xiop; 677 678 679 putline(pkt,newline) 680 register struct packet *pkt; 681 char *newline; 682 { 683 static char obf[BUFSIZ]; 684 char *xf; 685 register char *p; 686 687 if(pkt->p_upd == 0) return; 688 689 if(!Xcreate) { 690 stat(pkt->p_file,&Statbuf); 691 xf = auxf(pkt->p_file,'x'); 692 Xiop = xfcreat(xf,Statbuf.st_mode); 693 setbuf(Xiop,obf); 694 chown(xf,(Statbuf.st_gid<<8)|Statbuf.st_uid); 695 } 696 if (newline) 697 p = newline; 698 else { 699 if(!pkt->p_wrttn++) 700 p = pkt->p_line; 701 else 702 p = 0; 703 } 704 if (p) { 705 fputs(p,Xiop); 706 if (Xcreate) 707 while (*p) 708 pkt->p_nhash =+ *p++; 709 } 710 Xcreate = 1; 711 } 712 713 714 convflush(pkt) 715 register struct packet *pkt; 716 { 717 register char *p; 718 char hash[6]; 719 720 if (pkt->p_upd == 0) 721 return; 722 putline(pkt,0); 723 rewind(Xiop); 724 sprintf(hash,"%5u",pkt->p_nhash&0xFFFF); 725 zeropad(hash); 726 fprintf(Xiop,"%c%c%s\n",CTLCHAR,HEAD,hash); 727 fclose(Xiop); 728 } 729 730 731 xrm(pkt) 732 struct packet *pkt; 733 { 734 if (Xiop) 735 fclose(Xiop); 736 if(Xcreate) 737 unlink(auxf(pkt,'x')); 738 Xiop = Xcreate = 0; 739 } 740 741 742 char bpf[] "bad p-file (216)"; 743 744 rdpfile(f,rp,un) 745 char f[], un[]; 746 short *rp; 747 { 748 register short fd, i; 749 register char *p; 750 char s[65], *name; 751 752 fd = xopen(f,0); 753 if ((i=read(fd,s,64))<=0) 754 fatal(bpf); 755 close(fd); 756 p = s; 757 p[i] = 0; 758 for (; *p != ' '; p++) 759 if (*p == 0) 760 fatal(bpf); 761 *p = 0; 762 if ((*rp=patoi(s)) == -1) 763 fatal(bpf); 764 ++p; 765 while (*p++ == ' ') ; 766 name = --p; 767 for (; *p != '\n'; p++) 768 if (*p == 0) 769 fatal(bpf); 770 *p = 0; 771 if ((p-name)>SZLNAM) 772 fatal(bpf); 773 copy(name,un); 774 } 775 776 777 ckpfile(file) 778 register char *file; 779 { 780 short r; 781 char un[SZLNAM]; 782 783 if(exists(file)) { 784 rdpfile(file,&r,un); 785 fatal(sprintf(Error,"being edited at release %d by `%s' (scv1)", 786 r,un)); 787 } 788 } 789 790 791 /* 792 Bottom level read routines for release 3 SCCS files. 793 794 Usage: 795 struct Ibufr ib; 796 ... 797 opnr(&ib,"filename"); 798 ... 799 if(getr(&ib) == 1) [end-of-file]; 800 [ib.Irecptr is addr of record (always on word boundary)] 801 [ib.Ilen is length] 802 803 Address HASHADDR of the file must contain a 1-word stored hash count. 804 If this count is non-zero, then on end-of-file a computed hash count 805 is compared with it and a fatal error is issued if they aren't equal. 806 */ 807 808 opnr(buf,file) 809 register struct Ibufr *buf; 810 char file[]; 811 { 812 buf->Ifildes = xopen(file,0); 813 buf->Irecptr = buf->Ibuff2 + 2; 814 buf->Iend = buf->Irecptr + 510; 815 buf->Ilen = 510; 816 buf->Ibuff3[1] = -128; 817 buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0; 818 } 819 820 821 getr(buf) 822 register struct Ibufr *buf; 823 { 824 register char *p, *q; 825 short *w; 826 short i, n; 827 828 buf->Irecptr =+ buf->Ilen + !(buf->Ilen & 1); 829 830 i = 0; 831 while(1) { 832 buf->Ilen = 0; 833 buf->Ilen = *buf->Irecptr + 128; 834 835 if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1))) 836 return(++buf->Irecptr); 837 838 if(i++ == 1) return(1); 839 840 q = buf->Irecptr; 841 p = buf->Irecptr =- 512; 842 843 while(q <= buf->Iend) *p++ = *q++; 844 845 if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0) 846 return(1); 847 848 buf->Iend = buf->Ibuff2 + n - 1; 849 *(buf->Iend + 1) = -128; 850 851 w = buf->Ibuff2; 852 if(buf->Ihflag == 0) { 853 buf->Ihflag = 1; 854 buf->Ihtot = w[HASHADDR>>1]; 855 w[HASHADDR>>1] = 0; 856 } 857 if(n < 512) buf->Ibuff2[n] = 0; 858 859 buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]); 860 861 if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot) 862 fatal("corrupted file (201)"); 863 } 864 } 865 866 867 sumr(from,to) 868 register short *from, *to; 869 { 870 register short sum; 871 872 for (sum=0; from<=to; ) 873 sum =+ *from++; 874 return(sum); 875 } 876