#include #include #include #include #include <9p.h> #include typedef struct LemmyFile LemmyFile; struct LemmyFile { char *name; char * (*fsread)(Req*); int mode; }; void fsopen(Req *r); void fswrite(Req *r); void fsread(Req *r); void fsend(Srv *s); char* getcommunityfunc(Req*); char* gettimefunc(Req*); LemmyFile files[] = { {"getcommunity", getcommunityfunc, 0444}, {"gettime", gettimefunc, 0444}, }; Srv s = { .open = fsopen, .read = fsread, .write = fswrite, .end = fsend, }; File *root; File *lemmydir; char *endpoint; char* webfs(char *cmd, char *post) { int conn, ctlfd, fd, hd, n; char buf[256], *mtpt; mtpt = "/mnt/web"; snprint(buf, sizeof buf, "%s/clone", mtpt); if((ctlfd = open(buf, ORDWR)) < 0) { sysfatal("couldn't open %s: %r", buf); } if((n = read(ctlfd, buf, sizeof buf)) < 0) { sysfatal("reading i32: %r"); } if(n == 0) { sysfatal("short read on i32"); } buf[n] = '\0'; conn = atoi(buf); if(fprint(ctlfd, "url %s%s", endpoint, cmd) <= 0) { sysfatal("get ctl write: %r"); } if(post) { snprint(buf, sizeof buf, "%s/%d/postbody", mtpt, conn); if((fd = open(buf, OWRITE)) < 0) { sysfatal("open %s: %r", buf); } if(write(fd, post, strlen(post)) < 0) { sysfatal("post write failed: %r"); } close(fd); } snprint(buf, sizeof buf, "%s/%d/body", mtpt, conn); if((fd = open(buf, OREAD)) < 0) { sysfatal("open %s: %r", buf); } snprint(buf, sizeof buf, "%s/%d/contentlength", mtpt, conn); if ((hd = open(buf, OREAD)) < 0) { sysfatal("open header %s %r", buf); } if((n = read(hd, buf, sizeof buf)) < 0) { sysfatal("reading i32: %r"); } if(n == 0) { sysfatal("short read on i32"); } buf[n] = '\0'; int s = atoi(buf); close(hd); char* json_string = (char*)calloc(s, sizeof(char)); readn(fd, json_string, s*sizeof(char)); return json_string; /* JSON* j = jsonparse(json_string); if (j == nil) { sysfatal("error jsonparse %s: %r", json_string); } else { print("%J\n", j); jsonfree(j); } */ } void fsend(Srv *) { postnote(PNGROUP, getpid(), "shutdown"); threadexitsall(nil); } void fsopen(Req *r) { respond(r, nil); } void fsread(Req *r) { LemmyFile *f; r->ofcall.count = 0; f = r->fid->file->aux; respond(r, f->fsread(r)); } void fswrite(Req *r) { /* not implemented yet */ respond(r, nil); } void fsinit(void) { char *user; int i; user = getuser(); s.tree = alloctree(user, user, 0555, nil); if (s.tree == nil) { sysfatal("alloctree failed"); } root = s.tree->root; if ((lemmydir = createfile(root, "lemmy", user, DMDIR|0555, nil)) == nil) { sysfatal("lemmy root file failed"); } for (i = 0; i < nelem(files); i++) { if (createfile(lemmydir, files[i].name, user, files[i].mode, files + i) == nil) { sysfatal("%s file failed", files[i].name); } else { print("created %s\n", files[i].name); } } } void usage(void) { fprint(2, "usage: %s [-n filename] [-m mountpoint] [-e lemmy endpoint]\n", argv0); exits("usage"); } void threadmain(int argc, char **argv) { char *srvname = "lemmyfs"; char *mntpt = "/n"; ARGBEGIN { case 'n': srvname = EARGF(usage()); break; case 'm': mntpt = EARGF(usage()); break; case 'e': endpoint = EARGF(usage()); break; default: usage(); } ARGEND JSONfmtinstall(); fsinit(); threadpostmountsrv(&s, srvname, mntpt, MBEFORE); threadexits(nil); } char* getcommunityfunc(Req *r) { char *response; response = webfs("/community/list", nil); readstr(r, response); free(response); return nil; } char* gettimefunc(Req *r) { char buf[128]; snprint(buf, sizeof buf, "%ld\n", time(0)); readstr(r, buf); return nil; }