Annotation of researchv10no/sys/fs/neta.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/systm.h"
        !             3: #include "sys/inode.h"
        !             4: #include "sys/dir.h"
        !             5: #include "sys/user.h"
        !             6: #include "sys/proc.h"
        !             7: #include "sys/stat.h"
        !             8: #include "sys/neta.h"
        !             9: #include "sys/buf.h"
        !            10: #include "sys/stream.h"
        !            11: #include "sys/conf.h"
        !            12: 
        !            13: /*
        !            14:  * obsolete network filesystem protocol
        !            15:  *
        !            16:  * i_fsflags is used in various places instead of the
        !            17:  * obsolete i_key
        !            18:  * this is a cheat
        !            19:  * it is allowed only because neta will soon vanish
        !            20:  */
        !            21: 
        !            22: struct senda nilx;
        !            23: static long natrannum;
        !            24: #define ND 100
        !            25: struct {
        !            26:        char len, s, n;
        !            27:        struct senda x[ND];
        !            28:        struct rcva y[ND];
        !            29: } netabuf = {ND};
        !            30: #define addx(z) netabuf.x[netabuf.n] = *z; netabuf.s = 1;
        !            31: #define addy(z) netabuf.y[netabuf.n++] = *z; if(netabuf.n >= ND) netabuf.n = 0; netabuf.s = 0;
        !            32: 
        !            33: int naput(), naupdat(), naread(), nawrite(), natrunc(), nastat();
        !            34: int nanami(), namount();
        !            35: struct fstypsw nafs =
        !            36: fsinit(naput, naupdat, naread, nawrite, natrunc, nastat,
        !            37:        nanami, namount, nodev, nullopen, nodev);
        !            38: 
        !            39: namount(sip, ip, flag, mnt, fstyp)
        !            40: struct inode *ip, *sip;
        !            41: {
        !            42:        if (!suser())
        !            43:                return;
        !            44:        if (mnt)
        !            45:                nadomount(sip, ip, flag, fstyp);
        !            46:        else
        !            47:                naunmount(ip, fstyp);
        !            48: }
        !            49: 
        !            50: nadomount(cip, dip, flag, fstyp)
        !            51: register struct inode *cip, *dip;
        !            52: {
        !            53:        struct inode pi;
        !            54:        register struct inode *rip;
        !            55: 
        !            56:        if(cip->i_sptr == NULL) {
        !            57:                u.u_error = ENXIO;
        !            58:                return;
        !            59:        }
        !            60:        if((dip->i_mode & IFMT) != IFDIR) {
        !            61:                u.u_error = ENOTDIR;
        !            62:                return;
        !            63:        }
        !            64:        /*
        !            65:         * take care, because of the stupid user-generated device
        !            66:         */
        !            67:        if (dip->i_fstyp == fstyp && dip->i_dev == flag) {
        !            68:                u.u_error = EBUSY;
        !            69:                return;
        !            70:        }
        !            71:        pi.i_dev = flag;
        !            72:        pi.i_fstyp = fstyp;
        !            73:        if ((rip = iget(&pi, flag, ROOTINO)) == NULL)
        !            74:                return;
        !            75:        if (rip->i_count > 1) {
        !            76:                iput(rip);
        !            77:                u.u_error = EBUSY;
        !            78:                return;
        !            79:        }
        !            80:        /*
        !            81:         * fake the root, rather than sending NAGET now,
        !            82:         * to avoid a deadlock when a server mounts itself
        !            83:         * the next stat will correct it
        !            84:         */
        !            85:        rip->i_mode = IFDIR|0555;
        !            86:        rip->i_un.i_tag = (flag<<16)|ROOTINO;
        !            87:        rip->i_un.i_cip = cip;
        !            88:        rip->i_nlink = 2;
        !            89:        rip->i_size = 32;
        !            90:        rip->i_uid = rip->i_gid = -1;
        !            91:        dip->i_mroot = rip;
        !            92:        rip->i_mpoint = dip;
        !            93:        prele(rip);
        !            94:        dip->i_count++;
        !            95:        cip->i_count++; 
        !            96:        cip->i_un.i_fsflags = 0;
        !            97: }
        !            98: 
        !            99: naunmount(mip, fstyp)
        !           100: register struct inode *mip;
        !           101: {
        !           102:        register struct inode *rip;
        !           103: 
        !           104:        rip = mip->i_mroot;
        !           105:        plock(rip);
        !           106:        xumount(rip);   /* shared text from remote root */
        !           107:        if (rip->i_count > 1 || ifsbusy(rip)) {
        !           108:                u.u_error = EBUSY;
        !           109:                prele(rip);
        !           110:                return;
        !           111:        }
        !           112:        plock(mip);
        !           113:        mip->i_mroot = NULL;
        !           114:        iput(mip);
        !           115:        if ((mip = rip->i_un.i_cip) == NULL)
        !           116:                panic("naunmount");
        !           117:        iput(rip);
        !           118:        iput(mip);
        !           119: }
        !           120: 
        !           121: naput(ip)
        !           122: struct inode *ip;
        !           123: {      struct senda x;
        !           124:        struct rcva y;
        !           125: 
        !           126:        if (ip->i_un.i_cip == NULL)
        !           127:                return;         /* obscure gmount safety */
        !           128:        if(ip->i_flag & ICHG)
        !           129:                naupdat(ip, &time, &time, 0);
        !           130:        x = nilx;
        !           131:        x.trannum = natrannum++;
        !           132:        x.cmd = NPUT;
        !           133:        x.uid = u.u_uid;
        !           134:        x.tag = ip->i_un.i_tag;
        !           135:        x.dev = ip->i_dev;
        !           136:        x.ino = ip->i_number;
        !           137:        send(ip->i_un.i_cip, &x, &y);
        !           138:        if(y.errno)
        !           139:                u.u_error = y.errno;
        !           140: }
        !           141: 
        !           142: /*
        !           143:  * special case:
        !           144:  * the root is faked up locally
        !           145:  * really just to avoid a silly deadlock in the face server
        !           146:  */
        !           147: nafillin(fip, ip)
        !           148: struct inode *fip;
        !           149: register struct inode *ip;
        !           150: {      struct senda x;
        !           151:        struct rcva y;
        !           152: 
        !           153:        ip->i_un.i_cip = NULL;          /* in case we have to put it */
        !           154:        if (fip->i_un.i_cip == NULL) {
        !           155:                u.u_error = ENXIO;
        !           156:                iput(ip);
        !           157:                return (-1);
        !           158:        }
        !           159:        x = nilx;
        !           160:        x.trannum = natrannum++;
        !           161:        x.cmd = NGET;
        !           162:        x.uid = u.u_uid;
        !           163:        x.dev = ip->i_dev;
        !           164:        x.ino = ip->i_number;
        !           165:        send(fip->i_un.i_cip, &x, &y);
        !           166:        if(y.errno == 0) {
        !           167:                ip->i_mode = y.mode;
        !           168:                ip->i_un.i_tag = y.tag;
        !           169:                ip->i_un.i_cip = fip->i_un.i_cip;
        !           170:                ip->i_nlink = y.nlink;
        !           171:                ip->i_size = y.size;
        !           172:                ip->i_uid = y.uid;
        !           173:                ip->i_gid = y.gid;
        !           174:                return (0);
        !           175:        }
        !           176:        iput(ip);
        !           177:        u.u_error = y.errno;
        !           178:        return(-1);
        !           179: }
        !           180: 
        !           181: /* this is used by CREAT */
        !           182: naupdat(ip, ta, tm, waitfor)
        !           183: struct inode *ip;
        !           184: time_t *ta, *tm;
        !           185: {      struct senda x;
        !           186:        struct rcva y;
        !           187: 
        !           188:        if (ip->i_un.i_cip == NULL)
        !           189:                return;         /* obscure gmount safety */
        !           190:        x = nilx;
        !           191:        x.trannum = natrannum++;
        !           192:        x.cmd = NUPDAT;
        !           193:        x.uid = u.u_uid;
        !           194:        x.gid = u.u_gid;
        !           195:        x.newuid = ip->i_uid;
        !           196:        x.newgid = ip->i_gid;
        !           197:        x.mode = ip->i_mode;
        !           198:        x.tag = ip->i_un.i_tag;
        !           199:        x.dev = ip->i_dev;
        !           200:        x.ino = ip->i_number;
        !           201:        if(ip->i_flag & IACC)
        !           202:                x.ta = *ta;
        !           203:        else
        !           204:                x.ta = 0;
        !           205:        if(ip->i_flag & ICHG)
        !           206:                x.tm = *tm;
        !           207:        else
        !           208:                x.tm = 0;
        !           209:        send(ip->i_un.i_cip, &x, &y);
        !           210:        if(y.errno) {
        !           211:                u.u_error = y.errno;
        !           212:                return;
        !           213:        }
        !           214:        ip->i_mode = y.mode;
        !           215:        ip->i_nlink = y.nlink;
        !           216:        ip->i_size = y.size;
        !           217:        ip->i_uid = y.uid;
        !           218:        ip->i_gid = y.gid;
        !           219:        ip->i_flag &= ~(IUPD|IACC|ICHG);
        !           220: }
        !           221: 
        !           222: naread(ip)
        !           223: struct inode *ip;
        !           224: {      struct senda x;
        !           225:        struct rcva y;
        !           226:        struct buf *bp;
        !           227:        int n;
        !           228: 
        !           229:        bp = geteblk();
        !           230:        clrbuf(bp);     /* could use user's buffer */
        !           231:        x = nilx;
        !           232:        x.trannum = natrannum++;
        !           233:        x.cmd = NREAD;
        !           234:        x.uid = u.u_uid;
        !           235:        x.tag = ip->i_un.i_tag;
        !           236:        x.dev = ip->i_dev;
        !           237:        x.ino = ip->i_number;
        !           238:        x.buf = bp->b_un.b_addr;
        !           239:        do {
        !           240:                n = u.u_count;
        !           241:                if(n > BUFSIZE)
        !           242:                        n = BUFSIZE;
        !           243:                x.count = n;
        !           244:                x.offset = Ltol(u.u_offset);
        !           245:                send(ip->i_un.i_cip, &x, &y);
        !           246:                if((n = y.count) > 0) {
        !           247:                        if(u.u_segflg != SEGSYS) {
        !           248:                                if(copyout(bp->b_un.b_addr, u.u_base, n)) {
        !           249:                                        u.u_error = EFAULT;
        !           250:                                        break;
        !           251:                                }
        !           252:                        }
        !           253:                        else
        !           254:                                bcopy(bp->b_un.b_addr, u.u_base, n);
        !           255:                        u.u_base += n;
        !           256:                        u.u_offset = Lladd(u.u_offset, n);
        !           257:                        u.u_count -= n;
        !           258:                }
        !           259:                if(y.errno)
        !           260:                        u.u_error = y.errno;
        !           261:        } while(u.u_error == 0 && u.u_count != 0 && n > 0);
        !           262:        brelse(bp);
        !           263: }
        !           264: nawrite(ip)
        !           265: struct inode *ip;
        !           266: {      struct senda x;
        !           267:        struct rcva y;
        !           268:        struct buf *bp;
        !           269:        int n;
        !           270: 
        !           271:        bp = geteblk();
        !           272:        x = nilx;
        !           273:        x.trannum = natrannum++;
        !           274:        x.cmd = NWRT;
        !           275:        x.uid = u.u_uid;
        !           276:        x.tag = ip->i_un.i_tag;
        !           277:        x.dev = ip->i_dev;
        !           278:        x.ino = ip->i_number;
        !           279:        x.buf = bp->b_un.b_addr;
        !           280:        do {
        !           281:                n = u.u_count;
        !           282:                if(n > BUFSIZE)         /* should be bufsiz, but ... */
        !           283:                        n = BUFSIZE;
        !           284:                if(u.u_segflg != SEGSYS) {
        !           285:                        if(copyin(u.u_base, bp->b_un.b_addr, n)) {
        !           286:                                u.u_error = EFAULT;
        !           287:                                break;
        !           288:                        }
        !           289:                }
        !           290:                else
        !           291:                        bcopy(u.u_base, bp->b_un.b_addr, n);
        !           292:                x.count = n;
        !           293:                x.offset = Ltol(u.u_offset);
        !           294:                send(ip->i_un.i_cip, &x, &y);
        !           295:                if(y.errno) {
        !           296:                        u.u_error = y.errno;
        !           297:                        break;
        !           298:                }
        !           299:                ip->i_flag |= IUPD|ICHG;
        !           300:                u.u_count -= n;
        !           301:                u.u_offset = Lladd(u.u_offset, n);
        !           302:                u.u_base += n;
        !           303:        } while(u.u_error == 0 && u.u_count != 0);
        !           304:        brelse(bp);
        !           305: }
        !           306: 
        !           307: natrunc(ip)
        !           308: struct inode *ip;
        !           309: {      struct senda x;
        !           310:        struct rcva y;
        !           311: 
        !           312:        x = nilx;
        !           313:        x.trannum = natrannum++;
        !           314:        x.cmd = NTRUNC;
        !           315:        x.uid = u.u_uid;
        !           316:        x.tag = ip->i_un.i_tag;
        !           317:        x.dev = ip->i_dev;
        !           318:        x.ino = ip->i_number;
        !           319:        send(ip->i_un.i_cip, &x, &y);
        !           320:        if(y.errno)
        !           321:                u.u_error = y.errno;
        !           322: }
        !           323: 
        !           324: nastat(ip, ub)
        !           325: struct inode *ip;
        !           326: struct stat *ub;
        !           327: {      struct senda x;
        !           328:        struct rcva y;
        !           329:        struct stat ds;
        !           330: 
        !           331:        x = nilx;
        !           332:        x.trannum = natrannum++;
        !           333:        x.cmd = NSTAT;
        !           334:        x.uid = u.u_uid;
        !           335:        x.tag = ip->i_un.i_tag;
        !           336:        x.dev = ip->i_dev;
        !           337:        x.ino = ip->i_number;
        !           338:        x.ta = time;
        !           339:        send(ip->i_un.i_cip, &x, &y);
        !           340:        if(y.errno) {
        !           341:                u.u_error = y.errno;
        !           342:                return;
        !           343:        }
        !           344:        ds.st_dev = ip->i_dev;
        !           345:        ds.st_ino = ip->i_number;
        !           346:        ip->i_mode = ds.st_mode = y.mode;
        !           347:        ip->i_nlink = ds.st_nlink = y.nlink;
        !           348:        ip->i_uid = ds.st_uid = y.uid;
        !           349:        ip->i_gid = ds.st_gid = y.gid;
        !           350:        ds.st_size = ip->i_size = y.size;
        !           351:        ds.st_atime = y.tm[0];
        !           352:        ds.st_mtime = y.tm[1];
        !           353:        ds.st_ctime = y.tm[2];
        !           354:        if(copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
        !           355:                u.u_error = EFAULT;
        !           356: }
        !           357: 
        !           358: /* a lot like fsnami */
        !           359: nanami(p, flagp, follow)
        !           360: struct nx *p;
        !           361: struct argnamei *flagp;
        !           362: {      register struct inode *dp, *dip;
        !           363:        register char *cp;
        !           364:        int i, fstyp;
        !           365:        dev_t d;
        !           366:        struct direct dent;
        !           367:        struct senda x;
        !           368:        struct rcva y;
        !           369: 
        !           370:        cp = p->cp;
        !           371:        dp = p->dp;
        !           372:        x = nilx;
        !           373:        x.cmd = NNAMI;
        !           374:        x.uid = u.u_uid;
        !           375:        x.gid = u.u_gid;
        !           376: 
        !           377:        /*
        !           378:         * dp must be a directory and
        !           379:         * must have X permission.
        !           380:         * cp is a path name relative to that directory.
        !           381:         */
        !           382: 
        !           383: dirloop:
        !           384:        if((dp->i_mode&IFMT) != IFDIR)
        !           385:                u.u_error = ENOTDIR;
        !           386:        (void) access(dp, IEXEC);
        !           387:        for (i=0; *cp!='\0' && *cp!='/'; i++) {
        !           388:                if (i >= DIRSIZ) {
        !           389:                        u.u_error = ENOENT;
        !           390:                        break;
        !           391:                }
        !           392:                dent.d_name[i] = *cp++;
        !           393:        }
        !           394:        if(u.u_error)
        !           395:                goto outnull;
        !           396:        while (i < DIRSIZ)
        !           397:                dent.d_name[i++] = '\0';
        !           398:        if (dent.d_name[0] == '\0') {           /* null name, e.g. "/" or "" */
        !           399:                if (flagp->flag != NI_SEARCH) {
        !           400:                        u.u_error = ENOENT;
        !           401:                        goto outnull;
        !           402:                }
        !           403:                goto out;
        !           404:        }
        !           405:        u.u_segflg = SEGSYS;
        !           406: 
        !           407:        /* send off the request, get back ino, dev, flagp stuff */
        !           408:        x.trannum = natrannum++;
        !           409:        x.tag = dp->i_un.i_tag;
        !           410:        x.dev = dp->i_dev;
        !           411:        x.ino = dp->i_number;
        !           412:        x.count = DIRSIZ;
        !           413:        x.buf = dent.d_name;
        !           414:        while(*cp == '/')
        !           415:                cp++;
        !           416:        if(*cp=='\0') {
        !           417:                switch(flagp->flag) {
        !           418:                case NI_SEARCH:
        !           419:                        x.flags = NSEARCH;
        !           420:                        break;
        !           421:                case NI_DEL:
        !           422:                        x.flags = NDEL;
        !           423:                        break;
        !           424:                case NI_LINK:
        !           425:                        x.flags = NLINK;
        !           426:                        x.dev = flagp->un.il->i_dev;
        !           427:                        x.ino = flagp->un.il->i_number;
        !           428:                        break;
        !           429:                case NI_CREAT:
        !           430:                case NI_NXCREAT:
        !           431:                        x.flags = NCREAT;
        !           432:                        x.mode = flagp->un.mode;
        !           433:                        break;
        !           434:                case NI_MKDIR:
        !           435:                        x.flags = NMKDIR;
        !           436:                        x.mode = flagp->un.mode;
        !           437:                        break;
        !           438:                case NI_RMDIR:
        !           439:                        x.flags = NRMDIR;
        !           440:                        break;
        !           441:                default:
        !           442:                        u.u_error = ENXIO;
        !           443:                        goto outnull;
        !           444:                }
        !           445:        }
        !           446:        send(dp->i_un.i_cip, &x, &y);
        !           447:        if(y.errno) {
        !           448:                u.u_error = y.errno;
        !           449:                goto outnull;
        !           450:        }
        !           451:        if(y.flags == NOMATCH)
        !           452:                goto nomatch;
        !           453:        dent.d_ino = y.ino;
        !           454:        if (y.ino == 0) {
        !           455:                printf("y.ino 0 in nanami\n");
        !           456:                u.u_error = ENOENT;
        !           457:                goto outnull;
        !           458:        }
        !           459:        d = y.dev;
        !           460: 
        !           461:        if(*cp == 0 && (flagp->flag==NI_DEL || flagp->flag==NI_RMDIR)) {
        !           462:                /* delete the entry, server did all but xrele */
        !           463:                dip = iget(dp, d, dent.d_ino);
        !           464:                if (dip == NULL)
        !           465:                        goto outnull;
        !           466:                if (dip->i_count == 1) {
        !           467:                        dip->i_un.i_cip = NULL;
        !           468:                        iput(dip);
        !           469:                        goto outnull;
        !           470:                }
        !           471:                if(dip->i_flag&ITEXT)
        !           472:                        xrele(dip);             /* free busy text */
        !           473:                dip->i_nlink--;
        !           474:                dip->i_flag |= ICHG;
        !           475:                iput(dip);
        !           476:                goto outnull;
        !           477:        }
        !           478:        /*
        !           479:         * Special handling for ".."
        !           480:         */
        !           481:        fstyp = dp->i_fstyp;
        !           482: 
        !           483:        if(y.flags == NROOT) {  /* popped out of net fs */
        !           484:                if (dp == u.u_rdir)
        !           485:                        dent.d_ino = dp->i_number;
        !           486:                else if (dp != rootdir && dent.d_ino==ROOTINO
        !           487:                     &&  dp->i_number == ROOTINO) {
        !           488:                        if ((dip = dp->i_mpoint) == NULL)
        !           489:                                panic("namei: mpoint");
        !           490:                        iput(dp);
        !           491:                        dp = dip;
        !           492:                        plock(dp);
        !           493:                        dp->i_count++;
        !           494:                        /* was there always .. there? */
        !           495:                        if(*cp && cp < p->nbuf + 3)
        !           496:                                panic("nanami");
        !           497:                        if(!*cp && cp < p->nbuf + 2)
        !           498:                                panic("nanami2");
        !           499:                        if(*cp)
        !           500:                                *--cp = '/';
        !           501:                        *--cp = '.';
        !           502:                        *--cp = '.';
        !           503:                        if(fstyp != dp->i_fstyp)
        !           504:                                goto more;
        !           505:                        goto dirloop;
        !           506:                }
        !           507:        }
        !           508:        dip = dp;
        !           509:        prele(dip);
        !           510:        dp = iget(dip, d, dent.d_ino);
        !           511:        if(dp == NULL) {
        !           512:                iput(dip);
        !           513:                goto out;
        !           514:        }
        !           515:        if (dp->i_count == 1 && nafillin(dip, dp) < 0) {
        !           516:                iput(dip);
        !           517:                dp = NULL;
        !           518:                goto out;
        !           519:        }
        !           520:        if(fstyp != dp->i_fstyp) {
        !           521:                iput(dip);
        !           522:                goto more;
        !           523:        }
        !           524:        /*
        !           525:         * Check for symbolic link
        !           526:         */
        !           527:        if ((dp->i_mode&IFMT)==IFLNK && (follow || *cp)) {
        !           528:                char *ocp;
        !           529: 
        !           530:                ocp = cp;
        !           531:                while (*cp++)
        !           532:                        ;
        !           533:                if (dp->i_size + (cp-ocp) >= p->nlen-1
        !           534:                    || ++p->nlink>8) {
        !           535:                        u.u_error = ELOOP;
        !           536:                        iput(dip);
        !           537:                        goto outnull;
        !           538:                }
        !           539:                bcopy(ocp, p->nbuf+dp->i_size + 1, cp-ocp);
        !           540:                *(p->nbuf + dp->i_size) = '/';
        !           541:                u.u_base = p->nbuf;
        !           542:                u.u_count = dp->i_size;
        !           543:                u.u_offset = ltoL(0);
        !           544:                readi(dp);
        !           545:                if(u.u_error) {
        !           546:                        iput(dip);
        !           547:                        goto outnull;
        !           548:                }
        !           549:                cp = p->nbuf;
        !           550:                iput(dp);
        !           551:                if (*cp == '/') {
        !           552:                        iput(dip);
        !           553:                        while (*cp == '/')
        !           554:                                cp++;
        !           555:                        if ((dp = u.u_rdir) == NULL)
        !           556:                                dp = rootdir;
        !           557:                        plock(dp);
        !           558:                        dp->i_count++;
        !           559:                } else {
        !           560:                        dp = dip;
        !           561:                        plock(dp);
        !           562:                }
        !           563:                if(fstyp != dp->i_fstyp)
        !           564:                        goto more;
        !           565:                goto dirloop;
        !           566:        }
        !           567:        iput(dip);
        !           568:        if(*cp)
        !           569:                goto dirloop;
        !           570:        if(flagp->flag == NI_SEARCH && flagp->un.buf)
        !           571:                bcopy((caddr_t)dent.d_name, flagp->un.buf, flagp->len);
        !           572:        goto out;
        !           573: 
        !           574: nomatch:
        !           575:        /*
        !           576:         * Search failed.
        !           577:         */
        !           578:        switch(flagp->flag) {   /* probably creating a new file */
        !           579:        case NI_LINK:   /* make a link */
        !           580:        case NI_MKDIR:  /* make directory */
        !           581:                goto outnull;
        !           582:        case NI_CREAT:  /* create a new file */
        !           583:        case NI_NXCREAT:
        !           584:                if(y.errno == EACCES || y.ino == 0) {
        !           585:                        u.u_error = EACCES;
        !           586:                        goto outnull;
        !           587:                }
        !           588:                dip = iget(dp, y.dev, y.ino);
        !           589:                if(dip == NULL)
        !           590:                        goto outnull;
        !           591:                if (dip->i_count == 1 && nafillin(dp, dip) < 0)
        !           592:                        goto outnull;
        !           593:                iput(dp);
        !           594:                dp = dip;
        !           595:                flagp->un.mode = ~flagp->un.mode;
        !           596:                goto out;
        !           597: 
        !           598:        default:
        !           599:                u.u_error = ENOENT;
        !           600:                goto outnull;
        !           601:        }
        !           602: 
        !           603: out:
        !           604:        p->dp = dp;
        !           605:        return (0);
        !           606: 
        !           607: outnull:
        !           608:        iput(dp);
        !           609:        p->dp = NULL;
        !           610:        return (0);
        !           611: 
        !           612: more:
        !           613:        p->cp = cp;
        !           614:        p->dp = dp;
        !           615:        return (1);
        !           616: }
        !           617: 
        !           618: struct {
        !           619:        int tran;
        !           620:        short proc, dev;
        !           621: } ntx[32];     /* more debuggery */
        !           622: send(cip, x, y)
        !           623: struct inode *cip;
        !           624: struct senda *x;
        !           625: struct rcva *y;
        !           626: {      int n, tn, ix;
        !           627:        x->version = NETVERSION;
        !           628:        /* until demux works, use key as a lock */
        !           629:        while(cip->i_un.i_fsflags)
        !           630:                sleep((caddr_t)cip, PZERO);
        !           631:        cip->i_un.i_fsflags = 1;
        !           632:        tn = x->trannum;
        !           633:        netabuf.s = 2;
        !           634:        for(ix = 0; ntx[ix].tran && ix < 32; ix++) {
        !           635:                ntx[ix].tran = tn;
        !           636:                ntx[ix].proc = u.u_procp->p_pid;
        !           637:                ntx[ix].dev = x->dev;
        !           638:        }
        !           639:        n = istwrite(cip, (char *)x, sizeof(*x));
        !           640:        netabuf.s = 3;
        !           641:        if(n == -1) {
        !           642:                y->errno = EIO;
        !           643:                goto bad;
        !           644:        }
        !           645:        netabuf.s = 4;
        !           646:        if(x->count > 0 && x->buf && x->cmd != NREAD) {
        !           647:                n = istwrite(cip, x->buf, x->count);
        !           648:                if(n == -1)
        !           649:                        goto bad;
        !           650:        }
        !           651: readagain:
        !           652:        netabuf.s = 5;
        !           653:        n = istread(cip, (char *)y, sizeof(*y), 0);
        !           654:        netabuf.s = 6;
        !           655:        if(n != sizeof(*y))
        !           656:                goto bad;
        !           657:        if(y->errno == 0 && x->cmd == NREAD) {
        !           658:                n = istread(cip, x->buf, y->count, 0);
        !           659:                if(n != y->count) {
        !           660:                        printf("neta: read %d expected %d\n", n, y->count);
        !           661:                        /* shut it down */
        !           662:                        istwrite(cip, (char *)x, 0);
        !           663:                        goto bad;
        !           664:                }
        !           665:        }
        !           666:        if(y->errno == 0) {
        !           667:                if(y->trannum != tn) {
        !           668:                        if(y->trannum < tn)     /* distant past */
        !           669:                                goto readagain;
        !           670:                        printf("neta: sent %d got %d\n", tn, y->trannum);
        !           671:                        goto bad;
        !           672:                }
        !           673:                addx(x);
        !           674:                addy(y);
        !           675:                if(ix < 32)
        !           676:                        ntx[ix].tran = 0;
        !           677:                cip->i_un.i_fsflags = 0;
        !           678:                wakeup((caddr_t)cip);
        !           679:                return;
        !           680:        }
        !           681: bad:
        !           682:        cip->i_un.i_fsflags = 0;
        !           683:        if(ix < 32)
        !           684:                ntx[ix].tran = 0;
        !           685:        for(ix = 0; ix < 32; ix++)
        !           686:                if(ntx[ix].tran)
        !           687:                        printf("tran %d proc %d 0x%x\n", ntx[ix].tran, ntx[ix].proc, ntx[ix].dev);
        !           688:        wakeup((caddr_t)cip);
        !           689:        addx(x);
        !           690:        addy(y);
        !           691:        if(y->errno)
        !           692:                return;
        !           693:        y->errno = EIO;
        !           694: }
        !           695: static struct D { struct D *a; char *b;} VER = {&VER,"\n85/6/9:neta.c\n"};

unix.superglobalmegacorp.com

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