Annotation of researchv10no/netfs/serv/f6.c, revision 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.