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*33133Sbostic static char sccsid[] = "@(#)arff.c 5.6 (Berkeley) 12/26/87"; 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 */ 3830238Sbostic u_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 */ 4130238Sbostic u_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 4930238Sbostic #define RT_PFILE (0200|RT_FILE) /* protected file */ 504879Ssam #define RT_ESEG 8 514879Ssam 524879Ssam #define RT_BLOCK 512 /* block size */ 534879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 544879Ssam 55954Sbill struct rt_head { 564879Ssam short rt_numseg; /* # of segments available */ 574879Ssam short rt_nxtseg; /* # of next logical segment */ 584879Ssam short rt_lstseg; /* highest seg currently open */ 594879Ssam u_short rt_entpad; /* extra words/directory entry */ 604879Ssam short rt_stfile; /* block # where files begin */ 61954Sbill }; 624879Ssam 63954Sbill struct rt_dir { 64954Sbill struct rt_head rt_axhead; 65954Sbill struct rt_ent rt_ents[72]; 664879Ssam char _dirpad[6]; 67954Sbill }; 684879Ssam 6926131Sbloom #define rd_numseg rt_axhead.rt_numseg 7026131Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg 7126131Sbloom #define rd_lstseg rt_axhead.rt_lstseg 7226131Sbloom #define rd_entpad rt_axhead.rt_entpad 7326131Sbloom #define rd_stfile rt_axhead.rt_stfile 7426131Sbloom 75954Sbill typedef struct fldope { 76954Sbill int startad; 77954Sbill int count; 78954Sbill struct rt_ent *rtdope; 79954Sbill } FLDOPE; 804879Ssam 81954Sbill FLDOPE *lookup(); 824879Ssam 839877Ssam #define rt(p) ((struct rt_ent *) p ) 849877Ssam #define Ain1 03100 859877Ssam #define Ain2 050 869877Ssam #define flag(c) (flg[('c') - 'a']) 87954Sbill 889877Ssam char *man = "rxtd"; 899877Ssam char zeroes[512]; 90954Sbill 91954Sbill extern char *val; 92954Sbill extern char table[256]; 934879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 94*33133Sbostic { 959877Ssam { 4, 0, 1, 0, 14 }, 9626131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, 979877Ssam { 0, RT_ESEG } } 98*33133Sbostic } 994879Ssam }; 100954Sbill 10126131Sbloom struct rt_dir rt_nulldir = { 10226131Sbloom { 0, 0, 0, 0, 0 }, 10326131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, 10426131Sbloom { 0, RT_ESEG } } 10526131Sbloom }; 10626131Sbloom 1074879Ssam int rt_entsiz; 1084879Ssam int rt_nleft; 1094879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 1104879Ssam int floppydes; 1114879Ssam int dirdirty; 1124879Ssam char *rt_last; 1134879Ssam char *defdev = "/dev/floppy"; 114954Sbill 11526131Sbloom char *opt = "vfbcm"; 1164879Ssam 1174879Ssam extern long lseek(); 1184879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 1194879Ssam 120954Sbill int (*comfun)(); 121954Sbill char flg[26]; 122954Sbill char **namv; 123954Sbill int namc; 124954Sbill 125954Sbill main(argc, argv) 1264879Ssam char *argv[]; 127954Sbill { 128954Sbill register char *cp; 129954Sbill 1304879Ssam if (argc < 2) 131954Sbill usage(); 1324879Ssam for (cp = argv[1]; *cp; cp++) 1334879Ssam switch (*cp) { 134954Sbill 1354879Ssam case 'm': 1364879Ssam case 'v': 1374879Ssam case 'u': 1384879Ssam case 'w': 13926131Sbloom case 'b': 1404879Ssam flg[*cp-'a']++; 1414879Ssam continue; 1424879Ssam case 'c': 14313910Ssam flag(c)++; 1444879Ssam dirdirty++; 1454879Ssam continue; 146954Sbill 1474879Ssam case 'r': 1484879Ssam setcom(rcmd); 1494879Ssam flag(r)++; 1504879Ssam continue; 151954Sbill 1524879Ssam case 'd': 1534879Ssam setcom(dcmd); 1544879Ssam flag(d)++; 1554879Ssam continue; 156954Sbill 1574879Ssam case 'x': 1584879Ssam setcom(xcmd); 1594879Ssam continue; 160954Sbill 1614879Ssam case 't': 1624879Ssam setcom(tcmd); 1634879Ssam continue; 164954Sbill 1654879Ssam case 'f': 1664879Ssam defdev = argv[2]; 1674879Ssam argv++; 1684879Ssam argc--; 1694879Ssam continue; 1704879Ssam 1714879Ssam default: 1724879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1734879Ssam exit(1); 1744879Ssam } 1754879Ssam 176954Sbill namv = argv+2; 177954Sbill namc = argc-2; 1784879Ssam if (comfun == 0) { 1794879Ssam if (flag(u) == 0) { 1804879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1814879Ssam man); 182954Sbill exit(1); 183954Sbill } 184954Sbill setcom(rcmd); 185954Sbill } 186954Sbill (*comfun)(); 187954Sbill exit(notfound()); 188954Sbill } 189954Sbill 190954Sbill setcom(fun) 1914879Ssam int (*fun)(); 192954Sbill { 1934879Ssam if (comfun != 0) { 194954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 195954Sbill exit(1); 196954Sbill } 197954Sbill comfun = fun; 198954Sbill } 199954Sbill 200954Sbill usage() 201954Sbill { 2023356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 203954Sbill exit(1); 204954Sbill } 205954Sbill 206954Sbill notfound() 207954Sbill { 2084879Ssam register i, n = 0; 209954Sbill 2104879Ssam for (i = 0; i < namc; i++) 2114879Ssam if (namv[i]) { 212954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 213954Sbill n++; 214954Sbill } 2159877Ssam return (n); 216954Sbill } 217954Sbill 218954Sbill tcmd() 219954Sbill { 2204879Ssam register char *de, *last; 221954Sbill FLDOPE *lookup(), *dope; 2224879Ssam int segnum, nleft; 2234879Ssam register i; 224954Sbill register struct rt_ent *rde; 225954Sbill 226954Sbill rt_init(); 2279877Ssam if (namc != 0) { 2284879Ssam for (i = 0; i < namc; i++) 2294879Ssam if (dope = lookup(namv[i])) { 230954Sbill rde = dope->rtdope; 23126131Sbloom (void) rtls(rde); 232954Sbill namv[i] = 0; 233954Sbill } 2349877Ssam return; 2359877Ssam } 2369877Ssam for (segnum = 0; segnum != -1; 23726131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 2389877Ssam last = rt_last + segnum*2*RT_BLOCK; 2399877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2409877Ssam de += rt_entsiz) 2419877Ssam if (rtls(rt(de))) { 2429877Ssam nleft = (last-de)/rt_entsiz; 2439877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2449877Ssam printf(ENTRIES, nleft, segnum+1); 2459877Ssam break; 2469877Ssam } 2479877Ssam } 248954Sbill } 2494879Ssam 250954Sbill rtls(de) 2514879Ssam register struct rt_ent *de; 252954Sbill { 2534879Ssam int month, day, year; 254954Sbill char name[12], ext[4]; 255954Sbill 2564879Ssam switch (de->rt_stat) { 2574879Ssam 2584879Ssam case RT_TEMP: 2594879Ssam if (flag(v)) 260954Sbill printf("Tempfile:\n"); 2614879Ssam /* fall thru...*/ 262954Sbill 2634879Ssam case RT_FILE: 26430238Sbostic case RT_PFILE: 2654879Ssam if (!flag(v)) { 2664879Ssam sunrad50(name, de->rt_name); 2674879Ssam printf("%s\n", name); 268954Sbill break; 269954Sbill } 2704879Ssam unrad50(2, de->rt_name, name); 2714879Ssam unrad50(1, &(de->rt_name[2]), ext); 2724879Ssam day = de->rt_date.rt_dy; 2734879Ssam year = de->rt_date.rt_yr+72; 2744879Ssam month = de->rt_date.rt_mo; 2754879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2764879Ssam ext, month, day, year, de->rt_len); 2774879Ssam break; 278954Sbill 2794879Ssam case RT_NULL: 2804879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2814879Ssam break; 282954Sbill 2834879Ssam case RT_ESEG: 2849877Ssam return (1); 285954Sbill } 2869877Ssam return (0); 287954Sbill } 2884879Ssam 289954Sbill xcmd() 290954Sbill { 2914879Ssam register char *de, *last; 2923346Swnj int segnum; 293954Sbill char name[12]; 294954Sbill register int i; 295954Sbill 296954Sbill rt_init(); 2979877Ssam if (namc != 0) { 2984879Ssam for (i = 0; i < namc; i++) 2994879Ssam if (rtx(namv[i]) == 0) 3004879Ssam namv[i] = 0; 3019877Ssam return; 3029877Ssam } 3039877Ssam for (segnum = 0; segnum != -1; 30426131Sbloom segnum = rt_dir[segnum].rd_nxtseg-1) 3059877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 3069877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 30715553Sralph de += rt_entsiz) { 3089877Ssam switch (rt(de)->rt_stat) { 3099877Ssam 3109877Ssam case RT_ESEG: 31115553Sralph break; /* exit loop and try next segment */ 3129877Ssam 3139877Ssam case RT_TEMP: 3149877Ssam case RT_FILE: 31530238Sbostic case RT_PFILE: 3169877Ssam sunrad50(name,rt(de)->rt_name); 31726131Sbloom (void) rtx(name); 3189877Ssam 3199877Ssam case RT_NULL: 32015553Sralph default: 32115553Sralph continue; 3229877Ssam } 32315553Sralph break; 32415553Sralph } 325954Sbill } 3264879Ssam 327954Sbill rtx(name) 3284879Ssam char *name; 329954Sbill { 330954Sbill register FLDOPE *dope; 331954Sbill FLDOPE *lookup(); 332954Sbill register startad, count; 3334879Ssam int file; 3344879Ssam char buff[512]; 335954Sbill 336954Sbill 3374879Ssam if (dope = lookup(name)) { 3384879Ssam if (flag(v)) 33926131Sbloom (void) rtls(dope->rtdope); 340954Sbill else 341954Sbill printf("x - %s\n",name); 342954Sbill 3434879Ssam if ((file = creat(name, 0666)) < 0) 3449877Ssam return (1); 345954Sbill count = dope->count; 346954Sbill startad = dope->startad; 347954Sbill for( ; count > 0 ; count -= 512) { 34829823Skarels (void) lread(startad, 512, buff); 34926131Sbloom (void) write(file, buff, 512); 350954Sbill startad += 512; 351954Sbill } 35226131Sbloom (void) close(file); 3539877Ssam return (0); 354954Sbill } 3559877Ssam return (1); 356954Sbill } 3574879Ssam 358954Sbill rt_init() 359954Sbill { 360954Sbill static initized = 0; 3614879Ssam register char *de, *last; 3623346Swnj register i; 3633799Shickman int dirnum; 3643799Shickman char *mode; 3653799Shickman FILE *temp_floppydes; 366954Sbill 3674879Ssam if (initized) 3684879Ssam return; 369954Sbill initized = 1; 37013910Ssam if (flag(c)) { 37113910Ssam struct stat sb; 37213910Ssam char response[128]; 37313910Ssam int tty; 37413910Ssam 37513910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 37613910Ssam goto ignore; 37713910Ssam tty = open("/dev/tty", O_RDWR); 37813910Ssam #define SURE "Are you sure you want to clobber the floppy? " 37926131Sbloom (void) write(tty, SURE, sizeof (SURE)); 38026131Sbloom (void) read(tty, response, sizeof (response)); 38113910Ssam if (*response != 'y') 38213910Ssam exit(50); 38326131Sbloom (void) close(tty); 38413910Ssam ignore: 38513910Ssam ; 38613910Ssam } 3874879Ssam if (flag(c) || flag(d) || flag(r)) 3883799Shickman mode = "r+"; 389954Sbill else 3903799Shickman mode = "r"; 3914879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3923799Shickman perror(defdev); 3933356Swnj exit(1); 3943799Shickman } else 3953799Shickman floppydes = fileno(temp_floppydes); 3964879Ssam if (!flag(c)) { 39729823Skarels if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0])) 39829823Skarels exit(2); 39926131Sbloom dirnum = rt_dir[0].rd_numseg; 40012012Shelge /* check for blank/uninitialized diskette */ 40112012Shelge if (dirnum <= 0) { 40212012Shelge fprintf(stderr,"arff: bad directory format\n"); 40312012Shelge exit(1); 40412012Shelge } 4053346Swnj if (dirnum > RT_DIRSIZE) { 4064879Ssam fprintf(stderr,"arff: too many directory segments\n"); 4074879Ssam exit(1); 4083346Swnj } 4094879Ssam for (i = 1; i < dirnum; i++) 41029823Skarels if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i])) 41129823Skarels exit(1); 41226131Sbloom } else { 4133489Sroot dirnum = 1; 41426131Sbloom if (flag(b)) { 41526131Sbloom rt_dir[0].rd_numseg = 31; 41626131Sbloom rt_dir[0].rd_stfile = 68; 41726131Sbloom rt_dir[0].rt_ents[0].rt_len = 20480 - 68; 41826131Sbloom } 41926131Sbloom } 420954Sbill 42126131Sbloom rt_entsiz = 2*rt_dir[0].rd_entpad + 14; 42226131Sbloom /* 42326131Sbloom * We assume that the directory entries have no padding. This 42426131Sbloom * may not be a valid assumption, but there are numerous point 42526131Sbloom * in the code where it assumes it is an rt_ent structure and 42626131Sbloom * not an rt_entsiz sized structure. 42726131Sbloom */ 42826131Sbloom rt_entsiz = 14; 4293346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 4303346Swnj rt_nleft = 0; 4313346Swnj 4324879Ssam for (i = 0; i < dirnum; i++) { 4334879Ssam last = rt_last + i*2*RT_BLOCK; 4344879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 4354879Ssam if (rt(de)->rt_stat == RT_ESEG) 4364879Ssam break; 4374879Ssam rt_curend[i] = rt(de); 4384879Ssam rt_nleft += (last-de)/rt_entsiz; 439954Sbill } 440954Sbill } 441954Sbill 442954Sbill static FLDOPE result; 4434879Ssam 444954Sbill FLDOPE * 445954Sbill lookup(name) 4464879Ssam char *name; 447954Sbill { 448954Sbill unsigned short rname[3]; 44926131Sbloom register char *de; 4503346Swnj int segnum; 451954Sbill register index; 452954Sbill 453954Sbill srad50(name,rname); 454954Sbill 4553356Swnj /* 456954Sbill * Search for name, accumulate blocks in index 457954Sbill */ 458954Sbill rt_init(); 4594879Ssam for (segnum = 0; segnum != -1; 46026131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 4614879Ssam { 4624879Ssam index = 0; 4634879Ssam for (de=((char *)&rt_dir[segnum])+10; 4644879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4654879Ssam switch(rt(de)->rt_stat) { 4664879Ssam 4674879Ssam case RT_FILE: 46830238Sbostic case RT_PFILE: 4694879Ssam case RT_TEMP: 4704879Ssam if(samename(rname,rt(de)->rt_name)) { 4714879Ssam result.count = rt(de)->rt_len * 512; 4724879Ssam result.startad = 512* 47326131Sbloom (rt_dir[segnum].rd_stfile + index); 4744879Ssam result.rtdope = (struct rt_ent *) de; 4759877Ssam return (&result); 4764879Ssam } 4774879Ssam 4784879Ssam case RT_NULL: 4794879Ssam index += rt(de)->rt_len; 4804879Ssam } 4813346Swnj } 4829877Ssam return ((FLDOPE *) 0); 4834879Ssam 484954Sbill } 4854879Ssam 486954Sbill static 4874879Ssam samename(a, b) 4884879Ssam u_short a[], b[]; 489954Sbill { 4909877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 491954Sbill } 492954Sbill 4934879Ssam rad50(cp, out) 4944879Ssam register u_char *cp; 4954879Ssam u_short *out; 496954Sbill { 4974879Ssam register index, temp; 498954Sbill 4994879Ssam for (index = 0; *cp; index++) { 500954Sbill temp = Ain1 * table[*cp++]; 5014879Ssam if (*cp!=0) { 502954Sbill temp += Ain2 * table[*cp++]; 503954Sbill if(*cp!=0) 504954Sbill temp += table[*cp++]; 505954Sbill } 506954Sbill out[index] = temp; 507954Sbill } 508954Sbill } 509954Sbill 5104879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 5114879Ssam 5124879Ssam unrad50(count, in, cp) 5134879Ssam u_short *in; 5144879Ssam register char *cp; 515954Sbill { 5164879Ssam register i, temp; 5174879Ssam register u_char *v = (u_char *) val; 518954Sbill 5194879Ssam for (i = 0; i < count; i++) { 520954Sbill temp = in[i]; 5214879Ssam reduce(*cp++, temp, Ain1); 5224879Ssam reduce(*cp++, temp, Ain2); 5234879Ssam reduce(*cp++, temp, 1); 524954Sbill } 525954Sbill *cp=0; 526954Sbill } 527954Sbill 5284879Ssam srad50(name, rname) 5294879Ssam register char *name; 5304879Ssam register u_short *rname; 531954Sbill { 5324879Ssam register index; 5334879Ssam register char *cp; 5344879Ssam char file[7], ext[4]; 5354879Ssam 5363356Swnj /* 537954Sbill * Find end of pathname 538954Sbill */ 5394879Ssam for (cp = name; *cp++; ) 5404879Ssam ; 5414879Ssam while (cp >= name && *--cp != '/') 5424879Ssam ; 543954Sbill cp++; 5443356Swnj /* 545954Sbill * Change to rad50 546954Sbill */ 5474879Ssam for (index = 0; *cp; ) { 548954Sbill file[index++] = *cp++; 5494879Ssam if (*cp == '.') { 550954Sbill cp++; 551954Sbill break; 552954Sbill } 5534879Ssam if (index >= 6) { 554954Sbill break; 555954Sbill } 556954Sbill } 557954Sbill file[index] = 0; 5584879Ssam for (index = 0; *cp; ) { 559954Sbill ext[index++] = *cp++; 5604879Ssam if (*cp == '.' || index >= 3) 561954Sbill break; 562954Sbill } 563954Sbill ext[index]=0; 5644879Ssam rname[0] = rname[1] = rname[2] = 0; 5654879Ssam rad50((u_char *)file, rname); 5664879Ssam rad50((u_char *)ext, rname+2); 567954Sbill } 5684879Ssam 5694879Ssam sunrad50(name, rname) 5704879Ssam u_short rname[]; 5714879Ssam register char *name; 572954Sbill { 573954Sbill register char *cp, *cp2; 574954Sbill char ext[4]; 575954Sbill 5764879Ssam unrad50(2, rname, name); 5774879Ssam unrad50(1, rname + 2, ext); 5784879Ssam /* 5794879Ssam * Jam name and extension together with a dot 5804879Ssam * deleting white space 5814879Ssam */ 5824879Ssam for (cp = name; *cp++;) 5834879Ssam ; 5844879Ssam --cp; 5854879Ssam while (*--cp == ' ' && cp >= name) 5864879Ssam ; 5874879Ssam *++cp = '.'; 5884879Ssam cp++; 5894879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 590954Sbill *cp++ = *cp2++; 591954Sbill *cp=0; 5924879Ssam if (cp[-1] == '.') 5934879Ssam cp[-1] = 0; 594954Sbill } 595954Sbill 596954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5974879Ssam 598954Sbill static char table[256] = { 599954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 600954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 601954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 602954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 603954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 604954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 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, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 608954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 609954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 610954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 611954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 612954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 613954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 614954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 615954Sbill 6164879Ssam /* 6174879Ssam * Logical to physical adress translation 6184879Ssam */ 6194879Ssam long 6204879Ssam trans(logical) 6214879Ssam register int logical; 622954Sbill { 623954Sbill register int sector, bytes, track; 624954Sbill 6254879Ssam logical += 26*128; 6264879Ssam bytes = (logical&127); 627954Sbill logical >>= 7; 6284879Ssam sector = logical%26; 629954Sbill if(sector >= 13) 6304879Ssam sector = sector*2+1; 631954Sbill else 632954Sbill sector *= 2; 6334879Ssam sector += 26 + ((track = (logical/26))-1)*6; 634954Sbill sector %= 26; 6359877Ssam return ((((track*26)+sector) << 7) + bytes); 636954Sbill } 6374879Ssam 6384879Ssam lread(startad, count, obuff) 6394879Ssam register startad, count; 6404879Ssam register char *obuff; 641954Sbill { 642954Sbill long trans(); 643954Sbill extern floppydes; 6444879Ssam register int size = flag(m) ? 512 : 128; 64529823Skarels int error = 0; 64629823Skarels extern int errno; 6474879Ssam 648954Sbill rt_init(); 6494879Ssam while ((count -= size) >= 0) { 65026131Sbloom (void) lseek(floppydes, flag(m) ? 6514879Ssam (long)startad : trans(startad), 0); 65229823Skarels if (read(floppydes, obuff, size) != size) { 65329823Skarels error = errno; 65429823Skarels fprintf(stderr, "arff: read error block %d: ", 6554879Ssam startad/size); 65629823Skarels errno = error; 65729823Skarels perror(""); 65829823Skarels } 6594879Ssam obuff += size; 6604879Ssam startad += size; 6614879Ssam } 66229823Skarels return (error); 663954Sbill } 6644879Ssam 6654879Ssam lwrite(startad, count, obuff) 6664879Ssam register startad, count; 6674879Ssam register char *obuff; 668954Sbill { 669954Sbill long trans(); 670954Sbill extern floppydes; 6714879Ssam register int size = flag(m) ? 512 : 128; 6724879Ssam 673954Sbill rt_init(); 6744879Ssam while ((count -= size) >= 0) { 67526131Sbloom (void) lseek(floppydes, flag(m) ? 6764879Ssam (long)startad : trans(startad), 0); 6774879Ssam if (write(floppydes, obuff, size) != size) 6784879Ssam fprintf(stderr, "arff: write error block %d\n", 6794879Ssam startad/size); 6804879Ssam obuff += size; 6814879Ssam startad += size; 6824879Ssam } 683954Sbill } 684954Sbill 685954Sbill rcmd() 686954Sbill { 687954Sbill register int i; 688954Sbill 689954Sbill rt_init(); 6904879Ssam if (namc > 0) 6914879Ssam for (i = 0; i < namc; i++) 6924879Ssam if (rtr(namv[i]) == 0) 6934879Ssam namv[i] = 0; 694954Sbill } 695954Sbill 696954Sbill rtr(name) 6974879Ssam char *name; 698954Sbill { 6994879Ssam register FLDOPE *dope; 7004879Ssam register struct rt_ent *de; 7014879Ssam struct stat buf; 7024879Ssam register struct stat *bufp = &buf; 7033346Swnj int segnum; 70426131Sbloom char type; 705954Sbill 7064879Ssam if (stat(name, bufp) < 0) { 7073489Sroot perror(name); 7089877Ssam return (-1); 7093489Sroot } 71026131Sbloom type = 'a'; 7114879Ssam if (dope = lookup(name)) { 712954Sbill /* can replace, no problem */ 713954Sbill de = dope->rtdope; 71426131Sbloom if (bufp->st_size <= (de->rt_len * 512)) { 71526131Sbloom printf("r - %s\n",name); 7164879Ssam toflop(name, bufp->st_size, dope); 71726131Sbloom goto found; 71826131Sbloom } else { 71926131Sbloom de = dope->rtdope; 72026131Sbloom type = 'r'; 72126131Sbloom de->rt_stat = RT_NULL; 72226131Sbloom de->rt_name[0] = 0; 72326131Sbloom de->rt_name[1] = 0; 72426131Sbloom de->rt_name[2] = 0; 72526131Sbloom *((u_short *)&(de->rt_date)) = 0; 72626131Sbloom scrunch(); 727954Sbill } 7289877Ssam } 7299877Ssam /* 7309877Ssam * Search for vacant spot 7319877Ssam */ 7329877Ssam for (segnum = 0; segnum != -1; 73326131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 7349877Ssam { 7359877Ssam for (de = rt_dir[segnum].rt_ents; 7369877Ssam rt(de)->rt_stat != RT_ESEG; de++) 7379877Ssam if ((de)->rt_stat == RT_NULL) { 7389877Ssam if (bufp->st_size <= (de->rt_len*512)) { 73926131Sbloom printf("%c - %s\n", type, name), 7409877Ssam mkent(de, segnum, bufp,name); 7419877Ssam goto found; 742954Sbill } 7439877Ssam continue; 7449877Ssam } 745954Sbill } 74630998Sbostic if (type == 'r') 74726131Sbloom printf("%s: no slot for file, file deleted\n",name); 74826131Sbloom else 74926131Sbloom printf("%s: no slot for file\n", name); 7509877Ssam return (-1); 7514879Ssam 7524879Ssam found: 7534879Ssam if (dope = lookup(name)) { 7544879Ssam toflop(name, bufp->st_size, dope); 7553489Sroot return (0); 756954Sbill } 7573489Sroot printf("%s: internal error, added then not found\n", name); 7583489Sroot return (-1); 7594879Ssam } 760954Sbill 7614879Ssam mkent(de, segnum, bufp, name) 7624879Ssam register struct rt_ent *de; 7634879Ssam int segnum; 7644879Ssam register struct stat *bufp; 7654879Ssam char *name; 766954Sbill { 7674879Ssam struct tm *localtime(); 7684879Ssam register struct tm *timp; 7694879Ssam register struct rt_ent *workp; 7704879Ssam int count; 771954Sbill 772954Sbill count = (((bufp->st_size -1) >>9) + 1); 7734879Ssam /* make sure there is room */ 7744879Ssam if (de->rt_len == count) 775954Sbill goto overwrite; 7764879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 77726131Sbloom /* no entries left on segment, trying adding new segment */ 77826131Sbloom if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { 77926131Sbloom short newseg; 78026131Sbloom register int i; 78126131Sbloom int maxseg; 78226131Sbloom short size; 78326131Sbloom 78426131Sbloom newseg = rt_dir[0].rd_lstseg++; 78526131Sbloom rt_dir[newseg] = rt_nulldir; 78626131Sbloom rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; 78726131Sbloom rt_dir[segnum].rd_nxtseg = newseg + 1; 78826131Sbloom rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; 78926131Sbloom rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; 79026131Sbloom size = 0; 79126131Sbloom maxseg = 0; 79226131Sbloom for(i = newseg - 1; i >= 0; i--) { 79326131Sbloom workp = rt_curend[i] - 1; 79426131Sbloom if (workp->rt_stat != RT_NULL) 79526131Sbloom continue; 79626131Sbloom if (workp->rt_len < size) 79726131Sbloom continue; 79826131Sbloom size = workp->rt_len; 79926131Sbloom maxseg = i; 80026131Sbloom } 80126131Sbloom size = 0; 80226131Sbloom for (workp = &rt_dir[maxseg].rt_ents[0]; 80326131Sbloom workp->rt_stat != RT_ESEG; workp++) { 80426131Sbloom size += workp->rt_len; 80526131Sbloom } 80626131Sbloom workp--; 80726131Sbloom rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; 80826131Sbloom rt_dir[newseg].rd_stfile = 80926131Sbloom rt_dir[maxseg].rd_stfile + size - workp->rt_len; 81026131Sbloom workp->rt_len = 0; 81126131Sbloom rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; 81226131Sbloom lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 81326131Sbloom if (segnum != 0) 81426131Sbloom lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 81526131Sbloom (char *)&rt_dir[segnum]); 81626131Sbloom lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, 81726131Sbloom (char *)&rt_dir[newseg]); 81826131Sbloom segnum = newseg; 81926131Sbloom de = &rt_dir[newseg].rt_ents[0]; 82026131Sbloom } else { 82126131Sbloom fprintf(stderr, "All directory segments full on %s\n", 82226131Sbloom defdev); 82326131Sbloom exit(1); 82426131Sbloom } 825954Sbill } 8264879Ssam /* copy directory entries up */ 8274879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 828954Sbill *workp = workp[-1]; 829954Sbill de[1].rt_len -= count; 830954Sbill de->rt_len = count; 8313346Swnj rt_curend[segnum]++; 832954Sbill rt_nleft--; 8334879Ssam 834954Sbill overwrite: 835954Sbill srad50(name,de->rt_name); 836954Sbill timp = localtime(&bufp->st_mtime); 8377320Swnj de->rt_date.rt_dy = timp->tm_mday; 838954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 839954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 840954Sbill de->rt_stat = RT_FILE; 841954Sbill de->rt_pad = 0; 842954Sbill de->rt_chan = 0; 843954Sbill de->rt_job = 0; 8444879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 845954Sbill } 846954Sbill 8474879Ssam toflop(name, ocount, dope) 8484879Ssam char *name; 8494879Ssam register FLDOPE *dope; 8504879Ssam long ocount; 851954Sbill { 852954Sbill register file, n, startad = dope->startad, count = ocount; 853954Sbill char buff[512]; 854954Sbill 8554879Ssam file = open(name, 0); 8564879Ssam if (file < 0) { 8574879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 8584879Ssam exit(1); 8594879Ssam } 860954Sbill for( ; count >= 512; count -= 512) { 86126131Sbloom (void) read(file, buff, 512); 8624879Ssam lwrite(startad, 512, buff); 863954Sbill startad += 512; 864954Sbill } 86526131Sbloom (void) read(file, buff, count); 86626131Sbloom (void) close(file); 8674879Ssam if (count <= 0) 8684879Ssam return; 8694879Ssam for (n = count; n < 512; n ++) 8704879Ssam buff[n] = 0; 8714879Ssam lwrite(startad, 512, buff); 8724879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 8734879Ssam if (count <= 0) 8744879Ssam return; 8754879Ssam for ( ; count > 0 ; count--) { 876954Sbill startad += 512; 8774879Ssam lwrite(startad, 512, zeroes); 878954Sbill } 8794879Ssam } 880954Sbill 881954Sbill dcmd() 882954Sbill { 883954Sbill register int i; 884954Sbill 885954Sbill rt_init(); 8864879Ssam if (namc) 8874879Ssam for (i = 0; i < namc; i++) 8884879Ssam if (rtk(namv[i])==0) 8894879Ssam namv[i]=0; 8904879Ssam if (dirdirty) 891954Sbill scrunch(); 892954Sbill } 8934879Ssam 894954Sbill rtk(name) 8954879Ssam char *name; 896954Sbill { 897954Sbill register FLDOPE *dope; 898954Sbill register struct rt_ent *de; 899954Sbill FLDOPE *lookup(); 900954Sbill 9014879Ssam if (dope = lookup(name)) { 902954Sbill printf("d - %s\n",name); 903954Sbill de = dope->rtdope; 904954Sbill de->rt_stat = RT_NULL; 905954Sbill de->rt_name[0] = 0; 906954Sbill de->rt_name[1] = 0; 907954Sbill de->rt_name[2] = 0; 9089877Ssam *((u_short *)&(de->rt_date)) = 0; 909954Sbill dirdirty = 1; 9109877Ssam return (0); 911954Sbill } 9129877Ssam return (1); 913954Sbill } 9144879Ssam 9154879Ssam scrunch() 9164879Ssam { 9173346Swnj register struct rt_ent *de , *workp; 9183346Swnj register segnum; 9194879Ssam 9204879Ssam for (segnum = 0; segnum != -1; 92126131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 9224879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 9239877Ssam if (de->rt_stat == RT_NULL && 92412012Shelge (de+1)->rt_stat == RT_NULL) { 9254879Ssam (de+1)->rt_len += de->rt_len; 92612012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 9274879Ssam *workp = workp[1]; 9284879Ssam de--; 9294879Ssam rt_curend[segnum]--; 9304879Ssam rt_nleft++; 9314879Ssam } 93212012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 93312012Shelge (char *)&rt_dir[segnum]); 934954Sbill } 93512012Shelge dirdirty = 0; 936954Sbill } 937