|
|
1.1 ! root 1: /* ! 2: * read an old (V6 and before) PDP-11 Unix filesystem ! 3: * quick, cheap hack; runs only on VAXes ! 4: */ ! 5: ! 6: /* ! 7: * miscellaneous filesystem definitions ! 8: * some are magic numbers here ! 9: */ ! 10: ! 11: #include <stdio.h> ! 12: #include <sys/types.h> ! 13: #include <sys/inode.h> ! 14: #include <sys/dir.h> /* hack: pdp11 dirs == vax dirs */ ! 15: ! 16: #define BLSIZE 512 ! 17: ! 18: /* ! 19: * v6 disk inode ! 20: */ ! 21: #define V6NADDR 8 ! 22: ! 23: struct v6dinode { ! 24: short flags; ! 25: unsigned char nlinks; ! 26: unsigned char uid; ! 27: unsigned char gid; ! 28: unsigned char hisize; ! 29: unsigned short losize; ! 30: unsigned short addr[V6NADDR]; ! 31: unsigned short atime[2]; /* pdp-11 order */ ! 32: unsigned short mtime[2]; /* pdp-11 order */ ! 33: }; ! 34: ! 35: /* ! 36: * type part of mode ! 37: */ ! 38: #define V6FMT 0160000 ! 39: #define V6IFREG 0100000 ! 40: #define V6IFDIR 0140000 ! 41: #define V6IFCHR 0120000 ! 42: #define V6IFBLK 0160000 ! 43: #define V6MODE 07777 ! 44: #define V6LARGE 010000 ! 45: ! 46: #define V6SUPERB 1 ! 47: #define V6ROOT 1 /* root inode */ ! 48: ! 49: /* ! 50: * local file data ! 51: */ ! 52: typedef struct Fsfile { ! 53: long addr[V6NADDR]; ! 54: int large; ! 55: } Fsfile; ! 56: ! 57: #define fsp(f) ((Fsfile *)((f)->fs)) ! 58: ! 59: #include "rf.h" ! 60: #include <errno.h> ! 61: #include <libc.h> ! 62: ! 63: int fserrno; ! 64: static int devfd; ! 65: static Rfile *root; ! 66: ! 67: /* ! 68: * init: ! 69: * open the device ! 70: */ ! 71: ! 72: Rfile * ! 73: fsinit(argc, argv) ! 74: int argc; ! 75: char **argv; ! 76: { ! 77: register Rfile *f; ! 78: char *passwd, *group; ! 79: ! 80: if (argc <= 1) ! 81: rfpanic("no device specified\n"); ! 82: if ((devfd = open(argv[1], 0)) < 0) ! 83: rfpanic("%s: cannot open\n", argv[1]); ! 84: if (argc > 2) ! 85: passwd = argv[2]; ! 86: else ! 87: passwd = "/etc/passwd"; ! 88: if (argc > 3) ! 89: group = argv[3]; ! 90: else ! 91: group = "/etc/group"; ! 92: rfuidmap = rfmkidmap(passwd, (Namemap *)0); ! 93: rfgidmap = rfmkidmap(group, (Namemap *)0); ! 94: /* never mind the super-block */ ! 95: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) ! 96: rfpanic("no mem for root\n"); ! 97: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) ! 98: rfpanic("no mem for root\n"); ! 99: f->ino = V6ROOT; ! 100: fsstat(f); ! 101: root = f; ! 102: return (f); ! 103: } ! 104: ! 105: /* ! 106: * access a file ! 107: */ ! 108: ! 109: Rfile * ! 110: fswalk(df, name) ! 111: Rfile *df; ! 112: char *name; ! 113: { ! 114: register Rfile *f; ! 115: int ino; ! 116: ! 117: if ((ino = dsearch(df, name)) == 0) { ! 118: fserrno = ENOENT; ! 119: return (NULL); ! 120: } ! 121: if (df == root) { /* "." and ".." magic */ ! 122: if (strcmp(name, ".") == 0) ! 123: return (df); ! 124: if (strcmp(name, "..") == 0) { ! 125: fserrno = 0; /* pseudo-error: popped out of root */ ! 126: return (NULL); ! 127: } ! 128: } ! 129: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) { ! 130: fserrno = ENOMEM; ! 131: return (NULL); ! 132: } ! 133: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) { ! 134: free((char *)f); ! 135: fserrno = ENOMEM; ! 136: return (NULL); ! 137: } ! 138: f->ino = ino; ! 139: fsstat(f); ! 140: return (f); ! 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: int ! 160: fsstat(f) ! 161: Rfile *f; ! 162: { ! 163: ! 164: getino(f); ! 165: return (0); ! 166: } ! 167: ! 168: /* ! 169: * read data ! 170: */ ! 171: int ! 172: fsread(f, off, buf, len) ! 173: register Rfile *f; ! 174: long off; ! 175: char *buf; ! 176: int len; ! 177: { ! 178: char blk[BLSIZE]; ! 179: int rest; ! 180: daddr_t bno; ! 181: ! 182: switch (f->mode & IFMT) { ! 183: case IFREG: ! 184: case IFDIR: ! 185: break; ! 186: ! 187: default: ! 188: return (0); ! 189: } ! 190: if (off >= f->size) ! 191: return (0); ! 192: if (off + len > f->size) ! 193: len = f->size - off; ! 194: bno = off / BLSIZE; ! 195: if (getlblk(f, bno, blk) == 0) ! 196: return (-1); ! 197: rest = (bno + 1)*BLSIZE - off; ! 198: if (len > rest) ! 199: len = rest; ! 200: memcpy(buf, blk + (off % BLSIZE), len); ! 201: return (len); ! 202: } ! 203: ! 204: /* ! 205: * read a piece of a directory ! 206: * -- cheap out for now: just return one ! 207: */ ! 208: int ! 209: fsdirread(f, off, buf, len, offp) ! 210: register Rfile *f; ! 211: long off; ! 212: char *buf; ! 213: int len; ! 214: long *offp; ! 215: { ! 216: int stlen; ! 217: register struct direct *de; ! 218: char blk[BLSIZE]; ! 219: char one[BLSIZE]; ! 220: int n; ! 221: ! 222: if (off % sizeof(struct direct)) { ! 223: fserrno = EINVAL; ! 224: return (-1); ! 225: } ! 226: stlen = len; ! 227: de = (struct direct *)&blk[BLSIZE]; ! 228: for (; off < f->size; de++, off += sizeof(struct direct)) { ! 229: if (de >= (struct direct *)&blk[BLSIZE]) { ! 230: if (getlblk(f, off/BLSIZE, blk) == 0) ! 231: break; ! 232: de = (struct direct *)&blk[off%BLSIZE]; ! 233: } ! 234: if (de->d_ino == 0) ! 235: continue; ! 236: n = sprintf(one, "%d\t%.14s", de->d_ino, de->d_name); ! 237: n++; /* need the NUL too */ ! 238: if (n > len) ! 239: break; ! 240: memcpy(buf, one, n); ! 241: len -= n; ! 242: buf += n; ! 243: } ! 244: *offp = off; ! 245: return (stlen - len); ! 246: } ! 247: ! 248: /* ! 249: * fetch an i-node ! 250: * -- no sanity check for now ! 251: * -- magic inode-to-disk-block stuff here ! 252: */ ! 253: ! 254: #define LINOPB (BLSIZE/sizeof(struct v6dinode)) ! 255: int ! 256: getino(f) ! 257: register Rfile *f; ! 258: { ! 259: char buf[BLSIZE]; ! 260: register struct v6dinode *dp; ! 261: register int ioff; ! 262: register int i; ! 263: int mode; ! 264: ! 265: ioff = f->ino - 1; ! 266: lseek(devfd, (long)BLSIZE*(ioff/LINOPB + V6SUPERB + 1), 0); ! 267: if (read(devfd, buf, BLSIZE) != BLSIZE) { ! 268: /* print error */ ! 269: return (0); ! 270: } ! 271: dp = ((struct v6dinode *)buf) + (ioff%LINOPB); ! 272: switch (dp->flags & V6FMT) { ! 273: case V6IFREG: ! 274: mode = IFREG; ! 275: break; ! 276: ! 277: case V6IFDIR: ! 278: mode = IFDIR; ! 279: break; ! 280: ! 281: case V6IFCHR: ! 282: mode = IFCHR; ! 283: break; ! 284: ! 285: case V6IFBLK: ! 286: mode = IFBLK; ! 287: break; ! 288: ! 289: default: ! 290: return (0); /* unalloc or illegal */ ! 291: } ! 292: for (i = 0; i < V6NADDR; i++) ! 293: fsp(f)->addr[i] = dp->addr[i]; ! 294: f->dev = 0; /* all the same device */ ! 295: f->rdev = fsp(f)->addr[0]; ! 296: f->mode = mode | (dp->flags & V6MODE); ! 297: fsp(f)->large = (dp->flags & V6LARGE) != 0; ! 298: f->nlink = dp->nlinks; ! 299: f->uid = dp->uid; ! 300: f->gid = dp->gid; ! 301: f->size = (dp->hisize << 16) + dp->losize; ! 302: f->tm = (dp->mtime[0]<<16) + dp->mtime[1]; ! 303: f->ta = (dp->atime[0]<<16) + dp->atime[1]; ! 304: f->tc = f->tm; ! 305: return (1); ! 306: } ! 307: ! 308: /* ! 309: * look up a file ! 310: */ ! 311: ! 312: #define LNDPB (BLSIZE/sizeof(struct direct)) ! 313: ! 314: int ! 315: dsearch(f, name) ! 316: Rfile *f; ! 317: char *name; ! 318: { ! 319: struct direct dbuf[LNDPB]; ! 320: register struct direct *de; ! 321: register int i; ! 322: register long b, size; ! 323: ! 324: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) { ! 325: if (getlblk(f, b, (char *)dbuf) == 0) ! 326: continue; ! 327: for (i = 0, de = dbuf; i < LNDPB; i++, de++) { ! 328: if (de->d_ino == 0) ! 329: continue; ! 330: if (strncmp(de->d_name, name, DIRSIZ) == 0) ! 331: return (de->d_ino); ! 332: } ! 333: } ! 334: return (0); ! 335: } ! 336: ! 337: /* ! 338: * read a block from a file ! 339: */ ! 340: daddr_t bmap(); ! 341: ! 342: getlblk(f, bno, buf) ! 343: Rfile *f; ! 344: daddr_t bno; ! 345: char *buf; ! 346: { ! 347: daddr_t dbno; ! 348: ! 349: if ((dbno = bmap(f, bno)) == 0) { ! 350: memset(buf, 0, BLSIZE); ! 351: return (1); ! 352: } ! 353: lseek(devfd, dbno*BLSIZE, 0); ! 354: if (read(devfd, buf, BLSIZE) != BLSIZE) { ! 355: fserrno = errno; ! 356: return (0); ! 357: } ! 358: return (1); ! 359: } ! 360: ! 361: /* ! 362: * logical to physical block ! 363: * only singly-indirect files for now ! 364: */ ! 365: #define LNINDIR (BLSIZE/sizeof(unsigned short)) ! 366: ! 367: daddr_t ! 368: bmap(f, bno) ! 369: register Rfile *f; ! 370: daddr_t bno; ! 371: { ! 372: unsigned short indbuf[LNINDIR]; ! 373: ! 374: if (fsp(f)->large == 0) { ! 375: if (bno < V6NADDR) ! 376: return (fsp(f)->addr[bno]); ! 377: return (0); ! 378: } ! 379: if (bno < V6NADDR*LNINDIR) { ! 380: lseek(devfd, fsp(f)->addr[bno/LNINDIR]*BLSIZE, 0); ! 381: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE) ! 382: return (0); ! 383: return (indbuf[bno%LNINDIR]); ! 384: } ! 385: return (0); ! 386: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.