ref: cc6e4b6231bb28fe268feea3bfb50f7e0ee59166
dir: /cons.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <avl.h> #include "dat.h" #include "fns.h" typedef struct Cmd Cmd; Cmd cmdtab[]; struct Cmd { char *name; char *sub; int minarg; int maxarg; void (*fn)(int, char**, int); }; static void setdbg(int fd, char **ap, int na) { debug = (na == 1) ? atoi(ap[0]) : !debug; fprint(fd, "debug → %d\n", debug); } static void syncfs(int fd, char **, int) { fprint(fd, "sync\n"); } static void snapfs(int fd, char **ap, int na) { Tree *t, *n; char *e; if((t = openlabel(ap[0])) == nil){ fprint(fd, "snap: open %s: does not exist\n", ap[0]); return; } if((n = newsnap(t)) == nil){ fprint(fd, "snap: save %s: failed\n", ap[na-1]); return; } if((e = labelsnap(ap[na-1], n->gen)) != nil){ fprint(fd, "snap: save %s: %s\n", ap[na-1], e); return; } if(na <= 1 || strcmp(ap[0], ap[1]) == 0){ /* the label moved */ if((e = unrefsnap(t->gen, n->gen)) != nil){ fprint(fd, "snap: unref old: %s\n", e); return; } } closesnap(n); closesnap(t); sync(); fprint(fd, "snap %s: ok\n", ap[na-1]); } static void fsckfs(int fd, char**, int) { if(checkfs(fd)) fprint(fd, "ok\n"); else fprint(fd, "broken fs\n"); } static void refreshusers(int fd, char **ap, int na) { char *l, *e; Tree *t; l = (na == 0) ? "main" : ap[0]; if((t = openlabel(l)) == nil){ fprint(fd, "load users: no label %s", l); return; } e = loadusers(fd, t); if(e != nil) fprint(fd, "load users: %s\n", e); else fprint(fd, "refreshed users\n"); closesnap(t); } static void showusers(int fd, char**, int) { User *u, *v; int i, j; char *sep; rlock(&fs->userlk); for(i = 0; i < fs->nusers; i++){ u = &fs->users[i]; fprint(fd, "%d:%s:", u->id, u->name); if((v = uid2user(fs->users, fs->nusers, u->lead)) == nil) fprint(fd, "???:"); else fprint(fd, "%s:", v->name); sep = ""; for(j = 0; j < u->nmemb; j++){ if((v = uid2user(fs->users, fs->nusers, u->memb[j])) == nil) fprint(fd, "%s???", sep); else fprint(fd, "%s%s", sep, v->name); sep = ","; } fprint(fd, "\n"); } runlock(&fs->userlk); } static void help(int fd, char **ap, int na) { Cmd *c; int i; for(c = cmdtab; c->name != nil; c++){ if(na == 0 || strcmp(ap[0], c->name) == 0){ if(c->sub == nil) fprint(fd, "%s", c->name); else fprint(fd, "%s %s", c->name, c->sub); for(i = 0; i < c->minarg; i++) fprint(fd, " a%d", i); for(i = c->minarg; i < c->maxarg; i++) fprint(fd, " [a%d]", i); fprint(fd, "\n"); } } } Cmd cmdtab[] = { {.name="sync", .sub=nil, .minarg=0, .maxarg=0, .fn=syncfs}, {.name="snap", .sub=nil, .minarg=1, .maxarg=2, .fn=snapfs}, {.name="check", .sub=nil, .minarg=1, .maxarg=1, .fn=fsckfs}, {.name="help", .sub=nil, .minarg=0, .maxarg=0, .fn=help}, {.name="users", .sub=nil, .minarg=0, .maxarg=1, .fn=refreshusers}, /* debugging */ {.name="show", .sub="cache", .minarg=0, .maxarg=0, .fn=showcache}, {.name="show", .sub="tree", .minarg=0, .maxarg=1, .fn=showtree}, {.name="show", .sub="snap", .minarg=0, .maxarg=1, .fn=showsnap}, {.name="show", .sub="fid", .minarg=0, .maxarg=0, .fn=showfid}, {.name="show", .sub="free", .minarg=0, .maxarg=0, .fn=showfree}, {.name="show", .sub="users", .minarg=0, .maxarg=0, .fn=showusers}, {.name="debug", .sub=nil, .minarg=1, .maxarg=1, .fn=setdbg}, {.name=nil, .sub=nil}, }; void runcons(int tid, void *pfd) { char buf[256], *f[4], **ap; int i, n, nf, na, fd; Cmd *c; fd = (uintptr)pfd; while(1){ if((n = read(fd, buf, sizeof(buf)-1)) == -1) break; quiesce(tid); buf[n] = 0; nf = tokenize(buf, f, nelem(f)); if(nf == 0 || strlen(f[0]) == 0) continue; for(c = cmdtab; c->name != nil; c++){ ap = f; na = nf; if(strcmp(c->name, *ap) != 0) continue; ap++; na--; if(c->sub != nil){ if(strcmp(c->sub, *ap) != 0) continue; ap++; na--; } if(na < c->minarg || na > c->maxarg) continue; c->fn(fd, ap, na); break; } if(c->name == nil){ fprint(fd, "unknown command '"); for(i = 0; i < nf; i++) fprint(fd, " %s", f[i]); fprint(fd, "'\n"); } quiesce(tid); } }