122483Sdist /* 222483Sdist * Copyright (c) 1980 Regents of the University of California. 322483Sdist * All rights reserved. The Berkeley software License Agreement 422483Sdist * specifies the terms and conditions for redistribution. 522483Sdist */ 622483Sdist 79877Ssam #ifndef lint 822483Sdist char copyright[] = 922483Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022483Sdist All rights reserved.\n"; 1122483Sdist #endif not lint 124879Ssam 1322483Sdist #ifndef lint 14*29823Skarels static char sccsid[] = "@(#)arff.c 5.3 (Berkeley) 09/03/86"; 1522483Sdist #endif not lint 1622483Sdist 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 6826131Sbloom #define rd_numseg rt_axhead.rt_numseg 6926131Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg 7026131Sbloom #define rd_lstseg rt_axhead.rt_lstseg 7126131Sbloom #define rd_entpad rt_axhead.rt_entpad 7226131Sbloom #define rd_stfile rt_axhead.rt_stfile 7326131Sbloom 74954Sbill typedef struct fldope { 75954Sbill int startad; 76954Sbill int count; 77954Sbill struct rt_ent *rtdope; 78954Sbill } FLDOPE; 794879Ssam 80954Sbill FLDOPE *lookup(); 814879Ssam 829877Ssam #define rt(p) ((struct rt_ent *) p ) 839877Ssam #define Ain1 03100 849877Ssam #define Ain2 050 859877Ssam #define flag(c) (flg[('c') - 'a']) 86954Sbill 879877Ssam char *man = "rxtd"; 889877Ssam char zeroes[512]; 89954Sbill 90954Sbill extern char *val; 91954Sbill extern char table[256]; 924879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 939877Ssam { 4, 0, 1, 0, 14 }, 9426131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, 959877Ssam { 0, RT_ESEG } } 964879Ssam }; 97954Sbill 9826131Sbloom struct rt_dir rt_nulldir = { 9926131Sbloom { 0, 0, 0, 0, 0 }, 10026131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, 10126131Sbloom { 0, RT_ESEG } } 10226131Sbloom }; 10326131Sbloom 1044879Ssam int rt_entsiz; 1054879Ssam int rt_nleft; 1064879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 1074879Ssam int floppydes; 1084879Ssam int dirdirty; 1094879Ssam char *rt_last; 1104879Ssam char *defdev = "/dev/floppy"; 111954Sbill 11226131Sbloom char *opt = "vfbcm"; 1134879Ssam 1144879Ssam extern long lseek(); 1154879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 1164879Ssam 117954Sbill int (*comfun)(); 118954Sbill char flg[26]; 119954Sbill char **namv; 120954Sbill int namc; 121954Sbill 122954Sbill main(argc, argv) 1234879Ssam char *argv[]; 124954Sbill { 125954Sbill register char *cp; 126954Sbill 1274879Ssam if (argc < 2) 128954Sbill usage(); 1294879Ssam for (cp = argv[1]; *cp; cp++) 1304879Ssam switch (*cp) { 131954Sbill 1324879Ssam case 'm': 1334879Ssam case 'v': 1344879Ssam case 'u': 1354879Ssam case 'w': 13626131Sbloom case 'b': 1374879Ssam flg[*cp-'a']++; 1384879Ssam continue; 1394879Ssam case 'c': 14013910Ssam flag(c)++; 1414879Ssam dirdirty++; 1424879Ssam continue; 143954Sbill 1444879Ssam case 'r': 1454879Ssam setcom(rcmd); 1464879Ssam flag(r)++; 1474879Ssam continue; 148954Sbill 1494879Ssam case 'd': 1504879Ssam setcom(dcmd); 1514879Ssam flag(d)++; 1524879Ssam continue; 153954Sbill 1544879Ssam case 'x': 1554879Ssam setcom(xcmd); 1564879Ssam continue; 157954Sbill 1584879Ssam case 't': 1594879Ssam setcom(tcmd); 1604879Ssam continue; 161954Sbill 1624879Ssam case 'f': 1634879Ssam defdev = argv[2]; 1644879Ssam argv++; 1654879Ssam argc--; 1664879Ssam continue; 1674879Ssam 1684879Ssam default: 1694879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1704879Ssam exit(1); 1714879Ssam } 1724879Ssam 173954Sbill namv = argv+2; 174954Sbill namc = argc-2; 1754879Ssam if (comfun == 0) { 1764879Ssam if (flag(u) == 0) { 1774879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1784879Ssam man); 179954Sbill exit(1); 180954Sbill } 181954Sbill setcom(rcmd); 182954Sbill } 183954Sbill (*comfun)(); 184954Sbill exit(notfound()); 185954Sbill } 186954Sbill 187954Sbill setcom(fun) 1884879Ssam int (*fun)(); 189954Sbill { 1904879Ssam if (comfun != 0) { 191954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 192954Sbill exit(1); 193954Sbill } 194954Sbill comfun = fun; 195954Sbill } 196954Sbill 197954Sbill usage() 198954Sbill { 1993356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 200954Sbill exit(1); 201954Sbill } 202954Sbill 203954Sbill notfound() 204954Sbill { 2054879Ssam register i, n = 0; 206954Sbill 2074879Ssam for (i = 0; i < namc; i++) 2084879Ssam if (namv[i]) { 209954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 210954Sbill n++; 211954Sbill } 2129877Ssam return (n); 213954Sbill } 214954Sbill 215954Sbill tcmd() 216954Sbill { 2174879Ssam register char *de, *last; 218954Sbill FLDOPE *lookup(), *dope; 2194879Ssam int segnum, nleft; 2204879Ssam register i; 221954Sbill register struct rt_ent *rde; 222954Sbill 223954Sbill rt_init(); 2249877Ssam if (namc != 0) { 2254879Ssam for (i = 0; i < namc; i++) 2264879Ssam if (dope = lookup(namv[i])) { 227954Sbill rde = dope->rtdope; 22826131Sbloom (void) rtls(rde); 229954Sbill namv[i] = 0; 230954Sbill } 2319877Ssam return; 2329877Ssam } 2339877Ssam for (segnum = 0; segnum != -1; 23426131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 2359877Ssam last = rt_last + segnum*2*RT_BLOCK; 2369877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2379877Ssam de += rt_entsiz) 2389877Ssam if (rtls(rt(de))) { 2399877Ssam nleft = (last-de)/rt_entsiz; 2409877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2419877Ssam printf(ENTRIES, nleft, segnum+1); 2429877Ssam break; 2439877Ssam } 2449877Ssam } 245954Sbill } 2464879Ssam 247954Sbill rtls(de) 2484879Ssam register struct rt_ent *de; 249954Sbill { 2504879Ssam int month, day, year; 251954Sbill char name[12], ext[4]; 252954Sbill 2534879Ssam switch (de->rt_stat) { 2544879Ssam 2554879Ssam case RT_TEMP: 2564879Ssam if (flag(v)) 257954Sbill printf("Tempfile:\n"); 2584879Ssam /* fall thru...*/ 259954Sbill 2604879Ssam case RT_FILE: 2614879Ssam if (!flag(v)) { 2624879Ssam sunrad50(name, de->rt_name); 2634879Ssam printf("%s\n", name); 264954Sbill break; 265954Sbill } 2664879Ssam unrad50(2, de->rt_name, name); 2674879Ssam unrad50(1, &(de->rt_name[2]), ext); 2684879Ssam day = de->rt_date.rt_dy; 2694879Ssam year = de->rt_date.rt_yr+72; 2704879Ssam month = de->rt_date.rt_mo; 2714879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2724879Ssam ext, month, day, year, de->rt_len); 2734879Ssam break; 274954Sbill 2754879Ssam case RT_NULL: 2764879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2774879Ssam break; 278954Sbill 2794879Ssam case RT_ESEG: 2809877Ssam return (1); 281954Sbill } 2829877Ssam return (0); 283954Sbill } 2844879Ssam 285954Sbill xcmd() 286954Sbill { 2874879Ssam register char *de, *last; 2883346Swnj int segnum; 289954Sbill char name[12]; 290954Sbill register int i; 291954Sbill 292954Sbill rt_init(); 2939877Ssam if (namc != 0) { 2944879Ssam for (i = 0; i < namc; i++) 2954879Ssam if (rtx(namv[i]) == 0) 2964879Ssam namv[i] = 0; 2979877Ssam return; 2989877Ssam } 2999877Ssam for (segnum = 0; segnum != -1; 30026131Sbloom segnum = rt_dir[segnum].rd_nxtseg-1) 3019877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 3029877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 30315553Sralph de += rt_entsiz) { 3049877Ssam switch (rt(de)->rt_stat) { 3059877Ssam 3069877Ssam case RT_ESEG: 30715553Sralph break; /* exit loop and try next segment */ 3089877Ssam 3099877Ssam case RT_TEMP: 3109877Ssam case RT_FILE: 3119877Ssam sunrad50(name,rt(de)->rt_name); 31226131Sbloom (void) rtx(name); 3139877Ssam 3149877Ssam case RT_NULL: 31515553Sralph default: 31615553Sralph continue; 3179877Ssam } 31815553Sralph break; 31915553Sralph } 320954Sbill } 3214879Ssam 322954Sbill rtx(name) 3234879Ssam char *name; 324954Sbill { 325954Sbill register FLDOPE *dope; 326954Sbill FLDOPE *lookup(); 327954Sbill register startad, count; 3284879Ssam int file; 3294879Ssam char buff[512]; 330954Sbill 331954Sbill 3324879Ssam if (dope = lookup(name)) { 3334879Ssam if (flag(v)) 33426131Sbloom (void) rtls(dope->rtdope); 335954Sbill else 336954Sbill printf("x - %s\n",name); 337954Sbill 3384879Ssam if ((file = creat(name, 0666)) < 0) 3399877Ssam return (1); 340954Sbill count = dope->count; 341954Sbill startad = dope->startad; 342954Sbill for( ; count > 0 ; count -= 512) { 343*29823Skarels (void) lread(startad, 512, buff); 34426131Sbloom (void) write(file, buff, 512); 345954Sbill startad += 512; 346954Sbill } 34726131Sbloom (void) close(file); 3489877Ssam return (0); 349954Sbill } 3509877Ssam return (1); 351954Sbill } 3524879Ssam 353954Sbill rt_init() 354954Sbill { 355954Sbill static initized = 0; 3564879Ssam register char *de, *last; 3573346Swnj register i; 3583799Shickman int dirnum; 3593799Shickman char *mode; 3603799Shickman FILE *temp_floppydes; 361954Sbill 3624879Ssam if (initized) 3634879Ssam return; 364954Sbill initized = 1; 36513910Ssam if (flag(c)) { 36613910Ssam struct stat sb; 36713910Ssam char response[128]; 36813910Ssam int tty; 36913910Ssam 37013910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 37113910Ssam goto ignore; 37213910Ssam tty = open("/dev/tty", O_RDWR); 37313910Ssam #define SURE "Are you sure you want to clobber the floppy? " 37426131Sbloom (void) write(tty, SURE, sizeof (SURE)); 37526131Sbloom (void) read(tty, response, sizeof (response)); 37613910Ssam if (*response != 'y') 37713910Ssam exit(50); 37826131Sbloom (void) close(tty); 37913910Ssam ignore: 38013910Ssam ; 38113910Ssam } 3824879Ssam if (flag(c) || flag(d) || flag(r)) 3833799Shickman mode = "r+"; 384954Sbill else 3853799Shickman mode = "r"; 3864879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3873799Shickman perror(defdev); 3883356Swnj exit(1); 3893799Shickman } else 3903799Shickman floppydes = fileno(temp_floppydes); 3914879Ssam if (!flag(c)) { 392*29823Skarels if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0])) 393*29823Skarels exit(2); 39426131Sbloom dirnum = rt_dir[0].rd_numseg; 39512012Shelge /* check for blank/uninitialized diskette */ 39612012Shelge if (dirnum <= 0) { 39712012Shelge fprintf(stderr,"arff: bad directory format\n"); 39812012Shelge exit(1); 39912012Shelge } 4003346Swnj if (dirnum > RT_DIRSIZE) { 4014879Ssam fprintf(stderr,"arff: too many directory segments\n"); 4024879Ssam exit(1); 4033346Swnj } 4044879Ssam for (i = 1; i < dirnum; i++) 405*29823Skarels if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i])) 406*29823Skarels exit(1); 40726131Sbloom } else { 4083489Sroot dirnum = 1; 40926131Sbloom if (flag(b)) { 41026131Sbloom rt_dir[0].rd_numseg = 31; 41126131Sbloom rt_dir[0].rd_stfile = 68; 41226131Sbloom rt_dir[0].rt_ents[0].rt_len = 20480 - 68; 41326131Sbloom } 41426131Sbloom } 415954Sbill 41626131Sbloom rt_entsiz = 2*rt_dir[0].rd_entpad + 14; 41726131Sbloom /* 41826131Sbloom * We assume that the directory entries have no padding. This 41926131Sbloom * may not be a valid assumption, but there are numerous point 42026131Sbloom * in the code where it assumes it is an rt_ent structure and 42126131Sbloom * not an rt_entsiz sized structure. 42226131Sbloom */ 42326131Sbloom rt_entsiz = 14; 4243346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 4253346Swnj rt_nleft = 0; 4263346Swnj 4274879Ssam for (i = 0; i < dirnum; i++) { 4284879Ssam last = rt_last + i*2*RT_BLOCK; 4294879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 4304879Ssam if (rt(de)->rt_stat == RT_ESEG) 4314879Ssam break; 4324879Ssam rt_curend[i] = rt(de); 4334879Ssam rt_nleft += (last-de)/rt_entsiz; 434954Sbill } 435954Sbill } 436954Sbill 437954Sbill static FLDOPE result; 4384879Ssam 439954Sbill FLDOPE * 440954Sbill lookup(name) 4414879Ssam char *name; 442954Sbill { 443954Sbill unsigned short rname[3]; 44426131Sbloom register char *de; 4453346Swnj int segnum; 446954Sbill register index; 447954Sbill 448954Sbill srad50(name,rname); 449954Sbill 4503356Swnj /* 451954Sbill * Search for name, accumulate blocks in index 452954Sbill */ 453954Sbill rt_init(); 4544879Ssam for (segnum = 0; segnum != -1; 45526131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 4564879Ssam { 4574879Ssam index = 0; 4584879Ssam for (de=((char *)&rt_dir[segnum])+10; 4594879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4604879Ssam switch(rt(de)->rt_stat) { 4614879Ssam 4624879Ssam case RT_FILE: 4634879Ssam case RT_TEMP: 4644879Ssam if(samename(rname,rt(de)->rt_name)) { 4654879Ssam result.count = rt(de)->rt_len * 512; 4664879Ssam result.startad = 512* 46726131Sbloom (rt_dir[segnum].rd_stfile + index); 4684879Ssam result.rtdope = (struct rt_ent *) de; 4699877Ssam return (&result); 4704879Ssam } 4714879Ssam 4724879Ssam case RT_NULL: 4734879Ssam index += rt(de)->rt_len; 4744879Ssam } 4753346Swnj } 4769877Ssam return ((FLDOPE *) 0); 4774879Ssam 478954Sbill } 4794879Ssam 480954Sbill static 4814879Ssam samename(a, b) 4824879Ssam u_short a[], b[]; 483954Sbill { 4849877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 485954Sbill } 486954Sbill 4874879Ssam rad50(cp, out) 4884879Ssam register u_char *cp; 4894879Ssam u_short *out; 490954Sbill { 4914879Ssam register index, temp; 492954Sbill 4934879Ssam for (index = 0; *cp; index++) { 494954Sbill temp = Ain1 * table[*cp++]; 4954879Ssam if (*cp!=0) { 496954Sbill temp += Ain2 * table[*cp++]; 497954Sbill if(*cp!=0) 498954Sbill temp += table[*cp++]; 499954Sbill } 500954Sbill out[index] = temp; 501954Sbill } 502954Sbill } 503954Sbill 5044879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 5054879Ssam 5064879Ssam unrad50(count, in, cp) 5074879Ssam u_short *in; 5084879Ssam register char *cp; 509954Sbill { 5104879Ssam register i, temp; 5114879Ssam register u_char *v = (u_char *) val; 512954Sbill 5134879Ssam for (i = 0; i < count; i++) { 514954Sbill temp = in[i]; 5154879Ssam reduce(*cp++, temp, Ain1); 5164879Ssam reduce(*cp++, temp, Ain2); 5174879Ssam reduce(*cp++, temp, 1); 518954Sbill } 519954Sbill *cp=0; 520954Sbill } 521954Sbill 5224879Ssam srad50(name, rname) 5234879Ssam register char *name; 5244879Ssam register u_short *rname; 525954Sbill { 5264879Ssam register index; 5274879Ssam register char *cp; 5284879Ssam char file[7], ext[4]; 5294879Ssam 5303356Swnj /* 531954Sbill * Find end of pathname 532954Sbill */ 5334879Ssam for (cp = name; *cp++; ) 5344879Ssam ; 5354879Ssam while (cp >= name && *--cp != '/') 5364879Ssam ; 537954Sbill cp++; 5383356Swnj /* 539954Sbill * Change to rad50 540954Sbill */ 5414879Ssam for (index = 0; *cp; ) { 542954Sbill file[index++] = *cp++; 5434879Ssam if (*cp == '.') { 544954Sbill cp++; 545954Sbill break; 546954Sbill } 5474879Ssam if (index >= 6) { 548954Sbill break; 549954Sbill } 550954Sbill } 551954Sbill file[index] = 0; 5524879Ssam for (index = 0; *cp; ) { 553954Sbill ext[index++] = *cp++; 5544879Ssam if (*cp == '.' || index >= 3) 555954Sbill break; 556954Sbill } 557954Sbill ext[index]=0; 5584879Ssam rname[0] = rname[1] = rname[2] = 0; 5594879Ssam rad50((u_char *)file, rname); 5604879Ssam rad50((u_char *)ext, rname+2); 561954Sbill } 5624879Ssam 5634879Ssam sunrad50(name, rname) 5644879Ssam u_short rname[]; 5654879Ssam register char *name; 566954Sbill { 567954Sbill register char *cp, *cp2; 568954Sbill char ext[4]; 569954Sbill 5704879Ssam unrad50(2, rname, name); 5714879Ssam unrad50(1, rname + 2, ext); 5724879Ssam /* 5734879Ssam * Jam name and extension together with a dot 5744879Ssam * deleting white space 5754879Ssam */ 5764879Ssam for (cp = name; *cp++;) 5774879Ssam ; 5784879Ssam --cp; 5794879Ssam while (*--cp == ' ' && cp >= name) 5804879Ssam ; 5814879Ssam *++cp = '.'; 5824879Ssam cp++; 5834879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 584954Sbill *cp++ = *cp2++; 585954Sbill *cp=0; 5864879Ssam if (cp[-1] == '.') 5874879Ssam cp[-1] = 0; 588954Sbill } 589954Sbill 590954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5914879Ssam 592954Sbill static char table[256] = { 593954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 594954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 595954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 596954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 597954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 598954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 599954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 600954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 601954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 602954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 603954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 604954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 605954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 606954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 607954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 608954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 609954Sbill 6104879Ssam /* 6114879Ssam * Logical to physical adress translation 6124879Ssam */ 6134879Ssam long 6144879Ssam trans(logical) 6154879Ssam register int logical; 616954Sbill { 617954Sbill register int sector, bytes, track; 618954Sbill 6194879Ssam logical += 26*128; 6204879Ssam bytes = (logical&127); 621954Sbill logical >>= 7; 6224879Ssam sector = logical%26; 623954Sbill if(sector >= 13) 6244879Ssam sector = sector*2+1; 625954Sbill else 626954Sbill sector *= 2; 6274879Ssam sector += 26 + ((track = (logical/26))-1)*6; 628954Sbill sector %= 26; 6299877Ssam return ((((track*26)+sector) << 7) + bytes); 630954Sbill } 6314879Ssam 6324879Ssam lread(startad, count, obuff) 6334879Ssam register startad, count; 6344879Ssam register char *obuff; 635954Sbill { 636954Sbill long trans(); 637954Sbill extern floppydes; 6384879Ssam register int size = flag(m) ? 512 : 128; 639*29823Skarels int error = 0; 640*29823Skarels extern int errno; 6414879Ssam 642954Sbill rt_init(); 6434879Ssam while ((count -= size) >= 0) { 64426131Sbloom (void) lseek(floppydes, flag(m) ? 6454879Ssam (long)startad : trans(startad), 0); 646*29823Skarels if (read(floppydes, obuff, size) != size) { 647*29823Skarels error = errno; 648*29823Skarels fprintf(stderr, "arff: read error block %d: ", 6494879Ssam startad/size); 650*29823Skarels errno = error; 651*29823Skarels perror(""); 652*29823Skarels } 6534879Ssam obuff += size; 6544879Ssam startad += size; 6554879Ssam } 656*29823Skarels return (error); 657954Sbill } 6584879Ssam 6594879Ssam lwrite(startad, count, obuff) 6604879Ssam register startad, count; 6614879Ssam register char *obuff; 662954Sbill { 663954Sbill long trans(); 664954Sbill extern floppydes; 6654879Ssam register int size = flag(m) ? 512 : 128; 6664879Ssam 667954Sbill rt_init(); 6684879Ssam while ((count -= size) >= 0) { 66926131Sbloom (void) lseek(floppydes, flag(m) ? 6704879Ssam (long)startad : trans(startad), 0); 6714879Ssam if (write(floppydes, obuff, size) != size) 6724879Ssam fprintf(stderr, "arff: write error block %d\n", 6734879Ssam startad/size); 6744879Ssam obuff += size; 6754879Ssam startad += size; 6764879Ssam } 677954Sbill } 678954Sbill 679954Sbill rcmd() 680954Sbill { 681954Sbill register int i; 682954Sbill 683954Sbill rt_init(); 6844879Ssam if (namc > 0) 6854879Ssam for (i = 0; i < namc; i++) 6864879Ssam if (rtr(namv[i]) == 0) 6874879Ssam namv[i] = 0; 688954Sbill } 689954Sbill 690954Sbill rtr(name) 6914879Ssam char *name; 692954Sbill { 6934879Ssam register FLDOPE *dope; 6944879Ssam register struct rt_ent *de; 6954879Ssam struct stat buf; 6964879Ssam register struct stat *bufp = &buf; 6973346Swnj int segnum; 69826131Sbloom char type; 699954Sbill 7004879Ssam if (stat(name, bufp) < 0) { 7013489Sroot perror(name); 7029877Ssam return (-1); 7033489Sroot } 70426131Sbloom type = 'a'; 7054879Ssam if (dope = lookup(name)) { 706954Sbill /* can replace, no problem */ 707954Sbill de = dope->rtdope; 70826131Sbloom if (bufp->st_size <= (de->rt_len * 512)) { 70926131Sbloom printf("r - %s\n",name); 7104879Ssam toflop(name, bufp->st_size, dope); 71126131Sbloom goto found; 71226131Sbloom } else { 71326131Sbloom de = dope->rtdope; 71426131Sbloom type = 'r'; 71526131Sbloom de->rt_stat = RT_NULL; 71626131Sbloom de->rt_name[0] = 0; 71726131Sbloom de->rt_name[1] = 0; 71826131Sbloom de->rt_name[2] = 0; 71926131Sbloom *((u_short *)&(de->rt_date)) = 0; 72026131Sbloom scrunch(); 721954Sbill } 7229877Ssam } 7239877Ssam /* 7249877Ssam * Search for vacant spot 7259877Ssam */ 7269877Ssam for (segnum = 0; segnum != -1; 72726131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 7289877Ssam { 7299877Ssam for (de = rt_dir[segnum].rt_ents; 7309877Ssam rt(de)->rt_stat != RT_ESEG; de++) 7319877Ssam if ((de)->rt_stat == RT_NULL) { 7329877Ssam if (bufp->st_size <= (de->rt_len*512)) { 73326131Sbloom printf("%c - %s\n", type, name), 7349877Ssam mkent(de, segnum, bufp,name); 7359877Ssam goto found; 736954Sbill } 7379877Ssam continue; 7389877Ssam } 739954Sbill } 74026131Sbloom if (type = 'r') 74126131Sbloom printf("%s: no slot for file, file deleted\n",name); 74226131Sbloom else 74326131Sbloom printf("%s: no slot for file\n", name); 7449877Ssam return (-1); 7454879Ssam 7464879Ssam found: 7474879Ssam if (dope = lookup(name)) { 7484879Ssam toflop(name, bufp->st_size, dope); 7493489Sroot return (0); 750954Sbill } 7513489Sroot printf("%s: internal error, added then not found\n", name); 7523489Sroot return (-1); 7534879Ssam } 754954Sbill 7554879Ssam mkent(de, segnum, bufp, name) 7564879Ssam register struct rt_ent *de; 7574879Ssam int segnum; 7584879Ssam register struct stat *bufp; 7594879Ssam char *name; 760954Sbill { 7614879Ssam struct tm *localtime(); 7624879Ssam register struct tm *timp; 7634879Ssam register struct rt_ent *workp; 7644879Ssam int count; 765954Sbill 766954Sbill count = (((bufp->st_size -1) >>9) + 1); 7674879Ssam /* make sure there is room */ 7684879Ssam if (de->rt_len == count) 769954Sbill goto overwrite; 7704879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 77126131Sbloom /* no entries left on segment, trying adding new segment */ 77226131Sbloom if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { 77326131Sbloom short newseg; 77426131Sbloom register int i; 77526131Sbloom int maxseg; 77626131Sbloom short size; 77726131Sbloom 77826131Sbloom newseg = rt_dir[0].rd_lstseg++; 77926131Sbloom rt_dir[newseg] = rt_nulldir; 78026131Sbloom rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; 78126131Sbloom rt_dir[segnum].rd_nxtseg = newseg + 1; 78226131Sbloom rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; 78326131Sbloom rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; 78426131Sbloom size = 0; 78526131Sbloom maxseg = 0; 78626131Sbloom for(i = newseg - 1; i >= 0; i--) { 78726131Sbloom workp = rt_curend[i] - 1; 78826131Sbloom if (workp->rt_stat != RT_NULL) 78926131Sbloom continue; 79026131Sbloom if (workp->rt_len < size) 79126131Sbloom continue; 79226131Sbloom size = workp->rt_len; 79326131Sbloom maxseg = i; 79426131Sbloom } 79526131Sbloom size = 0; 79626131Sbloom for (workp = &rt_dir[maxseg].rt_ents[0]; 79726131Sbloom workp->rt_stat != RT_ESEG; workp++) { 79826131Sbloom size += workp->rt_len; 79926131Sbloom } 80026131Sbloom workp--; 80126131Sbloom rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; 80226131Sbloom rt_dir[newseg].rd_stfile = 80326131Sbloom rt_dir[maxseg].rd_stfile + size - workp->rt_len; 80426131Sbloom workp->rt_len = 0; 80526131Sbloom rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; 80626131Sbloom lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 80726131Sbloom if (segnum != 0) 80826131Sbloom lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 80926131Sbloom (char *)&rt_dir[segnum]); 81026131Sbloom lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, 81126131Sbloom (char *)&rt_dir[newseg]); 81226131Sbloom segnum = newseg; 81326131Sbloom de = &rt_dir[newseg].rt_ents[0]; 81426131Sbloom } else { 81526131Sbloom fprintf(stderr, "All directory segments full on %s\n", 81626131Sbloom defdev); 81726131Sbloom exit(1); 81826131Sbloom } 819954Sbill } 8204879Ssam /* copy directory entries up */ 8214879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 822954Sbill *workp = workp[-1]; 823954Sbill de[1].rt_len -= count; 824954Sbill de->rt_len = count; 8253346Swnj rt_curend[segnum]++; 826954Sbill rt_nleft--; 8274879Ssam 828954Sbill overwrite: 829954Sbill srad50(name,de->rt_name); 830954Sbill timp = localtime(&bufp->st_mtime); 8317320Swnj de->rt_date.rt_dy = timp->tm_mday; 832954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 833954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 834954Sbill de->rt_stat = RT_FILE; 835954Sbill de->rt_pad = 0; 836954Sbill de->rt_chan = 0; 837954Sbill de->rt_job = 0; 8384879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 839954Sbill } 840954Sbill 8414879Ssam toflop(name, ocount, dope) 8424879Ssam char *name; 8434879Ssam register FLDOPE *dope; 8444879Ssam long ocount; 845954Sbill { 846954Sbill register file, n, startad = dope->startad, count = ocount; 847954Sbill char buff[512]; 848954Sbill 8494879Ssam file = open(name, 0); 8504879Ssam if (file < 0) { 8514879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 8524879Ssam exit(1); 8534879Ssam } 854954Sbill for( ; count >= 512; count -= 512) { 85526131Sbloom (void) read(file, buff, 512); 8564879Ssam lwrite(startad, 512, buff); 857954Sbill startad += 512; 858954Sbill } 85926131Sbloom (void) read(file, buff, count); 86026131Sbloom (void) close(file); 8614879Ssam if (count <= 0) 8624879Ssam return; 8634879Ssam for (n = count; n < 512; n ++) 8644879Ssam buff[n] = 0; 8654879Ssam lwrite(startad, 512, buff); 8664879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 8674879Ssam if (count <= 0) 8684879Ssam return; 8694879Ssam for ( ; count > 0 ; count--) { 870954Sbill startad += 512; 8714879Ssam lwrite(startad, 512, zeroes); 872954Sbill } 8734879Ssam } 874954Sbill 875954Sbill dcmd() 876954Sbill { 877954Sbill register int i; 878954Sbill 879954Sbill rt_init(); 8804879Ssam if (namc) 8814879Ssam for (i = 0; i < namc; i++) 8824879Ssam if (rtk(namv[i])==0) 8834879Ssam namv[i]=0; 8844879Ssam if (dirdirty) 885954Sbill scrunch(); 886954Sbill } 8874879Ssam 888954Sbill rtk(name) 8894879Ssam char *name; 890954Sbill { 891954Sbill register FLDOPE *dope; 892954Sbill register struct rt_ent *de; 893954Sbill FLDOPE *lookup(); 894954Sbill 8954879Ssam if (dope = lookup(name)) { 896954Sbill printf("d - %s\n",name); 897954Sbill de = dope->rtdope; 898954Sbill de->rt_stat = RT_NULL; 899954Sbill de->rt_name[0] = 0; 900954Sbill de->rt_name[1] = 0; 901954Sbill de->rt_name[2] = 0; 9029877Ssam *((u_short *)&(de->rt_date)) = 0; 903954Sbill dirdirty = 1; 9049877Ssam return (0); 905954Sbill } 9069877Ssam return (1); 907954Sbill } 9084879Ssam 9094879Ssam scrunch() 9104879Ssam { 9113346Swnj register struct rt_ent *de , *workp; 9123346Swnj register segnum; 9134879Ssam 9144879Ssam for (segnum = 0; segnum != -1; 91526131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 9164879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 9179877Ssam if (de->rt_stat == RT_NULL && 91812012Shelge (de+1)->rt_stat == RT_NULL) { 9194879Ssam (de+1)->rt_len += de->rt_len; 92012012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 9214879Ssam *workp = workp[1]; 9224879Ssam de--; 9234879Ssam rt_curend[segnum]--; 9244879Ssam rt_nleft++; 9254879Ssam } 92612012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 92712012Shelge (char *)&rt_dir[segnum]); 928954Sbill } 92912012Shelge dirdirty = 0; 930954Sbill } 931