summaryrefslogtreecommitdiff
path: root/appl/cmd/9srvfs.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/9srvfs.b')
-rw-r--r--appl/cmd/9srvfs.b99
1 files changed, 99 insertions, 0 deletions
diff --git a/appl/cmd/9srvfs.b b/appl/cmd/9srvfs.b
new file mode 100644
index 00000000..d152d1bb
--- /dev/null
+++ b/appl/cmd/9srvfs.b
@@ -0,0 +1,99 @@
+implement P9srvfs;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+
+include "string.m";
+ str: String;
+
+include "sh.m";
+ sh: Sh;
+
+include "arg.m";
+
+P9srvfs: module
+{
+ init: fn(nil: ref Draw->Context, nil: list of string);
+};
+
+init(ctxt: ref Draw->Context, args: list of string)
+{
+ sys = load Sys Sys->PATH;
+ str = load String String->PATH;
+ if(str == nil)
+ nomod(String->PATH);
+
+ perm := 8r600;
+ arg := load Arg Arg->PATH;
+ if(arg == nil)
+ nomod(Arg->PATH);
+ arg->init(args);
+ arg->setusage("9srvfs [-p perm] name path|{command}");
+ while((o := arg->opt()) != 0)
+ case o {
+ 'p' =>
+ s := arg->earg();
+ if(s == nil)
+ arg->usage();
+ (perm, s) = str->toint(s, 8);
+ if(s != nil)
+ arg->usage();
+ * =>
+ arg->usage();
+ }
+ args = arg->argv();
+ if(len args != 2)
+ arg->usage();
+ arg = nil;
+
+ srvname := hd args;
+ args = tl args;
+ dest := hd args;
+ if(dest == nil)
+ dest = ".";
+ iscmd := dest[0] == '{' && dest[len dest-1] == '}';
+ if(!iscmd){ # quick check before creating service file
+ (ok, d) := sys->stat(dest);
+ if(ok < 0)
+ error(sys->sprint("can't stat %s: %r", dest));
+ if((d.mode & Sys->DMDIR) == 0)
+ error(sys->sprint("%s: not a directory", dest));
+ }else{
+ sh = load Sh Sh->PATH;
+ if(sh == nil)
+ nomod(Sh->PATH);
+ }
+ srvfd := sys->create("/srv/"+srvname, Sys->ORDWR, perm);
+ if(srvfd == nil)
+ error(sys->sprint("can't create /srv/%s: %r", srvname));
+ if(iscmd){
+ sync := chan of int;
+ spawn runcmd(sh, ctxt, dest :: nil, srvfd, sync);
+ <-sync;
+ }else{
+ if(sys->export(srvfd, dest, Sys->EXPWAIT) < 0)
+ error(sys->sprint("export failed: %r"));
+ }
+}
+
+error(msg: string)
+{
+ sys->fprint(sys->fildes(2), "9srvfs: %s\n", msg);
+ raise "fail:error";
+}
+
+nomod(mod: string)
+{
+ error(sys->sprint("can't load %s: %r", mod));
+}
+
+runcmd(sh: Sh, ctxt: ref Draw->Context, argv: list of string, stdin: ref Sys->FD, sync: chan of int)
+{
+ sys->pctl(Sys->FORKFD, nil);
+ sys->dup(stdin.fd, 0);
+ stdin = nil;
+ sync <-= 0;
+ sh->run(ctxt, argv);
+}