Annotation of researchv10no/netfs/serv/f6.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.