1 static char *sccsid = "@(#)arff.c 4.5 (Berkeley) 81/04/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 mode, dirnum; 347 register char *last; 348 349 if(initized) return; 350 initized = 1; 351 if(flag('c') || flag('d') || flag('r')) 352 mode = 2; 353 else 354 mode = 0; 355 if((floppydes = open(defdev,mode)) < 0) { 356 dbprintf("Floppy open failed\n"); 357 exit(1); 358 } 359 if(flag('c')==0) { 360 lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]); 361 dirnum = rt_dir[0].rt_axhead.rt_numseg; 362 if (dirnum > RT_DIRSIZE) { 363 fprintf(stderr,"arff: too many directory segments\n"); 364 exit(1); 365 } 366 for (i=1; i<dirnum; i++) 367 lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]); 368 } else 369 dirnum = 1; 370 371 rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 372 rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 373 rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 374 rt_nleft = 0; 375 376 for (i=0; i<dirnum; i++) { 377 last = rt_last + i*2*RT_BLOCK; 378 for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 379 if(rt(de)->rt_stat==RT_ESEG) break; 380 } 381 rt_curend[i] = rt(de); 382 rt_nleft += (last - de) / rt_entsiz; 383 } 384 } 385 386 static FLDOPE result; 387 FLDOPE * 388 lookup(name) 389 char * name; 390 { 391 unsigned short rname[3]; 392 register char *de; 393 int segnum; 394 register char *last; 395 register index; 396 397 srad50(name,rname); 398 399 /* 400 * Search for name, accumulate blocks in index 401 */ 402 rt_init(); 403 for (segnum=0; segnum != -1; /* for all dir. segments */ 404 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 405 index = 0; 406 last = rt_last + segnum*2*RT_BLOCK; 407 for(de=((char *)&rt_dir[segnum])+10; 408 rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 409 switch(rt(de)->rt_stat) { 410 case RT_FILE: 411 case RT_TEMP: 412 if(samename(rname,rt(de)->rt_name)) 413 goto found; 414 case RT_NULL: 415 index += rt(de)->rt_len; 416 } 417 } 418 } 419 return((FLDOPE *) 0); 420 found: result.count = rt(de)->rt_len * 512; 421 result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 422 result.rtdope = (struct rt_ent *) de; 423 return(&result); 424 } 425 static 426 samename(a,b) 427 unsigned short a[3],b[3]; 428 { 429 return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 430 } 431 432 433 rad50(cp,out) 434 register unsigned char *cp; 435 unsigned short *out; 436 { 437 register index; 438 register temp; 439 440 for(index = 0;*cp; index++) { 441 442 temp = Ain1 * table[*cp++]; 443 if(*cp!=0) { 444 temp += Ain2 * table[*cp++]; 445 446 if(*cp!=0) 447 temp += table[*cp++]; 448 } 449 450 out[index] = temp; 451 } 452 } 453 #define reduce(x,p,q) \ 454 (x = v[p/q], p %= q); 455 456 unrad50(count,in,cp) 457 unsigned short *in; 458 register char *cp; 459 { 460 register i, temp; register unsigned char *v = (unsigned char *) val; 461 462 for(i = 0; i < count; i++) { 463 temp = in[i]; 464 465 reduce (*cp++,temp,Ain1); 466 reduce (*cp++,temp,Ain2); 467 reduce (*cp++,temp,1); 468 } 469 *cp=0; 470 } 471 472 srad50(name,rname) 473 register char * name; 474 register unsigned short *rname; 475 { 476 register index; register char *cp; 477 char file[7],ext[4]; 478 /* 479 * Find end of pathname 480 */ 481 for(cp = name; *cp++; ); 482 while(cp >= name && *--cp != '/'); 483 cp++; 484 /* 485 * Change to rad50 486 * 487 */ 488 for(index = 0; *cp; ){ 489 file[index++] = *cp++; 490 if(*cp=='.') { 491 cp++; 492 break; 493 } 494 if(index>=6) { 495 break; 496 } 497 } 498 file[index] = 0; 499 for(index = 0; *cp; ){ 500 ext[index++] = *cp++; 501 if(*cp=='.' || index>=3) { 502 break; 503 } 504 } 505 ext[index]=0; 506 rname[0] = 0; 507 rname[1] = 0; 508 rname[2] = 0; 509 rad50((unsigned char *)file,rname); 510 rad50((unsigned char *)ext,rname+2); 511 } 512 sunrad50(name,rname) 513 unsigned short rname[3]; 514 register char *name; 515 { 516 register char *cp, *cp2; 517 char ext[4]; 518 519 unrad50(2,rname,name); 520 unrad50(1,rname + 2,ext); 521 /* Jam name and extension together with a dot 522 deleting white space */ 523 for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 524 *++cp = '.';cp++; 525 for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 526 *cp++ = *cp2++; 527 } 528 *cp=0; 529 if(cp[-1]=='.') cp[-1] = 0; 530 } 531 532 static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 533 static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 534 static char table[256] = { 535 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 536 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 537 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 538 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 539 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 540 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 541 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 542 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 543 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 544 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 545 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 546 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 547 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 548 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 549 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 550 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 551 552 long trans(logical) 553 register int logical; 554 { 555 /* Logical to physical adress translation */ 556 register int sector, bytes, track; 557 558 logical += 26 * 128; 559 bytes = (logical & 127); 560 logical >>= 7; 561 sector = logical % 26; 562 if(sector >= 13) 563 sector = sector *2 +1; 564 else 565 sector *= 2; 566 sector += 26 + ((track = (logical / 26)) - 1) * 6; 567 sector %= 26; 568 return( (((track *26) + sector) << 7) + bytes); 569 } 570 lread(startad,count,obuff) 571 register startad, count; 572 register char * obuff; 573 { 574 long trans(); 575 extern floppydes; 576 rt_init(); 577 if(flg['m'-'a']==0) 578 while( (count -= 128) >= 0) { 579 lseek(floppydes, trans(startad), 0); 580 if (read(floppydes,obuff,128) != 128) 581 fprintf(stderr, "arff: read error block %d\n",startad/128); 582 obuff += 128; 583 startad += 128; 584 } 585 else 586 while( (count -= 512) >= 0) { 587 lseek(floppydes,(long) (startad), 0); 588 fprintf(stderr, "arff: read error block %d\n",startad/512); 589 obuff += 512; 590 startad += 512; 591 } 592 } 593 lwrite(startad,count,obuff) 594 register startad, count; 595 register char * obuff; 596 { 597 long trans(); 598 extern floppydes; 599 rt_init(); 600 if(flg['m'-'a']==0) 601 while( (count -= 128) >= 0) { 602 lseek(floppydes, trans(startad), 0); 603 if ( write(floppydes,obuff,128) != 128) 604 fprintf(stderr, "arff: write error block %d\n",startad/128); 605 obuff += 128; 606 startad += 128; 607 } 608 else 609 while( (count -= 512) >= 0) { 610 lseek(floppydes,(long) (startad), 0); 611 if ( write(floppydes,obuff,512) != 512) 612 fprintf(stderr, "arff: write error block %d\n",startad/512); 613 obuff += 512; 614 startad += 512; 615 } 616 } 617 618 rcmd() 619 { 620 register int i; 621 622 rt_init(); 623 if (namc>0) 624 for(i = 0; i < namc; i++) 625 if(rtr(namv[i])==0) namv[i]=0; 626 } 627 628 rtr(name) 629 char *name; 630 { 631 register FLDOPE *dope; register struct rt_ent *de; 632 struct stat buf; register struct stat *bufp = &buf; 633 int segnum; 634 register char *last; 635 636 if(stat(name,bufp)<0) { 637 perror(name); 638 return(-1); 639 } 640 if(dope = lookup(name)) { 641 /* can replace, no problem */ 642 de = dope->rtdope; 643 if(bufp->st_size <= (de->rt_len * 512)) 644 printf("r - %s\n",name), 645 toflop(name,bufp->st_size,dope); 646 else { 647 fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 648 return(-1); 649 } 650 } else { 651 /* Search for vacant spot */ 652 for (segnum=0; segnum != -1; /* for all dir. segments */ 653 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 654 last = rt_last + segnum*2*RT_BLOCK; 655 for(de = rt_dir[segnum].rt_ents; 656 rt(de)->rt_stat != RT_ESEG; de++) { 657 switch((de)->rt_stat) { 658 case RT_NULL: 659 if(bufp->st_size <= (de->rt_len * 512)) { 660 printf("a - %s\n",name), 661 mkent(de,segnum,bufp,name); 662 goto found; 663 } 664 continue; 665 } 666 } 667 } 668 printf("%s: no slot for file\n", name); 669 return (-1); 670 } 671 found: if(dope=lookup(name)) { 672 toflop(name,bufp->st_size,dope); 673 return (0); 674 } 675 printf("%s: internal error, added then not found\n", name); 676 return (-1); 677 678 } 679 mkent(de,segnum,bufp,name) 680 register struct rt_ent *de; 681 int segnum; 682 register struct stat *bufp; 683 char *name; 684 { 685 struct tm *localtime(); register struct tm *timp; 686 register struct rt_ent *workp; int count; 687 688 count = (((bufp->st_size -1) >>9) + 1); 689 /* Make sure there is room */ 690 if(de->rt_len==count) 691 goto overwrite; 692 if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 693 /* no entries left on segment */ 694 if(flg['o'-'a']) 695 goto overwrite; 696 fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 697 defdev); 698 exit(1); 699 } 700 /* copy directory entries up */ 701 for(workp = rt_curend[segnum]+1; workp > de; workp--) 702 *workp = workp[-1]; 703 de[1].rt_len -= count; 704 de->rt_len = count; 705 rt_curend[segnum]++; 706 rt_nleft--; 707 overwrite: 708 srad50(name,de->rt_name); 709 timp = localtime(&bufp->st_mtime); 710 de->rt_date.rt_dy = timp->tm_mday + 1; 711 de->rt_date.rt_mo = timp->tm_mon + 1; 712 de->rt_date.rt_yr = timp->tm_year - 72; 713 de->rt_stat = RT_FILE; 714 de->rt_pad = 0; 715 de->rt_chan = 0; 716 de->rt_job = 0; 717 lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 718 } 719 720 toflop(name,ocount,dope) 721 char *name; 722 register FLDOPE *dope; 723 long ocount; 724 { 725 register file, n, startad = dope->startad, count = ocount; 726 char buff[512]; 727 728 file = open(name,0); 729 if(file < 0) { 730 fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);} 731 for( ; count >= 512; count -= 512) { 732 read(file,buff,512); 733 lwrite(startad,512,buff); 734 startad += 512; 735 } 736 read(file,buff,count); 737 close(file); 738 if(count <= 0) return; 739 for(n = count; n < 512; n ++) buff[n] = 0; 740 lwrite(startad,512,buff); 741 count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 742 if(count <= 0) return; 743 for( ; count > 0 ; count--) { 744 startad += 512; 745 lwrite(startad,512,zeroes); 746 } 747 748 } 749 dcmd() 750 { 751 register int i; 752 753 rt_init(); 754 if(namc) 755 for(i = 0; i < namc; i++) 756 if(rtk(namv[i])==0) namv[i]=0; 757 if(dirdirty) 758 scrunch(); 759 760 } 761 rtk(name) 762 char *name; 763 { 764 register FLDOPE *dope; 765 register struct rt_ent *de; 766 FLDOPE *lookup(); 767 768 if(dope = lookup(name)) { 769 printf("d - %s\n",name); 770 de = dope->rtdope; 771 de->rt_stat = RT_NULL; 772 de->rt_name[0] = 0; 773 de->rt_name[1] = 0; 774 de->rt_name[2] = 0; 775 * ((unsigned short *) & (de->rt_date)) = 0; 776 dirdirty = 1; 777 return(0); 778 } 779 return(1); 780 } 781 scrunch() { 782 register struct rt_ent *de , *workp; 783 register segnum; 784 for (segnum=0; segnum != -1; /* for all dir. segments */ 785 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 786 dirdirty = 0; 787 for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 788 if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 789 (de+1)->rt_len += de->rt_len; 790 for(workp = de; workp < rt_curend[segnum]; workp++) 791 *workp = workp[1]; 792 de--; 793 rt_curend[segnum]--; 794 rt_nleft++; 795 dirdirty = 1; 796 } 797 } 798 if (dirdirty) 799 lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 800 } 801 } 802