1 static char *sccsid = "@(#)arff.c 4.7 (Berkeley) 81/07/08"; 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <time.h> 5 #include <signal.h> 6 #include <stdio.h> 7 #define dbprintf printf 8 struct rt_dat { 9 unsigned short int rt_yr:5; /* Year - 1972 */ 10 unsigned short int rt_dy:5; /* day */ 11 unsigned short int rt_mo:5; /* month */ 12 }; 13 struct rt_axent { 14 char rt_sent[14]; 15 }; 16 17 struct rt_ent { 18 char rt_pad; /* unusued */ 19 char rt_stat; /* Type of entry, or end of seg */ 20 unsigned short rt_name[3]; /* Name, 3 words in rad50 form */ 21 short rt_len; /* Length of file */ 22 char rt_chan; /* Only used in temporary files */ 23 char rt_job; /* Only used in temporary files */ 24 struct rt_dat rt_date; /* Creation Date */ 25 }; 26 #define RT_TEMP 1 27 #define RT_NULL 2 28 #define RT_FILE 4 29 #define RT_ESEG 8 30 #define RT_BLOCK 512 31 #define RT_DIRSIZE 31 /* max # of directory segments */ 32 struct rt_head { 33 short rt_numseg; /* number of segments available */ 34 short rt_nxtseg; /* segment no of next log. seg */ 35 short rt_lstseg; /* highest seg currenltly open */ 36 unsigned short rt_entpad; /* extra words/dir. entry */ 37 short rt_stfile; /* block no where files begin */ 38 }; 39 struct rt_dir { 40 struct rt_head rt_axhead; 41 struct rt_ent rt_ents[72]; 42 char _dirpad[6]; 43 }; 44 extern struct rt_dir rt_dir[RT_DIRSIZE]; 45 extern int rt_entsiz; 46 extern int floppydes; 47 extern char *rt_last; 48 typedef struct fldope { 49 int startad; 50 int count; 51 struct rt_ent *rtdope; 52 } FLDOPE; 53 FLDOPE *lookup(); 54 #define rt(p) ((struct rt_ent *) p ) 55 #define Ain1 03100 56 #define Ain2 050 57 #define flag(c) (flg[(c) - 'a']) 58 59 char *man = { "rxtd" }; 60 61 char zeroes[512]; 62 extern char *val; 63 extern char table[256]; 64 struct rt_dir 65 rt_dir[RT_DIRSIZE] = {{{4,0,1,0,14},{0,RT_NULL,{0,0,0},494,0}, {0,RT_ESEG}}}; 66 int rt_entsiz; 67 int rt_nleft; 68 struct rt_ent *rt_curend[RT_DIRSIZE]; 69 int floppydes; 70 int dirdirty; 71 char *rt_last; 72 char *defdev = "/dev/floppy"; 73 74 char *opt = { "vf" }; 75 76 int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 77 long lseek(); 78 int rcmd(); 79 int dcmd(); 80 int xcmd(); 81 int tcmd(); 82 int (*comfun)(); 83 char flg[26]; 84 char **namv; 85 int namc; 86 int file; 87 88 89 main(argc, argv) 90 char *argv[]; 91 { 92 register char *cp; 93 94 /* register i; 95 for(i=0; signum[i]; i++) 96 if(signal(signum[i], SIG_IGN) != SIG_IGN) 97 signal(signum[i], sigdone); */ 98 if(argc < 2) 99 usage(); 100 cp = argv[1]; 101 for(cp = argv[1]; *cp; cp++) 102 switch(*cp) { 103 case 'm': 104 case 'v': 105 case 'u': 106 case 'w': 107 flg[*cp - 'a']++; 108 continue; 109 case 'c': 110 { 111 #define SURE "Are you sure you want to clobber the floppy?\n" 112 int tty; 113 char response[128]; 114 tty = open("/dev/tty",2); 115 write(tty,SURE,sizeof(SURE)); 116 read(tty,response,sizeof(response)); 117 if(*response!='y') 118 exit(50); 119 flag('c')++; 120 close(tty); 121 } 122 dirdirty++; 123 continue; 124 125 case 'r': 126 setcom(rcmd); 127 flag('r')++; 128 continue; 129 130 case 'd': 131 setcom(dcmd); 132 flag('d')++; 133 continue; 134 135 case 'x': 136 setcom(xcmd); 137 continue; 138 139 case 't': 140 setcom(tcmd); 141 continue; 142 143 case 'f': 144 defdev = argv[2]; 145 argv++; 146 argc--; 147 continue; 148 149 150 default: 151 fprintf(stderr, "arff: bad option `%c'\n", *cp); 152 exit(1); 153 } 154 namv = argv+2; 155 namc = argc-2; 156 if(comfun == 0) { 157 if(flg['u'-'a'] == 0) { 158 fprintf(stderr, "arff: one of [%s] must be specified\n", man); 159 exit(1); 160 } 161 setcom(rcmd); 162 } 163 (*comfun)(); 164 exit(notfound()); 165 } 166 167 setcom(fun) 168 int (*fun)(); 169 { 170 171 if(comfun != 0) { 172 fprintf(stderr, "arff: only one of [%s] allowed\n", man); 173 exit(1); 174 } 175 comfun = fun; 176 } 177 178 usage() 179 { 180 181 fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 182 exit(1); 183 } 184 185 notfound() 186 { 187 register i, n; 188 189 n = 0; 190 for(i=0; i<namc; i++) 191 if(namv[i]) { 192 fprintf(stderr, "arff: %s not found\n", namv[i]); 193 n++; 194 } 195 return(n); 196 } 197 198 phserr() 199 { 200 201 fprintf(stderr, "arff: phase error on %s\n", file); 202 } 203 204 mesg(c) 205 { 206 207 if(flg['v'-'a']) 208 if(c != 'c' || flg['v'-'a'] > 1) 209 printf("%c - %s\n", c, file); 210 } 211 212 tcmd() 213 { 214 register char *de; 215 int segnum; 216 register char *last; 217 FLDOPE *lookup(), *dope; 218 int nleft; register i; 219 register struct rt_ent *rde; 220 221 rt_init(); 222 if(namc==0) 223 for (segnum=0; segnum != -1; /* for all dir. segments */ 224 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 225 last = rt_last + segnum*2*RT_BLOCK; 226 for(de=((char *)&rt_dir[segnum])+10; de <= last; 227 de += rt_entsiz) { 228 if(rtls(rt(de))) { 229 nleft = (last - de) / rt_entsiz; 230 printf("\n%d entries remaining",nleft); 231 printf(" in directory segment %d.\n",segnum+1); 232 break; 233 } 234 } 235 } 236 else 237 for(i = 0; i < namc; i++) { 238 if(dope = lookup(namv[i])) { 239 rde = dope->rtdope; 240 rtls(rde); 241 namv[i] = 0; 242 } 243 } 244 } 245 rtls(de) 246 register struct rt_ent *de; 247 { 248 int month,day,year; 249 char name[12], ext[4]; 250 251 if(flg['v'-'a']) 252 switch(de->rt_stat) { 253 case RT_TEMP: 254 printf("Tempfile:\n"); 255 case RT_FILE: 256 unrad50(2,de->rt_name,name); 257 unrad50(1,&(de->rt_name[2]),ext); 258 day = de->rt_date.rt_dy; 259 year = de->rt_date.rt_yr + 72; 260 month = de->rt_date.rt_mo; 261 printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 262 ext,month,day,year,de->rt_len); 263 break; 264 265 case RT_NULL: 266 printf("%-25.9s %d\n","<UNUSED>",de->rt_len); 267 break; 268 269 case RT_ESEG: 270 return(1); 271 } 272 else { 273 switch(de->rt_stat) { 274 case RT_TEMP: 275 case RT_FILE: 276 sunrad50(name,de->rt_name); 277 printf(name);putchar('\n'); 278 break; 279 280 case RT_ESEG: 281 return(1); 282 283 case RT_NULL: 284 ; 285 } 286 } 287 return(0); 288 } 289 xcmd() 290 { 291 register char *de; 292 int segnum; 293 register char *last; 294 char name[12]; 295 register int i; 296 297 rt_init(); 298 if(namc==0) 299 for (segnum=0; segnum != -1; /* for all dir. segments */ 300 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 301 last = rt_last + segnum*2*RT_BLOCK; 302 for(de=((char *)&rt_dir[segnum])+10; de <= last; 303 de += rt_entsiz) { 304 sunrad50(name,rt(de)->rt_name); 305 rtx(name); 306 } 307 } 308 else 309 for(i = 0; i < namc; i++) 310 if(rtx(namv[i])==0) namv[i] = 0; 311 } 312 rtx(name) 313 char *name; 314 { 315 register FLDOPE *dope; 316 FLDOPE *lookup(); 317 register startad, count; 318 int file; char buff[512]; 319 320 321 if(dope = lookup(name)) { 322 if(flg['v' - 'a']) 323 rtls(dope->rtdope); 324 else 325 printf("x - %s\n",name); 326 327 file = creat(name, 0666); 328 if(file < 0) return(1); 329 count = dope->count; 330 startad = dope->startad; 331 for( ; count > 0 ; count -= 512) { 332 lread(startad,512,buff); 333 write(file,buff,512); 334 startad += 512; 335 } 336 close(file); 337 return(0); 338 } 339 return(1); 340 } 341 rt_init() 342 { 343 static initized = 0; 344 register char *de; 345 register i; 346 int dirnum; 347 char *mode; 348 register char *last; 349 FILE *temp_floppydes; 350 351 if(initized) return; 352 initized = 1; 353 if(flag('c') || flag('d') || flag('r')) 354 mode = "r+"; 355 else 356 mode = "r"; 357 if((temp_floppydes = fopen(defdev, mode)) == NULL) { 358 perror(defdev); 359 exit(1); 360 } else 361 floppydes = fileno(temp_floppydes); 362 if(flag('c')==0) { 363 lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]); 364 dirnum = rt_dir[0].rt_axhead.rt_numseg; 365 if (dirnum > RT_DIRSIZE) { 366 fprintf(stderr,"arff: too many directory segments\n"); 367 exit(1); 368 } 369 for (i=1; i<dirnum; i++) 370 lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]); 371 } else 372 dirnum = 1; 373 374 rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 375 rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 376 rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 377 rt_nleft = 0; 378 379 for (i=0; i<dirnum; i++) { 380 last = rt_last + i*2*RT_BLOCK; 381 for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 382 if(rt(de)->rt_stat==RT_ESEG) break; 383 } 384 rt_curend[i] = rt(de); 385 rt_nleft += (last - de) / rt_entsiz; 386 } 387 } 388 389 static FLDOPE result; 390 FLDOPE * 391 lookup(name) 392 char * name; 393 { 394 unsigned short rname[3]; 395 register char *de; 396 int segnum; 397 register char *last; 398 register index; 399 400 srad50(name,rname); 401 402 /* 403 * Search for name, accumulate blocks in index 404 */ 405 rt_init(); 406 for (segnum=0; segnum != -1; /* for all dir. segments */ 407 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 408 index = 0; 409 last = rt_last + segnum*2*RT_BLOCK; 410 for(de=((char *)&rt_dir[segnum])+10; 411 rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 412 switch(rt(de)->rt_stat) { 413 case RT_FILE: 414 case RT_TEMP: 415 if(samename(rname,rt(de)->rt_name)) 416 goto found; 417 case RT_NULL: 418 index += rt(de)->rt_len; 419 } 420 } 421 } 422 return((FLDOPE *) 0); 423 found: result.count = rt(de)->rt_len * 512; 424 result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 425 result.rtdope = (struct rt_ent *) de; 426 return(&result); 427 } 428 static 429 samename(a,b) 430 unsigned short a[3],b[3]; 431 { 432 return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 433 } 434 435 436 rad50(cp,out) 437 register unsigned char *cp; 438 unsigned short *out; 439 { 440 register index; 441 register temp; 442 443 for(index = 0;*cp; index++) { 444 445 temp = Ain1 * table[*cp++]; 446 if(*cp!=0) { 447 temp += Ain2 * table[*cp++]; 448 449 if(*cp!=0) 450 temp += table[*cp++]; 451 } 452 453 out[index] = temp; 454 } 455 } 456 #define reduce(x,p,q) \ 457 (x = v[p/q], p %= q); 458 459 unrad50(count,in,cp) 460 unsigned short *in; 461 register char *cp; 462 { 463 register i, temp; register unsigned char *v = (unsigned char *) val; 464 465 for(i = 0; i < count; i++) { 466 temp = in[i]; 467 468 reduce (*cp++,temp,Ain1); 469 reduce (*cp++,temp,Ain2); 470 reduce (*cp++,temp,1); 471 } 472 *cp=0; 473 } 474 475 srad50(name,rname) 476 register char * name; 477 register unsigned short *rname; 478 { 479 register index; register char *cp; 480 char file[7],ext[4]; 481 /* 482 * Find end of pathname 483 */ 484 for(cp = name; *cp++; ); 485 while(cp >= name && *--cp != '/'); 486 cp++; 487 /* 488 * Change to rad50 489 * 490 */ 491 for(index = 0; *cp; ){ 492 file[index++] = *cp++; 493 if(*cp=='.') { 494 cp++; 495 break; 496 } 497 if(index>=6) { 498 break; 499 } 500 } 501 file[index] = 0; 502 for(index = 0; *cp; ){ 503 ext[index++] = *cp++; 504 if(*cp=='.' || index>=3) { 505 break; 506 } 507 } 508 ext[index]=0; 509 rname[0] = 0; 510 rname[1] = 0; 511 rname[2] = 0; 512 rad50((unsigned char *)file,rname); 513 rad50((unsigned char *)ext,rname+2); 514 } 515 sunrad50(name,rname) 516 unsigned short rname[3]; 517 register char *name; 518 { 519 register char *cp, *cp2; 520 char ext[4]; 521 522 unrad50(2,rname,name); 523 unrad50(1,rname + 2,ext); 524 /* Jam name and extension together with a dot 525 deleting white space */ 526 for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 527 *++cp = '.';cp++; 528 for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 529 *cp++ = *cp2++; 530 } 531 *cp=0; 532 if(cp[-1]=='.') cp[-1] = 0; 533 } 534 535 static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 536 static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 537 static char table[256] = { 538 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 539 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 540 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 541 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 542 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 543 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 544 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 545 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 546 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 547 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 548 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 549 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 550 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 551 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 552 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 553 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 554 555 long trans(logical) 556 register int logical; 557 { 558 /* Logical to physical adress translation */ 559 register int sector, bytes, track; 560 561 logical += 26 * 128; 562 bytes = (logical & 127); 563 logical >>= 7; 564 sector = logical % 26; 565 if(sector >= 13) 566 sector = sector *2 +1; 567 else 568 sector *= 2; 569 sector += 26 + ((track = (logical / 26)) - 1) * 6; 570 sector %= 26; 571 return( (((track *26) + sector) << 7) + bytes); 572 } 573 lread(startad,count,obuff) 574 register startad, count; 575 register char * obuff; 576 { 577 long trans(); 578 extern floppydes; 579 rt_init(); 580 if(flg['m'-'a']==0) 581 while( (count -= 128) >= 0) { 582 lseek(floppydes, trans(startad), 0); 583 if (read(floppydes,obuff,128) != 128) 584 fprintf(stderr, "arff: read error block %d\n",startad/128); 585 obuff += 128; 586 startad += 128; 587 } 588 else 589 while( (count -= 512) >= 0) { 590 lseek(floppydes,(long) (startad), 0); 591 if (read(floppydes, obuff, 512) != 512) 592 fprintf(stderr, "arff: read error block %d\n",startad/512); 593 obuff += 512; 594 startad += 512; 595 } 596 } 597 lwrite(startad,count,obuff) 598 register startad, count; 599 register char * obuff; 600 { 601 long trans(); 602 extern floppydes; 603 rt_init(); 604 if(flg['m'-'a']==0) 605 while( (count -= 128) >= 0) { 606 lseek(floppydes, trans(startad), 0); 607 if ( write(floppydes,obuff,128) != 128) 608 fprintf(stderr, "arff: write error block %d\n",startad/128); 609 obuff += 128; 610 startad += 128; 611 } 612 else 613 while( (count -= 512) >= 0) { 614 lseek(floppydes,(long) (startad), 0); 615 if ( write(floppydes,obuff,512) != 512) 616 fprintf(stderr, "arff: write error block %d\n",startad/512); 617 obuff += 512; 618 startad += 512; 619 } 620 } 621 622 rcmd() 623 { 624 register int i; 625 626 rt_init(); 627 if (namc>0) 628 for(i = 0; i < namc; i++) 629 if(rtr(namv[i])==0) namv[i]=0; 630 } 631 632 rtr(name) 633 char *name; 634 { 635 register FLDOPE *dope; register struct rt_ent *de; 636 struct stat buf; register struct stat *bufp = &buf; 637 int segnum; 638 register char *last; 639 640 if(stat(name,bufp)<0) { 641 perror(name); 642 return(-1); 643 } 644 if(dope = lookup(name)) { 645 /* can replace, no problem */ 646 de = dope->rtdope; 647 if(bufp->st_size <= (de->rt_len * 512)) 648 printf("r - %s\n",name), 649 toflop(name,bufp->st_size,dope); 650 else { 651 fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 652 return(-1); 653 } 654 } else { 655 /* Search for vacant spot */ 656 for (segnum=0; segnum != -1; /* for all dir. segments */ 657 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 658 last = rt_last + segnum*2*RT_BLOCK; 659 for(de = rt_dir[segnum].rt_ents; 660 rt(de)->rt_stat != RT_ESEG; de++) { 661 switch((de)->rt_stat) { 662 case RT_NULL: 663 if(bufp->st_size <= (de->rt_len * 512)) { 664 printf("a - %s\n",name), 665 mkent(de,segnum,bufp,name); 666 goto found; 667 } 668 continue; 669 } 670 } 671 } 672 printf("%s: no slot for file\n", name); 673 return (-1); 674 } 675 found: if(dope=lookup(name)) { 676 toflop(name,bufp->st_size,dope); 677 return (0); 678 } 679 printf("%s: internal error, added then not found\n", name); 680 return (-1); 681 682 } 683 mkent(de,segnum,bufp,name) 684 register struct rt_ent *de; 685 int segnum; 686 register struct stat *bufp; 687 char *name; 688 { 689 struct tm *localtime(); register struct tm *timp; 690 register struct rt_ent *workp; int count; 691 692 count = (((bufp->st_size -1) >>9) + 1); 693 /* Make sure there is room */ 694 if(de->rt_len==count) 695 goto overwrite; 696 if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 697 /* no entries left on segment */ 698 if(flg['o'-'a']) 699 goto overwrite; 700 fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 701 defdev); 702 exit(1); 703 } 704 /* copy directory entries up */ 705 for(workp = rt_curend[segnum]+1; workp > de; workp--) 706 *workp = workp[-1]; 707 de[1].rt_len -= count; 708 de->rt_len = count; 709 rt_curend[segnum]++; 710 rt_nleft--; 711 overwrite: 712 srad50(name,de->rt_name); 713 timp = localtime(&bufp->st_mtime); 714 de->rt_date.rt_dy = timp->tm_mday + 1; 715 de->rt_date.rt_mo = timp->tm_mon + 1; 716 de->rt_date.rt_yr = timp->tm_year - 72; 717 de->rt_stat = RT_FILE; 718 de->rt_pad = 0; 719 de->rt_chan = 0; 720 de->rt_job = 0; 721 lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 722 } 723 724 toflop(name,ocount,dope) 725 char *name; 726 register FLDOPE *dope; 727 long ocount; 728 { 729 register file, n, startad = dope->startad, count = ocount; 730 char buff[512]; 731 732 file = open(name,0); 733 if(file < 0) { 734 fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);} 735 for( ; count >= 512; count -= 512) { 736 read(file,buff,512); 737 lwrite(startad,512,buff); 738 startad += 512; 739 } 740 read(file,buff,count); 741 close(file); 742 if(count <= 0) return; 743 for(n = count; n < 512; n ++) buff[n] = 0; 744 lwrite(startad,512,buff); 745 count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 746 if(count <= 0) return; 747 for( ; count > 0 ; count--) { 748 startad += 512; 749 lwrite(startad,512,zeroes); 750 } 751 752 } 753 dcmd() 754 { 755 register int i; 756 757 rt_init(); 758 if(namc) 759 for(i = 0; i < namc; i++) 760 if(rtk(namv[i])==0) namv[i]=0; 761 if(dirdirty) 762 scrunch(); 763 764 } 765 rtk(name) 766 char *name; 767 { 768 register FLDOPE *dope; 769 register struct rt_ent *de; 770 FLDOPE *lookup(); 771 772 if(dope = lookup(name)) { 773 printf("d - %s\n",name); 774 de = dope->rtdope; 775 de->rt_stat = RT_NULL; 776 de->rt_name[0] = 0; 777 de->rt_name[1] = 0; 778 de->rt_name[2] = 0; 779 * ((unsigned short *) & (de->rt_date)) = 0; 780 dirdirty = 1; 781 return(0); 782 } 783 return(1); 784 } 785 scrunch() { 786 register struct rt_ent *de , *workp; 787 register segnum; 788 for (segnum=0; segnum != -1; /* for all dir. segments */ 789 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 790 dirdirty = 0; 791 for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 792 if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 793 (de+1)->rt_len += de->rt_len; 794 for(workp = de; workp < rt_curend[segnum]; workp++) 795 *workp = workp[1]; 796 de--; 797 rt_curend[segnum]--; 798 rt_nleft++; 799 dirdirty = 1; 800 } 801 } 802 if (dirdirty) 803 lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 804 } 805 } 806