|
|
1.1 ! root 1: /* ! 2: * read a 512-byte VAX-ordered Unix filesystem ! 3: * quick, cheap hack ! 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[1], 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: l3tol(fsp(f)->addr, dp->di_addr, NADDR); ! 235: f->dev = 0; ! 236: f->rdev = fsp(f)->addr[0]; ! 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 = dp->di_size; ! 242: f->tm = dp->di_mtime; ! 243: f->ta = dp->di_atime; ! 244: f->tc = dp->di_ctime; ! 245: return (1); ! 246: } ! 247: ! 248: /* ! 249: * look up a file ! 250: */ ! 251: ! 252: #define LNDPB (BLSIZE/sizeof(struct direct)) ! 253: ! 254: int ! 255: dsearch(f, name) ! 256: Rfile *f; ! 257: char *name; ! 258: { ! 259: struct direct dbuf[LNDPB]; ! 260: register struct direct *de; ! 261: register int i; ! 262: register long b, size; ! 263: ! 264: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) { ! 265: if (getlblk(f, b, (char *)dbuf) == 0) ! 266: continue; ! 267: for (i = 0, de = dbuf; i < LNDPB; i++, de++) { ! 268: if (de->d_ino == 0) ! 269: continue; ! 270: if (strncmp(de->d_name, name, DIRSIZ) == 0) ! 271: return (de->d_ino); ! 272: } ! 273: } ! 274: return (0); ! 275: } ! 276: ! 277: /* ! 278: * read a block from a file ! 279: */ ! 280: daddr_t bmap(); ! 281: ! 282: getlblk(f, bno, buf) ! 283: Rfile *f; ! 284: daddr_t bno; ! 285: char *buf; ! 286: { ! 287: daddr_t dbno; ! 288: ! 289: if ((dbno = bmap(f, bno)) == 0) { ! 290: memset(buf, 0, BLSIZE); ! 291: return (1); ! 292: } ! 293: lseek(devfd, dbno*BLSIZE, 0); ! 294: if (read(devfd, buf, BLSIZE) != BLSIZE) { ! 295: fserrno = errno; ! 296: return (0); ! 297: } ! 298: return (1); ! 299: } ! 300: ! 301: /* ! 302: * logical to physical block ! 303: * only singly-indirect files for now ! 304: */ ! 305: #define LNINDIR (BLSIZE/sizeof(daddr_t)) ! 306: ! 307: daddr_t ! 308: bmap(f, bno) ! 309: register Rfile *f; ! 310: daddr_t bno; ! 311: { ! 312: daddr_t indbuf[LNINDIR]; ! 313: ! 314: if (bno < NADDR - 3) ! 315: return (fsp(f)->addr[bno]); ! 316: bno -= NADDR - 3; ! 317: if (bno >= LNINDIR) ! 318: return (0); ! 319: lseek(devfd, fsp(f)->addr[NADDR-3]*BLSIZE, 0); ! 320: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE) ! 321: return (0); ! 322: return (indbuf[bno]); ! 323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.