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