|
|
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: #include "devtab.h" ! 9: ! 10: typedef struct Srv Srv; ! 11: struct Srv ! 12: { ! 13: char name[NAMELEN]; ! 14: char owner[NAMELEN]; ! 15: ulong perm; ! 16: Chan *chan; ! 17: Srv *link; ! 18: ulong path; ! 19: }; ! 20: ! 21: static QLock srvlk; ! 22: static Srv *srv; ! 23: static int path; ! 24: ! 25: int ! 26: srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) ! 27: { ! 28: Srv *sp; ! 29: ! 30: USED(tab); ! 31: USED(ntab); ! 32: qlock(&srvlk); ! 33: for(sp = srv; sp && s; sp = sp->link) ! 34: s--; ! 35: ! 36: if(sp == 0) { ! 37: qunlock(&srvlk); ! 38: return -1; ! 39: } ! 40: devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp); ! 41: qunlock(&srvlk); ! 42: return 1; ! 43: } ! 44: ! 45: void ! 46: srvinit(void) ! 47: { ! 48: path = 1; ! 49: } ! 50: ! 51: void ! 52: srvreset(void) ! 53: { ! 54: } ! 55: ! 56: Chan* ! 57: srvattach(char *spec) ! 58: { ! 59: return devattach('s', spec); ! 60: } ! 61: ! 62: Chan* ! 63: srvclone(Chan *c, Chan *nc) ! 64: { ! 65: return devclone(c, nc); ! 66: } ! 67: ! 68: int ! 69: srvwalk(Chan *c, char *name) ! 70: { ! 71: return devwalk(c, name, 0, 0, srvgen); ! 72: } ! 73: ! 74: void ! 75: srvstat(Chan *c, char *db) ! 76: { ! 77: devstat(c, db, 0, 0, srvgen); ! 78: } ! 79: ! 80: Chan* ! 81: srvopen(Chan *c, int omode) ! 82: { ! 83: Srv *sp; ! 84: ! 85: if(c->qid.path == CHDIR){ ! 86: if(omode != OREAD) ! 87: error(Eisdir); ! 88: c->mode = omode; ! 89: c->flag |= COPEN; ! 90: c->offset = 0; ! 91: return c; ! 92: } ! 93: qlock(&srvlk); ! 94: if(waserror()){ ! 95: qunlock(&srvlk); ! 96: nexterror(); ! 97: } ! 98: ! 99: for(sp = srv; sp; sp = sp->link) ! 100: if(sp->path == c->qid.path) ! 101: break; ! 102: ! 103: if(sp == 0 || sp->chan == 0) ! 104: error(Eshutdown); ! 105: ! 106: if(omode&OTRUNC) ! 107: error(Eperm); ! 108: if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR) ! 109: error(Eperm); ! 110: ! 111: close(c); ! 112: incref(sp->chan); ! 113: qunlock(&srvlk); ! 114: poperror(); ! 115: return sp->chan; ! 116: } ! 117: ! 118: void ! 119: srvcreate(Chan *c, char *name, int omode, ulong perm) ! 120: { ! 121: Srv *sp; ! 122: ! 123: if(omode != OWRITE) ! 124: error(Eperm); ! 125: ! 126: sp = malloc(sizeof(Srv)); ! 127: if(sp == 0) ! 128: error(Enomem); ! 129: ! 130: qlock(&srvlk); ! 131: if(waserror()){ ! 132: qunlock(&srvlk); ! 133: nexterror(); ! 134: } ! 135: sp->path = path++; ! 136: sp->link = srv; ! 137: c->qid.path = sp->path; ! 138: srv = sp; ! 139: qunlock(&srvlk); ! 140: poperror(); ! 141: ! 142: strncpy(sp->name, name, NAMELEN); ! 143: strncpy(sp->owner, u->p->user, NAMELEN); ! 144: sp->perm = perm&0777; ! 145: ! 146: c->flag |= COPEN; ! 147: c->mode = OWRITE; ! 148: } ! 149: ! 150: void ! 151: srvremove(Chan *c) ! 152: { ! 153: Srv *sp, **l; ! 154: ! 155: if(c->qid.path == CHDIR) ! 156: error(Eperm); ! 157: ! 158: qlock(&srvlk); ! 159: if(waserror()){ ! 160: qunlock(&srvlk); ! 161: nexterror(); ! 162: } ! 163: l = &srv; ! 164: for(sp = *l; sp; sp = sp->link) { ! 165: if(sp->path == c->qid.path) ! 166: break; ! 167: ! 168: l = &sp->link; ! 169: } ! 170: if(sp == 0) ! 171: error(Enonexist); ! 172: ! 173: if(strcmp(sp->name, "boot") == 0) ! 174: error(Eperm); ! 175: ! 176: *l = sp->link; ! 177: qunlock(&srvlk); ! 178: poperror(); ! 179: ! 180: if(sp->chan) ! 181: close(sp->chan); ! 182: free(sp); ! 183: } ! 184: ! 185: void ! 186: srvwstat(Chan *c, char *dp) ! 187: { ! 188: USED(c, dp); ! 189: error(Egreg); ! 190: } ! 191: ! 192: void ! 193: srvclose(Chan *c) ! 194: { ! 195: USED(c); ! 196: } ! 197: ! 198: long ! 199: srvread(Chan *c, void *va, long n, ulong offset) ! 200: { ! 201: USED(offset); ! 202: isdir(c); ! 203: return devdirread(c, va, n, 0, 0, srvgen); ! 204: } ! 205: ! 206: long ! 207: srvwrite(Chan *c, void *va, long n, ulong offset) ! 208: { ! 209: Srv *sp; ! 210: Chan *c1; ! 211: int fd; ! 212: char buf[32]; ! 213: ! 214: USED(offset); ! 215: if(n >= sizeof buf) ! 216: error(Egreg); ! 217: memmove(buf, va, n); /* so we can NUL-terminate */ ! 218: buf[n] = 0; ! 219: fd = strtoul(buf, 0, 0); ! 220: ! 221: c1 = fdtochan(fd, -1, 0, 1); /* error check only */ ! 222: ! 223: qlock(&srvlk); ! 224: if(waserror()) { ! 225: qunlock(&srvlk); ! 226: close(c1); ! 227: nexterror(); ! 228: } ! 229: for(sp = srv; sp; sp = sp->link) ! 230: if(sp->path == c->qid.path) ! 231: break; ! 232: ! 233: if(sp == 0) ! 234: error(Enonexist); ! 235: ! 236: if(sp->chan) ! 237: panic("srvwrite"); ! 238: ! 239: sp->chan = c1; ! 240: qunlock(&srvlk); ! 241: poperror(); ! 242: return n; ! 243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.