summaryrefslogtreecommitdiff
path: root/sys/src/cmd/hjfs/cons.c
diff options
context:
space:
mode:
authoraiju <aiju@phicode.de>2012-08-07 17:57:04 +0200
committeraiju <aiju@phicode.de>2012-08-07 17:57:04 +0200
commitb21b9ba89cf66a8fac6f94efb79cfb425a2c4df2 (patch)
tree42047f997cda3eddec9faeafeb74435cc72a4786 /sys/src/cmd/hjfs/cons.c
parentef1c1863051d0530a31b291f4e334ee7601c318c (diff)
added hjfs
Diffstat (limited to 'sys/src/cmd/hjfs/cons.c')
-rw-r--r--sys/src/cmd/hjfs/cons.c238
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);
+}