Annotation of lucent/sys/src/9/port/net.c, revision 1.1.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.