19877Ssam #ifndef lint 2*13605Ssam static char sccsid[] = "@(#)arff.c 4.15 (Berkeley) 83/07/02"; 39877Ssam #endif 44879Ssam 5954Sbill #include <sys/types.h> 6954Sbill #include <sys/stat.h> 7*13605Ssam #include <sys/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 */ 309877Ssam 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 639877Ssam #define rt(p) ((struct rt_ent *) p ) 649877Ssam #define Ain1 03100 659877Ssam #define Ain2 050 669877Ssam #define flag(c) (flg[('c') - 'a']) 67954Sbill 689877Ssam char *man = "rxtd"; 699877Ssam char zeroes[512]; 70954Sbill 71954Sbill extern char *val; 72954Sbill extern char table[256]; 734879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 749877Ssam { 4, 0, 1, 0, 14 }, 759877Ssam { { 0, RT_NULL, { 0, 0, 0 }, 494, 0 }, 769877Ssam { 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(); 1064879Ssam for (cp = argv[1]; *cp; cp++) 1074879Ssam switch (*cp) { 108954Sbill 1094879Ssam case 'm': 1104879Ssam case 'v': 1114879Ssam case 'u': 1124879Ssam case 'w': 1134879Ssam flg[*cp-'a']++; 1144879Ssam continue; 1154879Ssam case 'c': 1164879Ssam { 11712934Smckusick #define SURE "Are you sure you want to clobber the floppy?" 1184879Ssam int tty; 1194879Ssam char response[128]; 120954Sbill 1214879Ssam tty = open("/dev/tty", 2); 1224879Ssam write(tty, SURE, sizeof(SURE)); 1234879Ssam read(tty, response, sizeof(response)); 1244879Ssam if (*response != 'y') 1254879Ssam exit(50); 1264879Ssam flag(c)++; 1274879Ssam close(tty); 1284879Ssam } 1294879Ssam dirdirty++; 1304879Ssam continue; 131954Sbill 1324879Ssam case 'r': 1334879Ssam setcom(rcmd); 1344879Ssam flag(r)++; 1354879Ssam continue; 136954Sbill 1374879Ssam case 'd': 1384879Ssam setcom(dcmd); 1394879Ssam flag(d)++; 1404879Ssam continue; 141954Sbill 1424879Ssam case 'x': 1434879Ssam setcom(xcmd); 1444879Ssam continue; 145954Sbill 1464879Ssam case 't': 1474879Ssam setcom(tcmd); 1484879Ssam continue; 149954Sbill 1504879Ssam case 'f': 1514879Ssam defdev = argv[2]; 1524879Ssam argv++; 1534879Ssam argc--; 1544879Ssam continue; 1554879Ssam 1564879Ssam default: 1574879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1584879Ssam exit(1); 1594879Ssam } 1604879Ssam 161954Sbill namv = argv+2; 162954Sbill namc = argc-2; 1634879Ssam if (comfun == 0) { 1644879Ssam if (flag(u) == 0) { 1654879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1664879Ssam man); 167954Sbill exit(1); 168954Sbill } 169954Sbill setcom(rcmd); 170954Sbill } 171954Sbill (*comfun)(); 172954Sbill exit(notfound()); 173954Sbill } 174954Sbill 175954Sbill setcom(fun) 1764879Ssam int (*fun)(); 177954Sbill { 1784879Ssam if (comfun != 0) { 179954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 180954Sbill exit(1); 181954Sbill } 182954Sbill comfun = fun; 183954Sbill } 184954Sbill 185954Sbill usage() 186954Sbill { 1873356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 188954Sbill exit(1); 189954Sbill } 190954Sbill 191954Sbill notfound() 192954Sbill { 1934879Ssam register i, n = 0; 194954Sbill 1954879Ssam for (i = 0; i < namc; i++) 1964879Ssam if (namv[i]) { 197954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 198954Sbill n++; 199954Sbill } 2009877Ssam return (n); 201954Sbill } 202954Sbill 203954Sbill mesg(c) 204954Sbill { 2054879Ssam if (flag(v)) 2064879Ssam if (c != 'c' || flag(v) > 1) 207954Sbill printf("%c - %s\n", c, file); 208954Sbill } 209954Sbill 210954Sbill tcmd() 211954Sbill { 2124879Ssam register char *de, *last; 213954Sbill FLDOPE *lookup(), *dope; 2144879Ssam int segnum, nleft; 2154879Ssam register i; 216954Sbill register struct rt_ent *rde; 217954Sbill 218954Sbill rt_init(); 2199877Ssam if (namc != 0) { 2204879Ssam for (i = 0; i < namc; i++) 2214879Ssam if (dope = lookup(namv[i])) { 222954Sbill rde = dope->rtdope; 223954Sbill rtls(rde); 224954Sbill namv[i] = 0; 225954Sbill } 2269877Ssam return; 2279877Ssam } 2289877Ssam for (segnum = 0; segnum != -1; 2299877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 2309877Ssam last = rt_last + segnum*2*RT_BLOCK; 2319877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2329877Ssam de += rt_entsiz) 2339877Ssam if (rtls(rt(de))) { 2349877Ssam nleft = (last-de)/rt_entsiz; 2359877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2369877Ssam printf(ENTRIES, nleft, segnum+1); 2379877Ssam break; 2389877Ssam } 2399877Ssam } 240954Sbill } 2414879Ssam 242954Sbill rtls(de) 2434879Ssam register struct rt_ent *de; 244954Sbill { 2454879Ssam int month, day, year; 246954Sbill char name[12], ext[4]; 247954Sbill 2484879Ssam switch (de->rt_stat) { 2494879Ssam 2504879Ssam case RT_TEMP: 2514879Ssam if (flag(v)) 252954Sbill printf("Tempfile:\n"); 2534879Ssam /* fall thru...*/ 254954Sbill 2554879Ssam case RT_FILE: 2564879Ssam if (!flag(v)) { 2574879Ssam sunrad50(name, de->rt_name); 2584879Ssam printf("%s\n", name); 259954Sbill break; 260954Sbill } 2614879Ssam unrad50(2, de->rt_name, name); 2624879Ssam unrad50(1, &(de->rt_name[2]), ext); 2634879Ssam day = de->rt_date.rt_dy; 2644879Ssam year = de->rt_date.rt_yr+72; 2654879Ssam month = de->rt_date.rt_mo; 2664879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2674879Ssam ext, month, day, year, de->rt_len); 2684879Ssam break; 269954Sbill 2704879Ssam case RT_NULL: 2714879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2724879Ssam break; 273954Sbill 2744879Ssam case RT_ESEG: 2759877Ssam return (1); 276954Sbill } 2779877Ssam return (0); 278954Sbill } 2794879Ssam 280954Sbill xcmd() 281954Sbill { 2824879Ssam register char *de, *last; 2833346Swnj int segnum; 284954Sbill char name[12]; 285954Sbill register int i; 286954Sbill 287954Sbill rt_init(); 2889877Ssam if (namc != 0) { 2894879Ssam for (i = 0; i < namc; i++) 2904879Ssam if (rtx(namv[i]) == 0) 2914879Ssam namv[i] = 0; 2929877Ssam return; 2939877Ssam } 2949877Ssam for (segnum = 0; segnum != -1; 2959877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 2969877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 2979877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 2989877Ssam de += rt_entsiz) 2999877Ssam switch (rt(de)->rt_stat) { 3009877Ssam 3019877Ssam case RT_ESEG: 3029877Ssam return; 3039877Ssam 3049877Ssam case RT_TEMP: 3059877Ssam case RT_FILE: 3069877Ssam sunrad50(name,rt(de)->rt_name); 3079877Ssam rtx(name); 3089877Ssam 3099877Ssam case RT_NULL: 3109877Ssam break; 3119877Ssam } 312954Sbill } 3134879Ssam 314954Sbill rtx(name) 3154879Ssam char *name; 316954Sbill { 317954Sbill register FLDOPE *dope; 318954Sbill FLDOPE *lookup(); 319954Sbill register startad, count; 3204879Ssam int file; 3214879Ssam char buff[512]; 322954Sbill 323954Sbill 3244879Ssam if (dope = lookup(name)) { 3254879Ssam if (flag(v)) 326954Sbill rtls(dope->rtdope); 327954Sbill else 328954Sbill printf("x - %s\n",name); 329954Sbill 3304879Ssam if ((file = creat(name, 0666)) < 0) 3319877Ssam return (1); 332954Sbill count = dope->count; 333954Sbill startad = dope->startad; 334954Sbill for( ; count > 0 ; count -= 512) { 3354879Ssam lread(startad, 512, buff); 3364879Ssam write(file, buff, 512); 337954Sbill startad += 512; 338954Sbill } 339954Sbill close(file); 3409877Ssam return (0); 341954Sbill } 3429877Ssam return (1); 343954Sbill } 3444879Ssam 345954Sbill rt_init() 346954Sbill { 347954Sbill static initized = 0; 3484879Ssam register char *de, *last; 3493346Swnj register i; 3503799Shickman int dirnum; 3513799Shickman char *mode; 3523799Shickman FILE *temp_floppydes; 353954Sbill 3544879Ssam if (initized) 3554879Ssam return; 356954Sbill initized = 1; 3574879Ssam if (flag(c) || flag(d) || flag(r)) 3583799Shickman mode = "r+"; 359954Sbill else 3603799Shickman mode = "r"; 3614879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3623799Shickman perror(defdev); 3633356Swnj exit(1); 3643799Shickman } else 3653799Shickman floppydes = fileno(temp_floppydes); 3664879Ssam if (!flag(c)) { 3674879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3683346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 36912012Shelge /* check for blank/uninitialized diskette */ 37012012Shelge if (dirnum <= 0) { 37112012Shelge fprintf(stderr,"arff: bad directory format\n"); 37212012Shelge exit(1); 37312012Shelge } 3743346Swnj if (dirnum > RT_DIRSIZE) { 3754879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3764879Ssam exit(1); 3773346Swnj } 3784879Ssam for (i = 1; i < dirnum; i++) 3794879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3803489Sroot } else 3813489Sroot dirnum = 1; 382954Sbill 3833346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3843346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3853346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3863346Swnj rt_nleft = 0; 3873346Swnj 3884879Ssam for (i = 0; i < dirnum; i++) { 3894879Ssam last = rt_last + i*2*RT_BLOCK; 3904879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 3914879Ssam if (rt(de)->rt_stat == RT_ESEG) 3924879Ssam break; 3934879Ssam rt_curend[i] = rt(de); 3944879Ssam rt_nleft += (last-de)/rt_entsiz; 395954Sbill } 396954Sbill } 397954Sbill 398954Sbill static FLDOPE result; 3994879Ssam 400954Sbill FLDOPE * 401954Sbill lookup(name) 4024879Ssam char *name; 403954Sbill { 404954Sbill unsigned short rname[3]; 4054879Ssam register char *de, *last; 4063346Swnj int segnum; 407954Sbill register index; 408954Sbill 409954Sbill srad50(name,rname); 410954Sbill 4113356Swnj /* 412954Sbill * Search for name, accumulate blocks in index 413954Sbill */ 414954Sbill rt_init(); 4154879Ssam for (segnum = 0; segnum != -1; 4164879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4174879Ssam { 4184879Ssam index = 0; 4194879Ssam last = rt_last + segnum*2*RT_BLOCK; 4204879Ssam for (de=((char *)&rt_dir[segnum])+10; 4214879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4224879Ssam switch(rt(de)->rt_stat) { 4234879Ssam 4244879Ssam case RT_FILE: 4254879Ssam case RT_TEMP: 4264879Ssam if(samename(rname,rt(de)->rt_name)) { 4274879Ssam result.count = rt(de)->rt_len * 512; 4284879Ssam result.startad = 512* 4294879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4304879Ssam result.rtdope = (struct rt_ent *) de; 4319877Ssam return (&result); 4324879Ssam } 4334879Ssam 4344879Ssam case RT_NULL: 4354879Ssam index += rt(de)->rt_len; 4364879Ssam } 4373346Swnj } 4389877Ssam return ((FLDOPE *) 0); 4394879Ssam 440954Sbill } 4414879Ssam 442954Sbill static 4434879Ssam samename(a, b) 4444879Ssam u_short a[], b[]; 445954Sbill { 4469877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 447954Sbill } 448954Sbill 4494879Ssam rad50(cp, out) 4504879Ssam register u_char *cp; 4514879Ssam u_short *out; 452954Sbill { 4534879Ssam register index, temp; 454954Sbill 4554879Ssam for (index = 0; *cp; index++) { 456954Sbill temp = Ain1 * table[*cp++]; 4574879Ssam if (*cp!=0) { 458954Sbill temp += Ain2 * table[*cp++]; 459954Sbill if(*cp!=0) 460954Sbill temp += table[*cp++]; 461954Sbill } 462954Sbill out[index] = temp; 463954Sbill } 464954Sbill } 465954Sbill 4664879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4674879Ssam 4684879Ssam unrad50(count, in, cp) 4694879Ssam u_short *in; 4704879Ssam register char *cp; 471954Sbill { 4724879Ssam register i, temp; 4734879Ssam register u_char *v = (u_char *) val; 474954Sbill 4754879Ssam for (i = 0; i < count; i++) { 476954Sbill temp = in[i]; 4774879Ssam reduce(*cp++, temp, Ain1); 4784879Ssam reduce(*cp++, temp, Ain2); 4794879Ssam reduce(*cp++, temp, 1); 480954Sbill } 481954Sbill *cp=0; 482954Sbill } 483954Sbill 4844879Ssam srad50(name, rname) 4854879Ssam register char *name; 4864879Ssam register u_short *rname; 487954Sbill { 4884879Ssam register index; 4894879Ssam register char *cp; 4904879Ssam char file[7], ext[4]; 4914879Ssam 4923356Swnj /* 493954Sbill * Find end of pathname 494954Sbill */ 4954879Ssam for (cp = name; *cp++; ) 4964879Ssam ; 4974879Ssam while (cp >= name && *--cp != '/') 4984879Ssam ; 499954Sbill cp++; 5003356Swnj /* 501954Sbill * Change to rad50 502954Sbill */ 5034879Ssam for (index = 0; *cp; ) { 504954Sbill file[index++] = *cp++; 5054879Ssam if (*cp == '.') { 506954Sbill cp++; 507954Sbill break; 508954Sbill } 5094879Ssam if (index >= 6) { 510954Sbill break; 511954Sbill } 512954Sbill } 513954Sbill file[index] = 0; 5144879Ssam for (index = 0; *cp; ) { 515954Sbill ext[index++] = *cp++; 5164879Ssam if (*cp == '.' || index >= 3) 517954Sbill break; 518954Sbill } 519954Sbill ext[index]=0; 5204879Ssam rname[0] = rname[1] = rname[2] = 0; 5214879Ssam rad50((u_char *)file, rname); 5224879Ssam rad50((u_char *)ext, rname+2); 523954Sbill } 5244879Ssam 5254879Ssam sunrad50(name, rname) 5264879Ssam u_short rname[]; 5274879Ssam register char *name; 528954Sbill { 529954Sbill register char *cp, *cp2; 530954Sbill char ext[4]; 531954Sbill 5324879Ssam unrad50(2, rname, name); 5334879Ssam unrad50(1, rname + 2, ext); 5344879Ssam /* 5354879Ssam * Jam name and extension together with a dot 5364879Ssam * deleting white space 5374879Ssam */ 5384879Ssam for (cp = name; *cp++;) 5394879Ssam ; 5404879Ssam --cp; 5414879Ssam while (*--cp == ' ' && cp >= name) 5424879Ssam ; 5434879Ssam *++cp = '.'; 5444879Ssam cp++; 5454879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 546954Sbill *cp++ = *cp2++; 547954Sbill *cp=0; 5484879Ssam if (cp[-1] == '.') 5494879Ssam cp[-1] = 0; 550954Sbill } 551954Sbill 552954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 553954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5544879Ssam 555954Sbill static char table[256] = { 556954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 557954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 558954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 559954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 560954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 561954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 562954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 563954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 564954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 565954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 566954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 567954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 568954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 569954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 570954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 571954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 572954Sbill 5734879Ssam /* 5744879Ssam * Logical to physical adress translation 5754879Ssam */ 5764879Ssam long 5774879Ssam trans(logical) 5784879Ssam register int logical; 579954Sbill { 580954Sbill register int sector, bytes, track; 581954Sbill 5824879Ssam logical += 26*128; 5834879Ssam bytes = (logical&127); 584954Sbill logical >>= 7; 5854879Ssam sector = logical%26; 586954Sbill if(sector >= 13) 5874879Ssam sector = sector*2+1; 588954Sbill else 589954Sbill sector *= 2; 5904879Ssam sector += 26 + ((track = (logical/26))-1)*6; 591954Sbill sector %= 26; 5929877Ssam return ((((track*26)+sector) << 7) + bytes); 593954Sbill } 5944879Ssam 5954879Ssam lread(startad, count, obuff) 5964879Ssam register startad, count; 5974879Ssam register char *obuff; 598954Sbill { 599954Sbill long trans(); 600954Sbill extern floppydes; 6014879Ssam register int size = flag(m) ? 512 : 128; 6024879Ssam 603954Sbill rt_init(); 6044879Ssam while ((count -= size) >= 0) { 6054879Ssam lseek(floppydes, flag(m) ? 6064879Ssam (long)startad : trans(startad), 0); 6074879Ssam if (read(floppydes, obuff, size) != size) 6084879Ssam fprintf(stderr, "arff: read error block %d\n", 6094879Ssam startad/size); 6104879Ssam obuff += size; 6114879Ssam startad += size; 6124879Ssam } 613954Sbill } 6144879Ssam 6154879Ssam lwrite(startad, count, obuff) 6164879Ssam register startad, count; 6174879Ssam register char *obuff; 618954Sbill { 619954Sbill long trans(); 620954Sbill extern floppydes; 6214879Ssam register int size = flag(m) ? 512 : 128; 6224879Ssam 623954Sbill rt_init(); 6244879Ssam while ((count -= size) >= 0) { 6254879Ssam lseek(floppydes, flag(m) ? 6264879Ssam (long)startad : trans(startad), 0); 6274879Ssam if (write(floppydes, obuff, size) != size) 6284879Ssam fprintf(stderr, "arff: write error block %d\n", 6294879Ssam startad/size); 6304879Ssam obuff += size; 6314879Ssam startad += size; 6324879Ssam } 633954Sbill } 634954Sbill 635954Sbill rcmd() 636954Sbill { 637954Sbill register int i; 638954Sbill 639954Sbill rt_init(); 6404879Ssam if (namc > 0) 6414879Ssam for (i = 0; i < namc; i++) 6424879Ssam if (rtr(namv[i]) == 0) 6434879Ssam namv[i] = 0; 644954Sbill } 645954Sbill 646954Sbill rtr(name) 6474879Ssam char *name; 648954Sbill { 6494879Ssam register FLDOPE *dope; 6504879Ssam register struct rt_ent *de; 6514879Ssam struct stat buf; 6524879Ssam register struct stat *bufp = &buf; 6533346Swnj int segnum; 6543346Swnj register char *last; 655954Sbill 6564879Ssam if (stat(name, bufp) < 0) { 6573489Sroot perror(name); 6589877Ssam return (-1); 6593489Sroot } 6604879Ssam if (dope = lookup(name)) { 661954Sbill /* can replace, no problem */ 662954Sbill de = dope->rtdope; 6634879Ssam if (bufp->st_size <= (de->rt_len * 512)) 664954Sbill printf("r - %s\n",name), 6654879Ssam toflop(name, bufp->st_size, dope); 666954Sbill else { 6679877Ssam fprintf(stderr, 6689877Ssam "%s will not fit in currently used file on floppy\n", 6699877Ssam name); 6709877Ssam return (-1); 671954Sbill } 6729877Ssam goto found; 6739877Ssam } 6749877Ssam /* 6759877Ssam * Search for vacant spot 6769877Ssam */ 6779877Ssam for (segnum = 0; segnum != -1; 6789877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 6799877Ssam { 6809877Ssam last = rt_last + segnum*2*RT_BLOCK; 6819877Ssam for (de = rt_dir[segnum].rt_ents; 6829877Ssam rt(de)->rt_stat != RT_ESEG; de++) 6839877Ssam if ((de)->rt_stat == RT_NULL) { 6849877Ssam if (bufp->st_size <= (de->rt_len*512)) { 6859877Ssam printf("a - %s\n",name), 6869877Ssam mkent(de, segnum, bufp,name); 6879877Ssam goto found; 688954Sbill } 6899877Ssam continue; 6909877Ssam } 691954Sbill } 6929877Ssam printf("%s: no slot for file\n", name); 6939877Ssam return (-1); 6944879Ssam 6954879Ssam found: 6964879Ssam if (dope = lookup(name)) { 6974879Ssam toflop(name, bufp->st_size, dope); 6983489Sroot return (0); 699954Sbill } 7003489Sroot printf("%s: internal error, added then not found\n", name); 7013489Sroot return (-1); 7024879Ssam } 703954Sbill 7044879Ssam mkent(de, segnum, bufp, name) 7054879Ssam register struct rt_ent *de; 7064879Ssam int segnum; 7074879Ssam register struct stat *bufp; 7084879Ssam char *name; 709954Sbill { 7104879Ssam struct tm *localtime(); 7114879Ssam register struct tm *timp; 7124879Ssam register struct rt_ent *workp; 7134879Ssam int count; 714954Sbill 715954Sbill count = (((bufp->st_size -1) >>9) + 1); 7164879Ssam /* make sure there is room */ 7174879Ssam if (de->rt_len == count) 718954Sbill goto overwrite; 7194879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7204879Ssam /* no entries left on segment */ 7214879Ssam if (flag(o)) 722954Sbill goto overwrite; 7239877Ssam fprintf(stderr, "Directory segment #%d full on %s\n", 7249877Ssam segnum+1, defdev); 725954Sbill exit(1); 726954Sbill } 7274879Ssam /* copy directory entries up */ 7284879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 729954Sbill *workp = workp[-1]; 730954Sbill de[1].rt_len -= count; 731954Sbill de->rt_len = count; 7323346Swnj rt_curend[segnum]++; 733954Sbill rt_nleft--; 7344879Ssam 735954Sbill overwrite: 736954Sbill srad50(name,de->rt_name); 737954Sbill timp = localtime(&bufp->st_mtime); 7387320Swnj de->rt_date.rt_dy = timp->tm_mday; 739954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 740954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 741954Sbill de->rt_stat = RT_FILE; 742954Sbill de->rt_pad = 0; 743954Sbill de->rt_chan = 0; 744954Sbill de->rt_job = 0; 7454879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 746954Sbill } 747954Sbill 7484879Ssam toflop(name, ocount, dope) 7494879Ssam char *name; 7504879Ssam register FLDOPE *dope; 7514879Ssam long ocount; 752954Sbill { 753954Sbill register file, n, startad = dope->startad, count = ocount; 754954Sbill char buff[512]; 755954Sbill 7564879Ssam file = open(name, 0); 7574879Ssam if (file < 0) { 7584879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7594879Ssam exit(1); 7604879Ssam } 761954Sbill for( ; count >= 512; count -= 512) { 7624879Ssam read(file, buff, 512); 7634879Ssam lwrite(startad, 512, buff); 764954Sbill startad += 512; 765954Sbill } 7664879Ssam read(file, buff, count); 767954Sbill close(file); 7684879Ssam if (count <= 0) 7694879Ssam return; 7704879Ssam for (n = count; n < 512; n ++) 7714879Ssam buff[n] = 0; 7724879Ssam lwrite(startad, 512, buff); 7734879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7744879Ssam if (count <= 0) 7754879Ssam return; 7764879Ssam for ( ; count > 0 ; count--) { 777954Sbill startad += 512; 7784879Ssam lwrite(startad, 512, zeroes); 779954Sbill } 7804879Ssam } 781954Sbill 782954Sbill dcmd() 783954Sbill { 784954Sbill register int i; 785954Sbill 786954Sbill rt_init(); 7874879Ssam if (namc) 7884879Ssam for (i = 0; i < namc; i++) 7894879Ssam if (rtk(namv[i])==0) 7904879Ssam namv[i]=0; 7914879Ssam if (dirdirty) 792954Sbill scrunch(); 793954Sbill } 7944879Ssam 795954Sbill rtk(name) 7964879Ssam char *name; 797954Sbill { 798954Sbill register FLDOPE *dope; 799954Sbill register struct rt_ent *de; 800954Sbill FLDOPE *lookup(); 801954Sbill 8024879Ssam if (dope = lookup(name)) { 803954Sbill printf("d - %s\n",name); 804954Sbill de = dope->rtdope; 805954Sbill de->rt_stat = RT_NULL; 806954Sbill de->rt_name[0] = 0; 807954Sbill de->rt_name[1] = 0; 808954Sbill de->rt_name[2] = 0; 8099877Ssam *((u_short *)&(de->rt_date)) = 0; 810954Sbill dirdirty = 1; 8119877Ssam return (0); 812954Sbill } 8139877Ssam return (1); 814954Sbill } 8154879Ssam 8164879Ssam scrunch() 8174879Ssam { 8183346Swnj register struct rt_ent *de , *workp; 8193346Swnj register segnum; 8204879Ssam 8214879Ssam for (segnum = 0; segnum != -1; 8223346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8234879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 8249877Ssam if (de->rt_stat == RT_NULL && 82512012Shelge (de+1)->rt_stat == RT_NULL) { 8264879Ssam (de+1)->rt_len += de->rt_len; 82712012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 8284879Ssam *workp = workp[1]; 8294879Ssam de--; 8304879Ssam rt_curend[segnum]--; 8314879Ssam rt_nleft++; 8324879Ssam } 83312012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 83412012Shelge (char *)&rt_dir[segnum]); 835954Sbill } 83612012Shelge dirdirty = 0; 837954Sbill } 838