1*22483Sdist /* 2*22483Sdist * Copyright (c) 1980 Regents of the University of California. 3*22483Sdist * All rights reserved. The Berkeley software License Agreement 4*22483Sdist * specifies the terms and conditions for redistribution. 5*22483Sdist */ 6*22483Sdist 79877Ssam #ifndef lint 8*22483Sdist char copyright[] = 9*22483Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*22483Sdist All rights reserved.\n"; 11*22483Sdist #endif not lint 124879Ssam 13*22483Sdist #ifndef lint 14*22483Sdist static char sccsid[] = "@(#)arff.c 5.1 (Berkeley) 06/06/85"; 15*22483Sdist #endif not lint 16*22483Sdist 17954Sbill #include <sys/types.h> 18954Sbill #include <sys/stat.h> 1913605Ssam #include <sys/time.h> 20954Sbill #include <signal.h> 21954Sbill #include <stdio.h> 2213910Ssam #include <sys/file.h> 234879Ssam 24954Sbill #define dbprintf printf 254879Ssam 26954Sbill struct rt_dat { 274879Ssam u_short rt_yr:5; /* year-1972 */ 284879Ssam u_short rt_dy:5; /* day */ 294879Ssam u_short rt_mo:5; /* month */ 30954Sbill }; 314879Ssam 32954Sbill struct rt_axent { 33954Sbill char rt_sent[14]; 34954Sbill }; 35954Sbill 36954Sbill struct rt_ent { 374879Ssam char rt_pad; /* unusued */ 384879Ssam char rt_stat; /* type of entry, or end of seg */ 394879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 407319Swnj u_short rt_len; /* length of file */ 414879Ssam char rt_chan; /* only used in temporary files */ 424879Ssam char rt_job; /* only used in temporary files */ 439877Ssam struct rt_dat rt_date; /* creation date */ 44954Sbill }; 454879Ssam 464879Ssam #define RT_TEMP 1 474879Ssam #define RT_NULL 2 484879Ssam #define RT_FILE 4 494879Ssam #define RT_ESEG 8 504879Ssam 514879Ssam #define RT_BLOCK 512 /* block size */ 524879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 534879Ssam 54954Sbill struct rt_head { 554879Ssam short rt_numseg; /* # of segments available */ 564879Ssam short rt_nxtseg; /* # of next logical segment */ 574879Ssam short rt_lstseg; /* highest seg currently open */ 584879Ssam u_short rt_entpad; /* extra words/directory entry */ 594879Ssam short rt_stfile; /* block # where files begin */ 60954Sbill }; 614879Ssam 62954Sbill struct rt_dir { 63954Sbill struct rt_head rt_axhead; 64954Sbill struct rt_ent rt_ents[72]; 654879Ssam char _dirpad[6]; 66954Sbill }; 674879Ssam 68954Sbill typedef struct fldope { 69954Sbill int startad; 70954Sbill int count; 71954Sbill struct rt_ent *rtdope; 72954Sbill } FLDOPE; 734879Ssam 74954Sbill FLDOPE *lookup(); 754879Ssam 769877Ssam #define rt(p) ((struct rt_ent *) p ) 779877Ssam #define Ain1 03100 789877Ssam #define Ain2 050 799877Ssam #define flag(c) (flg[('c') - 'a']) 80954Sbill 819877Ssam char *man = "rxtd"; 829877Ssam char zeroes[512]; 83954Sbill 84954Sbill extern char *val; 85954Sbill extern char table[256]; 864879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 879877Ssam { 4, 0, 1, 0, 14 }, 889877Ssam { { 0, RT_NULL, { 0, 0, 0 }, 494, 0 }, 899877Ssam { 0, RT_ESEG } } 904879Ssam }; 91954Sbill 924879Ssam int rt_entsiz; 934879Ssam int rt_nleft; 944879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 954879Ssam int floppydes; 964879Ssam int dirdirty; 974879Ssam char *rt_last; 984879Ssam char *defdev = "/dev/floppy"; 99954Sbill 1004879Ssam char *opt = "vf"; 1014879Ssam 102954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 1034879Ssam extern long lseek(); 1044879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 1054879Ssam 106954Sbill int (*comfun)(); 107954Sbill char flg[26]; 108954Sbill char **namv; 109954Sbill int namc; 110954Sbill int file; 111954Sbill 112954Sbill main(argc, argv) 1134879Ssam char *argv[]; 114954Sbill { 115954Sbill register char *cp; 116954Sbill 1174879Ssam if (argc < 2) 118954Sbill usage(); 1194879Ssam for (cp = argv[1]; *cp; cp++) 1204879Ssam switch (*cp) { 121954Sbill 1224879Ssam case 'm': 1234879Ssam case 'v': 1244879Ssam case 'u': 1254879Ssam case 'w': 1264879Ssam flg[*cp-'a']++; 1274879Ssam continue; 1284879Ssam case 'c': 12913910Ssam flag(c)++; 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 } 2019877Ssam 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(); 2209877Ssam 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 } 2279877Ssam return; 2289877Ssam } 2299877Ssam for (segnum = 0; segnum != -1; 2309877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 2319877Ssam last = rt_last + segnum*2*RT_BLOCK; 2329877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2339877Ssam de += rt_entsiz) 2349877Ssam if (rtls(rt(de))) { 2359877Ssam nleft = (last-de)/rt_entsiz; 2369877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2379877Ssam printf(ENTRIES, nleft, segnum+1); 2389877Ssam break; 2399877Ssam } 2409877Ssam } 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: 2769877Ssam return (1); 277954Sbill } 2789877Ssam 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(); 2899877Ssam if (namc != 0) { 2904879Ssam for (i = 0; i < namc; i++) 2914879Ssam if (rtx(namv[i]) == 0) 2924879Ssam namv[i] = 0; 2939877Ssam return; 2949877Ssam } 2959877Ssam for (segnum = 0; segnum != -1; 2969877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 2979877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 2989877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 29915553Sralph de += rt_entsiz) { 3009877Ssam switch (rt(de)->rt_stat) { 3019877Ssam 3029877Ssam case RT_ESEG: 30315553Sralph break; /* exit loop and try next segment */ 3049877Ssam 3059877Ssam case RT_TEMP: 3069877Ssam case RT_FILE: 3079877Ssam sunrad50(name,rt(de)->rt_name); 3089877Ssam rtx(name); 3099877Ssam 3109877Ssam case RT_NULL: 31115553Sralph default: 31215553Sralph continue; 3139877Ssam } 31415553Sralph break; 31515553Sralph } 316954Sbill } 3174879Ssam 318954Sbill rtx(name) 3194879Ssam char *name; 320954Sbill { 321954Sbill register FLDOPE *dope; 322954Sbill FLDOPE *lookup(); 323954Sbill register startad, count; 3244879Ssam int file; 3254879Ssam char buff[512]; 326954Sbill 327954Sbill 3284879Ssam if (dope = lookup(name)) { 3294879Ssam if (flag(v)) 330954Sbill rtls(dope->rtdope); 331954Sbill else 332954Sbill printf("x - %s\n",name); 333954Sbill 3344879Ssam if ((file = creat(name, 0666)) < 0) 3359877Ssam return (1); 336954Sbill count = dope->count; 337954Sbill startad = dope->startad; 338954Sbill for( ; count > 0 ; count -= 512) { 3394879Ssam lread(startad, 512, buff); 3404879Ssam write(file, buff, 512); 341954Sbill startad += 512; 342954Sbill } 343954Sbill close(file); 3449877Ssam return (0); 345954Sbill } 3469877Ssam return (1); 347954Sbill } 3484879Ssam 349954Sbill rt_init() 350954Sbill { 351954Sbill static initized = 0; 3524879Ssam register char *de, *last; 3533346Swnj register i; 3543799Shickman int dirnum; 3553799Shickman char *mode; 3563799Shickman FILE *temp_floppydes; 357954Sbill 3584879Ssam if (initized) 3594879Ssam return; 360954Sbill initized = 1; 36113910Ssam if (flag(c)) { 36213910Ssam struct stat sb; 36313910Ssam char response[128]; 36413910Ssam int tty; 36513910Ssam 36613910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 36713910Ssam goto ignore; 36813910Ssam tty = open("/dev/tty", O_RDWR); 36913910Ssam #define SURE "Are you sure you want to clobber the floppy? " 37013910Ssam write(tty, SURE, sizeof (SURE)); 37113910Ssam read(tty, response, sizeof (response)); 37213910Ssam if (*response != 'y') 37313910Ssam exit(50); 37413910Ssam close(tty); 37513910Ssam ignore: 37613910Ssam ; 37713910Ssam } 3784879Ssam if (flag(c) || flag(d) || flag(r)) 3793799Shickman mode = "r+"; 380954Sbill else 3813799Shickman mode = "r"; 3824879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3833799Shickman perror(defdev); 3843356Swnj exit(1); 3853799Shickman } else 3863799Shickman floppydes = fileno(temp_floppydes); 3874879Ssam if (!flag(c)) { 3884879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3893346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 39012012Shelge /* check for blank/uninitialized diskette */ 39112012Shelge if (dirnum <= 0) { 39212012Shelge fprintf(stderr,"arff: bad directory format\n"); 39312012Shelge exit(1); 39412012Shelge } 3953346Swnj if (dirnum > RT_DIRSIZE) { 3964879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3974879Ssam exit(1); 3983346Swnj } 3994879Ssam for (i = 1; i < dirnum; i++) 4004879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 4013489Sroot } else 4023489Sroot dirnum = 1; 403954Sbill 4043346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 4053346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 4063346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 4073346Swnj rt_nleft = 0; 4083346Swnj 4094879Ssam for (i = 0; i < dirnum; i++) { 4104879Ssam last = rt_last + i*2*RT_BLOCK; 4114879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 4124879Ssam if (rt(de)->rt_stat == RT_ESEG) 4134879Ssam break; 4144879Ssam rt_curend[i] = rt(de); 4154879Ssam rt_nleft += (last-de)/rt_entsiz; 416954Sbill } 417954Sbill } 418954Sbill 419954Sbill static FLDOPE result; 4204879Ssam 421954Sbill FLDOPE * 422954Sbill lookup(name) 4234879Ssam char *name; 424954Sbill { 425954Sbill unsigned short rname[3]; 4264879Ssam register char *de, *last; 4273346Swnj int segnum; 428954Sbill register index; 429954Sbill 430954Sbill srad50(name,rname); 431954Sbill 4323356Swnj /* 433954Sbill * Search for name, accumulate blocks in index 434954Sbill */ 435954Sbill rt_init(); 4364879Ssam for (segnum = 0; segnum != -1; 4374879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4384879Ssam { 4394879Ssam index = 0; 4404879Ssam last = rt_last + segnum*2*RT_BLOCK; 4414879Ssam for (de=((char *)&rt_dir[segnum])+10; 4424879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4434879Ssam switch(rt(de)->rt_stat) { 4444879Ssam 4454879Ssam case RT_FILE: 4464879Ssam case RT_TEMP: 4474879Ssam if(samename(rname,rt(de)->rt_name)) { 4484879Ssam result.count = rt(de)->rt_len * 512; 4494879Ssam result.startad = 512* 4504879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4514879Ssam result.rtdope = (struct rt_ent *) de; 4529877Ssam return (&result); 4534879Ssam } 4544879Ssam 4554879Ssam case RT_NULL: 4564879Ssam index += rt(de)->rt_len; 4574879Ssam } 4583346Swnj } 4599877Ssam return ((FLDOPE *) 0); 4604879Ssam 461954Sbill } 4624879Ssam 463954Sbill static 4644879Ssam samename(a, b) 4654879Ssam u_short a[], b[]; 466954Sbill { 4679877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 468954Sbill } 469954Sbill 4704879Ssam rad50(cp, out) 4714879Ssam register u_char *cp; 4724879Ssam u_short *out; 473954Sbill { 4744879Ssam register index, temp; 475954Sbill 4764879Ssam for (index = 0; *cp; index++) { 477954Sbill temp = Ain1 * table[*cp++]; 4784879Ssam if (*cp!=0) { 479954Sbill temp += Ain2 * table[*cp++]; 480954Sbill if(*cp!=0) 481954Sbill temp += table[*cp++]; 482954Sbill } 483954Sbill out[index] = temp; 484954Sbill } 485954Sbill } 486954Sbill 4874879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4884879Ssam 4894879Ssam unrad50(count, in, cp) 4904879Ssam u_short *in; 4914879Ssam register char *cp; 492954Sbill { 4934879Ssam register i, temp; 4944879Ssam register u_char *v = (u_char *) val; 495954Sbill 4964879Ssam for (i = 0; i < count; i++) { 497954Sbill temp = in[i]; 4984879Ssam reduce(*cp++, temp, Ain1); 4994879Ssam reduce(*cp++, temp, Ain2); 5004879Ssam reduce(*cp++, temp, 1); 501954Sbill } 502954Sbill *cp=0; 503954Sbill } 504954Sbill 5054879Ssam srad50(name, rname) 5064879Ssam register char *name; 5074879Ssam register u_short *rname; 508954Sbill { 5094879Ssam register index; 5104879Ssam register char *cp; 5114879Ssam char file[7], ext[4]; 5124879Ssam 5133356Swnj /* 514954Sbill * Find end of pathname 515954Sbill */ 5164879Ssam for (cp = name; *cp++; ) 5174879Ssam ; 5184879Ssam while (cp >= name && *--cp != '/') 5194879Ssam ; 520954Sbill cp++; 5213356Swnj /* 522954Sbill * Change to rad50 523954Sbill */ 5244879Ssam for (index = 0; *cp; ) { 525954Sbill file[index++] = *cp++; 5264879Ssam if (*cp == '.') { 527954Sbill cp++; 528954Sbill break; 529954Sbill } 5304879Ssam if (index >= 6) { 531954Sbill break; 532954Sbill } 533954Sbill } 534954Sbill file[index] = 0; 5354879Ssam for (index = 0; *cp; ) { 536954Sbill ext[index++] = *cp++; 5374879Ssam if (*cp == '.' || index >= 3) 538954Sbill break; 539954Sbill } 540954Sbill ext[index]=0; 5414879Ssam rname[0] = rname[1] = rname[2] = 0; 5424879Ssam rad50((u_char *)file, rname); 5434879Ssam rad50((u_char *)ext, rname+2); 544954Sbill } 5454879Ssam 5464879Ssam sunrad50(name, rname) 5474879Ssam u_short rname[]; 5484879Ssam register char *name; 549954Sbill { 550954Sbill register char *cp, *cp2; 551954Sbill char ext[4]; 552954Sbill 5534879Ssam unrad50(2, rname, name); 5544879Ssam unrad50(1, rname + 2, ext); 5554879Ssam /* 5564879Ssam * Jam name and extension together with a dot 5574879Ssam * deleting white space 5584879Ssam */ 5594879Ssam for (cp = name; *cp++;) 5604879Ssam ; 5614879Ssam --cp; 5624879Ssam while (*--cp == ' ' && cp >= name) 5634879Ssam ; 5644879Ssam *++cp = '.'; 5654879Ssam cp++; 5664879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 567954Sbill *cp++ = *cp2++; 568954Sbill *cp=0; 5694879Ssam if (cp[-1] == '.') 5704879Ssam cp[-1] = 0; 571954Sbill } 572954Sbill 573954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 574954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5754879Ssam 576954Sbill static char table[256] = { 577954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 578954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 579954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 580954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 581954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 582954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 583954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 584954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 585954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 586954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 587954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 588954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 589954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 590954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 591954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 592954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 593954Sbill 5944879Ssam /* 5954879Ssam * Logical to physical adress translation 5964879Ssam */ 5974879Ssam long 5984879Ssam trans(logical) 5994879Ssam register int logical; 600954Sbill { 601954Sbill register int sector, bytes, track; 602954Sbill 6034879Ssam logical += 26*128; 6044879Ssam bytes = (logical&127); 605954Sbill logical >>= 7; 6064879Ssam sector = logical%26; 607954Sbill if(sector >= 13) 6084879Ssam sector = sector*2+1; 609954Sbill else 610954Sbill sector *= 2; 6114879Ssam sector += 26 + ((track = (logical/26))-1)*6; 612954Sbill sector %= 26; 6139877Ssam return ((((track*26)+sector) << 7) + bytes); 614954Sbill } 6154879Ssam 6164879Ssam lread(startad, count, obuff) 6174879Ssam register startad, count; 6184879Ssam register char *obuff; 619954Sbill { 620954Sbill long trans(); 621954Sbill extern floppydes; 6224879Ssam register int size = flag(m) ? 512 : 128; 6234879Ssam 624954Sbill rt_init(); 6254879Ssam while ((count -= size) >= 0) { 6264879Ssam lseek(floppydes, flag(m) ? 6274879Ssam (long)startad : trans(startad), 0); 6284879Ssam if (read(floppydes, obuff, size) != size) 6294879Ssam fprintf(stderr, "arff: read error block %d\n", 6304879Ssam startad/size); 6314879Ssam obuff += size; 6324879Ssam startad += size; 6334879Ssam } 634954Sbill } 6354879Ssam 6364879Ssam lwrite(startad, count, obuff) 6374879Ssam register startad, count; 6384879Ssam register char *obuff; 639954Sbill { 640954Sbill long trans(); 641954Sbill extern floppydes; 6424879Ssam register int size = flag(m) ? 512 : 128; 6434879Ssam 644954Sbill rt_init(); 6454879Ssam while ((count -= size) >= 0) { 6464879Ssam lseek(floppydes, flag(m) ? 6474879Ssam (long)startad : trans(startad), 0); 6484879Ssam if (write(floppydes, obuff, size) != size) 6494879Ssam fprintf(stderr, "arff: write error block %d\n", 6504879Ssam startad/size); 6514879Ssam obuff += size; 6524879Ssam startad += size; 6534879Ssam } 654954Sbill } 655954Sbill 656954Sbill rcmd() 657954Sbill { 658954Sbill register int i; 659954Sbill 660954Sbill rt_init(); 6614879Ssam if (namc > 0) 6624879Ssam for (i = 0; i < namc; i++) 6634879Ssam if (rtr(namv[i]) == 0) 6644879Ssam namv[i] = 0; 665954Sbill } 666954Sbill 667954Sbill rtr(name) 6684879Ssam char *name; 669954Sbill { 6704879Ssam register FLDOPE *dope; 6714879Ssam register struct rt_ent *de; 6724879Ssam struct stat buf; 6734879Ssam register struct stat *bufp = &buf; 6743346Swnj int segnum; 6753346Swnj register char *last; 676954Sbill 6774879Ssam if (stat(name, bufp) < 0) { 6783489Sroot perror(name); 6799877Ssam return (-1); 6803489Sroot } 6814879Ssam if (dope = lookup(name)) { 682954Sbill /* can replace, no problem */ 683954Sbill de = dope->rtdope; 6844879Ssam if (bufp->st_size <= (de->rt_len * 512)) 685954Sbill printf("r - %s\n",name), 6864879Ssam toflop(name, bufp->st_size, dope); 687954Sbill else { 6889877Ssam fprintf(stderr, 6899877Ssam "%s will not fit in currently used file on floppy\n", 6909877Ssam name); 6919877Ssam return (-1); 692954Sbill } 6939877Ssam goto found; 6949877Ssam } 6959877Ssam /* 6969877Ssam * Search for vacant spot 6979877Ssam */ 6989877Ssam for (segnum = 0; segnum != -1; 6999877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 7009877Ssam { 7019877Ssam last = rt_last + segnum*2*RT_BLOCK; 7029877Ssam for (de = rt_dir[segnum].rt_ents; 7039877Ssam rt(de)->rt_stat != RT_ESEG; de++) 7049877Ssam if ((de)->rt_stat == RT_NULL) { 7059877Ssam if (bufp->st_size <= (de->rt_len*512)) { 7069877Ssam printf("a - %s\n",name), 7079877Ssam mkent(de, segnum, bufp,name); 7089877Ssam goto found; 709954Sbill } 7109877Ssam continue; 7119877Ssam } 712954Sbill } 7139877Ssam printf("%s: no slot for file\n", name); 7149877Ssam return (-1); 7154879Ssam 7164879Ssam found: 7174879Ssam if (dope = lookup(name)) { 7184879Ssam toflop(name, bufp->st_size, dope); 7193489Sroot return (0); 720954Sbill } 7213489Sroot printf("%s: internal error, added then not found\n", name); 7223489Sroot return (-1); 7234879Ssam } 724954Sbill 7254879Ssam mkent(de, segnum, bufp, name) 7264879Ssam register struct rt_ent *de; 7274879Ssam int segnum; 7284879Ssam register struct stat *bufp; 7294879Ssam char *name; 730954Sbill { 7314879Ssam struct tm *localtime(); 7324879Ssam register struct tm *timp; 7334879Ssam register struct rt_ent *workp; 7344879Ssam int count; 735954Sbill 736954Sbill count = (((bufp->st_size -1) >>9) + 1); 7374879Ssam /* make sure there is room */ 7384879Ssam if (de->rt_len == count) 739954Sbill goto overwrite; 7404879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7414879Ssam /* no entries left on segment */ 7424879Ssam if (flag(o)) 743954Sbill goto overwrite; 7449877Ssam fprintf(stderr, "Directory segment #%d full on %s\n", 7459877Ssam segnum+1, defdev); 746954Sbill exit(1); 747954Sbill } 7484879Ssam /* copy directory entries up */ 7494879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 750954Sbill *workp = workp[-1]; 751954Sbill de[1].rt_len -= count; 752954Sbill de->rt_len = count; 7533346Swnj rt_curend[segnum]++; 754954Sbill rt_nleft--; 7554879Ssam 756954Sbill overwrite: 757954Sbill srad50(name,de->rt_name); 758954Sbill timp = localtime(&bufp->st_mtime); 7597320Swnj de->rt_date.rt_dy = timp->tm_mday; 760954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 761954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 762954Sbill de->rt_stat = RT_FILE; 763954Sbill de->rt_pad = 0; 764954Sbill de->rt_chan = 0; 765954Sbill de->rt_job = 0; 7664879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 767954Sbill } 768954Sbill 7694879Ssam toflop(name, ocount, dope) 7704879Ssam char *name; 7714879Ssam register FLDOPE *dope; 7724879Ssam long ocount; 773954Sbill { 774954Sbill register file, n, startad = dope->startad, count = ocount; 775954Sbill char buff[512]; 776954Sbill 7774879Ssam file = open(name, 0); 7784879Ssam if (file < 0) { 7794879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7804879Ssam exit(1); 7814879Ssam } 782954Sbill for( ; count >= 512; count -= 512) { 7834879Ssam read(file, buff, 512); 7844879Ssam lwrite(startad, 512, buff); 785954Sbill startad += 512; 786954Sbill } 7874879Ssam read(file, buff, count); 788954Sbill close(file); 7894879Ssam if (count <= 0) 7904879Ssam return; 7914879Ssam for (n = count; n < 512; n ++) 7924879Ssam buff[n] = 0; 7934879Ssam lwrite(startad, 512, buff); 7944879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7954879Ssam if (count <= 0) 7964879Ssam return; 7974879Ssam for ( ; count > 0 ; count--) { 798954Sbill startad += 512; 7994879Ssam lwrite(startad, 512, zeroes); 800954Sbill } 8014879Ssam } 802954Sbill 803954Sbill dcmd() 804954Sbill { 805954Sbill register int i; 806954Sbill 807954Sbill rt_init(); 8084879Ssam if (namc) 8094879Ssam for (i = 0; i < namc; i++) 8104879Ssam if (rtk(namv[i])==0) 8114879Ssam namv[i]=0; 8124879Ssam if (dirdirty) 813954Sbill scrunch(); 814954Sbill } 8154879Ssam 816954Sbill rtk(name) 8174879Ssam char *name; 818954Sbill { 819954Sbill register FLDOPE *dope; 820954Sbill register struct rt_ent *de; 821954Sbill FLDOPE *lookup(); 822954Sbill 8234879Ssam if (dope = lookup(name)) { 824954Sbill printf("d - %s\n",name); 825954Sbill de = dope->rtdope; 826954Sbill de->rt_stat = RT_NULL; 827954Sbill de->rt_name[0] = 0; 828954Sbill de->rt_name[1] = 0; 829954Sbill de->rt_name[2] = 0; 8309877Ssam *((u_short *)&(de->rt_date)) = 0; 831954Sbill dirdirty = 1; 8329877Ssam return (0); 833954Sbill } 8349877Ssam return (1); 835954Sbill } 8364879Ssam 8374879Ssam scrunch() 8384879Ssam { 8393346Swnj register struct rt_ent *de , *workp; 8403346Swnj register segnum; 8414879Ssam 8424879Ssam for (segnum = 0; segnum != -1; 8433346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8444879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 8459877Ssam if (de->rt_stat == RT_NULL && 84612012Shelge (de+1)->rt_stat == RT_NULL) { 8474879Ssam (de+1)->rt_len += de->rt_len; 84812012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 8494879Ssam *workp = workp[1]; 8504879Ssam de--; 8514879Ssam rt_curend[segnum]--; 8524879Ssam rt_nleft++; 8534879Ssam } 85412012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 85512012Shelge (char *)&rt_dir[segnum]); 856954Sbill } 85712012Shelge dirdirty = 0; 858954Sbill } 859