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*37979Sbostic static char sccsid[] = "@(#)arff.c 5.7 (Berkeley) 05/11/89"; 1522483Sdist #endif not lint 1622483Sdist 17954Sbill #include <sys/types.h> 18954Sbill #include <sys/stat.h> 1913605Ssam #include <sys/time.h> 20*37979Sbostic #include <sys/signal.h> 21*37979Sbostic #include <sys/file.h> 22954Sbill #include <stdio.h> 23*37979Sbostic #include "pathnames.h" 244879Ssam 25954Sbill #define dbprintf printf 264879Ssam 27954Sbill struct rt_dat { 284879Ssam u_short rt_yr:5; /* year-1972 */ 294879Ssam u_short rt_dy:5; /* day */ 304879Ssam u_short rt_mo:5; /* month */ 31954Sbill }; 324879Ssam 33954Sbill struct rt_axent { 34954Sbill char rt_sent[14]; 35954Sbill }; 36954Sbill 37954Sbill struct rt_ent { 384879Ssam char rt_pad; /* unusued */ 3930238Sbostic u_char rt_stat; /* type of entry, or end of seg */ 404879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 417319Swnj u_short rt_len; /* length of file */ 4230238Sbostic u_char rt_chan; /* only used in temporary files */ 434879Ssam char rt_job; /* only used in temporary files */ 449877Ssam struct rt_dat rt_date; /* creation date */ 45954Sbill }; 464879Ssam 474879Ssam #define RT_TEMP 1 484879Ssam #define RT_NULL 2 494879Ssam #define RT_FILE 4 5030238Sbostic #define RT_PFILE (0200|RT_FILE) /* protected file */ 514879Ssam #define RT_ESEG 8 524879Ssam 534879Ssam #define RT_BLOCK 512 /* block size */ 544879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 554879Ssam 56954Sbill struct rt_head { 574879Ssam short rt_numseg; /* # of segments available */ 584879Ssam short rt_nxtseg; /* # of next logical segment */ 594879Ssam short rt_lstseg; /* highest seg currently open */ 604879Ssam u_short rt_entpad; /* extra words/directory entry */ 614879Ssam short rt_stfile; /* block # where files begin */ 62954Sbill }; 634879Ssam 64954Sbill struct rt_dir { 65954Sbill struct rt_head rt_axhead; 66954Sbill struct rt_ent rt_ents[72]; 674879Ssam char _dirpad[6]; 68954Sbill }; 694879Ssam 7026131Sbloom #define rd_numseg rt_axhead.rt_numseg 7126131Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg 7226131Sbloom #define rd_lstseg rt_axhead.rt_lstseg 7326131Sbloom #define rd_entpad rt_axhead.rt_entpad 7426131Sbloom #define rd_stfile rt_axhead.rt_stfile 7526131Sbloom 76954Sbill typedef struct fldope { 77954Sbill int startad; 78954Sbill int count; 79954Sbill struct rt_ent *rtdope; 80954Sbill } FLDOPE; 814879Ssam 82954Sbill FLDOPE *lookup(); 834879Ssam 849877Ssam #define rt(p) ((struct rt_ent *) p ) 859877Ssam #define Ain1 03100 869877Ssam #define Ain2 050 879877Ssam #define flag(c) (flg[('c') - 'a']) 88954Sbill 899877Ssam char *man = "rxtd"; 909877Ssam char zeroes[512]; 91954Sbill 92954Sbill extern char *val; 93954Sbill extern char table[256]; 944879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 9533133Sbostic { 969877Ssam { 4, 0, 1, 0, 14 }, 9726131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, 989877Ssam { 0, RT_ESEG } } 9933133Sbostic } 1004879Ssam }; 101954Sbill 10226131Sbloom struct rt_dir rt_nulldir = { 10326131Sbloom { 0, 0, 0, 0, 0 }, 10426131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, 10526131Sbloom { 0, RT_ESEG } } 10626131Sbloom }; 10726131Sbloom 1084879Ssam int rt_entsiz; 1094879Ssam int rt_nleft; 1104879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 1114879Ssam int floppydes; 1124879Ssam int dirdirty; 1134879Ssam char *rt_last; 114*37979Sbostic char *defdev = _PATH_FLOPPY; 115954Sbill 11626131Sbloom char *opt = "vfbcm"; 1174879Ssam 1184879Ssam extern long lseek(); 1194879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 1204879Ssam 121954Sbill int (*comfun)(); 122954Sbill char flg[26]; 123954Sbill char **namv; 124954Sbill int namc; 125954Sbill 126954Sbill main(argc, argv) 1274879Ssam char *argv[]; 128954Sbill { 129954Sbill register char *cp; 130954Sbill 1314879Ssam if (argc < 2) 132954Sbill usage(); 1334879Ssam for (cp = argv[1]; *cp; cp++) 1344879Ssam switch (*cp) { 135954Sbill 1364879Ssam case 'm': 1374879Ssam case 'v': 1384879Ssam case 'u': 1394879Ssam case 'w': 14026131Sbloom case 'b': 1414879Ssam flg[*cp-'a']++; 1424879Ssam continue; 1434879Ssam case 'c': 14413910Ssam flag(c)++; 1454879Ssam dirdirty++; 1464879Ssam continue; 147954Sbill 1484879Ssam case 'r': 1494879Ssam setcom(rcmd); 1504879Ssam flag(r)++; 1514879Ssam continue; 152954Sbill 1534879Ssam case 'd': 1544879Ssam setcom(dcmd); 1554879Ssam flag(d)++; 1564879Ssam continue; 157954Sbill 1584879Ssam case 'x': 1594879Ssam setcom(xcmd); 1604879Ssam continue; 161954Sbill 1624879Ssam case 't': 1634879Ssam setcom(tcmd); 1644879Ssam continue; 165954Sbill 1664879Ssam case 'f': 1674879Ssam defdev = argv[2]; 1684879Ssam argv++; 1694879Ssam argc--; 1704879Ssam continue; 1714879Ssam 1724879Ssam default: 1734879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1744879Ssam exit(1); 1754879Ssam } 1764879Ssam 177954Sbill namv = argv+2; 178954Sbill namc = argc-2; 1794879Ssam if (comfun == 0) { 1804879Ssam if (flag(u) == 0) { 1814879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1824879Ssam man); 183954Sbill exit(1); 184954Sbill } 185954Sbill setcom(rcmd); 186954Sbill } 187954Sbill (*comfun)(); 188954Sbill exit(notfound()); 189954Sbill } 190954Sbill 191954Sbill setcom(fun) 1924879Ssam int (*fun)(); 193954Sbill { 1944879Ssam if (comfun != 0) { 195954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 196954Sbill exit(1); 197954Sbill } 198954Sbill comfun = fun; 199954Sbill } 200954Sbill 201954Sbill usage() 202954Sbill { 2033356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 204954Sbill exit(1); 205954Sbill } 206954Sbill 207954Sbill notfound() 208954Sbill { 2094879Ssam register i, n = 0; 210954Sbill 2114879Ssam for (i = 0; i < namc; i++) 2124879Ssam if (namv[i]) { 213954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 214954Sbill n++; 215954Sbill } 2169877Ssam return (n); 217954Sbill } 218954Sbill 219954Sbill tcmd() 220954Sbill { 2214879Ssam register char *de, *last; 222954Sbill FLDOPE *lookup(), *dope; 2234879Ssam int segnum, nleft; 2244879Ssam register i; 225954Sbill register struct rt_ent *rde; 226954Sbill 227954Sbill rt_init(); 2289877Ssam if (namc != 0) { 2294879Ssam for (i = 0; i < namc; i++) 2304879Ssam if (dope = lookup(namv[i])) { 231954Sbill rde = dope->rtdope; 23226131Sbloom (void) rtls(rde); 233954Sbill namv[i] = 0; 234954Sbill } 2359877Ssam return; 2369877Ssam } 2379877Ssam for (segnum = 0; segnum != -1; 23826131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 2399877Ssam last = rt_last + segnum*2*RT_BLOCK; 2409877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2419877Ssam de += rt_entsiz) 2429877Ssam if (rtls(rt(de))) { 2439877Ssam nleft = (last-de)/rt_entsiz; 2449877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2459877Ssam printf(ENTRIES, nleft, segnum+1); 2469877Ssam break; 2479877Ssam } 2489877Ssam } 249954Sbill } 2504879Ssam 251954Sbill rtls(de) 2524879Ssam register struct rt_ent *de; 253954Sbill { 2544879Ssam int month, day, year; 255954Sbill char name[12], ext[4]; 256954Sbill 2574879Ssam switch (de->rt_stat) { 2584879Ssam 2594879Ssam case RT_TEMP: 2604879Ssam if (flag(v)) 261954Sbill printf("Tempfile:\n"); 2624879Ssam /* fall thru...*/ 263954Sbill 2644879Ssam case RT_FILE: 26530238Sbostic case RT_PFILE: 2664879Ssam if (!flag(v)) { 2674879Ssam sunrad50(name, de->rt_name); 2684879Ssam printf("%s\n", name); 269954Sbill break; 270954Sbill } 2714879Ssam unrad50(2, de->rt_name, name); 2724879Ssam unrad50(1, &(de->rt_name[2]), ext); 2734879Ssam day = de->rt_date.rt_dy; 2744879Ssam year = de->rt_date.rt_yr+72; 2754879Ssam month = de->rt_date.rt_mo; 2764879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2774879Ssam ext, month, day, year, de->rt_len); 2784879Ssam break; 279954Sbill 2804879Ssam case RT_NULL: 2814879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2824879Ssam break; 283954Sbill 2844879Ssam case RT_ESEG: 2859877Ssam return (1); 286954Sbill } 2879877Ssam return (0); 288954Sbill } 2894879Ssam 290954Sbill xcmd() 291954Sbill { 2924879Ssam register char *de, *last; 2933346Swnj int segnum; 294954Sbill char name[12]; 295954Sbill register int i; 296954Sbill 297954Sbill rt_init(); 2989877Ssam if (namc != 0) { 2994879Ssam for (i = 0; i < namc; i++) 3004879Ssam if (rtx(namv[i]) == 0) 3014879Ssam namv[i] = 0; 3029877Ssam return; 3039877Ssam } 3049877Ssam for (segnum = 0; segnum != -1; 30526131Sbloom segnum = rt_dir[segnum].rd_nxtseg-1) 3069877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 3079877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 30815553Sralph de += rt_entsiz) { 3099877Ssam switch (rt(de)->rt_stat) { 3109877Ssam 3119877Ssam case RT_ESEG: 31215553Sralph break; /* exit loop and try next segment */ 3139877Ssam 3149877Ssam case RT_TEMP: 3159877Ssam case RT_FILE: 31630238Sbostic case RT_PFILE: 3179877Ssam sunrad50(name,rt(de)->rt_name); 31826131Sbloom (void) rtx(name); 3199877Ssam 3209877Ssam case RT_NULL: 32115553Sralph default: 32215553Sralph continue; 3239877Ssam } 32415553Sralph break; 32515553Sralph } 326954Sbill } 3274879Ssam 328954Sbill rtx(name) 3294879Ssam char *name; 330954Sbill { 331954Sbill register FLDOPE *dope; 332954Sbill FLDOPE *lookup(); 333954Sbill register startad, count; 3344879Ssam int file; 3354879Ssam char buff[512]; 336954Sbill 337954Sbill 3384879Ssam if (dope = lookup(name)) { 3394879Ssam if (flag(v)) 34026131Sbloom (void) rtls(dope->rtdope); 341954Sbill else 342954Sbill printf("x - %s\n",name); 343954Sbill 3444879Ssam if ((file = creat(name, 0666)) < 0) 3459877Ssam return (1); 346954Sbill count = dope->count; 347954Sbill startad = dope->startad; 348954Sbill for( ; count > 0 ; count -= 512) { 34929823Skarels (void) lread(startad, 512, buff); 35026131Sbloom (void) write(file, buff, 512); 351954Sbill startad += 512; 352954Sbill } 35326131Sbloom (void) close(file); 3549877Ssam return (0); 355954Sbill } 3569877Ssam return (1); 357954Sbill } 3584879Ssam 359954Sbill rt_init() 360954Sbill { 361954Sbill static initized = 0; 3624879Ssam register char *de, *last; 3633346Swnj register i; 3643799Shickman int dirnum; 3653799Shickman char *mode; 3663799Shickman FILE *temp_floppydes; 367954Sbill 3684879Ssam if (initized) 3694879Ssam return; 370954Sbill initized = 1; 37113910Ssam if (flag(c)) { 37213910Ssam struct stat sb; 37313910Ssam char response[128]; 37413910Ssam int tty; 37513910Ssam 37613910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 37713910Ssam goto ignore; 378*37979Sbostic tty = open(_PATH_TTY, O_RDWR); 37913910Ssam #define SURE "Are you sure you want to clobber the floppy? " 38026131Sbloom (void) write(tty, SURE, sizeof (SURE)); 38126131Sbloom (void) read(tty, response, sizeof (response)); 38213910Ssam if (*response != 'y') 38313910Ssam exit(50); 38426131Sbloom (void) close(tty); 38513910Ssam ignore: 38613910Ssam ; 38713910Ssam } 3884879Ssam if (flag(c) || flag(d) || flag(r)) 3893799Shickman mode = "r+"; 390954Sbill else 3913799Shickman mode = "r"; 3924879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3933799Shickman perror(defdev); 3943356Swnj exit(1); 3953799Shickman } else 3963799Shickman floppydes = fileno(temp_floppydes); 3974879Ssam if (!flag(c)) { 39829823Skarels if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0])) 39929823Skarels exit(2); 40026131Sbloom dirnum = rt_dir[0].rd_numseg; 40112012Shelge /* check for blank/uninitialized diskette */ 40212012Shelge if (dirnum <= 0) { 40312012Shelge fprintf(stderr,"arff: bad directory format\n"); 40412012Shelge exit(1); 40512012Shelge } 4063346Swnj if (dirnum > RT_DIRSIZE) { 4074879Ssam fprintf(stderr,"arff: too many directory segments\n"); 4084879Ssam exit(1); 4093346Swnj } 4104879Ssam for (i = 1; i < dirnum; i++) 41129823Skarels if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i])) 41229823Skarels exit(1); 41326131Sbloom } else { 4143489Sroot dirnum = 1; 41526131Sbloom if (flag(b)) { 41626131Sbloom rt_dir[0].rd_numseg = 31; 41726131Sbloom rt_dir[0].rd_stfile = 68; 41826131Sbloom rt_dir[0].rt_ents[0].rt_len = 20480 - 68; 41926131Sbloom } 42026131Sbloom } 421954Sbill 42226131Sbloom rt_entsiz = 2*rt_dir[0].rd_entpad + 14; 42326131Sbloom /* 42426131Sbloom * We assume that the directory entries have no padding. This 42526131Sbloom * may not be a valid assumption, but there are numerous point 42626131Sbloom * in the code where it assumes it is an rt_ent structure and 42726131Sbloom * not an rt_entsiz sized structure. 42826131Sbloom */ 42926131Sbloom rt_entsiz = 14; 4303346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 4313346Swnj rt_nleft = 0; 4323346Swnj 4334879Ssam for (i = 0; i < dirnum; i++) { 4344879Ssam last = rt_last + i*2*RT_BLOCK; 4354879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 4364879Ssam if (rt(de)->rt_stat == RT_ESEG) 4374879Ssam break; 4384879Ssam rt_curend[i] = rt(de); 4394879Ssam rt_nleft += (last-de)/rt_entsiz; 440954Sbill } 441954Sbill } 442954Sbill 443954Sbill static FLDOPE result; 4444879Ssam 445954Sbill FLDOPE * 446954Sbill lookup(name) 4474879Ssam char *name; 448954Sbill { 449954Sbill unsigned short rname[3]; 45026131Sbloom register char *de; 4513346Swnj int segnum; 452954Sbill register index; 453954Sbill 454954Sbill srad50(name,rname); 455954Sbill 4563356Swnj /* 457954Sbill * Search for name, accumulate blocks in index 458954Sbill */ 459954Sbill rt_init(); 4604879Ssam for (segnum = 0; segnum != -1; 46126131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 4624879Ssam { 4634879Ssam index = 0; 4644879Ssam for (de=((char *)&rt_dir[segnum])+10; 4654879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4664879Ssam switch(rt(de)->rt_stat) { 4674879Ssam 4684879Ssam case RT_FILE: 46930238Sbostic case RT_PFILE: 4704879Ssam case RT_TEMP: 4714879Ssam if(samename(rname,rt(de)->rt_name)) { 4724879Ssam result.count = rt(de)->rt_len * 512; 4734879Ssam result.startad = 512* 47426131Sbloom (rt_dir[segnum].rd_stfile + index); 4754879Ssam result.rtdope = (struct rt_ent *) de; 4769877Ssam return (&result); 4774879Ssam } 4784879Ssam 4794879Ssam case RT_NULL: 4804879Ssam index += rt(de)->rt_len; 4814879Ssam } 4823346Swnj } 4839877Ssam return ((FLDOPE *) 0); 4844879Ssam 485954Sbill } 4864879Ssam 487954Sbill static 4884879Ssam samename(a, b) 4894879Ssam u_short a[], b[]; 490954Sbill { 4919877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 492954Sbill } 493954Sbill 4944879Ssam rad50(cp, out) 4954879Ssam register u_char *cp; 4964879Ssam u_short *out; 497954Sbill { 4984879Ssam register index, temp; 499954Sbill 5004879Ssam for (index = 0; *cp; index++) { 501954Sbill temp = Ain1 * table[*cp++]; 5024879Ssam if (*cp!=0) { 503954Sbill temp += Ain2 * table[*cp++]; 504954Sbill if(*cp!=0) 505954Sbill temp += table[*cp++]; 506954Sbill } 507954Sbill out[index] = temp; 508954Sbill } 509954Sbill } 510954Sbill 5114879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 5124879Ssam 5134879Ssam unrad50(count, in, cp) 5144879Ssam u_short *in; 5154879Ssam register char *cp; 516954Sbill { 5174879Ssam register i, temp; 5184879Ssam register u_char *v = (u_char *) val; 519954Sbill 5204879Ssam for (i = 0; i < count; i++) { 521954Sbill temp = in[i]; 5224879Ssam reduce(*cp++, temp, Ain1); 5234879Ssam reduce(*cp++, temp, Ain2); 5244879Ssam reduce(*cp++, temp, 1); 525954Sbill } 526954Sbill *cp=0; 527954Sbill } 528954Sbill 5294879Ssam srad50(name, rname) 5304879Ssam register char *name; 5314879Ssam register u_short *rname; 532954Sbill { 5334879Ssam register index; 5344879Ssam register char *cp; 5354879Ssam char file[7], ext[4]; 5364879Ssam 5373356Swnj /* 538954Sbill * Find end of pathname 539954Sbill */ 5404879Ssam for (cp = name; *cp++; ) 5414879Ssam ; 5424879Ssam while (cp >= name && *--cp != '/') 5434879Ssam ; 544954Sbill cp++; 5453356Swnj /* 546954Sbill * Change to rad50 547954Sbill */ 5484879Ssam for (index = 0; *cp; ) { 549954Sbill file[index++] = *cp++; 5504879Ssam if (*cp == '.') { 551954Sbill cp++; 552954Sbill break; 553954Sbill } 5544879Ssam if (index >= 6) { 555954Sbill break; 556954Sbill } 557954Sbill } 558954Sbill file[index] = 0; 5594879Ssam for (index = 0; *cp; ) { 560954Sbill ext[index++] = *cp++; 5614879Ssam if (*cp == '.' || index >= 3) 562954Sbill break; 563954Sbill } 564954Sbill ext[index]=0; 5654879Ssam rname[0] = rname[1] = rname[2] = 0; 5664879Ssam rad50((u_char *)file, rname); 5674879Ssam rad50((u_char *)ext, rname+2); 568954Sbill } 5694879Ssam 5704879Ssam sunrad50(name, rname) 5714879Ssam u_short rname[]; 5724879Ssam register char *name; 573954Sbill { 574954Sbill register char *cp, *cp2; 575954Sbill char ext[4]; 576954Sbill 5774879Ssam unrad50(2, rname, name); 5784879Ssam unrad50(1, rname + 2, ext); 5794879Ssam /* 5804879Ssam * Jam name and extension together with a dot 5814879Ssam * deleting white space 5824879Ssam */ 5834879Ssam for (cp = name; *cp++;) 5844879Ssam ; 5854879Ssam --cp; 5864879Ssam while (*--cp == ' ' && cp >= name) 5874879Ssam ; 5884879Ssam *++cp = '.'; 5894879Ssam cp++; 5904879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 591954Sbill *cp++ = *cp2++; 592954Sbill *cp=0; 5934879Ssam if (cp[-1] == '.') 5944879Ssam cp[-1] = 0; 595954Sbill } 596954Sbill 597954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5984879Ssam 599954Sbill static char table[256] = { 600954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 601954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 602954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 603954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 604954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 605954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 606954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 607954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 608954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 609954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 610954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 611954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 612954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 613954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 614954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 615954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 616954Sbill 6174879Ssam /* 6184879Ssam * Logical to physical adress translation 6194879Ssam */ 6204879Ssam long 6214879Ssam trans(logical) 6224879Ssam register int logical; 623954Sbill { 624954Sbill register int sector, bytes, track; 625954Sbill 6264879Ssam logical += 26*128; 6274879Ssam bytes = (logical&127); 628954Sbill logical >>= 7; 6294879Ssam sector = logical%26; 630954Sbill if(sector >= 13) 6314879Ssam sector = sector*2+1; 632954Sbill else 633954Sbill sector *= 2; 6344879Ssam sector += 26 + ((track = (logical/26))-1)*6; 635954Sbill sector %= 26; 6369877Ssam return ((((track*26)+sector) << 7) + bytes); 637954Sbill } 6384879Ssam 6394879Ssam lread(startad, count, obuff) 6404879Ssam register startad, count; 6414879Ssam register char *obuff; 642954Sbill { 643954Sbill long trans(); 644954Sbill extern floppydes; 6454879Ssam register int size = flag(m) ? 512 : 128; 64629823Skarels int error = 0; 64729823Skarels extern int errno; 6484879Ssam 649954Sbill rt_init(); 6504879Ssam while ((count -= size) >= 0) { 65126131Sbloom (void) lseek(floppydes, flag(m) ? 6524879Ssam (long)startad : trans(startad), 0); 65329823Skarels if (read(floppydes, obuff, size) != size) { 65429823Skarels error = errno; 65529823Skarels fprintf(stderr, "arff: read error block %d: ", 6564879Ssam startad/size); 65729823Skarels errno = error; 65829823Skarels perror(""); 65929823Skarels } 6604879Ssam obuff += size; 6614879Ssam startad += size; 6624879Ssam } 66329823Skarels return (error); 664954Sbill } 6654879Ssam 6664879Ssam lwrite(startad, count, obuff) 6674879Ssam register startad, count; 6684879Ssam register char *obuff; 669954Sbill { 670954Sbill long trans(); 671954Sbill extern floppydes; 6724879Ssam register int size = flag(m) ? 512 : 128; 6734879Ssam 674954Sbill rt_init(); 6754879Ssam while ((count -= size) >= 0) { 67626131Sbloom (void) lseek(floppydes, flag(m) ? 6774879Ssam (long)startad : trans(startad), 0); 6784879Ssam if (write(floppydes, obuff, size) != size) 6794879Ssam fprintf(stderr, "arff: write error block %d\n", 6804879Ssam startad/size); 6814879Ssam obuff += size; 6824879Ssam startad += size; 6834879Ssam } 684954Sbill } 685954Sbill 686954Sbill rcmd() 687954Sbill { 688954Sbill register int i; 689954Sbill 690954Sbill rt_init(); 6914879Ssam if (namc > 0) 6924879Ssam for (i = 0; i < namc; i++) 6934879Ssam if (rtr(namv[i]) == 0) 6944879Ssam namv[i] = 0; 695954Sbill } 696954Sbill 697954Sbill rtr(name) 6984879Ssam char *name; 699954Sbill { 7004879Ssam register FLDOPE *dope; 7014879Ssam register struct rt_ent *de; 7024879Ssam struct stat buf; 7034879Ssam register struct stat *bufp = &buf; 7043346Swnj int segnum; 70526131Sbloom char type; 706954Sbill 7074879Ssam if (stat(name, bufp) < 0) { 7083489Sroot perror(name); 7099877Ssam return (-1); 7103489Sroot } 71126131Sbloom type = 'a'; 7124879Ssam if (dope = lookup(name)) { 713954Sbill /* can replace, no problem */ 714954Sbill de = dope->rtdope; 71526131Sbloom if (bufp->st_size <= (de->rt_len * 512)) { 71626131Sbloom printf("r - %s\n",name); 7174879Ssam toflop(name, bufp->st_size, dope); 71826131Sbloom goto found; 71926131Sbloom } else { 72026131Sbloom de = dope->rtdope; 72126131Sbloom type = 'r'; 72226131Sbloom de->rt_stat = RT_NULL; 72326131Sbloom de->rt_name[0] = 0; 72426131Sbloom de->rt_name[1] = 0; 72526131Sbloom de->rt_name[2] = 0; 72626131Sbloom *((u_short *)&(de->rt_date)) = 0; 72726131Sbloom scrunch(); 728954Sbill } 7299877Ssam } 7309877Ssam /* 7319877Ssam * Search for vacant spot 7329877Ssam */ 7339877Ssam for (segnum = 0; segnum != -1; 73426131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 7359877Ssam { 7369877Ssam for (de = rt_dir[segnum].rt_ents; 7379877Ssam rt(de)->rt_stat != RT_ESEG; de++) 7389877Ssam if ((de)->rt_stat == RT_NULL) { 7399877Ssam if (bufp->st_size <= (de->rt_len*512)) { 74026131Sbloom printf("%c - %s\n", type, name), 7419877Ssam mkent(de, segnum, bufp,name); 7429877Ssam goto found; 743954Sbill } 7449877Ssam continue; 7459877Ssam } 746954Sbill } 74730998Sbostic if (type == 'r') 74826131Sbloom printf("%s: no slot for file, file deleted\n",name); 74926131Sbloom else 75026131Sbloom printf("%s: no slot for file\n", name); 7519877Ssam return (-1); 7524879Ssam 7534879Ssam found: 7544879Ssam if (dope = lookup(name)) { 7554879Ssam toflop(name, bufp->st_size, dope); 7563489Sroot return (0); 757954Sbill } 7583489Sroot printf("%s: internal error, added then not found\n", name); 7593489Sroot return (-1); 7604879Ssam } 761954Sbill 7624879Ssam mkent(de, segnum, bufp, name) 7634879Ssam register struct rt_ent *de; 7644879Ssam int segnum; 7654879Ssam register struct stat *bufp; 7664879Ssam char *name; 767954Sbill { 7684879Ssam struct tm *localtime(); 7694879Ssam register struct tm *timp; 7704879Ssam register struct rt_ent *workp; 7714879Ssam int count; 772954Sbill 773954Sbill count = (((bufp->st_size -1) >>9) + 1); 7744879Ssam /* make sure there is room */ 7754879Ssam if (de->rt_len == count) 776954Sbill goto overwrite; 7774879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 77826131Sbloom /* no entries left on segment, trying adding new segment */ 77926131Sbloom if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { 78026131Sbloom short newseg; 78126131Sbloom register int i; 78226131Sbloom int maxseg; 78326131Sbloom short size; 78426131Sbloom 78526131Sbloom newseg = rt_dir[0].rd_lstseg++; 78626131Sbloom rt_dir[newseg] = rt_nulldir; 78726131Sbloom rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; 78826131Sbloom rt_dir[segnum].rd_nxtseg = newseg + 1; 78926131Sbloom rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; 79026131Sbloom rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; 79126131Sbloom size = 0; 79226131Sbloom maxseg = 0; 79326131Sbloom for(i = newseg - 1; i >= 0; i--) { 79426131Sbloom workp = rt_curend[i] - 1; 79526131Sbloom if (workp->rt_stat != RT_NULL) 79626131Sbloom continue; 79726131Sbloom if (workp->rt_len < size) 79826131Sbloom continue; 79926131Sbloom size = workp->rt_len; 80026131Sbloom maxseg = i; 80126131Sbloom } 80226131Sbloom size = 0; 80326131Sbloom for (workp = &rt_dir[maxseg].rt_ents[0]; 80426131Sbloom workp->rt_stat != RT_ESEG; workp++) { 80526131Sbloom size += workp->rt_len; 80626131Sbloom } 80726131Sbloom workp--; 80826131Sbloom rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; 80926131Sbloom rt_dir[newseg].rd_stfile = 81026131Sbloom rt_dir[maxseg].rd_stfile + size - workp->rt_len; 81126131Sbloom workp->rt_len = 0; 81226131Sbloom rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; 81326131Sbloom lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 81426131Sbloom if (segnum != 0) 81526131Sbloom lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 81626131Sbloom (char *)&rt_dir[segnum]); 81726131Sbloom lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, 81826131Sbloom (char *)&rt_dir[newseg]); 81926131Sbloom segnum = newseg; 82026131Sbloom de = &rt_dir[newseg].rt_ents[0]; 82126131Sbloom } else { 82226131Sbloom fprintf(stderr, "All directory segments full on %s\n", 82326131Sbloom defdev); 82426131Sbloom exit(1); 82526131Sbloom } 826954Sbill } 8274879Ssam /* copy directory entries up */ 8284879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 829954Sbill *workp = workp[-1]; 830954Sbill de[1].rt_len -= count; 831954Sbill de->rt_len = count; 8323346Swnj rt_curend[segnum]++; 833954Sbill rt_nleft--; 8344879Ssam 835954Sbill overwrite: 836954Sbill srad50(name,de->rt_name); 837954Sbill timp = localtime(&bufp->st_mtime); 8387320Swnj de->rt_date.rt_dy = timp->tm_mday; 839954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 840954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 841954Sbill de->rt_stat = RT_FILE; 842954Sbill de->rt_pad = 0; 843954Sbill de->rt_chan = 0; 844954Sbill de->rt_job = 0; 8454879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 846954Sbill } 847954Sbill 8484879Ssam toflop(name, ocount, dope) 8494879Ssam char *name; 8504879Ssam register FLDOPE *dope; 8514879Ssam long ocount; 852954Sbill { 853954Sbill register file, n, startad = dope->startad, count = ocount; 854954Sbill char buff[512]; 855954Sbill 8564879Ssam file = open(name, 0); 8574879Ssam if (file < 0) { 8584879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 8594879Ssam exit(1); 8604879Ssam } 861954Sbill for( ; count >= 512; count -= 512) { 86226131Sbloom (void) read(file, buff, 512); 8634879Ssam lwrite(startad, 512, buff); 864954Sbill startad += 512; 865954Sbill } 86626131Sbloom (void) read(file, buff, count); 86726131Sbloom (void) close(file); 8684879Ssam if (count <= 0) 8694879Ssam return; 8704879Ssam for (n = count; n < 512; n ++) 8714879Ssam buff[n] = 0; 8724879Ssam lwrite(startad, 512, buff); 8734879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 8744879Ssam if (count <= 0) 8754879Ssam return; 8764879Ssam for ( ; count > 0 ; count--) { 877954Sbill startad += 512; 8784879Ssam lwrite(startad, 512, zeroes); 879954Sbill } 8804879Ssam } 881954Sbill 882954Sbill dcmd() 883954Sbill { 884954Sbill register int i; 885954Sbill 886954Sbill rt_init(); 8874879Ssam if (namc) 8884879Ssam for (i = 0; i < namc; i++) 8894879Ssam if (rtk(namv[i])==0) 8904879Ssam namv[i]=0; 8914879Ssam if (dirdirty) 892954Sbill scrunch(); 893954Sbill } 8944879Ssam 895954Sbill rtk(name) 8964879Ssam char *name; 897954Sbill { 898954Sbill register FLDOPE *dope; 899954Sbill register struct rt_ent *de; 900954Sbill FLDOPE *lookup(); 901954Sbill 9024879Ssam if (dope = lookup(name)) { 903954Sbill printf("d - %s\n",name); 904954Sbill de = dope->rtdope; 905954Sbill de->rt_stat = RT_NULL; 906954Sbill de->rt_name[0] = 0; 907954Sbill de->rt_name[1] = 0; 908954Sbill de->rt_name[2] = 0; 9099877Ssam *((u_short *)&(de->rt_date)) = 0; 910954Sbill dirdirty = 1; 9119877Ssam return (0); 912954Sbill } 9139877Ssam return (1); 914954Sbill } 9154879Ssam 9164879Ssam scrunch() 9174879Ssam { 9183346Swnj register struct rt_ent *de , *workp; 9193346Swnj register segnum; 9204879Ssam 9214879Ssam for (segnum = 0; segnum != -1; 92226131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 9234879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 9249877Ssam if (de->rt_stat == RT_NULL && 92512012Shelge (de+1)->rt_stat == RT_NULL) { 9264879Ssam (de+1)->rt_len += de->rt_len; 92712012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 9284879Ssam *workp = workp[1]; 9294879Ssam de--; 9304879Ssam rt_curend[segnum]--; 9314879Ssam rt_nleft++; 9324879Ssam } 93312012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 93412012Shelge (char *)&rt_dir[segnum]); 935954Sbill } 93612012Shelge dirdirty = 0; 937954Sbill } 938