19877Ssam #ifndef lint 2*15553Sralph static char sccsid[] = "@(#)arff.c 4.17 (Berkeley) 83/11/18"; 39877Ssam #endif 44879Ssam 5954Sbill #include <sys/types.h> 6954Sbill #include <sys/stat.h> 713605Ssam #include <sys/time.h> 8954Sbill #include <signal.h> 9954Sbill #include <stdio.h> 1013910Ssam #include <sys/file.h> 114879Ssam 12954Sbill #define dbprintf printf 134879Ssam 14954Sbill struct rt_dat { 154879Ssam u_short rt_yr:5; /* year-1972 */ 164879Ssam u_short rt_dy:5; /* day */ 174879Ssam u_short rt_mo:5; /* month */ 18954Sbill }; 194879Ssam 20954Sbill struct rt_axent { 21954Sbill char rt_sent[14]; 22954Sbill }; 23954Sbill 24954Sbill struct rt_ent { 254879Ssam char rt_pad; /* unusued */ 264879Ssam char rt_stat; /* type of entry, or end of seg */ 274879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 287319Swnj u_short rt_len; /* length of file */ 294879Ssam char rt_chan; /* only used in temporary files */ 304879Ssam char rt_job; /* only used in temporary files */ 319877Ssam struct rt_dat rt_date; /* creation date */ 32954Sbill }; 334879Ssam 344879Ssam #define RT_TEMP 1 354879Ssam #define RT_NULL 2 364879Ssam #define RT_FILE 4 374879Ssam #define RT_ESEG 8 384879Ssam 394879Ssam #define RT_BLOCK 512 /* block size */ 404879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 414879Ssam 42954Sbill struct rt_head { 434879Ssam short rt_numseg; /* # of segments available */ 444879Ssam short rt_nxtseg; /* # of next logical segment */ 454879Ssam short rt_lstseg; /* highest seg currently open */ 464879Ssam u_short rt_entpad; /* extra words/directory entry */ 474879Ssam short rt_stfile; /* block # where files begin */ 48954Sbill }; 494879Ssam 50954Sbill struct rt_dir { 51954Sbill struct rt_head rt_axhead; 52954Sbill struct rt_ent rt_ents[72]; 534879Ssam char _dirpad[6]; 54954Sbill }; 554879Ssam 56954Sbill typedef struct fldope { 57954Sbill int startad; 58954Sbill int count; 59954Sbill struct rt_ent *rtdope; 60954Sbill } FLDOPE; 614879Ssam 62954Sbill FLDOPE *lookup(); 634879Ssam 649877Ssam #define rt(p) ((struct rt_ent *) p ) 659877Ssam #define Ain1 03100 669877Ssam #define Ain2 050 679877Ssam #define flag(c) (flg[('c') - 'a']) 68954Sbill 699877Ssam char *man = "rxtd"; 709877Ssam char zeroes[512]; 71954Sbill 72954Sbill extern char *val; 73954Sbill extern char table[256]; 744879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 759877Ssam { 4, 0, 1, 0, 14 }, 769877Ssam { { 0, RT_NULL, { 0, 0, 0 }, 494, 0 }, 779877Ssam { 0, RT_ESEG } } 784879Ssam }; 79954Sbill 804879Ssam int rt_entsiz; 814879Ssam int rt_nleft; 824879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 834879Ssam int floppydes; 844879Ssam int dirdirty; 854879Ssam char *rt_last; 864879Ssam char *defdev = "/dev/floppy"; 87954Sbill 884879Ssam char *opt = "vf"; 894879Ssam 90954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 914879Ssam extern long lseek(); 924879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 934879Ssam 94954Sbill int (*comfun)(); 95954Sbill char flg[26]; 96954Sbill char **namv; 97954Sbill int namc; 98954Sbill int file; 99954Sbill 100954Sbill main(argc, argv) 1014879Ssam char *argv[]; 102954Sbill { 103954Sbill register char *cp; 104954Sbill 1054879Ssam if (argc < 2) 106954Sbill usage(); 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': 11713910Ssam flag(c)++; 1184879Ssam dirdirty++; 1194879Ssam continue; 120954Sbill 1214879Ssam case 'r': 1224879Ssam setcom(rcmd); 1234879Ssam flag(r)++; 1244879Ssam continue; 125954Sbill 1264879Ssam case 'd': 1274879Ssam setcom(dcmd); 1284879Ssam flag(d)++; 1294879Ssam continue; 130954Sbill 1314879Ssam case 'x': 1324879Ssam setcom(xcmd); 1334879Ssam continue; 134954Sbill 1354879Ssam case 't': 1364879Ssam setcom(tcmd); 1374879Ssam continue; 138954Sbill 1394879Ssam case 'f': 1404879Ssam defdev = argv[2]; 1414879Ssam argv++; 1424879Ssam argc--; 1434879Ssam continue; 1444879Ssam 1454879Ssam default: 1464879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1474879Ssam exit(1); 1484879Ssam } 1494879Ssam 150954Sbill namv = argv+2; 151954Sbill namc = argc-2; 1524879Ssam if (comfun == 0) { 1534879Ssam if (flag(u) == 0) { 1544879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1554879Ssam man); 156954Sbill exit(1); 157954Sbill } 158954Sbill setcom(rcmd); 159954Sbill } 160954Sbill (*comfun)(); 161954Sbill exit(notfound()); 162954Sbill } 163954Sbill 164954Sbill setcom(fun) 1654879Ssam int (*fun)(); 166954Sbill { 1674879Ssam if (comfun != 0) { 168954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 169954Sbill exit(1); 170954Sbill } 171954Sbill comfun = fun; 172954Sbill } 173954Sbill 174954Sbill usage() 175954Sbill { 1763356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 177954Sbill exit(1); 178954Sbill } 179954Sbill 180954Sbill notfound() 181954Sbill { 1824879Ssam register i, n = 0; 183954Sbill 1844879Ssam for (i = 0; i < namc; i++) 1854879Ssam if (namv[i]) { 186954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 187954Sbill n++; 188954Sbill } 1899877Ssam return (n); 190954Sbill } 191954Sbill 192954Sbill mesg(c) 193954Sbill { 1944879Ssam if (flag(v)) 1954879Ssam if (c != 'c' || flag(v) > 1) 196954Sbill printf("%c - %s\n", c, file); 197954Sbill } 198954Sbill 199954Sbill tcmd() 200954Sbill { 2014879Ssam register char *de, *last; 202954Sbill FLDOPE *lookup(), *dope; 2034879Ssam int segnum, nleft; 2044879Ssam register i; 205954Sbill register struct rt_ent *rde; 206954Sbill 207954Sbill rt_init(); 2089877Ssam if (namc != 0) { 2094879Ssam for (i = 0; i < namc; i++) 2104879Ssam if (dope = lookup(namv[i])) { 211954Sbill rde = dope->rtdope; 212954Sbill rtls(rde); 213954Sbill namv[i] = 0; 214954Sbill } 2159877Ssam return; 2169877Ssam } 2179877Ssam for (segnum = 0; segnum != -1; 2189877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 2199877Ssam last = rt_last + segnum*2*RT_BLOCK; 2209877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2219877Ssam de += rt_entsiz) 2229877Ssam if (rtls(rt(de))) { 2239877Ssam nleft = (last-de)/rt_entsiz; 2249877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2259877Ssam printf(ENTRIES, nleft, segnum+1); 2269877Ssam break; 2279877Ssam } 2289877Ssam } 229954Sbill } 2304879Ssam 231954Sbill rtls(de) 2324879Ssam register struct rt_ent *de; 233954Sbill { 2344879Ssam int month, day, year; 235954Sbill char name[12], ext[4]; 236954Sbill 2374879Ssam switch (de->rt_stat) { 2384879Ssam 2394879Ssam case RT_TEMP: 2404879Ssam if (flag(v)) 241954Sbill printf("Tempfile:\n"); 2424879Ssam /* fall thru...*/ 243954Sbill 2444879Ssam case RT_FILE: 2454879Ssam if (!flag(v)) { 2464879Ssam sunrad50(name, de->rt_name); 2474879Ssam printf("%s\n", name); 248954Sbill break; 249954Sbill } 2504879Ssam unrad50(2, de->rt_name, name); 2514879Ssam unrad50(1, &(de->rt_name[2]), ext); 2524879Ssam day = de->rt_date.rt_dy; 2534879Ssam year = de->rt_date.rt_yr+72; 2544879Ssam month = de->rt_date.rt_mo; 2554879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2564879Ssam ext, month, day, year, de->rt_len); 2574879Ssam break; 258954Sbill 2594879Ssam case RT_NULL: 2604879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2614879Ssam break; 262954Sbill 2634879Ssam case RT_ESEG: 2649877Ssam return (1); 265954Sbill } 2669877Ssam return (0); 267954Sbill } 2684879Ssam 269954Sbill xcmd() 270954Sbill { 2714879Ssam register char *de, *last; 2723346Swnj int segnum; 273954Sbill char name[12]; 274954Sbill register int i; 275954Sbill 276954Sbill rt_init(); 2779877Ssam if (namc != 0) { 2784879Ssam for (i = 0; i < namc; i++) 2794879Ssam if (rtx(namv[i]) == 0) 2804879Ssam namv[i] = 0; 2819877Ssam return; 2829877Ssam } 2839877Ssam for (segnum = 0; segnum != -1; 2849877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 2859877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 2869877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 287*15553Sralph de += rt_entsiz) { 2889877Ssam switch (rt(de)->rt_stat) { 2899877Ssam 2909877Ssam case RT_ESEG: 291*15553Sralph break; /* exit loop and try next segment */ 2929877Ssam 2939877Ssam case RT_TEMP: 2949877Ssam case RT_FILE: 2959877Ssam sunrad50(name,rt(de)->rt_name); 2969877Ssam rtx(name); 2979877Ssam 2989877Ssam case RT_NULL: 299*15553Sralph default: 300*15553Sralph continue; 3019877Ssam } 302*15553Sralph break; 303*15553Sralph } 304954Sbill } 3054879Ssam 306954Sbill rtx(name) 3074879Ssam char *name; 308954Sbill { 309954Sbill register FLDOPE *dope; 310954Sbill FLDOPE *lookup(); 311954Sbill register startad, count; 3124879Ssam int file; 3134879Ssam char buff[512]; 314954Sbill 315954Sbill 3164879Ssam if (dope = lookup(name)) { 3174879Ssam if (flag(v)) 318954Sbill rtls(dope->rtdope); 319954Sbill else 320954Sbill printf("x - %s\n",name); 321954Sbill 3224879Ssam if ((file = creat(name, 0666)) < 0) 3239877Ssam return (1); 324954Sbill count = dope->count; 325954Sbill startad = dope->startad; 326954Sbill for( ; count > 0 ; count -= 512) { 3274879Ssam lread(startad, 512, buff); 3284879Ssam write(file, buff, 512); 329954Sbill startad += 512; 330954Sbill } 331954Sbill close(file); 3329877Ssam return (0); 333954Sbill } 3349877Ssam return (1); 335954Sbill } 3364879Ssam 337954Sbill rt_init() 338954Sbill { 339954Sbill static initized = 0; 3404879Ssam register char *de, *last; 3413346Swnj register i; 3423799Shickman int dirnum; 3433799Shickman char *mode; 3443799Shickman FILE *temp_floppydes; 345954Sbill 3464879Ssam if (initized) 3474879Ssam return; 348954Sbill initized = 1; 34913910Ssam if (flag(c)) { 35013910Ssam struct stat sb; 35113910Ssam char response[128]; 35213910Ssam int tty; 35313910Ssam 35413910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 35513910Ssam goto ignore; 35613910Ssam tty = open("/dev/tty", O_RDWR); 35713910Ssam #define SURE "Are you sure you want to clobber the floppy? " 35813910Ssam write(tty, SURE, sizeof (SURE)); 35913910Ssam read(tty, response, sizeof (response)); 36013910Ssam if (*response != 'y') 36113910Ssam exit(50); 36213910Ssam close(tty); 36313910Ssam ignore: 36413910Ssam ; 36513910Ssam } 3664879Ssam if (flag(c) || flag(d) || flag(r)) 3673799Shickman mode = "r+"; 368954Sbill else 3693799Shickman mode = "r"; 3704879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3713799Shickman perror(defdev); 3723356Swnj exit(1); 3733799Shickman } else 3743799Shickman floppydes = fileno(temp_floppydes); 3754879Ssam if (!flag(c)) { 3764879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3773346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 37812012Shelge /* check for blank/uninitialized diskette */ 37912012Shelge if (dirnum <= 0) { 38012012Shelge fprintf(stderr,"arff: bad directory format\n"); 38112012Shelge exit(1); 38212012Shelge } 3833346Swnj if (dirnum > RT_DIRSIZE) { 3844879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3854879Ssam exit(1); 3863346Swnj } 3874879Ssam for (i = 1; i < dirnum; i++) 3884879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3893489Sroot } else 3903489Sroot dirnum = 1; 391954Sbill 3923346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3933346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3943346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3953346Swnj rt_nleft = 0; 3963346Swnj 3974879Ssam for (i = 0; i < dirnum; i++) { 3984879Ssam last = rt_last + i*2*RT_BLOCK; 3994879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 4004879Ssam if (rt(de)->rt_stat == RT_ESEG) 4014879Ssam break; 4024879Ssam rt_curend[i] = rt(de); 4034879Ssam rt_nleft += (last-de)/rt_entsiz; 404954Sbill } 405954Sbill } 406954Sbill 407954Sbill static FLDOPE result; 4084879Ssam 409954Sbill FLDOPE * 410954Sbill lookup(name) 4114879Ssam char *name; 412954Sbill { 413954Sbill unsigned short rname[3]; 4144879Ssam register char *de, *last; 4153346Swnj int segnum; 416954Sbill register index; 417954Sbill 418954Sbill srad50(name,rname); 419954Sbill 4203356Swnj /* 421954Sbill * Search for name, accumulate blocks in index 422954Sbill */ 423954Sbill rt_init(); 4244879Ssam for (segnum = 0; segnum != -1; 4254879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4264879Ssam { 4274879Ssam index = 0; 4284879Ssam last = rt_last + segnum*2*RT_BLOCK; 4294879Ssam for (de=((char *)&rt_dir[segnum])+10; 4304879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4314879Ssam switch(rt(de)->rt_stat) { 4324879Ssam 4334879Ssam case RT_FILE: 4344879Ssam case RT_TEMP: 4354879Ssam if(samename(rname,rt(de)->rt_name)) { 4364879Ssam result.count = rt(de)->rt_len * 512; 4374879Ssam result.startad = 512* 4384879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4394879Ssam result.rtdope = (struct rt_ent *) de; 4409877Ssam return (&result); 4414879Ssam } 4424879Ssam 4434879Ssam case RT_NULL: 4444879Ssam index += rt(de)->rt_len; 4454879Ssam } 4463346Swnj } 4479877Ssam return ((FLDOPE *) 0); 4484879Ssam 449954Sbill } 4504879Ssam 451954Sbill static 4524879Ssam samename(a, b) 4534879Ssam u_short a[], b[]; 454954Sbill { 4559877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 456954Sbill } 457954Sbill 4584879Ssam rad50(cp, out) 4594879Ssam register u_char *cp; 4604879Ssam u_short *out; 461954Sbill { 4624879Ssam register index, temp; 463954Sbill 4644879Ssam for (index = 0; *cp; index++) { 465954Sbill temp = Ain1 * table[*cp++]; 4664879Ssam if (*cp!=0) { 467954Sbill temp += Ain2 * table[*cp++]; 468954Sbill if(*cp!=0) 469954Sbill temp += table[*cp++]; 470954Sbill } 471954Sbill out[index] = temp; 472954Sbill } 473954Sbill } 474954Sbill 4754879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4764879Ssam 4774879Ssam unrad50(count, in, cp) 4784879Ssam u_short *in; 4794879Ssam register char *cp; 480954Sbill { 4814879Ssam register i, temp; 4824879Ssam register u_char *v = (u_char *) val; 483954Sbill 4844879Ssam for (i = 0; i < count; i++) { 485954Sbill temp = in[i]; 4864879Ssam reduce(*cp++, temp, Ain1); 4874879Ssam reduce(*cp++, temp, Ain2); 4884879Ssam reduce(*cp++, temp, 1); 489954Sbill } 490954Sbill *cp=0; 491954Sbill } 492954Sbill 4934879Ssam srad50(name, rname) 4944879Ssam register char *name; 4954879Ssam register u_short *rname; 496954Sbill { 4974879Ssam register index; 4984879Ssam register char *cp; 4994879Ssam char file[7], ext[4]; 5004879Ssam 5013356Swnj /* 502954Sbill * Find end of pathname 503954Sbill */ 5044879Ssam for (cp = name; *cp++; ) 5054879Ssam ; 5064879Ssam while (cp >= name && *--cp != '/') 5074879Ssam ; 508954Sbill cp++; 5093356Swnj /* 510954Sbill * Change to rad50 511954Sbill */ 5124879Ssam for (index = 0; *cp; ) { 513954Sbill file[index++] = *cp++; 5144879Ssam if (*cp == '.') { 515954Sbill cp++; 516954Sbill break; 517954Sbill } 5184879Ssam if (index >= 6) { 519954Sbill break; 520954Sbill } 521954Sbill } 522954Sbill file[index] = 0; 5234879Ssam for (index = 0; *cp; ) { 524954Sbill ext[index++] = *cp++; 5254879Ssam if (*cp == '.' || index >= 3) 526954Sbill break; 527954Sbill } 528954Sbill ext[index]=0; 5294879Ssam rname[0] = rname[1] = rname[2] = 0; 5304879Ssam rad50((u_char *)file, rname); 5314879Ssam rad50((u_char *)ext, rname+2); 532954Sbill } 5334879Ssam 5344879Ssam sunrad50(name, rname) 5354879Ssam u_short rname[]; 5364879Ssam register char *name; 537954Sbill { 538954Sbill register char *cp, *cp2; 539954Sbill char ext[4]; 540954Sbill 5414879Ssam unrad50(2, rname, name); 5424879Ssam unrad50(1, rname + 2, ext); 5434879Ssam /* 5444879Ssam * Jam name and extension together with a dot 5454879Ssam * deleting white space 5464879Ssam */ 5474879Ssam for (cp = name; *cp++;) 5484879Ssam ; 5494879Ssam --cp; 5504879Ssam while (*--cp == ' ' && cp >= name) 5514879Ssam ; 5524879Ssam *++cp = '.'; 5534879Ssam cp++; 5544879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 555954Sbill *cp++ = *cp2++; 556954Sbill *cp=0; 5574879Ssam if (cp[-1] == '.') 5584879Ssam cp[-1] = 0; 559954Sbill } 560954Sbill 561954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 562954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5634879Ssam 564954Sbill static char table[256] = { 565954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 566954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 567954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 568954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 569954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 570954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 571954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 572954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 573954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 574954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 575954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 576954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 577954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 578954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 579954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 580954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 581954Sbill 5824879Ssam /* 5834879Ssam * Logical to physical adress translation 5844879Ssam */ 5854879Ssam long 5864879Ssam trans(logical) 5874879Ssam register int logical; 588954Sbill { 589954Sbill register int sector, bytes, track; 590954Sbill 5914879Ssam logical += 26*128; 5924879Ssam bytes = (logical&127); 593954Sbill logical >>= 7; 5944879Ssam sector = logical%26; 595954Sbill if(sector >= 13) 5964879Ssam sector = sector*2+1; 597954Sbill else 598954Sbill sector *= 2; 5994879Ssam sector += 26 + ((track = (logical/26))-1)*6; 600954Sbill sector %= 26; 6019877Ssam return ((((track*26)+sector) << 7) + bytes); 602954Sbill } 6034879Ssam 6044879Ssam lread(startad, count, obuff) 6054879Ssam register startad, count; 6064879Ssam register char *obuff; 607954Sbill { 608954Sbill long trans(); 609954Sbill extern floppydes; 6104879Ssam register int size = flag(m) ? 512 : 128; 6114879Ssam 612954Sbill rt_init(); 6134879Ssam while ((count -= size) >= 0) { 6144879Ssam lseek(floppydes, flag(m) ? 6154879Ssam (long)startad : trans(startad), 0); 6164879Ssam if (read(floppydes, obuff, size) != size) 6174879Ssam fprintf(stderr, "arff: read error block %d\n", 6184879Ssam startad/size); 6194879Ssam obuff += size; 6204879Ssam startad += size; 6214879Ssam } 622954Sbill } 6234879Ssam 6244879Ssam lwrite(startad, count, obuff) 6254879Ssam register startad, count; 6264879Ssam register char *obuff; 627954Sbill { 628954Sbill long trans(); 629954Sbill extern floppydes; 6304879Ssam register int size = flag(m) ? 512 : 128; 6314879Ssam 632954Sbill rt_init(); 6334879Ssam while ((count -= size) >= 0) { 6344879Ssam lseek(floppydes, flag(m) ? 6354879Ssam (long)startad : trans(startad), 0); 6364879Ssam if (write(floppydes, obuff, size) != size) 6374879Ssam fprintf(stderr, "arff: write error block %d\n", 6384879Ssam startad/size); 6394879Ssam obuff += size; 6404879Ssam startad += size; 6414879Ssam } 642954Sbill } 643954Sbill 644954Sbill rcmd() 645954Sbill { 646954Sbill register int i; 647954Sbill 648954Sbill rt_init(); 6494879Ssam if (namc > 0) 6504879Ssam for (i = 0; i < namc; i++) 6514879Ssam if (rtr(namv[i]) == 0) 6524879Ssam namv[i] = 0; 653954Sbill } 654954Sbill 655954Sbill rtr(name) 6564879Ssam char *name; 657954Sbill { 6584879Ssam register FLDOPE *dope; 6594879Ssam register struct rt_ent *de; 6604879Ssam struct stat buf; 6614879Ssam register struct stat *bufp = &buf; 6623346Swnj int segnum; 6633346Swnj register char *last; 664954Sbill 6654879Ssam if (stat(name, bufp) < 0) { 6663489Sroot perror(name); 6679877Ssam return (-1); 6683489Sroot } 6694879Ssam if (dope = lookup(name)) { 670954Sbill /* can replace, no problem */ 671954Sbill de = dope->rtdope; 6724879Ssam if (bufp->st_size <= (de->rt_len * 512)) 673954Sbill printf("r - %s\n",name), 6744879Ssam toflop(name, bufp->st_size, dope); 675954Sbill else { 6769877Ssam fprintf(stderr, 6779877Ssam "%s will not fit in currently used file on floppy\n", 6789877Ssam name); 6799877Ssam return (-1); 680954Sbill } 6819877Ssam goto found; 6829877Ssam } 6839877Ssam /* 6849877Ssam * Search for vacant spot 6859877Ssam */ 6869877Ssam for (segnum = 0; segnum != -1; 6879877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 6889877Ssam { 6899877Ssam last = rt_last + segnum*2*RT_BLOCK; 6909877Ssam for (de = rt_dir[segnum].rt_ents; 6919877Ssam rt(de)->rt_stat != RT_ESEG; de++) 6929877Ssam if ((de)->rt_stat == RT_NULL) { 6939877Ssam if (bufp->st_size <= (de->rt_len*512)) { 6949877Ssam printf("a - %s\n",name), 6959877Ssam mkent(de, segnum, bufp,name); 6969877Ssam goto found; 697954Sbill } 6989877Ssam continue; 6999877Ssam } 700954Sbill } 7019877Ssam printf("%s: no slot for file\n", name); 7029877Ssam return (-1); 7034879Ssam 7044879Ssam found: 7054879Ssam if (dope = lookup(name)) { 7064879Ssam toflop(name, bufp->st_size, dope); 7073489Sroot return (0); 708954Sbill } 7093489Sroot printf("%s: internal error, added then not found\n", name); 7103489Sroot return (-1); 7114879Ssam } 712954Sbill 7134879Ssam mkent(de, segnum, bufp, name) 7144879Ssam register struct rt_ent *de; 7154879Ssam int segnum; 7164879Ssam register struct stat *bufp; 7174879Ssam char *name; 718954Sbill { 7194879Ssam struct tm *localtime(); 7204879Ssam register struct tm *timp; 7214879Ssam register struct rt_ent *workp; 7224879Ssam int count; 723954Sbill 724954Sbill count = (((bufp->st_size -1) >>9) + 1); 7254879Ssam /* make sure there is room */ 7264879Ssam if (de->rt_len == count) 727954Sbill goto overwrite; 7284879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7294879Ssam /* no entries left on segment */ 7304879Ssam if (flag(o)) 731954Sbill goto overwrite; 7329877Ssam fprintf(stderr, "Directory segment #%d full on %s\n", 7339877Ssam segnum+1, defdev); 734954Sbill exit(1); 735954Sbill } 7364879Ssam /* copy directory entries up */ 7374879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 738954Sbill *workp = workp[-1]; 739954Sbill de[1].rt_len -= count; 740954Sbill de->rt_len = count; 7413346Swnj rt_curend[segnum]++; 742954Sbill rt_nleft--; 7434879Ssam 744954Sbill overwrite: 745954Sbill srad50(name,de->rt_name); 746954Sbill timp = localtime(&bufp->st_mtime); 7477320Swnj de->rt_date.rt_dy = timp->tm_mday; 748954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 749954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 750954Sbill de->rt_stat = RT_FILE; 751954Sbill de->rt_pad = 0; 752954Sbill de->rt_chan = 0; 753954Sbill de->rt_job = 0; 7544879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 755954Sbill } 756954Sbill 7574879Ssam toflop(name, ocount, dope) 7584879Ssam char *name; 7594879Ssam register FLDOPE *dope; 7604879Ssam long ocount; 761954Sbill { 762954Sbill register file, n, startad = dope->startad, count = ocount; 763954Sbill char buff[512]; 764954Sbill 7654879Ssam file = open(name, 0); 7664879Ssam if (file < 0) { 7674879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7684879Ssam exit(1); 7694879Ssam } 770954Sbill for( ; count >= 512; count -= 512) { 7714879Ssam read(file, buff, 512); 7724879Ssam lwrite(startad, 512, buff); 773954Sbill startad += 512; 774954Sbill } 7754879Ssam read(file, buff, count); 776954Sbill close(file); 7774879Ssam if (count <= 0) 7784879Ssam return; 7794879Ssam for (n = count; n < 512; n ++) 7804879Ssam buff[n] = 0; 7814879Ssam lwrite(startad, 512, buff); 7824879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7834879Ssam if (count <= 0) 7844879Ssam return; 7854879Ssam for ( ; count > 0 ; count--) { 786954Sbill startad += 512; 7874879Ssam lwrite(startad, 512, zeroes); 788954Sbill } 7894879Ssam } 790954Sbill 791954Sbill dcmd() 792954Sbill { 793954Sbill register int i; 794954Sbill 795954Sbill rt_init(); 7964879Ssam if (namc) 7974879Ssam for (i = 0; i < namc; i++) 7984879Ssam if (rtk(namv[i])==0) 7994879Ssam namv[i]=0; 8004879Ssam if (dirdirty) 801954Sbill scrunch(); 802954Sbill } 8034879Ssam 804954Sbill rtk(name) 8054879Ssam char *name; 806954Sbill { 807954Sbill register FLDOPE *dope; 808954Sbill register struct rt_ent *de; 809954Sbill FLDOPE *lookup(); 810954Sbill 8114879Ssam if (dope = lookup(name)) { 812954Sbill printf("d - %s\n",name); 813954Sbill de = dope->rtdope; 814954Sbill de->rt_stat = RT_NULL; 815954Sbill de->rt_name[0] = 0; 816954Sbill de->rt_name[1] = 0; 817954Sbill de->rt_name[2] = 0; 8189877Ssam *((u_short *)&(de->rt_date)) = 0; 819954Sbill dirdirty = 1; 8209877Ssam return (0); 821954Sbill } 8229877Ssam return (1); 823954Sbill } 8244879Ssam 8254879Ssam scrunch() 8264879Ssam { 8273346Swnj register struct rt_ent *de , *workp; 8283346Swnj register segnum; 8294879Ssam 8304879Ssam for (segnum = 0; segnum != -1; 8313346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8324879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 8339877Ssam if (de->rt_stat == RT_NULL && 83412012Shelge (de+1)->rt_stat == RT_NULL) { 8354879Ssam (de+1)->rt_len += de->rt_len; 83612012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 8374879Ssam *workp = workp[1]; 8384879Ssam de--; 8394879Ssam rt_curend[segnum]--; 8404879Ssam rt_nleft++; 8414879Ssam } 84212012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 84312012Shelge (char *)&rt_dir[segnum]); 844954Sbill } 84512012Shelge dirdirty = 0; 846954Sbill } 847