Annotation of researchv10no/netfs/serv/f11.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * file service routines for FILES-11 ODS-1
        !             3:  * in its modern instance, with subdirectories
        !             4:  */
        !             5: 
        !             6: #include <rf.h>
        !             7: #include "files11.h"
        !             8: #include "f11.h"
        !             9: 
        !            10: #define        NULL    0
        !            11: #define        HUGE    0x7fffffff
        !            12: 
        !            13: int diskfd;
        !            14: struct homeblock home;
        !            15: Fsfile indexf;
        !            16: unsigned short dirtyp;
        !            17: 
        !            18: static htorf();
        !            19: static char *itoa();
        !            20: static int binchk();
        !            21: char *r50toa();
        !            22: char *malloc();
        !            23: 
        !            24: /*
        !            25:  * permission hacks
        !            26:  */
        !            27: #define        UXOTHER 1
        !            28: static Idmap gmap[] = { "other", UXOTHER, 0 };
        !            29: 
        !            30: /*
        !            31:  * init:
        !            32:  * install the root
        !            33:  *
        !            34:  * argv[1] == the file containing our filesystem
        !            35:  */
        !            36: Rfile *
        !            37: fsinit(argc, argv)
        !            38: int argc;
        !            39: char **argv;
        !            40: {
        !            41:        register Rfile *f;
        !            42:        register long firsthdr;
        !            43:        char *p;
        !            44: 
        !            45:        p = "dir";
        !            46:        dirtyp = ator50(&p);
        !            47:        if (argc <= 1)
        !            48:                rfpanic("no files-11 filesystem specified\n");
        !            49:        if ((diskfd = open(argv[1], 0)) < 0)    /* readonly for now */
        !            50:                rfpanic("%s: cannot open\n", argv[1]);
        !            51:        if (lseek(diskfd, (long)HOMEBLK * BLKSIZ, 0) < 0)
        !            52:                rfpanic("can't seek for home block\n");
        !            53:        if (read(diskfd, (char *)&home, sizeof(home)) != sizeof(home))
        !            54:                rfpanic("can't read homeblock\n");
        !            55:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL
        !            56:        ||  (f->fs = malloc(sizeof(Fsfile))) == NULL)
        !            57:                rfpanic("no mem for root\n");
        !            58:        firsthdr = plong(home.H_iblb)+home.H_ibsz;
        !            59:        lseek(diskfd, (firsthdr + fidtob(FINDEX)) * BLKSIZ, 0);
        !            60:        if (read(diskfd, (char *)&indexf.h, sizeof(indexf.h)) != sizeof(indexf.h))
        !            61:                rfpanic("can't read index header\n");
        !            62:        indexf.lbase = HUGE;
        !            63:        if (gethdr(FROOT, &fsp(f)->h) == 0)
        !            64:                rfpanic("can't read root header\n");
        !            65:        htorf(f, &fsp(f)->h);
        !            66:        fsp(f)->parent = FROOT;
        !            67:        fsp(f)->lbase = HUGE;
        !            68:        fsp(f)->flags = FBIN;
        !            69:        fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0;
        !            70:        rfgidmap = gmap;
        !            71:        return (f);
        !            72: }
        !            73: 
        !            74: /*
        !            75:  * access a file
        !            76:  */
        !            77: Rfile *
        !            78: fswalk(df, name)
        !            79: Rfile *df;
        !            80: char *name;
        !            81: {
        !            82:        register Rfile *f;
        !            83:        unsigned short fid;
        !            84:        int binary;
        !            85: 
        !            86:        binary = binchk(name);
        !            87:        if (strcmp(name, ".") == 0)
        !            88:                return (df);
        !            89:        else if (strcmp(name, "..") == 0) {
        !            90:                if (df->ino == FROOT) {
        !            91:                        fserrno = 0;            /* magic: popped out */
        !            92:                        return (NULL);
        !            93:                }
        !            94:                fid = fsp(df)->parent;
        !            95:        } else if ((fid = f11walk(df, name)) == 0)
        !            96:                return (NULL);
        !            97:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
        !            98:                rflog("no mem\n");
        !            99:                fserrno = RFEINVAL;
        !           100:                return (NULL);
        !           101:        }
        !           102:        if ((f->fs = malloc(sizeof(Fsfile))) == NULL) {
        !           103:                free((char *)f);
        !           104:                rflog("no mem\n");
        !           105:                fserrno = RFEINVAL;
        !           106:                return (NULL);
        !           107:        }
        !           108:        fsp(f)->lbase = HUGE;
        !           109:        if (gethdr(fid, &fsp(f)->h) == 0) {
        !           110:                free((char *)f);
        !           111:                fserrno = RFEIO;
        !           112:                return (NULL);
        !           113:        }
        !           114:        if (fsp(f)->h.h_ident.i_fnam.f_typ == dirtyp)
        !           115:                fsp(f)->parent = fsp(df)->h.h_fnum;
        !           116:        htorf(f, &fsp(f)->h);
        !           117:        fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0;
        !           118:        if (binary)
        !           119:                fsp(f)->flags = FBIN;
        !           120:        else if (fsp(f)->h.h_fcs.f_rtyp == RTVAR && fsp(f)->h.h_fcs.f_ratt & RTCR)
        !           121:                fsp(f)->flags = 0;
        !           122:        else
        !           123:                fsp(f)->flags = FBIN;
        !           124:        return (f);
        !           125: }
        !           126: 
        !           127: /*
        !           128:  * see if filename is `binary': trailing % in name
        !           129:  * stamp it out if so
        !           130:  */
        !           131: static
        !           132: binchk(name)
        !           133: register char *name;
        !           134: {
        !           135:        name += strlen(name);
        !           136:        if (*--name == '%') {
        !           137:                *name = 0;
        !           138:                return (1);
        !           139:        }
        !           140:        return (0);
        !           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: fsstat(f)
        !           160: register Rfile *f;
        !           161: {
        !           162: 
        !           163:        if (gethdr(fsp(f)->h.h_fnum, &fsp(f)->h) == 0) {
        !           164:                fserrno = RFEINVAL;
        !           165:                return (-1);
        !           166:        }
        !           167:        htorf(f, &fsp(f)->h);
        !           168:        return (0);
        !           169: }
        !           170: 
        !           171: /*
        !           172:  * read
        !           173:  */
        !           174: int
        !           175: fsread(f, off, buf, len)
        !           176: Rfile *f;
        !           177: long off;
        !           178: char *buf;
        !           179: int len;
        !           180: {
        !           181: 
        !           182:        if (fsp(f)->flags & FBIN)
        !           183:                return (binread(f, off, buf, len));
        !           184:        else
        !           185:                return (textread(f, off, buf, len));
        !           186: }
        !           187: 
        !           188: int
        !           189: binread(f, off, buf, len)
        !           190: Rfile *f;
        !           191: long off;
        !           192: char *buf;
        !           193: int len;
        !           194: {
        !           195:        char bbuf[BLKSIZ];
        !           196:        int boff;
        !           197:        long bno;
        !           198:        int nread, r;
        !           199:        int ncpy;
        !           200: 
        !           201:        nread = 0;
        !           202:        bno = off / BLKSIZ;
        !           203:        boff = off % BLKSIZ;
        !           204:        /*
        !           205:         * contract this loop later
        !           206:         */
        !           207:        r = 0;
        !           208:        while (len > 0) {
        !           209:                if ((r = f11rblk(f, bno, bbuf)) <= 0)
        !           210:                        break;
        !           211:                ncpy = BLKSIZ - boff;
        !           212:                ncpy = (len > ncpy) ? ncpy : len;
        !           213:                memcpy(buf, bbuf+boff, ncpy);
        !           214:                len -= ncpy;
        !           215:                buf += ncpy;
        !           216:                nread += ncpy;
        !           217:                boff = 0;
        !           218:                bno++;
        !           219:        }
        !           220:        if (nread || r >= 0)
        !           221:                return (nread);
        !           222:        fserrno = RFEIO;
        !           223:        return (-1);
        !           224: }
        !           225: 
        !           226: int
        !           227: textread(f, off, buf, len)
        !           228: Rfile *f;
        !           229: long off;
        !           230: char *buf;
        !           231: int len;
        !           232: {
        !           233:        unsigned char bbuf[BLKSIZ];
        !           234:        int boff;
        !           235:        long bno;
        !           236:        int nread, r;
        !           237:        int ncpy;
        !           238:        int rlen;
        !           239:        unsigned char *p;
        !           240: 
        !           241:        nread = 0;
        !           242:        if (off == fsp(f)->tuoff) {
        !           243:                bno = fsp(f)->tbno;
        !           244:                boff = fsp(f)->tboff;
        !           245:        } else if (off == 0) {
        !           246:                bno = 0;
        !           247:                boff = 0;
        !           248:        } else {                                /* wrong, but so what? */
        !           249:                bno = off / BLKSIZ;
        !           250:                boff = off % BLKSIZ;
        !           251:        }
        !           252:        if ((r = f11rblk(f, bno, bbuf)) <= 0)
        !           253:                goto out;
        !           254:        p = bbuf + boff;
        !           255:        while (len > 0) {
        !           256:                if (boff & 01) {
        !           257:                        p++;
        !           258:                        boff++;
        !           259:                }
        !           260:                if ((bno * BLKSIZ) + boff >= f->size)
        !           261:                        break;
        !           262:                rlen = p[0] + (p[1]<<8);
        !           263:                if (rlen == -1) {       /* skip to next block */
        !           264:                        if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
        !           265:                                goto out;
        !           266:                        p = bbuf;
        !           267:                        boff = 0;
        !           268:                        continue;
        !           269:                }
        !           270:                if (rlen + 1 > len)     /* +1 for newline */
        !           271:                        /* set a particular error here? */
        !           272:                        break;
        !           273:                p += 2;
        !           274:                for (; rlen > 0; rlen -= ncpy) {
        !           275:                        ncpy = &bbuf[BLKSIZ] - p;
        !           276:                        if (ncpy > rlen)
        !           277:                                ncpy = rlen;
        !           278:                        memcpy(buf, p, ncpy);
        !           279:                        p += ncpy;
        !           280:                        boff = p - bbuf;
        !           281:                        nread += ncpy;
        !           282:                        buf += ncpy;
        !           283:                        len -= ncpy;
        !           284:                        if (ncpy < rlen) {      /* next block */
        !           285:                                if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
        !           286:                                        goto out;
        !           287:                                p = bbuf;
        !           288:                                boff = 0;
        !           289:                        }
        !           290:                }
        !           291:                *buf++ = '\n';
        !           292:                nread++;
        !           293:                len--;
        !           294:                if (boff > BLKSIZ - 2) {        /* about to need new block */
        !           295:                        if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
        !           296:                                goto out;
        !           297:                        p = bbuf;
        !           298:                        boff = 0;
        !           299:                }
        !           300:        }
        !           301: out:
        !           302:        if (boff == BLKSIZ) {
        !           303:                boff = 0;
        !           304:                bno++;
        !           305:        }
        !           306:        if (nread) {
        !           307:                fsp(f)->tuoff = off + nread;
        !           308:                fsp(f)->tbno = bno;
        !           309:                fsp(f)->tboff = boff;
        !           310:        }
        !           311:        if (nread || r >= 0)
        !           312:                return (nread);
        !           313:        fserrno = RFEIO;
        !           314:        return (-1);
        !           315: }
        !           316: 
        !           317: /*
        !           318:  * read directory --
        !           319:  * return ascii records: decimal `i-number', tab, filename, NUL
        !           320:  * filename is filname.typ.ver
        !           321:  * *offp gets new file offset for directory
        !           322:  */
        !           323: #define        DENTSIZE        (6+9+4+6+1)     /* max len of a directory record */
        !           324: 
        !           325: int
        !           326: fsdirread(f, off, buf, len, offp)
        !           327: Rfile *f;
        !           328: long off;
        !           329: char *buf;
        !           330: int len;
        !           331: long *offp;
        !           332: {
        !           333:        char bbuf[BLKSIZ];
        !           334:        register char *p;
        !           335:        register struct directory *dp;
        !           336:        struct directory *dend;
        !           337:        char *op;
        !           338:        int r;
        !           339:        long bno;
        !           340:        int boff;
        !           341: 
        !           342:        bno = off / BLKSIZ;
        !           343:        if ((r = f11rblk(f, bno, bbuf)) <= 0) {
        !           344:                fserrno = RFEIO;
        !           345:                return (r);
        !           346:        }
        !           347:        boff = off % BLKSIZ;
        !           348:        dp = (struct directory *)bbuf + (boff/sizeof(struct directory));
        !           349:        dend = (struct directory *)&bbuf[BLKSIZ];
        !           350:        p = buf;
        !           351:        while (len >= DENTSIZE) {
        !           352:                while (dp < dend && dp->d_fid.f_num == 0)
        !           353:                        dp++;
        !           354:                if (dp >= dend) {
        !           355:                        bno++;
        !           356:                        dp = (struct directory *)bbuf;
        !           357:                        if ((r = f11rblk(f, bno, bbuf)) <= 0)
        !           358:                                break;
        !           359:                }
        !           360:                op = p;
        !           361:                p = itoa(p, dp->d_fid.f_num);
        !           362:                *p++ = '\t';
        !           363:                p = r50toa(p, dp->d_fname.f_nam[0]);
        !           364:                p = r50toa(p, dp->d_fname.f_nam[1]);
        !           365:                p = r50toa(p, dp->d_fname.f_nam[2]);
        !           366:                while (p[-1] == ' ')
        !           367:                        --p;
        !           368:                *p++ = '.';
        !           369:                p = r50toa(p, dp->d_fname.f_typ);
        !           370:                while (p[-1] == ' ')
        !           371:                        --p;
        !           372:                *p++ = '.';
        !           373:                p = itoa(p, dp->d_fname.f_ver);
        !           374:                *p++ = 0;
        !           375:                len -= p - op;
        !           376:                dp++;
        !           377:        }
        !           378:        if (p == buf && r < 0) {
        !           379:                fserrno = RFEIO;
        !           380:                return (-1);
        !           381:        }
        !           382:        *offp = (bno * BLKSIZ) + (char *)dp - bbuf;
        !           383:        return (p - buf);
        !           384: }
        !           385: 
        !           386: /*
        !           387:  * f11 to rf file attributes
        !           388:  * -- temporary permission hack:
        !           389:  * turn apparent f11 other to asserted unix other group
        !           390:  */
        !           391: #define        F11OTHER (-1)
        !           392: 
        !           393: static
        !           394: htorf(f, h)
        !           395: register Rfile *f;
        !           396: register struct header *h;
        !           397: {
        !           398:        f->ino = h->h_fnum;
        !           399:        f->dev = 0;
        !           400:        f->mode = htouperm(h->h_fpro);
        !           401:        if (h->h_ident.i_fnam.f_typ != dirtyp)
        !           402:                f->type = RFTREG;
        !           403:        else {
        !           404:                f->mode |= (f->mode & 0444)>>2; /* copy `read' into `execute' */
        !           405:                f->type = RFTDIR;
        !           406:        }
        !           407:        f->nlink = 1;
        !           408:        f->uid = h->h_fown.u_prog;
        !           409:        f->gid = h->h_fown.u_proj;
        !           410:        if (f->gid == F11OTHER)
        !           411:                f->gid = UXOTHER;
        !           412:        f->rdev = 0;
        !           413:        f->size = hfilesize(h);
        !           414:        f->ta = 0;
        !           415:        f->tm = htoutime(h->h_ident.i_rvdt);
        !           416:        f->tc = htoutime(h->h_ident.i_crdt);    /* wrong, but let it stand */
        !           417:        if (f->tm == 0)
        !           418:                f->tm = f->tc;
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * number to string
        !           423:  */
        !           424: 
        !           425: static char digits[] = "0123456789";
        !           426: 
        !           427: static char *
        !           428: itoa(s, n)
        !           429: register char *s;
        !           430: register unsigned int n;
        !           431: {
        !           432:        register int d;
        !           433: 
        !           434:        if ((d = n / 10) == 0)
        !           435:                *s++ = digits[n];
        !           436:        else {
        !           437:                s = itoa(s, d);
        !           438:                *s++ = digits[n % 10];
        !           439:        }
        !           440:        return (s);
        !           441: }

unix.superglobalmegacorp.com

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