1*3346Swnj static char *sccsid = "@(#)arff.c 4.3 (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 { 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 31*3346Swnj #define RT_DIRSIZE 31 /* max # of directory segments */ 32954Sbill struct rt_head { 33954Sbill short rt_numseg; /*number of segments available*/ 34954Sbill short rt_nxtseg; /*segment no of next log. seg */ 35954Sbill short rt_lstseg; /*highest seg currenltly open */ 36954Sbill unsigned short rt_entpad; /*extra words/dir. entry */ 37954Sbill 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 }; 44*3346Swnj 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]; 64*3346Swnj struct rt_dir 65*3346Swnj 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; 68*3346Swnj 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 94954Sbill /*register i; 95954Sbill for(i=0; signum[i]; i++) 96954Sbill if(signal(signum[i], SIG_IGN) != SIG_IGN) 97954Sbill 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)); 1161735Sbill read(tty,response,128); 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 179954Sbill 180954Sbill 181954Sbill 182954Sbill 183954Sbill 184954Sbill 185954Sbill usage() 186954Sbill { 187954Sbill printf("usage: ar [%s][%s] archive files ...\n", opt, man); 188954Sbill exit(1); 189954Sbill } 190954Sbill 191954Sbill 192954Sbill 193954Sbill notfound() 194954Sbill { 195954Sbill register i, n; 196954Sbill 197954Sbill n = 0; 198954Sbill for(i=0; i<namc; i++) 199954Sbill if(namv[i]) { 200954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 201954Sbill n++; 202954Sbill } 203954Sbill return(n); 204954Sbill } 205954Sbill 206954Sbill 207954Sbill 208954Sbill phserr() 209954Sbill { 210954Sbill 211954Sbill fprintf(stderr, "arff: phase error on %s\n", file); 212954Sbill } 213954Sbill 214954Sbill mesg(c) 215954Sbill { 216954Sbill 217954Sbill if(flg['v'-'a']) 218954Sbill if(c != 'c' || flg['v'-'a'] > 1) 219954Sbill printf("%c - %s\n", c, file); 220954Sbill } 221954Sbill 222954Sbill tcmd() 223954Sbill { 224954Sbill register char *de; 225*3346Swnj int segnum; 226*3346Swnj register char *last; 227954Sbill FLDOPE *lookup(), *dope; 228954Sbill int nleft; register i; 229954Sbill register struct rt_ent *rde; 230954Sbill 231954Sbill rt_init(); 232954Sbill if(namc==0) 233*3346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 234*3346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 235*3346Swnj last = rt_last + segnum*2*RT_BLOCK; 236*3346Swnj for(de=((char *)&rt_dir[segnum])+10; de <= last; 237*3346Swnj de += rt_entsiz) { 238954Sbill if(rtls(rt(de))) { 239*3346Swnj nleft = (last - de) / rt_entsiz; 240*3346Swnj printf("\n%d entries remaining",nleft); 241*3346Swnj printf(" in directory segment %d.\n",segnum+1); 242954Sbill break; 243954Sbill } 244954Sbill } 245*3346Swnj } 246954Sbill else 247954Sbill for(i = 0; i < namc; i++) { 248954Sbill if(dope = lookup(namv[i])) { 249954Sbill rde = dope->rtdope; 250954Sbill rtls(rde); 251954Sbill namv[i] = 0; 252954Sbill } 253954Sbill } 254954Sbill } 255954Sbill rtls(de) 256954Sbill register struct rt_ent *de; 257954Sbill { 258954Sbill int month,day,year; 259954Sbill char name[12], ext[4]; 260954Sbill 261954Sbill if(flg['v'-'a']) 262954Sbill switch(de->rt_stat) { 263954Sbill case RT_TEMP: 264954Sbill printf("Tempfile:\n"); 265954Sbill case RT_FILE: 266954Sbill unrad50(2,de->rt_name,name); 267954Sbill unrad50(1,&(de->rt_name[2]),ext); 268954Sbill day = de->rt_date.rt_dy; 269954Sbill year = de->rt_date.rt_yr + 72; 270954Sbill month = de->rt_date.rt_mo; 271954Sbill printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 272954Sbill ext,month,day,year,de->rt_len); 273954Sbill break; 274954Sbill 275954Sbill case RT_NULL: 276954Sbill printf("%-25.9s %d\n","<UNUSED>",de->rt_len); 277954Sbill break; 278954Sbill 279954Sbill case RT_ESEG: 280954Sbill return(1); 281954Sbill } 282954Sbill else { 283954Sbill switch(de->rt_stat) { 284954Sbill case RT_TEMP: 285954Sbill case RT_FILE: 286954Sbill sunrad50(name,de->rt_name); 287954Sbill printf(name);putchar('\n'); 288954Sbill break; 289954Sbill 290954Sbill case RT_ESEG: 291954Sbill return(1); 292954Sbill 293954Sbill case RT_NULL: 294954Sbill ; 295954Sbill } 296954Sbill } 297954Sbill return(0); 298954Sbill } 299954Sbill xcmd() 300954Sbill { 301954Sbill register char *de; 302*3346Swnj int segnum; 303*3346Swnj register char *last; 304954Sbill char name[12]; 305954Sbill register int i; 306954Sbill 307954Sbill rt_init(); 308954Sbill if(namc==0) 309*3346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 310*3346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 311*3346Swnj last = rt_last + segnum*2*RT_BLOCK; 312*3346Swnj for(de=((char *)&rt_dir[segnum])+10; de <= last; 313*3346Swnj de += rt_entsiz) { 314954Sbill sunrad50(name,rt(de)->rt_name); 315954Sbill rtx(name); 316954Sbill } 317*3346Swnj } 318954Sbill 319954Sbill else 320954Sbill for(i = 0; i < namc; i++) 321954Sbill if(rtx(namv[i])==0) namv[i] = 0; 322954Sbill } 323954Sbill rtx(name) 324954Sbill char *name; 325954Sbill { 326954Sbill register FLDOPE *dope; 327954Sbill FLDOPE *lookup(); 328954Sbill register startad, count; 329954Sbill int file; char buff[512]; 330954Sbill 331954Sbill 332954Sbill if(dope = lookup(name)) { 333954Sbill if(flg['v' - 'a']) 334954Sbill rtls(dope->rtdope); 335954Sbill else 336954Sbill printf("x - %s\n",name); 337954Sbill 338954Sbill file = creat(name, 0666); 339954Sbill if(file < 0) return(1); 340954Sbill count = dope->count; 341954Sbill startad = dope->startad; 342954Sbill for( ; count > 0 ; count -= 512) { 343954Sbill lread(startad,512,buff); 344954Sbill write(file,buff,512); 345954Sbill startad += 512; 346954Sbill } 347954Sbill close(file); 348954Sbill return(0); 349954Sbill } 350954Sbill return(1); 351954Sbill } 352954Sbill rt_init() 353954Sbill { 354954Sbill static initized = 0; 355954Sbill register char *de; 356*3346Swnj register i; 357*3346Swnj int mode, dirnum; 358*3346Swnj register char *last; 359954Sbill 360954Sbill if(initized) return; 361954Sbill initized = 1; 362954Sbill if(flag('c') || flag('d') || flag('r')) 363954Sbill mode = 2; 364954Sbill else 365954Sbill mode = 0; 366954Sbill if((floppydes = open(defdev,mode)) < 0) 367954Sbill dbprintf("Floppy open failed\n"); 368*3346Swnj if(flag('c')==0) { 369*3346Swnj lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]); 370*3346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 371*3346Swnj if (dirnum > RT_DIRSIZE) { 372*3346Swnj fprintf(stderr,"arff: too many directory segments\n"); 373*3346Swnj exit(1); 374*3346Swnj } 375*3346Swnj for (i=1; i<dirnum; i++) 376*3346Swnj lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]); 377*3346Swnj } 378954Sbill 379*3346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 380*3346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 381*3346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 382*3346Swnj rt_nleft = 0; 383*3346Swnj 384*3346Swnj for (i=0; i<dirnum; i++) { 385*3346Swnj last = rt_last + i*2*RT_BLOCK; 386*3346Swnj for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) { 387954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 388*3346Swnj } 389*3346Swnj rt_curend[i] = rt(de); 390*3346Swnj rt_nleft += (last - de) / rt_entsiz; 391954Sbill } 392954Sbill } 393954Sbill 394954Sbill static FLDOPE result; 395954Sbill FLDOPE * 396954Sbill lookup(name) 397954Sbill char * name; 398954Sbill { 399954Sbill unsigned short rname[3]; 400954Sbill register char *de; 401*3346Swnj int segnum; 402*3346Swnj register char *last; 403954Sbill register index; 404954Sbill 405954Sbill srad50(name,rname); 406954Sbill 407954Sbill /* 408954Sbill * Search for name, accumulate blocks in index 409954Sbill */ 410954Sbill rt_init(); 411*3346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 412*3346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 413*3346Swnj index = 0; 414*3346Swnj last = rt_last + segnum*2*RT_BLOCK; 415*3346Swnj for(de=((char *)&rt_dir[segnum])+10; 416*3346Swnj rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) { 417954Sbill switch(rt(de)->rt_stat) { 418954Sbill case RT_ESEG: 419*3346Swnj exit(1); 420954Sbill case RT_FILE: 421954Sbill case RT_TEMP: 422954Sbill if(samename(rname,rt(de)->rt_name)) 423954Sbill goto found; 424954Sbill case RT_NULL: 425954Sbill index += rt(de)->rt_len; 426954Sbill } 427*3346Swnj } 428*3346Swnj } 429954Sbill return((FLDOPE *) 0); 430954Sbill found: result.count = rt(de)->rt_len * 512; 431*3346Swnj result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index); 432954Sbill result.rtdope = (struct rt_ent *) de; 433954Sbill return(&result); 434954Sbill } 435954Sbill static 436954Sbill samename(a,b) 437954Sbill unsigned short a[3],b[3]; 438954Sbill { 439954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 440954Sbill } 441954Sbill 442954Sbill 443954Sbill rad50(cp,out) 444954Sbill register unsigned char *cp; 445954Sbill unsigned short *out; 446954Sbill { 447954Sbill register index; 448954Sbill register temp; 449954Sbill 450954Sbill for(index = 0;*cp; index++) { 451954Sbill 452954Sbill temp = Ain1 * table[*cp++]; 453954Sbill if(*cp!=0) { 454954Sbill temp += Ain2 * table[*cp++]; 455954Sbill 456954Sbill if(*cp!=0) 457954Sbill temp += table[*cp++]; 458954Sbill } 459954Sbill 460954Sbill out[index] = temp; 461954Sbill } 462954Sbill } 463954Sbill #define reduce(x,p,q) \ 464954Sbill (x = v[p/q], p %= q); 465954Sbill 466954Sbill unrad50(count,in,cp) 467954Sbill unsigned short *in; 468954Sbill register char *cp; 469954Sbill { 470954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 471954Sbill 472954Sbill for(i = 0; i < count; i++) { 473954Sbill temp = in[i]; 474954Sbill 475954Sbill reduce (*cp++,temp,Ain1); 476954Sbill reduce (*cp++,temp,Ain2); 477954Sbill reduce (*cp++,temp,1); 478954Sbill } 479954Sbill *cp=0; 480954Sbill } 481954Sbill 482954Sbill srad50(name,rname) 483954Sbill register char * name; 484954Sbill register unsigned short *rname; 485954Sbill { 486954Sbill register index; register char *cp; 487954Sbill char file[7],ext[4]; 488954Sbill /* 489954Sbill * Find end of pathname 490954Sbill */ 491954Sbill for(cp = name; *cp++; ); 492954Sbill while(cp >= name && *--cp != '/'); 493954Sbill cp++; 494954Sbill /* 495954Sbill * Change to rad50 496954Sbill * 497954Sbill */ 498954Sbill for(index = 0; *cp; ){ 499954Sbill file[index++] = *cp++; 500954Sbill if(*cp=='.') { 501954Sbill cp++; 502954Sbill break; 503954Sbill } 504954Sbill if(index>=6) { 505954Sbill break; 506954Sbill } 507954Sbill } 508954Sbill file[index] = 0; 509954Sbill for(index = 0; *cp; ){ 510954Sbill ext[index++] = *cp++; 511954Sbill if(*cp=='.' || index>=3) { 512954Sbill break; 513954Sbill } 514954Sbill } 515954Sbill ext[index]=0; 516954Sbill rname[0] = 0; 517954Sbill rname[1] = 0; 518954Sbill rname[2] = 0; 519954Sbill rad50((unsigned char *)file,rname); 520954Sbill rad50((unsigned char *)ext,rname+2); 521954Sbill } 522954Sbill sunrad50(name,rname) 523954Sbill unsigned short rname[3]; 524954Sbill register char *name; 525954Sbill { 526954Sbill register char *cp, *cp2; 527954Sbill char ext[4]; 528954Sbill 529954Sbill unrad50(2,rname,name); 530954Sbill unrad50(1,rname + 2,ext); 531954Sbill /* Jam name and extension together with a dot 532954Sbill deleting white space */ 533954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 534954Sbill *++cp = '.';cp++; 535954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 536954Sbill *cp++ = *cp2++; 537954Sbill } 538954Sbill *cp=0; 539954Sbill if(cp[-1]=='.') cp[-1] = 0; 540954Sbill } 541954Sbill 542954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 543954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 544954Sbill static char table[256] = { 545954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 546954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 547954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 548954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 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, 29, 551954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 552954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 553954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 554954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 555954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 556954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 557954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 558954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 559954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 560954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 561954Sbill 562954Sbill long trans(logical) 563954Sbill register int logical; 564954Sbill { 565954Sbill /* Logical to physical adress translation */ 566954Sbill register int sector, bytes, track; 567954Sbill 568954Sbill logical += 26 * 128; 569954Sbill bytes = (logical & 127); 570954Sbill logical >>= 7; 571954Sbill sector = logical % 26; 572954Sbill if(sector >= 13) 573954Sbill sector = sector *2 +1; 574954Sbill else 575954Sbill sector *= 2; 576954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 577954Sbill sector %= 26; 578954Sbill return( (((track *26) + sector) << 7) + bytes); 579954Sbill } 580954Sbill lread(startad,count,obuff) 581954Sbill register startad, count; 582954Sbill register char * obuff; 583954Sbill { 584954Sbill long trans(); 585954Sbill extern floppydes; 586954Sbill rt_init(); 587954Sbill if(flg['m'-'a']==0) 588954Sbill while( (count -= 128) >= 0) { 589954Sbill lseek(floppydes, trans(startad), 0); 590954Sbill read(floppydes,obuff,128); 591954Sbill obuff += 128; 592954Sbill startad += 128; 593954Sbill } 594954Sbill else 595954Sbill while( (count -= 512) >= 0) { 596954Sbill lseek(floppydes,(long) (startad), 0); 597954Sbill read(floppydes,obuff,512); 598954Sbill obuff += 512; 599954Sbill startad += 512; 600954Sbill } 601954Sbill } 602954Sbill lwrite(startad,count,obuff) 603954Sbill register startad, count; 604954Sbill register char * obuff; 605954Sbill { 606954Sbill long trans(); 607954Sbill extern floppydes; 608954Sbill rt_init(); 609954Sbill if(flg['m'-'a']==0) 610954Sbill while( (count -= 128) >= 0) { 611954Sbill lseek(floppydes, trans(startad), 0); 612954Sbill write(floppydes,obuff,128); 613954Sbill obuff += 128; 614954Sbill startad += 128; 615954Sbill } 616954Sbill else 617954Sbill while( (count -= 512) >= 0) { 618954Sbill lseek(floppydes,(long) (startad), 0); 619954Sbill write(floppydes,obuff,512); 620954Sbill obuff += 512; 621954Sbill startad += 512; 622954Sbill } 623954Sbill } 624954Sbill 625954Sbill rcmd() 626954Sbill { 627954Sbill register int i; 628*3346Swnj int debug; 629954Sbill 630954Sbill rt_init(); 631954Sbill if(namc>0) 632954Sbill for(i = 0; i < namc; i++) 633*3346Swnj if((debug = rtr(namv[i]))==0) namv[i]=0; 634*3346Swnj else printf("debug-rtr returns %d\n",debug); 635954Sbill 636954Sbill 637954Sbill } 638954Sbill 639954Sbill rtr(name) 640954Sbill char *name; 641954Sbill { 642954Sbill register FLDOPE *dope; register struct rt_ent *de; 643954Sbill struct stat buf; register struct stat *bufp = &buf; 644*3346Swnj int segnum; 645*3346Swnj register char *last; 646954Sbill 647954Sbill if(stat(name,bufp)<0) return(1); 648954Sbill if(dope = lookup(name)) { 649954Sbill /* can replace, no problem */ 650954Sbill de = dope->rtdope; 651954Sbill if(bufp->st_size <= (de->rt_len * 512)) 652954Sbill printf("r - %s\n",name), 653954Sbill toflop(name,bufp->st_size,dope); 654954Sbill else { 655954Sbill printf("%s will not fit in currently used file on floppy\n",name); 656954Sbill return(1); 657954Sbill } 658954Sbill } else { 659*3346Swnj /* Search for vacant spot */ 660*3346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 661*3346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 662*3346Swnj last = rt_last + segnum*2*RT_BLOCK; 663*3346Swnj for(de = rt_dir[segnum].rt_ents; 664*3346Swnj rt(de)->rt_stat != RT_ESEG; de++) { 665954Sbill switch((de)->rt_stat) { 666954Sbill case RT_NULL: 667954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 668954Sbill printf("a - %s\n",name), 669*3346Swnj mkent(de,segnum,bufp,name); 670954Sbill goto found; 671954Sbill } 672954Sbill continue; 673954Sbill case RT_ESEG: 674*3346Swnj exit(1); 675954Sbill } 676954Sbill } 677*3346Swnj } 678*3346Swnj return(3); 679954Sbill } 680954Sbill found: if(dope=lookup(name)) { 681954Sbill toflop(name,bufp->st_size,dope); 682954Sbill return(0); 683954Sbill } 684954Sbill return(7); 685954Sbill 686954Sbill } 687*3346Swnj mkent(de,segnum,bufp,name) 688954Sbill register struct rt_ent *de; 689*3346Swnj int segnum; 690954Sbill register struct stat *bufp; 691954Sbill char *name; 692954Sbill { 693954Sbill struct tm *localtime(); register struct tm *timp; 694954Sbill register struct rt_ent *workp; int count; 695954Sbill 696954Sbill count = (((bufp->st_size -1) >>9) + 1); 697954Sbill /* Make sure there is room */ 698954Sbill if(de->rt_len==count) 699954Sbill goto overwrite; 700*3346Swnj if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 701*3346Swnj /* no entries left on segment */ 702954Sbill if(flg['o'-'a']) 703954Sbill goto overwrite; 704*3346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 705*3346Swnj defdev); 706954Sbill exit(1); 707954Sbill } 708954Sbill /* copy directory entries up */ 709*3346Swnj for(workp = rt_curend[segnum]+1; workp > de; workp--) 710954Sbill *workp = workp[-1]; 711954Sbill de[1].rt_len -= count; 712954Sbill de->rt_len = count; 713*3346Swnj rt_curend[segnum]++; 714954Sbill rt_nleft--; 715954Sbill overwrite: 716954Sbill srad50(name,de->rt_name); 717954Sbill timp = localtime(&bufp->st_mtime); 718954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 719954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 720954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 721954Sbill de->rt_stat = RT_FILE; 722954Sbill de->rt_pad = 0; 723954Sbill de->rt_chan = 0; 724954Sbill de->rt_job = 0; 725*3346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 726954Sbill 727954Sbill } 728954Sbill 729954Sbill toflop(name,ocount,dope) 730954Sbill char *name; 731954Sbill register FLDOPE *dope; 732954Sbill long ocount; 733954Sbill { 734954Sbill register file, n, startad = dope->startad, count = ocount; 735954Sbill char buff[512]; 736954Sbill 737954Sbill file = open(name,0); 738954Sbill if(file < 0) { 739954Sbill printf("arff: couldn't open %s\n",name);exit(1);} 740954Sbill for( ; count >= 512; count -= 512) { 741954Sbill read(file,buff,512); 742954Sbill lwrite(startad,512,buff); 743954Sbill startad += 512; 744954Sbill } 745954Sbill read(file,buff,count); 746954Sbill close(file); 747954Sbill if(count <= 0) return; 748954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 749954Sbill lwrite(startad,512,buff); 750954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 751954Sbill if(count <= 0) return; 752954Sbill for( ; count > 0 ; count--) { 753954Sbill startad += 512; 754954Sbill lwrite(startad,512,zeroes); 755954Sbill } 756954Sbill 757954Sbill } 758954Sbill dcmd() 759954Sbill { 760954Sbill register int i; 761954Sbill 762954Sbill rt_init(); 763954Sbill if(namc) 764954Sbill for(i = 0; i < namc; i++) 765954Sbill if(rtk(namv[i])==0) namv[i]=0; 766954Sbill if(dirdirty) 767954Sbill scrunch(); 768954Sbill 769954Sbill } 770954Sbill rtk(name) 771954Sbill char *name; 772954Sbill { 773954Sbill register FLDOPE *dope; 774954Sbill register struct rt_ent *de; 775954Sbill FLDOPE *lookup(); 776954Sbill 777954Sbill if(dope = lookup(name)) { 778954Sbill printf("d - %s\n",name); 779954Sbill de = dope->rtdope; 780954Sbill de->rt_stat = RT_NULL; 781954Sbill de->rt_name[0] = 0; 782954Sbill de->rt_name[1] = 0; 783954Sbill de->rt_name[2] = 0; 784954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 785954Sbill dirdirty = 1; 786954Sbill return(0); 787954Sbill } 788954Sbill return(1); 789954Sbill } 790954Sbill scrunch() { 791*3346Swnj register struct rt_ent *de , *workp; 792*3346Swnj register segnum; 793*3346Swnj for (segnum=0; segnum != -1; /* for all dir. segments */ 794*3346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 795*3346Swnj dirdirty = 0; 796*3346Swnj for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) { 797954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 798954Sbill (de+1)->rt_len += de->rt_len; 799*3346Swnj for(workp = de; workp < rt_curend[segnum]; workp++) 800954Sbill *workp = workp[1]; 801954Sbill de--; 802*3346Swnj rt_curend[segnum]--; 803954Sbill rt_nleft++; 804*3346Swnj dirdirty = 1; 805954Sbill } 806*3346Swnj } 807*3346Swnj if (dirdirty) 808*3346Swnj lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]); 809954Sbill } 810954Sbill } 811