1*3799Shickman static char *sccsid = "@(#)arff.c 4.6 (Berkeley) 81/05/18"; 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 653489Sroot 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; 346*3799Shickman int dirnum; 347*3799Shickman char *mode; 3483346Swnj register char *last; 349*3799Shickman FILE *temp_floppydes; 350954Sbill 351954Sbill if(initized) return; 352954Sbill initized = 1; 353954Sbill if(flag('c') || flag('d') || flag('r')) 354*3799Shickman mode = "r+"; 355954Sbill else 356*3799Shickman mode = "r"; 357*3799Shickman if((temp_floppydes = fopen(defdev, mode)) == NULL) { 358*3799Shickman perror(defdev); 3593356Swnj exit(1); 360*3799Shickman } else 361*3799Shickman floppydes = fileno(temp_floppydes); 3623346Swnj if(flag('c')==0) { 3633346Swnj lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]); 3643346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 3653346Swnj if (dirnum > RT_DIRSIZE) { 3663346Swnj fprintf(stderr,"arff: too many directory segments\n"); 3673346Swnj exit(1); 3683346Swnj } 3693346Swnj for (i=1; i<dirnum; i++) 3703346Swnj lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]); 3713489Sroot } else 3723489Sroot dirnum = 1; 373954Sbill 3743346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3753346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3763346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3773346Swnj rt_nleft = 0; 3783346Swnj 3793346Swnj for (i=0; i<dirnum; i++) { 3803346Swnj last = rt_last + i*2*RT_BLOCK; 3813346Swnj for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 382954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 3833346Swnj } 3843346Swnj rt_curend[i] = rt(de); 3853346Swnj rt_nleft += (last - de) / rt_entsiz; 386954Sbill } 387954Sbill } 388954Sbill 389954Sbill static FLDOPE result; 390954Sbill FLDOPE * 391954Sbill lookup(name) 392954Sbill char * name; 393954Sbill { 394954Sbill unsigned short rname[3]; 395954Sbill register char *de; 3963346Swnj int segnum; 3973346Swnj register char *last; 398954Sbill register index; 399954Sbill 400954Sbill srad50(name,rname); 401954Sbill 4023356Swnj /* 403954Sbill * Search for name, accumulate blocks in index 404954Sbill */ 405954Sbill rt_init(); 4063346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 4073346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 4083346Swnj index = 0; 4093346Swnj last = rt_last + segnum*2*RT_BLOCK; 4103346Swnj for(de=((char *)&rt_dir[segnum])+10; 4113346Swnj rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 412954Sbill switch(rt(de)->rt_stat) { 413954Sbill case RT_FILE: 414954Sbill case RT_TEMP: 415954Sbill if(samename(rname,rt(de)->rt_name)) 416954Sbill goto found; 417954Sbill case RT_NULL: 418954Sbill index += rt(de)->rt_len; 419954Sbill } 4203346Swnj } 4213346Swnj } 422954Sbill return((FLDOPE *) 0); 423954Sbill found: result.count = rt(de)->rt_len * 512; 4243346Swnj result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 425954Sbill result.rtdope = (struct rt_ent *) de; 426954Sbill return(&result); 427954Sbill } 428954Sbill static 429954Sbill samename(a,b) 430954Sbill unsigned short a[3],b[3]; 431954Sbill { 432954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 433954Sbill } 434954Sbill 435954Sbill 436954Sbill rad50(cp,out) 437954Sbill register unsigned char *cp; 438954Sbill unsigned short *out; 439954Sbill { 440954Sbill register index; 441954Sbill register temp; 442954Sbill 443954Sbill for(index = 0;*cp; index++) { 444954Sbill 445954Sbill temp = Ain1 * table[*cp++]; 446954Sbill if(*cp!=0) { 447954Sbill temp += Ain2 * table[*cp++]; 448954Sbill 449954Sbill if(*cp!=0) 450954Sbill temp += table[*cp++]; 451954Sbill } 452954Sbill 453954Sbill out[index] = temp; 454954Sbill } 455954Sbill } 456954Sbill #define reduce(x,p,q) \ 457954Sbill (x = v[p/q], p %= q); 458954Sbill 459954Sbill unrad50(count,in,cp) 460954Sbill unsigned short *in; 461954Sbill register char *cp; 462954Sbill { 463954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 464954Sbill 465954Sbill for(i = 0; i < count; i++) { 466954Sbill temp = in[i]; 467954Sbill 468954Sbill reduce (*cp++,temp,Ain1); 469954Sbill reduce (*cp++,temp,Ain2); 470954Sbill reduce (*cp++,temp,1); 471954Sbill } 472954Sbill *cp=0; 473954Sbill } 474954Sbill 475954Sbill srad50(name,rname) 476954Sbill register char * name; 477954Sbill register unsigned short *rname; 478954Sbill { 479954Sbill register index; register char *cp; 480954Sbill char file[7],ext[4]; 4813356Swnj /* 482954Sbill * Find end of pathname 483954Sbill */ 484954Sbill for(cp = name; *cp++; ); 485954Sbill while(cp >= name && *--cp != '/'); 486954Sbill cp++; 4873356Swnj /* 488954Sbill * Change to rad50 489954Sbill * 490954Sbill */ 491954Sbill for(index = 0; *cp; ){ 492954Sbill file[index++] = *cp++; 493954Sbill if(*cp=='.') { 494954Sbill cp++; 495954Sbill break; 496954Sbill } 497954Sbill if(index>=6) { 498954Sbill break; 499954Sbill } 500954Sbill } 501954Sbill file[index] = 0; 502954Sbill for(index = 0; *cp; ){ 503954Sbill ext[index++] = *cp++; 504954Sbill if(*cp=='.' || index>=3) { 505954Sbill break; 506954Sbill } 507954Sbill } 508954Sbill ext[index]=0; 509954Sbill rname[0] = 0; 510954Sbill rname[1] = 0; 511954Sbill rname[2] = 0; 512954Sbill rad50((unsigned char *)file,rname); 513954Sbill rad50((unsigned char *)ext,rname+2); 514954Sbill } 515954Sbill sunrad50(name,rname) 516954Sbill unsigned short rname[3]; 517954Sbill register char *name; 518954Sbill { 519954Sbill register char *cp, *cp2; 520954Sbill char ext[4]; 521954Sbill 522954Sbill unrad50(2,rname,name); 523954Sbill unrad50(1,rname + 2,ext); 524954Sbill /* Jam name and extension together with a dot 525954Sbill deleting white space */ 526954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 527954Sbill *++cp = '.';cp++; 528954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 529954Sbill *cp++ = *cp2++; 530954Sbill } 531954Sbill *cp=0; 532954Sbill if(cp[-1]=='.') cp[-1] = 0; 533954Sbill } 534954Sbill 535954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 536954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 537954Sbill static char table[256] = { 538954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 539954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 540954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 541954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 542954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 543954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 544954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 545954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 546954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 547954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 548954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 549954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 550954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 551954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 552954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 553954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 554954Sbill 555954Sbill long trans(logical) 556954Sbill register int logical; 557954Sbill { 558954Sbill /* Logical to physical adress translation */ 559954Sbill register int sector, bytes, track; 560954Sbill 561954Sbill logical += 26 * 128; 562954Sbill bytes = (logical & 127); 563954Sbill logical >>= 7; 564954Sbill sector = logical % 26; 565954Sbill if(sector >= 13) 566954Sbill sector = sector *2 +1; 567954Sbill else 568954Sbill sector *= 2; 569954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 570954Sbill sector %= 26; 571954Sbill return( (((track *26) + sector) << 7) + bytes); 572954Sbill } 573954Sbill lread(startad,count,obuff) 574954Sbill register startad, count; 575954Sbill register char * obuff; 576954Sbill { 577954Sbill long trans(); 578954Sbill extern floppydes; 579*3799Shickman int temp; 580954Sbill rt_init(); 581954Sbill if(flg['m'-'a']==0) 582954Sbill while( (count -= 128) >= 0) { 583954Sbill lseek(floppydes, trans(startad), 0); 584*3799Shickman if ((temp = read(floppydes,obuff,128)) != 128) 585*3799Shickman fprintf(stderr, "arff: read error block %d %d\n",startad/128, temp); 586954Sbill obuff += 128; 587954Sbill startad += 128; 588954Sbill } 589954Sbill else 590954Sbill while( (count -= 512) >= 0) { 591954Sbill lseek(floppydes,(long) (startad), 0); 592*3799Shickman if ((temp = read(floppydes, obuff, 512)) != 512) 593*3799Shickman fprintf(stderr, "arff: read error block %d %d\n",startad/512, temp); 594954Sbill obuff += 512; 595954Sbill startad += 512; 596954Sbill } 597954Sbill } 598954Sbill lwrite(startad,count,obuff) 599954Sbill register startad, count; 600954Sbill register char * obuff; 601954Sbill { 602954Sbill long trans(); 603954Sbill extern floppydes; 604954Sbill rt_init(); 605954Sbill if(flg['m'-'a']==0) 606954Sbill while( (count -= 128) >= 0) { 607954Sbill lseek(floppydes, trans(startad), 0); 6083356Swnj if ( write(floppydes,obuff,128) != 128) 6093356Swnj fprintf(stderr, "arff: write error block %d\n",startad/128); 610954Sbill obuff += 128; 611954Sbill startad += 128; 612954Sbill } 613954Sbill else 614954Sbill while( (count -= 512) >= 0) { 615954Sbill lseek(floppydes,(long) (startad), 0); 6163356Swnj if ( write(floppydes,obuff,512) != 512) 6173356Swnj fprintf(stderr, "arff: write error block %d\n",startad/512); 618954Sbill obuff += 512; 619954Sbill startad += 512; 620954Sbill } 621954Sbill } 622954Sbill 623954Sbill rcmd() 624954Sbill { 625954Sbill register int i; 626954Sbill 627954Sbill rt_init(); 6283489Sroot if (namc>0) 629954Sbill for(i = 0; i < namc; i++) 6303356Swnj if(rtr(namv[i])==0) namv[i]=0; 631954Sbill } 632954Sbill 633954Sbill rtr(name) 634954Sbill char *name; 635954Sbill { 636954Sbill register FLDOPE *dope; register struct rt_ent *de; 637954Sbill struct stat buf; register struct stat *bufp = &buf; 6383346Swnj int segnum; 6393346Swnj register char *last; 640954Sbill 6413489Sroot if(stat(name,bufp)<0) { 6423489Sroot perror(name); 6433489Sroot return(-1); 6443489Sroot } 645954Sbill if(dope = lookup(name)) { 646954Sbill /* can replace, no problem */ 647954Sbill de = dope->rtdope; 648954Sbill if(bufp->st_size <= (de->rt_len * 512)) 649954Sbill printf("r - %s\n",name), 650954Sbill toflop(name,bufp->st_size,dope); 651954Sbill else { 6523356Swnj fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 6533489Sroot return(-1); 654954Sbill } 655954Sbill } else { 6563346Swnj /* Search for vacant spot */ 6573346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 6583346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 6593346Swnj last = rt_last + segnum*2*RT_BLOCK; 6603346Swnj for(de = rt_dir[segnum].rt_ents; 6613346Swnj rt(de)->rt_stat != RT_ESEG; de++) { 662954Sbill switch((de)->rt_stat) { 663954Sbill case RT_NULL: 664954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 665954Sbill printf("a - %s\n",name), 6663346Swnj mkent(de,segnum,bufp,name); 667954Sbill goto found; 668954Sbill } 669954Sbill continue; 670954Sbill } 671954Sbill } 6723346Swnj } 6733489Sroot printf("%s: no slot for file\n", name); 6743489Sroot return (-1); 675954Sbill } 676954Sbill found: if(dope=lookup(name)) { 677954Sbill toflop(name,bufp->st_size,dope); 6783489Sroot return (0); 679954Sbill } 6803489Sroot printf("%s: internal error, added then not found\n", name); 6813489Sroot return (-1); 682954Sbill 683954Sbill } 6843346Swnj mkent(de,segnum,bufp,name) 685954Sbill register struct rt_ent *de; 6863346Swnj int segnum; 687954Sbill register struct stat *bufp; 688954Sbill char *name; 689954Sbill { 690954Sbill struct tm *localtime(); register struct tm *timp; 691954Sbill register struct rt_ent *workp; int count; 692954Sbill 693954Sbill count = (((bufp->st_size -1) >>9) + 1); 694954Sbill /* Make sure there is room */ 695954Sbill if(de->rt_len==count) 696954Sbill goto overwrite; 6973346Swnj if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 6983346Swnj /* no entries left on segment */ 699954Sbill if(flg['o'-'a']) 700954Sbill goto overwrite; 7013346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 7023346Swnj defdev); 703954Sbill exit(1); 704954Sbill } 705954Sbill /* copy directory entries up */ 7063346Swnj for(workp = rt_curend[segnum]+1; workp > de; workp--) 707954Sbill *workp = workp[-1]; 708954Sbill de[1].rt_len -= count; 709954Sbill de->rt_len = count; 7103346Swnj rt_curend[segnum]++; 711954Sbill rt_nleft--; 712954Sbill overwrite: 713954Sbill srad50(name,de->rt_name); 714954Sbill timp = localtime(&bufp->st_mtime); 715954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 716954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 717954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 718954Sbill de->rt_stat = RT_FILE; 719954Sbill de->rt_pad = 0; 720954Sbill de->rt_chan = 0; 721954Sbill de->rt_job = 0; 7223346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 723954Sbill } 724954Sbill 725954Sbill toflop(name,ocount,dope) 726954Sbill char *name; 727954Sbill register FLDOPE *dope; 728954Sbill long ocount; 729954Sbill { 730954Sbill register file, n, startad = dope->startad, count = ocount; 731954Sbill char buff[512]; 732954Sbill 733954Sbill file = open(name,0); 734954Sbill if(file < 0) { 7353356Swnj fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);} 736954Sbill for( ; count >= 512; count -= 512) { 737954Sbill read(file,buff,512); 738954Sbill lwrite(startad,512,buff); 739954Sbill startad += 512; 740954Sbill } 741954Sbill read(file,buff,count); 742954Sbill close(file); 743954Sbill if(count <= 0) return; 744954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 745954Sbill lwrite(startad,512,buff); 746954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 747954Sbill if(count <= 0) return; 748954Sbill for( ; count > 0 ; count--) { 749954Sbill startad += 512; 750954Sbill lwrite(startad,512,zeroes); 751954Sbill } 752954Sbill 753954Sbill } 754954Sbill dcmd() 755954Sbill { 756954Sbill register int i; 757954Sbill 758954Sbill rt_init(); 759954Sbill if(namc) 760954Sbill for(i = 0; i < namc; i++) 761954Sbill if(rtk(namv[i])==0) namv[i]=0; 762954Sbill if(dirdirty) 763954Sbill scrunch(); 764954Sbill 765954Sbill } 766954Sbill rtk(name) 767954Sbill char *name; 768954Sbill { 769954Sbill register FLDOPE *dope; 770954Sbill register struct rt_ent *de; 771954Sbill FLDOPE *lookup(); 772954Sbill 773954Sbill if(dope = lookup(name)) { 774954Sbill printf("d - %s\n",name); 775954Sbill de = dope->rtdope; 776954Sbill de->rt_stat = RT_NULL; 777954Sbill de->rt_name[0] = 0; 778954Sbill de->rt_name[1] = 0; 779954Sbill de->rt_name[2] = 0; 780954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 781954Sbill dirdirty = 1; 782954Sbill return(0); 783954Sbill } 784954Sbill return(1); 785954Sbill } 786954Sbill scrunch() { 7873346Swnj register struct rt_ent *de , *workp; 7883346Swnj register segnum; 7893346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 7903346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 7913346Swnj dirdirty = 0; 7923346Swnj for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 793954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 794954Sbill (de+1)->rt_len += de->rt_len; 7953346Swnj for(workp = de; workp < rt_curend[segnum]; workp++) 796954Sbill *workp = workp[1]; 797954Sbill de--; 7983346Swnj rt_curend[segnum]--; 799954Sbill rt_nleft++; 8003346Swnj dirdirty = 1; 801954Sbill } 8023346Swnj } 8033346Swnj if (dirdirty) 8043346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 805954Sbill } 806954Sbill } 807