1*3489Sroot static char *sccsid = "@(#)arff.c 4.5 (Berkeley) 81/04/08"; 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 { 93356Swnj unsigned short int rt_yr:5; /* Year - 1972 */ 103356Swnj unsigned short int rt_dy:5; /* day */ 113356Swnj unsigned short int rt_mo:5; /* month */ 12954Sbill }; 13954Sbill struct rt_axent { 14954Sbill char rt_sent[14]; 15954Sbill }; 16954Sbill 17954Sbill struct rt_ent { 183356Swnj char rt_pad; /* unusued */ 193356Swnj char rt_stat; /* Type of entry, or end of seg */ 203356Swnj unsigned short rt_name[3]; /* Name, 3 words in rad50 form */ 213356Swnj short rt_len; /* Length of file */ 223356Swnj char rt_chan; /* Only used in temporary files */ 233356Swnj char rt_job; /* Only used in temporary files */ 243356Swnj 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 { 333356Swnj short rt_numseg; /* number of segments available */ 343356Swnj short rt_nxtseg; /* segment no of next log. seg */ 353356Swnj short rt_lstseg; /* highest seg currenltly open */ 363356Swnj unsigned short rt_entpad; /* extra words/dir. entry */ 373356Swnj 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 65*3489Sroot 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 943356Swnj /* register i; 95954Sbill for(i=0; signum[i]; i++) 96954Sbill if(signal(signum[i], SIG_IGN) != SIG_IGN) 973356Swnj 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)); 1163356Swnj 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 { 1803356Swnj 1813356Swnj 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; 3553356Swnj if((floppydes = open(defdev,mode)) < 0) { 356954Sbill dbprintf("Floppy open failed\n"); 3573356Swnj exit(1); 3583356Swnj } 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]); 368*3489Sroot } else 369*3489Sroot dirnum = 1; 370954Sbill 3713346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3723346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3733346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3743346Swnj rt_nleft = 0; 3753346Swnj 3763346Swnj for (i=0; i<dirnum; i++) { 3773346Swnj last = rt_last + i*2*RT_BLOCK; 3783346Swnj for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 379954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 3803346Swnj } 3813346Swnj rt_curend[i] = rt(de); 3823346Swnj rt_nleft += (last - de) / rt_entsiz; 383954Sbill } 384954Sbill } 385954Sbill 386954Sbill static FLDOPE result; 387954Sbill FLDOPE * 388954Sbill lookup(name) 389954Sbill char * name; 390954Sbill { 391954Sbill unsigned short rname[3]; 392954Sbill register char *de; 3933346Swnj int segnum; 3943346Swnj register char *last; 395954Sbill register index; 396954Sbill 397954Sbill srad50(name,rname); 398954Sbill 3993356Swnj /* 400954Sbill * Search for name, accumulate blocks in index 401954Sbill */ 402954Sbill rt_init(); 4033346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 4043346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 4053346Swnj index = 0; 4063346Swnj last = rt_last + segnum*2*RT_BLOCK; 4073346Swnj for(de=((char *)&rt_dir[segnum])+10; 4083346Swnj rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 409954Sbill switch(rt(de)->rt_stat) { 410954Sbill case RT_FILE: 411954Sbill case RT_TEMP: 412954Sbill if(samename(rname,rt(de)->rt_name)) 413954Sbill goto found; 414954Sbill case RT_NULL: 415954Sbill index += rt(de)->rt_len; 416954Sbill } 4173346Swnj } 4183346Swnj } 419954Sbill return((FLDOPE *) 0); 420954Sbill found: result.count = rt(de)->rt_len * 512; 4213346Swnj result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 422954Sbill result.rtdope = (struct rt_ent *) de; 423954Sbill return(&result); 424954Sbill } 425954Sbill static 426954Sbill samename(a,b) 427954Sbill unsigned short a[3],b[3]; 428954Sbill { 429954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 430954Sbill } 431954Sbill 432954Sbill 433954Sbill rad50(cp,out) 434954Sbill register unsigned char *cp; 435954Sbill unsigned short *out; 436954Sbill { 437954Sbill register index; 438954Sbill register temp; 439954Sbill 440954Sbill for(index = 0;*cp; index++) { 441954Sbill 442954Sbill temp = Ain1 * table[*cp++]; 443954Sbill if(*cp!=0) { 444954Sbill temp += Ain2 * table[*cp++]; 445954Sbill 446954Sbill if(*cp!=0) 447954Sbill temp += table[*cp++]; 448954Sbill } 449954Sbill 450954Sbill out[index] = temp; 451954Sbill } 452954Sbill } 453954Sbill #define reduce(x,p,q) \ 454954Sbill (x = v[p/q], p %= q); 455954Sbill 456954Sbill unrad50(count,in,cp) 457954Sbill unsigned short *in; 458954Sbill register char *cp; 459954Sbill { 460954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 461954Sbill 462954Sbill for(i = 0; i < count; i++) { 463954Sbill temp = in[i]; 464954Sbill 465954Sbill reduce (*cp++,temp,Ain1); 466954Sbill reduce (*cp++,temp,Ain2); 467954Sbill reduce (*cp++,temp,1); 468954Sbill } 469954Sbill *cp=0; 470954Sbill } 471954Sbill 472954Sbill srad50(name,rname) 473954Sbill register char * name; 474954Sbill register unsigned short *rname; 475954Sbill { 476954Sbill register index; register char *cp; 477954Sbill char file[7],ext[4]; 4783356Swnj /* 479954Sbill * Find end of pathname 480954Sbill */ 481954Sbill for(cp = name; *cp++; ); 482954Sbill while(cp >= name && *--cp != '/'); 483954Sbill cp++; 4843356Swnj /* 485954Sbill * Change to rad50 486954Sbill * 487954Sbill */ 488954Sbill for(index = 0; *cp; ){ 489954Sbill file[index++] = *cp++; 490954Sbill if(*cp=='.') { 491954Sbill cp++; 492954Sbill break; 493954Sbill } 494954Sbill if(index>=6) { 495954Sbill break; 496954Sbill } 497954Sbill } 498954Sbill file[index] = 0; 499954Sbill for(index = 0; *cp; ){ 500954Sbill ext[index++] = *cp++; 501954Sbill if(*cp=='.' || index>=3) { 502954Sbill break; 503954Sbill } 504954Sbill } 505954Sbill ext[index]=0; 506954Sbill rname[0] = 0; 507954Sbill rname[1] = 0; 508954Sbill rname[2] = 0; 509954Sbill rad50((unsigned char *)file,rname); 510954Sbill rad50((unsigned char *)ext,rname+2); 511954Sbill } 512954Sbill sunrad50(name,rname) 513954Sbill unsigned short rname[3]; 514954Sbill register char *name; 515954Sbill { 516954Sbill register char *cp, *cp2; 517954Sbill char ext[4]; 518954Sbill 519954Sbill unrad50(2,rname,name); 520954Sbill unrad50(1,rname + 2,ext); 521954Sbill /* Jam name and extension together with a dot 522954Sbill deleting white space */ 523954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 524954Sbill *++cp = '.';cp++; 525954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 526954Sbill *cp++ = *cp2++; 527954Sbill } 528954Sbill *cp=0; 529954Sbill if(cp[-1]=='.') cp[-1] = 0; 530954Sbill } 531954Sbill 532954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 533954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 534954Sbill static char table[256] = { 535954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 536954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 537954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 538954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 539954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 540954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 541954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 542954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 543954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 544954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 545954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 546954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 547954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 548954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 549954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 550954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 551954Sbill 552954Sbill long trans(logical) 553954Sbill register int logical; 554954Sbill { 555954Sbill /* Logical to physical adress translation */ 556954Sbill register int sector, bytes, track; 557954Sbill 558954Sbill logical += 26 * 128; 559954Sbill bytes = (logical & 127); 560954Sbill logical >>= 7; 561954Sbill sector = logical % 26; 562954Sbill if(sector >= 13) 563954Sbill sector = sector *2 +1; 564954Sbill else 565954Sbill sector *= 2; 566954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 567954Sbill sector %= 26; 568954Sbill return( (((track *26) + sector) << 7) + bytes); 569954Sbill } 570954Sbill lread(startad,count,obuff) 571954Sbill register startad, count; 572954Sbill register char * obuff; 573954Sbill { 574954Sbill long trans(); 575954Sbill extern floppydes; 576954Sbill rt_init(); 577954Sbill if(flg['m'-'a']==0) 578954Sbill while( (count -= 128) >= 0) { 579954Sbill lseek(floppydes, trans(startad), 0); 5803356Swnj if (read(floppydes,obuff,128) != 128) 5813356Swnj fprintf(stderr, "arff: read error block %d\n",startad/128); 582954Sbill obuff += 128; 583954Sbill startad += 128; 584954Sbill } 585954Sbill else 586954Sbill while( (count -= 512) >= 0) { 587954Sbill lseek(floppydes,(long) (startad), 0); 5883356Swnj fprintf(stderr, "arff: read error block %d\n",startad/512); 589954Sbill obuff += 512; 590954Sbill startad += 512; 591954Sbill } 592954Sbill } 593954Sbill lwrite(startad,count,obuff) 594954Sbill register startad, count; 595954Sbill register char * obuff; 596954Sbill { 597954Sbill long trans(); 598954Sbill extern floppydes; 599954Sbill rt_init(); 600954Sbill if(flg['m'-'a']==0) 601954Sbill while( (count -= 128) >= 0) { 602954Sbill lseek(floppydes, trans(startad), 0); 6033356Swnj if ( write(floppydes,obuff,128) != 128) 6043356Swnj fprintf(stderr, "arff: write error block %d\n",startad/128); 605954Sbill obuff += 128; 606954Sbill startad += 128; 607954Sbill } 608954Sbill else 609954Sbill while( (count -= 512) >= 0) { 610954Sbill lseek(floppydes,(long) (startad), 0); 6113356Swnj if ( write(floppydes,obuff,512) != 512) 6123356Swnj fprintf(stderr, "arff: write error block %d\n",startad/512); 613954Sbill obuff += 512; 614954Sbill startad += 512; 615954Sbill } 616954Sbill } 617954Sbill 618954Sbill rcmd() 619954Sbill { 620954Sbill register int i; 621954Sbill 622954Sbill rt_init(); 623*3489Sroot if (namc>0) 624954Sbill for(i = 0; i < namc; i++) 6253356Swnj if(rtr(namv[i])==0) namv[i]=0; 626954Sbill } 627954Sbill 628954Sbill rtr(name) 629954Sbill char *name; 630954Sbill { 631954Sbill register FLDOPE *dope; register struct rt_ent *de; 632954Sbill struct stat buf; register struct stat *bufp = &buf; 6333346Swnj int segnum; 6343346Swnj register char *last; 635954Sbill 636*3489Sroot if(stat(name,bufp)<0) { 637*3489Sroot perror(name); 638*3489Sroot return(-1); 639*3489Sroot } 640954Sbill if(dope = lookup(name)) { 641954Sbill /* can replace, no problem */ 642954Sbill de = dope->rtdope; 643954Sbill if(bufp->st_size <= (de->rt_len * 512)) 644954Sbill printf("r - %s\n",name), 645954Sbill toflop(name,bufp->st_size,dope); 646954Sbill else { 6473356Swnj fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 648*3489Sroot return(-1); 649954Sbill } 650954Sbill } else { 6513346Swnj /* Search for vacant spot */ 6523346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 6533346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 6543346Swnj last = rt_last + segnum*2*RT_BLOCK; 6553346Swnj for(de = rt_dir[segnum].rt_ents; 6563346Swnj rt(de)->rt_stat != RT_ESEG; de++) { 657954Sbill switch((de)->rt_stat) { 658954Sbill case RT_NULL: 659954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 660954Sbill printf("a - %s\n",name), 6613346Swnj mkent(de,segnum,bufp,name); 662954Sbill goto found; 663954Sbill } 664954Sbill continue; 665954Sbill } 666954Sbill } 6673346Swnj } 668*3489Sroot printf("%s: no slot for file\n", name); 669*3489Sroot return (-1); 670954Sbill } 671954Sbill found: if(dope=lookup(name)) { 672954Sbill toflop(name,bufp->st_size,dope); 673*3489Sroot return (0); 674954Sbill } 675*3489Sroot printf("%s: internal error, added then not found\n", name); 676*3489Sroot return (-1); 677954Sbill 678954Sbill } 6793346Swnj mkent(de,segnum,bufp,name) 680954Sbill register struct rt_ent *de; 6813346Swnj int segnum; 682954Sbill register struct stat *bufp; 683954Sbill char *name; 684954Sbill { 685954Sbill struct tm *localtime(); register struct tm *timp; 686954Sbill register struct rt_ent *workp; int count; 687954Sbill 688954Sbill count = (((bufp->st_size -1) >>9) + 1); 689954Sbill /* Make sure there is room */ 690954Sbill if(de->rt_len==count) 691954Sbill goto overwrite; 6923346Swnj if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 6933346Swnj /* no entries left on segment */ 694954Sbill if(flg['o'-'a']) 695954Sbill goto overwrite; 6963346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 6973346Swnj defdev); 698954Sbill exit(1); 699954Sbill } 700954Sbill /* copy directory entries up */ 7013346Swnj for(workp = rt_curend[segnum]+1; workp > de; workp--) 702954Sbill *workp = workp[-1]; 703954Sbill de[1].rt_len -= count; 704954Sbill de->rt_len = count; 7053346Swnj rt_curend[segnum]++; 706954Sbill rt_nleft--; 707954Sbill overwrite: 708954Sbill srad50(name,de->rt_name); 709954Sbill timp = localtime(&bufp->st_mtime); 710954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 711954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 712954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 713954Sbill de->rt_stat = RT_FILE; 714954Sbill de->rt_pad = 0; 715954Sbill de->rt_chan = 0; 716954Sbill de->rt_job = 0; 7173346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 718954Sbill } 719954Sbill 720954Sbill toflop(name,ocount,dope) 721954Sbill char *name; 722954Sbill register FLDOPE *dope; 723954Sbill long ocount; 724954Sbill { 725954Sbill register file, n, startad = dope->startad, count = ocount; 726954Sbill char buff[512]; 727954Sbill 728954Sbill file = open(name,0); 729954Sbill if(file < 0) { 7303356Swnj fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);} 731954Sbill for( ; count >= 512; count -= 512) { 732954Sbill read(file,buff,512); 733954Sbill lwrite(startad,512,buff); 734954Sbill startad += 512; 735954Sbill } 736954Sbill read(file,buff,count); 737954Sbill close(file); 738954Sbill if(count <= 0) return; 739954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 740954Sbill lwrite(startad,512,buff); 741954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 742954Sbill if(count <= 0) return; 743954Sbill for( ; count > 0 ; count--) { 744954Sbill startad += 512; 745954Sbill lwrite(startad,512,zeroes); 746954Sbill } 747954Sbill 748954Sbill } 749954Sbill dcmd() 750954Sbill { 751954Sbill register int i; 752954Sbill 753954Sbill rt_init(); 754954Sbill if(namc) 755954Sbill for(i = 0; i < namc; i++) 756954Sbill if(rtk(namv[i])==0) namv[i]=0; 757954Sbill if(dirdirty) 758954Sbill scrunch(); 759954Sbill 760954Sbill } 761954Sbill rtk(name) 762954Sbill char *name; 763954Sbill { 764954Sbill register FLDOPE *dope; 765954Sbill register struct rt_ent *de; 766954Sbill FLDOPE *lookup(); 767954Sbill 768954Sbill if(dope = lookup(name)) { 769954Sbill printf("d - %s\n",name); 770954Sbill de = dope->rtdope; 771954Sbill de->rt_stat = RT_NULL; 772954Sbill de->rt_name[0] = 0; 773954Sbill de->rt_name[1] = 0; 774954Sbill de->rt_name[2] = 0; 775954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 776954Sbill dirdirty = 1; 777954Sbill return(0); 778954Sbill } 779954Sbill return(1); 780954Sbill } 781954Sbill scrunch() { 7823346Swnj register struct rt_ent *de , *workp; 7833346Swnj register segnum; 7843346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 7853346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 7863346Swnj dirdirty = 0; 7873346Swnj for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 788954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 789954Sbill (de+1)->rt_len += de->rt_len; 7903346Swnj for(workp = de; workp < rt_curend[segnum]; workp++) 791954Sbill *workp = workp[1]; 792954Sbill de--; 7933346Swnj rt_curend[segnum]--; 794954Sbill rt_nleft++; 7953346Swnj dirdirty = 1; 796954Sbill } 7973346Swnj } 7983346Swnj if (dirdirty) 7993346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 800954Sbill } 801954Sbill } 802