Annotation of researchv9/netb/src/work.c, revision 1.1.1.1

1.1       root        1: #include "share.h"
                      2: 
                      3: file files[FILES];     /* dynamic? */
                      4: int nfile = FILES;
                      5: int nmoffset;
                      6: 
                      7: doput()
                      8: {      int i;
                      9:        for(i = 0; i < nfile; i++)
                     10:                if(files[i].tag == client.tag)
                     11:                        break;
                     12:        if(i >= nfile) {
                     13:                error("put: tag 0x%x not found\n", client.tag);
                     14:                client.errno = ENOENT;
                     15:                return;
                     16:        }
                     17:        if(files[i].tag == roottag)     /* never toss the root */
                     18:                return;
                     19:        close(files[i].fd);
                     20:        files[i].fd = -1;
                     21:        files[i].tag = 0;
                     22:        free(files[i].name);
                     23: }
                     24: 
                     25: /* real paranoia would check that name and fd still refer to the same file */
                     26: doupdate()
                     27: {      int i,f = 0;
                     28:        for(i = 0; i < nfile; i++)
                     29:                if(files[i].tag == client.tag)
                     30:                        break;
                     31:        if(i >= nfile) {
                     32:                error("update: tag 0x%x not found\n", client.tag);
                     33:                client.errno = ENOENT;
                     34:                return;
                     35:        }
                     36:        errno = 0;
                     37:        if(client.ta)
                     38:                f++, client.ta += dtime;
                     39:        else
                     40:                client.ta = files[i].stb.st_atime;
                     41:        if(client.tm)
                     42:                f++, client.tm += dtime;
                     43:        else
                     44:                client.tm = files[i].stb.st_mtime;
                     45:        if(f)   /* could someone have changed the file name underfoot? */
                     46:                utime(files[i].name, &client.ta);
                     47:        if(errno) {
                     48:                client.errno = errno;
                     49:                error("update: utime errno %d\n", errno);
                     50:                /* and forget the rest of it */
                     51:                return;
                     52:        }
                     53:        if(client.mode != files[i].stb.st_mode) {
                     54:                if(!isowner(&files[i].stb)) {
                     55:                        /* except for client root, this should never happen */
                     56:                        error("doupdate: client user %d not owner of %s (chmod)\n",
                     57:                                client.uid, files[i].name);
                     58:                        client.errno = EPERM;
                     59:                        return;
                     60:                }
                     61:                if(cray == 1) { /* stupid thing has no fchmod */
                     62:                        chmod(files[i].name, client.mode);
                     63:                        if(errno) {
                     64:                                error("chmod(%s,0%o) failed %d\n", files[i].name,
                     65:                                        client.mode, errno);
                     66:                                return;
                     67:                        }
                     68:                } else {
                     69:                        fchmod(files[i].fd, client.mode);
                     70:                        if(errno) {
                     71:                                error("fchmod(%s,0%o) failed %d\n", files[i].name,
                     72:                                        client.mode, errno);
                     73:                                return;
                     74:                        }
                     75:                }
                     76:        }
                     77:        /* refresh the stat? */
                     78: }
                     79: 
                     80: doread()
                     81: {      int i, n;
                     82:        for(i = 0; i < nfile; i++)
                     83:                if(client.tag == files[i].tag)
                     84:                        break;
                     85:        if(i >= nfile) {
                     86:                error("doread: tag 0x%x missing\n", client.tag);
                     87:                client.errno = ENOENT;
                     88:                return;
                     89:        }
                     90:        /* permissions check missing here */
                     91:        /* trust the client, except for unknown users, and our policy on `other' */
                     92:        /*if(clientuid() == -1  && !otherok) {
                     93:                client.errno = EPERM;
                     94:                return;
                     95:        }*/ /*no point, can't get here */
                     96:        /* if we're doing read-ahead, here's the spot */
                     97:        if((files[i].stb.st_mode & S_IFMT) == S_IFDIR) {
                     98:                /* fancy directory handling would go here
                     99:                doreaddir(i);
                    100:                return;*/
                    101:        }
                    102:        /* now we know that the headers for sndread add up to 16 bytes */
                    103:        if(files[i].pos != client.offset) {
                    104:                lseek(files[i].fd, client.offset, 0);
                    105:                files[i].pos = client.offset;   /* are you sure? */
                    106:        }
                    107:        if(16 + client.count > inlen)   /* sanity */
                    108:                client.count = inlen - 16;
                    109:        n = read(files[i].fd, inbuf + 16, (int)client.count);
                    110:        if(n < 0) {
                    111:                files[i].pos = (unsigned int)-1;        /* can't trust it? */
                    112:                client.errno = errno;
                    113:                return;
                    114:        }
                    115:        client.resplen = 16 + n;        /* read sets it */
                    116:        files[i].pos += n;
                    117: }
                    118: 
                    119: dowrite(p)
                    120: unsigned char *p;
                    121: {      int i, n;
                    122:        for(i = 0; i < nfile; i++)
                    123:                if(client.tag == files[i].tag)
                    124:                        break;
                    125:        if(i >= nfile) {
                    126:                debug("dowrite: tag 0x%x missing\n", client.tag);
                    127:                client.errno = ENOENT;
                    128:                return;
                    129:        }
                    130:        /*if(clientuid() == -1  && !otherok) {
                    131:                client.errno = EPERM;
                    132:                return;
                    133:        }*/ /* no point, can't happen */
                    134:        if(files[i].flags) {
                    135:                client.errno = EPERM;
                    136:                return;
                    137:        }
                    138:        if(files[i].pos != client.offset) {
                    139:                lseek(files[i].fd, client.offset, 0);
                    140:                files[i].pos = client.offset;
                    141:        }
                    142:        if(24 + client.count > inlen) {
                    143:                client.errno = EFAULT;
                    144:                return;
                    145:        }
                    146:        n = write(files[i].fd, inbuf + 24, (int)client.count);  /* secret 24 */
                    147:        if(n != client.count) {
                    148:                client.errno = errno? errno: EIO;
                    149:                files[i].pos = (unsigned int) -1;       /* ??? */
                    150:                return;
                    151:        }
                    152:        files[i].pos += i;
                    153: }
                    154: 
                    155: donami(p, len)
                    156: unsigned char *p;
                    157: {      int i, offset;
                    158:        unsigned char *s, *t, *bufend;
                    159:        for(i = 0; i < nfile; i++)
                    160:                if(client.tag == files[i].tag)
                    161:                        break;
                    162:        if(i >= nfile) {
                    163:                error("nami: tag 0x%x not found\n", client.tag);
                    164:                client.errno = ENOENT;
                    165:                return;
                    166:        }
                    167:        debug("nbnami: tag 0x%x for %d\n", client.tag, i);
                    168:        /* build the new name in nmbuf */
                    169:        for(s = nmbuf, t = files[i].name; *t; )
                    170:                *s++ = *t++;
                    171:        *s++ = '/';
                    172:        nmoffset = s - nmbuf;
                    173:        bufend = s + len;
                    174:        for(t = p; *t && s < bufend; t++) {     /* two tests for paranoia */
                    175:                if(s >= nmbuf + inlen) {
                    176:                        fatal("nami overran nmbuf\n");
                    177:                        client.errno = EFAULT;
                    178:                        return;
                    179:                }
                    180:                *s++ = *t;
                    181:        }
                    182:        *s = 0;
                    183:        debug("nbnami: nmbuf |%s|\n", nmbuf);
                    184:        /* first write the simple code and then worry about . and .. and null */
                    185:        if(client.flags == 0) {
                    186:                openit();
                    187:                return;
                    188:        }
                    189:        switch(client.flags) {
                    190:        default:
                    191:                error("nami: unk flag %d\n", client.flags);
                    192:                client.errno = EINVAL;
                    193:                return;
                    194:        case NI_NXCREAT:        /* expects it not to exist */
                    195:                creatit();
                    196:                break;
                    197:        case NI_LINK:   /* expects it not to exist */
                    198:                linkit();
                    199:                break;
                    200:        case NI_MKDIR:  /* expects it not to exist */
                    201:                mkdirit();
                    202:                break;
                    203:        case NI_RMDIR:  /* expects it to exist */
                    204:                rmdirit();
                    205:                break;
                    206:        case NI_DEL:    /* expects it to exist */
                    207:                delit();
                    208:                break;
                    209:        case NI_CREAT:  /* doesn't care */
                    210:                creatit();
                    211:                break;
                    212:        }
                    213: }
                    214: 
                    215: /* are fd and name consistent? (when might they not be?) */
                    216: /* this is only called on fstat() or stats of the root */
                    217: dostat()
                    218: {      static int t = 0;
                    219:        int i, n;
                    220:        struct stat *x;
                    221:        if(++t % 3 == 1 || t < 3) {
                    222:                i = time(0) - client.ta;
                    223: /*             if(i != dtime)
                    224:                        error("client time %d host time %d dtime %d\n",
                    225:                                client.ta, time(0), i);
                    226: */
                    227:                dtime = i;
                    228:        }
                    229:        for(i = 0; i < nfile; i++)
                    230:                if(client.tag == files[i].tag)
                    231:                        break;
                    232:        if(i >= nfile) {
                    233:                error("dostat: tag %d not found\n", client.tag);
                    234:                client.errno = ENOENT;
                    235:                return;
                    236:        }
                    237:        n = fstat(files[i].fd, &files[i].stb);
                    238:        if(n < 0) {     /* this is probably a serious error */
                    239:                error("dostat: returned errno %d %s(%d) %x\n", errno, files[i].name,
                    240:                        files[i].fd, files[i].tag);
                    241:                client.errno = errno;
                    242:                return;
                    243:        }
                    244:        x = &files[i].stb;
                    245:        client.ino = x->st_ino;
                    246:        client.dev = hostdev(x->st_dev);
                    247:        client.nlink = x->st_nlink;
                    248:        client.uid = hostuid(x->st_uid);
                    249:        client.gid = hostgid(x->st_gid);
                    250:        client.mode = x->st_mode;       /* permission calculation? */
                    251:        client.size = x->st_size;
                    252:        client.ta = x->st_atime - dtime;
                    253:        client.tm = x->st_mtime - dtime;
                    254:        client.tc = x->st_ctime - dtime;
                    255:        if(cray && client.size >= 0x80000000)
                    256:                client.size = 0x7fffffff;
                    257:        if((client.mode & S_IFMT) != S_IFREG && (client.mode & S_IFMT) != S_IFDIR)
                    258:                client.mode = 0;
                    259: }
                    260:        
                    261: /* paranoia suggests checking that fd and name are consistent */
                    262: dotrunc()
                    263: {      int i, n;
                    264:        for(i = 0; i < nfile; i++)
                    265:                if(client.tag == files[i].tag)
                    266:                        break;
                    267:        if(i >= nfile) {
                    268:                error("trunc: tag %d not found\n", client.tag);
                    269:                client.errno = ENOENT;
                    270:                return;
                    271:        }
                    272:        if(clientuid() == -1 && !otherok) {
                    273:                client.errno = EPERM;
                    274:                return;
                    275:        }
                    276:        n = creat(files[i].name, files[i].stb.st_mode);
                    277:        if(n < 0) {
                    278:                error("dotrunc: creat errno %d %s\n", errno, files[i].name);
                    279:                client.errno = errno;
                    280:                return;
                    281:        }
                    282:        close(n);
                    283: }

unix.superglobalmegacorp.com

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