Annotation of researchv10no/netfs/libnetb/funcs.c, revision 1.1.1.1

1.1       root        1: #include "netb.h"
                      2: #include "nberrno.h"
                      3: #include "rf.h"
                      4: #include "tag.h"
                      5: 
                      6: #define        NULL    0
                      7: extern char *strchr();
                      8: extern int defaultuid, defaultgid;
                      9: extern int cuid, cgid;
                     10: 
                     11: #define        ARB     4096
                     12: 
                     13: /*
                     14:  * netb-to-local service translation
                     15:  */
                     16: 
                     17: static long timeoff;
                     18: static timecheck();
                     19: static Rfile *root;    /* should this be a global? */
                     20: static int nberrno;
                     21: 
                     22: /*
                     23:  * magic knowledge: fserrno and nberrno codes are the same
                     24:  */
                     25: #define        fstonberr(e)    (e)
                     26: 
                     27: /*
                     28:  * compatibility with old clients
                     29:  * that don't generate NBROOTTAG
                     30:  */
                     31: static Tag oldrtag;
                     32: static int oldrdev;
                     33: #define        OLDRINO 2L
                     34: static int oldclient;  /* it used oldrtag */
                     35: static int sawroot;
                     36: 
                     37: static Rfile *getfile();
                     38: static putmode();
                     39: 
                     40: /*
                     41:  * make a tag from a file
                     42:  * the root is an exception; it has NBROOTTAG, always
                     43:  * 0x80000000 is a temporary protection against confusion with oldrtag
                     44:  */
                     45: #define        maketag(f)      (0x80000000|((f)->dev<<16)|((f)->ino&0xffff))
                     46: 
                     47: /*
                     48:  * file modes
                     49:  * not specified in netb.h,
                     50:  * but they are the same as V7 Unix
                     51:  */
                     52: 
                     53: #define        NB_IFMT 0170000 /* file type */
                     54: #define        NB_IFDIR        0040000 /* directory */
                     55: #define        NB_IFREG        0100000 /* regular file */
                     56: #define        NB_PERM 07777   /* permissions */
                     57: 
                     58: #define        fstonbmode(m)   (m)     /* other modes (assumed) same as rf */
                     59: #define        nbtofsmode(m)   ((m)&07777)     /* modes that may be set */
                     60: 
                     61: long time();
                     62: 
                     63: /*
                     64:  * init things;
                     65:  * called before the connection is fully open
                     66:  * mainly, set up the root
                     67:  */
                     68: 
                     69: int
                     70: _rfinit(argc, argv)
                     71: int argc;
                     72: char **argv;
                     73: {
                     74: 
                     75:        if ((root = fsinit(argc, argv)) == NULL) {
                     76:                rflog("init failed\n");
                     77:                return (0);
                     78:        }
                     79:        if (_rfnewtag((Tag)NBROOTTAG, root) != root) {
                     80:                rflog("can't install root\n");
                     81:                return (0);
                     82:        }
                     83:        return (1);
                     84: }
                     85: 
                     86: /*
                     87:  * namei
                     88:  *
                     89:  * hand the pathname to fswalk, a piece at a time
                     90:  * on reaching the end, do the operation implied by SNB_FLAGS
                     91:  * fswalk might return an Rfile that is already in our table;
                     92:  * keep the older one.
                     93:  * -- be careful when calling fsdone on intermediate directories
                     94:  * in the path; they might be in use in some other way, and
                     95:  * fsdone will wreak havoc.
                     96:  * dirintab is there so _rfdone needn't be called every time,
                     97:  * especially for directories we know are already in the table
                     98:  */
                     99: 
                    100: _rfnamei(fd, sp, len)
                    101: int fd;
                    102: unsigned char *sp;
                    103: int len;
                    104: {
                    105:        unsigned char rbuf[RNMSIZE];
                    106:        register unsigned char *pp;
                    107:        register Rfile *f, *df;
                    108:        Rfile *lnf;
                    109:        int dirintab;
                    110:        register char *cp, *ep;
                    111:        Tag t;
                    112:        int cruid, crgid, crmode;
                    113:        long tm;
                    114: 
                    115:        nberrno = 0;
                    116:        tonetchar(rbuf, RNB_FLAGS, 0);
                    117:        pp = sp;
                    118:        if (len < SNMSIZE)
                    119:                rfpanic("namei: len %d\n", len);
                    120:        pp[len] = 0;    /* guarantee null at end of name */
                    121:        cp = (char *)pp + SNMSIZE;
                    122:        while (*cp == '/')
                    123:                cp++;
                    124:        dirintab = 1;
                    125:        if ((df = getfile(&pp[SNB_TAG])) == NULL) {
                    126:                nberrno = NBEINVAL;
                    127:                goto out;
                    128:        }
                    129:        while ((ep = strchr(cp, '/')) != NULL) {
                    130:                *ep++ = 0;
                    131:                while (*ep == '/')
                    132:                        ep++;
                    133:                if (df->type != RFTDIR) {
                    134:                        nberrno = NBENOENT;
                    135:                        goto out;
                    136:                }
                    137:                if (_rfpdsearch(df, rfuid, rfgid) == NULL) {
                    138:                        nberrno = NBEACCES;
                    139:                        goto out;
                    140:                }
                    141:                if ((f = fswalk(df, cp)) == NULL)
                    142:                        goto eout;
                    143:                if (f != df && dirintab == 0)
                    144:                        fsdone(df);
                    145:                if (f->ino == root->ino && f->dev == root->dev) {
                    146:                        if (f != root)
                    147:                                fsdone(f);
                    148:                        df = root;
                    149:                        dirintab = 1;
                    150:                } else if ((df = _rftagtof(maketag(f))) != NULL) {
                    151:                        fsdone(f);
                    152:                        dirintab = 1;
                    153:                } else {
                    154:                        df = f;
                    155:                        dirintab = 0;
                    156:                }
                    157:                cp = ep;
                    158:        }
                    159:        /*
                    160:         * cp is now last component
                    161:         *
                    162:         * the tests that follow are wrong if the root isn't a directory
                    163:         * think about implications
                    164:         */
                    165:        if (df->type != RFTDIR) {
                    166:                nberrno = NBENOENT;
                    167:                goto out;
                    168:        }
                    169:        if (_rfpdsearch(df, rfuid, rfgid) == 0) {
                    170:                nberrno = NBEACCES;
                    171:                goto out;
                    172:        }
                    173:        switch (frnetchar(pp, SNB_FLAGS)) {
                    174:        case NI_SEARCH:
                    175:                if (cp[0] == 0) {               /* empty filename */
                    176:                        f = df;
                    177:                        fsstat(f);              /* get fresh info */
                    178:                        break;
                    179:                }
                    180:                if ((f = fswalk(df, cp)) == NULL)
                    181:                        goto eout;
                    182:                break;
                    183: 
                    184:        case NI_NXCREAT:
                    185:        case NI_CREAT:
                    186:                cruid = rfuid;
                    187:                if (cruid == RFNOID && defaultuid != RFNOID)
                    188:                        cruid = defaultuid;
                    189:                crgid = rfgid;
                    190:                if (crgid == RFNOID && defaultgid != RFNOID)
                    191:                        crgid = defaultgid;
                    192:                crmode = frnetshort(pp, SNM_MODE);
                    193:                if ((f = fswalk(df, cp)) == NULL) {     /* doesn't exist */
                    194:                        if (cruid == RFNOID || crgid == RFNOID  /* don't create ownerless files */
                    195:                        ||  _rfpdwrite(df, cruid, crgid) == 0) {
                    196:                                nberrno = NBEACCES;
                    197:                                goto out;
                    198:                        }
                    199:                } else if (frnetchar(pp, SNB_FLAGS) == NI_NXCREAT) {
                    200:                        _rfdone(f);
                    201:                        nberrno = NBEEXIST;     /* NXCREAT means it shouldn't exist */
                    202:                        goto out;
                    203:                } else {
                    204:                        if (_rfpwrite(f, cruid, crgid) == 0) {
                    205:                                _rfdone(f);
                    206:                                nberrno = NBEACCES;
                    207:                                goto out;
                    208:                        }
                    209:                        cruid = f->uid;
                    210:                        crgid = f->gid;
                    211:                        crmode = f->mode;
                    212:                        _rfdone(f);             /* we'll re-create anyway */
                    213:                }
                    214:                if ((f = fscreate(df, cp, crmode, cruid, crgid)) == NULL)
                    215:                        goto eout;
                    216:                break;
                    217: 
                    218:        case NI_LINK:
                    219:                if ((lnf = getfile(&pp[SNM_INO])) == NULL) {
                    220:                        nberrno = NBEINVAL;
                    221:                        goto out;
                    222:                }
                    223: #if NOTDEF
                    224:                if (lnf->type == RFTDIR && _rfpsuper(lnf, rfuid, rfgid) == 0) {
                    225: #else
                    226:                if (lnf->type == RFTDIR) {
                    227: #endif
                    228:                        nberrno = NBEISDIR;
                    229:                        goto out;
                    230:                }
                    231:                if (_rfpdwrite(df, rfuid, rfgid) == 0) {
                    232:                        nberrno = NBEACCES;
                    233:                        goto out;
                    234:                }
                    235:                if (fslink(df, cp, lnf) < 0)
                    236:                        goto eout;
                    237:                goto out;
                    238: 
                    239:        case NI_MKDIR:
                    240:                cruid = rfuid;
                    241:                if (cruid == RFNOID && defaultuid != RFNOID)
                    242:                        cruid = defaultuid;
                    243:                crgid = rfgid;
                    244:                if (crgid == RFNOID && defaultgid != RFNOID)
                    245:                        crgid = defaultgid;
                    246:                if (cruid == RFNOID || crgid == RFNOID
                    247:                ||  _rfpdwrite(df, cruid, crgid) == 0) {
                    248:                        nberrno = NBEACCES;
                    249:                        goto out;
                    250:                }
                    251:                if (fsmkdir(df, cp, frnetshort(pp, SNM_MODE), cruid, crgid) < 0)
                    252:                        goto eout;
                    253:                goto out;
                    254: 
                    255:        case NI_RMDIR:
                    256:                if (_rfpdwrite(df, rfuid, rfgid) == 0) {
                    257:                        nberrno = NBEACCES;
                    258:                        goto out;
                    259:                }
                    260:                if (fsrmdir(df, cp) < 0)
                    261:                        goto eout;
                    262:                goto out;
                    263: 
                    264:        case NI_DEL:
                    265:                if (_rfpdwrite(df, rfuid, rfgid) == 0) {
                    266:                        nberrno = NBEACCES;
                    267:                        goto out;
                    268:                }
                    269:                if ((f = fswalk(df, cp)) == NULL)
                    270:                        goto eout;
                    271: #if NOTDEF
                    272:                if (f->type == RFTDIR && _rfpsuper(f, rfuid, rfgid) == 0) {
                    273: #else
                    274:                if (f->type == RFTDIR) {
                    275: #endif
                    276:                        _rfdone(f);
                    277:                        nberrno = NBEISDIR;
                    278:                        goto out;
                    279:                }
                    280:                _rfdone(f);
                    281:                if (fsdelete(df, cp) < 0)
                    282:                        goto eout;
                    283:                goto out;
                    284: 
                    285:        default:
                    286:                nberrno = NBEINVAL;
                    287:                goto out;
                    288:        }
                    289:        /*
                    290:         * returning a newly-opened file
                    291:         */
                    292:        if (f->dev == root->dev && f->ino == root->ino)
                    293:                t = NBROOTTAG;
                    294:        else
                    295:                t = maketag(f);
                    296:        if ((lnf = _rfnewtag(t, f)) == NULL) {
                    297:                fsdone(f);
                    298:                nberrno = NBEINVAL;
                    299:                goto out;
                    300:        } else if (lnf != f) {          /* already had that file */
                    301:                fsdone(f);
                    302:                f = lnf;
                    303:        }
                    304:        if (f == df)
                    305:                dirintab = 1;   /* we just made sure of that */
                    306:        pp = rbuf;
                    307:        tonetlong(pp, RNM_TAG, t);
                    308:        tonetlong(pp, RNM_INO, f->ino);
                    309:        tonetshort(pp, RNM_DEV, f->dev);
                    310:        putmode(pp, RNM_MODE, f);
                    311:        tonetshort(pp, RNM_NLINK, f->nlink);
                    312:        /*
                    313:         * the default ownership here might be wrong...check it.
                    314:         */
                    315:        if (defaultuid != RFNOID && rfuid == RFNOID && f->uid == defaultuid)
                    316:                len = cuid;     /* tell him he owns it */
                    317:        else
                    318:                len = _rfcuid(f->uid);
                    319:        tonetshort(pp, RNM_UID, len);
                    320:        len = _rfcgid(f->gid);  /* stub - this gid processing may be wrong */
                    321:        if (len == RFNOID)
                    322:                len = cgid;
                    323:        tonetshort(pp, RNM_GID, len);
                    324:        tonetshort(pp, RNM_RDEV, f->rdev);
                    325: #if 0x100000000 == 0   /* 32-bit machine */
                    326:        tonetlong(pp, RNM_SIZE, f->size);
                    327: #else                  /* probably the Cray */
                    328:        if ((tm = f->size) > 0x7fffffff)
                    329:                tm = 0x7fffffff;
                    330:        tonetlong(pp, RNM_SIZE, tm);
                    331: #endif
                    332:        tm = f->ta + timeoff;
                    333:        tonetlong(pp, RNM_ATIME, tm);
                    334:        tm = f->tm + timeoff;
                    335:        tonetlong(pp, RNM_MTIME, tm);
                    336:        tm = f->tc + timeoff;
                    337:        tonetlong(pp, RNM_CTIME, tm);
                    338:        if (oldclient) {
                    339:                len = (f->dev & 0xff) | (oldrdev & 0xff00);
                    340:                tonetshort(pp, RNM_DEV, len);
                    341:                if (f == root) {
                    342:                        tonetlong(pp, RNM_TAG, oldrtag);
                    343:                        tonetshort(pp, RNM_DEV, oldrdev);
                    344:                        tonetlong(pp, RNM_INO, OLDRINO);
                    345:                }
                    346:        }
                    347:        goto out;
                    348: 
                    349:        /*
                    350:         * failed to find a file
                    351:         * if nberrno == 0, popped out of root
                    352:         */
                    353: eout:
                    354:        if (fserrno)
                    355:                nberrno = fstonberr(fserrno);
                    356:        else {
                    357:                nberrno = 0;
                    358:                tonetchar(rbuf, RNB_FLAGS, NBROOT);
                    359:                while (*cp && *cp != '/')
                    360:                        cp++;
                    361:                len = cp - (char *)(sp + SNMSIZE);
                    362:                if (rfdebug)
                    363:                        rflog("popped out; used %d\n", len);
                    364:                tonetlong(rbuf, RNM_USED, len);
                    365:        }
                    366:        /*
                    367:         * done
                    368:         */
                    369: out:
                    370:        if (dirintab == 0)
                    371:                _rfdone(df);
                    372:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    373:        _rfresp(fd, sp, rbuf, RNMSIZE);
                    374: }
                    375: 
                    376: /*
                    377:  * discard f if it is not in the tag table
                    378:  * used by rfnamei to discard files fetched halfway,
                    379:  * e.g. directories in the middle of a path
                    380:  */
                    381: 
                    382: _rfdone(f)
                    383: register Rfile *f;
                    384: {
                    385: 
                    386:        if (f == root)
                    387:                return;
                    388:        if (_rftagtof(maketag(f)) == f)
                    389:                return;
                    390:        fsdone(f);
                    391: }
                    392: 
                    393: /*
                    394:  * put
                    395:  */
                    396: 
                    397: _rfput(fd, sp, len)
                    398: int fd;
                    399: register unsigned char *sp;
                    400: int len;
                    401: {
                    402:        unsigned char rbuf[RNBSIZE];
                    403:        Tag t;
                    404:        Rfile *f;
                    405: 
                    406:        t = frnetlong(sp, SNB_TAG);
                    407:        if ((f = getfile(&sp[SNB_TAG])) == NULL)
                    408:                nberrno = NBEINVAL;
                    409:        else {
                    410:                _rfdeltag(t);
                    411:                nberrno = 0;
                    412:                fsdone(f);
                    413:        }
                    414:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    415:        _rfresp(fd, sp, rbuf, RNBSIZE);
                    416: }
                    417: 
                    418: /*
                    419:  * stat
                    420:  */
                    421: 
                    422: _rfstat(fd, sp, len)
                    423: int fd;
                    424: unsigned char *sp;
                    425: int len;
                    426: {
                    427:        int i;
                    428:        unsigned char rbuf[RSTSIZE];
                    429:        register unsigned char *rp;
                    430:        register Rfile *f;
                    431:        long tm;
                    432: 
                    433:        if (len < SSTSIZE)
                    434:                rfpanic("stat: len %d\n", len);
                    435:        rp = rbuf;
                    436:        if ((f = getfile(&sp[SNB_TAG])) == NULL)
                    437:                nberrno = NBEINVAL;
                    438:        else if (fsstat(f) < 0)
                    439:                nberrno = fstonberr(fserrno);
                    440:        else {
                    441:                nberrno = 0;
                    442:                /* should have hysteresis here */
                    443:                timecheck(frnetlong(sp, SST_TIME));
                    444:                tonetlong(rp, RST_INO, f->ino);
                    445:                tonetshort(rp, RST_DEV, f->dev);
                    446:                putmode(rp, RST_MODE, f);
                    447:                tonetshort(rp, RST_NLINK, f->nlink);
                    448:                if (defaultuid != RFNOID && rfuid == RFNOID && f->uid == defaultuid)
                    449:                        i = cuid;       /* let the client think he owns it */
                    450:                else
                    451:                        i = _rfcuid(f->uid);
                    452: /*rflog("stat: f->uid=%d defaultuid=%d cuid=%d rfcuid=%d returning %d\n",
                    453: f->uid, defaultuid, cuid, _rfcuid(f->uid), i);*/
                    454:                tonetshort(rp, RST_UID, i);
                    455:                i = _rfcgid(f->gid);    /* stub - default gid processing? */
                    456:                tonetshort(rp, RST_GID, i);
                    457: #if 0x100000000 == 0           /* 32-bit machine */
                    458:                tonetlong(rp, RST_SIZE, f->size);
                    459: #else                          /* probably the Cray */
                    460:                if ((tm = f->size) > 0x7fffffff)
                    461:                        tm = 0x7fffffff;
                    462:                tonetlong(rp, RST_SIZE, f->size);
                    463: #endif
                    464:                tm = f->ta + timeoff;
                    465:                tonetlong(rp, RST_ATIME, tm);
                    466:                tm = f->tm + timeoff;
                    467:                tonetlong(rp, RST_MTIME, tm);
                    468:                tm = f->tc + timeoff;
                    469:                tonetlong(rp, RST_CTIME, tm);
                    470:        }
                    471:        tonetshort(rp, RNB_ERRNO, nberrno);
                    472:        _rfresp(fd, sp, rp, RSTSIZE);
                    473: }
                    474: 
                    475: /*
                    476:  * update:
                    477:  * write attributes
                    478:  */
                    479: 
                    480: _rfupdate(fd, sp, len)
                    481: int fd;
                    482: register unsigned char *sp;
                    483: int len;
                    484: {
                    485:        unsigned char rbuf[RNBSIZE];
                    486:        static Rfile na;
                    487:        Rfile *f;
                    488: 
                    489:        if (len < SUPSIZE)
                    490:                rfpanic("update: len %d\n", len);
                    491:        if ((f = getfile(&sp[SNB_TAG])) == NULL)
                    492:                nberrno = NBEINVAL;
                    493:        else {
                    494:                na.mode = nbtofsmode(frnetshort(sp, SUP_MODE));
                    495:                na.ta = frnetlong(sp, SUP_ATIME);
                    496:                na.tm = frnetlong(sp, SUP_MTIME);
                    497:                if (na.ta == 0)         /* current time: local system did it */
                    498:                        na.ta = f->ta;
                    499:                else
                    500:                        na.ta -= timeoff;
                    501:                if (na.tm == 0)
                    502:                        na.tm = f->tm;
                    503:                else
                    504:                        na.tm -= timeoff;
                    505:                na.uid = f->uid;        /* netb doesn't supply */
                    506:                na.gid = f->gid;
                    507:                na.size = f->size;      /* not set here */
                    508:                if ((na.mode & NB_PERM) != (fstonbmode(f->mode) & NB_PERM)
                    509:                &&  _rfpowner(f, rfuid, rfgid) == 0)
                    510:                        nberrno = NBEPERM;
                    511:                else if (fsupdate(f, &na) < 0)
                    512:                        nberrno = fstonberr(fserrno);
                    513:                else
                    514:                        nberrno = 0;
                    515:        }
                    516:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    517:        _rfresp(fd, sp, rbuf, RNBSIZE);
                    518: }
                    519: 
                    520: /*
                    521:  * read
                    522:  */
                    523: _rfread(fd, sp, mlen)
                    524: int fd;
                    525: register unsigned char *sp;
                    526: int mlen;
                    527: {
                    528:        unsigned char rbuf[RNBSIZE+ARB];        /* should be negotiated size */
                    529:        Rfile *f;
                    530:        int len;
                    531: 
                    532:        if (mlen < SRDSIZE)
                    533:                rfpanic("read: len %d\n", mlen);
                    534:        len = frnetlong(sp, SRD_LEN);
                    535:        tonetchar(rbuf, RNB_FLAGS, 0);
                    536:        if (len <= 0 || (f = getfile(&sp[SNB_TAG])) == NULL) {
                    537:                nberrno = NBEINVAL;
                    538:                len = 0;
                    539:        } else if (_rfpread(f, rfuid, rfgid) == 0) {
                    540:                nberrno = NBEACCES;
                    541:                len = 0;
                    542:        } else {
                    543:                if (len > ARB)
                    544:                        len = ARB;
                    545:                len = fsread(f, frnetlong(sp, SRD_OFFSET),
                    546:                        (char *)rbuf + RNBSIZE, len);
                    547:                if (len < 0) {
                    548:                        nberrno = fstonberr(fserrno);
                    549:                        len = 0;
                    550:                } else {
                    551:                        nberrno = 0;
                    552:                        if (len == 0)
                    553:                                tonetchar(rbuf, RNB_FLAGS, NBEND);
                    554:                }
                    555:        }
                    556:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    557:        len += RNBSIZE;
                    558:        _rfresp(fd, sp, rbuf, len);
                    559: }
                    560: 
                    561: /*
                    562:  * read directory
                    563:  */
                    564: _rfdir(fd, sp, mlen)
                    565: int fd;
                    566: register unsigned char *sp;
                    567: int mlen;
                    568: {
                    569:        unsigned char rbuf[RDISIZE+ARB];
                    570:        Rfile *f;
                    571:        int len;
                    572:        long noff;
                    573: 
                    574:        if (mlen < SRDSIZE)
                    575:                rfpanic("readdir: len %d\n", mlen);
                    576:        len = frnetlong(sp, SRD_LEN);
                    577:        if (len <= 0 || (f = getfile(&sp[SNB_TAG])) == NULL) {
                    578:                nberrno = NBEINVAL;
                    579:                len = 0;
                    580:        } else if (f->type != RFTDIR) {
                    581:                nberrno = NBENOTDIR;
                    582:                len = 0;
                    583:        } else if (_rfpdread(f, rfuid, rfgid) == 0) {
                    584:                nberrno = NBEACCES;
                    585:                len = 0;
                    586:        } else {
                    587:                if (len > ARB)
                    588:                        len = ARB;
                    589:                len = fsdirread(f, frnetlong(sp, SRD_OFFSET),
                    590:                        (char *)rbuf + RDISIZE, len, &noff);
                    591:                if (len < 0) {
                    592:                        nberrno = fstonberr(fserrno);
                    593:                        len = 0;
                    594:                } else {
                    595:                        nberrno = 0;
                    596:                        noff -= frnetlong(sp, SRD_OFFSET);
                    597:                        tonetlong(rbuf, RDI_USED, noff);
                    598:                }
                    599:        }
                    600:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    601:        len += RDISIZE;
                    602:        _rfresp(fd, sp, rbuf, len);
                    603: }
                    604: 
                    605: /*
                    606:  * write
                    607:  * --permissions botch:
                    608:  * if we just check for write permission,
                    609:  * f = creat(name, 0) will leave a file descriptor we can't write
                    610:  * hence the owner check
                    611:  * if the client wants to protect the user better,
                    612:  * it can do its own checks;
                    613:  * here we are concerned with the server
                    614:  */
                    615: _rfwrite(fd, sp, mlen)
                    616: int fd;
                    617: register unsigned char *sp;
                    618: int mlen;
                    619: {
                    620:        unsigned char rbuf[RNBSIZE];
                    621:        Rfile *f;
                    622:        int n;
                    623:        long off;
                    624: 
                    625:        n = frnetlong(sp, SWR_LEN);
                    626:        if (mlen != SWRSIZE + n)
                    627:                rfpanic("write: size skew %d\n", mlen);
                    628:        off = frnetlong(sp, SWR_OFFSET);
                    629:        nberrno = 0;
                    630:        if ((f = getfile(&sp[SNB_TAG])) == NULL)
                    631:                nberrno = NBEINVAL;
                    632:        else if (_rfpwrite(f, rfuid, rfgid) == 0
                    633:             &&  _rfpowner(f, rfuid, rfgid) == 0)
                    634:                nberrno = NBEACCES;
                    635:        else if ((n = fswrite(f, off, (char *)sp + SWRSIZE, n)) < 0)
                    636:                nberrno = fstonberr(fserrno);
                    637:        tonetlong(rbuf, RNB_FSIZE, f->size);
                    638:        tonetshort(rbuf, RNB_ERRNO, nberrno);
                    639:        _rfresp(fd, sp, rbuf, RNBSIZE);
                    640: }
                    641: 
                    642: /*
                    643:  * truncate file
                    644:  */
                    645: _rftrunc(fd, sp, len)
                    646: int fd;
                    647: register unsigned char *sp;
                    648: int len;
                    649: {
                    650:        unsigned char rbuf[RNBSIZE];
                    651:        register Rfile *f;
                    652:        Rfile newf;
                    653: 
                    654:        nberrno = 0;
                    655:        if ((f = getfile(&sp[SNB_TAG])) == NULL)
                    656:                nberrno = NBEINVAL;
                    657:        else if (_rfpwrite(f, rfuid, rfgid) == 0
                    658:             &&  _rfpowner(f, rfuid, rfgid) == 0)       /* wrong? */
                    659:                nberrno = NBEACCES;
                    660:        else {
                    661:                newf = *f;
                    662:                newf.size = 0;
                    663:                if (fsupdate(f, &newf) < 0)
                    664:                        nberrno = fstonberr(fserrno);
                    665:        }
                    666:        tonetlong(rbuf, RNB_ERRNO, nberrno);
                    667:        _rfresp(fd, sp, rbuf, RNBSIZE);
                    668: }
                    669: 
                    670: /*
                    671:  * turn SNB_TAG (or some other tag)
                    672:  * into an Rfile
                    673:  */
                    674: 
                    675: static Rfile *
                    676: getfile(pp)
                    677: register unsigned char *pp;
                    678: {
                    679:        Tag t;
                    680:        Rfile *f;
                    681: 
                    682:        t = frnetlong(pp, 0);
                    683:        if (t == NBROOTTAG || (oldclient && t == oldrtag)) {
                    684:                sawroot = 1;
                    685:                return (root);          /* easy */
                    686:        }
                    687:        if ((f = _rftagtof(t)) != NULL)
                    688:                return (f);
                    689:        if (sawroot == 0 && (t & 0xffff) == OLDRINO) {  /* old-style root tag? */
                    690:                oldrtag = t;
                    691:                oldrdev = t >> 16;
                    692:                oldclient = 1;
                    693:                rflog("old client; root tag %lx\n", t);
                    694:                sawroot = 1;
                    695:                return (root);
                    696:        }
                    697:        nberrno = NBEINVAL;     /* shouldn't happen */
                    698:        rflog("bad tag %lx\n", t);
                    699:        return (NULL);
                    700: }
                    701: 
                    702: static
                    703: putmode(pp, off, f)
                    704: register unsigned char *pp;
                    705: int off;
                    706: register Rfile *f;
                    707: {
                    708:        int mode;
                    709: 
                    710:        mode = fstonbmode(f->mode);
                    711:        if (f->type == RFTDIR) {
                    712:                mode &= 07777;
                    713:                mode |= NB_IFDIR;
                    714:        } else if ((mode & NB_IFMT) == 0)
                    715:                mode |= NB_IFREG;
                    716:        /* else pass mode through unchanged for now */
                    717:        tonetshort(pp, off, mode);
                    718: }
                    719: 
                    720: /*
                    721:  * correct offset twixt client time and ours
                    722:  * only so often, or if difference is large;
                    723:  * e.g. hosts synchronize from a common clock,
                    724:  * but at different times
                    725:  */
                    726: 
                    727: static
                    728: timecheck(cltime)
                    729: long cltime;
                    730: {
                    731:        static int stall;
                    732:        static long lastck;
                    733:        long ourtime;
                    734:        int diff;
                    735: 
                    736:        if (stall-- != 0)       /* only every few stats */
                    737:                return;
                    738:        stall = 3;
                    739:        ourtime = time((long *)0);
                    740:        diff = cltime - ourtime;
                    741:        if (diff == timeoff) {
                    742:                lastck = ourtime;
                    743:                return;         /* no change */
                    744:        }
                    745:        if (diff - timeoff < 2 && diff - timeoff > -2   /* modest change */
                    746:        &&  ourtime - lastck < 90*60)           /* and last change was recent */
                    747:                return;
                    748:        lastck = ourtime;
                    749:        rflog("time: client %ld server %ld old diff %d new %d\n",
                    750:                cltime, ourtime, timeoff, diff);
                    751:        timeoff = diff;
                    752: }

unix.superglobalmegacorp.com

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