Annotation of researchv9/netb/src/file.c, revision 1.1

1.1     ! root        1: /* when the client reads directories, some work may be required */
        !             2: #include "share.h"
        !             3: 
        !             4: file tfile;
        !             5: int roottag;
        !             6: unsigned char *slash;
        !             7: 
        !             8: openit()
        !             9: {      int n;
        !            10:        if(!openfile()) {
        !            11:                if(client.namiflags != NBROOT)
        !            12:                        client.errno = ENOENT;
        !            13:                return;
        !            14:        }
        !            15:        n = gimmefile();
        !            16:        if(n < 0)
        !            17:                return;
        !            18:        files[n].fd = tfile.fd;
        !            19:        files[n].flags = tfile.flags;
        !            20:        if(stat(nmbuf, &files[n].stb) < 0) {
        !            21:                client.errno = errno;   /* must have been set? */
        !            22:                close(tfile.fd);
        !            23:                return;                 /* files[n].tag is 0 still */
        !            24:        }
        !            25:        checkdev(files[n].stb.st_dev);
        !            26:        files[n].tag = maketag(&files[n].stb);
        !            27:        if(setname(n))
        !            28:                return;
        !            29:        checkdupl(n);
        !            30:        retnami(n);
        !            31: }
        !            32: 
        !            33: creatit()
        !            34: {      int n, fd;
        !            35:        if((n = openfile()) && client.flags == NI_NXCREAT) {
        !            36:                client.errno = EEXIST;
        !            37:                close(tfile.fd);
        !            38:                return;
        !            39:        }
        !            40:        if(n) { /* exists, creat it */
        !            41:                if(writeperm())
        !            42:                        return;
        !            43:                n = creat(nmbuf, (int)client.mode);
        !            44:                if(n >= 0)
        !            45:                        close(n);
        !            46:                else {
        !            47:                        client.errno = errno;
        !            48:                        return;
        !            49:                }
        !            50:                n = gimmefile();
        !            51:                if(n < 0)
        !            52:                        return;
        !            53:                files[n].fd = tfile.fd;
        !            54:                files[n].flags = tfile.flags;
        !            55:                if(stat(nmbuf, &files[n].stb) < 0) {
        !            56:                        client.errno = errno;
        !            57:                        close(tfile.fd);
        !            58:                        return;
        !            59:                }
        !            60:                checkdev(files[n].stb.st_dev);
        !            61:                files[n].tag = maketag(&files[n].stb);
        !            62:                if(setname(n))
        !            63:                        return;
        !            64:                checkdupl(n);   /* here it is important too to get the new one */
        !            65:                retnami(n);
        !            66:                return;
        !            67:        }
        !            68:        /* doesn't exist, creat it */
        !            69:        if(client.namiflags == NBROOT)
        !            70:                return; /* can't creat the root (is errno set?) */
        !            71:        n = gimmefile();
        !            72:        if(n < 0)
        !            73:                return;
        !            74:        if(dirwriteperm())
        !            75:                return;
        !            76:        if((client.mode & S_IFMT)) {    /* no symbolic links or mknods */
        !            77:                error("client: client.mode 0%o\n", client.mode);
        !            78:                client.errno = EXDEV;
        !            79:                return;
        !            80:        }
        !            81:        if((fd = creat(nmbuf, client.mode)) < 0) {
        !            82:                client.errno = errno;
        !            83:                return;
        !            84:        }
        !            85:        if(chown(nmbuf, clientuid(), clientgid()) < 0)
        !            86:                return;
        !            87:        files[n].fd = open(nmbuf, 2);
        !            88:        if(files[n].fd < 0) {
        !            89:                files[n].fd = open(nmbuf, 0);
        !            90:                if(files[n].fd < 0) {
        !            91:                        client.errno = errno;
        !            92:                        unlink(nmbuf);
        !            93:                        close(fd);
        !            94:                        return;
        !            95:                }
        !            96:                files[n].flags = 1;
        !            97:        }
        !            98:        close(fd);      /* fd was write-only */
        !            99:        if(stat(nmbuf, &files[n].stb) < 0) {    /* it was there a second ago */
        !           100:                client.errno = errno;
        !           101:                unlink(nmbuf);
        !           102:                close(files[n].fd);
        !           103:                return;
        !           104:        }
        !           105:        checkdev(files[n].stb.st_dev);
        !           106:        files[n].tag = maketag(&files[n].stb);
        !           107:        if(setname(n))
        !           108:                return;
        !           109:        retnami(n);
        !           110: }
        !           111:        
        !           112: linkit()
        !           113: {      int i, n;
        !           114:        if(dirwriteperm())
        !           115:                return;
        !           116:        if(openfile()) {
        !           117:                client.errno = EEXIST;
        !           118:                close(tfile.fd);
        !           119:                return;
        !           120:        }
        !           121:        for(i = 0; i < FILES; i++)
        !           122:                if(files[i].tag == client.ino)
        !           123:                        break;
        !           124:        if(i >= FILES) {        /* can't happen */
        !           125:                error("can't happen: linkit %s, no tag %x\n", nmbuf, client.ino);
        !           126:                client.errno = EXDEV;   /* not really */
        !           127:                return;
        !           128:        }
        !           129:        debug("linking %s to %s\n", files[i].name, nmbuf);
        !           130:        n = link(files[i].name, nmbuf);
        !           131:        if(n < 0) {
        !           132:                debug("link errno %d\n", errno);
        !           133:                client.errno = errno;
        !           134:        }
        !           135: }
        !           136: 
        !           137: mkdirit()
        !           138: {      int n;
        !           139:        if(openfile()) {
        !           140:                client.errno = EEXIST;
        !           141:                close(tfile.fd);        /* how does entry get tossed? */
        !           142:                return;
        !           143:        }
        !           144:        if(client.namiflags == NBROOT)
        !           145:                return;
        !           146:        if(dirwriteperm())
        !           147:                return;
        !           148:        if(mkdir(nmbuf, client.mode) < 0) {
        !           149:                client.errno = errno;
        !           150:                return;
        !           151:        }
        !           152:        if(chown(nmbuf, clientuid(), clientgid()) < 0)
        !           153:                return;
        !           154: }
        !           155:        
        !           156: rmdirit()
        !           157: {
        !           158:        if(!openfile()) {
        !           159:                client.errno = EEXIST;
        !           160:                return;
        !           161:        }
        !           162:        close(tfile.fd);
        !           163:        if(dirwriteperm())
        !           164:                return;
        !           165:        if(rmdir(nmbuf) < 0)
        !           166:                client.errno = errno;
        !           167:        else
        !           168:                client.errno = 0;
        !           169: }
        !           170: 
        !           171: delit()
        !           172: {
        !           173:        if(!openfile()) {
        !           174:                client.errno = ENOENT;
        !           175:                close(tfile.fd);
        !           176:                return;
        !           177:        }
        !           178:        if(client.namiflags == NBROOT)
        !           179:                return;
        !           180:        close(tfile.fd);
        !           181:        if(dirwriteperm())
        !           182:                return;
        !           183:        if((tfile.stb.st_mode & S_IFMT) != S_IFREG) {
        !           184:                client.errno = EISDIR;
        !           185:                return;
        !           186:        }
        !           187:        if(unlink(nmbuf) < 0)
        !           188:                client.errno = errno;
        !           189:        else
        !           190:                client.errno = 0;
        !           191: }
        !           192: 
        !           193: openfile()
        !           194: {      unsigned char *p;
        !           195:        static struct stat statb;
        !           196:        int i;
        !           197:        slash = 0;
        !           198:        for(p = nmbuf; *p; ) {
        !           199:                for(; *p == '/'; p++)
        !           200:                        slash = p;
        !           201:                if(*p == 0)
        !           202:                        break;
        !           203:                *--p = 0;
        !           204:                i = stat(nmbuf, &statb);
        !           205:                if(i < 0) {
        !           206:                        debug("openfile: stat %s (%d)\n", nmbuf, errno);
        !           207:                        client.errno = errno;
        !           208:                        return(0);
        !           209:                }
        !           210:                if(searchperm())
        !           211:                        return(0);
        !           212:                *p++ = '/';
        !           213:                checkdev(statb.st_dev);
        !           214:                if(maketag(&statb) == roottag && p[0] == '.' && p[1] == '.'
        !           215:                        && (p[2] == 0 || p[2] == '/')) {
        !           216:                        client.namiflags = NBROOT;
        !           217:                        client.used = 2 + (p - nmbuf) - nmoffset;
        !           218:                        debug("openfile: root used %d offset %d\n", client.used,
        !           219:                                nmoffset);
        !           220:                        return(0);
        !           221:                }
        !           222:                while(*p && *p != '/')
        !           223:                        p++;
        !           224:        }
        !           225:        i = stat(nmbuf, &statb);
        !           226:        if(i < 0)
        !           227:                return(0);
        !           228:        tfile.fd = -1;
        !           229:        tfile.flags = 0;
        !           230:        tfile.stb = statb;
        !           231:        tfile.fd = open(nmbuf, 2);
        !           232:        if(tfile.fd < 0) {
        !           233:                tfile.fd = open(nmbuf, 0);
        !           234:                if(tfile.fd < 0)
        !           235:                        return(0);
        !           236:                tfile.flags = 1;
        !           237:        }
        !           238:        return(1);
        !           239: }
        !           240: 
        !           241: retnami(n)
        !           242: {      file *t = files + n;
        !           243:        client.tag = t->tag;
        !           244:        client.ino = t->stb.st_ino;
        !           245:        client.dev = hostdev(t->stb.st_dev);
        !           246:        debug("retnami dev 0x%x ino %d tag 0x%x %s\n", client.dev, client.ino,
        !           247:                client.tag, t->name);
        !           248:        client.mode = t->stb.st_mode;
        !           249:        client.used = 0;        /* ? */
        !           250:        client.nlink = t->stb.st_nlink;
        !           251:        client.uid = hostuid(t->stb.st_uid);
        !           252:        client.gid = hostgid(t->stb.st_gid);
        !           253:        client.size = t->stb.st_size;           /* watch it! */
        !           254:        if(cray && client.size >= 0x80000000)
        !           255:                client.size = 0x7fffffff;
        !           256:        /* fortunately all known hosts agree on time */
        !           257:        client.ta = t->stb.st_atime - dtime;
        !           258:        client.tc = t->stb.st_ctime - dtime;
        !           259:        client.tm = t->stb.st_mtime - dtime;
        !           260: }
        !           261: 
        !           262: gimmefile()
        !           263: {      int i;
        !           264:        for(i = 0; i < FILES; i++)
        !           265:                if(files[i].tag == 0)
        !           266:                        break;
        !           267:        if(i >= FILES) {
        !           268:                error("out of file structs %d\n", i);
        !           269:                client.errno = ENFILE;
        !           270:                return(-1);
        !           271:        }
        !           272:        files[i].flags = 0;
        !           273:        files[i].pos = 0;
        !           274:        return(i);
        !           275: }
        !           276: 
        !           277: /* is this really an error to recover from? */
        !           278: setname(n)
        !           279: {      unsigned char *p;
        !           280:        p = (unsigned char *)malloc(strlen(nmbuf) + 1);
        !           281:        if(p == NULL) {
        !           282:                error("out of space on %s\n", nmbuf);
        !           283:                client.errno = ENOSPC;
        !           284:                return(-1);
        !           285:        }
        !           286:        strcpy(p, nmbuf);
        !           287:        files[n].name = p;
        !           288:        return(0);
        !           289: }
        !           290: 
        !           291: checkdupl(n)
        !           292: {      int i;
        !           293:        unsigned char *x;
        !           294:        /* if it duplicates someone we've got, toss the old one, but use its tag */
        !           295:        for(i = 0; i < FILES; i++) {
        !           296:                if(i == n)
        !           297:                        continue;
        !           298:                if(files[i].tag != files[n].tag)
        !           299:                        continue;
        !           300:                debug("ok: creat found dup %s\n", nmbuf);
        !           301:                if(strlen(files[i].name) < strlen(files[n].name)) {
        !           302:                        x = files[n].name;
        !           303:                        files[n].name = files[i].name;
        !           304:                        free(x);
        !           305:                }
        !           306:                else
        !           307:                        free(files[i].name);
        !           308:                close(files[i].fd);
        !           309:                files[i].tag = 0;
        !           310:        }
        !           311:        /* update device translation if necessary */
        !           312:        checkdev(files[n].stb.st_dev);
        !           313: }
        !           314: 
        !           315: dev *devs;
        !           316: int devlen, ndev;
        !           317: checkdev(n)
        !           318: {      int i;
        !           319:        for(i = 0; i < ndev; i++)
        !           320:                if(devs[i].hdev == n)
        !           321:                        return;
        !           322:        if(ndev >= devlen) {
        !           323:                if(!devlen)
        !           324:                        devs = (dev *) malloc((devlen = 10) * sizeof(dev));
        !           325:                else {
        !           326:                        devlen *= 2;
        !           327:                        devs = (dev *) realloc((char *)devs, devlen * sizeof(dev));
        !           328:                        error("reallocated devs to %d entries\n", devlen);
        !           329:                }
        !           330:                if(!devs)
        !           331:                        fatal("alloc of %d devs failed!\n", devlen);
        !           332:        }
        !           333:        if(ndev >= 256)
        !           334:                fatal("%d devs? (too many)\n", ndev);
        !           335:        devs[ndev].hdev = n;
        !           336:        devs[ndev].cdev = hisdev | ndev;
        !           337:        debug("devs[%d] %x->%x\n", ndev, n, hisdev | ndev);
        !           338:        ndev++;
        !           339: }
        !           340: 
        !           341: addroot()
        !           342: {      int n;
        !           343:        n = gimmefile();
        !           344:        files[n].name = (unsigned char *)"/";
        !           345:        files[n].fd = open("/", 2);
        !           346:        if(files[n].fd < 0) {
        !           347:                files[n].fd = open("/", 0);
        !           348:                if(files[n].fd < 0)
        !           349:                        fatal("can't open root, errno %d\n", errno);
        !           350:                files[n].flags = 1;
        !           351:        }
        !           352:        if(stat("/", &files[n].stb) < 0)
        !           353:                fatal("stat root errno %d\n", errno);
        !           354:        checkdev(files[n].stb.st_dev);
        !           355:        files[n].tag = maketag(&files[n].stb);
        !           356:        roottag = files[n].tag;
        !           357:        debug("root %d, tag 0x%x\n", n, files[n].tag);
        !           358:        if(files[n].stb.st_ino != ROOTINO)      /* which ROOTINO is this? */
        !           359:                error("client and host probably don't agree on rootino %d\n",
        !           360:                        files[n].stb.st_ino);
        !           361: }
        !           362: 
        !           363: maketag(s)
        !           364: struct stat *s;
        !           365: {      int tag;
        !           366:        tag = (hostdev(s->st_dev) << 16) | s->st_ino;
        !           367:        debug("maketag (%x,%x)->%x\n", s->st_dev, s->st_ino, tag);
        !           368:        return(tag);
        !           369: }
        !           370: 
        !           371: #if cray == 1
        !           372: #include "signal.h"
        !           373: int crapsig;
        !           374: char sysbuf[256];
        !           375: mkdir(s)
        !           376: char *s;
        !           377: {      int pid, ret = 0;
        !           378:        if(!crapsig++)
        !           379:                signal(SIGCLD, SIG_IGN);
        !           380:        sprintf(sysbuf, "mkdir %s", s);
        !           381:        if(strlen(sysbuf) >= sizeof(sysbuf))
        !           382:                fatal("sysbuf overflow %s\n", sysbuf);
        !           383:        if((pid = fork()) == 0) {
        !           384:                setuid(clientuid());
        !           385:                setgid(clientgid());
        !           386:                exit(system(sysbuf));
        !           387:        }
        !           388:        wait(&ret);
        !           389:        if(!ret)
        !           390:                return(0);
        !           391:        errno = EPERM;  /* who knows? */
        !           392:        return(-1);
        !           393: }
        !           394: rmdir(s)
        !           395: char *s;
        !           396: {
        !           397:        if(!crapsig++)
        !           398:                signal(SIGCLD, SIG_IGN);
        !           399:        sprintf(sysbuf, "rmdir %s", s);
        !           400:        if(strlen(sysbuf) >= sizeof(sysbuf))
        !           401:                fatal("sysbuf overflow in rmdir %s\n", sysbuf);
        !           402:        if(system(sysbuf) == 0)
        !           403:                return(0);
        !           404:        errno = EPERM;  /* ? */
        !           405:        return(-1);
        !           406: }
        !           407: fchmod()
        !           408: {
        !           409:        fatal("!!!fchmod called\n");
        !           410: }
        !           411: #endif

unix.superglobalmegacorp.com

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