1*4879Ssam static char *sccsid = "@(#)arff.c 4.8 (Berkeley) 81/11/13"; 2*4879Ssam 3954Sbill #include <sys/types.h> 4954Sbill #include <sys/stat.h> 5954Sbill #include <time.h> 6954Sbill #include <signal.h> 7954Sbill #include <stdio.h> 8*4879Ssam 9954Sbill #define dbprintf printf 10*4879Ssam 11954Sbill struct rt_dat { 12*4879Ssam u_short rt_yr:5; /* year-1972 */ 13*4879Ssam u_short rt_dy:5; /* day */ 14*4879Ssam u_short rt_mo:5; /* month */ 15954Sbill }; 16*4879Ssam 17954Sbill struct rt_axent { 18954Sbill char rt_sent[14]; 19954Sbill }; 20954Sbill 21954Sbill struct rt_ent { 22*4879Ssam char rt_pad; /* unusued */ 23*4879Ssam char rt_stat; /* type of entry, or end of seg */ 24*4879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 25*4879Ssam short rt_len; /* length of file */ 26*4879Ssam char rt_chan; /* only used in temporary files */ 27*4879Ssam char rt_job; /* only used in temporary files */ 28*4879Ssam struct rt_dat rt_date; /* creation date */ 29954Sbill }; 30*4879Ssam 31*4879Ssam #define RT_TEMP 1 32*4879Ssam #define RT_NULL 2 33*4879Ssam #define RT_FILE 4 34*4879Ssam #define RT_ESEG 8 35*4879Ssam 36*4879Ssam #define RT_BLOCK 512 /* block size */ 37*4879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 38*4879Ssam 39954Sbill struct rt_head { 40*4879Ssam short rt_numseg; /* # of segments available */ 41*4879Ssam short rt_nxtseg; /* # of next logical segment */ 42*4879Ssam short rt_lstseg; /* highest seg currently open */ 43*4879Ssam u_short rt_entpad; /* extra words/directory entry */ 44*4879Ssam short rt_stfile; /* block # where files begin */ 45954Sbill }; 46*4879Ssam 47954Sbill struct rt_dir { 48954Sbill struct rt_head rt_axhead; 49954Sbill struct rt_ent rt_ents[72]; 50*4879Ssam char _dirpad[6]; 51954Sbill }; 52*4879Ssam 533346Swnj extern struct rt_dir rt_dir[RT_DIRSIZE]; 54954Sbill extern int rt_entsiz; 55954Sbill extern int floppydes; 56954Sbill extern char *rt_last; 57*4879Ssam 58954Sbill typedef struct fldope { 59954Sbill int startad; 60954Sbill int count; 61954Sbill struct rt_ent *rtdope; 62954Sbill } FLDOPE; 63*4879Ssam 64954Sbill FLDOPE *lookup(); 65*4879Ssam 66954Sbill #define rt(p) ((struct rt_ent *) p ) 67954Sbill #define Ain1 03100 68954Sbill #define Ain2 050 69*4879Ssam #define flag(c) (flg[('c') - 'a']) 70954Sbill 71*4879Ssam char *man = "rxtd"; 72*4879Ssam char zeroes[512]; 73954Sbill 74954Sbill extern char *val; 75954Sbill extern char table[256]; 76*4879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 77*4879Ssam {4, 0, 1, 0, 14}, 78*4879Ssam { {0, RT_NULL, {0, 0, 0}, 494, 0}, {0, RT_ESEG} } 79*4879Ssam }; 80954Sbill 81*4879Ssam int rt_entsiz; 82*4879Ssam int rt_nleft; 83*4879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 84*4879Ssam int floppydes; 85*4879Ssam int dirdirty; 86*4879Ssam char *rt_last; 87*4879Ssam char *defdev = "/dev/floppy"; 88954Sbill 89*4879Ssam char *opt = "vf"; 90*4879Ssam 91954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 92*4879Ssam extern long lseek(); 93*4879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 94*4879Ssam 95954Sbill int (*comfun)(); 96954Sbill char flg[26]; 97954Sbill char **namv; 98954Sbill int namc; 99954Sbill int file; 100954Sbill 101954Sbill main(argc, argv) 102*4879Ssam char *argv[]; 103954Sbill { 104954Sbill register char *cp; 105954Sbill 106*4879Ssam if (argc < 2) 107954Sbill usage(); 108954Sbill cp = argv[1]; 109*4879Ssam for (cp = argv[1]; *cp; cp++) 110*4879Ssam switch (*cp) { 111954Sbill 112*4879Ssam case 'm': 113*4879Ssam case 'v': 114*4879Ssam case 'u': 115*4879Ssam case 'w': 116*4879Ssam flg[*cp-'a']++; 117*4879Ssam continue; 118*4879Ssam case 'c': 119*4879Ssam { 120*4879Ssam #define SURE "Last chance before clobbering floppy?" 121*4879Ssam int tty; 122*4879Ssam char response[128]; 123954Sbill 124*4879Ssam tty = open("/dev/tty", 2); 125*4879Ssam write(tty, SURE, sizeof(SURE)); 126*4879Ssam read(tty, response, sizeof(response)); 127*4879Ssam if (*response != 'y') 128*4879Ssam exit(50); 129*4879Ssam flag(c)++; 130*4879Ssam close(tty); 131*4879Ssam } 132*4879Ssam dirdirty++; 133*4879Ssam continue; 134954Sbill 135*4879Ssam case 'r': 136*4879Ssam setcom(rcmd); 137*4879Ssam flag(r)++; 138*4879Ssam continue; 139954Sbill 140*4879Ssam case 'd': 141*4879Ssam setcom(dcmd); 142*4879Ssam flag(d)++; 143*4879Ssam continue; 144954Sbill 145*4879Ssam case 'x': 146*4879Ssam setcom(xcmd); 147*4879Ssam continue; 148954Sbill 149*4879Ssam case 't': 150*4879Ssam setcom(tcmd); 151*4879Ssam continue; 152954Sbill 153*4879Ssam case 'f': 154*4879Ssam defdev = argv[2]; 155*4879Ssam argv++; 156*4879Ssam argc--; 157*4879Ssam continue; 158*4879Ssam 159*4879Ssam default: 160*4879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 161*4879Ssam exit(1); 162*4879Ssam } 163*4879Ssam 164954Sbill namv = argv+2; 165954Sbill namc = argc-2; 166*4879Ssam if (comfun == 0) { 167*4879Ssam if (flag(u) == 0) { 168*4879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 169*4879Ssam man); 170954Sbill exit(1); 171954Sbill } 172954Sbill setcom(rcmd); 173954Sbill } 174954Sbill (*comfun)(); 175954Sbill exit(notfound()); 176954Sbill } 177954Sbill 178954Sbill setcom(fun) 179*4879Ssam int (*fun)(); 180954Sbill { 181*4879Ssam if (comfun != 0) { 182954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 183954Sbill exit(1); 184954Sbill } 185954Sbill comfun = fun; 186954Sbill } 187954Sbill 188954Sbill usage() 189954Sbill { 1903356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 191954Sbill exit(1); 192954Sbill } 193954Sbill 194954Sbill notfound() 195954Sbill { 196*4879Ssam register i, n = 0; 197954Sbill 198*4879Ssam for (i = 0; i < namc; i++) 199*4879Ssam if (namv[i]) { 200954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 201954Sbill n++; 202954Sbill } 203954Sbill return(n); 204954Sbill } 205954Sbill 206954Sbill mesg(c) 207954Sbill { 208*4879Ssam if (flag(v)) 209*4879Ssam if (c != 'c' || flag(v) > 1) 210954Sbill printf("%c - %s\n", c, file); 211954Sbill } 212954Sbill 213954Sbill tcmd() 214954Sbill { 215*4879Ssam register char *de, *last; 216954Sbill FLDOPE *lookup(), *dope; 217*4879Ssam int segnum, nleft; 218*4879Ssam register i; 219954Sbill register struct rt_ent *rde; 220954Sbill 221954Sbill rt_init(); 222*4879Ssam if (namc == 0) 223*4879Ssam for (segnum = 0; segnum != -1; 224*4879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 225*4879Ssam { 226*4879Ssam last = rt_last + segnum*2*RT_BLOCK; 227*4879Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 228*4879Ssam de += rt_entsiz) 229*4879Ssam if (rtls(rt(de))) { 230*4879Ssam nleft = (last-de)/rt_entsiz; 231*4879Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 232*4879Ssam printf(ENTRIES, nleft, segnum+1); 233*4879Ssam break; 234*4879Ssam } 235954Sbill } 236954Sbill else 237*4879Ssam for (i = 0; i < namc; i++) 238*4879Ssam if (dope = lookup(namv[i])) { 239954Sbill rde = dope->rtdope; 240954Sbill rtls(rde); 241954Sbill namv[i] = 0; 242954Sbill } 243954Sbill } 244*4879Ssam 245954Sbill rtls(de) 246*4879Ssam register struct rt_ent *de; 247954Sbill { 248*4879Ssam int month, day, year; 249954Sbill char name[12], ext[4]; 250954Sbill 251*4879Ssam switch (de->rt_stat) { 252*4879Ssam 253*4879Ssam case RT_TEMP: 254*4879Ssam if (flag(v)) 255954Sbill printf("Tempfile:\n"); 256*4879Ssam /* fall thru...*/ 257954Sbill 258*4879Ssam case RT_FILE: 259*4879Ssam if (!flag(v)) { 260*4879Ssam sunrad50(name, de->rt_name); 261*4879Ssam printf("%s\n", name); 262954Sbill break; 263954Sbill } 264*4879Ssam unrad50(2, de->rt_name, name); 265*4879Ssam unrad50(1, &(de->rt_name[2]), ext); 266*4879Ssam day = de->rt_date.rt_dy; 267*4879Ssam year = de->rt_date.rt_yr+72; 268*4879Ssam month = de->rt_date.rt_mo; 269*4879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 270*4879Ssam ext, month, day, year, de->rt_len); 271*4879Ssam break; 272954Sbill 273*4879Ssam case RT_NULL: 274*4879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 275*4879Ssam break; 276954Sbill 277*4879Ssam case RT_ESEG: 278*4879Ssam return(1); 279954Sbill } 280954Sbill return(0); 281954Sbill } 282*4879Ssam 283954Sbill xcmd() 284954Sbill { 285*4879Ssam register char *de, *last; 2863346Swnj int segnum; 287954Sbill char name[12]; 288954Sbill register int i; 289954Sbill 290954Sbill rt_init(); 291*4879Ssam if (namc == 0) 292*4879Ssam for (segnum = 0; segnum != -1; 293*4879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 294*4879Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 295*4879Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 296*4879Ssam de += rt_entsiz) 297*4879Ssam sunrad50(name, rt(de)->rt_name), rtx(name); 298954Sbill else 299*4879Ssam for (i = 0; i < namc; i++) 300*4879Ssam if (rtx(namv[i]) == 0) 301*4879Ssam namv[i] = 0; 302954Sbill } 303*4879Ssam 304954Sbill rtx(name) 305*4879Ssam char *name; 306954Sbill { 307954Sbill register FLDOPE *dope; 308954Sbill FLDOPE *lookup(); 309954Sbill register startad, count; 310*4879Ssam int file; 311*4879Ssam char buff[512]; 312954Sbill 313954Sbill 314*4879Ssam if (dope = lookup(name)) { 315*4879Ssam if (flag(v)) 316954Sbill rtls(dope->rtdope); 317954Sbill else 318954Sbill printf("x - %s\n",name); 319954Sbill 320*4879Ssam if ((file = creat(name, 0666)) < 0) 321*4879Ssam return(1); 322954Sbill count = dope->count; 323954Sbill startad = dope->startad; 324954Sbill for( ; count > 0 ; count -= 512) { 325*4879Ssam lread(startad, 512, buff); 326*4879Ssam write(file, buff, 512); 327954Sbill startad += 512; 328954Sbill } 329954Sbill close(file); 330954Sbill return(0); 331954Sbill } 332954Sbill return(1); 333954Sbill } 334*4879Ssam 335954Sbill rt_init() 336954Sbill { 337954Sbill static initized = 0; 338*4879Ssam register char *de, *last; 3393346Swnj register i; 3403799Shickman int dirnum; 3413799Shickman char *mode; 3423799Shickman FILE *temp_floppydes; 343954Sbill 344*4879Ssam if (initized) 345*4879Ssam return; 346954Sbill initized = 1; 347*4879Ssam if (flag(c) || flag(d) || flag(r)) 3483799Shickman mode = "r+"; 349954Sbill else 3503799Shickman mode = "r"; 351*4879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3523799Shickman perror(defdev); 3533356Swnj exit(1); 3543799Shickman } else 3553799Shickman floppydes = fileno(temp_floppydes); 356*4879Ssam if (!flag(c)) { 357*4879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3583346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 3593346Swnj if (dirnum > RT_DIRSIZE) { 360*4879Ssam fprintf(stderr,"arff: too many directory segments\n"); 361*4879Ssam exit(1); 3623346Swnj } 363*4879Ssam for (i = 1; i < dirnum; i++) 364*4879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3653489Sroot } else 3663489Sroot dirnum = 1; 367954Sbill 3683346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3693346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3703346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3713346Swnj rt_nleft = 0; 3723346Swnj 373*4879Ssam for (i = 0; i < dirnum; i++) { 374*4879Ssam last = rt_last + i*2*RT_BLOCK; 375*4879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 376*4879Ssam if (rt(de)->rt_stat == RT_ESEG) 377*4879Ssam break; 378*4879Ssam rt_curend[i] = rt(de); 379*4879Ssam rt_nleft += (last-de)/rt_entsiz; 380954Sbill } 381954Sbill } 382954Sbill 383954Sbill static FLDOPE result; 384*4879Ssam 385954Sbill FLDOPE * 386954Sbill lookup(name) 387*4879Ssam char *name; 388954Sbill { 389954Sbill unsigned short rname[3]; 390*4879Ssam register char *de, *last; 3913346Swnj int segnum; 392954Sbill register index; 393954Sbill 394954Sbill srad50(name,rname); 395954Sbill 3963356Swnj /* 397954Sbill * Search for name, accumulate blocks in index 398954Sbill */ 399954Sbill rt_init(); 400*4879Ssam for (segnum = 0; segnum != -1; 401*4879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 402*4879Ssam { 403*4879Ssam index = 0; 404*4879Ssam last = rt_last + segnum*2*RT_BLOCK; 405*4879Ssam for (de=((char *)&rt_dir[segnum])+10; 406*4879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 407*4879Ssam switch(rt(de)->rt_stat) { 408*4879Ssam 409*4879Ssam case RT_FILE: 410*4879Ssam case RT_TEMP: 411*4879Ssam if(samename(rname,rt(de)->rt_name)) { 412*4879Ssam result.count = rt(de)->rt_len * 512; 413*4879Ssam result.startad = 512* 414*4879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 415*4879Ssam result.rtdope = (struct rt_ent *) de; 416*4879Ssam return(&result); 417*4879Ssam } 418*4879Ssam 419*4879Ssam case RT_NULL: 420*4879Ssam index += rt(de)->rt_len; 421*4879Ssam } 4223346Swnj } 423954Sbill return((FLDOPE *) 0); 424*4879Ssam 425954Sbill } 426*4879Ssam 427954Sbill static 428*4879Ssam samename(a, b) 429*4879Ssam u_short a[], b[]; 430954Sbill { 431*4879Ssam return(*a == *b && a[1] == b[1] && a[2] == b[2] ); 432954Sbill } 433954Sbill 434*4879Ssam rad50(cp, out) 435*4879Ssam register u_char *cp; 436*4879Ssam u_short *out; 437954Sbill { 438*4879Ssam register index, temp; 439954Sbill 440*4879Ssam for (index = 0; *cp; index++) { 441954Sbill temp = Ain1 * table[*cp++]; 442*4879Ssam if (*cp!=0) { 443954Sbill temp += Ain2 * table[*cp++]; 444954Sbill if(*cp!=0) 445954Sbill temp += table[*cp++]; 446954Sbill } 447954Sbill out[index] = temp; 448954Sbill } 449954Sbill } 450954Sbill 451*4879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 452*4879Ssam 453*4879Ssam unrad50(count, in, cp) 454*4879Ssam u_short *in; 455*4879Ssam register char *cp; 456954Sbill { 457*4879Ssam register i, temp; 458*4879Ssam register u_char *v = (u_char *) val; 459954Sbill 460*4879Ssam for (i = 0; i < count; i++) { 461954Sbill temp = in[i]; 462*4879Ssam reduce(*cp++, temp, Ain1); 463*4879Ssam reduce(*cp++, temp, Ain2); 464*4879Ssam reduce(*cp++, temp, 1); 465954Sbill } 466954Sbill *cp=0; 467954Sbill } 468954Sbill 469*4879Ssam srad50(name, rname) 470*4879Ssam register char *name; 471*4879Ssam register u_short *rname; 472954Sbill { 473*4879Ssam register index; 474*4879Ssam register char *cp; 475*4879Ssam char file[7], ext[4]; 476*4879Ssam 4773356Swnj /* 478954Sbill * Find end of pathname 479954Sbill */ 480*4879Ssam for (cp = name; *cp++; ) 481*4879Ssam ; 482*4879Ssam while (cp >= name && *--cp != '/') 483*4879Ssam ; 484954Sbill cp++; 4853356Swnj /* 486954Sbill * Change to rad50 487954Sbill */ 488*4879Ssam for (index = 0; *cp; ) { 489954Sbill file[index++] = *cp++; 490*4879Ssam if (*cp == '.') { 491954Sbill cp++; 492954Sbill break; 493954Sbill } 494*4879Ssam if (index >= 6) { 495954Sbill break; 496954Sbill } 497954Sbill } 498954Sbill file[index] = 0; 499*4879Ssam for (index = 0; *cp; ) { 500954Sbill ext[index++] = *cp++; 501*4879Ssam if (*cp == '.' || index >= 3) 502954Sbill break; 503954Sbill } 504954Sbill ext[index]=0; 505*4879Ssam rname[0] = rname[1] = rname[2] = 0; 506*4879Ssam rad50((u_char *)file, rname); 507*4879Ssam rad50((u_char *)ext, rname+2); 508954Sbill } 509*4879Ssam 510*4879Ssam sunrad50(name, rname) 511*4879Ssam u_short rname[]; 512*4879Ssam register char *name; 513954Sbill { 514954Sbill register char *cp, *cp2; 515954Sbill char ext[4]; 516954Sbill 517*4879Ssam unrad50(2, rname, name); 518*4879Ssam unrad50(1, rname + 2, ext); 519*4879Ssam /* 520*4879Ssam * Jam name and extension together with a dot 521*4879Ssam * deleting white space 522*4879Ssam */ 523*4879Ssam for (cp = name; *cp++;) 524*4879Ssam ; 525*4879Ssam --cp; 526*4879Ssam while (*--cp == ' ' && cp >= name) 527*4879Ssam ; 528*4879Ssam *++cp = '.'; 529*4879Ssam cp++; 530*4879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 531954Sbill *cp++ = *cp2++; 532954Sbill *cp=0; 533*4879Ssam if (cp[-1] == '.') 534*4879Ssam cp[-1] = 0; 535954Sbill } 536954Sbill 537954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 538954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 539*4879Ssam 540954Sbill static char table[256] = { 541954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 542954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 543954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 544954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 545954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 546954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 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, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 550954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 551954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 552954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 553954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 554954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 555954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 556954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 557954Sbill 558*4879Ssam /* 559*4879Ssam * Logical to physical adress translation 560*4879Ssam */ 561*4879Ssam long 562*4879Ssam trans(logical) 563*4879Ssam register int logical; 564954Sbill { 565954Sbill register int sector, bytes, track; 566954Sbill 567*4879Ssam logical += 26*128; 568*4879Ssam bytes = (logical&127); 569954Sbill logical >>= 7; 570*4879Ssam sector = logical%26; 571954Sbill if(sector >= 13) 572*4879Ssam sector = sector*2+1; 573954Sbill else 574954Sbill sector *= 2; 575*4879Ssam sector += 26 + ((track = (logical/26))-1)*6; 576954Sbill sector %= 26; 577*4879Ssam return((((track*26)+sector) << 7) + bytes); 578954Sbill } 579*4879Ssam 580*4879Ssam lread(startad, count, obuff) 581*4879Ssam register startad, count; 582*4879Ssam register char *obuff; 583954Sbill { 584954Sbill long trans(); 585954Sbill extern floppydes; 586*4879Ssam register int size = flag(m) ? 512 : 128; 587*4879Ssam 588954Sbill rt_init(); 589*4879Ssam while ((count -= size) >= 0) { 590*4879Ssam lseek(floppydes, flag(m) ? 591*4879Ssam (long)startad : trans(startad), 0); 592*4879Ssam if (read(floppydes, obuff, size) != size) 593*4879Ssam fprintf(stderr, "arff: read error block %d\n", 594*4879Ssam startad/size); 595*4879Ssam obuff += size; 596*4879Ssam startad += size; 597*4879Ssam } 598954Sbill } 599*4879Ssam 600*4879Ssam lwrite(startad, count, obuff) 601*4879Ssam register startad, count; 602*4879Ssam register char *obuff; 603954Sbill { 604954Sbill long trans(); 605954Sbill extern floppydes; 606*4879Ssam register int size = flag(m) ? 512 : 128; 607*4879Ssam 608954Sbill rt_init(); 609*4879Ssam while ((count -= size) >= 0) { 610*4879Ssam lseek(floppydes, flag(m) ? 611*4879Ssam (long)startad : trans(startad), 0); 612*4879Ssam if (write(floppydes, obuff, size) != size) 613*4879Ssam fprintf(stderr, "arff: write error block %d\n", 614*4879Ssam startad/size); 615*4879Ssam obuff += size; 616*4879Ssam startad += size; 617*4879Ssam } 618954Sbill } 619954Sbill 620954Sbill rcmd() 621954Sbill { 622954Sbill register int i; 623954Sbill 624954Sbill rt_init(); 625*4879Ssam if (namc > 0) 626*4879Ssam for (i = 0; i < namc; i++) 627*4879Ssam if (rtr(namv[i]) == 0) 628*4879Ssam namv[i] = 0; 629954Sbill } 630954Sbill 631954Sbill rtr(name) 632*4879Ssam char *name; 633954Sbill { 634*4879Ssam register FLDOPE *dope; 635*4879Ssam register struct rt_ent *de; 636*4879Ssam struct stat buf; 637*4879Ssam register struct stat *bufp = &buf; 6383346Swnj int segnum; 6393346Swnj register char *last; 640954Sbill 641*4879Ssam if (stat(name, bufp) < 0) { 6423489Sroot perror(name); 6433489Sroot return(-1); 6443489Sroot } 645*4879Ssam if (dope = lookup(name)) { 646954Sbill /* can replace, no problem */ 647954Sbill de = dope->rtdope; 648*4879Ssam if (bufp->st_size <= (de->rt_len * 512)) 649954Sbill printf("r - %s\n",name), 650*4879Ssam 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 { 656*4879Ssam /* Search for vacant spot */ 657*4879Ssam for (segnum = 0; segnum != -1; 658*4879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 659*4879Ssam { 660*4879Ssam last = rt_last + segnum*2*RT_BLOCK; 661*4879Ssam for (de = rt_dir[segnum].rt_ents; 662*4879Ssam rt(de)->rt_stat != RT_ESEG; de++) 663*4879Ssam if ((de)->rt_stat == RT_NULL) { 664*4879Ssam if (bufp->st_size <= (de->rt_len*512)) { 665*4879Ssam printf("a - %s\n",name), 666*4879Ssam mkent(de, segnum, bufp,name); 667*4879Ssam goto found; 668*4879Ssam } 669*4879Ssam continue; 670954Sbill } 6713346Swnj } 6723489Sroot printf("%s: no slot for file\n", name); 6733489Sroot return (-1); 674954Sbill } 675*4879Ssam 676*4879Ssam found: 677*4879Ssam if (dope = lookup(name)) { 678*4879Ssam toflop(name, bufp->st_size, dope); 6793489Sroot return (0); 680954Sbill } 6813489Sroot printf("%s: internal error, added then not found\n", name); 6823489Sroot return (-1); 683*4879Ssam } 684954Sbill 685*4879Ssam mkent(de, segnum, bufp, name) 686*4879Ssam register struct rt_ent *de; 687*4879Ssam int segnum; 688*4879Ssam register struct stat *bufp; 689*4879Ssam char *name; 690954Sbill { 691*4879Ssam struct tm *localtime(); 692*4879Ssam register struct tm *timp; 693*4879Ssam register struct rt_ent *workp; 694*4879Ssam int count; 695954Sbill 696954Sbill count = (((bufp->st_size -1) >>9) + 1); 697*4879Ssam /* make sure there is room */ 698*4879Ssam if (de->rt_len == count) 699954Sbill goto overwrite; 700*4879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 701*4879Ssam /* no entries left on segment */ 702*4879Ssam if (flag(o)) 703954Sbill goto overwrite; 7043346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 705*4879Ssam defdev); 706954Sbill exit(1); 707954Sbill } 708*4879Ssam /* copy directory entries up */ 709*4879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 710954Sbill *workp = workp[-1]; 711954Sbill de[1].rt_len -= count; 712954Sbill de->rt_len = count; 7133346Swnj rt_curend[segnum]++; 714954Sbill rt_nleft--; 715*4879Ssam 716954Sbill overwrite: 717954Sbill srad50(name,de->rt_name); 718954Sbill timp = localtime(&bufp->st_mtime); 719954Sbill de->rt_date.rt_dy = timp->tm_mday + 1; 720954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 721954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 722954Sbill de->rt_stat = RT_FILE; 723954Sbill de->rt_pad = 0; 724954Sbill de->rt_chan = 0; 725954Sbill de->rt_job = 0; 726*4879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 727954Sbill } 728954Sbill 729*4879Ssam toflop(name, ocount, dope) 730*4879Ssam char *name; 731*4879Ssam register FLDOPE *dope; 732*4879Ssam long ocount; 733954Sbill { 734954Sbill register file, n, startad = dope->startad, count = ocount; 735954Sbill char buff[512]; 736954Sbill 737*4879Ssam file = open(name, 0); 738*4879Ssam if (file < 0) { 739*4879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 740*4879Ssam exit(1); 741*4879Ssam } 742954Sbill for( ; count >= 512; count -= 512) { 743*4879Ssam read(file, buff, 512); 744*4879Ssam lwrite(startad, 512, buff); 745954Sbill startad += 512; 746954Sbill } 747*4879Ssam read(file, buff, count); 748954Sbill close(file); 749*4879Ssam if (count <= 0) 750*4879Ssam return; 751*4879Ssam for (n = count; n < 512; n ++) 752*4879Ssam buff[n] = 0; 753*4879Ssam lwrite(startad, 512, buff); 754*4879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 755*4879Ssam if (count <= 0) 756*4879Ssam return; 757*4879Ssam for ( ; count > 0 ; count--) { 758954Sbill startad += 512; 759*4879Ssam lwrite(startad, 512, zeroes); 760954Sbill } 761*4879Ssam } 762954Sbill 763954Sbill dcmd() 764954Sbill { 765954Sbill register int i; 766954Sbill 767954Sbill rt_init(); 768*4879Ssam if (namc) 769*4879Ssam for (i = 0; i < namc; i++) 770*4879Ssam if (rtk(namv[i])==0) 771*4879Ssam namv[i]=0; 772*4879Ssam if (dirdirty) 773954Sbill scrunch(); 774954Sbill } 775*4879Ssam 776954Sbill rtk(name) 777*4879Ssam char *name; 778954Sbill { 779954Sbill register FLDOPE *dope; 780954Sbill register struct rt_ent *de; 781954Sbill FLDOPE *lookup(); 782954Sbill 783*4879Ssam if (dope = lookup(name)) { 784954Sbill printf("d - %s\n",name); 785954Sbill de = dope->rtdope; 786954Sbill de->rt_stat = RT_NULL; 787954Sbill de->rt_name[0] = 0; 788954Sbill de->rt_name[1] = 0; 789954Sbill de->rt_name[2] = 0; 790*4879Ssam * ((u_short *)&(de->rt_date)) = 0; 791954Sbill dirdirty = 1; 792954Sbill return(0); 793954Sbill } 794954Sbill return(1); 795954Sbill } 796*4879Ssam 797*4879Ssam scrunch() 798*4879Ssam { 7993346Swnj register struct rt_ent *de , *workp; 8003346Swnj register segnum; 801*4879Ssam 802*4879Ssam for (segnum = 0; segnum != -1; 8033346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 804*4879Ssam dirdirty = 0; 805*4879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 806*4879Ssam if (de->rt_stat == RT_NULL && de[1].rt_stat == RT_NULL) { 807*4879Ssam (de+1)->rt_len += de->rt_len; 808*4879Ssam for (workp = de; workp < rt_curend[segnum]; workp++) 809*4879Ssam *workp = workp[1]; 810*4879Ssam de--; 811*4879Ssam rt_curend[segnum]--; 812*4879Ssam rt_nleft++; 813*4879Ssam dirdirty = 1; 814*4879Ssam } 815*4879Ssam if (dirdirty) 816*4879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 817*4879Ssam (char *)&rt_dir[segnum]); 818954Sbill } 819954Sbill } 820