1*9877Ssam #ifndef lint 2*9877Ssam static char sccsid[] = "@(#)arff.c 4.12 (Berkeley) 82/12/23"; 3*9877Ssam #endif 44879Ssam 5954Sbill #include <sys/types.h> 6954Sbill #include <sys/stat.h> 7954Sbill #include <time.h> 8954Sbill #include <signal.h> 9954Sbill #include <stdio.h> 104879Ssam 11954Sbill #define dbprintf printf 124879Ssam 13954Sbill struct rt_dat { 144879Ssam u_short rt_yr:5; /* year-1972 */ 154879Ssam u_short rt_dy:5; /* day */ 164879Ssam u_short rt_mo:5; /* month */ 17954Sbill }; 184879Ssam 19954Sbill struct rt_axent { 20954Sbill char rt_sent[14]; 21954Sbill }; 22954Sbill 23954Sbill struct rt_ent { 244879Ssam char rt_pad; /* unusued */ 254879Ssam char rt_stat; /* type of entry, or end of seg */ 264879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 277319Swnj u_short rt_len; /* length of file */ 284879Ssam char rt_chan; /* only used in temporary files */ 294879Ssam char rt_job; /* only used in temporary files */ 30*9877Ssam struct rt_dat rt_date; /* creation date */ 31954Sbill }; 324879Ssam 334879Ssam #define RT_TEMP 1 344879Ssam #define RT_NULL 2 354879Ssam #define RT_FILE 4 364879Ssam #define RT_ESEG 8 374879Ssam 384879Ssam #define RT_BLOCK 512 /* block size */ 394879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 404879Ssam 41954Sbill struct rt_head { 424879Ssam short rt_numseg; /* # of segments available */ 434879Ssam short rt_nxtseg; /* # of next logical segment */ 444879Ssam short rt_lstseg; /* highest seg currently open */ 454879Ssam u_short rt_entpad; /* extra words/directory entry */ 464879Ssam short rt_stfile; /* block # where files begin */ 47954Sbill }; 484879Ssam 49954Sbill struct rt_dir { 50954Sbill struct rt_head rt_axhead; 51954Sbill struct rt_ent rt_ents[72]; 524879Ssam char _dirpad[6]; 53954Sbill }; 544879Ssam 55954Sbill typedef struct fldope { 56954Sbill int startad; 57954Sbill int count; 58954Sbill struct rt_ent *rtdope; 59954Sbill } FLDOPE; 604879Ssam 61954Sbill FLDOPE *lookup(); 624879Ssam 63*9877Ssam #define rt(p) ((struct rt_ent *) p ) 64*9877Ssam #define Ain1 03100 65*9877Ssam #define Ain2 050 66*9877Ssam #define flag(c) (flg[('c') - 'a']) 67954Sbill 68*9877Ssam char *man = "rxtd"; 69*9877Ssam char zeroes[512]; 70954Sbill 71954Sbill extern char *val; 72954Sbill extern char table[256]; 734879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 74*9877Ssam { 4, 0, 1, 0, 14 }, 75*9877Ssam { { 0, RT_NULL, { 0, 0, 0 }, 494, 0 }, 76*9877Ssam { 0, RT_ESEG } } 774879Ssam }; 78954Sbill 794879Ssam int rt_entsiz; 804879Ssam int rt_nleft; 814879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 824879Ssam int floppydes; 834879Ssam int dirdirty; 844879Ssam char *rt_last; 854879Ssam char *defdev = "/dev/floppy"; 86954Sbill 874879Ssam char *opt = "vf"; 884879Ssam 89954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 904879Ssam extern long lseek(); 914879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 924879Ssam 93954Sbill int (*comfun)(); 94954Sbill char flg[26]; 95954Sbill char **namv; 96954Sbill int namc; 97954Sbill int file; 98954Sbill 99954Sbill main(argc, argv) 1004879Ssam char *argv[]; 101954Sbill { 102954Sbill register char *cp; 103954Sbill 1044879Ssam if (argc < 2) 105954Sbill usage(); 106954Sbill cp = argv[1]; 1074879Ssam for (cp = argv[1]; *cp; cp++) 1084879Ssam switch (*cp) { 109954Sbill 1104879Ssam case 'm': 1114879Ssam case 'v': 1124879Ssam case 'u': 1134879Ssam case 'w': 1144879Ssam flg[*cp-'a']++; 1154879Ssam continue; 1164879Ssam case 'c': 1174879Ssam { 1184879Ssam #define SURE "Last chance before clobbering floppy?" 1194879Ssam int tty; 1204879Ssam char response[128]; 121954Sbill 1224879Ssam tty = open("/dev/tty", 2); 1234879Ssam write(tty, SURE, sizeof(SURE)); 1244879Ssam read(tty, response, sizeof(response)); 1254879Ssam if (*response != 'y') 1264879Ssam exit(50); 1274879Ssam flag(c)++; 1284879Ssam close(tty); 1294879Ssam } 1304879Ssam dirdirty++; 1314879Ssam continue; 132954Sbill 1334879Ssam case 'r': 1344879Ssam setcom(rcmd); 1354879Ssam flag(r)++; 1364879Ssam continue; 137954Sbill 1384879Ssam case 'd': 1394879Ssam setcom(dcmd); 1404879Ssam flag(d)++; 1414879Ssam continue; 142954Sbill 1434879Ssam case 'x': 1444879Ssam setcom(xcmd); 1454879Ssam continue; 146954Sbill 1474879Ssam case 't': 1484879Ssam setcom(tcmd); 1494879Ssam continue; 150954Sbill 1514879Ssam case 'f': 1524879Ssam defdev = argv[2]; 1534879Ssam argv++; 1544879Ssam argc--; 1554879Ssam continue; 1564879Ssam 1574879Ssam default: 1584879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1594879Ssam exit(1); 1604879Ssam } 1614879Ssam 162954Sbill namv = argv+2; 163954Sbill namc = argc-2; 1644879Ssam if (comfun == 0) { 1654879Ssam if (flag(u) == 0) { 1664879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1674879Ssam man); 168954Sbill exit(1); 169954Sbill } 170954Sbill setcom(rcmd); 171954Sbill } 172954Sbill (*comfun)(); 173954Sbill exit(notfound()); 174954Sbill } 175954Sbill 176954Sbill setcom(fun) 1774879Ssam int (*fun)(); 178954Sbill { 1794879Ssam if (comfun != 0) { 180954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 181954Sbill exit(1); 182954Sbill } 183954Sbill comfun = fun; 184954Sbill } 185954Sbill 186954Sbill usage() 187954Sbill { 1883356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 189954Sbill exit(1); 190954Sbill } 191954Sbill 192954Sbill notfound() 193954Sbill { 1944879Ssam register i, n = 0; 195954Sbill 1964879Ssam for (i = 0; i < namc; i++) 1974879Ssam if (namv[i]) { 198954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 199954Sbill n++; 200954Sbill } 201*9877Ssam return (n); 202954Sbill } 203954Sbill 204954Sbill mesg(c) 205954Sbill { 2064879Ssam if (flag(v)) 2074879Ssam if (c != 'c' || flag(v) > 1) 208954Sbill printf("%c - %s\n", c, file); 209954Sbill } 210954Sbill 211954Sbill tcmd() 212954Sbill { 2134879Ssam register char *de, *last; 214954Sbill FLDOPE *lookup(), *dope; 2154879Ssam int segnum, nleft; 2164879Ssam register i; 217954Sbill register struct rt_ent *rde; 218954Sbill 219954Sbill rt_init(); 220*9877Ssam if (namc != 0) { 2214879Ssam for (i = 0; i < namc; i++) 2224879Ssam if (dope = lookup(namv[i])) { 223954Sbill rde = dope->rtdope; 224954Sbill rtls(rde); 225954Sbill namv[i] = 0; 226954Sbill } 227*9877Ssam return; 228*9877Ssam } 229*9877Ssam for (segnum = 0; segnum != -1; 230*9877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 231*9877Ssam last = rt_last + segnum*2*RT_BLOCK; 232*9877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 233*9877Ssam de += rt_entsiz) 234*9877Ssam if (rtls(rt(de))) { 235*9877Ssam nleft = (last-de)/rt_entsiz; 236*9877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 237*9877Ssam printf(ENTRIES, nleft, segnum+1); 238*9877Ssam break; 239*9877Ssam } 240*9877Ssam } 241954Sbill } 2424879Ssam 243954Sbill rtls(de) 2444879Ssam register struct rt_ent *de; 245954Sbill { 2464879Ssam int month, day, year; 247954Sbill char name[12], ext[4]; 248954Sbill 2494879Ssam switch (de->rt_stat) { 2504879Ssam 2514879Ssam case RT_TEMP: 2524879Ssam if (flag(v)) 253954Sbill printf("Tempfile:\n"); 2544879Ssam /* fall thru...*/ 255954Sbill 2564879Ssam case RT_FILE: 2574879Ssam if (!flag(v)) { 2584879Ssam sunrad50(name, de->rt_name); 2594879Ssam printf("%s\n", name); 260954Sbill break; 261954Sbill } 2624879Ssam unrad50(2, de->rt_name, name); 2634879Ssam unrad50(1, &(de->rt_name[2]), ext); 2644879Ssam day = de->rt_date.rt_dy; 2654879Ssam year = de->rt_date.rt_yr+72; 2664879Ssam month = de->rt_date.rt_mo; 2674879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2684879Ssam ext, month, day, year, de->rt_len); 2694879Ssam break; 270954Sbill 2714879Ssam case RT_NULL: 2724879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2734879Ssam break; 274954Sbill 2754879Ssam case RT_ESEG: 276*9877Ssam return (1); 277954Sbill } 278*9877Ssam return (0); 279954Sbill } 2804879Ssam 281954Sbill xcmd() 282954Sbill { 2834879Ssam register char *de, *last; 2843346Swnj int segnum; 285954Sbill char name[12]; 286954Sbill register int i; 287954Sbill 288954Sbill rt_init(); 289*9877Ssam if (namc != 0) { 2904879Ssam for (i = 0; i < namc; i++) 2914879Ssam if (rtx(namv[i]) == 0) 2924879Ssam namv[i] = 0; 293*9877Ssam return; 294*9877Ssam } 295*9877Ssam for (segnum = 0; segnum != -1; 296*9877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 297*9877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 298*9877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 299*9877Ssam de += rt_entsiz) 300*9877Ssam switch (rt(de)->rt_stat) { 301*9877Ssam 302*9877Ssam case RT_ESEG: 303*9877Ssam return; 304*9877Ssam 305*9877Ssam case RT_TEMP: 306*9877Ssam case RT_FILE: 307*9877Ssam sunrad50(name,rt(de)->rt_name); 308*9877Ssam rtx(name); 309*9877Ssam 310*9877Ssam case RT_NULL: 311*9877Ssam break; 312*9877Ssam } 313954Sbill } 3144879Ssam 315954Sbill rtx(name) 3164879Ssam char *name; 317954Sbill { 318954Sbill register FLDOPE *dope; 319954Sbill FLDOPE *lookup(); 320954Sbill register startad, count; 3214879Ssam int file; 3224879Ssam char buff[512]; 323954Sbill 324954Sbill 3254879Ssam if (dope = lookup(name)) { 3264879Ssam if (flag(v)) 327954Sbill rtls(dope->rtdope); 328954Sbill else 329954Sbill printf("x - %s\n",name); 330954Sbill 3314879Ssam if ((file = creat(name, 0666)) < 0) 332*9877Ssam return (1); 333954Sbill count = dope->count; 334954Sbill startad = dope->startad; 335954Sbill for( ; count > 0 ; count -= 512) { 3364879Ssam lread(startad, 512, buff); 3374879Ssam write(file, buff, 512); 338954Sbill startad += 512; 339954Sbill } 340954Sbill close(file); 341*9877Ssam return (0); 342954Sbill } 343*9877Ssam return (1); 344954Sbill } 3454879Ssam 346954Sbill rt_init() 347954Sbill { 348954Sbill static initized = 0; 3494879Ssam register char *de, *last; 3503346Swnj register i; 3513799Shickman int dirnum; 3523799Shickman char *mode; 3533799Shickman FILE *temp_floppydes; 354954Sbill 3554879Ssam if (initized) 3564879Ssam return; 357954Sbill initized = 1; 3584879Ssam if (flag(c) || flag(d) || flag(r)) 3593799Shickman mode = "r+"; 360954Sbill else 3613799Shickman mode = "r"; 3624879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3633799Shickman perror(defdev); 3643356Swnj exit(1); 3653799Shickman } else 3663799Shickman floppydes = fileno(temp_floppydes); 3674879Ssam if (!flag(c)) { 3684879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3693346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 3703346Swnj if (dirnum > RT_DIRSIZE) { 3714879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3724879Ssam exit(1); 3733346Swnj } 3744879Ssam for (i = 1; i < dirnum; i++) 3754879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3763489Sroot } else 3773489Sroot dirnum = 1; 378954Sbill 3793346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3803346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3813346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3823346Swnj rt_nleft = 0; 3833346Swnj 3844879Ssam for (i = 0; i < dirnum; i++) { 3854879Ssam last = rt_last + i*2*RT_BLOCK; 3864879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 3874879Ssam if (rt(de)->rt_stat == RT_ESEG) 3884879Ssam break; 3894879Ssam rt_curend[i] = rt(de); 3904879Ssam rt_nleft += (last-de)/rt_entsiz; 391954Sbill } 392954Sbill } 393954Sbill 394954Sbill static FLDOPE result; 3954879Ssam 396954Sbill FLDOPE * 397954Sbill lookup(name) 3984879Ssam char *name; 399954Sbill { 400954Sbill unsigned short rname[3]; 4014879Ssam register char *de, *last; 4023346Swnj int segnum; 403954Sbill register index; 404954Sbill 405954Sbill srad50(name,rname); 406954Sbill 4073356Swnj /* 408954Sbill * Search for name, accumulate blocks in index 409954Sbill */ 410954Sbill rt_init(); 4114879Ssam for (segnum = 0; segnum != -1; 4124879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4134879Ssam { 4144879Ssam index = 0; 4154879Ssam last = rt_last + segnum*2*RT_BLOCK; 4164879Ssam for (de=((char *)&rt_dir[segnum])+10; 4174879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4184879Ssam switch(rt(de)->rt_stat) { 4194879Ssam 4204879Ssam case RT_FILE: 4214879Ssam case RT_TEMP: 4224879Ssam if(samename(rname,rt(de)->rt_name)) { 4234879Ssam result.count = rt(de)->rt_len * 512; 4244879Ssam result.startad = 512* 4254879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4264879Ssam result.rtdope = (struct rt_ent *) de; 427*9877Ssam return (&result); 4284879Ssam } 4294879Ssam 4304879Ssam case RT_NULL: 4314879Ssam index += rt(de)->rt_len; 4324879Ssam } 4333346Swnj } 434*9877Ssam return ((FLDOPE *) 0); 4354879Ssam 436954Sbill } 4374879Ssam 438954Sbill static 4394879Ssam samename(a, b) 4404879Ssam u_short a[], b[]; 441954Sbill { 442*9877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 443954Sbill } 444954Sbill 4454879Ssam rad50(cp, out) 4464879Ssam register u_char *cp; 4474879Ssam u_short *out; 448954Sbill { 4494879Ssam register index, temp; 450954Sbill 4514879Ssam for (index = 0; *cp; index++) { 452954Sbill temp = Ain1 * table[*cp++]; 4534879Ssam if (*cp!=0) { 454954Sbill temp += Ain2 * table[*cp++]; 455954Sbill if(*cp!=0) 456954Sbill temp += table[*cp++]; 457954Sbill } 458954Sbill out[index] = temp; 459954Sbill } 460954Sbill } 461954Sbill 4624879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4634879Ssam 4644879Ssam unrad50(count, in, cp) 4654879Ssam u_short *in; 4664879Ssam register char *cp; 467954Sbill { 4684879Ssam register i, temp; 4694879Ssam register u_char *v = (u_char *) val; 470954Sbill 4714879Ssam for (i = 0; i < count; i++) { 472954Sbill temp = in[i]; 4734879Ssam reduce(*cp++, temp, Ain1); 4744879Ssam reduce(*cp++, temp, Ain2); 4754879Ssam reduce(*cp++, temp, 1); 476954Sbill } 477954Sbill *cp=0; 478954Sbill } 479954Sbill 4804879Ssam srad50(name, rname) 4814879Ssam register char *name; 4824879Ssam register u_short *rname; 483954Sbill { 4844879Ssam register index; 4854879Ssam register char *cp; 4864879Ssam char file[7], ext[4]; 4874879Ssam 4883356Swnj /* 489954Sbill * Find end of pathname 490954Sbill */ 4914879Ssam for (cp = name; *cp++; ) 4924879Ssam ; 4934879Ssam while (cp >= name && *--cp != '/') 4944879Ssam ; 495954Sbill cp++; 4963356Swnj /* 497954Sbill * Change to rad50 498954Sbill */ 4994879Ssam for (index = 0; *cp; ) { 500954Sbill file[index++] = *cp++; 5014879Ssam if (*cp == '.') { 502954Sbill cp++; 503954Sbill break; 504954Sbill } 5054879Ssam if (index >= 6) { 506954Sbill break; 507954Sbill } 508954Sbill } 509954Sbill file[index] = 0; 5104879Ssam for (index = 0; *cp; ) { 511954Sbill ext[index++] = *cp++; 5124879Ssam if (*cp == '.' || index >= 3) 513954Sbill break; 514954Sbill } 515954Sbill ext[index]=0; 5164879Ssam rname[0] = rname[1] = rname[2] = 0; 5174879Ssam rad50((u_char *)file, rname); 5184879Ssam rad50((u_char *)ext, rname+2); 519954Sbill } 5204879Ssam 5214879Ssam sunrad50(name, rname) 5224879Ssam u_short rname[]; 5234879Ssam register char *name; 524954Sbill { 525954Sbill register char *cp, *cp2; 526954Sbill char ext[4]; 527954Sbill 5284879Ssam unrad50(2, rname, name); 5294879Ssam unrad50(1, rname + 2, ext); 5304879Ssam /* 5314879Ssam * Jam name and extension together with a dot 5324879Ssam * deleting white space 5334879Ssam */ 5344879Ssam for (cp = name; *cp++;) 5354879Ssam ; 5364879Ssam --cp; 5374879Ssam while (*--cp == ' ' && cp >= name) 5384879Ssam ; 5394879Ssam *++cp = '.'; 5404879Ssam cp++; 5414879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 542954Sbill *cp++ = *cp2++; 543954Sbill *cp=0; 5444879Ssam if (cp[-1] == '.') 5454879Ssam cp[-1] = 0; 546954Sbill } 547954Sbill 548954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 549954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5504879Ssam 551954Sbill static char table[256] = { 552954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 553954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 554954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 555954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 556954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 557954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 558954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 559954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 560954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 561954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 562954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 563954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 564954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 565954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 566954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 567954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 568954Sbill 5694879Ssam /* 5704879Ssam * Logical to physical adress translation 5714879Ssam */ 5724879Ssam long 5734879Ssam trans(logical) 5744879Ssam register int logical; 575954Sbill { 576954Sbill register int sector, bytes, track; 577954Sbill 5784879Ssam logical += 26*128; 5794879Ssam bytes = (logical&127); 580954Sbill logical >>= 7; 5814879Ssam sector = logical%26; 582954Sbill if(sector >= 13) 5834879Ssam sector = sector*2+1; 584954Sbill else 585954Sbill sector *= 2; 5864879Ssam sector += 26 + ((track = (logical/26))-1)*6; 587954Sbill sector %= 26; 588*9877Ssam return ((((track*26)+sector) << 7) + bytes); 589954Sbill } 5904879Ssam 5914879Ssam lread(startad, count, obuff) 5924879Ssam register startad, count; 5934879Ssam register char *obuff; 594954Sbill { 595954Sbill long trans(); 596954Sbill extern floppydes; 5974879Ssam register int size = flag(m) ? 512 : 128; 5984879Ssam 599954Sbill rt_init(); 6004879Ssam while ((count -= size) >= 0) { 6014879Ssam lseek(floppydes, flag(m) ? 6024879Ssam (long)startad : trans(startad), 0); 6034879Ssam if (read(floppydes, obuff, size) != size) 6044879Ssam fprintf(stderr, "arff: read error block %d\n", 6054879Ssam startad/size); 6064879Ssam obuff += size; 6074879Ssam startad += size; 6084879Ssam } 609954Sbill } 6104879Ssam 6114879Ssam lwrite(startad, count, obuff) 6124879Ssam register startad, count; 6134879Ssam register char *obuff; 614954Sbill { 615954Sbill long trans(); 616954Sbill extern floppydes; 6174879Ssam register int size = flag(m) ? 512 : 128; 6184879Ssam 619954Sbill rt_init(); 6204879Ssam while ((count -= size) >= 0) { 6214879Ssam lseek(floppydes, flag(m) ? 6224879Ssam (long)startad : trans(startad), 0); 6234879Ssam if (write(floppydes, obuff, size) != size) 6244879Ssam fprintf(stderr, "arff: write error block %d\n", 6254879Ssam startad/size); 6264879Ssam obuff += size; 6274879Ssam startad += size; 6284879Ssam } 629954Sbill } 630954Sbill 631954Sbill rcmd() 632954Sbill { 633954Sbill register int i; 634954Sbill 635954Sbill rt_init(); 6364879Ssam if (namc > 0) 6374879Ssam for (i = 0; i < namc; i++) 6384879Ssam if (rtr(namv[i]) == 0) 6394879Ssam namv[i] = 0; 640954Sbill } 641954Sbill 642954Sbill rtr(name) 6434879Ssam char *name; 644954Sbill { 6454879Ssam register FLDOPE *dope; 6464879Ssam register struct rt_ent *de; 6474879Ssam struct stat buf; 6484879Ssam register struct stat *bufp = &buf; 6493346Swnj int segnum; 6503346Swnj register char *last; 651954Sbill 6524879Ssam if (stat(name, bufp) < 0) { 6533489Sroot perror(name); 654*9877Ssam return (-1); 6553489Sroot } 6564879Ssam if (dope = lookup(name)) { 657954Sbill /* can replace, no problem */ 658954Sbill de = dope->rtdope; 6594879Ssam if (bufp->st_size <= (de->rt_len * 512)) 660954Sbill printf("r - %s\n",name), 6614879Ssam toflop(name, bufp->st_size, dope); 662954Sbill else { 663*9877Ssam fprintf(stderr, 664*9877Ssam "%s will not fit in currently used file on floppy\n", 665*9877Ssam name); 666*9877Ssam return (-1); 667954Sbill } 668*9877Ssam goto found; 669*9877Ssam } 670*9877Ssam /* 671*9877Ssam * Search for vacant spot 672*9877Ssam */ 673*9877Ssam for (segnum = 0; segnum != -1; 674*9877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 675*9877Ssam { 676*9877Ssam last = rt_last + segnum*2*RT_BLOCK; 677*9877Ssam for (de = rt_dir[segnum].rt_ents; 678*9877Ssam rt(de)->rt_stat != RT_ESEG; de++) 679*9877Ssam if ((de)->rt_stat == RT_NULL) { 680*9877Ssam if (bufp->st_size <= (de->rt_len*512)) { 681*9877Ssam printf("a - %s\n",name), 682*9877Ssam mkent(de, segnum, bufp,name); 683*9877Ssam goto found; 684954Sbill } 685*9877Ssam continue; 686*9877Ssam } 687954Sbill } 688*9877Ssam printf("%s: no slot for file\n", name); 689*9877Ssam return (-1); 6904879Ssam 6914879Ssam found: 6924879Ssam if (dope = lookup(name)) { 6934879Ssam toflop(name, bufp->st_size, dope); 6943489Sroot return (0); 695954Sbill } 6963489Sroot printf("%s: internal error, added then not found\n", name); 6973489Sroot return (-1); 6984879Ssam } 699954Sbill 7004879Ssam mkent(de, segnum, bufp, name) 7014879Ssam register struct rt_ent *de; 7024879Ssam int segnum; 7034879Ssam register struct stat *bufp; 7044879Ssam char *name; 705954Sbill { 7064879Ssam struct tm *localtime(); 7074879Ssam register struct tm *timp; 7084879Ssam register struct rt_ent *workp; 7094879Ssam int count; 710954Sbill 711954Sbill count = (((bufp->st_size -1) >>9) + 1); 7124879Ssam /* make sure there is room */ 7134879Ssam if (de->rt_len == count) 714954Sbill goto overwrite; 7154879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7164879Ssam /* no entries left on segment */ 7174879Ssam if (flag(o)) 718954Sbill goto overwrite; 719*9877Ssam fprintf(stderr, "Directory segment #%d full on %s\n", 720*9877Ssam segnum+1, defdev); 721954Sbill exit(1); 722954Sbill } 7234879Ssam /* copy directory entries up */ 7244879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 725954Sbill *workp = workp[-1]; 726954Sbill de[1].rt_len -= count; 727954Sbill de->rt_len = count; 7283346Swnj rt_curend[segnum]++; 729954Sbill rt_nleft--; 7304879Ssam 731954Sbill overwrite: 732954Sbill srad50(name,de->rt_name); 733954Sbill timp = localtime(&bufp->st_mtime); 7347320Swnj de->rt_date.rt_dy = timp->tm_mday; 735954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 736954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 737954Sbill de->rt_stat = RT_FILE; 738954Sbill de->rt_pad = 0; 739954Sbill de->rt_chan = 0; 740954Sbill de->rt_job = 0; 7414879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 742954Sbill } 743954Sbill 7444879Ssam toflop(name, ocount, dope) 7454879Ssam char *name; 7464879Ssam register FLDOPE *dope; 7474879Ssam long ocount; 748954Sbill { 749954Sbill register file, n, startad = dope->startad, count = ocount; 750954Sbill char buff[512]; 751954Sbill 7524879Ssam file = open(name, 0); 7534879Ssam if (file < 0) { 7544879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7554879Ssam exit(1); 7564879Ssam } 757954Sbill for( ; count >= 512; count -= 512) { 7584879Ssam read(file, buff, 512); 7594879Ssam lwrite(startad, 512, buff); 760954Sbill startad += 512; 761954Sbill } 7624879Ssam read(file, buff, count); 763954Sbill close(file); 7644879Ssam if (count <= 0) 7654879Ssam return; 7664879Ssam for (n = count; n < 512; n ++) 7674879Ssam buff[n] = 0; 7684879Ssam lwrite(startad, 512, buff); 7694879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7704879Ssam if (count <= 0) 7714879Ssam return; 7724879Ssam for ( ; count > 0 ; count--) { 773954Sbill startad += 512; 7744879Ssam lwrite(startad, 512, zeroes); 775954Sbill } 7764879Ssam } 777954Sbill 778954Sbill dcmd() 779954Sbill { 780954Sbill register int i; 781954Sbill 782954Sbill rt_init(); 7834879Ssam if (namc) 7844879Ssam for (i = 0; i < namc; i++) 7854879Ssam if (rtk(namv[i])==0) 7864879Ssam namv[i]=0; 7874879Ssam if (dirdirty) 788954Sbill scrunch(); 789954Sbill } 7904879Ssam 791954Sbill rtk(name) 7924879Ssam char *name; 793954Sbill { 794954Sbill register FLDOPE *dope; 795954Sbill register struct rt_ent *de; 796954Sbill FLDOPE *lookup(); 797954Sbill 7984879Ssam if (dope = lookup(name)) { 799954Sbill printf("d - %s\n",name); 800954Sbill de = dope->rtdope; 801954Sbill de->rt_stat = RT_NULL; 802954Sbill de->rt_name[0] = 0; 803954Sbill de->rt_name[1] = 0; 804954Sbill de->rt_name[2] = 0; 805*9877Ssam *((u_short *)&(de->rt_date)) = 0; 806954Sbill dirdirty = 1; 807*9877Ssam return (0); 808954Sbill } 809*9877Ssam return (1); 810954Sbill } 8114879Ssam 8124879Ssam scrunch() 8134879Ssam { 8143346Swnj register struct rt_ent *de , *workp; 8153346Swnj register segnum; 8164879Ssam 8174879Ssam for (segnum = 0; segnum != -1; 8183346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8194879Ssam dirdirty = 0; 8204879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 821*9877Ssam if (de->rt_stat == RT_NULL && 822*9877Ssam de[1].rt_stat == RT_NULL) { 8234879Ssam (de+1)->rt_len += de->rt_len; 8244879Ssam for (workp = de; workp < rt_curend[segnum]; workp++) 8254879Ssam *workp = workp[1]; 8264879Ssam de--; 8274879Ssam rt_curend[segnum]--; 8284879Ssam rt_nleft++; 8294879Ssam dirdirty = 1; 8304879Ssam } 8314879Ssam if (dirdirty) 8324879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 8334879Ssam (char *)&rt_dir[segnum]); 834954Sbill } 835954Sbill } 836