Annotation of lucent/sys/src/9/port/net.c, revision 1.1

1.1     ! root        1: #include       "u.h"
        !             2: #include       "../port/lib.h"
        !             3: #include       "mem.h"
        !             4: #include       "dat.h"
        !             5: #include       "fns.h"
        !             6: #include       "../port/error.h"
        !             7: 
        !             8: enum
        !             9: {
        !            10:        Qlisten = 1,
        !            11:        Qclone  = 2,
        !            12:        Q2nd    = 3,
        !            13:        Q3rd    = 4,
        !            14:        Qinf    = 5,
        !            15: };
        !            16: 
        !            17: /*
        !            18:  *  find protection structure
        !            19:  */
        !            20: static Netprot*
        !            21: findprot(Network *np, int id)
        !            22: {
        !            23:        Netprot *p;
        !            24: 
        !            25:        for(p = np->prot; p; p = p->next)
        !            26:                if(p->id == id)
        !            27:                        break;
        !            28:        return p;
        !            29: }
        !            30: 
        !            31: /*
        !            32:  *  generate a 3 level directory
        !            33:  */
        !            34: int
        !            35: netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
        !            36: {
        !            37:        Qid q;
        !            38:        char buf[32];
        !            39:        Network *np = vp;
        !            40:        int t;
        !            41:        Netprot *p;
        !            42:        int perm;
        !            43:        char *o;
        !            44: 
        !            45:        USED(ntab);
        !            46:        q.vers = 0;
        !            47: 
        !            48:        /* top level directory contains the name of the network */
        !            49:        if(c->qid.path == CHDIR){
        !            50:                switch(i){
        !            51:                case 0:
        !            52:                        q.path = CHDIR | Q2nd;
        !            53:                        strcpy(buf, np->name);
        !            54:                        devdir(c, q, buf, 0, eve, 0555, dp);
        !            55:                        break;
        !            56:                default:
        !            57:                        return -1;
        !            58:                }
        !            59:                return 1;
        !            60:        }
        !            61: 
        !            62:        /* second level contains clone plus all the conversations */
        !            63:        t = STREAMTYPE(c->qid.path);
        !            64:        if(t == Q2nd || t == Qclone){
        !            65:                if(i == 0){
        !            66:                        q.path = Qclone;
        !            67:                        devdir(c, q, "clone", 0, eve, 0666, dp);
        !            68:                }else if(i <= np->nconv){
        !            69:                        if(findprot(np, i-1) == 0)
        !            70:                                return 0;
        !            71:                        q.path = CHDIR|STREAMQID(i-1, Q3rd);
        !            72:                        sprint(buf, "%d", i-1);
        !            73:                        devdir(c, q, buf, 0, eve, 0555, dp);
        !            74:                }else
        !            75:                        return -1;
        !            76:                return 1;
        !            77:        }
        !            78: 
        !            79:        /* third level depends on the number of info files */
        !            80:        p = findprot(np, STREAMID(c->qid.path));
        !            81:        if(p == 0)
        !            82:                return 0;
        !            83:        if(*p->owner){
        !            84:                o = p->owner;
        !            85:                perm = p->mode;
        !            86:        } else {
        !            87:                o = eve;
        !            88:                perm = 0666;
        !            89:        }
        !            90:        switch(i){
        !            91:        case 0:
        !            92:                q.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
        !            93:                devdir(c, q, "data", 0, o, perm, dp);
        !            94:                break;
        !            95:        case 1:
        !            96:                q.path = STREAMQID(STREAMID(c->qid.path), Sctlqid);
        !            97:                devdir(c, q, "ctl", 0, o, perm, dp);
        !            98:                break;
        !            99:        case 2:
        !           100:                if(np->listen == 0)
        !           101:                        return 0;
        !           102:                q.path = STREAMQID(STREAMID(c->qid.path), Qlisten);
        !           103:                devdir(c, q, "listen", 0, o, perm, dp);
        !           104:                break;
        !           105:        default:
        !           106:                i -= 3;
        !           107:                if(i >= np->ninfo)
        !           108:                        return -1;
        !           109:                q.path = STREAMQID(STREAMID(c->qid.path), Qinf+i);
        !           110:                devdir(c, q, np->info[i].name, 0, eve, 0444, dp);
        !           111:                break;
        !           112:        }
        !           113:        return 1;
        !           114: }
        !           115: 
        !           116: int     
        !           117: netwalk(Chan *c, char *name, Network *np)
        !           118: {
        !           119:        if(strcmp(name, "..") == 0) {
        !           120:                switch(STREAMTYPE(c->qid.path)){
        !           121:                case Q2nd:
        !           122:                        c->qid.path = CHDIR;
        !           123:                        break;
        !           124:                case Q3rd:
        !           125:                        c->qid.path = CHDIR|Q2nd;
        !           126:                        break;
        !           127:                default:
        !           128:                        panic("netwalk %lux", c->qid.path);
        !           129:                }
        !           130:                return 1;
        !           131:        }
        !           132: 
        !           133:        return devwalk(c, name, (Dirtab*)np, 0, netgen);
        !           134: }
        !           135: 
        !           136: void
        !           137: netstat(Chan *c, char *db, Network *np)
        !           138: {
        !           139:        devstat(c, db, (Dirtab*)np, 1, netgen);
        !           140: }
        !           141: 
        !           142: Chan *
        !           143: netopen(Chan *c, int omode, Network *np)
        !           144: {
        !           145:        int id = 0;
        !           146:        Netprot *p;
        !           147: 
        !           148:        if(c->qid.path & CHDIR){
        !           149:                if(omode != OREAD)
        !           150:                        error(Eperm);
        !           151:        } else {
        !           152:                switch(STREAMTYPE(c->qid.path)){
        !           153:                case Sdataqid:
        !           154:                case Sctlqid:
        !           155:                        id = STREAMID(c->qid.path);
        !           156:                        break;
        !           157:                case Qlisten:
        !           158:                        streamopen(c, np->devp);
        !           159:                        id = (*np->listen)(c);
        !           160:                        streamclose(c);
        !           161:                        c->qid.path = STREAMQID(id, Sctlqid);
        !           162:                        break;
        !           163:                case Qclone:
        !           164:                        id = (*np->clone)(c);
        !           165:                        c->qid.path = STREAMQID(id, Sctlqid);
        !           166:                        break;
        !           167:                default:
        !           168:                        if(omode != OREAD)
        !           169:                                error(Ebadarg);
        !           170:                }
        !           171:                switch(STREAMTYPE(c->qid.path)){
        !           172:                case Sdataqid:
        !           173:                case Sctlqid:
        !           174:                        streamopen(c, np->devp);
        !           175:                        if(np->protop && c->stream->devq->next->info != np->protop)
        !           176:                                pushq(c->stream, np->protop);
        !           177:                        p = findprot(np, id);
        !           178:                        if(netown(p, u->p->user, omode&7) < 0)
        !           179:                                error(Eperm);
        !           180:                        break;
        !           181:                }
        !           182:        }
        !           183:        c->mode = openmode(omode);
        !           184:        c->flag |= COPEN;
        !           185:        c->offset = 0;
        !           186:        return c;
        !           187: }
        !           188: 
        !           189: long
        !           190: netread(Chan *c, void *a, long n, ulong offset, Network *np)
        !           191: {
        !           192:        int t;
        !           193:        char buf[256];
        !           194: 
        !           195:        if(c->stream)
        !           196:                return streamread(c, a, n);
        !           197: 
        !           198:        if(c->qid.path&CHDIR)
        !           199:                return devdirread(c, a, n, (Dirtab*)np, 0, netgen);
        !           200: 
        !           201:        t = STREAMTYPE(c->qid.path);
        !           202:        if(t < Qinf || t >= Qinf + np->ninfo)
        !           203:                error(Ebadusefd);
        !           204: 
        !           205:        (*np->info[t-Qinf].fill)(c, buf, sizeof(buf));
        !           206:        return readstr(offset, a, n, buf);
        !           207: }
        !           208: 
        !           209: void
        !           210: netadd(Network *np, Netprot *p, int id)
        !           211: {
        !           212:        Netprot **l, *pp;
        !           213: 
        !           214:        memset(p, 0, sizeof(Netprot));
        !           215:        p->id = id;
        !           216: 
        !           217:        l = &np->prot;
        !           218:        for(pp = np->prot; pp; pp = pp->next){
        !           219:                if(pp->id == id)
        !           220:                        panic("netadd");
        !           221:                l = &pp->next;
        !           222:        }
        !           223:        *l = p;
        !           224: }
        !           225: 
        !           226: Lock netlock;
        !           227: 
        !           228: int
        !           229: netown(Netprot *p, char *o, int omode)
        !           230: {
        !           231:        static int access[] = { 0400, 0200, 0600, 0100 };
        !           232:        int mode;
        !           233:        int t;
        !           234: 
        !           235:        lock(&netlock);
        !           236:        if(*p->owner){
        !           237:                if(strncmp(o, p->owner, NAMELEN) == 0)  /* User */
        !           238:                        mode = p->mode;
        !           239:                else if(strncmp(o, eve, NAMELEN) == 0)  /* Bootes is group */
        !           240:                        mode = p->mode<<3;
        !           241:                else
        !           242:                        mode = p->mode<<6;              /* Other */
        !           243: 
        !           244:                t = access[omode&3];
        !           245:                if((t & mode) == t){
        !           246:                        unlock(&netlock);
        !           247:                        return 0;
        !           248:                } else {
        !           249:                        unlock(&netlock);
        !           250:                        return -1;
        !           251:                }
        !           252:        }
        !           253:        strncpy(p->owner, o, NAMELEN);
        !           254:        p->mode = 0660;
        !           255:        unlock(&netlock);
        !           256:        return 0;
        !           257: }
        !           258: 
        !           259: void
        !           260: netdisown(Netprot *p)
        !           261: {
        !           262:        p->owner[0] = 0;
        !           263: }
        !           264: 
        !           265: #undef CHDIR   /* BUG */
        !           266: #include "/sys/src/libc/9syscall/sys.h"
        !           267: 
        !           268: void
        !           269: netwstat(Chan *c, char *db, Network *np)
        !           270: {
        !           271:        Dir dir;
        !           272:        Netprot *p;
        !           273: 
        !           274:        p = findprot(np, STREAMID(c->qid.path));
        !           275:        if(p == 0)
        !           276:                error(Enonexist);
        !           277:        lock(np);
        !           278: 
        !           279:        /*
        !           280:         *  A network channel's ownership/permissions can be changed only if the
        !           281:         *  wstat is by the owner or (HACK!) if it is performed using an fwstat.
        !           282:         *  The latter allows processes started by a network listener to gain
        !           283:         *  ownership of the connection.  The open file descriptor is used as
        !           284:         *  a capability for the connection.
        !           285:         */
        !           286:        if(strncmp(p->owner, u->p->user, NAMELEN) != 0 && u->scallnr != FWSTAT){
        !           287:                unlock(np);
        !           288:                error(Eperm);
        !           289:        }
        !           290:        convM2D(db, &dir);
        !           291:        strncpy(p->owner, dir.uid, NAMELEN);
        !           292:        p->mode = dir.mode;
        !           293: 
        !           294:        unlock(np);
        !           295: }

unix.superglobalmegacorp.com

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