Annotation of researchv8dc/netfs/work.c, revision 1.1.1.1

1.1       root        1: #include "fserv.h"
                      2: #include "errno.h"
                      3: #include "sys/neta.h"
                      4: extern char *buf, *nbuf;
                      5: extern int dtime, myfd, wrcnt, rdcnt, lflag;
                      6: extern struct rcva y, nilrcv;
                      7: 
                      8: doput(x)
                      9: struct senda *x;
                     10: {
                     11:        y.trannum = x->trannum;
                     12:        if(x->tag == 0) {
                     13:                debug("\tput got 0");
                     14:                respond(EIO);
                     15:                dumpstate();
                     16:                leave(9);
                     17:        }
                     18:        clrnetf(x->tag);
                     19:        respond(errno);
                     20: }
                     21: 
                     22: doget(x)
                     23: struct senda *x;
                     24: {      netf *p;
                     25:        y.trannum = x->trannum;
                     26:        p = getnetf(x->dev, x->ino);
                     27:        if(p == 0) {
                     28:                debug("\tget didn't %d %d", x->dev, x->ino);
                     29:                respond(errno);
                     30:                dumpstate();
                     31:                return;
                     32:        }
                     33:        if(p->fd == -1 && xstat(p->name, &p->statb) < 0
                     34:                || p->fd != -1 && fstat(p->fd, &p->statb) < 0) {
                     35:                respond(errno);
                     36:                return;
                     37:        }
                     38:        debug2("\tget %d %d 0%o %d %d %s\n", p->dev, p->ino,
                     39:                p->statb.st_mode, p->statb.st_uid, p->statb.st_gid, p->name);
                     40:        y.mode = p->statb.st_mode;
                     41:        y.tag = p->tag;
                     42:        y.nlink = p->statb.st_nlink;
                     43:        y.uid = hostuid(&p->statb);
                     44:        y.gid = hostgid(&p->statb);
                     45:        y.size = p->statb.st_size;
                     46:        respond(0);
                     47: }
                     48: 
                     49: dofree(x)              /* means rmt thinks nlink == 0 */
                     50: struct senda *x;
                     51: {
                     52:        y.trannum = x->trannum;
                     53:        respond(0);
                     54: }
                     55: 
                     56: doupdat(x)
                     57: struct senda *x;
                     58: {      netf *p;
                     59:        int i;
                     60:        y.trannum = x->trannum;
                     61:        p = gettag(x->tag);
                     62:        if(p == 0) {
                     63:                respond(errno);
                     64:                return;
                     65:        }
                     66:        debug2("\tupdat 0%o %d %d\n", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid);
                     67:        debug2("\t\t0%o %d %d\n", x->mode, x->uid, x->gid);
                     68:        x->ta += dtime;
                     69:        x->tm += dtime;
                     70:        if(p->name == 0) {      /* of course this can't happen */
                     71:                debug("\tname 0 tag %d\n", p->tag);
                     72:                respond(EIO);
                     73:                dumpstate();
                     74:                return;
                     75:        }
                     76:        debug2("\t%s\n", p->name);
                     77:        if(x->ta == dtime)
                     78:                x->ta = p->statb.st_atime;
                     79:        if(x->tm == dtime)
                     80:                x->tm = p->statb.st_mtime;
                     81:        utime(p->name, &x->ta);
                     82:        errno = 0;      /* p->name may be wrong, so times off [bug] */
                     83:        if(x->mode != p->statb.st_mode) {
                     84:                i = 1;
                     85:                if(isowner(x, &p->statb))
                     86:                        fchmod(p->fd, x->mode);
                     87:                else
                     88:                        errno = EPERM;
                     89:                perror("\tfchmod");
                     90:        }
                     91:        if(x->uid == 0 && (hostuid(&p->statb) != x->newuid
                     92:                || hostgid(&p->statb) != x->newgid)) {
                     93:                i = 1;
                     94:                if(isowner(x, &p->statb))
                     95:                        fchown(p->fd, myuid(x->newuid, x->newgid),
                     96:                                mygid(x->newuid, x->newgid));
                     97:                else
                     98:                        errno = EPERM;
                     99:                if(errno)
                    100:                        perror("\tfchown");
                    101:                debug1("\tupdat %d %d\n", p->statb.st_uid, p->statb.st_gid);
                    102:        }
                    103:        if(i)
                    104:                fstat(p->fd, &p->statb);
                    105:        y.mode = p->statb.st_mode;
                    106:        y.nlink = p->statb.st_nlink;
                    107:        y.uid = hostuid(&p->statb);
                    108:        y.gid = hostgid(&p->statb);
                    109:        y.size =  p->statb.st_size;
                    110:        if(hisdev(p->statb.st_dev) != p->dev || p->ino != p->statb.st_ino) {
                    111:                debug("\tdev oops\n");
                    112:                dumpstate();
                    113:        }
                    114:        respond(errno);
                    115: }
                    116: 
                    117: doread(x)
                    118: struct senda *x;
                    119: {      netf *p;
                    120:        int n, offset = 0;
                    121:        y.trannum = x->trannum;
                    122:        p = gettag(x->tag);
                    123:        if(p == 0) {
                    124:                if(errno == 0)
                    125:                        errno = EIO;
                    126:                respond(errno);
                    127:                return;
                    128:        }
                    129:        if(ftype(p) == S_IFLNK) {
                    130:                n = readlink(p->name, buf, x->count);
                    131:                offset = x->offset;
                    132:                debug2("readlink %s %d %d\n", p->name, n, x->count);
                    133:                offset = x->offset;
                    134:                if(n < offset)
                    135:                        offset = n;
                    136:        }
                    137:        else {
                    138:                if(opennf(p, 0)) {
                    139:                        respond(errno);
                    140:                        return;
                    141:                }
                    142:                if(lseek(p->fd, x->offset, 0) < 0)
                    143:                        perror("\tread lseek");
                    144:                getbuf(x->count);
                    145:                n = read(p->fd, buf, x->count);
                    146:        }
                    147:        debug1("\tread got %d wanted %d\n", n, x->count);
                    148:        if(n < 0) {
                    149:                y.errno = errno;
                    150:                y.count = n;
                    151:                respond(0);
                    152:                return;
                    153:        }
                    154:        y.count = n - offset;
                    155:        respond(0);
                    156:        (void) write(myfd, buf + offset, (unsigned) n - offset);
                    157:        wrcnt += n;
                    158: }
                    159: 
                    160: dowrite(x)
                    161: struct senda *x;
                    162: {      netf *p;
                    163:        int n;
                    164:        y.trannum = x->trannum;
                    165:        if(x->count == 0)
                    166:                respond(0);
                    167:        getbuf(x->count);
                    168:        if((n = read(myfd, buf, x->count)) != x->count) {
                    169:                debug("\twrite expected %d got %d\n", x->count, n);
                    170:                rdcnt += n;
                    171:                if(errno == 0)
                    172:                        errno = EIO;
                    173:                respond(errno);
                    174:                dumpstate();
                    175:                return;
                    176:        }
                    177:        wrcnt += n;
                    178:        debug1("\twrite %d\n", x->count);
                    179:        p = gettag(x->tag);
                    180:        if(p == 0) {
                    181:                respond(errno);
                    182:                return;
                    183:        }
                    184:        if(opennf(p, 1)) {
                    185:                respond(errno);
                    186:                return;
                    187:        }
                    188:        n = lseek(p->fd, x->offset, 0);
                    189:        if(n < 0) {
                    190:                debug("\twrite lseek %d\n", errno);
                    191:                dumpstate();
                    192:        }
                    193:        if((n = write(p->fd, buf, x->count)) != x->count) {
                    194:                debug("\twrite failed %d %d\n", n, p->fd);
                    195:                if(errno == 0)
                    196:                        errno = EIO;
                    197:                dumpstate();
                    198:        }
                    199:        respond(errno);
                    200: }
                    201: 
                    202: dotrunc(x)
                    203: struct senda *x;
                    204: {
                    205:        y.trannum = x->trannum;
                    206:        truncnf(x->tag);
                    207:        respond(errno);
                    208: }
                    209: 
                    210: dostat(x)
                    211: struct senda *x;
                    212: {      netf *p;
                    213:        y.trannum = x->trannum;
                    214:        debug2("\tstat %d\n", x->tag);
                    215:        p = gettag(x->tag);
                    216:        if(p == 0) {
                    217:                respond(errno);
                    218:                return;
                    219:        }
                    220:        debug2("\tlstat %s ", p->name);
                    221:        if(p->fd == -1 && xstat(p->name, &p->statb) < 0
                    222:                || p->fd != -1 && fstat(p->fd, &p->statb) < 0) {
                    223:                respond(errno);
                    224:                return;
                    225:        }
                    226:        debug2("0%o %d %d\n", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid);
                    227:        y.mode = p->statb.st_mode;
                    228:        y.nlink = p->statb.st_nlink;
                    229:        y.uid = hostuid(&p->statb);
                    230:        y.gid = hostgid(&p->statb);
                    231:        debug2("\thostuid(%d) = %d\n", p->statb.st_uid, y.uid);
                    232:        debug2("\tgid %d\n", y.gid);
                    233:        y.size = p->statb.st_size;
                    234:        y.tm[0] = p->statb.st_atime;
                    235:        y.tm[1] = p->statb.st_mtime;
                    236:        y.tm[2] = p->statb.st_ctime;
                    237:        if(hisdev(p->statb.st_dev) != p->dev || p->ino != p->statb.st_ino) {
                    238:                debug("\toops dev or ino\n");
                    239:                dumpstate();
                    240:        }
                    241:        respond(0);
                    242: }
                    243: 
                    244: donami(x)
                    245: struct senda *x;
                    246: {      netf *p, *q;
                    247:        int fd, i, nlink = 0;
                    248:        y.trannum = x->trannum;
                    249:        getbuf(x->count);
                    250:        if((i = read(myfd, buf, x->count)) != x->count) {
                    251:                rdcnt += i;
                    252:                if(errno == 0)
                    253:                        errno = EIO;
                    254:                respond(errno);
                    255:                return;
                    256:        }
                    257:        rdcnt += i;
                    258:        p = gettag(x->tag);
                    259:        if(p == 0) {
                    260:                respond(errno);
                    261:                return;
                    262:        }
                    263:        debug1("\tcdir %s 0%o %d %d\n", p->name, p->statb.st_mode,
                    264:                p->statb.st_uid, p->statb.st_gid);
                    265:        if(ftype(p) != S_IFDIR) {
                    266:                respond(ENOTDIR);
                    267:                return;
                    268:        }
                    269:        if(noaccess(x, &p->statb, S_IEXEC)) {
                    270:                respond(EACCES);
                    271:                return;
                    272:        }
                    273:        fixnbuf(p->name, x->count, buf, x->flags);
                    274:        debug2("\tnami %s (%d)\n", nbuf, x->flags);
                    275: again:
                    276:        q = 0;
                    277:        if(x->flags == NDEL)
                    278:                q = oldnetf(nbuf);
                    279:        if(q == 0)
                    280:                q = newnetf(nbuf, -1, 0);
                    281:        if(q != 0) {
                    282:                debug2("\tfound\n");
                    283:                errno = 0;
                    284:                if(lflag && ftype(q) == S_IFLNK)
                    285:                        if(lcllink(q)) {
                    286:                                if(nlink++ > 4) {
                    287:                                        errno = ELOOP;
                    288:                                        goto bad;
                    289:                                }
                    290:                                goto again;
                    291:                        }
                    292:                y.ino = q->ino;
                    293:                y.tag = q->tag;
                    294:                y.dev = q->dev;
                    295:                y.mode = q->statb.st_mode;
                    296:                y.nlink = q->statb.st_nlink;
                    297:                y.uid = hostuid(&q->statb);
                    298:                y.gid = hostgid(&q->statb);
                    299:                y.size = q->statb.st_size;
                    300:                if(isroot(q) && strncmp(buf, ".", x->count)) {
                    301:                        debug2("NROOT %s\n", buf);
                    302:                        y.flags = NROOT;
                    303:                }
                    304:                if(x->flags == NDEL) {
                    305:                        if(noaccess(x, &p->statb, S_IWRITE)) {
                    306:                                debug1("\tnodelete\n");
                    307:                                respond(EPERM);
                    308:                                return;
                    309:                        }
                    310:                        if(y.dev != x->dev)
                    311:                                errno = EBUSY;
                    312:                        if(y.flags == NROOT)
                    313:                                errno = EPERM;
                    314:                        (void) unlink(nbuf);
                    315:                        debug1("\tunlink %s %d\n", nbuf, errno);
                    316:                }
                    317:                if(x->flags == NCREAT && noaccess(x, &q->statb, S_IWRITE)) {
                    318:                        debug1("\tnocreat\n");
                    319:                        respond(EPERM);
                    320:                        return;
                    321:                }
                    322:                respond(errno);
                    323:                return;
                    324:        }
                    325:        else {
                    326:                y.flags = NOMATCH;
                    327:                if(x->flags == NLINK) {
                    328:                        if(noaccess(x, &p->statb, S_IWRITE)) {
                    329:                                debug1("\tnolink %d %d %d\n", x->uid,
                    330:                                        p->statb.st_uid, p->statb.st_gid);
                    331:                                respond(EPERM);
                    332:                                return;
                    333:                        }
                    334:                        q = gettag(x->tag);
                    335:                        p = getnetf(x->dev, x->ino);
                    336:                        if(q == 0 || p == 0) {
                    337:                                debug1("\tno link p 0x%x q 0x%x", p, q);
                    338:                                respond(EXDEV);
                    339:                                return;
                    340:                        }
                    341:                        debug1("\tlink %d %d %d %s %s",
                    342:                                x->dev, x->ino, q->dev, p->name, nbuf);
                    343:                        if(q->dev != p->dev)
                    344:                                errno = EXDEV;
                    345:                        i = link(p->name, nbuf);
                    346:                        if(i != -1)
                    347:                                errno = 0;
                    348:                        else
                    349:                                debug("\tlink %d", errno);
                    350:                }
                    351:                else if(x->flags == NCREAT) {
                    352:                        debug1("\tnami creat 0%o %s\n", x->mode, nbuf);
                    353:                        if(noaccess(x, &p->statb, S_IWRITE)) {
                    354:                                debug1("\tnoaccess\n");
                    355:                                respond(EACCES);
                    356:                                return;
                    357:                        }
                    358:                        switch(x->mode & S_IFMT) {
                    359:                        case 0:
                    360:                        case S_IFREG:
                    361:                                fd = creat(nbuf, x->mode);
                    362:                                if(fd != -1) {
                    363:                                        q = newnetf(nbuf, fd, 1);
                    364:                                        y.ino = q->ino;
                    365:                                        y.dev = q->dev;
                    366:                                        errno = 0;
                    367:                                        chown(nbuf, myuid(x->uid, x->gid),
                    368:                                                mygid(x->uid, x->gid));
                    369:                                        debug1("\tchown %d %d\n",
                    370:                                                myuid(x->uid, x->gid),
                    371:                                                mygid(x->uid, x->gid));
                    372:                                        (void) fstat(fd, &q->statb);
                    373:                                }
                    374:                                break;
                    375:                        case S_IFDIR:
                    376:                                if(x->uid != 0) {
                    377:                                        debug1("\tsuser %d\n", x->uid);
                    378:                                        respond(EPERM);
                    379:                                        return;
                    380:                                }
                    381:                                i = mknod(nbuf, x->mode, 0);
                    382:                                if(i != -1) {
                    383:                                        q = newnetf(nbuf, -1, 0);
                    384:                                        y.ino = q->ino;
                    385:                                        y.dev = q->dev;
                    386:                                        errno = 0;
                    387:                                        chown(nbuf, myuid(x->uid, x->gid),
                    388:                                                mygid(x->uid, x->gid));
                    389:                                        (void) fstat(q->fd, &q->statb);
                    390:                                        debug1("\tmknod 0%o %d %d\n",
                    391:                                                q->statb.st_mode, q->statb.st_uid, q->statb.st_gid);
                    392:                                }
                    393:                                else
                    394:                                        debug1("\tmknod\n");
                    395:                                break;
                    396:                        case S_IFLNK:
                    397:                                errno = 0;
                    398:                                fd = creat(nbuf, 0777);
                    399:                                if(fd < 0)
                    400:                                        break;
                    401:                                chown(nbuf, myuid(x->uid, x->gid),
                    402:                                        mygid(x->uid, x->gid));
                    403:                                i = fchmod(fd, x->mode | S_IFLNK);
                    404:                                debug1("\tfchmod(%s) %d errno %d\n", nbuf, i, errno);
                    405:                                if(errno == 0) {
                    406:                                        debug2("\tfd = %d\n", fd);
                    407:                                        q = newnetf(nbuf, fd, 1);
                    408:                                        y.ino = q->ino;
                    409:                                        y.dev = q->dev;
                    410:                                }
                    411:                                break;
                    412:                        default:
                    413:                                errno = EPERM;
                    414:                                break;
                    415:                        }
                    416:                }
                    417:        }
                    418: bad:
                    419:        y.tag = q->tag;
                    420:        y.nlink = q->statb.st_nlink;
                    421:        y.size = q->statb.st_size;
                    422:        y.uid = hostuid(&q->statb);
                    423:        y.gid = hostuid(&q->statb);
                    424:        respond(errno);
                    425: }

unix.superglobalmegacorp.com

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