|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)arff.c 5.2 (Berkeley) 2/11/86"; ! 15: #endif not lint ! 16: ! 17: #include <sys/types.h> ! 18: #include <sys/stat.h> ! 19: #include <sys/time.h> ! 20: #include <signal.h> ! 21: #include <stdio.h> ! 22: #include <sys/file.h> ! 23: ! 24: #define dbprintf printf ! 25: ! 26: struct rt_dat { ! 27: u_short rt_yr:5; /* year-1972 */ ! 28: u_short rt_dy:5; /* day */ ! 29: u_short rt_mo:5; /* month */ ! 30: }; ! 31: ! 32: struct rt_axent { ! 33: char rt_sent[14]; ! 34: }; ! 35: ! 36: struct rt_ent { ! 37: char rt_pad; /* unusued */ ! 38: char rt_stat; /* type of entry, or end of seg */ ! 39: u_short rt_name[3]; /* name, 3 words in rad50 form */ ! 40: u_short rt_len; /* length of file */ ! 41: char rt_chan; /* only used in temporary files */ ! 42: char rt_job; /* only used in temporary files */ ! 43: struct rt_dat rt_date; /* creation date */ ! 44: }; ! 45: ! 46: #define RT_TEMP 1 ! 47: #define RT_NULL 2 ! 48: #define RT_FILE 4 ! 49: #define RT_ESEG 8 ! 50: ! 51: #define RT_BLOCK 512 /* block size */ ! 52: #define RT_DIRSIZE 31 /* max # of directory segments */ ! 53: ! 54: struct rt_head { ! 55: short rt_numseg; /* # of segments available */ ! 56: short rt_nxtseg; /* # of next logical segment */ ! 57: short rt_lstseg; /* highest seg currently open */ ! 58: u_short rt_entpad; /* extra words/directory entry */ ! 59: short rt_stfile; /* block # where files begin */ ! 60: }; ! 61: ! 62: struct rt_dir { ! 63: struct rt_head rt_axhead; ! 64: struct rt_ent rt_ents[72]; ! 65: char _dirpad[6]; ! 66: }; ! 67: ! 68: #define rd_numseg rt_axhead.rt_numseg ! 69: #define rd_nxtseg rt_axhead.rt_nxtseg ! 70: #define rd_lstseg rt_axhead.rt_lstseg ! 71: #define rd_entpad rt_axhead.rt_entpad ! 72: #define rd_stfile rt_axhead.rt_stfile ! 73: ! 74: typedef struct fldope { ! 75: int startad; ! 76: int count; ! 77: struct rt_ent *rtdope; ! 78: } FLDOPE; ! 79: ! 80: FLDOPE *lookup(); ! 81: ! 82: #define rt(p) ((struct rt_ent *) p ) ! 83: #define Ain1 03100 ! 84: #define Ain2 050 ! 85: #define flag(c) (flg[('c') - 'a']) ! 86: ! 87: char *man = "rxtd"; ! 88: char zeroes[512]; ! 89: ! 90: extern char *val; ! 91: extern char table[256]; ! 92: struct rt_dir rt_dir[RT_DIRSIZE] = { ! 93: { 4, 0, 1, 0, 14 }, ! 94: { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, ! 95: { 0, RT_ESEG } } ! 96: }; ! 97: ! 98: struct rt_dir rt_nulldir = { ! 99: { 0, 0, 0, 0, 0 }, ! 100: { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, ! 101: { 0, RT_ESEG } } ! 102: }; ! 103: ! 104: int rt_entsiz; ! 105: int rt_nleft; ! 106: struct rt_ent *rt_curend[RT_DIRSIZE]; ! 107: int floppydes; ! 108: int dirdirty; ! 109: char *rt_last; ! 110: char *defdev = "/dev/floppy"; ! 111: ! 112: char *opt = "vfbcm"; ! 113: ! 114: extern long lseek(); ! 115: int rcmd(), dcmd(), xcmd(), tcmd(); ! 116: ! 117: int (*comfun)(); ! 118: char flg[26]; ! 119: char **namv; ! 120: int namc; ! 121: ! 122: main(argc, argv) ! 123: char *argv[]; ! 124: { ! 125: register char *cp; ! 126: ! 127: if (argc < 2) ! 128: usage(); ! 129: for (cp = argv[1]; *cp; cp++) ! 130: switch (*cp) { ! 131: ! 132: case 'm': ! 133: case 'v': ! 134: case 'u': ! 135: case 'w': ! 136: case 'b': ! 137: flg[*cp-'a']++; ! 138: continue; ! 139: case 'c': ! 140: flag(c)++; ! 141: dirdirty++; ! 142: continue; ! 143: ! 144: case 'r': ! 145: setcom(rcmd); ! 146: flag(r)++; ! 147: continue; ! 148: ! 149: case 'd': ! 150: setcom(dcmd); ! 151: flag(d)++; ! 152: continue; ! 153: ! 154: case 'x': ! 155: setcom(xcmd); ! 156: continue; ! 157: ! 158: case 't': ! 159: setcom(tcmd); ! 160: continue; ! 161: ! 162: case 'f': ! 163: defdev = argv[2]; ! 164: argv++; ! 165: argc--; ! 166: continue; ! 167: ! 168: default: ! 169: fprintf(stderr, "arff: bad option `%c'\n", *cp); ! 170: exit(1); ! 171: } ! 172: ! 173: namv = argv+2; ! 174: namc = argc-2; ! 175: if (comfun == 0) { ! 176: if (flag(u) == 0) { ! 177: fprintf(stderr, "arff: one of [%s] must be specified\n", ! 178: man); ! 179: exit(1); ! 180: } ! 181: setcom(rcmd); ! 182: } ! 183: (*comfun)(); ! 184: exit(notfound()); ! 185: } ! 186: ! 187: setcom(fun) ! 188: int (*fun)(); ! 189: { ! 190: if (comfun != 0) { ! 191: fprintf(stderr, "arff: only one of [%s] allowed\n", man); ! 192: exit(1); ! 193: } ! 194: comfun = fun; ! 195: } ! 196: ! 197: usage() ! 198: { ! 199: fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); ! 200: exit(1); ! 201: } ! 202: ! 203: notfound() ! 204: { ! 205: register i, n = 0; ! 206: ! 207: for (i = 0; i < namc; i++) ! 208: if (namv[i]) { ! 209: fprintf(stderr, "arff: %s not found\n", namv[i]); ! 210: n++; ! 211: } ! 212: return (n); ! 213: } ! 214: ! 215: tcmd() ! 216: { ! 217: register char *de, *last; ! 218: FLDOPE *lookup(), *dope; ! 219: int segnum, nleft; ! 220: register i; ! 221: register struct rt_ent *rde; ! 222: ! 223: rt_init(); ! 224: if (namc != 0) { ! 225: for (i = 0; i < namc; i++) ! 226: if (dope = lookup(namv[i])) { ! 227: rde = dope->rtdope; ! 228: (void) rtls(rde); ! 229: namv[i] = 0; ! 230: } ! 231: return; ! 232: } ! 233: for (segnum = 0; segnum != -1; ! 234: segnum = rt_dir[segnum].rd_nxtseg - 1) { ! 235: last = rt_last + segnum*2*RT_BLOCK; ! 236: for (de = ((char *)&rt_dir[segnum])+10; de <= last; ! 237: de += rt_entsiz) ! 238: if (rtls(rt(de))) { ! 239: nleft = (last-de)/rt_entsiz; ! 240: #define ENTRIES "\n%d entries remaining in directory segment %d.\n" ! 241: printf(ENTRIES, nleft, segnum+1); ! 242: break; ! 243: } ! 244: } ! 245: } ! 246: ! 247: rtls(de) ! 248: register struct rt_ent *de; ! 249: { ! 250: int month, day, year; ! 251: char name[12], ext[4]; ! 252: ! 253: switch (de->rt_stat) { ! 254: ! 255: case RT_TEMP: ! 256: if (flag(v)) ! 257: printf("Tempfile:\n"); ! 258: /* fall thru...*/ ! 259: ! 260: case RT_FILE: ! 261: if (!flag(v)) { ! 262: sunrad50(name, de->rt_name); ! 263: printf("%s\n", name); ! 264: break; ! 265: } ! 266: unrad50(2, de->rt_name, name); ! 267: unrad50(1, &(de->rt_name[2]), ext); ! 268: day = de->rt_date.rt_dy; ! 269: year = de->rt_date.rt_yr+72; ! 270: month = de->rt_date.rt_mo; ! 271: printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, ! 272: ext, month, day, year, de->rt_len); ! 273: break; ! 274: ! 275: case RT_NULL: ! 276: printf("%-25.9s %d\n","<UNUSED>", de->rt_len); ! 277: break; ! 278: ! 279: case RT_ESEG: ! 280: return (1); ! 281: } ! 282: return (0); ! 283: } ! 284: ! 285: xcmd() ! 286: { ! 287: register char *de, *last; ! 288: int segnum; ! 289: char name[12]; ! 290: register int i; ! 291: ! 292: rt_init(); ! 293: if (namc != 0) { ! 294: for (i = 0; i < namc; i++) ! 295: if (rtx(namv[i]) == 0) ! 296: namv[i] = 0; ! 297: return; ! 298: } ! 299: for (segnum = 0; segnum != -1; ! 300: segnum = rt_dir[segnum].rd_nxtseg-1) ! 301: for (last = rt_last+(segnum*2*RT_BLOCK), ! 302: de = ((char *)&rt_dir[segnum])+10; de <= last; ! 303: de += rt_entsiz) { ! 304: switch (rt(de)->rt_stat) { ! 305: ! 306: case RT_ESEG: ! 307: break; /* exit loop and try next segment */ ! 308: ! 309: case RT_TEMP: ! 310: case RT_FILE: ! 311: sunrad50(name,rt(de)->rt_name); ! 312: (void) rtx(name); ! 313: ! 314: case RT_NULL: ! 315: default: ! 316: continue; ! 317: } ! 318: break; ! 319: } ! 320: } ! 321: ! 322: rtx(name) ! 323: char *name; ! 324: { ! 325: register FLDOPE *dope; ! 326: FLDOPE *lookup(); ! 327: register startad, count; ! 328: int file; ! 329: char buff[512]; ! 330: ! 331: ! 332: if (dope = lookup(name)) { ! 333: if (flag(v)) ! 334: (void) rtls(dope->rtdope); ! 335: else ! 336: printf("x - %s\n",name); ! 337: ! 338: if ((file = creat(name, 0666)) < 0) ! 339: return (1); ! 340: count = dope->count; ! 341: startad = dope->startad; ! 342: for( ; count > 0 ; count -= 512) { ! 343: lread(startad, 512, buff); ! 344: (void) write(file, buff, 512); ! 345: startad += 512; ! 346: } ! 347: (void) close(file); ! 348: return (0); ! 349: } ! 350: return (1); ! 351: } ! 352: ! 353: rt_init() ! 354: { ! 355: static initized = 0; ! 356: register char *de, *last; ! 357: register i; ! 358: int dirnum; ! 359: char *mode; ! 360: FILE *temp_floppydes; ! 361: ! 362: if (initized) ! 363: return; ! 364: initized = 1; ! 365: if (flag(c)) { ! 366: struct stat sb; ! 367: char response[128]; ! 368: int tty; ! 369: ! 370: if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) ! 371: goto ignore; ! 372: tty = open("/dev/tty", O_RDWR); ! 373: #define SURE "Are you sure you want to clobber the floppy? " ! 374: (void) write(tty, SURE, sizeof (SURE)); ! 375: (void) read(tty, response, sizeof (response)); ! 376: if (*response != 'y') ! 377: exit(50); ! 378: (void) close(tty); ! 379: ignore: ! 380: ; ! 381: } ! 382: if (flag(c) || flag(d) || flag(r)) ! 383: mode = "r+"; ! 384: else ! 385: mode = "r"; ! 386: if ((temp_floppydes = fopen(defdev, mode)) == NULL) { ! 387: perror(defdev); ! 388: exit(1); ! 389: } else ! 390: floppydes = fileno(temp_floppydes); ! 391: if (!flag(c)) { ! 392: lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); ! 393: dirnum = rt_dir[0].rd_numseg; ! 394: /* check for blank/uninitialized diskette */ ! 395: if (dirnum <= 0) { ! 396: fprintf(stderr,"arff: bad directory format\n"); ! 397: exit(1); ! 398: } ! 399: if (dirnum > RT_DIRSIZE) { ! 400: fprintf(stderr,"arff: too many directory segments\n"); ! 401: exit(1); ! 402: } ! 403: for (i = 1; i < dirnum; i++) ! 404: lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); ! 405: } else { ! 406: dirnum = 1; ! 407: if (flag(b)) { ! 408: rt_dir[0].rd_numseg = 31; ! 409: rt_dir[0].rd_stfile = 68; ! 410: rt_dir[0].rt_ents[0].rt_len = 20480 - 68; ! 411: } ! 412: } ! 413: ! 414: rt_entsiz = 2*rt_dir[0].rd_entpad + 14; ! 415: /* ! 416: * We assume that the directory entries have no padding. This ! 417: * may not be a valid assumption, but there are numerous point ! 418: * in the code where it assumes it is an rt_ent structure and ! 419: * not an rt_entsiz sized structure. ! 420: */ ! 421: rt_entsiz = 14; ! 422: rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; ! 423: rt_nleft = 0; ! 424: ! 425: for (i = 0; i < dirnum; i++) { ! 426: last = rt_last + i*2*RT_BLOCK; ! 427: for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) ! 428: if (rt(de)->rt_stat == RT_ESEG) ! 429: break; ! 430: rt_curend[i] = rt(de); ! 431: rt_nleft += (last-de)/rt_entsiz; ! 432: } ! 433: } ! 434: ! 435: static FLDOPE result; ! 436: ! 437: FLDOPE * ! 438: lookup(name) ! 439: char *name; ! 440: { ! 441: unsigned short rname[3]; ! 442: register char *de; ! 443: int segnum; ! 444: register index; ! 445: ! 446: srad50(name,rname); ! 447: ! 448: /* ! 449: * Search for name, accumulate blocks in index ! 450: */ ! 451: rt_init(); ! 452: for (segnum = 0; segnum != -1; ! 453: segnum = rt_dir[segnum].rd_nxtseg - 1) ! 454: { ! 455: index = 0; ! 456: for (de=((char *)&rt_dir[segnum])+10; ! 457: rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) ! 458: switch(rt(de)->rt_stat) { ! 459: ! 460: case RT_FILE: ! 461: case RT_TEMP: ! 462: if(samename(rname,rt(de)->rt_name)) { ! 463: result.count = rt(de)->rt_len * 512; ! 464: result.startad = 512* ! 465: (rt_dir[segnum].rd_stfile + index); ! 466: result.rtdope = (struct rt_ent *) de; ! 467: return (&result); ! 468: } ! 469: ! 470: case RT_NULL: ! 471: index += rt(de)->rt_len; ! 472: } ! 473: } ! 474: return ((FLDOPE *) 0); ! 475: ! 476: } ! 477: ! 478: static ! 479: samename(a, b) ! 480: u_short a[], b[]; ! 481: { ! 482: return (*a == *b && a[1] == b[1] && a[2] == b[2] ); ! 483: } ! 484: ! 485: rad50(cp, out) ! 486: register u_char *cp; ! 487: u_short *out; ! 488: { ! 489: register index, temp; ! 490: ! 491: for (index = 0; *cp; index++) { ! 492: temp = Ain1 * table[*cp++]; ! 493: if (*cp!=0) { ! 494: temp += Ain2 * table[*cp++]; ! 495: if(*cp!=0) ! 496: temp += table[*cp++]; ! 497: } ! 498: out[index] = temp; ! 499: } ! 500: } ! 501: ! 502: #define reduce(x, p, q) (x = v[p/q], p %= q); ! 503: ! 504: unrad50(count, in, cp) ! 505: u_short *in; ! 506: register char *cp; ! 507: { ! 508: register i, temp; ! 509: register u_char *v = (u_char *) val; ! 510: ! 511: for (i = 0; i < count; i++) { ! 512: temp = in[i]; ! 513: reduce(*cp++, temp, Ain1); ! 514: reduce(*cp++, temp, Ain2); ! 515: reduce(*cp++, temp, 1); ! 516: } ! 517: *cp=0; ! 518: } ! 519: ! 520: srad50(name, rname) ! 521: register char *name; ! 522: register u_short *rname; ! 523: { ! 524: register index; ! 525: register char *cp; ! 526: char file[7], ext[4]; ! 527: ! 528: /* ! 529: * Find end of pathname ! 530: */ ! 531: for (cp = name; *cp++; ) ! 532: ; ! 533: while (cp >= name && *--cp != '/') ! 534: ; ! 535: cp++; ! 536: /* ! 537: * Change to rad50 ! 538: */ ! 539: for (index = 0; *cp; ) { ! 540: file[index++] = *cp++; ! 541: if (*cp == '.') { ! 542: cp++; ! 543: break; ! 544: } ! 545: if (index >= 6) { ! 546: break; ! 547: } ! 548: } ! 549: file[index] = 0; ! 550: for (index = 0; *cp; ) { ! 551: ext[index++] = *cp++; ! 552: if (*cp == '.' || index >= 3) ! 553: break; ! 554: } ! 555: ext[index]=0; ! 556: rname[0] = rname[1] = rname[2] = 0; ! 557: rad50((u_char *)file, rname); ! 558: rad50((u_char *)ext, rname+2); ! 559: } ! 560: ! 561: sunrad50(name, rname) ! 562: u_short rname[]; ! 563: register char *name; ! 564: { ! 565: register char *cp, *cp2; ! 566: char ext[4]; ! 567: ! 568: unrad50(2, rname, name); ! 569: unrad50(1, rname + 2, ext); ! 570: /* ! 571: * Jam name and extension together with a dot ! 572: * deleting white space ! 573: */ ! 574: for (cp = name; *cp++;) ! 575: ; ! 576: --cp; ! 577: while (*--cp == ' ' && cp >= name) ! 578: ; ! 579: *++cp = '.'; ! 580: cp++; ! 581: for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) ! 582: *cp++ = *cp2++; ! 583: *cp=0; ! 584: if (cp[-1] == '.') ! 585: cp[-1] = 0; ! 586: } ! 587: ! 588: static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; ! 589: ! 590: static char table[256] = { ! 591: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ! 592: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ! 593: 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, ! 594: 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, ! 595: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ! 596: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, ! 597: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ! 598: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, ! 599: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ! 600: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ! 601: 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, ! 602: 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, ! 603: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ! 604: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, ! 605: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ! 606: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; ! 607: ! 608: /* ! 609: * Logical to physical adress translation ! 610: */ ! 611: long ! 612: trans(logical) ! 613: register int logical; ! 614: { ! 615: register int sector, bytes, track; ! 616: ! 617: logical += 26*128; ! 618: bytes = (logical&127); ! 619: logical >>= 7; ! 620: sector = logical%26; ! 621: if(sector >= 13) ! 622: sector = sector*2+1; ! 623: else ! 624: sector *= 2; ! 625: sector += 26 + ((track = (logical/26))-1)*6; ! 626: sector %= 26; ! 627: return ((((track*26)+sector) << 7) + bytes); ! 628: } ! 629: ! 630: lread(startad, count, obuff) ! 631: register startad, count; ! 632: register char *obuff; ! 633: { ! 634: long trans(); ! 635: extern floppydes; ! 636: register int size = flag(m) ? 512 : 128; ! 637: ! 638: rt_init(); ! 639: while ((count -= size) >= 0) { ! 640: (void) lseek(floppydes, flag(m) ? ! 641: (long)startad : trans(startad), 0); ! 642: if (read(floppydes, obuff, size) != size) ! 643: fprintf(stderr, "arff: read error block %d\n", ! 644: startad/size); ! 645: obuff += size; ! 646: startad += size; ! 647: } ! 648: } ! 649: ! 650: lwrite(startad, count, obuff) ! 651: register startad, count; ! 652: register char *obuff; ! 653: { ! 654: long trans(); ! 655: extern floppydes; ! 656: register int size = flag(m) ? 512 : 128; ! 657: ! 658: rt_init(); ! 659: while ((count -= size) >= 0) { ! 660: (void) lseek(floppydes, flag(m) ? ! 661: (long)startad : trans(startad), 0); ! 662: if (write(floppydes, obuff, size) != size) ! 663: fprintf(stderr, "arff: write error block %d\n", ! 664: startad/size); ! 665: obuff += size; ! 666: startad += size; ! 667: } ! 668: } ! 669: ! 670: rcmd() ! 671: { ! 672: register int i; ! 673: ! 674: rt_init(); ! 675: if (namc > 0) ! 676: for (i = 0; i < namc; i++) ! 677: if (rtr(namv[i]) == 0) ! 678: namv[i] = 0; ! 679: } ! 680: ! 681: rtr(name) ! 682: char *name; ! 683: { ! 684: register FLDOPE *dope; ! 685: register struct rt_ent *de; ! 686: struct stat buf; ! 687: register struct stat *bufp = &buf; ! 688: int segnum; ! 689: char type; ! 690: ! 691: if (stat(name, bufp) < 0) { ! 692: perror(name); ! 693: return (-1); ! 694: } ! 695: type = 'a'; ! 696: if (dope = lookup(name)) { ! 697: /* can replace, no problem */ ! 698: de = dope->rtdope; ! 699: if (bufp->st_size <= (de->rt_len * 512)) { ! 700: printf("r - %s\n",name); ! 701: toflop(name, bufp->st_size, dope); ! 702: goto found; ! 703: } else { ! 704: de = dope->rtdope; ! 705: type = 'r'; ! 706: de->rt_stat = RT_NULL; ! 707: de->rt_name[0] = 0; ! 708: de->rt_name[1] = 0; ! 709: de->rt_name[2] = 0; ! 710: *((u_short *)&(de->rt_date)) = 0; ! 711: scrunch(); ! 712: } ! 713: } ! 714: /* ! 715: * Search for vacant spot ! 716: */ ! 717: for (segnum = 0; segnum != -1; ! 718: segnum = rt_dir[segnum].rd_nxtseg - 1) ! 719: { ! 720: for (de = rt_dir[segnum].rt_ents; ! 721: rt(de)->rt_stat != RT_ESEG; de++) ! 722: if ((de)->rt_stat == RT_NULL) { ! 723: if (bufp->st_size <= (de->rt_len*512)) { ! 724: printf("%c - %s\n", type, name), ! 725: mkent(de, segnum, bufp,name); ! 726: goto found; ! 727: } ! 728: continue; ! 729: } ! 730: } ! 731: if (type = 'r') ! 732: printf("%s: no slot for file, file deleted\n",name); ! 733: else ! 734: printf("%s: no slot for file\n", name); ! 735: return (-1); ! 736: ! 737: found: ! 738: if (dope = lookup(name)) { ! 739: toflop(name, bufp->st_size, dope); ! 740: return (0); ! 741: } ! 742: printf("%s: internal error, added then not found\n", name); ! 743: return (-1); ! 744: } ! 745: ! 746: mkent(de, segnum, bufp, name) ! 747: register struct rt_ent *de; ! 748: int segnum; ! 749: register struct stat *bufp; ! 750: char *name; ! 751: { ! 752: struct tm *localtime(); ! 753: register struct tm *timp; ! 754: register struct rt_ent *workp; ! 755: int count; ! 756: ! 757: count = (((bufp->st_size -1) >>9) + 1); ! 758: /* make sure there is room */ ! 759: if (de->rt_len == count) ! 760: goto overwrite; ! 761: if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { ! 762: /* no entries left on segment, trying adding new segment */ ! 763: if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { ! 764: short newseg; ! 765: register int i; ! 766: int maxseg; ! 767: short size; ! 768: ! 769: newseg = rt_dir[0].rd_lstseg++; ! 770: rt_dir[newseg] = rt_nulldir; ! 771: rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; ! 772: rt_dir[segnum].rd_nxtseg = newseg + 1; ! 773: rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; ! 774: rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; ! 775: size = 0; ! 776: maxseg = 0; ! 777: for(i = newseg - 1; i >= 0; i--) { ! 778: workp = rt_curend[i] - 1; ! 779: if (workp->rt_stat != RT_NULL) ! 780: continue; ! 781: if (workp->rt_len < size) ! 782: continue; ! 783: size = workp->rt_len; ! 784: maxseg = i; ! 785: } ! 786: size = 0; ! 787: for (workp = &rt_dir[maxseg].rt_ents[0]; ! 788: workp->rt_stat != RT_ESEG; workp++) { ! 789: size += workp->rt_len; ! 790: } ! 791: workp--; ! 792: rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; ! 793: rt_dir[newseg].rd_stfile = ! 794: rt_dir[maxseg].rd_stfile + size - workp->rt_len; ! 795: workp->rt_len = 0; ! 796: rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; ! 797: lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); ! 798: if (segnum != 0) ! 799: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, ! 800: (char *)&rt_dir[segnum]); ! 801: lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, ! 802: (char *)&rt_dir[newseg]); ! 803: segnum = newseg; ! 804: de = &rt_dir[newseg].rt_ents[0]; ! 805: } else { ! 806: fprintf(stderr, "All directory segments full on %s\n", ! 807: defdev); ! 808: exit(1); ! 809: } ! 810: } ! 811: /* copy directory entries up */ ! 812: for (workp = rt_curend[segnum]+1; workp > de; workp--) ! 813: *workp = workp[-1]; ! 814: de[1].rt_len -= count; ! 815: de->rt_len = count; ! 816: rt_curend[segnum]++; ! 817: rt_nleft--; ! 818: ! 819: overwrite: ! 820: srad50(name,de->rt_name); ! 821: timp = localtime(&bufp->st_mtime); ! 822: de->rt_date.rt_dy = timp->tm_mday; ! 823: de->rt_date.rt_mo = timp->tm_mon + 1; ! 824: de->rt_date.rt_yr = timp->tm_year - 72; ! 825: de->rt_stat = RT_FILE; ! 826: de->rt_pad = 0; ! 827: de->rt_chan = 0; ! 828: de->rt_job = 0; ! 829: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); ! 830: } ! 831: ! 832: toflop(name, ocount, dope) ! 833: char *name; ! 834: register FLDOPE *dope; ! 835: long ocount; ! 836: { ! 837: register file, n, startad = dope->startad, count = ocount; ! 838: char buff[512]; ! 839: ! 840: file = open(name, 0); ! 841: if (file < 0) { ! 842: fprintf(stderr, "arff: couldn't open %s\n",name); ! 843: exit(1); ! 844: } ! 845: for( ; count >= 512; count -= 512) { ! 846: (void) read(file, buff, 512); ! 847: lwrite(startad, 512, buff); ! 848: startad += 512; ! 849: } ! 850: (void) read(file, buff, count); ! 851: (void) close(file); ! 852: if (count <= 0) ! 853: return; ! 854: for (n = count; n < 512; n ++) ! 855: buff[n] = 0; ! 856: lwrite(startad, 512, buff); ! 857: count = (dope->rtdope->rt_len*512-ocount)/512 ; ! 858: if (count <= 0) ! 859: return; ! 860: for ( ; count > 0 ; count--) { ! 861: startad += 512; ! 862: lwrite(startad, 512, zeroes); ! 863: } ! 864: } ! 865: ! 866: dcmd() ! 867: { ! 868: register int i; ! 869: ! 870: rt_init(); ! 871: if (namc) ! 872: for (i = 0; i < namc; i++) ! 873: if (rtk(namv[i])==0) ! 874: namv[i]=0; ! 875: if (dirdirty) ! 876: scrunch(); ! 877: } ! 878: ! 879: rtk(name) ! 880: char *name; ! 881: { ! 882: register FLDOPE *dope; ! 883: register struct rt_ent *de; ! 884: FLDOPE *lookup(); ! 885: ! 886: if (dope = lookup(name)) { ! 887: printf("d - %s\n",name); ! 888: de = dope->rtdope; ! 889: de->rt_stat = RT_NULL; ! 890: de->rt_name[0] = 0; ! 891: de->rt_name[1] = 0; ! 892: de->rt_name[2] = 0; ! 893: *((u_short *)&(de->rt_date)) = 0; ! 894: dirdirty = 1; ! 895: return (0); ! 896: } ! 897: return (1); ! 898: } ! 899: ! 900: scrunch() ! 901: { ! 902: register struct rt_ent *de , *workp; ! 903: register segnum; ! 904: ! 905: for (segnum = 0; segnum != -1; ! 906: segnum = rt_dir[segnum].rd_nxtseg - 1) { ! 907: for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) ! 908: if (de->rt_stat == RT_NULL && ! 909: (de+1)->rt_stat == RT_NULL) { ! 910: (de+1)->rt_len += de->rt_len; ! 911: for (workp=de; workp<rt_curend[segnum]; workp++) ! 912: *workp = workp[1]; ! 913: de--; ! 914: rt_curend[segnum]--; ! 915: rt_nleft++; ! 916: } ! 917: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, ! 918: (char *)&rt_dir[segnum]); ! 919: } ! 920: dirdirty = 0; ! 921: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.