1*1735Sbill static char *sccsid = "@(#)arff.c 4.2 (Berkeley) 11/03/80"; 2954Sbill #include <sys/types.h> 3954Sbill #include <sys/stat.h> 4954Sbill #include <time.h> 5954Sbill #include <signal.h> 6954Sbill #include <stdio.h> 7954Sbill #define dbprintf printf 8954Sbill struct rt_dat { 9954Sbill unsigned short int rt_yr:5; /*Year - 1972 */ 10954Sbill unsigned short int rt_dy:5; /*day */ 11954Sbill unsigned short int rt_mo:5; /*month */ 12954Sbill }; 13954Sbill struct rt_axent { 14954Sbill char rt_sent[14]; 15954Sbill }; 16954Sbill 17954Sbill struct rt_ent { 18954Sbill char rt_pad; /*unusued */ 19954Sbill char rt_stat; /*Type of entry, or end of seg*/ 20954Sbill unsigned short rt_name[3]; /*Name, 3 words in rad50 form */ 21954Sbill short rt_len; /*Length of file */ 22954Sbill char rt_chan; /*Only used in temporary files*/ 23954Sbill char rt_job; /*Only used in temporary files*/ 24954Sbill struct rt_dat rt_date; /*Creation Date */ 25954Sbill }; 26954Sbill #define RT_TEMP 1 27954Sbill #define RT_NULL 2 28954Sbill #define RT_FILE 4 29954Sbill #define RT_ESEG 8 30954Sbill #define RT_BLOCK 512 31954Sbill struct rt_head { 32954Sbill short rt_numseg; /*number of segments available*/ 33954Sbill short rt_nxtseg; /*segment no of next log. seg */ 34954Sbill short rt_lstseg; /*highest seg currenltly open */ 35954Sbill unsigned short rt_entpad; /*extra words/dir. entry */ 36954Sbill short rt_stfile; /*block no where files begin */ 37954Sbill }; 38954Sbill struct rt_dir { 39954Sbill struct rt_head rt_axhead; 40954Sbill struct rt_ent rt_ents[72]; 41954Sbill char _dirpad[6]; 42954Sbill }; 43954Sbill extern struct rt_dir rt_dir; 44954Sbill extern int rt_entsiz; 45954Sbill extern int floppydes; 46954Sbill extern char *rt_last; 47954Sbill typedef struct fldope { 48954Sbill int startad; 49954Sbill int count; 50954Sbill struct rt_ent *rtdope; 51954Sbill } FLDOPE; 52954Sbill FLDOPE *lookup(); 53954Sbill #define rt(p) ((struct rt_ent *) p ) 54954Sbill #define Ain1 03100 55954Sbill #define Ain2 050 56954Sbill #define flag(c) (flg[(c) - 'a']) 57954Sbill 58954Sbill char *man = { "rxtd" }; 59954Sbill 60954Sbill char zeroes[512]; 61954Sbill extern char *val; 62954Sbill extern char table[256]; 63954Sbill struct rt_dir rt_dir = {{4,0,1,0,14},{0,RT_NULL,{0,0,0},494,0}, {0,RT_ESEG}}; 64954Sbill int rt_entsiz; 65954Sbill int rt_nleft; 66954Sbill struct rt_ent *rt_curend; 67954Sbill int floppydes; 68954Sbill int dirdirty; 69954Sbill char *rt_last; 70954Sbill char *defdev = "/dev/floppy"; 71954Sbill 72954Sbill char *opt = { "vf" }; 73954Sbill 74954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 75954Sbill long lseek(); 76954Sbill int rcmd(); 77954Sbill int dcmd(); 78954Sbill int xcmd(); 79954Sbill int tcmd(); 80954Sbill int (*comfun)(); 81954Sbill char flg[26]; 82954Sbill char **namv; 83954Sbill int namc; 84954Sbill int file; 85954Sbill 86954Sbill 87954Sbill main(argc, argv) 88954Sbill char *argv[]; 89954Sbill { 90954Sbill register char *cp; 91954Sbill 92954Sbill /*register i; 93954Sbill for(i=0; signum[i]; i++) 94954Sbill if(signal(signum[i], SIG_IGN) != SIG_IGN) 95954Sbill signal(signum[i], sigdone);*/ 96954Sbill if(argc < 2) 97954Sbill usage(); 98954Sbill cp = argv[1]; 99954Sbill for(cp = argv[1]; *cp; cp++) 100954Sbill switch(*cp) { 101954Sbill case 'm': 102954Sbill case 'v': 103954Sbill case 'u': 104954Sbill case 'w': 105954Sbill flg[*cp - 'a']++; 106954Sbill continue; 107954Sbill case 'c': 108954Sbill { 109954Sbill #define SURE "Are you sure you want to clobber the floppy?\n" 110954Sbill int tty; 111*1735Sbill char response[128]; 112954Sbill tty = open("/dev/tty",2); 113954Sbill write(tty,SURE,sizeof(SURE)); 114*1735Sbill read(tty,response,128); 115954Sbill if(*response!='y') 116954Sbill exit(50); 117954Sbill flag('c')++; 118954Sbill close(tty); 119954Sbill } 120954Sbill dirdirty++; 121954Sbill continue; 122954Sbill 123954Sbill case 'r': 124954Sbill setcom(rcmd); 125954Sbill flag('r')++; 126954Sbill continue; 127954Sbill 128954Sbill case 'd': 129954Sbill setcom(dcmd); 130954Sbill flag('d')++; 131954Sbill continue; 132954Sbill 133954Sbill case 'x': 134954Sbill setcom(xcmd); 135954Sbill continue; 136954Sbill 137954Sbill case 't': 138954Sbill setcom(tcmd); 139954Sbill continue; 140954Sbill 141954Sbill case 'f': 142954Sbill defdev = argv[2]; 143954Sbill argv++; 144954Sbill argc--; 145954Sbill continue; 146954Sbill 147954Sbill 148954Sbill default: 149954Sbill fprintf(stderr, "arff: bad option `%c'\n", *cp); 150954Sbill exit(1); 151954Sbill } 152954Sbill namv = argv+2; 153954Sbill namc = argc-2; 154954Sbill if(comfun == 0) { 155954Sbill if(flg['u'-'a'] == 0) { 156954Sbill fprintf(stderr, "arff: one of [%s] must be specified\n", man); 157954Sbill exit(1); 158954Sbill } 159954Sbill setcom(rcmd); 160954Sbill } 161954Sbill (*comfun)(); 162954Sbill exit(notfound()); 163954Sbill } 164954Sbill 165954Sbill setcom(fun) 166954Sbill int (*fun)(); 167954Sbill { 168954Sbill 169954Sbill if(comfun != 0) { 170954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 171954Sbill exit(1); 172954Sbill } 173954Sbill comfun = fun; 174954Sbill } 175954Sbill 176954Sbill 177954Sbill 178954Sbill 179954Sbill 180954Sbill 181954Sbill 182954Sbill 183954Sbill usage() 184954Sbill { 185954Sbill printf("usage: ar [%s][%s] archive files ...\n", opt, man); 186954Sbill exit(1); 187954Sbill } 188954Sbill 189954Sbill 190954Sbill 191954Sbill notfound() 192954Sbill { 193954Sbill register i, n; 194954Sbill 195954Sbill n = 0; 196954Sbill for(i=0; i<namc; i++) 197954Sbill if(namv[i]) { 198954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 199954Sbill n++; 200954Sbill } 201954Sbill return(n); 202954Sbill } 203954Sbill 204954Sbill 205954Sbill 206954Sbill phserr() 207954Sbill { 208954Sbill 209954Sbill fprintf(stderr, "arff: phase error on %s\n", file); 210954Sbill } 211954Sbill 212954Sbill mesg(c) 213954Sbill { 214954Sbill 215954Sbill if(flg['v'-'a']) 216954Sbill if(c != 'c' || flg['v'-'a'] > 1) 217954Sbill printf("%c - %s\n", c, file); 218954Sbill } 219954Sbill 220954Sbill tcmd() 221954Sbill { 222954Sbill register char *de; 223954Sbill FLDOPE *lookup(), *dope; 224954Sbill int nleft; register i; 225954Sbill register struct rt_ent *rde; 226954Sbill 227954Sbill rt_init(); 228954Sbill if(namc==0) 229954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 230954Sbill if(rtls(rt(de))) { 231954Sbill nleft = (rt_last - de) / rt_entsiz; 232954Sbill printf("\n\n%d entries remaining.\n",nleft); 233954Sbill break; 234954Sbill } 235954Sbill } 236954Sbill else 237954Sbill for(i = 0; i < namc; i++) { 238954Sbill if(dope = lookup(namv[i])) { 239954Sbill rde = dope->rtdope; 240954Sbill rtls(rde); 241954Sbill namv[i] = 0; 242954Sbill } 243954Sbill } 244954Sbill } 245954Sbill rtls(de) 246954Sbill register struct rt_ent *de; 247954Sbill { 248954Sbill int month,day,year; 249954Sbill char name[12], ext[4]; 250954Sbill 251954Sbill if(flg['v'-'a']) 252954Sbill switch(de->rt_stat) { 253954Sbill case RT_TEMP: 254954Sbill printf("Tempfile:\n"); 255954Sbill case RT_FILE: 256954Sbill unrad50(2,de->rt_name,name); 257954Sbill unrad50(1,&(de->rt_name[2]),ext); 258954Sbill day = de->rt_date.rt_dy; 259954Sbill year = de->rt_date.rt_yr + 72; 260954Sbill month = de->rt_date.rt_mo; 261954Sbill printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 262954Sbill ext,month,day,year,de->rt_len); 263954Sbill break; 264954Sbill 265954Sbill case RT_NULL: 266954Sbill printf("%-25.9s %d\n","<UNUSED>",de->rt_len); 267954Sbill break; 268954Sbill 269954Sbill case RT_ESEG: 270954Sbill return(1); 271954Sbill } 272954Sbill else { 273954Sbill switch(de->rt_stat) { 274954Sbill case RT_TEMP: 275954Sbill case RT_FILE: 276954Sbill sunrad50(name,de->rt_name); 277954Sbill printf(name);putchar('\n'); 278954Sbill break; 279954Sbill 280954Sbill case RT_ESEG: 281954Sbill return(1); 282954Sbill 283954Sbill case RT_NULL: 284954Sbill ; 285954Sbill } 286954Sbill } 287954Sbill return(0); 288954Sbill } 289954Sbill xcmd() 290954Sbill { 291954Sbill register char *de; 292954Sbill char name[12]; 293954Sbill register int i; 294954Sbill 295954Sbill rt_init(); 296954Sbill if(namc==0) 297954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 298954Sbill sunrad50(name,rt(de)->rt_name); 299954Sbill rtx(name); 300954Sbill } 301954Sbill 302954Sbill else 303954Sbill for(i = 0; i < namc; i++) 304954Sbill if(rtx(namv[i])==0) namv[i] = 0; 305954Sbill } 306954Sbill rtx(name) 307954Sbill char *name; 308954Sbill { 309954Sbill register FLDOPE *dope; 310954Sbill FLDOPE *lookup(); 311954Sbill register startad, count; 312954Sbill int file; char buff[512]; 313954Sbill 314954Sbill 315954Sbill if(dope = lookup(name)) { 316954Sbill if(flg['v' - 'a']) 317954Sbill rtls(dope->rtdope); 318954Sbill else 319954Sbill printf("x - %s\n",name); 320954Sbill 321954Sbill file = creat(name, 0666); 322954Sbill if(file < 0) return(1); 323954Sbill count = dope->count; 324954Sbill startad = dope->startad; 325954Sbill for( ; count > 0 ; count -= 512) { 326954Sbill lread(startad,512,buff); 327954Sbill write(file,buff,512); 328954Sbill startad += 512; 329954Sbill } 330954Sbill close(file); 331954Sbill return(0); 332954Sbill } 333954Sbill return(1); 334954Sbill } 335954Sbill rt_init() 336954Sbill { 337954Sbill static initized = 0; 338954Sbill register char *de; 339954Sbill int mode; 340954Sbill 341954Sbill if(initized) return; 342954Sbill initized = 1; 343954Sbill if(flag('c') || flag('d') || flag('r')) 344954Sbill mode = 2; 345954Sbill else 346954Sbill mode = 0; 347954Sbill if((floppydes = open(defdev,mode)) < 0) 348954Sbill dbprintf("Floppy open failed\n"); 349954Sbill if(flag('c')==0) 350954Sbill lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 351954Sbill 352954Sbill rt_entsiz = 2*rt_dir.rt_axhead.rt_entpad + 14; 353954Sbill rt_entsiz = 14; 354954Sbill rt_last = ((char *) &rt_dir) + 10 + 1014/rt_entsiz*rt_entsiz; 355954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 356954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 357954Sbill } 358954Sbill rt_curend = rt(de); 359954Sbill rt_nleft = (rt_last - de) / rt_entsiz; 360954Sbill } 361954Sbill 362954Sbill static FLDOPE result; 363954Sbill FLDOPE * 364954Sbill lookup(name) 365954Sbill char * name; 366954Sbill { 367954Sbill unsigned short rname[3]; 368954Sbill register char *de; 369954Sbill register index; 370954Sbill 371954Sbill srad50(name,rname); 372954Sbill 373954Sbill /* 374954Sbill * Search for name, accumulate blocks in index 375954Sbill */ 376954Sbill rt_init(); 377954Sbill index = 0; 378954Sbill for(de = ((char *) &rt_dir) + 10; de <= rt_last; de += rt_entsiz) { 379954Sbill switch(rt(de)->rt_stat) { 380954Sbill case RT_ESEG: 381954Sbill return((FLDOPE *) 0); 382954Sbill case RT_FILE: 383954Sbill case RT_TEMP: 384954Sbill if(samename(rname,rt(de)->rt_name)) 385954Sbill goto found; 386954Sbill case RT_NULL: 387954Sbill index += rt(de)->rt_len; 388954Sbill } 389954Sbill } 390954Sbill return((FLDOPE *) 0); 391954Sbill found: result.count = rt(de)->rt_len * 512; 392954Sbill result.startad = 512 * (rt_dir.rt_axhead.rt_stfile + index); 393954Sbill result.rtdope = (struct rt_ent *) de; 394954Sbill return(&result); 395954Sbill } 396954Sbill static 397954Sbill samename(a,b) 398954Sbill unsigned short a[3],b[3]; 399954Sbill { 400954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 401954Sbill } 402954Sbill 403954Sbill 404954Sbill rad50(cp,out) 405954Sbill register unsigned char *cp; 406954Sbill unsigned short *out; 407954Sbill { 408954Sbill register index; 409954Sbill register temp; 410954Sbill 411954Sbill for(index = 0;*cp; index++) { 412954Sbill 413954Sbill temp = Ain1 * table[*cp++]; 414954Sbill if(*cp!=0) { 415954Sbill temp += Ain2 * table[*cp++]; 416954Sbill 417954Sbill if(*cp!=0) 418954Sbill temp += table[*cp++]; 419954Sbill } 420954Sbill 421954Sbill out[index] = temp; 422954Sbill } 423954Sbill } 424954Sbill #define reduce(x,p,q) \ 425954Sbill (x = v[p/q], p %= q); 426954Sbill 427954Sbill unrad50(count,in,cp) 428954Sbill unsigned short *in; 429954Sbill register char *cp; 430954Sbill { 431954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 432954Sbill 433954Sbill for(i = 0; i < count; i++) { 434954Sbill temp = in[i]; 435954Sbill 436954Sbill reduce (*cp++,temp,Ain1); 437954Sbill reduce (*cp++,temp,Ain2); 438954Sbill reduce (*cp++,temp,1); 439954Sbill } 440954Sbill *cp=0; 441954Sbill } 442954Sbill 443954Sbill srad50(name,rname) 444954Sbill register char * name; 445954Sbill register unsigned short *rname; 446954Sbill { 447954Sbill register index; register char *cp; 448954Sbill char file[7],ext[4]; 449954Sbill /* 450954Sbill * Find end of pathname 451954Sbill */ 452954Sbill for(cp = name; *cp++; ); 453954Sbill while(cp >= name && *--cp != '/'); 454954Sbill cp++; 455954Sbill /* 456954Sbill * Change to rad50 457954Sbill * 458954Sbill */ 459954Sbill for(index = 0; *cp; ){ 460954Sbill file[index++] = *cp++; 461954Sbill if(*cp=='.') { 462954Sbill cp++; 463954Sbill break; 464954Sbill } 465954Sbill if(index>=6) { 466954Sbill break; 467954Sbill } 468954Sbill } 469954Sbill file[index] = 0; 470954Sbill for(index = 0; *cp; ){ 471954Sbill ext[index++] = *cp++; 472954Sbill if(*cp=='.' || index>=3) { 473954Sbill break; 474954Sbill } 475954Sbill } 476954Sbill ext[index]=0; 477954Sbill rname[0] = 0; 478954Sbill rname[1] = 0; 479954Sbill rname[2] = 0; 480954Sbill rad50((unsigned char *)file,rname); 481954Sbill rad50((unsigned char *)ext,rname+2); 482954Sbill } 483954Sbill sunrad50(name,rname) 484954Sbill unsigned short rname[3]; 485954Sbill register char *name; 486954Sbill { 487954Sbill register char *cp, *cp2; 488954Sbill char ext[4]; 489954Sbill 490954Sbill unrad50(2,rname,name); 491954Sbill unrad50(1,rname + 2,ext); 492954Sbill /* Jam name and extension together with a dot 493954Sbill deleting white space */ 494954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 495954Sbill *++cp = '.';cp++; 496954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 497954Sbill *cp++ = *cp2++; 498954Sbill } 499954Sbill *cp=0; 500954Sbill if(cp[-1]=='.') cp[-1] = 0; 501954Sbill } 502954Sbill 503954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 504954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 505954Sbill static char table[256] = { 506954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 507954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 508954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 509954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 510954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 511954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 512954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 513954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 514954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 515954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 516954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 517954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 518954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 519954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 520954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 521954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 522954Sbill 523954Sbill long trans(logical) 524954Sbill register int logical; 525954Sbill { 526954Sbill /* Logical to physical adress translation */ 527954Sbill register int sector, bytes, track; 528954Sbill 529954Sbill logical += 26 * 128; 530954Sbill bytes = (logical & 127); 531954Sbill logical >>= 7; 532954Sbill sector = logical % 26; 533954Sbill if(sector >= 13) 534954Sbill sector = sector *2 +1; 535954Sbill else 536954Sbill sector *= 2; 537954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 538954Sbill sector %= 26; 539954Sbill return( (((track *26) + sector) << 7) + bytes); 540954Sbill } 541954Sbill lread(startad,count,obuff) 542954Sbill register startad, count; 543954Sbill register char * obuff; 544954Sbill { 545954Sbill long trans(); 546954Sbill extern floppydes; 547954Sbill rt_init(); 548954Sbill if(flg['m'-'a']==0) 549954Sbill while( (count -= 128) >= 0) { 550954Sbill lseek(floppydes, trans(startad), 0); 551954Sbill read(floppydes,obuff,128); 552954Sbill obuff += 128; 553954Sbill startad += 128; 554954Sbill } 555954Sbill else 556954Sbill while( (count -= 512) >= 0) { 557954Sbill lseek(floppydes,(long) (startad), 0); 558954Sbill read(floppydes,obuff,512); 559954Sbill obuff += 512; 560954Sbill startad += 512; 561954Sbill } 562954Sbill } 563954Sbill lwrite(startad,count,obuff) 564954Sbill register startad, count; 565954Sbill register char * obuff; 566954Sbill { 567954Sbill long trans(); 568954Sbill extern floppydes; 569954Sbill rt_init(); 570954Sbill if(flg['m'-'a']==0) 571954Sbill while( (count -= 128) >= 0) { 572954Sbill lseek(floppydes, trans(startad), 0); 573954Sbill write(floppydes,obuff,128); 574954Sbill obuff += 128; 575954Sbill startad += 128; 576954Sbill } 577954Sbill else 578954Sbill while( (count -= 512) >= 0) { 579954Sbill lseek(floppydes,(long) (startad), 0); 580954Sbill write(floppydes,obuff,512); 581954Sbill obuff += 512; 582954Sbill startad += 512; 583954Sbill } 584954Sbill } 585954Sbill 586954Sbill rcmd() 587954Sbill { 588954Sbill register int i; 589954Sbill 590954Sbill rt_init(); 591954Sbill if(namc>0) 592954Sbill for(i = 0; i < namc; i++) 593954Sbill if(rtr(namv[i])==0) namv[i]=0; 594954Sbill 595954Sbill 596954Sbill } 597954Sbill 598954Sbill rtr(name) 599954Sbill char *name; 600954Sbill { 601954Sbill register FLDOPE *dope; register struct rt_ent *de; 602954Sbill struct stat buf; register struct stat *bufp = &buf; 603954Sbill 604954Sbill if(stat(name,bufp)<0) return(1); 605954Sbill if(dope = lookup(name)) { 606954Sbill /* can replace, no problem */ 607954Sbill de = dope->rtdope; 608954Sbill if(bufp->st_size <= (de->rt_len * 512)) 609954Sbill printf("r - %s\n",name), 610954Sbill toflop(name,bufp->st_size,dope); 611954Sbill else { 612954Sbill printf("%s will not fit in currently used file on floppy\n",name); 613954Sbill return(1); 614954Sbill } 615954Sbill } else { 616954Sbill /* Search for vacant spot */ 617954Sbill for(de = rt_dir.rt_ents; (char *) de <= rt_last; de++) { 618954Sbill switch((de)->rt_stat) { 619954Sbill case RT_NULL: 620954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 621954Sbill printf("a - %s\n",name), 622954Sbill mkent(de,bufp,name); 623954Sbill goto found; 624954Sbill } 625954Sbill continue; 626954Sbill case RT_ESEG: 627954Sbill return(3); 628954Sbill } 629954Sbill } 630954Sbill return(5); 631954Sbill } 632954Sbill found: if(dope=lookup(name)) { 633954Sbill toflop(name,bufp->st_size,dope); 634954Sbill return(0); 635954Sbill } 636954Sbill return(7); 637954Sbill 638954Sbill } 639954Sbill mkent(de,bufp,name) 640954Sbill register struct rt_ent *de; 641954Sbill register struct stat *bufp; 642954Sbill char *name; 643954Sbill { 644954Sbill struct tm *localtime(); register struct tm *timp; 645954Sbill register struct rt_ent *workp; int count; 646954Sbill 647954Sbill count = (((bufp->st_size -1) >>9) + 1); 648954Sbill /* Make sure there is room */ 649954Sbill if(de->rt_len==count) 650954Sbill goto overwrite; 651954Sbill if(rt_nleft==0) { 652954Sbill if(flg['o'-'a']) 653954Sbill goto overwrite; 654954Sbill fprintf(stderr,"Directory full on %s\n",defdev); 655954Sbill exit(1); 656954Sbill } 657954Sbill /* copy directory entries up */ 658954Sbill for(workp = rt_curend+1; workp > de; workp--) 659954Sbill *workp = workp[-1]; 660954Sbill de[1].rt_len -= count; 661954Sbill de->rt_len = count; 662954Sbill rt_curend++; 663954Sbill rt_nleft--; 664954Sbill overwrite: 665954Sbill srad50(name,de->rt_name); 666954Sbill timp = localtime(&bufp->st_mtime); 667954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 668954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 669954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 670954Sbill de->rt_stat = RT_FILE; 671954Sbill de->rt_pad = 0; 672954Sbill de->rt_chan = 0; 673954Sbill de->rt_job = 0; 674954Sbill lwrite(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 675954Sbill 676954Sbill } 677954Sbill 678954Sbill toflop(name,ocount,dope) 679954Sbill char *name; 680954Sbill register FLDOPE *dope; 681954Sbill long ocount; 682954Sbill { 683954Sbill register file, n, startad = dope->startad, count = ocount; 684954Sbill char buff[512]; 685954Sbill 686954Sbill file = open(name,0); 687954Sbill if(file < 0) { 688954Sbill printf("arff: couldn't open %s\n",name);exit(1);} 689954Sbill for( ; count >= 512; count -= 512) { 690954Sbill read(file,buff,512); 691954Sbill lwrite(startad,512,buff); 692954Sbill startad += 512; 693954Sbill } 694954Sbill read(file,buff,count); 695954Sbill close(file); 696954Sbill if(count <= 0) return; 697954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 698954Sbill lwrite(startad,512,buff); 699954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 700954Sbill if(count <= 0) return; 701954Sbill for( ; count > 0 ; count--) { 702954Sbill startad += 512; 703954Sbill lwrite(startad,512,zeroes); 704954Sbill } 705954Sbill 706954Sbill } 707954Sbill dcmd() 708954Sbill { 709954Sbill register int i; 710954Sbill 711954Sbill rt_init(); 712954Sbill if(namc) 713954Sbill for(i = 0; i < namc; i++) 714954Sbill if(rtk(namv[i])==0) namv[i]=0; 715954Sbill if(dirdirty) 716954Sbill scrunch(); 717954Sbill 718954Sbill } 719954Sbill rtk(name) 720954Sbill char *name; 721954Sbill { 722954Sbill register FLDOPE *dope; 723954Sbill register struct rt_ent *de; 724954Sbill FLDOPE *lookup(); 725954Sbill 726954Sbill if(dope = lookup(name)) { 727954Sbill printf("d - %s\n",name); 728954Sbill de = dope->rtdope; 729954Sbill de->rt_stat = RT_NULL; 730954Sbill de->rt_name[0] = 0; 731954Sbill de->rt_name[1] = 0; 732954Sbill de->rt_name[2] = 0; 733954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 734954Sbill dirdirty = 1; 735954Sbill return(0); 736954Sbill } 737954Sbill return(1); 738954Sbill } 739954Sbill scrunch() { 740954Sbill register struct rt_ent *de = rt_dir.rt_ents, *workp; 741954Sbill for(de = rt_dir.rt_ents; de <= rt_curend; de++) { 742954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 743954Sbill (de+1)->rt_len += de->rt_len; 744954Sbill for(workp = de; workp < rt_curend; workp++) 745954Sbill *workp = workp[1]; 746954Sbill de--; 747954Sbill rt_curend--; 748954Sbill rt_nleft++; 749954Sbill } 750954Sbill } 751954Sbill lwrite(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 752954Sbill } 753