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