Annotation of researchv9/netb/src/file.c, revision 1.1.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.