Annotation of researchv10no/sys/fs/neta.c, revision 1.1.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.