#include #include #include #include #include #include <9p.h> #include #include #include static char *delim = nil; static char *uid = "json"; static char *mtpt = nil; void fsread(Req *r) { if(r->fid->file->aux) readstr(r, r->fid->file->aux); respond(r, nil); } Srv fs = { .read = fsread, }; char* esmprint(char *fmt, ...) { char *s; va_list arg; va_start(arg, fmt); s = vsmprint(fmt, arg); va_end(arg); if(s == nil) sysfatal("out of memory"); return s; } char* jprint(char *fmt, ...) { char *s, *p; va_list arg; p = nil; if(delim != nil){ if((p = smprint("%s%s", fmt, delim)) == nil) sysfatal("out of memory"); fmt = p; } va_start(arg, fmt); s = vsmprint(fmt, arg); va_end(arg); if(s == nil) sysfatal("out of memory"); if(p) free(p); return s; } void json2files(File *dir, JSON *j) { File *d, *f; JSONEl *tok; char *p; void *s; int anum = 0; int bnum = 0; for(tok = j->first; tok != nil; tok = tok->next){ s = nil; switch(tok->val->t){ case JSONNull: s = jprint("null"); break; case JSONBool: if(tok->val->n) s = jprint("true"); else s = jprint("false"); break; case JSONNumber: s = jprint("%0.f", tok->val->n); break; case JSONString: s = jprint("%s", tok->val->s); break; case JSONArray: case JSONObject: if((s = tok->name) == nil || strlen(s) < 1) s = esmprint("%d", anum++); if((d = createfile(dir, s, uid, DMDIR|0777, nil)) == nil) sysfatal("createfile: JSONObject: %r"); d->qid.type = QTDIR; json2files(d, tok->val); continue; default: sysfatal("wut: %r"); } if((p = tok->name) == nil) p = esmprint("%d", bnum++); if((f = createfile(dir, p, uid, 0666, s)) != nil) f->length = strlen(s); } } void populatetree(File *root, int fd) { Biobuf in; String *s; JSON *j; Binit(&in, fd, OREAD); s = s_new(); while(s_read(&in, s, 8192)) ; if((j = jsonparse(s_to_c(s))) == nil) sysfatal("jsonparse: %r"); json2files(root, j); s_free(s); Bterm(&in); } void usage(void) { fprint(2, "usage: %s [-D] [-s srv] [-m mtpt] [-n] [file]\n", argv0); exits("usage"); } void main(int argc, char **argv) { char *srv; int fd; fd = 0; srv = nil; mtpt = "/mnt/json"; ARGBEGIN{ case 'D': chatty9p++; break; case 's': srv = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; case 'n': delim = "\n"; break; default: usage(); }ARGEND; if(argc > 1) usage(); else if(argc == 1){ if((fd = open(argv[0], OREAD)) < 0) sysfatal("open: %r"); } if(chatty9p) fprint(2, "jsonfs.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srv, mtpt); fs.tree = alloctree(nil, nil, DMDIR|0777, nil); populatetree(fs.tree->root, fd); postmountsrv(&fs, srv, mtpt, MREPL|MCREATE); exits(nil); }