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

1.1     ! root        1: /*
        !             2:  * files-11 subroutines,
        !             3:  * mostly concerned directly with
        !             4:  * filesystem structures
        !             5:  */
        !             6: 
        !             7: #include <time.h>
        !             8: #include <ctype.h>
        !             9: #include <rf.h>
        !            10: #include "files11.h"
        !            11: #include "f11.h"
        !            12: 
        !            13: #define        NULL    0
        !            14: 
        !            15: /*
        !            16:  * convert files-11 ascii time to unix binary time
        !            17:  * 13 bytes: DDMMMYYhhmmss
        !            18:  */
        !            19: 
        !            20: static char *months[] = {
        !            21:        "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
        !            22:        "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", 0
        !            23: };
        !            24: 
        !            25: static int i2val();
        !            26: 
        !            27: long
        !            28: htoutime(ht)
        !            29: register char *ht;
        !            30: {
        !            31:        struct tm tm;
        !            32:        register int mon;
        !            33: 
        !            34:        if (*ht == 0)
        !            35:                return (0);
        !            36:        tm.tm_yday = 0;
        !            37:        tm.tm_mday = i2val(ht);
        !            38:        ht += 2;
        !            39:        for (mon = 0; months[mon]; mon++)
        !            40:                if (strncmp(ht, months[mon], 3) == 0)
        !            41:                        break;
        !            42:        tm.tm_mon = mon;
        !            43:        ht += 3;
        !            44:        tm.tm_year = i2val(ht);
        !            45:        ht += 2;
        !            46:        tm.tm_hour = i2val(ht);
        !            47:        ht += 2;
        !            48:        tm.tm_min = i2val(ht);
        !            49:        ht += 2;
        !            50:        tm.tm_sec = i2val(ht);
        !            51:        return (timelocal(&tm, (char *)NULL));
        !            52: }
        !            53: 
        !            54: static int
        !            55: i2val(s)
        !            56: register char *s;
        !            57: {
        !            58:        if (!isdigit(s[0]) || !isdigit(s[1]))
        !            59:                return (0);
        !            60:        return ((s[0]-'0') * 10 + (s[1]-'0'));
        !            61: }
        !            62: 
        !            63: /*
        !            64:  * convert f11 protection to unix permissions
        !            65:  * information is lost, most importantly the delete flag
        !            66:  */
        !            67: int
        !            68: htouperm(hp)
        !            69: register int hp;
        !            70: {
        !            71:        register int up;
        !            72:        register int i;
        !            73: 
        !            74:        hp >>= 4;               /* discard `system' field */
        !            75:        up = 0;
        !            76:        for (i = 0; i < 3; i++) {       /* and do owner, group, world */
        !            77:                up <<= 3;
        !            78:                if ((hp & 1) == 0)      /* read */
        !            79:                        up |= 4;
        !            80:                if ((hp & 2) == 0)      /* write */
        !            81:                        up |= 2;
        !            82:                if ((hp & 4) == 0)      /* execute */
        !            83:                        up |= 1;
        !            84:                hp >>= 4;
        !            85:        }
        !            86:        return (up);
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * compute the file size
        !            91:  * use the FCS attributes if they look valid,
        !            92:  * else just count the blocks
        !            93:  */
        !            94: 
        !            95: long
        !            96: hfilesize(h)
        !            97: register struct header *h;
        !            98: {
        !            99:        register int i;
        !           100:        register long sz;
        !           101:        register Bmap *bp;
        !           102: 
        !           103:        if (h->h_fcs.f_rtyp != 0) {
        !           104:                sz = plong(h->h_fcs.f_efbk) - 1;
        !           105:                sz *= BLKSIZ;
        !           106:                sz += h->h_fcs.f_ffby;
        !           107:                return (sz);
        !           108:        }
        !           109:        for (sz = 0, i = 0; bp = getmap(&h->h_map, i); i++)
        !           110:                sz += bp->count;
        !           111:        return (sz * BLKSIZ);
        !           112: }
        !           113: 
        !           114: /*
        !           115:  * search a directory
        !           116:  * return the file id
        !           117:  */
        !           118: 
        !           119: int
        !           120: f11walk(df, name)
        !           121: Rfile *df;
        !           122: char *name;
        !           123: {
        !           124:        struct filnam fn;
        !           125:        register struct directory *dp;
        !           126:        register struct filnam *fp;
        !           127:        register unsigned short bestfid, bestver;
        !           128:        char buf[BLKSIZ];
        !           129:        long bno;
        !           130: 
        !           131:        if (utohname(name, &fn) == 0) {
        !           132:                fserrno = RFEINVAL;
        !           133:                return (0);
        !           134:        }
        !           135:        bestfid = 0;
        !           136:        bestver = 0;
        !           137:        fp = &fn;
        !           138:        for (bno = 0; f11rblk(df, bno, buf) > 0; bno++) {
        !           139:                dp = (struct directory *)buf;
        !           140:                for (; dp < (struct directory *)&buf[BLKSIZ]; dp++) {
        !           141:                        if (dp->d_fid.f_num == 0)
        !           142:                                continue;
        !           143:                        if (dp->d_fname.f_nam[0] != fp->f_nam[0]
        !           144:                        ||  dp->d_fname.f_nam[1] != fp->f_nam[1]
        !           145:                        ||  dp->d_fname.f_nam[2] != fp->f_nam[2]
        !           146:                        ||  dp->d_fname.f_typ    != fp->f_typ)
        !           147:                                continue;
        !           148:                        if (dp->d_fname.f_ver == fp->f_ver)
        !           149:                                return (dp->d_fid.f_num);       /* exact match */
        !           150:                        if (fp->f_ver)
        !           151:                                continue;               /* exact wanted */
        !           152:                        if (dp->d_fname.f_ver > bestver) {
        !           153:                                bestver = dp->d_fname.f_ver;
        !           154:                                bestfid = dp->d_fid.f_num;
        !           155:                        }
        !           156:                }
        !           157:        }
        !           158:        if (bestfid == 0)
        !           159:                fserrno = RFENOENT;
        !           160:        return (bestfid);
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * convert an ascii filename into a files-11 one
        !           165:  * unspecified parts are left 0
        !           166:  * returns 0 for bad filename, 1 for ok
        !           167:  */
        !           168: 
        !           169: int
        !           170: utohname(name, f)
        !           171: char *name;
        !           172: register struct filnam *f;
        !           173: {
        !           174:        char *n;
        !           175:        register char *e;
        !           176:        register int i;
        !           177:        register int x;
        !           178: 
        !           179:        f->f_nam[0] = f->f_nam[1] = f->f_nam[2] = 0;
        !           180:        f->f_typ = 0;
        !           181:        f->f_ver = 0;
        !           182:        n = name;
        !           183:        for (e = n; *e && *e != '.'; e++)
        !           184:                ;
        !           185:        if (e - n > 9)
        !           186:                return (0);
        !           187:        if (*e)
        !           188:                *e++ = 0;
        !           189:        for (i = 0; i < 3; i++) {
        !           190:                if ((x = ator50(&n)) < 0)
        !           191:                        return (0);
        !           192:                f->f_nam[i] = x;
        !           193:        }
        !           194:        n = e;
        !           195:        for (; *e && *e != '.'; e++)
        !           196:                ;
        !           197:        if (e - n > 3)
        !           198:                return (0);
        !           199:        if (*e)
        !           200:                *e++ = 0;
        !           201:        if ((x = ator50(&n)) < 0)
        !           202:                return (0);
        !           203:        f->f_typ = x;
        !           204:        if (*e) {
        !           205:                x = atoi(e);
        !           206:                if (x < 0 || x > 65535)
        !           207:                        return (0);
        !           208:                f->f_ver = x;
        !           209:        }
        !           210:        return (1);
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * read a block from a file
        !           215:  */
        !           216: int
        !           217: f11rblk(f, bno, buf)
        !           218: Rfile *f;
        !           219: long bno;
        !           220: char *buf;
        !           221: {
        !           222:        register Bmap *bp;
        !           223: 
        !           224:        if ((bp = getblk(fsp(f), bno)) == NULL)
        !           225:                return (0);
        !           226:        lseek(diskfd, (long)bp->bno * BLKSIZ, 0);
        !           227:        if (read(diskfd, buf, BLKSIZ) != BLKSIZ)
        !           228:                return (-1);
        !           229:        return (1);
        !           230: }
        !           231: 
        !           232: /*
        !           233:  * get the header for a file
        !           234:  */
        !           235: 
        !           236: int
        !           237: gethdr(fid, hp)
        !           238: unsigned short fid;
        !           239: struct header *hp;
        !           240: {
        !           241:        long bno;
        !           242:        register Bmap *bp;
        !           243: 
        !           244:        bno = IBITMAP + home.H_ibsz + fidtob(fid);
        !           245:        if ((bp = getblk(&indexf, bno)) == NULL)
        !           246:                return (0);
        !           247:        lseek(diskfd, (long)bp->bno * BLKSIZ, 0);
        !           248:        if (read(diskfd, (char *)hp, sizeof(*hp)) != sizeof(*hp))
        !           249:                return (0);
        !           250:        if (hp->h_fnum != fid)
        !           251:                fprint(2, "gethdr: wanted fid %d, got %d\n", fid, hp->h_fnum);
        !           252:        return (1);
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * get the map for a chunk of a file,
        !           257:  * starting at block bno
        !           258:  */
        !           259: 
        !           260: Bmap *
        !           261: getblk(fsf, bno)
        !           262: register Fsfile *fsf;
        !           263: long bno;
        !           264: {
        !           265:        static Bmap b;
        !           266:        long offset;
        !           267:        int mi;
        !           268:        long mbno;
        !           269:        register Bmap *bp;
        !           270: 
        !           271:        offset = bno - fsf->lbase;
        !           272:        if (offset > 0 && offset < fsf->lmap.count) {   /* within cached map */
        !           273:                b.count = fsf->lmap.count - offset;
        !           274:                b.bno = fsf->lmap.bno + offset;
        !           275:                return (&b);
        !           276:        }
        !           277:        if (offset > 0) {
        !           278:                mi = fsf->lmi + 1;
        !           279:                mbno = fsf->lbase + fsf->lmap.count;
        !           280:        } else {
        !           281:                mi = 0;
        !           282:                mbno = 0;
        !           283:        }
        !           284:        while ((bp = getmap(&fsf->h.h_map, mi)) != NULL) {
        !           285:                if (mbno + bp->count < bno) {
        !           286:                        mbno += bp->count;
        !           287:                        mi++;
        !           288:                        continue;
        !           289:                }
        !           290:                fsf->lbase = mbno;
        !           291:                fsf->lmi = mi;
        !           292:                fsf->lmap = *bp;
        !           293:                offset = bno - mbno;
        !           294:                b.count = bp->count - offset;
        !           295:                b.bno = bp->bno + offset;
        !           296:                return (&b);
        !           297:        }
        !           298:        return (NULL);
        !           299: }
        !           300: 
        !           301: /*
        !           302:  * fetch the n'th retrieval pointer from a map
        !           303:  * no hope for extended headers yet
        !           304:  */
        !           305: 
        !           306: #define        RS(c, l)        ((c << 8)|l)
        !           307: 
        !           308: Bmap *
        !           309: getmap(m, n)
        !           310: register struct map *m;
        !           311: int n;
        !           312: {
        !           313:        static Bmap b;
        !           314:        register unsigned char *p;
        !           315:        register int off;
        !           316: 
        !           317:        off = m->m_ctsz + m->m_lbsz;
        !           318:        off *= n;
        !           319:        if (off >= m->m_use * sizeof(short))
        !           320:                return (NULL);
        !           321:        p = m->m_rtrvp + off;
        !           322:        switch (RS(m->m_ctsz, m->m_lbsz)) {
        !           323:        case RS(1, 3):
        !           324:                b.count = p[1];
        !           325:                b.bno = (p[0]<<24) | p[2] | (p[3]<<8);
        !           326:                break;
        !           327: 
        !           328:        case RS(2, 2):
        !           329:                b.count = p[0] | (p[1]<<8);
        !           330:                b.bno = p[2] | (p[3]<<8);
        !           331:                break;
        !           332: 
        !           333:        case RS(2, 4):
        !           334:                b.count = p[0] | (p[1]<<8);
        !           335:                b.bno = (p[3]<<16) | (p[4]<<24) | p[4] | (p[5]<<8);
        !           336:                break;
        !           337: 
        !           338:        default:
        !           339:                return (NULL);
        !           340:        }
        !           341:        b.count++;
        !           342:        return (&b);
        !           343: }

unix.superglobalmegacorp.com

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