13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * exportfs - Export a plan 9 name space across a network 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include <u.h> 53e12c5d1SDavid du Colombier #include <libc.h> 63e12c5d1SDavid du Colombier #include <auth.h> 7*219b2ee8SDavid du Colombier #include <fcall.h> 83e12c5d1SDavid du Colombier #define Extern 93e12c5d1SDavid du Colombier #include "exportfs.h" 103e12c5d1SDavid du Colombier 113e12c5d1SDavid du Colombier void (*fcalls[])(Fsrpc*) = 123e12c5d1SDavid du Colombier { 133e12c5d1SDavid du Colombier [Tnop] Xnop, 143e12c5d1SDavid du Colombier [Tsession] Xsession, 153e12c5d1SDavid du Colombier [Tflush] Xflush, 163e12c5d1SDavid du Colombier [Tattach] Xattach, 173e12c5d1SDavid du Colombier [Tclone] Xclone, 183e12c5d1SDavid du Colombier [Twalk] Xwalk, 193e12c5d1SDavid du Colombier [Topen] slave, 203e12c5d1SDavid du Colombier [Tcreate] Xcreate, 213e12c5d1SDavid du Colombier [Tclunk] Xclunk, 223e12c5d1SDavid du Colombier [Tread] slave, 233e12c5d1SDavid du Colombier [Twrite] slave, 243e12c5d1SDavid du Colombier [Tremove] Xremove, 253e12c5d1SDavid du Colombier [Tstat] Xstat, 263e12c5d1SDavid du Colombier [Twstat] Xwstat, 273e12c5d1SDavid du Colombier [Tclwalk] Xclwalk, 283e12c5d1SDavid du Colombier }; 293e12c5d1SDavid du Colombier 30*219b2ee8SDavid du Colombier int nonone; 31*219b2ee8SDavid du Colombier 32*219b2ee8SDavid du Colombier void 33*219b2ee8SDavid du Colombier usage(void) 34*219b2ee8SDavid du Colombier { 35*219b2ee8SDavid du Colombier fprint(2, "usage: %s [-as] [-c ctlfile]\n", argv0); 36*219b2ee8SDavid du Colombier fatal("usage"); 37*219b2ee8SDavid du Colombier } 38*219b2ee8SDavid du Colombier 393e12c5d1SDavid du Colombier void 403e12c5d1SDavid du Colombier main(int argc, char **argv) 413e12c5d1SDavid du Colombier { 423e12c5d1SDavid du Colombier char buf[128]; 433e12c5d1SDavid du Colombier Fsrpc *r; 44bd389b36SDavid du Colombier int n, srv; 453e12c5d1SDavid du Colombier char *dbfile; 463e12c5d1SDavid du Colombier char *ctlfile; 47*219b2ee8SDavid du Colombier char user[NAMELEN]; 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier dbfile = "/tmp/exportdb"; 503e12c5d1SDavid du Colombier ctlfile = 0; 51bd389b36SDavid du Colombier srv = 0; 523e12c5d1SDavid du Colombier 533e12c5d1SDavid du Colombier ARGBEGIN{ 543e12c5d1SDavid du Colombier case 'a': 55*219b2ee8SDavid du Colombier if(srvauth(0, user) < 0) 56*219b2ee8SDavid du Colombier fatal("srvauth"); 57*219b2ee8SDavid du Colombier if(newns(user, 0) < 0) 58*219b2ee8SDavid du Colombier fatal("newns"); 593e12c5d1SDavid du Colombier putenv("service", "exportfs"); 603e12c5d1SDavid du Colombier break; 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier case 'c': 633e12c5d1SDavid du Colombier ctlfile = ARGF(); 643e12c5d1SDavid du Colombier break; 653e12c5d1SDavid du Colombier 663e12c5d1SDavid du Colombier case 'd': 673e12c5d1SDavid du Colombier dbg++; 683e12c5d1SDavid du Colombier break; 693e12c5d1SDavid du Colombier 703e12c5d1SDavid du Colombier case 'f': 713e12c5d1SDavid du Colombier dbfile = ARGF(); 723e12c5d1SDavid du Colombier break; 733e12c5d1SDavid du Colombier 74bd389b36SDavid du Colombier case 's': 75bd389b36SDavid du Colombier srv++; 76bd389b36SDavid du Colombier break; 77*219b2ee8SDavid du Colombier 78*219b2ee8SDavid du Colombier default: 79*219b2ee8SDavid du Colombier usage(); 803e12c5d1SDavid du Colombier }ARGEND 813e12c5d1SDavid du Colombier USED(argc, argv); 823e12c5d1SDavid du Colombier 833e12c5d1SDavid du Colombier if(dbg) { 843e12c5d1SDavid du Colombier n = create(dbfile, OWRITE|OTRUNC, 0666); 853e12c5d1SDavid du Colombier dup(n, 2); 863e12c5d1SDavid du Colombier close(n); 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier 89*219b2ee8SDavid du Colombier DEBUG(2, "exportfs: started\n"); 90*219b2ee8SDavid du Colombier 913e12c5d1SDavid du Colombier rfork(RFNOTEG); 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier Workq = malloc(sizeof(Fsrpc)*Nr_workbufs); 943e12c5d1SDavid du Colombier fhash = malloc(sizeof(Fid*)*FHASHSIZE); 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier if(Workq == 0 || fhash == 0) 973e12c5d1SDavid du Colombier fatal("no initial memory"); 983e12c5d1SDavid du Colombier 993e12c5d1SDavid du Colombier memset(Workq, 0, sizeof(Fsrpc)*Nr_workbufs); 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier fmtinstall('F', fcallconv); 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier /* 104*219b2ee8SDavid du Colombier * Get tree to serve from network connection, 105*219b2ee8SDavid du Colombier * check we can get there and ack the connection 1063e12c5d1SDavid du Colombier */ 107*219b2ee8SDavid du Colombier if(srv) { 108bd389b36SDavid du Colombier chdir("/"); 109*219b2ee8SDavid du Colombier DEBUG(2, "invoked as server for /"); 110*219b2ee8SDavid du Colombier } 111bd389b36SDavid du Colombier else { 112bd389b36SDavid du Colombier buf[0] = 0; 1133e12c5d1SDavid du Colombier n = read(0, buf, sizeof(buf)); 114bd389b36SDavid du Colombier if(n < 0) { 1153e12c5d1SDavid du Colombier errstr(buf); 116bd389b36SDavid du Colombier fprint(0, "read(0): %s", buf); 117*219b2ee8SDavid du Colombier DEBUG(2, "read(0): %s", buf); 1183e12c5d1SDavid du Colombier exits(buf); 1193e12c5d1SDavid du Colombier } 120*219b2ee8SDavid du Colombier buf[n] = 0; 121bd389b36SDavid du Colombier if(chdir(buf) < 0) { 122bd389b36SDavid du Colombier char ebuf[128]; 123bd389b36SDavid du Colombier errstr(ebuf); 124bd389b36SDavid du Colombier fprint(0, "chdir(%d:\"%s\"): %s", n, buf, ebuf); 125*219b2ee8SDavid du Colombier DEBUG(2, "chdir(%d:\"%s\"): %s", n, buf, ebuf); 126bd389b36SDavid du Colombier exits(ebuf); 127bd389b36SDavid du Colombier } 128bd389b36SDavid du Colombier } 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier /* 1313e12c5d1SDavid du Colombier * take ownership of the network connection and 1323e12c5d1SDavid du Colombier * push the fcall line discipline 1333e12c5d1SDavid du Colombier */ 1343e12c5d1SDavid du Colombier if(ctlfile) 1353e12c5d1SDavid du Colombier pushfcall(ctlfile); 1363e12c5d1SDavid du Colombier 137*219b2ee8SDavid du Colombier DEBUG(2, "initing root\n"); 1383e12c5d1SDavid du Colombier initroot(); 1393e12c5d1SDavid du Colombier 1403e12c5d1SDavid du Colombier DEBUG(2, "exportfs: %s\n", buf); 1413e12c5d1SDavid du Colombier 142bd389b36SDavid du Colombier if(srv == 0 && write(0, "OK", 2) != 2) 1433e12c5d1SDavid du Colombier fatal("open ack write"); 1443e12c5d1SDavid du Colombier 1453e12c5d1SDavid du Colombier /* 1463e12c5d1SDavid du Colombier * Start serving file requests from the network 1473e12c5d1SDavid du Colombier */ 1483e12c5d1SDavid du Colombier for(;;) { 1493e12c5d1SDavid du Colombier r = getsbuf(); 1503e12c5d1SDavid du Colombier if(r == 0) 1513e12c5d1SDavid du Colombier fatal("Out of service buffers"); 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier do 154*219b2ee8SDavid du Colombier n = read9p(0, r->buf, sizeof(r->buf)); 1553e12c5d1SDavid du Colombier while(n == 0); 1563e12c5d1SDavid du Colombier 1573e12c5d1SDavid du Colombier if(n < 0) 1583e12c5d1SDavid du Colombier fatal("server read"); 1593e12c5d1SDavid du Colombier 1603e12c5d1SDavid du Colombier 1613e12c5d1SDavid du Colombier if(convM2S(r->buf, &r->work, n) == 0) 1623e12c5d1SDavid du Colombier fatal("format error"); 1633e12c5d1SDavid du Colombier 1643e12c5d1SDavid du Colombier DEBUG(2, "%F\n", &r->work, &r->work); 1653e12c5d1SDavid du Colombier (fcalls[r->work.type])(r); 1663e12c5d1SDavid du Colombier } 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier 1693e12c5d1SDavid du Colombier void 1703e12c5d1SDavid du Colombier reply(Fcall *r, Fcall *t, char *err) 1713e12c5d1SDavid du Colombier { 1723e12c5d1SDavid du Colombier char data[MAXFDATA+MAXMSG]; 1733e12c5d1SDavid du Colombier int n; 1743e12c5d1SDavid du Colombier 1753e12c5d1SDavid du Colombier t->tag = r->tag; 1763e12c5d1SDavid du Colombier t->fid = r->fid; 1773e12c5d1SDavid du Colombier if(err) { 1783e12c5d1SDavid du Colombier t->type = Rerror; 1793e12c5d1SDavid du Colombier strncpy(t->ename, err, ERRLEN); 1803e12c5d1SDavid du Colombier } 1813e12c5d1SDavid du Colombier else 1823e12c5d1SDavid du Colombier t->type = r->type + 1; 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier DEBUG(2, "\t%F\n", t); 1853e12c5d1SDavid du Colombier 1863e12c5d1SDavid du Colombier n = convS2M(t, data); 187*219b2ee8SDavid du Colombier if(write9p(0, data, n)!=n) 1883e12c5d1SDavid du Colombier fatal("mount write"); 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier Fid * 1923e12c5d1SDavid du Colombier getfid(int nr) 1933e12c5d1SDavid du Colombier { 1943e12c5d1SDavid du Colombier Fid *f; 1953e12c5d1SDavid du Colombier 1963e12c5d1SDavid du Colombier for(f = fidhash(nr); f; f = f->next) 1973e12c5d1SDavid du Colombier if(f->nr == nr) 1983e12c5d1SDavid du Colombier return f; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier return 0; 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier 2033e12c5d1SDavid du Colombier int 2043e12c5d1SDavid du Colombier freefid(int nr) 2053e12c5d1SDavid du Colombier { 2063e12c5d1SDavid du Colombier Fid *f, **l; 207*219b2ee8SDavid du Colombier char buf[128]; 2083e12c5d1SDavid du Colombier 2093e12c5d1SDavid du Colombier l = &fidhash(nr); 2103e12c5d1SDavid du Colombier for(f = *l; f; f = f->next) { 2113e12c5d1SDavid du Colombier if(f->nr == nr) { 212*219b2ee8SDavid du Colombier if(f->mpend) 213*219b2ee8SDavid du Colombier f->mpend->busy = 0; 214*219b2ee8SDavid du Colombier if(f->mid) { 215*219b2ee8SDavid du Colombier sprint(buf, "/mnt/exportfs/%d", f->mid); 216*219b2ee8SDavid du Colombier unmount(0, buf); 217*219b2ee8SDavid du Colombier psmap[f->mid] = 0; 218*219b2ee8SDavid du Colombier } 2193e12c5d1SDavid du Colombier *l = f->next; 2203e12c5d1SDavid du Colombier f->next = fidfree; 2213e12c5d1SDavid du Colombier fidfree = f; 2223e12c5d1SDavid du Colombier return 1; 2233e12c5d1SDavid du Colombier } 2243e12c5d1SDavid du Colombier l = &f->next; 2253e12c5d1SDavid du Colombier } 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier return 0; 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier 2303e12c5d1SDavid du Colombier Fid * 2313e12c5d1SDavid du Colombier newfid(int nr) 2323e12c5d1SDavid du Colombier { 2333e12c5d1SDavid du Colombier Fid *new, **l; 2343e12c5d1SDavid du Colombier int i; 2353e12c5d1SDavid du Colombier 2363e12c5d1SDavid du Colombier l = &fidhash(nr); 2373e12c5d1SDavid du Colombier for(new = *l; new; new = new->next) 2383e12c5d1SDavid du Colombier if(new->nr == nr) 2393e12c5d1SDavid du Colombier return 0; 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier if(fidfree == 0) { 2423e12c5d1SDavid du Colombier fidfree = malloc(sizeof(Fid) * Fidchunk); 2433e12c5d1SDavid du Colombier if(fidfree == 0) 2443e12c5d1SDavid du Colombier fatal("out of memory"); 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier for(i = 0; i < Fidchunk-1; i++) 2473e12c5d1SDavid du Colombier fidfree[i].next = &fidfree[i+1]; 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier fidfree[Fidchunk-1].next = 0; 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier new = fidfree; 2533e12c5d1SDavid du Colombier fidfree = new->next; 2543e12c5d1SDavid du Colombier 2553e12c5d1SDavid du Colombier memset(new, 0, sizeof(Fid)); 2563e12c5d1SDavid du Colombier new->next = *l; 2573e12c5d1SDavid du Colombier *l = new; 2583e12c5d1SDavid du Colombier new->nr = nr; 2593e12c5d1SDavid du Colombier new->fid = -1; 260*219b2ee8SDavid du Colombier new->mpend = 0; 261*219b2ee8SDavid du Colombier new->mid = 0; 2623e12c5d1SDavid du Colombier 2633e12c5d1SDavid du Colombier return new; 2643e12c5d1SDavid du Colombier } 2653e12c5d1SDavid du Colombier 2663e12c5d1SDavid du Colombier Fsrpc * 2673e12c5d1SDavid du Colombier getsbuf(void) 2683e12c5d1SDavid du Colombier { 2693e12c5d1SDavid du Colombier static int ap; 2703e12c5d1SDavid du Colombier int look; 2713e12c5d1SDavid du Colombier Fsrpc *wb; 2723e12c5d1SDavid du Colombier 2733e12c5d1SDavid du Colombier for(look = 0; look < Nr_workbufs; look++) { 2743e12c5d1SDavid du Colombier if(++ap == Nr_workbufs) 2753e12c5d1SDavid du Colombier ap = 0; 2763e12c5d1SDavid du Colombier if(Workq[ap].busy == 0) 2773e12c5d1SDavid du Colombier break; 2783e12c5d1SDavid du Colombier } 2793e12c5d1SDavid du Colombier 2803e12c5d1SDavid du Colombier if(look == Nr_workbufs) 2813e12c5d1SDavid du Colombier fatal("No more work buffers"); 2823e12c5d1SDavid du Colombier 2833e12c5d1SDavid du Colombier wb = &Workq[ap]; 2843e12c5d1SDavid du Colombier wb->pid = 0; 2853e12c5d1SDavid du Colombier wb->canint = 0; 2863e12c5d1SDavid du Colombier wb->flushtag = NOTAG; 2873e12c5d1SDavid du Colombier wb->busy = 1; 2883e12c5d1SDavid du Colombier 2893e12c5d1SDavid du Colombier return wb; 2903e12c5d1SDavid du Colombier } 2913e12c5d1SDavid du Colombier 2923e12c5d1SDavid du Colombier char * 2933e12c5d1SDavid du Colombier strcatalloc(char *p, char *n) 2943e12c5d1SDavid du Colombier { 2953e12c5d1SDavid du Colombier char *v; 2963e12c5d1SDavid du Colombier 2973e12c5d1SDavid du Colombier v = realloc(p, strlen(p)+strlen(n)+1); 2983e12c5d1SDavid du Colombier if(v == 0) 2993e12c5d1SDavid du Colombier fatal("no memory"); 3003e12c5d1SDavid du Colombier strcat(v, n); 3013e12c5d1SDavid du Colombier return v; 3023e12c5d1SDavid du Colombier } 3033e12c5d1SDavid du Colombier 3043e12c5d1SDavid du Colombier File * 3053e12c5d1SDavid du Colombier file(File *parent, char *name) 3063e12c5d1SDavid du Colombier { 307*219b2ee8SDavid du Colombier Dir dir; 3083e12c5d1SDavid du Colombier char buf[128]; 3093e12c5d1SDavid du Colombier File *f, *new; 3103e12c5d1SDavid du Colombier 3113e12c5d1SDavid du Colombier DEBUG(2, "\tfile: 0x%x %s name %s\n", parent, parent->name, name); 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier for(f = parent->child; f; f = f->childlist) 3143e12c5d1SDavid du Colombier if(strcmp(name, f->name) == 0) 3153e12c5d1SDavid du Colombier return f; 3163e12c5d1SDavid du Colombier 3173e12c5d1SDavid du Colombier makepath(buf, parent, name); 3183e12c5d1SDavid du Colombier if(dirstat(buf, &dir) < 0) 3193e12c5d1SDavid du Colombier return 0; 3203e12c5d1SDavid du Colombier 3213e12c5d1SDavid du Colombier new = malloc(sizeof(File)); 3223e12c5d1SDavid du Colombier if(new == 0) 3233e12c5d1SDavid du Colombier fatal("no memory"); 3243e12c5d1SDavid du Colombier 3253e12c5d1SDavid du Colombier memset(new, 0, sizeof(File)); 3263e12c5d1SDavid du Colombier strcpy(new->name, name); 3273e12c5d1SDavid du Colombier new->qid.vers = dir.qid.vers; 3283e12c5d1SDavid du Colombier new->qid.path = (dir.qid.path&CHDIR)|++qid; 3293e12c5d1SDavid du Colombier 3303e12c5d1SDavid du Colombier new->parent = parent; 3313e12c5d1SDavid du Colombier new->childlist = parent->child; 3323e12c5d1SDavid du Colombier parent->child = new; 3333e12c5d1SDavid du Colombier 3343e12c5d1SDavid du Colombier return new; 3353e12c5d1SDavid du Colombier } 3363e12c5d1SDavid du Colombier 3373e12c5d1SDavid du Colombier void 3383e12c5d1SDavid du Colombier initroot(void) 3393e12c5d1SDavid du Colombier { 3403e12c5d1SDavid du Colombier Dir dir; 3413e12c5d1SDavid du Colombier 3423e12c5d1SDavid du Colombier root = malloc(sizeof(File)); 3433e12c5d1SDavid du Colombier if(root == 0) 3443e12c5d1SDavid du Colombier fatal("no memory"); 3453e12c5d1SDavid du Colombier 3463e12c5d1SDavid du Colombier memset(root, 0, sizeof(File)); 3473e12c5d1SDavid du Colombier strcpy(root->name, "."); 3483e12c5d1SDavid du Colombier if(dirstat(root->name, &dir) < 0) 3493e12c5d1SDavid du Colombier fatal("root stat"); 3503e12c5d1SDavid du Colombier 3513e12c5d1SDavid du Colombier root->qid.vers = dir.qid.vers; 3523e12c5d1SDavid du Colombier root->qid.path = (dir.qid.path&CHDIR)|++qid; 353*219b2ee8SDavid du Colombier 354*219b2ee8SDavid du Colombier psmpt = malloc(sizeof(File)); 355*219b2ee8SDavid du Colombier if(psmpt == 0) 356*219b2ee8SDavid du Colombier fatal("no memory"); 357*219b2ee8SDavid du Colombier 358*219b2ee8SDavid du Colombier memset(psmpt, 0, sizeof(File)); 359*219b2ee8SDavid du Colombier strcpy(psmpt->name, "/"); 360*219b2ee8SDavid du Colombier if(dirstat(psmpt->name, &dir) < 0) 361*219b2ee8SDavid du Colombier return; 362*219b2ee8SDavid du Colombier 363*219b2ee8SDavid du Colombier psmpt->qid.vers = dir.qid.vers; 364*219b2ee8SDavid du Colombier psmpt->qid.path = (dir.qid.path&CHDIR)|++qid; 365*219b2ee8SDavid du Colombier 366*219b2ee8SDavid du Colombier psmpt = file(psmpt, "mnt"); 367*219b2ee8SDavid du Colombier if(psmpt == 0) 368*219b2ee8SDavid du Colombier return; 369*219b2ee8SDavid du Colombier psmpt = file(psmpt, "exportfs"); 3703e12c5d1SDavid du Colombier } 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier void 3733e12c5d1SDavid du Colombier makepath(char *s, File *p, char *name) 3743e12c5d1SDavid du Colombier { 3753e12c5d1SDavid du Colombier int i; 376*219b2ee8SDavid du Colombier char *c, *seg[256]; 3773e12c5d1SDavid du Colombier 3783e12c5d1SDavid du Colombier seg[0] = name; 3793e12c5d1SDavid du Colombier for(i = 1; i < 100 && p; i++, p = p->parent) 3803e12c5d1SDavid du Colombier seg[i] = p->name; 3813e12c5d1SDavid du Colombier 3823e12c5d1SDavid du Colombier while(i--) { 3833e12c5d1SDavid du Colombier for(c = seg[i]; *c; c++) 3843e12c5d1SDavid du Colombier *s++ = *c; 3853e12c5d1SDavid du Colombier *s++ = '/'; 3863e12c5d1SDavid du Colombier } 3873e12c5d1SDavid du Colombier while(s[-1] == '/') 3883e12c5d1SDavid du Colombier s--; 3893e12c5d1SDavid du Colombier *s = '\0'; 3903e12c5d1SDavid du Colombier } 3913e12c5d1SDavid du Colombier 3923e12c5d1SDavid du Colombier void 3933e12c5d1SDavid du Colombier fatal(char *s) 3943e12c5d1SDavid du Colombier { 3953e12c5d1SDavid du Colombier char buf[128]; 3963e12c5d1SDavid du Colombier Proc *m; 3973e12c5d1SDavid du Colombier 3983e12c5d1SDavid du Colombier sprint(buf, "exportfs: %r: %s", s); 3993e12c5d1SDavid du Colombier 4003e12c5d1SDavid du Colombier /* Clear away the slave children */ 4013e12c5d1SDavid du Colombier for(m = Proclist; m; m = m->next) 402*219b2ee8SDavid du Colombier postnote(PNPROC, m->pid, "kill"); 4033e12c5d1SDavid du Colombier 404bd389b36SDavid du Colombier DEBUG(2, "%s\n", buf); 4053e12c5d1SDavid du Colombier exits(buf); 4063e12c5d1SDavid du Colombier } 4073e12c5d1SDavid du Colombier 408*219b2ee8SDavid du Colombier char pushmsg[] = "push fcall"; 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier void 4113e12c5d1SDavid du Colombier pushfcall(char *ctl) 4123e12c5d1SDavid du Colombier { 4133e12c5d1SDavid du Colombier int cfd; 4143e12c5d1SDavid du Colombier Dir dir; 4153e12c5d1SDavid du Colombier 4163e12c5d1SDavid du Colombier if(dirfstat(0, &dir) < 0){ 4173e12c5d1SDavid du Colombier fprint(2, "dirfstat(0) failed: %r\n"); 4183e12c5d1SDavid du Colombier return; 4193e12c5d1SDavid du Colombier } 4203e12c5d1SDavid du Colombier memmove(dir.uid, getuser(), NAMELEN); 4213e12c5d1SDavid du Colombier if(dirfwstat(1, &dir) < 0){ 4223e12c5d1SDavid du Colombier fprint(2, "dirfwstat(1) failed: %r\n"); 4233e12c5d1SDavid du Colombier return; 4243e12c5d1SDavid du Colombier } 4253e12c5d1SDavid du Colombier cfd = open(ctl, ORDWR); 4263e12c5d1SDavid du Colombier if(cfd < 0){ 4273e12c5d1SDavid du Colombier fprint(2, "open(%s0) failed: %r\n", ctl); 4283e12c5d1SDavid du Colombier return; 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier if(write(cfd, pushmsg, strlen(pushmsg)) < 0){ 4313e12c5d1SDavid du Colombier fprint(2, "%s failed: %r\n", pushmsg); 4323e12c5d1SDavid du Colombier return; 4333e12c5d1SDavid du Colombier } 4343e12c5d1SDavid du Colombier close(cfd); 4353e12c5d1SDavid du Colombier } 436