|
|
1.1 ! root 1: /* ! 2: * read a V7 PDP-11 filesystem ! 3: * quick hack: assumed to be on a VAX (byte order matters) ! 4: */ ! 5: ! 6: /* ! 7: * miscellaneous filesystem definitions ! 8: * some are magic numbers here ! 9: */ ! 10: ! 11: #include <sys/param.h> ! 12: #include <sys/filsys.h> ! 13: #include <sys/ino.h> ! 14: #include <sys/inode.h> ! 15: #include <sys/dir.h> ! 16: ! 17: #define BLSIZE 512 ! 18: ! 19: #include "rf.h" ! 20: #include <errno.h> ! 21: #include <libc.h> ! 22: ! 23: int fserrno; ! 24: static int devfd; ! 25: static Rfile *root; ! 26: ! 27: typedef struct Fsfile { ! 28: daddr_t addr[NADDR]; ! 29: } Fsfile; ! 30: #define fsp(f) ((Fsfile *)((f)->fs)) ! 31: ! 32: /* ! 33: * init: ! 34: * open the device ! 35: */ ! 36: ! 37: Rfile * ! 38: fsinit(argc, argv) ! 39: int argc; ! 40: char **argv; ! 41: { ! 42: register Rfile *f; ! 43: ! 44: if (argc <= 1) ! 45: rfpanic("no device specified\n"); ! 46: if ((devfd = open(argv[0], 0)) < 0) ! 47: rfpanic("%s: cannot open\n", argv[1]); ! 48: /* never mind the super-block */ ! 49: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) ! 50: rfpanic("no mem for root\n"); ! 51: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) ! 52: rfpanic("no mem for root\n"); ! 53: f->ino = ROOTINO; ! 54: fsstat(f); ! 55: root = f; ! 56: return (f); ! 57: } ! 58: ! 59: /* ! 60: * access a file ! 61: */ ! 62: ! 63: Rfile * ! 64: fswalk(df, name) ! 65: register Rfile *df; ! 66: char *name; ! 67: { ! 68: register Rfile *f; ! 69: int ino; ! 70: ! 71: if ((ino = dsearch(df, name)) == 0) { ! 72: fserrno = ENOENT; ! 73: return (NULL); ! 74: } ! 75: if (df == root) { /* "." and ".." magic */ ! 76: if (strcmp(name, ".") == 0) ! 77: return (df); ! 78: if (strcmp(name, "..") == 0) { ! 79: fserrno = 0; /* pseudo-error: popped out of root */ ! 80: return (NULL); ! 81: } ! 82: } ! 83: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) { ! 84: fserrno = ENOMEM; ! 85: return (NULL); ! 86: } ! 87: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) { ! 88: free((char *)f); ! 89: fserrno = ENOMEM; ! 90: return (NULL); ! 91: } ! 92: f->ino = ino; ! 93: fsstat(f); ! 94: return (f); ! 95: } ! 96: ! 97: /* ! 98: * discard a file reference ! 99: */ ! 100: int ! 101: fsdone(f) ! 102: Rfile *f; ! 103: { ! 104: ! 105: free(f->fs); ! 106: free((char *)f); ! 107: return (0); ! 108: } ! 109: ! 110: /* ! 111: * return file status ! 112: */ ! 113: int ! 114: fsstat(f) ! 115: Rfile *f; ! 116: { ! 117: ! 118: getino(f); ! 119: return (0); ! 120: } ! 121: ! 122: /* ! 123: * read data ! 124: */ ! 125: int ! 126: fsread(f, off, buf, len) ! 127: register Rfile *f; ! 128: long off; ! 129: char *buf; ! 130: int len; ! 131: { ! 132: char blk[BLSIZE]; ! 133: int rest; ! 134: daddr_t bno; ! 135: ! 136: switch (f->mode & IFMT) { ! 137: case IFREG: ! 138: case IFDIR: ! 139: break; ! 140: ! 141: default: ! 142: return (0); ! 143: } ! 144: if (off >= f->size) ! 145: return (0); ! 146: if (off + len > f->size) ! 147: len = f->size - off; ! 148: bno = off / BLSIZE; ! 149: if (getlblk(f, bno, blk) == 0) ! 150: return (-1); ! 151: rest = (bno + 1)*BLSIZE - off; ! 152: if (len > rest) ! 153: len = rest; ! 154: memcpy(buf, blk + (off % BLSIZE), len); ! 155: return (len); ! 156: } ! 157: ! 158: /* ! 159: * read a piece of a directory ! 160: * -- cheap out for now: just return one ! 161: */ ! 162: int ! 163: fsdirread(f, off, buf, len, offp) ! 164: register Rfile *f; ! 165: long off; ! 166: char *buf; ! 167: int len; ! 168: long *offp; ! 169: { ! 170: int stlen; ! 171: register struct direct *de; ! 172: char blk[BLSIZE]; ! 173: char one[BLSIZE]; ! 174: int n; ! 175: ! 176: if (off % sizeof(struct direct)) { ! 177: fserrno = EINVAL; ! 178: return (-1); ! 179: } ! 180: stlen = len; ! 181: de = (struct direct *)&blk[BLSIZE]; ! 182: for (; off < f->size; de++, off += sizeof(struct direct)) { ! 183: if (de >= (struct direct *)&blk[BLSIZE]) { ! 184: if (getlblk(f, off/BLSIZE, blk) == 0) ! 185: break; ! 186: de = (struct direct *)&blk[off%BLSIZE]; ! 187: } ! 188: if (de->d_ino == 0) ! 189: continue; ! 190: n = sprint(one, "%d\t%.14s", de->d_ino, de->d_name); ! 191: n++; /* need the NUL too */ ! 192: if (n > len) ! 193: break; ! 194: memcpy(buf, one, n); ! 195: len -= n; ! 196: buf += n; ! 197: } ! 198: *offp = off; ! 199: return (stlen - len); ! 200: } ! 201: ! 202: /* ! 203: * fetch an i-node ! 204: * -- no sanity check for now ! 205: * -- magic inode-to-disk-block stuff here ! 206: */ ! 207: ! 208: #define LINOPB (BLSIZE/sizeof(struct dinode)) ! 209: int ! 210: getino(f) ! 211: register Rfile *f; ! 212: { ! 213: char buf[BLSIZE]; ! 214: register struct dinode *dp; ! 215: register unsigned int ioff; ! 216: ! 217: ioff = f->ino - 1; ! 218: lseek(devfd, (long)BLSIZE*(ioff/LINOPB + SUPERB + 1), 0); ! 219: if (read(devfd, buf, BLSIZE) != BLSIZE) { ! 220: /* print error */ ! 221: return (0); ! 222: } ! 223: dp = ((struct dinode *)buf) + (ioff%LINOPB); ! 224: switch (dp->di_mode & IFMT) { ! 225: case IFREG: ! 226: case IFDIR: ! 227: case IFBLK: ! 228: case IFCHR: ! 229: break; ! 230: ! 231: default: ! 232: return (0); /* unalloc or illegal */ ! 233: } ! 234: l11tol(fsp(f)->addr, dp->di_addr, NADDR); ! 235: f->dev = 0; ! 236: f->rdev = fsp(f)->addr[0]; /* perhaps wrong; who cares? */ ! 237: f->mode = dp->di_mode; ! 238: f->nlink = dp->di_nlink; ! 239: f->uid = dp->di_uid; ! 240: f->gid = dp->di_gid; ! 241: f->size = p11long(dp->di_size); ! 242: f->tm = p11long(dp->di_mtime); ! 243: f->ta = p11long(dp->di_atime); ! 244: f->tc = p11long(dp->di_ctime); ! 245: return (1); ! 246: } ! 247: ! 248: l11tol(l3, l, n) ! 249: register unsigned char *l3, *l; ! 250: register int n; ! 251: { ! 252: while (--n >= 0) { ! 253: *l++ = l3[2]; ! 254: *l++ = l3[3]; ! 255: *l++ = l3[1]; ! 256: *l++ = 0; ! 257: l3 += 3; ! 258: } ! 259: } ! 260: ! 261: long ! 262: p11long(l) ! 263: long l; ! 264: { ! 265: return ((l<<16) | ((l>>16)&0xffff)); ! 266: } ! 267: ! 268: /* ! 269: * look up a file ! 270: */ ! 271: ! 272: #define LNDPB (BLSIZE/sizeof(struct direct)) ! 273: ! 274: int ! 275: dsearch(f, name) ! 276: Rfile *f; ! 277: char *name; ! 278: { ! 279: struct direct dbuf[LNDPB]; ! 280: register struct direct *de; ! 281: register int i; ! 282: register long b, size; ! 283: ! 284: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) { ! 285: if (getlblk(f, b, (char *)dbuf) == 0) ! 286: continue; ! 287: for (i = 0, de = dbuf; i < LNDPB; i++, de++) { ! 288: if (de->d_ino == 0) ! 289: continue; ! 290: if (strncmp(de->d_name, name, DIRSIZ) == 0) ! 291: return (de->d_ino); ! 292: } ! 293: } ! 294: return (0); ! 295: } ! 296: ! 297: /* ! 298: * read a block from a file ! 299: */ ! 300: daddr_t bmap(); ! 301: ! 302: getlblk(f, bno, buf) ! 303: Rfile *f; ! 304: daddr_t bno; ! 305: char *buf; ! 306: { ! 307: daddr_t dbno; ! 308: ! 309: if ((dbno = bmap(f, bno)) == 0) { ! 310: memset(buf, 0, BLSIZE); ! 311: return (1); ! 312: } ! 313: lseek(devfd, dbno*BLSIZE, 0); ! 314: if (read(devfd, buf, BLSIZE) != BLSIZE) { ! 315: fserrno = errno; ! 316: return (0); ! 317: } ! 318: return (1); ! 319: } ! 320: ! 321: /* ! 322: * logical to physical block ! 323: * only singly-indirect files for now ! 324: */ ! 325: #define LNINDIR (BLSIZE/sizeof(daddr_t)) ! 326: ! 327: daddr_t ! 328: bmap(f, bno) ! 329: register Rfile *f; ! 330: daddr_t bno; ! 331: { ! 332: daddr_t indbuf[LNINDIR]; ! 333: ! 334: if (bno < NADDR - 3) ! 335: return (fsp(f)->addr[bno]); ! 336: bno -= NADDR - 3; ! 337: if (bno >= LNINDIR) ! 338: return (0); ! 339: lseek(devfd, fsp(f)->addr[NADDR-3]*BLSIZE, 0); ! 340: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE) ! 341: return (0); ! 342: return (indbuf[bno]); ! 343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.