|
|
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: #define DEVTAB ! 8: #include "devtab.h" ! 9: ! 10: extern ulong kerndate; ! 11: ! 12: int ! 13: devno(int c, int user) ! 14: { ! 15: Rune *s; ! 16: int i; ! 17: ! 18: s = devchar; ! 19: i = 0; ! 20: while(*s){ ! 21: if(c == *s) ! 22: return i; ! 23: i++; ! 24: s++; ! 25: } ! 26: ! 27: if(user) ! 28: return -1; ! 29: panic("devno %C 0x%ux", c, c); ! 30: return 0; ! 31: } ! 32: ! 33: void ! 34: devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db) ! 35: { ! 36: strcpy(db->name, n); ! 37: db->qid = qid; ! 38: db->type = devchar[c->type]; ! 39: db->dev = c->dev; ! 40: if(qid.path & CHDIR) ! 41: db->mode = CHDIR|perm; ! 42: else ! 43: db->mode = perm; ! 44: if(c->flag&CMSG) ! 45: db->mode |= CHMOUNT; ! 46: db->atime = seconds(); ! 47: db->mtime = kerndate; ! 48: db->hlength = 0; ! 49: db->length = length; ! 50: memmove(db->uid, user, NAMELEN); ! 51: memmove(db->gid, eve, NAMELEN); ! 52: } ! 53: ! 54: int ! 55: devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) ! 56: { ! 57: if(tab==0 || i>=ntab) ! 58: return -1; ! 59: tab += i; ! 60: devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); ! 61: return 1; ! 62: } ! 63: ! 64: Chan * ! 65: devattach(int tc, char *spec) ! 66: { ! 67: Chan *c; ! 68: ! 69: USED(spec); ! 70: c = newchan(); ! 71: c->qid = (Qid){CHDIR, 0}; ! 72: c->type = devno(tc, 0); ! 73: return c; ! 74: } ! 75: ! 76: Chan * ! 77: devclone(Chan *c, Chan *nc) ! 78: { ! 79: if(c->flag & COPEN) ! 80: panic("clone of open file type %C\n", devchar[c->type]); ! 81: if(nc == 0) ! 82: nc = newchan(); ! 83: nc->type = c->type; ! 84: nc->dev = c->dev; ! 85: nc->mode = c->mode; ! 86: nc->qid = c->qid; ! 87: nc->offset = c->offset; ! 88: nc->flag = c->flag; ! 89: nc->mnt = c->mnt; ! 90: nc->mountid = c->mountid; ! 91: nc->aux = c->aux; ! 92: nc->mchan = c->mchan; ! 93: nc->mqid = c->mqid; ! 94: return nc; ! 95: } ! 96: ! 97: int ! 98: devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) ! 99: { ! 100: long i; ! 101: Dir dir; ! 102: ! 103: isdir(c); ! 104: if(name[0]=='.' && name[1]==0) ! 105: return 1; ! 106: for(i=0;; i++) ! 107: switch((*gen)(c, tab, ntab, i, &dir)){ ! 108: case -1: ! 109: strncpy(u->error, Enonexist, NAMELEN); ! 110: return 0; ! 111: case 0: ! 112: continue; ! 113: case 1: ! 114: if(strcmp(name, dir.name) == 0){ ! 115: c->qid = dir.qid; ! 116: return 1; ! 117: } ! 118: continue; ! 119: } ! 120: return 1; /* not reached */ ! 121: } ! 122: ! 123: void ! 124: devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) ! 125: { ! 126: int i; ! 127: Dir dir; ! 128: ! 129: for(i=0;; i++) ! 130: switch((*gen)(c, tab, ntab, i, &dir)){ ! 131: case -1: ! 132: /* ! 133: * given a channel, we cannot derive the directory name ! 134: * that the channel was generated from since it was lost ! 135: * by namec. ! 136: */ ! 137: if(c->qid.path & CHDIR){ ! 138: devdir(c, c->qid, ".", 0L, eve, CHDIR|0775, &dir); ! 139: convD2M(&dir, db); ! 140: return; ! 141: } ! 142: print("%s %s: devstat %C %lux\n", u->p->text, u->p->user, ! 143: devchar[c->type], c->qid.path); ! 144: error(Enonexist); ! 145: case 0: ! 146: break; ! 147: case 1: ! 148: if(eqqid(c->qid, dir.qid)){ ! 149: if(c->flag&CMSG) ! 150: dir.mode |= CHMOUNT; ! 151: convD2M(&dir, db); ! 152: return; ! 153: } ! 154: break; ! 155: } ! 156: } ! 157: ! 158: long ! 159: devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) ! 160: { ! 161: long k, m; ! 162: Dir dir; ! 163: ! 164: k = c->offset/DIRLEN; ! 165: for(m=0; m<n; k++) ! 166: switch((*gen)(c, tab, ntab, k, &dir)){ ! 167: case -1: ! 168: return m; ! 169: ! 170: case 0: ! 171: c->offset += DIRLEN; ! 172: break; ! 173: ! 174: case 1: ! 175: convD2M(&dir, d); ! 176: m += DIRLEN; ! 177: d += DIRLEN; ! 178: break; ! 179: } ! 180: return m; ! 181: } ! 182: ! 183: Chan * ! 184: devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) ! 185: { ! 186: int i; ! 187: Dir dir; ! 188: ulong t, mode; ! 189: static int access[] = { 0400, 0200, 0600, 0100 }; ! 190: ! 191: for(i=0;; i++) ! 192: switch((*gen)(c, tab, ntab, i, &dir)){ ! 193: case -1: ! 194: goto Return; ! 195: case 0: ! 196: break; ! 197: case 1: ! 198: if(eqqid(c->qid, dir.qid)) { ! 199: if(strcmp(u->p->user, dir.uid) == 0) /* User */ ! 200: mode = dir.mode; ! 201: else if(strcmp(u->p->user, eve) == 0) /* eve is group */ ! 202: mode = dir.mode<<3; ! 203: else ! 204: mode = dir.mode<<6; /* Other */ ! 205: ! 206: t = access[omode&3]; ! 207: if((t & mode) == t) ! 208: goto Return; ! 209: error(Eperm); ! 210: } ! 211: break; ! 212: } ! 213: Return: ! 214: c->offset = 0; ! 215: if((c->qid.path&CHDIR) && omode!=OREAD) ! 216: error(Eperm); ! 217: c->mode = openmode(omode); ! 218: c->flag |= COPEN; ! 219: return c; ! 220: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.