1*954Sbill static char *sccsid = "@(#)arff.c 4.1 (Berkeley) 10/01/80"; 2*954Sbill #include <sys/types.h> 3*954Sbill #include <sys/stat.h> 4*954Sbill #include <time.h> 5*954Sbill #include <signal.h> 6*954Sbill #include <stdio.h> 7*954Sbill #define dbprintf printf 8*954Sbill struct rt_dat { 9*954Sbill unsigned short int rt_yr:5; /*Year - 1972 */ 10*954Sbill unsigned short int rt_dy:5; /*day */ 11*954Sbill unsigned short int rt_mo:5; /*month */ 12*954Sbill }; 13*954Sbill struct rt_axent { 14*954Sbill char rt_sent[14]; 15*954Sbill }; 16*954Sbill 17*954Sbill struct rt_ent { 18*954Sbill char rt_pad; /*unusued */ 19*954Sbill char rt_stat; /*Type of entry, or end of seg*/ 20*954Sbill unsigned short rt_name[3]; /*Name, 3 words in rad50 form */ 21*954Sbill short rt_len; /*Length of file */ 22*954Sbill char rt_chan; /*Only used in temporary files*/ 23*954Sbill char rt_job; /*Only used in temporary files*/ 24*954Sbill struct rt_dat rt_date; /*Creation Date */ 25*954Sbill }; 26*954Sbill #define RT_TEMP 1 27*954Sbill #define RT_NULL 2 28*954Sbill #define RT_FILE 4 29*954Sbill #define RT_ESEG 8 30*954Sbill #define RT_BLOCK 512 31*954Sbill struct rt_head { 32*954Sbill short rt_numseg; /*number of segments available*/ 33*954Sbill short rt_nxtseg; /*segment no of next log. seg */ 34*954Sbill short rt_lstseg; /*highest seg currenltly open */ 35*954Sbill unsigned short rt_entpad; /*extra words/dir. entry */ 36*954Sbill short rt_stfile; /*block no where files begin */ 37*954Sbill }; 38*954Sbill struct rt_dir { 39*954Sbill struct rt_head rt_axhead; 40*954Sbill struct rt_ent rt_ents[72]; 41*954Sbill char _dirpad[6]; 42*954Sbill }; 43*954Sbill extern struct rt_dir rt_dir; 44*954Sbill extern int rt_entsiz; 45*954Sbill extern int floppydes; 46*954Sbill extern char *rt_last; 47*954Sbill typedef struct fldope { 48*954Sbill int startad; 49*954Sbill int count; 50*954Sbill struct rt_ent *rtdope; 51*954Sbill } FLDOPE; 52*954Sbill FLDOPE *lookup(); 53*954Sbill #define rt(p) ((struct rt_ent *) p ) 54*954Sbill #define Ain1 03100 55*954Sbill #define Ain2 050 56*954Sbill #define flag(c) (flg[(c) - 'a']) 57*954Sbill 58*954Sbill char *man = { "rxtd" }; 59*954Sbill 60*954Sbill char zeroes[512]; 61*954Sbill extern char *val; 62*954Sbill extern char table[256]; 63*954Sbill struct rt_dir rt_dir = {{4,0,1,0,14},{0,RT_NULL,{0,0,0},494,0}, {0,RT_ESEG}}; 64*954Sbill int rt_entsiz; 65*954Sbill int rt_nleft; 66*954Sbill struct rt_ent *rt_curend; 67*954Sbill int floppydes; 68*954Sbill int dirdirty; 69*954Sbill char *rt_last; 70*954Sbill char *defdev = "/dev/floppy"; 71*954Sbill 72*954Sbill char *opt = { "vf" }; 73*954Sbill 74*954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 75*954Sbill long lseek(); 76*954Sbill int rcmd(); 77*954Sbill int dcmd(); 78*954Sbill int xcmd(); 79*954Sbill int tcmd(); 80*954Sbill int (*comfun)(); 81*954Sbill char flg[26]; 82*954Sbill char **namv; 83*954Sbill int namc; 84*954Sbill int file; 85*954Sbill 86*954Sbill 87*954Sbill main(argc, argv) 88*954Sbill char *argv[]; 89*954Sbill { 90*954Sbill register char *cp; 91*954Sbill 92*954Sbill /*register i; 93*954Sbill for(i=0; signum[i]; i++) 94*954Sbill if(signal(signum[i], SIG_IGN) != SIG_IGN) 95*954Sbill signal(signum[i], sigdone);*/ 96*954Sbill if(argc < 2) 97*954Sbill usage(); 98*954Sbill cp = argv[1]; 99*954Sbill for(cp = argv[1]; *cp; cp++) 100*954Sbill switch(*cp) { 101*954Sbill case 'm': 102*954Sbill case 'v': 103*954Sbill case 'u': 104*954Sbill case 'w': 105*954Sbill flg[*cp - 'a']++; 106*954Sbill continue; 107*954Sbill case 'c': 108*954Sbill { 109*954Sbill #define SURE "Are you sure you want to clobber the floppy?\n" 110*954Sbill int tty; 111*954Sbill char response[2]; 112*954Sbill tty = open("/dev/tty",2); 113*954Sbill write(tty,SURE,sizeof(SURE)); 114*954Sbill read(tty,response,2); 115*954Sbill if(*response!='y') 116*954Sbill exit(50); 117*954Sbill flag('c')++; 118*954Sbill close(tty); 119*954Sbill } 120*954Sbill dirdirty++; 121*954Sbill continue; 122*954Sbill 123*954Sbill case 'r': 124*954Sbill setcom(rcmd); 125*954Sbill flag('r')++; 126*954Sbill continue; 127*954Sbill 128*954Sbill case 'd': 129*954Sbill setcom(dcmd); 130*954Sbill flag('d')++; 131*954Sbill continue; 132*954Sbill 133*954Sbill case 'x': 134*954Sbill setcom(xcmd); 135*954Sbill continue; 136*954Sbill 137*954Sbill case 't': 138*954Sbill setcom(tcmd); 139*954Sbill continue; 140*954Sbill 141*954Sbill case 'f': 142*954Sbill defdev = argv[2]; 143*954Sbill argv++; 144*954Sbill argc--; 145*954Sbill continue; 146*954Sbill 147*954Sbill 148*954Sbill default: 149*954Sbill fprintf(stderr, "arff: bad option `%c'\n", *cp); 150*954Sbill exit(1); 151*954Sbill } 152*954Sbill namv = argv+2; 153*954Sbill namc = argc-2; 154*954Sbill if(comfun == 0) { 155*954Sbill if(flg['u'-'a'] == 0) { 156*954Sbill fprintf(stderr, "arff: one of [%s] must be specified\n", man); 157*954Sbill exit(1); 158*954Sbill } 159*954Sbill setcom(rcmd); 160*954Sbill } 161*954Sbill (*comfun)(); 162*954Sbill exit(notfound()); 163*954Sbill } 164*954Sbill 165*954Sbill setcom(fun) 166*954Sbill int (*fun)(); 167*954Sbill { 168*954Sbill 169*954Sbill if(comfun != 0) { 170*954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 171*954Sbill exit(1); 172*954Sbill } 173*954Sbill comfun = fun; 174*954Sbill } 175*954Sbill 176*954Sbill 177*954Sbill 178*954Sbill 179*954Sbill 180*954Sbill 181*954Sbill 182*954Sbill 183*954Sbill usage() 184*954Sbill { 185*954Sbill printf("usage: ar [%s][%s] archive files ...\n", opt, man); 186*954Sbill exit(1); 187*954Sbill } 188*954Sbill 189*954Sbill 190*954Sbill 191*954Sbill notfound() 192*954Sbill { 193*954Sbill register i, n; 194*954Sbill 195*954Sbill n = 0; 196*954Sbill for(i=0; i<namc; i++) 197*954Sbill if(namv[i]) { 198*954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 199*954Sbill n++; 200*954Sbill } 201*954Sbill return(n); 202*954Sbill } 203*954Sbill 204*954Sbill 205*954Sbill 206*954Sbill phserr() 207*954Sbill { 208*954Sbill 209*954Sbill fprintf(stderr, "arff: phase error on %s\n", file); 210*954Sbill } 211*954Sbill 212*954Sbill mesg(c) 213*954Sbill { 214*954Sbill 215*954Sbill if(flg['v'-'a']) 216*954Sbill if(c != 'c' || flg['v'-'a'] > 1) 217*954Sbill printf("%c - %s\n", c, file); 218*954Sbill } 219*954Sbill 220*954Sbill tcmd() 221*954Sbill { 222*954Sbill register char *de; 223*954Sbill FLDOPE *lookup(), *dope; 224*954Sbill int nleft; register i; 225*954Sbill register struct rt_ent *rde; 226*954Sbill 227*954Sbill rt_init(); 228*954Sbill if(namc==0) 229*954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 230*954Sbill if(rtls(rt(de))) { 231*954Sbill nleft = (rt_last - de) / rt_entsiz; 232*954Sbill printf("\n\n%d entries remaining.\n",nleft); 233*954Sbill break; 234*954Sbill } 235*954Sbill } 236*954Sbill else 237*954Sbill for(i = 0; i < namc; i++) { 238*954Sbill if(dope = lookup(namv[i])) { 239*954Sbill rde = dope->rtdope; 240*954Sbill rtls(rde); 241*954Sbill namv[i] = 0; 242*954Sbill } 243*954Sbill } 244*954Sbill } 245*954Sbill rtls(de) 246*954Sbill register struct rt_ent *de; 247*954Sbill { 248*954Sbill int month,day,year; 249*954Sbill char name[12], ext[4]; 250*954Sbill 251*954Sbill if(flg['v'-'a']) 252*954Sbill switch(de->rt_stat) { 253*954Sbill case RT_TEMP: 254*954Sbill printf("Tempfile:\n"); 255*954Sbill case RT_FILE: 256*954Sbill unrad50(2,de->rt_name,name); 257*954Sbill unrad50(1,&(de->rt_name[2]),ext); 258*954Sbill day = de->rt_date.rt_dy; 259*954Sbill year = de->rt_date.rt_yr + 72; 260*954Sbill month = de->rt_date.rt_mo; 261*954Sbill printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 262*954Sbill ext,month,day,year,de->rt_len); 263*954Sbill break; 264*954Sbill 265*954Sbill case RT_NULL: 266*954Sbill printf("%-25.9s %d\n","<UNUSED>",de->rt_len); 267*954Sbill break; 268*954Sbill 269*954Sbill case RT_ESEG: 270*954Sbill return(1); 271*954Sbill } 272*954Sbill else { 273*954Sbill switch(de->rt_stat) { 274*954Sbill case RT_TEMP: 275*954Sbill case RT_FILE: 276*954Sbill sunrad50(name,de->rt_name); 277*954Sbill printf(name);putchar('\n'); 278*954Sbill break; 279*954Sbill 280*954Sbill case RT_ESEG: 281*954Sbill return(1); 282*954Sbill 283*954Sbill case RT_NULL: 284*954Sbill ; 285*954Sbill } 286*954Sbill } 287*954Sbill return(0); 288*954Sbill } 289*954Sbill xcmd() 290*954Sbill { 291*954Sbill register char *de; 292*954Sbill char name[12]; 293*954Sbill register int i; 294*954Sbill 295*954Sbill rt_init(); 296*954Sbill if(namc==0) 297*954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 298*954Sbill sunrad50(name,rt(de)->rt_name); 299*954Sbill rtx(name); 300*954Sbill } 301*954Sbill 302*954Sbill else 303*954Sbill for(i = 0; i < namc; i++) 304*954Sbill if(rtx(namv[i])==0) namv[i] = 0; 305*954Sbill } 306*954Sbill rtx(name) 307*954Sbill char *name; 308*954Sbill { 309*954Sbill register FLDOPE *dope; 310*954Sbill FLDOPE *lookup(); 311*954Sbill register startad, count; 312*954Sbill int file; char buff[512]; 313*954Sbill 314*954Sbill 315*954Sbill if(dope = lookup(name)) { 316*954Sbill if(flg['v' - 'a']) 317*954Sbill rtls(dope->rtdope); 318*954Sbill else 319*954Sbill printf("x - %s\n",name); 320*954Sbill 321*954Sbill file = creat(name, 0666); 322*954Sbill if(file < 0) return(1); 323*954Sbill count = dope->count; 324*954Sbill startad = dope->startad; 325*954Sbill for( ; count > 0 ; count -= 512) { 326*954Sbill lread(startad,512,buff); 327*954Sbill write(file,buff,512); 328*954Sbill startad += 512; 329*954Sbill } 330*954Sbill close(file); 331*954Sbill return(0); 332*954Sbill } 333*954Sbill return(1); 334*954Sbill } 335*954Sbill rt_init() 336*954Sbill { 337*954Sbill static initized = 0; 338*954Sbill register char *de; 339*954Sbill int mode; 340*954Sbill 341*954Sbill if(initized) return; 342*954Sbill initized = 1; 343*954Sbill if(flag('c') || flag('d') || flag('r')) 344*954Sbill mode = 2; 345*954Sbill else 346*954Sbill mode = 0; 347*954Sbill if((floppydes = open(defdev,mode)) < 0) 348*954Sbill dbprintf("Floppy open failed\n"); 349*954Sbill if(flag('c')==0) 350*954Sbill lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 351*954Sbill 352*954Sbill rt_entsiz = 2*rt_dir.rt_axhead.rt_entpad + 14; 353*954Sbill rt_entsiz = 14; 354*954Sbill rt_last = ((char *) &rt_dir) + 10 + 1014/rt_entsiz*rt_entsiz; 355*954Sbill for(de=((char *)&rt_dir)+10; de <= rt_last; de += rt_entsiz) { 356*954Sbill if(rt(de)->rt_stat==RT_ESEG) break; 357*954Sbill } 358*954Sbill rt_curend = rt(de); 359*954Sbill rt_nleft = (rt_last - de) / rt_entsiz; 360*954Sbill } 361*954Sbill 362*954Sbill static FLDOPE result; 363*954Sbill FLDOPE * 364*954Sbill lookup(name) 365*954Sbill char * name; 366*954Sbill { 367*954Sbill unsigned short rname[3]; 368*954Sbill register char *de; 369*954Sbill register index; 370*954Sbill 371*954Sbill srad50(name,rname); 372*954Sbill 373*954Sbill /* 374*954Sbill * Search for name, accumulate blocks in index 375*954Sbill */ 376*954Sbill rt_init(); 377*954Sbill index = 0; 378*954Sbill for(de = ((char *) &rt_dir) + 10; de <= rt_last; de += rt_entsiz) { 379*954Sbill switch(rt(de)->rt_stat) { 380*954Sbill case RT_ESEG: 381*954Sbill return((FLDOPE *) 0); 382*954Sbill case RT_FILE: 383*954Sbill case RT_TEMP: 384*954Sbill if(samename(rname,rt(de)->rt_name)) 385*954Sbill goto found; 386*954Sbill case RT_NULL: 387*954Sbill index += rt(de)->rt_len; 388*954Sbill } 389*954Sbill } 390*954Sbill return((FLDOPE *) 0); 391*954Sbill found: result.count = rt(de)->rt_len * 512; 392*954Sbill result.startad = 512 * (rt_dir.rt_axhead.rt_stfile + index); 393*954Sbill result.rtdope = (struct rt_ent *) de; 394*954Sbill return(&result); 395*954Sbill } 396*954Sbill static 397*954Sbill samename(a,b) 398*954Sbill unsigned short a[3],b[3]; 399*954Sbill { 400*954Sbill return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] ); 401*954Sbill } 402*954Sbill 403*954Sbill 404*954Sbill rad50(cp,out) 405*954Sbill register unsigned char *cp; 406*954Sbill unsigned short *out; 407*954Sbill { 408*954Sbill register index; 409*954Sbill register temp; 410*954Sbill 411*954Sbill for(index = 0;*cp; index++) { 412*954Sbill 413*954Sbill temp = Ain1 * table[*cp++]; 414*954Sbill if(*cp!=0) { 415*954Sbill temp += Ain2 * table[*cp++]; 416*954Sbill 417*954Sbill if(*cp!=0) 418*954Sbill temp += table[*cp++]; 419*954Sbill } 420*954Sbill 421*954Sbill out[index] = temp; 422*954Sbill } 423*954Sbill } 424*954Sbill #define reduce(x,p,q) \ 425*954Sbill (x = v[p/q], p %= q); 426*954Sbill 427*954Sbill unrad50(count,in,cp) 428*954Sbill unsigned short *in; 429*954Sbill register char *cp; 430*954Sbill { 431*954Sbill register i, temp; register unsigned char *v = (unsigned char *) val; 432*954Sbill 433*954Sbill for(i = 0; i < count; i++) { 434*954Sbill temp = in[i]; 435*954Sbill 436*954Sbill reduce (*cp++,temp,Ain1); 437*954Sbill reduce (*cp++,temp,Ain2); 438*954Sbill reduce (*cp++,temp,1); 439*954Sbill } 440*954Sbill *cp=0; 441*954Sbill } 442*954Sbill 443*954Sbill srad50(name,rname) 444*954Sbill register char * name; 445*954Sbill register unsigned short *rname; 446*954Sbill { 447*954Sbill register index; register char *cp; 448*954Sbill char file[7],ext[4]; 449*954Sbill /* 450*954Sbill * Find end of pathname 451*954Sbill */ 452*954Sbill for(cp = name; *cp++; ); 453*954Sbill while(cp >= name && *--cp != '/'); 454*954Sbill cp++; 455*954Sbill /* 456*954Sbill * Change to rad50 457*954Sbill * 458*954Sbill */ 459*954Sbill for(index = 0; *cp; ){ 460*954Sbill file[index++] = *cp++; 461*954Sbill if(*cp=='.') { 462*954Sbill cp++; 463*954Sbill break; 464*954Sbill } 465*954Sbill if(index>=6) { 466*954Sbill break; 467*954Sbill } 468*954Sbill } 469*954Sbill file[index] = 0; 470*954Sbill for(index = 0; *cp; ){ 471*954Sbill ext[index++] = *cp++; 472*954Sbill if(*cp=='.' || index>=3) { 473*954Sbill break; 474*954Sbill } 475*954Sbill } 476*954Sbill ext[index]=0; 477*954Sbill rname[0] = 0; 478*954Sbill rname[1] = 0; 479*954Sbill rname[2] = 0; 480*954Sbill rad50((unsigned char *)file,rname); 481*954Sbill rad50((unsigned char *)ext,rname+2); 482*954Sbill } 483*954Sbill sunrad50(name,rname) 484*954Sbill unsigned short rname[3]; 485*954Sbill register char *name; 486*954Sbill { 487*954Sbill register char *cp, *cp2; 488*954Sbill char ext[4]; 489*954Sbill 490*954Sbill unrad50(2,rname,name); 491*954Sbill unrad50(1,rname + 2,ext); 492*954Sbill /* Jam name and extension together with a dot 493*954Sbill deleting white space */ 494*954Sbill for(cp = name; *cp++;);--cp; while(*--cp==' ' && cp>=name); 495*954Sbill *++cp = '.';cp++; 496*954Sbill for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) { 497*954Sbill *cp++ = *cp2++; 498*954Sbill } 499*954Sbill *cp=0; 500*954Sbill if(cp[-1]=='.') cp[-1] = 0; 501*954Sbill } 502*954Sbill 503*954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 504*954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 505*954Sbill static char table[256] = { 506*954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 507*954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 508*954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 509*954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 510*954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 511*954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 512*954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 513*954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 514*954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 515*954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 516*954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 517*954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 518*954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 519*954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 520*954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 521*954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 522*954Sbill 523*954Sbill long trans(logical) 524*954Sbill register int logical; 525*954Sbill { 526*954Sbill /* Logical to physical adress translation */ 527*954Sbill register int sector, bytes, track; 528*954Sbill 529*954Sbill logical += 26 * 128; 530*954Sbill bytes = (logical & 127); 531*954Sbill logical >>= 7; 532*954Sbill sector = logical % 26; 533*954Sbill if(sector >= 13) 534*954Sbill sector = sector *2 +1; 535*954Sbill else 536*954Sbill sector *= 2; 537*954Sbill sector += 26 + ((track = (logical / 26)) - 1) * 6; 538*954Sbill sector %= 26; 539*954Sbill return( (((track *26) + sector) << 7) + bytes); 540*954Sbill } 541*954Sbill lread(startad,count,obuff) 542*954Sbill register startad, count; 543*954Sbill register char * obuff; 544*954Sbill { 545*954Sbill long trans(); 546*954Sbill extern floppydes; 547*954Sbill rt_init(); 548*954Sbill if(flg['m'-'a']==0) 549*954Sbill while( (count -= 128) >= 0) { 550*954Sbill lseek(floppydes, trans(startad), 0); 551*954Sbill read(floppydes,obuff,128); 552*954Sbill obuff += 128; 553*954Sbill startad += 128; 554*954Sbill } 555*954Sbill else 556*954Sbill while( (count -= 512) >= 0) { 557*954Sbill lseek(floppydes,(long) (startad), 0); 558*954Sbill read(floppydes,obuff,512); 559*954Sbill obuff += 512; 560*954Sbill startad += 512; 561*954Sbill } 562*954Sbill } 563*954Sbill lwrite(startad,count,obuff) 564*954Sbill register startad, count; 565*954Sbill register char * obuff; 566*954Sbill { 567*954Sbill long trans(); 568*954Sbill extern floppydes; 569*954Sbill rt_init(); 570*954Sbill if(flg['m'-'a']==0) 571*954Sbill while( (count -= 128) >= 0) { 572*954Sbill lseek(floppydes, trans(startad), 0); 573*954Sbill write(floppydes,obuff,128); 574*954Sbill obuff += 128; 575*954Sbill startad += 128; 576*954Sbill } 577*954Sbill else 578*954Sbill while( (count -= 512) >= 0) { 579*954Sbill lseek(floppydes,(long) (startad), 0); 580*954Sbill write(floppydes,obuff,512); 581*954Sbill obuff += 512; 582*954Sbill startad += 512; 583*954Sbill } 584*954Sbill } 585*954Sbill 586*954Sbill rcmd() 587*954Sbill { 588*954Sbill register int i; 589*954Sbill 590*954Sbill rt_init(); 591*954Sbill if(namc>0) 592*954Sbill for(i = 0; i < namc; i++) 593*954Sbill if(rtr(namv[i])==0) namv[i]=0; 594*954Sbill 595*954Sbill 596*954Sbill } 597*954Sbill 598*954Sbill rtr(name) 599*954Sbill char *name; 600*954Sbill { 601*954Sbill register FLDOPE *dope; register struct rt_ent *de; 602*954Sbill struct stat buf; register struct stat *bufp = &buf; 603*954Sbill 604*954Sbill if(stat(name,bufp)<0) return(1); 605*954Sbill if(dope = lookup(name)) { 606*954Sbill /* can replace, no problem */ 607*954Sbill de = dope->rtdope; 608*954Sbill if(bufp->st_size <= (de->rt_len * 512)) 609*954Sbill printf("r - %s\n",name), 610*954Sbill toflop(name,bufp->st_size,dope); 611*954Sbill else { 612*954Sbill printf("%s will not fit in currently used file on floppy\n",name); 613*954Sbill return(1); 614*954Sbill } 615*954Sbill } else { 616*954Sbill /* Search for vacant spot */ 617*954Sbill for(de = rt_dir.rt_ents; (char *) de <= rt_last; de++) { 618*954Sbill switch((de)->rt_stat) { 619*954Sbill case RT_NULL: 620*954Sbill if(bufp->st_size <= (de->rt_len * 512)) { 621*954Sbill printf("a - %s\n",name), 622*954Sbill mkent(de,bufp,name); 623*954Sbill goto found; 624*954Sbill } 625*954Sbill continue; 626*954Sbill case RT_ESEG: 627*954Sbill return(3); 628*954Sbill } 629*954Sbill } 630*954Sbill return(5); 631*954Sbill } 632*954Sbill found: if(dope=lookup(name)) { 633*954Sbill toflop(name,bufp->st_size,dope); 634*954Sbill return(0); 635*954Sbill } 636*954Sbill return(7); 637*954Sbill 638*954Sbill } 639*954Sbill mkent(de,bufp,name) 640*954Sbill register struct rt_ent *de; 641*954Sbill register struct stat *bufp; 642*954Sbill char *name; 643*954Sbill { 644*954Sbill struct tm *localtime(); register struct tm *timp; 645*954Sbill register struct rt_ent *workp; int count; 646*954Sbill 647*954Sbill count = (((bufp->st_size -1) >>9) + 1); 648*954Sbill /* Make sure there is room */ 649*954Sbill if(de->rt_len==count) 650*954Sbill goto overwrite; 651*954Sbill if(rt_nleft==0) { 652*954Sbill if(flg['o'-'a']) 653*954Sbill goto overwrite; 654*954Sbill fprintf(stderr,"Directory full on %s\n",defdev); 655*954Sbill exit(1); 656*954Sbill } 657*954Sbill /* copy directory entries up */ 658*954Sbill for(workp = rt_curend+1; workp > de; workp--) 659*954Sbill *workp = workp[-1]; 660*954Sbill de[1].rt_len -= count; 661*954Sbill de->rt_len = count; 662*954Sbill rt_curend++; 663*954Sbill rt_nleft--; 664*954Sbill overwrite: 665*954Sbill srad50(name,de->rt_name); 666*954Sbill timp = localtime(&bufp->st_mtime); 667*954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 668*954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 669*954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 670*954Sbill de->rt_stat = RT_FILE; 671*954Sbill de->rt_pad = 0; 672*954Sbill de->rt_chan = 0; 673*954Sbill de->rt_job = 0; 674*954Sbill lwrite(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 675*954Sbill 676*954Sbill } 677*954Sbill 678*954Sbill toflop(name,ocount,dope) 679*954Sbill char *name; 680*954Sbill register FLDOPE *dope; 681*954Sbill long ocount; 682*954Sbill { 683*954Sbill register file, n, startad = dope->startad, count = ocount; 684*954Sbill char buff[512]; 685*954Sbill 686*954Sbill file = open(name,0); 687*954Sbill if(file < 0) { 688*954Sbill printf("arff: couldn't open %s\n",name);exit(1);} 689*954Sbill for( ; count >= 512; count -= 512) { 690*954Sbill read(file,buff,512); 691*954Sbill lwrite(startad,512,buff); 692*954Sbill startad += 512; 693*954Sbill } 694*954Sbill read(file,buff,count); 695*954Sbill close(file); 696*954Sbill if(count <= 0) return; 697*954Sbill for(n = count; n < 512; n ++) buff[n] = 0; 698*954Sbill lwrite(startad,512,buff); 699*954Sbill count = (dope->rtdope->rt_len * 512 - ocount) / 512 ; 700*954Sbill if(count <= 0) return; 701*954Sbill for( ; count > 0 ; count--) { 702*954Sbill startad += 512; 703*954Sbill lwrite(startad,512,zeroes); 704*954Sbill } 705*954Sbill 706*954Sbill } 707*954Sbill dcmd() 708*954Sbill { 709*954Sbill register int i; 710*954Sbill 711*954Sbill rt_init(); 712*954Sbill if(namc) 713*954Sbill for(i = 0; i < namc; i++) 714*954Sbill if(rtk(namv[i])==0) namv[i]=0; 715*954Sbill if(dirdirty) 716*954Sbill scrunch(); 717*954Sbill 718*954Sbill } 719*954Sbill rtk(name) 720*954Sbill char *name; 721*954Sbill { 722*954Sbill register FLDOPE *dope; 723*954Sbill register struct rt_ent *de; 724*954Sbill FLDOPE *lookup(); 725*954Sbill 726*954Sbill if(dope = lookup(name)) { 727*954Sbill printf("d - %s\n",name); 728*954Sbill de = dope->rtdope; 729*954Sbill de->rt_stat = RT_NULL; 730*954Sbill de->rt_name[0] = 0; 731*954Sbill de->rt_name[1] = 0; 732*954Sbill de->rt_name[2] = 0; 733*954Sbill * ((unsigned short *) & (de->rt_date)) = 0; 734*954Sbill dirdirty = 1; 735*954Sbill return(0); 736*954Sbill } 737*954Sbill return(1); 738*954Sbill } 739*954Sbill scrunch() { 740*954Sbill register struct rt_ent *de = rt_dir.rt_ents, *workp; 741*954Sbill for(de = rt_dir.rt_ents; de <= rt_curend; de++) { 742*954Sbill if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) { 743*954Sbill (de+1)->rt_len += de->rt_len; 744*954Sbill for(workp = de; workp < rt_curend; workp++) 745*954Sbill *workp = workp[1]; 746*954Sbill de--; 747*954Sbill rt_curend--; 748*954Sbill rt_nleft++; 749*954Sbill } 750*954Sbill } 751*954Sbill lwrite(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir); 752*954Sbill } 753