19877Ssam #ifndef lint 2*13910Ssam static char sccsid[] = "@(#)arff.c 4.16 (Berkeley) 83/07/10"; 39877Ssam #endif 44879Ssam 5954Sbill #include <sys/types.h> 6954Sbill #include <sys/stat.h> 713605Ssam #include <sys/time.h> 8954Sbill #include <signal.h> 9954Sbill #include <stdio.h> 10*13910Ssam #include <sys/file.h> 114879Ssam 12954Sbill #define dbprintf printf 134879Ssam 14954Sbill struct rt_dat { 154879Ssam u_short rt_yr:5; /* year-1972 */ 164879Ssam u_short rt_dy:5; /* day */ 174879Ssam u_short rt_mo:5; /* month */ 18954Sbill }; 194879Ssam 20954Sbill struct rt_axent { 21954Sbill char rt_sent[14]; 22954Sbill }; 23954Sbill 24954Sbill struct rt_ent { 254879Ssam char rt_pad; /* unusued */ 264879Ssam char rt_stat; /* type of entry, or end of seg */ 274879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 287319Swnj u_short rt_len; /* length of file */ 294879Ssam char rt_chan; /* only used in temporary files */ 304879Ssam char rt_job; /* only used in temporary files */ 319877Ssam struct rt_dat rt_date; /* creation date */ 32954Sbill }; 334879Ssam 344879Ssam #define RT_TEMP 1 354879Ssam #define RT_NULL 2 364879Ssam #define RT_FILE 4 374879Ssam #define RT_ESEG 8 384879Ssam 394879Ssam #define RT_BLOCK 512 /* block size */ 404879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 414879Ssam 42954Sbill struct rt_head { 434879Ssam short rt_numseg; /* # of segments available */ 444879Ssam short rt_nxtseg; /* # of next logical segment */ 454879Ssam short rt_lstseg; /* highest seg currently open */ 464879Ssam u_short rt_entpad; /* extra words/directory entry */ 474879Ssam short rt_stfile; /* block # where files begin */ 48954Sbill }; 494879Ssam 50954Sbill struct rt_dir { 51954Sbill struct rt_head rt_axhead; 52954Sbill struct rt_ent rt_ents[72]; 534879Ssam char _dirpad[6]; 54954Sbill }; 554879Ssam 56954Sbill typedef struct fldope { 57954Sbill int startad; 58954Sbill int count; 59954Sbill struct rt_ent *rtdope; 60954Sbill } FLDOPE; 614879Ssam 62954Sbill FLDOPE *lookup(); 634879Ssam 649877Ssam #define rt(p) ((struct rt_ent *) p ) 659877Ssam #define Ain1 03100 669877Ssam #define Ain2 050 679877Ssam #define flag(c) (flg[('c') - 'a']) 68954Sbill 699877Ssam char *man = "rxtd"; 709877Ssam char zeroes[512]; 71954Sbill 72954Sbill extern char *val; 73954Sbill extern char table[256]; 744879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 759877Ssam { 4, 0, 1, 0, 14 }, 769877Ssam { { 0, RT_NULL, { 0, 0, 0 }, 494, 0 }, 779877Ssam { 0, RT_ESEG } } 784879Ssam }; 79954Sbill 804879Ssam int rt_entsiz; 814879Ssam int rt_nleft; 824879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 834879Ssam int floppydes; 844879Ssam int dirdirty; 854879Ssam char *rt_last; 864879Ssam char *defdev = "/dev/floppy"; 87954Sbill 884879Ssam char *opt = "vf"; 894879Ssam 90954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 914879Ssam extern long lseek(); 924879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 934879Ssam 94954Sbill int (*comfun)(); 95954Sbill char flg[26]; 96954Sbill char **namv; 97954Sbill int namc; 98954Sbill int file; 99954Sbill 100954Sbill main(argc, argv) 1014879Ssam char *argv[]; 102954Sbill { 103954Sbill register char *cp; 104954Sbill 1054879Ssam if (argc < 2) 106954Sbill usage(); 1074879Ssam for (cp = argv[1]; *cp; cp++) 1084879Ssam switch (*cp) { 109954Sbill 1104879Ssam case 'm': 1114879Ssam case 'v': 1124879Ssam case 'u': 1134879Ssam case 'w': 1144879Ssam flg[*cp-'a']++; 1154879Ssam continue; 1164879Ssam case 'c': 117*13910Ssam flag(c)++; 1184879Ssam dirdirty++; 1194879Ssam continue; 120954Sbill 1214879Ssam case 'r': 1224879Ssam setcom(rcmd); 1234879Ssam flag(r)++; 1244879Ssam continue; 125954Sbill 1264879Ssam case 'd': 1274879Ssam setcom(dcmd); 1284879Ssam flag(d)++; 1294879Ssam continue; 130954Sbill 1314879Ssam case 'x': 1324879Ssam setcom(xcmd); 1334879Ssam continue; 134954Sbill 1354879Ssam case 't': 1364879Ssam setcom(tcmd); 1374879Ssam continue; 138954Sbill 1394879Ssam case 'f': 1404879Ssam defdev = argv[2]; 1414879Ssam argv++; 1424879Ssam argc--; 1434879Ssam continue; 1444879Ssam 1454879Ssam default: 1464879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1474879Ssam exit(1); 1484879Ssam } 1494879Ssam 150954Sbill namv = argv+2; 151954Sbill namc = argc-2; 1524879Ssam if (comfun == 0) { 1534879Ssam if (flag(u) == 0) { 1544879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1554879Ssam man); 156954Sbill exit(1); 157954Sbill } 158954Sbill setcom(rcmd); 159954Sbill } 160954Sbill (*comfun)(); 161954Sbill exit(notfound()); 162954Sbill } 163954Sbill 164954Sbill setcom(fun) 1654879Ssam int (*fun)(); 166954Sbill { 1674879Ssam if (comfun != 0) { 168954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 169954Sbill exit(1); 170954Sbill } 171954Sbill comfun = fun; 172954Sbill } 173954Sbill 174954Sbill usage() 175954Sbill { 1763356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 177954Sbill exit(1); 178954Sbill } 179954Sbill 180954Sbill notfound() 181954Sbill { 1824879Ssam register i, n = 0; 183954Sbill 1844879Ssam for (i = 0; i < namc; i++) 1854879Ssam if (namv[i]) { 186954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 187954Sbill n++; 188954Sbill } 1899877Ssam return (n); 190954Sbill } 191954Sbill 192954Sbill mesg(c) 193954Sbill { 1944879Ssam if (flag(v)) 1954879Ssam if (c != 'c' || flag(v) > 1) 196954Sbill printf("%c - %s\n", c, file); 197954Sbill } 198954Sbill 199954Sbill tcmd() 200954Sbill { 2014879Ssam register char *de, *last; 202954Sbill FLDOPE *lookup(), *dope; 2034879Ssam int segnum, nleft; 2044879Ssam register i; 205954Sbill register struct rt_ent *rde; 206954Sbill 207954Sbill rt_init(); 2089877Ssam if (namc != 0) { 2094879Ssam for (i = 0; i < namc; i++) 2104879Ssam if (dope = lookup(namv[i])) { 211954Sbill rde = dope->rtdope; 212954Sbill rtls(rde); 213954Sbill namv[i] = 0; 214954Sbill } 2159877Ssam return; 2169877Ssam } 2179877Ssam for (segnum = 0; segnum != -1; 2189877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 2199877Ssam last = rt_last + segnum*2*RT_BLOCK; 2209877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2219877Ssam de += rt_entsiz) 2229877Ssam if (rtls(rt(de))) { 2239877Ssam nleft = (last-de)/rt_entsiz; 2249877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2259877Ssam printf(ENTRIES, nleft, segnum+1); 2269877Ssam break; 2279877Ssam } 2289877Ssam } 229954Sbill } 2304879Ssam 231954Sbill rtls(de) 2324879Ssam register struct rt_ent *de; 233954Sbill { 2344879Ssam int month, day, year; 235954Sbill char name[12], ext[4]; 236954Sbill 2374879Ssam switch (de->rt_stat) { 2384879Ssam 2394879Ssam case RT_TEMP: 2404879Ssam if (flag(v)) 241954Sbill printf("Tempfile:\n"); 2424879Ssam /* fall thru...*/ 243954Sbill 2444879Ssam case RT_FILE: 2454879Ssam if (!flag(v)) { 2464879Ssam sunrad50(name, de->rt_name); 2474879Ssam printf("%s\n", name); 248954Sbill break; 249954Sbill } 2504879Ssam unrad50(2, de->rt_name, name); 2514879Ssam unrad50(1, &(de->rt_name[2]), ext); 2524879Ssam day = de->rt_date.rt_dy; 2534879Ssam year = de->rt_date.rt_yr+72; 2544879Ssam month = de->rt_date.rt_mo; 2554879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2564879Ssam ext, month, day, year, de->rt_len); 2574879Ssam break; 258954Sbill 2594879Ssam case RT_NULL: 2604879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2614879Ssam break; 262954Sbill 2634879Ssam case RT_ESEG: 2649877Ssam return (1); 265954Sbill } 2669877Ssam return (0); 267954Sbill } 2684879Ssam 269954Sbill xcmd() 270954Sbill { 2714879Ssam register char *de, *last; 2723346Swnj int segnum; 273954Sbill char name[12]; 274954Sbill register int i; 275954Sbill 276954Sbill rt_init(); 2779877Ssam if (namc != 0) { 2784879Ssam for (i = 0; i < namc; i++) 2794879Ssam if (rtx(namv[i]) == 0) 2804879Ssam namv[i] = 0; 2819877Ssam return; 2829877Ssam } 2839877Ssam for (segnum = 0; segnum != -1; 2849877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 2859877Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 2869877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 2879877Ssam de += rt_entsiz) 2889877Ssam switch (rt(de)->rt_stat) { 2899877Ssam 2909877Ssam case RT_ESEG: 2919877Ssam return; 2929877Ssam 2939877Ssam case RT_TEMP: 2949877Ssam case RT_FILE: 2959877Ssam sunrad50(name,rt(de)->rt_name); 2969877Ssam rtx(name); 2979877Ssam 2989877Ssam case RT_NULL: 2999877Ssam break; 3009877Ssam } 301954Sbill } 3024879Ssam 303954Sbill rtx(name) 3044879Ssam char *name; 305954Sbill { 306954Sbill register FLDOPE *dope; 307954Sbill FLDOPE *lookup(); 308954Sbill register startad, count; 3094879Ssam int file; 3104879Ssam char buff[512]; 311954Sbill 312954Sbill 3134879Ssam if (dope = lookup(name)) { 3144879Ssam if (flag(v)) 315954Sbill rtls(dope->rtdope); 316954Sbill else 317954Sbill printf("x - %s\n",name); 318954Sbill 3194879Ssam if ((file = creat(name, 0666)) < 0) 3209877Ssam return (1); 321954Sbill count = dope->count; 322954Sbill startad = dope->startad; 323954Sbill for( ; count > 0 ; count -= 512) { 3244879Ssam lread(startad, 512, buff); 3254879Ssam write(file, buff, 512); 326954Sbill startad += 512; 327954Sbill } 328954Sbill close(file); 3299877Ssam return (0); 330954Sbill } 3319877Ssam return (1); 332954Sbill } 3334879Ssam 334954Sbill rt_init() 335954Sbill { 336954Sbill static initized = 0; 3374879Ssam register char *de, *last; 3383346Swnj register i; 3393799Shickman int dirnum; 3403799Shickman char *mode; 3413799Shickman FILE *temp_floppydes; 342954Sbill 3434879Ssam if (initized) 3444879Ssam return; 345954Sbill initized = 1; 346*13910Ssam if (flag(c)) { 347*13910Ssam struct stat sb; 348*13910Ssam char response[128]; 349*13910Ssam int tty; 350*13910Ssam 351*13910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 352*13910Ssam goto ignore; 353*13910Ssam tty = open("/dev/tty", O_RDWR); 354*13910Ssam #define SURE "Are you sure you want to clobber the floppy? " 355*13910Ssam write(tty, SURE, sizeof (SURE)); 356*13910Ssam read(tty, response, sizeof (response)); 357*13910Ssam if (*response != 'y') 358*13910Ssam exit(50); 359*13910Ssam close(tty); 360*13910Ssam ignore: 361*13910Ssam ; 362*13910Ssam } 3634879Ssam if (flag(c) || flag(d) || flag(r)) 3643799Shickman mode = "r+"; 365954Sbill else 3663799Shickman mode = "r"; 3674879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3683799Shickman perror(defdev); 3693356Swnj exit(1); 3703799Shickman } else 3713799Shickman floppydes = fileno(temp_floppydes); 3724879Ssam if (!flag(c)) { 3734879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3743346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 37512012Shelge /* check for blank/uninitialized diskette */ 37612012Shelge if (dirnum <= 0) { 37712012Shelge fprintf(stderr,"arff: bad directory format\n"); 37812012Shelge exit(1); 37912012Shelge } 3803346Swnj if (dirnum > RT_DIRSIZE) { 3814879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3824879Ssam exit(1); 3833346Swnj } 3844879Ssam for (i = 1; i < dirnum; i++) 3854879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3863489Sroot } else 3873489Sroot dirnum = 1; 388954Sbill 3893346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3903346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3913346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3923346Swnj rt_nleft = 0; 3933346Swnj 3944879Ssam for (i = 0; i < dirnum; i++) { 3954879Ssam last = rt_last + i*2*RT_BLOCK; 3964879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 3974879Ssam if (rt(de)->rt_stat == RT_ESEG) 3984879Ssam break; 3994879Ssam rt_curend[i] = rt(de); 4004879Ssam rt_nleft += (last-de)/rt_entsiz; 401954Sbill } 402954Sbill } 403954Sbill 404954Sbill static FLDOPE result; 4054879Ssam 406954Sbill FLDOPE * 407954Sbill lookup(name) 4084879Ssam char *name; 409954Sbill { 410954Sbill unsigned short rname[3]; 4114879Ssam register char *de, *last; 4123346Swnj int segnum; 413954Sbill register index; 414954Sbill 415954Sbill srad50(name,rname); 416954Sbill 4173356Swnj /* 418954Sbill * Search for name, accumulate blocks in index 419954Sbill */ 420954Sbill rt_init(); 4214879Ssam for (segnum = 0; segnum != -1; 4224879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4234879Ssam { 4244879Ssam index = 0; 4254879Ssam last = rt_last + segnum*2*RT_BLOCK; 4264879Ssam for (de=((char *)&rt_dir[segnum])+10; 4274879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4284879Ssam switch(rt(de)->rt_stat) { 4294879Ssam 4304879Ssam case RT_FILE: 4314879Ssam case RT_TEMP: 4324879Ssam if(samename(rname,rt(de)->rt_name)) { 4334879Ssam result.count = rt(de)->rt_len * 512; 4344879Ssam result.startad = 512* 4354879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4364879Ssam result.rtdope = (struct rt_ent *) de; 4379877Ssam return (&result); 4384879Ssam } 4394879Ssam 4404879Ssam case RT_NULL: 4414879Ssam index += rt(de)->rt_len; 4424879Ssam } 4433346Swnj } 4449877Ssam return ((FLDOPE *) 0); 4454879Ssam 446954Sbill } 4474879Ssam 448954Sbill static 4494879Ssam samename(a, b) 4504879Ssam u_short a[], b[]; 451954Sbill { 4529877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 453954Sbill } 454954Sbill 4554879Ssam rad50(cp, out) 4564879Ssam register u_char *cp; 4574879Ssam u_short *out; 458954Sbill { 4594879Ssam register index, temp; 460954Sbill 4614879Ssam for (index = 0; *cp; index++) { 462954Sbill temp = Ain1 * table[*cp++]; 4634879Ssam if (*cp!=0) { 464954Sbill temp += Ain2 * table[*cp++]; 465954Sbill if(*cp!=0) 466954Sbill temp += table[*cp++]; 467954Sbill } 468954Sbill out[index] = temp; 469954Sbill } 470954Sbill } 471954Sbill 4724879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4734879Ssam 4744879Ssam unrad50(count, in, cp) 4754879Ssam u_short *in; 4764879Ssam register char *cp; 477954Sbill { 4784879Ssam register i, temp; 4794879Ssam register u_char *v = (u_char *) val; 480954Sbill 4814879Ssam for (i = 0; i < count; i++) { 482954Sbill temp = in[i]; 4834879Ssam reduce(*cp++, temp, Ain1); 4844879Ssam reduce(*cp++, temp, Ain2); 4854879Ssam reduce(*cp++, temp, 1); 486954Sbill } 487954Sbill *cp=0; 488954Sbill } 489954Sbill 4904879Ssam srad50(name, rname) 4914879Ssam register char *name; 4924879Ssam register u_short *rname; 493954Sbill { 4944879Ssam register index; 4954879Ssam register char *cp; 4964879Ssam char file[7], ext[4]; 4974879Ssam 4983356Swnj /* 499954Sbill * Find end of pathname 500954Sbill */ 5014879Ssam for (cp = name; *cp++; ) 5024879Ssam ; 5034879Ssam while (cp >= name && *--cp != '/') 5044879Ssam ; 505954Sbill cp++; 5063356Swnj /* 507954Sbill * Change to rad50 508954Sbill */ 5094879Ssam for (index = 0; *cp; ) { 510954Sbill file[index++] = *cp++; 5114879Ssam if (*cp == '.') { 512954Sbill cp++; 513954Sbill break; 514954Sbill } 5154879Ssam if (index >= 6) { 516954Sbill break; 517954Sbill } 518954Sbill } 519954Sbill file[index] = 0; 5204879Ssam for (index = 0; *cp; ) { 521954Sbill ext[index++] = *cp++; 5224879Ssam if (*cp == '.' || index >= 3) 523954Sbill break; 524954Sbill } 525954Sbill ext[index]=0; 5264879Ssam rname[0] = rname[1] = rname[2] = 0; 5274879Ssam rad50((u_char *)file, rname); 5284879Ssam rad50((u_char *)ext, rname+2); 529954Sbill } 5304879Ssam 5314879Ssam sunrad50(name, rname) 5324879Ssam u_short rname[]; 5334879Ssam register char *name; 534954Sbill { 535954Sbill register char *cp, *cp2; 536954Sbill char ext[4]; 537954Sbill 5384879Ssam unrad50(2, rname, name); 5394879Ssam unrad50(1, rname + 2, ext); 5404879Ssam /* 5414879Ssam * Jam name and extension together with a dot 5424879Ssam * deleting white space 5434879Ssam */ 5444879Ssam for (cp = name; *cp++;) 5454879Ssam ; 5464879Ssam --cp; 5474879Ssam while (*--cp == ' ' && cp >= name) 5484879Ssam ; 5494879Ssam *++cp = '.'; 5504879Ssam cp++; 5514879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 552954Sbill *cp++ = *cp2++; 553954Sbill *cp=0; 5544879Ssam if (cp[-1] == '.') 5554879Ssam cp[-1] = 0; 556954Sbill } 557954Sbill 558954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 559954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5604879Ssam 561954Sbill static char table[256] = { 562954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 563954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 564954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 565954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 566954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 567954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 568954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 569954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 570954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 571954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 572954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 573954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 574954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 575954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 576954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 577954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 578954Sbill 5794879Ssam /* 5804879Ssam * Logical to physical adress translation 5814879Ssam */ 5824879Ssam long 5834879Ssam trans(logical) 5844879Ssam register int logical; 585954Sbill { 586954Sbill register int sector, bytes, track; 587954Sbill 5884879Ssam logical += 26*128; 5894879Ssam bytes = (logical&127); 590954Sbill logical >>= 7; 5914879Ssam sector = logical%26; 592954Sbill if(sector >= 13) 5934879Ssam sector = sector*2+1; 594954Sbill else 595954Sbill sector *= 2; 5964879Ssam sector += 26 + ((track = (logical/26))-1)*6; 597954Sbill sector %= 26; 5989877Ssam return ((((track*26)+sector) << 7) + bytes); 599954Sbill } 6004879Ssam 6014879Ssam lread(startad, count, obuff) 6024879Ssam register startad, count; 6034879Ssam register char *obuff; 604954Sbill { 605954Sbill long trans(); 606954Sbill extern floppydes; 6074879Ssam register int size = flag(m) ? 512 : 128; 6084879Ssam 609954Sbill rt_init(); 6104879Ssam while ((count -= size) >= 0) { 6114879Ssam lseek(floppydes, flag(m) ? 6124879Ssam (long)startad : trans(startad), 0); 6134879Ssam if (read(floppydes, obuff, size) != size) 6144879Ssam fprintf(stderr, "arff: read error block %d\n", 6154879Ssam startad/size); 6164879Ssam obuff += size; 6174879Ssam startad += size; 6184879Ssam } 619954Sbill } 6204879Ssam 6214879Ssam lwrite(startad, count, obuff) 6224879Ssam register startad, count; 6234879Ssam register char *obuff; 624954Sbill { 625954Sbill long trans(); 626954Sbill extern floppydes; 6274879Ssam register int size = flag(m) ? 512 : 128; 6284879Ssam 629954Sbill rt_init(); 6304879Ssam while ((count -= size) >= 0) { 6314879Ssam lseek(floppydes, flag(m) ? 6324879Ssam (long)startad : trans(startad), 0); 6334879Ssam if (write(floppydes, obuff, size) != size) 6344879Ssam fprintf(stderr, "arff: write error block %d\n", 6354879Ssam startad/size); 6364879Ssam obuff += size; 6374879Ssam startad += size; 6384879Ssam } 639954Sbill } 640954Sbill 641954Sbill rcmd() 642954Sbill { 643954Sbill register int i; 644954Sbill 645954Sbill rt_init(); 6464879Ssam if (namc > 0) 6474879Ssam for (i = 0; i < namc; i++) 6484879Ssam if (rtr(namv[i]) == 0) 6494879Ssam namv[i] = 0; 650954Sbill } 651954Sbill 652954Sbill rtr(name) 6534879Ssam char *name; 654954Sbill { 6554879Ssam register FLDOPE *dope; 6564879Ssam register struct rt_ent *de; 6574879Ssam struct stat buf; 6584879Ssam register struct stat *bufp = &buf; 6593346Swnj int segnum; 6603346Swnj register char *last; 661954Sbill 6624879Ssam if (stat(name, bufp) < 0) { 6633489Sroot perror(name); 6649877Ssam return (-1); 6653489Sroot } 6664879Ssam if (dope = lookup(name)) { 667954Sbill /* can replace, no problem */ 668954Sbill de = dope->rtdope; 6694879Ssam if (bufp->st_size <= (de->rt_len * 512)) 670954Sbill printf("r - %s\n",name), 6714879Ssam toflop(name, bufp->st_size, dope); 672954Sbill else { 6739877Ssam fprintf(stderr, 6749877Ssam "%s will not fit in currently used file on floppy\n", 6759877Ssam name); 6769877Ssam return (-1); 677954Sbill } 6789877Ssam goto found; 6799877Ssam } 6809877Ssam /* 6819877Ssam * Search for vacant spot 6829877Ssam */ 6839877Ssam for (segnum = 0; segnum != -1; 6849877Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 6859877Ssam { 6869877Ssam last = rt_last + segnum*2*RT_BLOCK; 6879877Ssam for (de = rt_dir[segnum].rt_ents; 6889877Ssam rt(de)->rt_stat != RT_ESEG; de++) 6899877Ssam if ((de)->rt_stat == RT_NULL) { 6909877Ssam if (bufp->st_size <= (de->rt_len*512)) { 6919877Ssam printf("a - %s\n",name), 6929877Ssam mkent(de, segnum, bufp,name); 6939877Ssam goto found; 694954Sbill } 6959877Ssam continue; 6969877Ssam } 697954Sbill } 6989877Ssam printf("%s: no slot for file\n", name); 6999877Ssam return (-1); 7004879Ssam 7014879Ssam found: 7024879Ssam if (dope = lookup(name)) { 7034879Ssam toflop(name, bufp->st_size, dope); 7043489Sroot return (0); 705954Sbill } 7063489Sroot printf("%s: internal error, added then not found\n", name); 7073489Sroot return (-1); 7084879Ssam } 709954Sbill 7104879Ssam mkent(de, segnum, bufp, name) 7114879Ssam register struct rt_ent *de; 7124879Ssam int segnum; 7134879Ssam register struct stat *bufp; 7144879Ssam char *name; 715954Sbill { 7164879Ssam struct tm *localtime(); 7174879Ssam register struct tm *timp; 7184879Ssam register struct rt_ent *workp; 7194879Ssam int count; 720954Sbill 721954Sbill count = (((bufp->st_size -1) >>9) + 1); 7224879Ssam /* make sure there is room */ 7234879Ssam if (de->rt_len == count) 724954Sbill goto overwrite; 7254879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7264879Ssam /* no entries left on segment */ 7274879Ssam if (flag(o)) 728954Sbill goto overwrite; 7299877Ssam fprintf(stderr, "Directory segment #%d full on %s\n", 7309877Ssam segnum+1, defdev); 731954Sbill exit(1); 732954Sbill } 7334879Ssam /* copy directory entries up */ 7344879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 735954Sbill *workp = workp[-1]; 736954Sbill de[1].rt_len -= count; 737954Sbill de->rt_len = count; 7383346Swnj rt_curend[segnum]++; 739954Sbill rt_nleft--; 7404879Ssam 741954Sbill overwrite: 742954Sbill srad50(name,de->rt_name); 743954Sbill timp = localtime(&bufp->st_mtime); 7447320Swnj de->rt_date.rt_dy = timp->tm_mday; 745954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 746954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 747954Sbill de->rt_stat = RT_FILE; 748954Sbill de->rt_pad = 0; 749954Sbill de->rt_chan = 0; 750954Sbill de->rt_job = 0; 7514879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 752954Sbill } 753954Sbill 7544879Ssam toflop(name, ocount, dope) 7554879Ssam char *name; 7564879Ssam register FLDOPE *dope; 7574879Ssam long ocount; 758954Sbill { 759954Sbill register file, n, startad = dope->startad, count = ocount; 760954Sbill char buff[512]; 761954Sbill 7624879Ssam file = open(name, 0); 7634879Ssam if (file < 0) { 7644879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7654879Ssam exit(1); 7664879Ssam } 767954Sbill for( ; count >= 512; count -= 512) { 7684879Ssam read(file, buff, 512); 7694879Ssam lwrite(startad, 512, buff); 770954Sbill startad += 512; 771954Sbill } 7724879Ssam read(file, buff, count); 773954Sbill close(file); 7744879Ssam if (count <= 0) 7754879Ssam return; 7764879Ssam for (n = count; n < 512; n ++) 7774879Ssam buff[n] = 0; 7784879Ssam lwrite(startad, 512, buff); 7794879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7804879Ssam if (count <= 0) 7814879Ssam return; 7824879Ssam for ( ; count > 0 ; count--) { 783954Sbill startad += 512; 7844879Ssam lwrite(startad, 512, zeroes); 785954Sbill } 7864879Ssam } 787954Sbill 788954Sbill dcmd() 789954Sbill { 790954Sbill register int i; 791954Sbill 792954Sbill rt_init(); 7934879Ssam if (namc) 7944879Ssam for (i = 0; i < namc; i++) 7954879Ssam if (rtk(namv[i])==0) 7964879Ssam namv[i]=0; 7974879Ssam if (dirdirty) 798954Sbill scrunch(); 799954Sbill } 8004879Ssam 801954Sbill rtk(name) 8024879Ssam char *name; 803954Sbill { 804954Sbill register FLDOPE *dope; 805954Sbill register struct rt_ent *de; 806954Sbill FLDOPE *lookup(); 807954Sbill 8084879Ssam if (dope = lookup(name)) { 809954Sbill printf("d - %s\n",name); 810954Sbill de = dope->rtdope; 811954Sbill de->rt_stat = RT_NULL; 812954Sbill de->rt_name[0] = 0; 813954Sbill de->rt_name[1] = 0; 814954Sbill de->rt_name[2] = 0; 8159877Ssam *((u_short *)&(de->rt_date)) = 0; 816954Sbill dirdirty = 1; 8179877Ssam return (0); 818954Sbill } 8199877Ssam return (1); 820954Sbill } 8214879Ssam 8224879Ssam scrunch() 8234879Ssam { 8243346Swnj register struct rt_ent *de , *workp; 8253346Swnj register segnum; 8264879Ssam 8274879Ssam for (segnum = 0; segnum != -1; 8283346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8294879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 8309877Ssam if (de->rt_stat == RT_NULL && 83112012Shelge (de+1)->rt_stat == RT_NULL) { 8324879Ssam (de+1)->rt_len += de->rt_len; 83312012Shelge for (workp=de; workp<rt_curend[segnum]; workp++) 8344879Ssam *workp = workp[1]; 8354879Ssam de--; 8364879Ssam rt_curend[segnum]--; 8374879Ssam rt_nleft++; 8384879Ssam } 83912012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 84012012Shelge (char *)&rt_dir[segnum]); 841954Sbill } 84212012Shelge dirdirty = 0; 843954Sbill } 844