|
|
1.1 ! root 1: /* ! 2: * file service routines for FILES-11 ODS-1 ! 3: * in its modern instance, with subdirectories ! 4: */ ! 5: ! 6: #include <rf.h> ! 7: #include "files11.h" ! 8: #include "f11.h" ! 9: ! 10: #define NULL 0 ! 11: #define HUGE 0x7fffffff ! 12: ! 13: int diskfd; ! 14: struct homeblock home; ! 15: Fsfile indexf; ! 16: unsigned short dirtyp; ! 17: ! 18: static htorf(); ! 19: static char *itoa(); ! 20: static int binchk(); ! 21: char *r50toa(); ! 22: char *malloc(); ! 23: ! 24: /* ! 25: * permission hacks ! 26: */ ! 27: #define UXOTHER 1 ! 28: static Idmap gmap[] = { "other", UXOTHER, 0 }; ! 29: ! 30: /* ! 31: * init: ! 32: * install the root ! 33: * ! 34: * argv[1] == the file containing our filesystem ! 35: */ ! 36: Rfile * ! 37: fsinit(argc, argv) ! 38: int argc; ! 39: char **argv; ! 40: { ! 41: register Rfile *f; ! 42: register long firsthdr; ! 43: char *p; ! 44: ! 45: p = "dir"; ! 46: dirtyp = ator50(&p); ! 47: if (argc <= 1) ! 48: rfpanic("no files-11 filesystem specified\n"); ! 49: if ((diskfd = open(argv[1], 0)) < 0) /* readonly for now */ ! 50: rfpanic("%s: cannot open\n", argv[1]); ! 51: if (lseek(diskfd, (long)HOMEBLK * BLKSIZ, 0) < 0) ! 52: rfpanic("can't seek for home block\n"); ! 53: if (read(diskfd, (char *)&home, sizeof(home)) != sizeof(home)) ! 54: rfpanic("can't read homeblock\n"); ! 55: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL ! 56: || (f->fs = malloc(sizeof(Fsfile))) == NULL) ! 57: rfpanic("no mem for root\n"); ! 58: firsthdr = plong(home.H_iblb)+home.H_ibsz; ! 59: lseek(diskfd, (firsthdr + fidtob(FINDEX)) * BLKSIZ, 0); ! 60: if (read(diskfd, (char *)&indexf.h, sizeof(indexf.h)) != sizeof(indexf.h)) ! 61: rfpanic("can't read index header\n"); ! 62: indexf.lbase = HUGE; ! 63: if (gethdr(FROOT, &fsp(f)->h) == 0) ! 64: rfpanic("can't read root header\n"); ! 65: htorf(f, &fsp(f)->h); ! 66: fsp(f)->parent = FROOT; ! 67: fsp(f)->lbase = HUGE; ! 68: fsp(f)->flags = FBIN; ! 69: fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0; ! 70: rfgidmap = gmap; ! 71: return (f); ! 72: } ! 73: ! 74: /* ! 75: * access a file ! 76: */ ! 77: Rfile * ! 78: fswalk(df, name) ! 79: Rfile *df; ! 80: char *name; ! 81: { ! 82: register Rfile *f; ! 83: unsigned short fid; ! 84: int binary; ! 85: ! 86: binary = binchk(name); ! 87: if (strcmp(name, ".") == 0) ! 88: return (df); ! 89: else if (strcmp(name, "..") == 0) { ! 90: if (df->ino == FROOT) { ! 91: fserrno = 0; /* magic: popped out */ ! 92: return (NULL); ! 93: } ! 94: fid = fsp(df)->parent; ! 95: } else if ((fid = f11walk(df, name)) == 0) ! 96: return (NULL); ! 97: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) { ! 98: rflog("no mem\n"); ! 99: fserrno = RFEINVAL; ! 100: return (NULL); ! 101: } ! 102: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) { ! 103: free((char *)f); ! 104: rflog("no mem\n"); ! 105: fserrno = RFEINVAL; ! 106: return (NULL); ! 107: } ! 108: fsp(f)->lbase = HUGE; ! 109: if (gethdr(fid, &fsp(f)->h) == 0) { ! 110: free((char *)f); ! 111: fserrno = RFEIO; ! 112: return (NULL); ! 113: } ! 114: if (fsp(f)->h.h_ident.i_fnam.f_typ == dirtyp) ! 115: fsp(f)->parent = fsp(df)->h.h_fnum; ! 116: htorf(f, &fsp(f)->h); ! 117: fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0; ! 118: if (binary) ! 119: fsp(f)->flags = FBIN; ! 120: else if (fsp(f)->h.h_fcs.f_rtyp == RTVAR && fsp(f)->h.h_fcs.f_ratt & RTCR) ! 121: fsp(f)->flags = 0; ! 122: else ! 123: fsp(f)->flags = FBIN; ! 124: return (f); ! 125: } ! 126: ! 127: /* ! 128: * see if filename is `binary': trailing % in name ! 129: * stamp it out if so ! 130: */ ! 131: static ! 132: binchk(name) ! 133: register char *name; ! 134: { ! 135: name += strlen(name); ! 136: if (*--name == '%') { ! 137: *name = 0; ! 138: return (1); ! 139: } ! 140: return (0); ! 141: } ! 142: ! 143: /* ! 144: * discard a file reference ! 145: */ ! 146: int ! 147: fsdone(f) ! 148: Rfile *f; ! 149: { ! 150: ! 151: free(f->fs); ! 152: free((char *)f); ! 153: return (0); ! 154: } ! 155: ! 156: /* ! 157: * return file status ! 158: */ ! 159: fsstat(f) ! 160: register Rfile *f; ! 161: { ! 162: ! 163: if (gethdr(fsp(f)->h.h_fnum, &fsp(f)->h) == 0) { ! 164: fserrno = RFEINVAL; ! 165: return (-1); ! 166: } ! 167: htorf(f, &fsp(f)->h); ! 168: return (0); ! 169: } ! 170: ! 171: /* ! 172: * read ! 173: */ ! 174: int ! 175: fsread(f, off, buf, len) ! 176: Rfile *f; ! 177: long off; ! 178: char *buf; ! 179: int len; ! 180: { ! 181: ! 182: if (fsp(f)->flags & FBIN) ! 183: return (binread(f, off, buf, len)); ! 184: else ! 185: return (textread(f, off, buf, len)); ! 186: } ! 187: ! 188: int ! 189: binread(f, off, buf, len) ! 190: Rfile *f; ! 191: long off; ! 192: char *buf; ! 193: int len; ! 194: { ! 195: char bbuf[BLKSIZ]; ! 196: int boff; ! 197: long bno; ! 198: int nread, r; ! 199: int ncpy; ! 200: ! 201: nread = 0; ! 202: bno = off / BLKSIZ; ! 203: boff = off % BLKSIZ; ! 204: /* ! 205: * contract this loop later ! 206: */ ! 207: r = 0; ! 208: while (len > 0) { ! 209: if ((r = f11rblk(f, bno, bbuf)) <= 0) ! 210: break; ! 211: ncpy = BLKSIZ - boff; ! 212: ncpy = (len > ncpy) ? ncpy : len; ! 213: memcpy(buf, bbuf+boff, ncpy); ! 214: len -= ncpy; ! 215: buf += ncpy; ! 216: nread += ncpy; ! 217: boff = 0; ! 218: bno++; ! 219: } ! 220: if (nread || r >= 0) ! 221: return (nread); ! 222: fserrno = RFEIO; ! 223: return (-1); ! 224: } ! 225: ! 226: int ! 227: textread(f, off, buf, len) ! 228: Rfile *f; ! 229: long off; ! 230: char *buf; ! 231: int len; ! 232: { ! 233: unsigned char bbuf[BLKSIZ]; ! 234: int boff; ! 235: long bno; ! 236: int nread, r; ! 237: int ncpy; ! 238: int rlen; ! 239: unsigned char *p; ! 240: ! 241: nread = 0; ! 242: if (off == fsp(f)->tuoff) { ! 243: bno = fsp(f)->tbno; ! 244: boff = fsp(f)->tboff; ! 245: } else if (off == 0) { ! 246: bno = 0; ! 247: boff = 0; ! 248: } else { /* wrong, but so what? */ ! 249: bno = off / BLKSIZ; ! 250: boff = off % BLKSIZ; ! 251: } ! 252: if ((r = f11rblk(f, bno, bbuf)) <= 0) ! 253: goto out; ! 254: p = bbuf + boff; ! 255: while (len > 0) { ! 256: if (boff & 01) { ! 257: p++; ! 258: boff++; ! 259: } ! 260: if ((bno * BLKSIZ) + boff >= f->size) ! 261: break; ! 262: rlen = p[0] + (p[1]<<8); ! 263: if (rlen == -1) { /* skip to next block */ ! 264: if ((r = f11rblk(f, ++bno, bbuf)) <= 0) ! 265: goto out; ! 266: p = bbuf; ! 267: boff = 0; ! 268: continue; ! 269: } ! 270: if (rlen + 1 > len) /* +1 for newline */ ! 271: /* set a particular error here? */ ! 272: break; ! 273: p += 2; ! 274: for (; rlen > 0; rlen -= ncpy) { ! 275: ncpy = &bbuf[BLKSIZ] - p; ! 276: if (ncpy > rlen) ! 277: ncpy = rlen; ! 278: memcpy(buf, p, ncpy); ! 279: p += ncpy; ! 280: boff = p - bbuf; ! 281: nread += ncpy; ! 282: buf += ncpy; ! 283: len -= ncpy; ! 284: if (ncpy < rlen) { /* next block */ ! 285: if ((r = f11rblk(f, ++bno, bbuf)) <= 0) ! 286: goto out; ! 287: p = bbuf; ! 288: boff = 0; ! 289: } ! 290: } ! 291: *buf++ = '\n'; ! 292: nread++; ! 293: len--; ! 294: if (boff > BLKSIZ - 2) { /* about to need new block */ ! 295: if ((r = f11rblk(f, ++bno, bbuf)) <= 0) ! 296: goto out; ! 297: p = bbuf; ! 298: boff = 0; ! 299: } ! 300: } ! 301: out: ! 302: if (boff == BLKSIZ) { ! 303: boff = 0; ! 304: bno++; ! 305: } ! 306: if (nread) { ! 307: fsp(f)->tuoff = off + nread; ! 308: fsp(f)->tbno = bno; ! 309: fsp(f)->tboff = boff; ! 310: } ! 311: if (nread || r >= 0) ! 312: return (nread); ! 313: fserrno = RFEIO; ! 314: return (-1); ! 315: } ! 316: ! 317: /* ! 318: * read directory -- ! 319: * return ascii records: decimal `i-number', tab, filename, NUL ! 320: * filename is filname.typ.ver ! 321: * *offp gets new file offset for directory ! 322: */ ! 323: #define DENTSIZE (6+9+4+6+1) /* max len of a directory record */ ! 324: ! 325: int ! 326: fsdirread(f, off, buf, len, offp) ! 327: Rfile *f; ! 328: long off; ! 329: char *buf; ! 330: int len; ! 331: long *offp; ! 332: { ! 333: char bbuf[BLKSIZ]; ! 334: register char *p; ! 335: register struct directory *dp; ! 336: struct directory *dend; ! 337: char *op; ! 338: int r; ! 339: long bno; ! 340: int boff; ! 341: ! 342: bno = off / BLKSIZ; ! 343: if ((r = f11rblk(f, bno, bbuf)) <= 0) { ! 344: fserrno = RFEIO; ! 345: return (r); ! 346: } ! 347: boff = off % BLKSIZ; ! 348: dp = (struct directory *)bbuf + (boff/sizeof(struct directory)); ! 349: dend = (struct directory *)&bbuf[BLKSIZ]; ! 350: p = buf; ! 351: while (len >= DENTSIZE) { ! 352: while (dp < dend && dp->d_fid.f_num == 0) ! 353: dp++; ! 354: if (dp >= dend) { ! 355: bno++; ! 356: dp = (struct directory *)bbuf; ! 357: if ((r = f11rblk(f, bno, bbuf)) <= 0) ! 358: break; ! 359: } ! 360: op = p; ! 361: p = itoa(p, dp->d_fid.f_num); ! 362: *p++ = '\t'; ! 363: p = r50toa(p, dp->d_fname.f_nam[0]); ! 364: p = r50toa(p, dp->d_fname.f_nam[1]); ! 365: p = r50toa(p, dp->d_fname.f_nam[2]); ! 366: while (p[-1] == ' ') ! 367: --p; ! 368: *p++ = '.'; ! 369: p = r50toa(p, dp->d_fname.f_typ); ! 370: while (p[-1] == ' ') ! 371: --p; ! 372: *p++ = '.'; ! 373: p = itoa(p, dp->d_fname.f_ver); ! 374: *p++ = 0; ! 375: len -= p - op; ! 376: dp++; ! 377: } ! 378: if (p == buf && r < 0) { ! 379: fserrno = RFEIO; ! 380: return (-1); ! 381: } ! 382: *offp = (bno * BLKSIZ) + (char *)dp - bbuf; ! 383: return (p - buf); ! 384: } ! 385: ! 386: /* ! 387: * f11 to rf file attributes ! 388: * -- temporary permission hack: ! 389: * turn apparent f11 other to asserted unix other group ! 390: */ ! 391: #define F11OTHER (-1) ! 392: ! 393: static ! 394: htorf(f, h) ! 395: register Rfile *f; ! 396: register struct header *h; ! 397: { ! 398: f->ino = h->h_fnum; ! 399: f->dev = 0; ! 400: f->mode = htouperm(h->h_fpro); ! 401: if (h->h_ident.i_fnam.f_typ != dirtyp) ! 402: f->type = RFTREG; ! 403: else { ! 404: f->mode |= (f->mode & 0444)>>2; /* copy `read' into `execute' */ ! 405: f->type = RFTDIR; ! 406: } ! 407: f->nlink = 1; ! 408: f->uid = h->h_fown.u_prog; ! 409: f->gid = h->h_fown.u_proj; ! 410: if (f->gid == F11OTHER) ! 411: f->gid = UXOTHER; ! 412: f->rdev = 0; ! 413: f->size = hfilesize(h); ! 414: f->ta = 0; ! 415: f->tm = htoutime(h->h_ident.i_rvdt); ! 416: f->tc = htoutime(h->h_ident.i_crdt); /* wrong, but let it stand */ ! 417: if (f->tm == 0) ! 418: f->tm = f->tc; ! 419: } ! 420: ! 421: /* ! 422: * number to string ! 423: */ ! 424: ! 425: static char digits[] = "0123456789"; ! 426: ! 427: static char * ! 428: itoa(s, n) ! 429: register char *s; ! 430: register unsigned int n; ! 431: { ! 432: register int d; ! 433: ! 434: if ((d = n / 10) == 0) ! 435: *s++ = digits[n]; ! 436: else { ! 437: s = itoa(s, d); ! 438: *s++ = digits[n % 10]; ! 439: } ! 440: return (s); ! 441: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.