#include #include #include #include #include <9p.h> #include #include typedef struct Define Define; typedef struct Value Value; struct Define { char* key; char* val; Define* link; }; struct Value { char* val; Value* link; }; static Define *defines; static Value *values; static char* finddef(char *key) { Define *d; for(d = defines; d; d = d->link){ if(strcmp(d->key, key) == 0) return d->val; } return nil; } static void putdef(char *key, char *val) { Define *d; d = malloc(sizeof(Define)); d->key = strdup(key); d->val = strdup(val); d->link = defines; defines = d; } static char* putval(char *val) { char *s; Value *v; for(v = values; v; v = v->link){ if(strcmp(v->val, val) == 0) return v->val; } s = finddef(val); if(s != nil) val = s; v = malloc(sizeof(Value)); v->val = malloc(strlen(val) + 2); strcpy(v->val, val); strcat(v->val, "\n"); v->link = values; return v->val; } static void fsread(Req *r) { int n; char *val; val = r->fid->file->aux; if(r->ifcall.offset > strlen(val)){ respond(r, "invalid read"); return; } n = strlen(val) - r->ifcall.offset; if(n > r->ifcall.count) n = r->ifcall.count; memcpy(r->ofcall.data, val + r->ifcall.offset, n); r->ofcall.count = n; respond(r, nil); } static Srv fs = { .read = fsread, }; static char* load(char *file) { Define *d; File *f; Ndb *db; Ndbtuple *t, *u; db = ndbopen(file); if(db == nil) return "could not open file"; while(t = ndbparse(db)){ if(strncmp(t->attr, "define", Ndbalen) == 0){ while(t = t->entry) putdef(t->attr, t->val); }else if(strncmp(t->attr, "profile", Ndbalen) == 0){ f = createfile(fs.tree->root, t->val, nil, DMDIR|0555, nil); u = t; while(u = u->entry) createfile(f, u->attr, nil, 0444, putval(u->val)); } } ndbclose(db); while(defines){ d = defines; defines = defines->link; free(d->key); free(d->val); free(d); } return nil; } static void usage(void) { fprint(2, "usage: themefs [-f file] [-m mtpt]\n"); exits("usage"); } void main(int argc, char **argv) { char *user, *file, *mtpt; file = nil; mtpt = "/mnt/theme"; ARGBEGIN{ case 'f': file = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; default: usage(); }ARGEND; if(argc > 0) usage(); if(file == nil){ user = getenv("user"); file = malloc(strlen(user) + 16); strcpy(file, "/usr/"); strcat(file, user); strcat(file, "/lib/theme"); free(user); } fs.tree = alloctree(nil, nil, DMDIR|0555, nil); load(file); postmountsrv(&fs, nil, mtpt, MREPL | MCREATE); exits(nil); }