1*7320Swnj static char *sccsid = "@(#)arff.c 4.10 (Berkeley) 82/06/27"; 24879Ssam 3954Sbill #include <sys/types.h> 4954Sbill #include <sys/stat.h> 5954Sbill #include <time.h> 6954Sbill #include <signal.h> 7954Sbill #include <stdio.h> 84879Ssam 9954Sbill #define dbprintf printf 104879Ssam 11954Sbill struct rt_dat { 124879Ssam u_short rt_yr:5; /* year-1972 */ 134879Ssam u_short rt_dy:5; /* day */ 144879Ssam u_short rt_mo:5; /* month */ 15954Sbill }; 164879Ssam 17954Sbill struct rt_axent { 18954Sbill char rt_sent[14]; 19954Sbill }; 20954Sbill 21954Sbill struct rt_ent { 224879Ssam char rt_pad; /* unusued */ 234879Ssam char rt_stat; /* type of entry, or end of seg */ 244879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 257319Swnj u_short rt_len; /* length of file */ 264879Ssam char rt_chan; /* only used in temporary files */ 274879Ssam char rt_job; /* only used in temporary files */ 284879Ssam struct rt_dat rt_date; /* creation date */ 29954Sbill }; 304879Ssam 314879Ssam #define RT_TEMP 1 324879Ssam #define RT_NULL 2 334879Ssam #define RT_FILE 4 344879Ssam #define RT_ESEG 8 354879Ssam 364879Ssam #define RT_BLOCK 512 /* block size */ 374879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */ 384879Ssam 39954Sbill struct rt_head { 404879Ssam short rt_numseg; /* # of segments available */ 414879Ssam short rt_nxtseg; /* # of next logical segment */ 424879Ssam short rt_lstseg; /* highest seg currently open */ 434879Ssam u_short rt_entpad; /* extra words/directory entry */ 444879Ssam short rt_stfile; /* block # where files begin */ 45954Sbill }; 464879Ssam 47954Sbill struct rt_dir { 48954Sbill struct rt_head rt_axhead; 49954Sbill struct rt_ent rt_ents[72]; 504879Ssam char _dirpad[6]; 51954Sbill }; 524879Ssam 533346Swnj extern struct rt_dir rt_dir[RT_DIRSIZE]; 54954Sbill extern int rt_entsiz; 55954Sbill extern int floppydes; 56954Sbill extern char *rt_last; 574879Ssam 58954Sbill typedef struct fldope { 59954Sbill int startad; 60954Sbill int count; 61954Sbill struct rt_ent *rtdope; 62954Sbill } FLDOPE; 634879Ssam 64954Sbill FLDOPE *lookup(); 654879Ssam 66954Sbill #define rt(p) ((struct rt_ent *) p ) 67954Sbill #define Ain1 03100 68954Sbill #define Ain2 050 694879Ssam #define flag(c) (flg[('c') - 'a']) 70954Sbill 714879Ssam char *man = "rxtd"; 724879Ssam char zeroes[512]; 73954Sbill 74954Sbill extern char *val; 75954Sbill extern char table[256]; 764879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 774879Ssam {4, 0, 1, 0, 14}, 784879Ssam { {0, RT_NULL, {0, 0, 0}, 494, 0}, {0, RT_ESEG} } 794879Ssam }; 80954Sbill 814879Ssam int rt_entsiz; 824879Ssam int rt_nleft; 834879Ssam struct rt_ent *rt_curend[RT_DIRSIZE]; 844879Ssam int floppydes; 854879Ssam int dirdirty; 864879Ssam char *rt_last; 874879Ssam char *defdev = "/dev/floppy"; 88954Sbill 894879Ssam char *opt = "vf"; 904879Ssam 91954Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 924879Ssam extern long lseek(); 934879Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 944879Ssam 95954Sbill int (*comfun)(); 96954Sbill char flg[26]; 97954Sbill char **namv; 98954Sbill int namc; 99954Sbill int file; 100954Sbill 101954Sbill main(argc, argv) 1024879Ssam char *argv[]; 103954Sbill { 104954Sbill register char *cp; 105954Sbill 1064879Ssam if (argc < 2) 107954Sbill usage(); 108954Sbill cp = argv[1]; 1094879Ssam for (cp = argv[1]; *cp; cp++) 1104879Ssam switch (*cp) { 111954Sbill 1124879Ssam case 'm': 1134879Ssam case 'v': 1144879Ssam case 'u': 1154879Ssam case 'w': 1164879Ssam flg[*cp-'a']++; 1174879Ssam continue; 1184879Ssam case 'c': 1194879Ssam { 1204879Ssam #define SURE "Last chance before clobbering floppy?" 1214879Ssam int tty; 1224879Ssam char response[128]; 123954Sbill 1244879Ssam tty = open("/dev/tty", 2); 1254879Ssam write(tty, SURE, sizeof(SURE)); 1264879Ssam read(tty, response, sizeof(response)); 1274879Ssam if (*response != 'y') 1284879Ssam exit(50); 1294879Ssam flag(c)++; 1304879Ssam close(tty); 1314879Ssam } 1324879Ssam dirdirty++; 1334879Ssam continue; 134954Sbill 1354879Ssam case 'r': 1364879Ssam setcom(rcmd); 1374879Ssam flag(r)++; 1384879Ssam continue; 139954Sbill 1404879Ssam case 'd': 1414879Ssam setcom(dcmd); 1424879Ssam flag(d)++; 1434879Ssam continue; 144954Sbill 1454879Ssam case 'x': 1464879Ssam setcom(xcmd); 1474879Ssam continue; 148954Sbill 1494879Ssam case 't': 1504879Ssam setcom(tcmd); 1514879Ssam continue; 152954Sbill 1534879Ssam case 'f': 1544879Ssam defdev = argv[2]; 1554879Ssam argv++; 1564879Ssam argc--; 1574879Ssam continue; 1584879Ssam 1594879Ssam default: 1604879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp); 1614879Ssam exit(1); 1624879Ssam } 1634879Ssam 164954Sbill namv = argv+2; 165954Sbill namc = argc-2; 1664879Ssam if (comfun == 0) { 1674879Ssam if (flag(u) == 0) { 1684879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 1694879Ssam man); 170954Sbill exit(1); 171954Sbill } 172954Sbill setcom(rcmd); 173954Sbill } 174954Sbill (*comfun)(); 175954Sbill exit(notfound()); 176954Sbill } 177954Sbill 178954Sbill setcom(fun) 1794879Ssam int (*fun)(); 180954Sbill { 1814879Ssam if (comfun != 0) { 182954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 183954Sbill exit(1); 184954Sbill } 185954Sbill comfun = fun; 186954Sbill } 187954Sbill 188954Sbill usage() 189954Sbill { 1903356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 191954Sbill exit(1); 192954Sbill } 193954Sbill 194954Sbill notfound() 195954Sbill { 1964879Ssam register i, n = 0; 197954Sbill 1984879Ssam for (i = 0; i < namc; i++) 1994879Ssam if (namv[i]) { 200954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 201954Sbill n++; 202954Sbill } 203954Sbill return(n); 204954Sbill } 205954Sbill 206954Sbill mesg(c) 207954Sbill { 2084879Ssam if (flag(v)) 2094879Ssam if (c != 'c' || flag(v) > 1) 210954Sbill printf("%c - %s\n", c, file); 211954Sbill } 212954Sbill 213954Sbill tcmd() 214954Sbill { 2154879Ssam register char *de, *last; 216954Sbill FLDOPE *lookup(), *dope; 2174879Ssam int segnum, nleft; 2184879Ssam register i; 219954Sbill register struct rt_ent *rde; 220954Sbill 221954Sbill rt_init(); 2224879Ssam if (namc == 0) 2234879Ssam for (segnum = 0; segnum != -1; 2244879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 2254879Ssam { 2264879Ssam last = rt_last + segnum*2*RT_BLOCK; 2274879Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last; 2284879Ssam de += rt_entsiz) 2294879Ssam if (rtls(rt(de))) { 2304879Ssam nleft = (last-de)/rt_entsiz; 2314879Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 2324879Ssam printf(ENTRIES, nleft, segnum+1); 2334879Ssam break; 2344879Ssam } 235954Sbill } 236954Sbill else 2374879Ssam for (i = 0; i < namc; i++) 2384879Ssam if (dope = lookup(namv[i])) { 239954Sbill rde = dope->rtdope; 240954Sbill rtls(rde); 241954Sbill namv[i] = 0; 242954Sbill } 243954Sbill } 2444879Ssam 245954Sbill rtls(de) 2464879Ssam register struct rt_ent *de; 247954Sbill { 2484879Ssam int month, day, year; 249954Sbill char name[12], ext[4]; 250954Sbill 2514879Ssam switch (de->rt_stat) { 2524879Ssam 2534879Ssam case RT_TEMP: 2544879Ssam if (flag(v)) 255954Sbill printf("Tempfile:\n"); 2564879Ssam /* fall thru...*/ 257954Sbill 2584879Ssam case RT_FILE: 2594879Ssam if (!flag(v)) { 2604879Ssam sunrad50(name, de->rt_name); 2614879Ssam printf("%s\n", name); 262954Sbill break; 263954Sbill } 2644879Ssam unrad50(2, de->rt_name, name); 2654879Ssam unrad50(1, &(de->rt_name[2]), ext); 2664879Ssam day = de->rt_date.rt_dy; 2674879Ssam year = de->rt_date.rt_yr+72; 2684879Ssam month = de->rt_date.rt_mo; 2694879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2704879Ssam ext, month, day, year, de->rt_len); 2714879Ssam break; 272954Sbill 2734879Ssam case RT_NULL: 2744879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2754879Ssam break; 276954Sbill 2774879Ssam case RT_ESEG: 2784879Ssam return(1); 279954Sbill } 280954Sbill return(0); 281954Sbill } 2824879Ssam 283954Sbill xcmd() 284954Sbill { 2854879Ssam register char *de, *last; 2863346Swnj int segnum; 287954Sbill char name[12]; 288954Sbill register int i; 289954Sbill 290954Sbill rt_init(); 2914879Ssam if (namc == 0) 2924879Ssam for (segnum = 0; segnum != -1; 2934879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) 2944879Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 2954879Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 2964879Ssam de += rt_entsiz) 2974879Ssam sunrad50(name, rt(de)->rt_name), rtx(name); 298954Sbill else 2994879Ssam for (i = 0; i < namc; i++) 3004879Ssam if (rtx(namv[i]) == 0) 3014879Ssam namv[i] = 0; 302954Sbill } 3034879Ssam 304954Sbill rtx(name) 3054879Ssam char *name; 306954Sbill { 307954Sbill register FLDOPE *dope; 308954Sbill FLDOPE *lookup(); 309954Sbill register startad, count; 3104879Ssam int file; 3114879Ssam char buff[512]; 312954Sbill 313954Sbill 3144879Ssam if (dope = lookup(name)) { 3154879Ssam if (flag(v)) 316954Sbill rtls(dope->rtdope); 317954Sbill else 318954Sbill printf("x - %s\n",name); 319954Sbill 3204879Ssam if ((file = creat(name, 0666)) < 0) 3214879Ssam return(1); 322954Sbill count = dope->count; 323954Sbill startad = dope->startad; 324954Sbill for( ; count > 0 ; count -= 512) { 3254879Ssam lread(startad, 512, buff); 3264879Ssam write(file, buff, 512); 327954Sbill startad += 512; 328954Sbill } 329954Sbill close(file); 330954Sbill return(0); 331954Sbill } 332954Sbill return(1); 333954Sbill } 3344879Ssam 335954Sbill rt_init() 336954Sbill { 337954Sbill static initized = 0; 3384879Ssam register char *de, *last; 3393346Swnj register i; 3403799Shickman int dirnum; 3413799Shickman char *mode; 3423799Shickman FILE *temp_floppydes; 343954Sbill 3444879Ssam if (initized) 3454879Ssam return; 346954Sbill initized = 1; 3474879Ssam if (flag(c) || flag(d) || flag(r)) 3483799Shickman mode = "r+"; 349954Sbill else 3503799Shickman mode = "r"; 3514879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 3523799Shickman perror(defdev); 3533356Swnj exit(1); 3543799Shickman } else 3553799Shickman floppydes = fileno(temp_floppydes); 3564879Ssam if (!flag(c)) { 3574879Ssam lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 3583346Swnj dirnum = rt_dir[0].rt_axhead.rt_numseg; 3593346Swnj if (dirnum > RT_DIRSIZE) { 3604879Ssam fprintf(stderr,"arff: too many directory segments\n"); 3614879Ssam exit(1); 3623346Swnj } 3634879Ssam for (i = 1; i < dirnum; i++) 3644879Ssam lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 3653489Sroot } else 3663489Sroot dirnum = 1; 367954Sbill 3683346Swnj rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; 3693346Swnj rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ 3703346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 3713346Swnj rt_nleft = 0; 3723346Swnj 3734879Ssam for (i = 0; i < dirnum; i++) { 3744879Ssam last = rt_last + i*2*RT_BLOCK; 3754879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 3764879Ssam if (rt(de)->rt_stat == RT_ESEG) 3774879Ssam break; 3784879Ssam rt_curend[i] = rt(de); 3794879Ssam rt_nleft += (last-de)/rt_entsiz; 380954Sbill } 381954Sbill } 382954Sbill 383954Sbill static FLDOPE result; 3844879Ssam 385954Sbill FLDOPE * 386954Sbill lookup(name) 3874879Ssam char *name; 388954Sbill { 389954Sbill unsigned short rname[3]; 3904879Ssam register char *de, *last; 3913346Swnj int segnum; 392954Sbill register index; 393954Sbill 394954Sbill srad50(name,rname); 395954Sbill 3963356Swnj /* 397954Sbill * Search for name, accumulate blocks in index 398954Sbill */ 399954Sbill rt_init(); 4004879Ssam for (segnum = 0; segnum != -1; 4014879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 4024879Ssam { 4034879Ssam index = 0; 4044879Ssam last = rt_last + segnum*2*RT_BLOCK; 4054879Ssam for (de=((char *)&rt_dir[segnum])+10; 4064879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4074879Ssam switch(rt(de)->rt_stat) { 4084879Ssam 4094879Ssam case RT_FILE: 4104879Ssam case RT_TEMP: 4114879Ssam if(samename(rname,rt(de)->rt_name)) { 4124879Ssam result.count = rt(de)->rt_len * 512; 4134879Ssam result.startad = 512* 4144879Ssam (rt_dir[segnum].rt_axhead.rt_stfile + index); 4154879Ssam result.rtdope = (struct rt_ent *) de; 4164879Ssam return(&result); 4174879Ssam } 4184879Ssam 4194879Ssam case RT_NULL: 4204879Ssam index += rt(de)->rt_len; 4214879Ssam } 4223346Swnj } 423954Sbill return((FLDOPE *) 0); 4244879Ssam 425954Sbill } 4264879Ssam 427954Sbill static 4284879Ssam samename(a, b) 4294879Ssam u_short a[], b[]; 430954Sbill { 4314879Ssam return(*a == *b && a[1] == b[1] && a[2] == b[2] ); 432954Sbill } 433954Sbill 4344879Ssam rad50(cp, out) 4354879Ssam register u_char *cp; 4364879Ssam u_short *out; 437954Sbill { 4384879Ssam register index, temp; 439954Sbill 4404879Ssam for (index = 0; *cp; index++) { 441954Sbill temp = Ain1 * table[*cp++]; 4424879Ssam if (*cp!=0) { 443954Sbill temp += Ain2 * table[*cp++]; 444954Sbill if(*cp!=0) 445954Sbill temp += table[*cp++]; 446954Sbill } 447954Sbill out[index] = temp; 448954Sbill } 449954Sbill } 450954Sbill 4514879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 4524879Ssam 4534879Ssam unrad50(count, in, cp) 4544879Ssam u_short *in; 4554879Ssam register char *cp; 456954Sbill { 4574879Ssam register i, temp; 4584879Ssam register u_char *v = (u_char *) val; 459954Sbill 4604879Ssam for (i = 0; i < count; i++) { 461954Sbill temp = in[i]; 4624879Ssam reduce(*cp++, temp, Ain1); 4634879Ssam reduce(*cp++, temp, Ain2); 4644879Ssam reduce(*cp++, temp, 1); 465954Sbill } 466954Sbill *cp=0; 467954Sbill } 468954Sbill 4694879Ssam srad50(name, rname) 4704879Ssam register char *name; 4714879Ssam register u_short *rname; 472954Sbill { 4734879Ssam register index; 4744879Ssam register char *cp; 4754879Ssam char file[7], ext[4]; 4764879Ssam 4773356Swnj /* 478954Sbill * Find end of pathname 479954Sbill */ 4804879Ssam for (cp = name; *cp++; ) 4814879Ssam ; 4824879Ssam while (cp >= name && *--cp != '/') 4834879Ssam ; 484954Sbill cp++; 4853356Swnj /* 486954Sbill * Change to rad50 487954Sbill */ 4884879Ssam for (index = 0; *cp; ) { 489954Sbill file[index++] = *cp++; 4904879Ssam if (*cp == '.') { 491954Sbill cp++; 492954Sbill break; 493954Sbill } 4944879Ssam if (index >= 6) { 495954Sbill break; 496954Sbill } 497954Sbill } 498954Sbill file[index] = 0; 4994879Ssam for (index = 0; *cp; ) { 500954Sbill ext[index++] = *cp++; 5014879Ssam if (*cp == '.' || index >= 3) 502954Sbill break; 503954Sbill } 504954Sbill ext[index]=0; 5054879Ssam rname[0] = rname[1] = rname[2] = 0; 5064879Ssam rad50((u_char *)file, rname); 5074879Ssam rad50((u_char *)ext, rname+2); 508954Sbill } 5094879Ssam 5104879Ssam sunrad50(name, rname) 5114879Ssam u_short rname[]; 5124879Ssam register char *name; 513954Sbill { 514954Sbill register char *cp, *cp2; 515954Sbill char ext[4]; 516954Sbill 5174879Ssam unrad50(2, rname, name); 5184879Ssam unrad50(1, rname + 2, ext); 5194879Ssam /* 5204879Ssam * Jam name and extension together with a dot 5214879Ssam * deleting white space 5224879Ssam */ 5234879Ssam for (cp = name; *cp++;) 5244879Ssam ; 5254879Ssam --cp; 5264879Ssam while (*--cp == ' ' && cp >= name) 5274879Ssam ; 5284879Ssam *++cp = '.'; 5294879Ssam cp++; 5304879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 531954Sbill *cp++ = *cp2++; 532954Sbill *cp=0; 5334879Ssam if (cp[-1] == '.') 5344879Ssam cp[-1] = 0; 535954Sbill } 536954Sbill 537954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; 538954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 5394879Ssam 540954Sbill static char table[256] = { 541954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 542954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 543954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 544954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 545954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 546954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 547954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 548954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 549954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 550954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 551954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 552954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 553954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 554954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 555954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 556954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 557954Sbill 5584879Ssam /* 5594879Ssam * Logical to physical adress translation 5604879Ssam */ 5614879Ssam long 5624879Ssam trans(logical) 5634879Ssam register int logical; 564954Sbill { 565954Sbill register int sector, bytes, track; 566954Sbill 5674879Ssam logical += 26*128; 5684879Ssam bytes = (logical&127); 569954Sbill logical >>= 7; 5704879Ssam sector = logical%26; 571954Sbill if(sector >= 13) 5724879Ssam sector = sector*2+1; 573954Sbill else 574954Sbill sector *= 2; 5754879Ssam sector += 26 + ((track = (logical/26))-1)*6; 576954Sbill sector %= 26; 5774879Ssam return((((track*26)+sector) << 7) + bytes); 578954Sbill } 5794879Ssam 5804879Ssam lread(startad, count, obuff) 5814879Ssam register startad, count; 5824879Ssam register char *obuff; 583954Sbill { 584954Sbill long trans(); 585954Sbill extern floppydes; 5864879Ssam register int size = flag(m) ? 512 : 128; 5874879Ssam 588954Sbill rt_init(); 5894879Ssam while ((count -= size) >= 0) { 5904879Ssam lseek(floppydes, flag(m) ? 5914879Ssam (long)startad : trans(startad), 0); 5924879Ssam if (read(floppydes, obuff, size) != size) 5934879Ssam fprintf(stderr, "arff: read error block %d\n", 5944879Ssam startad/size); 5954879Ssam obuff += size; 5964879Ssam startad += size; 5974879Ssam } 598954Sbill } 5994879Ssam 6004879Ssam lwrite(startad, count, obuff) 6014879Ssam register startad, count; 6024879Ssam register char *obuff; 603954Sbill { 604954Sbill long trans(); 605954Sbill extern floppydes; 6064879Ssam register int size = flag(m) ? 512 : 128; 6074879Ssam 608954Sbill rt_init(); 6094879Ssam while ((count -= size) >= 0) { 6104879Ssam lseek(floppydes, flag(m) ? 6114879Ssam (long)startad : trans(startad), 0); 6124879Ssam if (write(floppydes, obuff, size) != size) 6134879Ssam fprintf(stderr, "arff: write error block %d\n", 6144879Ssam startad/size); 6154879Ssam obuff += size; 6164879Ssam startad += size; 6174879Ssam } 618954Sbill } 619954Sbill 620954Sbill rcmd() 621954Sbill { 622954Sbill register int i; 623954Sbill 624954Sbill rt_init(); 6254879Ssam if (namc > 0) 6264879Ssam for (i = 0; i < namc; i++) 6274879Ssam if (rtr(namv[i]) == 0) 6284879Ssam namv[i] = 0; 629954Sbill } 630954Sbill 631954Sbill rtr(name) 6324879Ssam char *name; 633954Sbill { 6344879Ssam register FLDOPE *dope; 6354879Ssam register struct rt_ent *de; 6364879Ssam struct stat buf; 6374879Ssam register struct stat *bufp = &buf; 6383346Swnj int segnum; 6393346Swnj register char *last; 640954Sbill 6414879Ssam if (stat(name, bufp) < 0) { 6423489Sroot perror(name); 6433489Sroot return(-1); 6443489Sroot } 6454879Ssam if (dope = lookup(name)) { 646954Sbill /* can replace, no problem */ 647954Sbill de = dope->rtdope; 6484879Ssam if (bufp->st_size <= (de->rt_len * 512)) 649954Sbill printf("r - %s\n",name), 6504879Ssam toflop(name, bufp->st_size, dope); 651954Sbill else { 6523356Swnj fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); 6533489Sroot return(-1); 654954Sbill } 655954Sbill } else { 6564879Ssam /* Search for vacant spot */ 6574879Ssam for (segnum = 0; segnum != -1; 6584879Ssam segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) 6594879Ssam { 6604879Ssam last = rt_last + segnum*2*RT_BLOCK; 6614879Ssam for (de = rt_dir[segnum].rt_ents; 6624879Ssam rt(de)->rt_stat != RT_ESEG; de++) 6634879Ssam if ((de)->rt_stat == RT_NULL) { 6644879Ssam if (bufp->st_size <= (de->rt_len*512)) { 6654879Ssam printf("a - %s\n",name), 6664879Ssam mkent(de, segnum, bufp,name); 6674879Ssam goto found; 6684879Ssam } 6694879Ssam continue; 670954Sbill } 6713346Swnj } 6723489Sroot printf("%s: no slot for file\n", name); 6733489Sroot return (-1); 674954Sbill } 6754879Ssam 6764879Ssam found: 6774879Ssam if (dope = lookup(name)) { 6784879Ssam toflop(name, bufp->st_size, dope); 6793489Sroot return (0); 680954Sbill } 6813489Sroot printf("%s: internal error, added then not found\n", name); 6823489Sroot return (-1); 6834879Ssam } 684954Sbill 6854879Ssam mkent(de, segnum, bufp, name) 6864879Ssam register struct rt_ent *de; 6874879Ssam int segnum; 6884879Ssam register struct stat *bufp; 6894879Ssam char *name; 690954Sbill { 6914879Ssam struct tm *localtime(); 6924879Ssam register struct tm *timp; 6934879Ssam register struct rt_ent *workp; 6944879Ssam int count; 695954Sbill 696954Sbill count = (((bufp->st_size -1) >>9) + 1); 6974879Ssam /* make sure there is room */ 6984879Ssam if (de->rt_len == count) 699954Sbill goto overwrite; 7004879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 7014879Ssam /* no entries left on segment */ 7024879Ssam if (flag(o)) 703954Sbill goto overwrite; 7043346Swnj fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, 7054879Ssam defdev); 706954Sbill exit(1); 707954Sbill } 7084879Ssam /* copy directory entries up */ 7094879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--) 710954Sbill *workp = workp[-1]; 711954Sbill de[1].rt_len -= count; 712954Sbill de->rt_len = count; 7133346Swnj rt_curend[segnum]++; 714954Sbill rt_nleft--; 7154879Ssam 716954Sbill overwrite: 717954Sbill srad50(name,de->rt_name); 718954Sbill timp = localtime(&bufp->st_mtime); 719*7320Swnj de->rt_date.rt_dy = timp->tm_mday; 720954Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 721954Sbill de->rt_date.rt_yr = timp->tm_year - 72; 722954Sbill de->rt_stat = RT_FILE; 723954Sbill de->rt_pad = 0; 724954Sbill de->rt_chan = 0; 725954Sbill de->rt_job = 0; 7264879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 727954Sbill } 728954Sbill 7294879Ssam toflop(name, ocount, dope) 7304879Ssam char *name; 7314879Ssam register FLDOPE *dope; 7324879Ssam long ocount; 733954Sbill { 734954Sbill register file, n, startad = dope->startad, count = ocount; 735954Sbill char buff[512]; 736954Sbill 7374879Ssam file = open(name, 0); 7384879Ssam if (file < 0) { 7394879Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 7404879Ssam exit(1); 7414879Ssam } 742954Sbill for( ; count >= 512; count -= 512) { 7434879Ssam read(file, buff, 512); 7444879Ssam lwrite(startad, 512, buff); 745954Sbill startad += 512; 746954Sbill } 7474879Ssam read(file, buff, count); 748954Sbill close(file); 7494879Ssam if (count <= 0) 7504879Ssam return; 7514879Ssam for (n = count; n < 512; n ++) 7524879Ssam buff[n] = 0; 7534879Ssam lwrite(startad, 512, buff); 7544879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ; 7554879Ssam if (count <= 0) 7564879Ssam return; 7574879Ssam for ( ; count > 0 ; count--) { 758954Sbill startad += 512; 7594879Ssam lwrite(startad, 512, zeroes); 760954Sbill } 7614879Ssam } 762954Sbill 763954Sbill dcmd() 764954Sbill { 765954Sbill register int i; 766954Sbill 767954Sbill rt_init(); 7684879Ssam if (namc) 7694879Ssam for (i = 0; i < namc; i++) 7704879Ssam if (rtk(namv[i])==0) 7714879Ssam namv[i]=0; 7724879Ssam if (dirdirty) 773954Sbill scrunch(); 774954Sbill } 7754879Ssam 776954Sbill rtk(name) 7774879Ssam char *name; 778954Sbill { 779954Sbill register FLDOPE *dope; 780954Sbill register struct rt_ent *de; 781954Sbill FLDOPE *lookup(); 782954Sbill 7834879Ssam if (dope = lookup(name)) { 784954Sbill printf("d - %s\n",name); 785954Sbill de = dope->rtdope; 786954Sbill de->rt_stat = RT_NULL; 787954Sbill de->rt_name[0] = 0; 788954Sbill de->rt_name[1] = 0; 789954Sbill de->rt_name[2] = 0; 7904879Ssam * ((u_short *)&(de->rt_date)) = 0; 791954Sbill dirdirty = 1; 792954Sbill return(0); 793954Sbill } 794954Sbill return(1); 795954Sbill } 7964879Ssam 7974879Ssam scrunch() 7984879Ssam { 7993346Swnj register struct rt_ent *de , *workp; 8003346Swnj register segnum; 8014879Ssam 8024879Ssam for (segnum = 0; segnum != -1; 8033346Swnj segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { 8044879Ssam dirdirty = 0; 8054879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 8064879Ssam if (de->rt_stat == RT_NULL && de[1].rt_stat == RT_NULL) { 8074879Ssam (de+1)->rt_len += de->rt_len; 8084879Ssam for (workp = de; workp < rt_curend[segnum]; workp++) 8094879Ssam *workp = workp[1]; 8104879Ssam de--; 8114879Ssam rt_curend[segnum]--; 8124879Ssam rt_nleft++; 8134879Ssam dirdirty = 1; 8144879Ssam } 8154879Ssam if (dirdirty) 8164879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 8174879Ssam (char *)&rt_dir[segnum]); 818954Sbill } 819954Sbill } 820