diff options
author | aiju <aiju@phicode.de> | 2012-08-07 17:57:04 +0200 |
---|---|---|
committer | aiju <aiju@phicode.de> | 2012-08-07 17:57:04 +0200 |
commit | b21b9ba89cf66a8fac6f94efb79cfb425a2c4df2 (patch) | |
tree | 42047f997cda3eddec9faeafeb74435cc72a4786 /sys/src/cmd/hjfs/cons.c | |
parent | ef1c1863051d0530a31b291f4e334ee7601c318c (diff) |
added hjfs
Diffstat (limited to 'sys/src/cmd/hjfs/cons.c')
-rw-r--r-- | sys/src/cmd/hjfs/cons.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/sys/src/cmd/hjfs/cons.c b/sys/src/cmd/hjfs/cons.c new file mode 100644 index 000000000..db76452b2 --- /dev/null +++ b/sys/src/cmd/hjfs/cons.c @@ -0,0 +1,238 @@ +#include <u.h> +#include <libc.h> +#include <thread.h> +#include <bio.h> +#include "dat.h" +#include "fns.h" + +enum { MAXARGS = 16 }; + +typedef struct Cmd Cmd; +static int echo; +extern Fs *fsmain; + +struct Cmd { + char *name; + int args; + int (*f)(int, char **); +}; + +static int +walkpath(Chan *ch, char *path, char **cr) +{ + char buf[NAMELEN], *p, *fp; + + buf[NAMELEN - 1] = 0; + fp = path; + if(*path != '/'){ + noent: + werrstr("%s: %s", fp, Enoent); + return -1; + } + path++; + for(;;){ + p = strchr(path, '/'); + if(p == nil){ + if(cr != nil){ + if(*path == 0){ + werrstr("%s: trailing slash", fp); + return -1; + } + *cr = path; + break; + } + p = path + strlen(path); + } + if(*path == '/'){ + path++; + continue; + } + if(*path == 0) + break; + if(p - path >= NAMELEN) + goto noent; + memcpy(buf, path, p - path); + if(chanwalk(ch, buf) <= 0){ + werrstr("%s: %r", fp); + return -1; + } + if(*p == 0) + break; + path = p + 1; + } + return 1; +} + +int +cmdhalt(int, char **) +{ + shutdown(); + return 0; +} + +int +cmddump(int, char **) +{ + fsdump(fsmain); + dprint("hjfs: dumped\n"); + return 0; +} + +int +cmdallow(int, char **) +{ + fsmain->flags |= FSNOPERM | FSCHOWN; + dprint("hjfs: allow\n"); + return 0; +} + +int +cmdchatty(int, char **) +{ + extern int chatty9p; + + chatty9p = !chatty9p; + return 0; +} + +int +cmddisallow(int, char **) +{ + fsmain->flags &= ~(FSNOPERM | FSCHOWN); + dprint("hjfs: disallow\n"); + return 0; +} + +int +cmdnoauth(int, char **) +{ + fsmain->flags ^= FSNOAUTH; + if((fsmain->flags & FSNOAUTH) != 0) + dprint("hjfs: auth enabled\n"); + else + dprint("hjfs: auth disabled\n"); + return 1; +} + +int +cmdcreate(int argc, char **argv) +{ + Chan *ch; + char *n; + short uid, gid; + ulong perm; + Dir di; + + if(argc != 5 && argc != 6) + return -9001; + perm = strtol(argv[4], &n, 8) & 0777; + if(*n != 0) + return -9001; + if(argc == 6) + for(n = argv[5]; *n != 0; n++) + switch(*n){ + case 'l': perm |= DMEXCL; break; + case 'd': perm |= DMDIR; break; + case 'a': perm |= DMAPPEND; break; + default: return -9001; + } + if(name2uid(fsmain, argv[2], &uid) < 0) + return -1; + if(name2uid(fsmain, argv[3], &gid) < 0) + return -1; + ch = chanattach(fsmain, 0); + if(ch == nil) + return -1; + ch->uid = uid; + if(walkpath(ch, argv[1], &n) < 0){ + chanclunk(ch); + return -1; + } + if(chancreat(ch, n, perm, OREAD) < 0){ + chanclunk(ch); + return -1; + } + nulldir(&di); + di.gid = argv[3]; + chanwstat(ch, &di); + chanclunk(ch); + return 1; +} + +int +cmdecho(int, char **argv) +{ + echo = strcmp(argv[1], "on") == 0; + return 1; +} + +extern int cmdnewuser(int, char **); + +Cmd cmds[] = { + {"allow", 1, cmdallow}, + {"noauth", 1, cmdnoauth}, + {"chatty", 1, cmdchatty}, + {"create", 0, cmdcreate}, + {"disallow", 1, cmddisallow}, + {"dump", 1, cmddump}, + {"halt", 1, cmdhalt}, + {"newuser", 0, cmdnewuser}, + {"echo", 2, cmdecho}, +}; + + +static void +consproc(void *v) +{ + Biobuf *in; + Cmd *c; + char *s; + char *args[MAXARGS]; + int rc; + + in = (Biobuf *) v; + for(;;){ + s = Brdstr(in, '\n', 1); + if(s == nil) + continue; + if(echo) + dprint("hjfs: >%s\n", s); + rc = tokenize(s, args, MAXARGS); + if(rc == 0) + goto syntax; + for(c = cmds; c < cmds + nelem(cmds); c++) + if(strcmp(c->name, args[0]) == 0){ + if(c->args != 0 && c->args != rc) + goto syntax; + if(c->f != nil){ + rc = c->f(rc, args); + if(rc == -9001) + goto syntax; + if(rc < 0) + dprint("hjfs: %r\n"); + goto done; + } + } + syntax: + dprint("hjfs: syntax error\n"); + done: + free(s); + } +} + +void +initcons(char *service) +{ + int fd, pfd[2]; + static Biobuf bio; + char buf[512]; + + snprint(buf, sizeof(buf), "/srv/%s.cmd", service); + fd = create(buf, OWRITE|ORCLOSE, 0600); + if(fd < 0) + return; + pipe(pfd); + fprint(fd, "%d", pfd[1]); + Binit(&bio, pfd[0], OREAD); + proccreate(consproc, &bio, mainstacksize); +} |