13e12c5d1SDavid du Colombier #include "u.h" 23e12c5d1SDavid du Colombier #include "../port/lib.h" 33e12c5d1SDavid du Colombier #include "mem.h" 43e12c5d1SDavid du Colombier #include "dat.h" 53e12c5d1SDavid du Colombier #include "fns.h" 63e12c5d1SDavid du Colombier #include "../port/error.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier #include "devtab.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier typedef struct Srv Srv; 113e12c5d1SDavid du Colombier struct Srv 123e12c5d1SDavid du Colombier { 133e12c5d1SDavid du Colombier char name[NAMELEN]; 143e12c5d1SDavid du Colombier char owner[NAMELEN]; 153e12c5d1SDavid du Colombier ulong perm; 163e12c5d1SDavid du Colombier Chan *chan; 173e12c5d1SDavid du Colombier Srv *link; 183e12c5d1SDavid du Colombier ulong path; 193e12c5d1SDavid du Colombier }; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier static QLock srvlk; 223e12c5d1SDavid du Colombier static Srv *srv; 233e12c5d1SDavid du Colombier static int path; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier int 263e12c5d1SDavid du Colombier srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier Srv *sp; 293e12c5d1SDavid du Colombier 303e12c5d1SDavid du Colombier USED(tab); 313e12c5d1SDavid du Colombier USED(ntab); 323e12c5d1SDavid du Colombier qlock(&srvlk); 333e12c5d1SDavid du Colombier for(sp = srv; sp && s; sp = sp->link) 343e12c5d1SDavid du Colombier s--; 353e12c5d1SDavid du Colombier 363e12c5d1SDavid du Colombier if(sp == 0) { 373e12c5d1SDavid du Colombier qunlock(&srvlk); 383e12c5d1SDavid du Colombier return -1; 393e12c5d1SDavid du Colombier } 403e12c5d1SDavid du Colombier devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp); 413e12c5d1SDavid du Colombier qunlock(&srvlk); 423e12c5d1SDavid du Colombier return 1; 433e12c5d1SDavid du Colombier } 443e12c5d1SDavid du Colombier 453e12c5d1SDavid du Colombier void 463e12c5d1SDavid du Colombier srvinit(void) 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier path = 1; 493e12c5d1SDavid du Colombier } 503e12c5d1SDavid du Colombier 513e12c5d1SDavid du Colombier void 523e12c5d1SDavid du Colombier srvreset(void) 533e12c5d1SDavid du Colombier { 543e12c5d1SDavid du Colombier } 553e12c5d1SDavid du Colombier 563e12c5d1SDavid du Colombier Chan* 573e12c5d1SDavid du Colombier srvattach(char *spec) 583e12c5d1SDavid du Colombier { 593e12c5d1SDavid du Colombier return devattach('s', spec); 603e12c5d1SDavid du Colombier } 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier Chan* 633e12c5d1SDavid du Colombier srvclone(Chan *c, Chan *nc) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier return devclone(c, nc); 663e12c5d1SDavid du Colombier } 673e12c5d1SDavid du Colombier 683e12c5d1SDavid du Colombier int 693e12c5d1SDavid du Colombier srvwalk(Chan *c, char *name) 703e12c5d1SDavid du Colombier { 713e12c5d1SDavid du Colombier return devwalk(c, name, 0, 0, srvgen); 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier 743e12c5d1SDavid du Colombier void 753e12c5d1SDavid du Colombier srvstat(Chan *c, char *db) 763e12c5d1SDavid du Colombier { 773e12c5d1SDavid du Colombier devstat(c, db, 0, 0, srvgen); 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier 803e12c5d1SDavid du Colombier Chan* 813e12c5d1SDavid du Colombier srvopen(Chan *c, int omode) 823e12c5d1SDavid du Colombier { 833e12c5d1SDavid du Colombier Srv *sp; 843e12c5d1SDavid du Colombier 853e12c5d1SDavid du Colombier if(c->qid.path == CHDIR){ 863e12c5d1SDavid du Colombier if(omode != OREAD) 873e12c5d1SDavid du Colombier error(Eisdir); 883e12c5d1SDavid du Colombier c->mode = omode; 893e12c5d1SDavid du Colombier c->flag |= COPEN; 903e12c5d1SDavid du Colombier c->offset = 0; 913e12c5d1SDavid du Colombier return c; 923e12c5d1SDavid du Colombier } 933e12c5d1SDavid du Colombier qlock(&srvlk); 943e12c5d1SDavid du Colombier if(waserror()){ 953e12c5d1SDavid du Colombier qunlock(&srvlk); 963e12c5d1SDavid du Colombier nexterror(); 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier 993e12c5d1SDavid du Colombier for(sp = srv; sp; sp = sp->link) 1003e12c5d1SDavid du Colombier if(sp->path == c->qid.path) 1013e12c5d1SDavid du Colombier break; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier if(sp == 0 || sp->chan == 0) 1043e12c5d1SDavid du Colombier error(Eshutdown); 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier if(omode&OTRUNC) 1073e12c5d1SDavid du Colombier error(Eperm); 1083e12c5d1SDavid du Colombier if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR) 1093e12c5d1SDavid du Colombier error(Eperm); 1103e12c5d1SDavid du Colombier 1113e12c5d1SDavid du Colombier close(c); 1123e12c5d1SDavid du Colombier incref(sp->chan); 1133e12c5d1SDavid du Colombier qunlock(&srvlk); 1143e12c5d1SDavid du Colombier poperror(); 1153e12c5d1SDavid du Colombier return sp->chan; 1163e12c5d1SDavid du Colombier } 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier void 1193e12c5d1SDavid du Colombier srvcreate(Chan *c, char *name, int omode, ulong perm) 1203e12c5d1SDavid du Colombier { 1213e12c5d1SDavid du Colombier Srv *sp; 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier if(omode != OWRITE) 1243e12c5d1SDavid du Colombier error(Eperm); 1253e12c5d1SDavid du Colombier 1263e12c5d1SDavid du Colombier sp = malloc(sizeof(Srv)); 1273e12c5d1SDavid du Colombier if(sp == 0) 1283e12c5d1SDavid du Colombier error(Enomem); 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier qlock(&srvlk); 1313e12c5d1SDavid du Colombier if(waserror()){ 1323e12c5d1SDavid du Colombier qunlock(&srvlk); 1333e12c5d1SDavid du Colombier nexterror(); 1343e12c5d1SDavid du Colombier } 1353e12c5d1SDavid du Colombier sp->path = path++; 1363e12c5d1SDavid du Colombier sp->link = srv; 1373e12c5d1SDavid du Colombier c->qid.path = sp->path; 1383e12c5d1SDavid du Colombier srv = sp; 1393e12c5d1SDavid du Colombier qunlock(&srvlk); 1403e12c5d1SDavid du Colombier poperror(); 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier strncpy(sp->name, name, NAMELEN); 1433e12c5d1SDavid du Colombier strncpy(sp->owner, u->p->user, NAMELEN); 1443e12c5d1SDavid du Colombier sp->perm = perm&0777; 1453e12c5d1SDavid du Colombier 1463e12c5d1SDavid du Colombier c->flag |= COPEN; 1473e12c5d1SDavid du Colombier c->mode = OWRITE; 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier void 1513e12c5d1SDavid du Colombier srvremove(Chan *c) 1523e12c5d1SDavid du Colombier { 1533e12c5d1SDavid du Colombier Srv *sp, **l; 1543e12c5d1SDavid du Colombier 1553e12c5d1SDavid du Colombier if(c->qid.path == CHDIR) 1563e12c5d1SDavid du Colombier error(Eperm); 1573e12c5d1SDavid du Colombier 1583e12c5d1SDavid du Colombier qlock(&srvlk); 1593e12c5d1SDavid du Colombier if(waserror()){ 1603e12c5d1SDavid du Colombier qunlock(&srvlk); 1613e12c5d1SDavid du Colombier nexterror(); 1623e12c5d1SDavid du Colombier } 1633e12c5d1SDavid du Colombier l = &srv; 1643e12c5d1SDavid du Colombier for(sp = *l; sp; sp = sp->link) { 1653e12c5d1SDavid du Colombier if(sp->path == c->qid.path) 1663e12c5d1SDavid du Colombier break; 1673e12c5d1SDavid du Colombier 168*219b2ee8SDavid du Colombier l = &sp->link; 1693e12c5d1SDavid du Colombier } 1703e12c5d1SDavid du Colombier if(sp == 0) 1713e12c5d1SDavid du Colombier error(Enonexist); 1723e12c5d1SDavid du Colombier 1733e12c5d1SDavid du Colombier if(strcmp(sp->name, "boot") == 0) 1743e12c5d1SDavid du Colombier error(Eperm); 1753e12c5d1SDavid du Colombier 1763e12c5d1SDavid du Colombier *l = sp->link; 1773e12c5d1SDavid du Colombier qunlock(&srvlk); 1783e12c5d1SDavid du Colombier poperror(); 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier if(sp->chan) 1813e12c5d1SDavid du Colombier close(sp->chan); 1823e12c5d1SDavid du Colombier free(sp); 1833e12c5d1SDavid du Colombier } 1843e12c5d1SDavid du Colombier 1853e12c5d1SDavid du Colombier void 1863e12c5d1SDavid du Colombier srvwstat(Chan *c, char *dp) 1873e12c5d1SDavid du Colombier { 1883e12c5d1SDavid du Colombier USED(c, dp); 1893e12c5d1SDavid du Colombier error(Egreg); 1903e12c5d1SDavid du Colombier } 1913e12c5d1SDavid du Colombier 1923e12c5d1SDavid du Colombier void 1933e12c5d1SDavid du Colombier srvclose(Chan *c) 1943e12c5d1SDavid du Colombier { 1953e12c5d1SDavid du Colombier USED(c); 1963e12c5d1SDavid du Colombier } 1973e12c5d1SDavid du Colombier 1983e12c5d1SDavid du Colombier long 1993e12c5d1SDavid du Colombier srvread(Chan *c, void *va, long n, ulong offset) 2003e12c5d1SDavid du Colombier { 2013e12c5d1SDavid du Colombier USED(offset); 2023e12c5d1SDavid du Colombier isdir(c); 2033e12c5d1SDavid du Colombier return devdirread(c, va, n, 0, 0, srvgen); 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier long 2073e12c5d1SDavid du Colombier srvwrite(Chan *c, void *va, long n, ulong offset) 2083e12c5d1SDavid du Colombier { 2093e12c5d1SDavid du Colombier Srv *sp; 2103e12c5d1SDavid du Colombier Chan *c1; 2113e12c5d1SDavid du Colombier int fd; 2123e12c5d1SDavid du Colombier char buf[32]; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier USED(offset); 2153e12c5d1SDavid du Colombier if(n >= sizeof buf) 2163e12c5d1SDavid du Colombier error(Egreg); 2173e12c5d1SDavid du Colombier memmove(buf, va, n); /* so we can NUL-terminate */ 2183e12c5d1SDavid du Colombier buf[n] = 0; 2193e12c5d1SDavid du Colombier fd = strtoul(buf, 0, 0); 2203e12c5d1SDavid du Colombier 2213e12c5d1SDavid du Colombier c1 = fdtochan(fd, -1, 0, 1); /* error check only */ 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier qlock(&srvlk); 2243e12c5d1SDavid du Colombier if(waserror()) { 2253e12c5d1SDavid du Colombier qunlock(&srvlk); 2263e12c5d1SDavid du Colombier close(c1); 2273e12c5d1SDavid du Colombier nexterror(); 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier for(sp = srv; sp; sp = sp->link) 2303e12c5d1SDavid du Colombier if(sp->path == c->qid.path) 2313e12c5d1SDavid du Colombier break; 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier if(sp == 0) 2343e12c5d1SDavid du Colombier error(Enonexist); 2353e12c5d1SDavid du Colombier 2363e12c5d1SDavid du Colombier if(sp->chan) 2373e12c5d1SDavid du Colombier panic("srvwrite"); 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier sp->chan = c1; 2403e12c5d1SDavid du Colombier qunlock(&srvlk); 2413e12c5d1SDavid du Colombier poperror(); 2423e12c5d1SDavid du Colombier return n; 2433e12c5d1SDavid du Colombier } 244