1*3356Swnj static char *sccsid = "@(#)arff.c 4.4 (Berkeley) 81/03/22"; 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 { 9*3356Swnj unsigned short int rt_yr:5; /* Year - 1972 */ 10*3356Swnj unsigned short int rt_dy:5; /* day */ 11*3356Swnj unsigned short int rt_mo:5; /* month */ 12954Sbill }; 13954Sbill struct rt_axent { 14954Sbill char rt_sent[14]; 15954Sbill }; 16954Sbill 17954Sbill struct rt_ent { 18*3356Swnj char rt_pad; /* unusued */ 19*3356Swnj char rt_stat; /* Type of entry, or end of seg */ 20*3356Swnj unsigned short rt_name[3]; /* Name, 3 words in rad50 form */ 21*3356Swnj short rt_len; /* Length of file */ 22*3356Swnj char rt_chan; /* Only used in temporary files */ 23*3356Swnj char rt_job; /* Only used in temporary files */ 24*3356Swnj 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 313346Swnj #define RT_DIRSIZE 31 /* max # of directory segments */ 32954Sbill struct rt_head { 33*3356Swnj short rt_numseg; /* number of segments available */ 34*3356Swnj short rt_nxtseg; /* segment no of next log. seg */ 35*3356Swnj short rt_lstseg; /* highest seg currenltly open */ 36*3356Swnj unsigned short rt_entpad; /* extra words/dir. entry */ 37*3356Swnj short rt_stfile; /* block no where files begin */ 38954Sbill }; 39954Sbill struct rt_dir { 40954Sbill struct rt_head rt_axhead; 41954Sbill struct rt_ent rt_ents[72]; 42954Sbill char _dirpad[6]; 43954Sbill }; 443346Swnj extern struct rt_dir rt_dir[RT_DIRSIZE]; 45954Sbill extern int rt_entsiz; 46954Sbill extern int floppydes; 47954Sbill extern char *rt_last; 48954Sbill typedef struct fldope { 49954Sbill int startad; 50954Sbill int count; 51954Sbill struct rt_ent *rtdope; 52954Sbill } FLDOPE; 53954Sbill FLDOPE *lookup(); 54954Sbill #define rt(p) ((struct rt_ent *) p ) 55954Sbill #define Ain1 03100 56954Sbill #define Ain2 050 57954Sbill #define flag(c) (flg[(c) - 'a']) 58954Sbill 59954Sbill char *man = { "rxtd" }; 60954Sbill 61954Sbill char zeroes[512]; 62954Sbill extern char *val; 63954Sbill extern char table[256]; 643346Swnj struct rt_dir 653346Swnj rt_dir[RT_DIRSIZE] = {{4,0,1,0,14},{0,RT_NULL,{0,0,0},494,0}, {0,RT_ESEG}}; 66954Sbill int rt_entsiz; 67954Sbill int rt_nleft; 683346Swnj struct rt_ent *rt_curend[RT_DIRSIZE]; 69954Sbill int floppydes; 70954Sbill int dirdirty; 71954Sbill char *rt_last; 72954Sbill char *defdev = "/dev/floppy"; 73954Sbill 74954Sbill char *opt = { "vf" }; 75954Sbill 76954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 77954Sbill long lseek(); 78954Sbill int rcmd(); 79954Sbill int dcmd(); 80954Sbill int xcmd(); 81954Sbill int tcmd(); 82954Sbill int (*comfun)(); 83954Sbill char flg[26]; 84954Sbill char **namv; 85954Sbill int namc; 86954Sbill int file; 87954Sbill 88954Sbill 89954Sbill main(argc, argv) 90954Sbill char *argv[]; 91954Sbill { 92954Sbill register char *cp; 93954Sbill 94*3356Swnj /* register i; 95954Sbill for(i=0; signum[i]; i++) 96954Sbill if(signal(signum[i], SIG_IGN) != SIG_IGN) 97*3356Swnj signal(signum[i], sigdone); */ 98954Sbill if(argc < 2) 99954Sbill usage(); 100954Sbill cp = argv[1]; 101954Sbill for(cp = argv[1]; *cp; cp++) 102954Sbill switch(*cp) { 103954Sbill case 'm': 104954Sbill case 'v': 105954Sbill case 'u': 106954Sbill case 'w': 107954Sbill flg[*cp - 'a']++; 108954Sbill continue; 109954Sbill case 'c': 110954Sbill { 111954Sbill #define SURE "Are you sure you want to clobber the floppy?\n" 112954Sbill int tty; 1131735Sbill char response[128]; 114954Sbill tty = open("/dev/tty",2); 115954Sbill write(tty,SURE,sizeof(SURE)); 116*3356Swnj read(tty,response,sizeof(response)); 117954Sbill if(*response!='y') 118954Sbill exit(50); 119954Sbill flag('c')++; 120954Sbill close(tty); 121954Sbill } 122954Sbill dirdirty++; 123954Sbill continue; 124954Sbill 125954Sbill case 'r': 126954Sbill setcom(rcmd); 127954Sbill flag('r')++; 128954Sbill continue; 129954Sbill 130954Sbill case 'd': 131954Sbill setcom(dcmd); 132954Sbill flag('d')++; 133954Sbill continue; 134954Sbill 135954Sbill case 'x': 136954Sbill setcom(xcmd); 137954Sbill continue; 138954Sbill 139954Sbill case 't': 140954Sbill setcom(tcmd); 141954Sbill continue; 142954Sbill 143954Sbill case 'f': 144954Sbill defdev = argv[2]; 145954Sbill argv++; 146954Sbill argc--; 147954Sbill continue; 148954Sbill 149954Sbill 150954Sbill default: 151954Sbill fprintf(stderr, "arff: bad option `%c'\n", *cp); 152954Sbill exit(1); 153954Sbill } 154954Sbill namv = argv+2; 155954Sbill namc = argc-2; 156954Sbill if(comfun == 0) { 157954Sbill if(flg['u'-'a'] == 0) { 158954Sbill fprintf(stderr, "arff: one of [%s] must be specified\n", man); 159954Sbill exit(1); 160954Sbill } 161954Sbill setcom(rcmd); 162954Sbill } 163954Sbill (*comfun)(); 164954Sbill exit(notfound()); 165954Sbill } 166954Sbill 167954Sbill setcom(fun) 168954Sbill int (*fun)(); 169954Sbill { 170954Sbill 171954Sbill if(comfun != 0) { 172954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 173954Sbill exit(1); 174954Sbill } 175954Sbill comfun = fun; 176954Sbill } 177954Sbill 178954Sbill usage() 179954Sbill { 180*3356Swnj 181*3356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 182954Sbill exit(1); 183954Sbill } 184954Sbill 185954Sbill notfound() 186954Sbill { 187954Sbill register i, n; 188954Sbill 189954Sbill n = 0; 190954Sbill for(i=0; i<namc; i++) 191954Sbill if(namv[i]) { 192954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 193954Sbill n++; 194954Sbill } 195954Sbill return(n); 196954Sbill } 197954Sbill 198954Sbill phserr() 199954Sbill { 200954Sbill 201954Sbill fprintf(stderr, "arff: phase error on %s\n", file); 202954Sbill } 203954Sbill 204954Sbill mesg(c) 205954Sbill { 206954Sbill 207954Sbill if(flg['v'-'a']) 208954Sbill if(c != 'c' || flg['v'-'a'] > 1) 209954Sbill printf("%c - %s\n", c, file); 210954Sbill } 211954Sbill 212954Sbill tcmd() 213954Sbill { 214954Sbill register char *de; 2153346Swnj int segnum; 2163346Swnj register char *last; 217954Sbill FLDOPE *lookup(), *dope; 218954Sbill int nleft; register i; 219954Sbill register struct rt_ent *rde; 220954Sbill 221954Sbill rt_init(); 222954Sbill if(namc==0) 2233346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 2243346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 2253346Swnj last = rt_last + segnum*2*RT_BLOCK; 2263346Swnj for(de=((char *)&rt_dir[segnum])+10; de <= last; 2273346Swnj de += rt_entsiz) { 228954Sbill if(rtls(rt(de))) { 2293346Swnj nleft = (last - de) / rt_entsiz; 2303346Swnj printf("\n%d entries remaining",nleft); 2313346Swnj printf(" in directory segment %d.\n",segnum+1); 232954Sbill break; 233954Sbill } 234954Sbill } 2353346Swnj } 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; 2923346Swnj int segnum; 2933346Swnj register char *last; 294954Sbill char name[12]; 295954Sbill register int i; 296954Sbill 297954Sbill rt_init(); 298954Sbill if(namc==0) 2993346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 3003346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 3013346Swnj last = rt_last + segnum*2*RT_BLOCK; 3023346Swnj for(de=((char *)&rt_dir[segnum])+10; de <= last; 3033346Swnj de += rt_entsiz) { 304954Sbill sunrad50(name,rt(de)->rt_name); 305954Sbill rtx(name); 306954Sbill } 3073346Swnj } 308954Sbill else 309954Sbill for(i = 0; i < namc; i++) 310954Sbill if(rtx(namv[i])==0) namv[i] = 0; 311954Sbill } 312954Sbill rtx(name) 313954Sbill char *name; 314954Sbill { 315954Sbill register FLDOPE *dope; 316954Sbill FLDOPE *lookup(); 317954Sbill register startad, count; 318954Sbill int file; char buff[512]; 319954Sbill 320954Sbill 321954Sbill if(dope = lookup(name)) { 322954Sbill if(flg['v' - 'a']) 323954Sbill rtls(dope->rtdope); 324954Sbill else 325954Sbill printf("x - %s\n",name); 326954Sbill 327954Sbill file = creat(name, 0666); 328954Sbill if(file < 0) return(1); 329954Sbill count = dope->count; 330954Sbill startad = dope->startad; 331954Sbill for( ; count > 0 ; count -= 512) { 332954Sbill lread(startad,512,buff); 333954Sbill write(file,buff,512); 334954Sbill startad += 512; 335954Sbill } 336954Sbill close(file); 337954Sbill return(0); 338954Sbill } 339954Sbill return(1); 340954Sbill } 341954Sbill rt_init() 342954Sbill { 343954Sbill static initized = 0; 344954Sbill register char *de; 3453346Swnj register i; 3463346Swnj int mode, dirnum; 3473346Swnj register char *last; 348954Sbill 349954Sbill if(initized) return; 350954Sbill initized = 1; 351954Sbill if(flag('c') || flag('d') || flag('r')) 352954Sbill mode = 2; 353954Sbill else 354954Sbill mode = 0; 355*3356Swnj if((floppydes = open(defdev,mode)) < 0) { 356954Sbill dbprintf("Floppy open failed\n"); 357*3356Swnj exit(1); 358*3356Swnj } 3593346Swnj if(flag('c')==0) { 3603346Swnj lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]); 3613346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 3623346Swnj if (dirnum > RT_DIRSIZE) { 3633346Swnj fprintf(stderr,"arff: too many directory segments\n"); 3643346Swnj exit(1); 3653346Swnj } 3663346Swnj for (i=1; i<dirnum; i++) 3673346Swnj lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]); 3683346Swnj } 369954Sbill 3703346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3713346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3723346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3733346Swnj rt_nleft = 0; 3743346Swnj 3753346Swnj for (i=0; i<dirnum; i++) { 3763346Swnj last = rt_last + i*2*RT_BLOCK; 3773346Swnj for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 378954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 3793346Swnj } 3803346Swnj rt_curend[i] = rt(de); 3813346Swnj rt_nleft += (last - de) / rt_entsiz; 382954Sbill } 383954Sbill } 384954Sbill 385954Sbill static FLDOPE result; 386954Sbill FLDOPE * 387954Sbill lookup(name) 388954Sbill char * name; 389954Sbill { 390954Sbill unsigned short rname[3]; 391954Sbill register char *de; 3923346Swnj int segnum; 3933346Swnj register char *last; 394954Sbill register index; 395954Sbill 396954Sbill srad50(name,rname); 397954Sbill 398*3356Swnj /* 399954Sbill * Search for name, accumulate blocks in index 400954Sbill */ 401954Sbill rt_init(); 4023346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 4033346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 4043346Swnj index = 0; 4053346Swnj last = rt_last + segnum*2*RT_BLOCK; 4063346Swnj for(de=((char *)&rt_dir[segnum])+10; 4073346Swnj rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 408954Sbill switch(rt(de)->rt_stat) { 409954Sbill case RT_FILE: 410954Sbill case RT_TEMP: 411954Sbill if(samename(rname,rt(de)->rt_name)) 412954Sbill goto found; 413954Sbill case RT_NULL: 414954Sbill index += rt(de)->rt_len; 415954Sbill } 4163346Swnj } 4173346Swnj } 418954Sbill return((FLDOPE *) 0); 419954Sbill found: result.count = rt(de)->rt_len * 512; 4203346Swnj result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 421954Sbill result.rtdope = (struct rt_ent *) de; 422954Sbill return(&result); 423954Sbill } 424954Sbill static 425954Sbill samename(a,b) 426954Sbill unsigned short a[3],b[3]; 427954Sbill { 428954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 429954Sbill } 430954Sbill 431954Sbill 432954Sbill rad50(cp,out) 433954Sbill register unsigned char *cp; 434954Sbill unsigned short *out; 435954Sbill { 436954Sbill register index; 437954Sbill register temp; 438954Sbill 439954Sbill for(index = 0;*cp; index++) { 440954Sbill 441954Sbill temp = Ain1 * table[*cp++]; 442954Sbill if(*cp!=0) { 443954Sbill temp += Ain2 * table[*cp++]; 444954Sbill 445954Sbill if(*cp!=0) 446954Sbill temp += table[*cp++]; 447954Sbill } 448954Sbill 449954Sbill out[index] = temp; 450954Sbill } 451954Sbill } 452954Sbill #define reduce(x,p,q) \ 453954Sbill (x = v[p/q], p %= q); 454954Sbill 455954Sbill unrad50(count,in,cp) 456954Sbill unsigned short *in; 457954Sbill register char *cp; 458954Sbill { 459954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 460954Sbill 461954Sbill for(i = 0; i < count; i++) { 462954Sbill temp = in[i]; 463954Sbill 464954Sbill reduce (*cp++,temp,Ain1); 465954Sbill reduce (*cp++,temp,Ain2); 466954Sbill reduce (*cp++,temp,1); 467954Sbill } 468954Sbill *cp=0; 469954Sbill } 470954Sbill 471954Sbill srad50(name,rname) 472954Sbill register char * name; 473954Sbill register unsigned short *rname; 474954Sbill { 475954Sbill register index; register char *cp; 476954Sbill char file[7],ext[4]; 477*3356Swnj /* 478954Sbill * Find end of pathname 479954Sbill */ 480954Sbill for(cp = name; *cp++; ); 481954Sbill while(cp >= name && *--cp != '/'); 482954Sbill cp++; 483*3356Swnj /* 484954Sbill * Change to rad50 485954Sbill * 486954Sbill */ 487954Sbill for(index = 0; *cp; ){ 488954Sbill file[index++] = *cp++; 489954Sbill if(*cp=='.') { 490954Sbill cp++; 491954Sbill break; 492954Sbill } 493954Sbill if(index>=6) { 494954Sbill break; 495954Sbill } 496954Sbill } 497954Sbill file[index] = 0; 498954Sbill for(index = 0; *cp; ){ 499954Sbill ext[index++] = *cp++; 500954Sbill if(*cp=='.' || index>=3) { 501954Sbill break; 502954Sbill } 503954Sbill } 504954Sbill ext[index]=0; 505954Sbill rname[0] = 0; 506954Sbill rname[1] = 0; 507954Sbill rname[2] = 0; 508954Sbill rad50((unsigned char *)file,rname); 509954Sbill rad50((unsigned char *)ext,rname+2); 510954Sbill } 511954Sbill sunrad50(name,rname) 512954Sbill unsigned short rname[3]; 513954Sbill register char *name; 514954Sbill { 515954Sbill register char *cp, *cp2; 516954Sbill char ext[4]; 517954Sbill 518954Sbill unrad50(2,rname,name); 519954Sbill unrad50(1,rname + 2,ext); 520954Sbill /* Jam name and extension together with a dot 521954Sbill deleting white space */ 522954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 523954Sbill *++cp = '.';cp++; 524954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 525954Sbill *cp++ = *cp2++; 526954Sbill } 527954Sbill *cp=0; 528954Sbill if(cp[-1]=='.') cp[-1] = 0; 529954Sbill } 530954Sbill 531954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 532954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 533954Sbill static char table[256] = { 534954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 535954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 536954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 537954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 538954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 539954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 540954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 541954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 542954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 543954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 544954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 545954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 546954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 547954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 548954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 549954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 550954Sbill 551954Sbill long trans(logical) 552954Sbill register int logical; 553954Sbill { 554954Sbill /* Logical to physical adress translation */ 555954Sbill register int sector, bytes, track; 556954Sbill 557954Sbill logical += 26 * 128; 558954Sbill bytes = (logical & 127); 559954Sbill logical >>= 7; 560954Sbill sector = logical % 26; 561954Sbill if(sector >= 13) 562954Sbill sector = sector *2 +1; 563954Sbill else 564954Sbill sector *= 2; 565954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 566954Sbill sector %= 26; 567954Sbill return( (((track *26) + sector) << 7) + bytes); 568954Sbill } 569954Sbill lread(startad,count,obuff) 570954Sbill register startad, count; 571954Sbill register char * obuff; 572954Sbill { 573954Sbill long trans(); 574954Sbill extern floppydes; 575954Sbill rt_init(); 576954Sbill if(flg['m'-'a']==0) 577954Sbill while( (count -= 128) >= 0) { 578954Sbill lseek(floppydes, trans(startad), 0); 579*3356Swnj if (read(floppydes,obuff,128) != 128) 580*3356Swnj fprintf(stderr, "arff: read error block %d\n",startad/128); 581954Sbill obuff += 128; 582954Sbill startad += 128; 583954Sbill } 584954Sbill else 585954Sbill while( (count -= 512) >= 0) { 586954Sbill lseek(floppydes,(long) (startad), 0); 587*3356Swnj fprintf(stderr, "arff: read error block %d\n",startad/512); 588954Sbill obuff += 512; 589954Sbill startad += 512; 590954Sbill } 591954Sbill } 592954Sbill lwrite(startad,count,obuff) 593954Sbill register startad, count; 594954Sbill register char * obuff; 595954Sbill { 596954Sbill long trans(); 597954Sbill extern floppydes; 598954Sbill rt_init(); 599954Sbill if(flg['m'-'a']==0) 600954Sbill while( (count -= 128) >= 0) { 601954Sbill lseek(floppydes, trans(startad), 0); 602*3356Swnj if ( write(floppydes,obuff,128) != 128) 603*3356Swnj fprintf(stderr, "arff: write error block %d\n",startad/128); 604954Sbill obuff += 128; 605954Sbill startad += 128; 606954Sbill } 607954Sbill else 608954Sbill while( (count -= 512) >= 0) { 609954Sbill lseek(floppydes,(long) (startad), 0); 610*3356Swnj if ( write(floppydes,obuff,512) != 512) 611*3356Swnj fprintf(stderr, "arff: write error block %d\n",startad/512); 612954Sbill obuff += 512; 613954Sbill startad += 512; 614954Sbill } 615954Sbill } 616954Sbill 617954Sbill rcmd() 618954Sbill { 619954Sbill register int i; 620954Sbill 621954Sbill rt_init(); 622954Sbill if(namc>0) 623954Sbill for(i = 0; i < namc; i++) 624*3356Swnj if(rtr(namv[i])==0) namv[i]=0; 625954Sbill 626954Sbill 627954Sbill } 628954Sbill 629954Sbill rtr(name) 630954Sbill char *name; 631954Sbill { 632954Sbill register FLDOPE *dope; register struct rt_ent *de; 633954Sbill struct stat buf; register struct stat *bufp = &buf; 6343346Swnj int segnum; 6353346Swnj register char *last; 636954Sbill 637954Sbill if(stat(name,bufp)<0) return(1); 638954Sbill if(dope = lookup(name)) { 639954Sbill /* can replace, no problem */ 640954Sbill de = dope->rtdope; 641954Sbill if(bufp->st_size <= (de->rt_len * 512)) 642954Sbill printf("r - %s\n",name), 643954Sbill toflop(name,bufp->st_size,dope); 644954Sbill else { 645*3356Swnj fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 646954Sbill return(1); 647954Sbill } 648954Sbill } else { 6493346Swnj /* Search for vacant spot */ 6503346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 6513346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 6523346Swnj last = rt_last + segnum*2*RT_BLOCK; 6533346Swnj for(de = rt_dir[segnum].rt_ents; 6543346Swnj rt(de)->rt_stat != RT_ESEG; de++) { 655954Sbill switch((de)->rt_stat) { 656954Sbill case RT_NULL: 657954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 658954Sbill printf("a - %s\n",name), 6593346Swnj mkent(de,segnum,bufp,name); 660954Sbill goto found; 661954Sbill } 662954Sbill continue; 663954Sbill } 664954Sbill } 6653346Swnj } 6663346Swnj return(3); 667954Sbill } 668954Sbill found: if(dope=lookup(name)) { 669954Sbill toflop(name,bufp->st_size,dope); 670954Sbill return(0); 671954Sbill } 672954Sbill return(7); 673954Sbill 674954Sbill } 6753346Swnj mkent(de,segnum,bufp,name) 676954Sbill register struct rt_ent *de; 6773346Swnj int segnum; 678954Sbill register struct stat *bufp; 679954Sbill char *name; 680954Sbill { 681954Sbill struct tm *localtime(); register struct tm *timp; 682954Sbill register struct rt_ent *workp; int count; 683954Sbill 684954Sbill count = (((bufp->st_size -1) >>9) + 1); 685954Sbill /* Make sure there is room */ 686954Sbill if(de->rt_len==count) 687954Sbill goto overwrite; 6883346Swnj if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 6893346Swnj /* no entries left on segment */ 690954Sbill if(flg['o'-'a']) 691954Sbill goto overwrite; 6923346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 6933346Swnj defdev); 694954Sbill exit(1); 695954Sbill } 696954Sbill /* copy directory entries up */ 6973346Swnj for(workp = rt_curend[segnum]+1; workp > de; workp--) 698954Sbill *workp = workp[-1]; 699954Sbill de[1].rt_len -= count; 700954Sbill de->rt_len = count; 7013346Swnj rt_curend[segnum]++; 702954Sbill rt_nleft--; 703954Sbill overwrite: 704954Sbill srad50(name,de->rt_name); 705954Sbill timp = localtime(&bufp->st_mtime); 706954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 707954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 708954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 709954Sbill de->rt_stat = RT_FILE; 710954Sbill de->rt_pad = 0; 711954Sbill de->rt_chan = 0; 712954Sbill de->rt_job = 0; 7133346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 714954Sbill } 715954Sbill 716954Sbill toflop(name,ocount,dope) 717954Sbill char *name; 718954Sbill register FLDOPE *dope; 719954Sbill long ocount; 720954Sbill { 721954Sbill register file, n, startad = dope->startad, count = ocount; 722954Sbill char buff[512]; 723954Sbill 724954Sbill file = open(name,0); 725954Sbill if(file < 0) { 726*3356Swnj fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);} 727954Sbill for( ; count >= 512; count -= 512) { 728954Sbill read(file,buff,512); 729954Sbill lwrite(startad,512,buff); 730954Sbill startad += 512; 731954Sbill } 732954Sbill read(file,buff,count); 733954Sbill close(file); 734954Sbill if(count <= 0) return; 735954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 736954Sbill lwrite(startad,512,buff); 737954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 738954Sbill if(count <= 0) return; 739954Sbill for( ; count > 0 ; count--) { 740954Sbill startad += 512; 741954Sbill lwrite(startad,512,zeroes); 742954Sbill } 743954Sbill 744954Sbill } 745954Sbill dcmd() 746954Sbill { 747954Sbill register int i; 748954Sbill 749954Sbill rt_init(); 750954Sbill if(namc) 751954Sbill for(i = 0; i < namc; i++) 752954Sbill if(rtk(namv[i])==0) namv[i]=0; 753954Sbill if(dirdirty) 754954Sbill scrunch(); 755954Sbill 756954Sbill } 757954Sbill rtk(name) 758954Sbill char *name; 759954Sbill { 760954Sbill register FLDOPE *dope; 761954Sbill register struct rt_ent *de; 762954Sbill FLDOPE *lookup(); 763954Sbill 764954Sbill if(dope = lookup(name)) { 765954Sbill printf("d - %s\n",name); 766954Sbill de = dope->rtdope; 767954Sbill de->rt_stat = RT_NULL; 768954Sbill de->rt_name[0] = 0; 769954Sbill de->rt_name[1] = 0; 770954Sbill de->rt_name[2] = 0; 771954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 772954Sbill dirdirty = 1; 773954Sbill return(0); 774954Sbill } 775954Sbill return(1); 776954Sbill } 777954Sbill scrunch() { 7783346Swnj register struct rt_ent *de , *workp; 7793346Swnj register segnum; 7803346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 7813346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 7823346Swnj dirdirty = 0; 7833346Swnj for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 784954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 785954Sbill (de+1)->rt_len += de->rt_len; 7863346Swnj for(workp = de; workp < rt_curend[segnum]; workp++) 787954Sbill *workp = workp[1]; 788954Sbill de--; 7893346Swnj rt_curend[segnum]--; 790954Sbill rt_nleft++; 7913346Swnj dirdirty = 1; 792954Sbill } 7933346Swnj } 7943346Swnj if (dirdirty) 7953346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 796954Sbill } 797954Sbill } 798