Annotation of researchv10no/netfs/libnetb/funcs.c, revision 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.