summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ip/cifsd/share.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/src/cmd/ip/cifsd/share.c')
-rw-r--r--sys/src/cmd/ip/cifsd/share.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/sys/src/cmd/ip/cifsd/share.c b/sys/src/cmd/ip/cifsd/share.c
new file mode 100644
index 000000000..e14014085
--- /dev/null
+++ b/sys/src/cmd/ip/cifsd/share.c
@@ -0,0 +1,124 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+static int
+run9fs(char *arg)
+{
+ char buf[1024], *argv[3], *s;
+ Waitmsg *w;
+ int fd, pid;
+
+ switch(pid = rfork(RFCFDG|RFREND|RFPROC)){
+ case -1:
+ return -1;
+ case 0:
+ open("/dev/null", ORDWR);
+ snprint(buf, sizeof(buf), "/sys/log/%s", progname);
+ if((fd = open(buf, OWRITE)) >= 0)
+ seek(fd, 0, 2);
+ else
+ fd = 0;
+ dup(fd, 1);
+ dup(fd, 2);
+ argv[0] = "/bin/9fs";
+ argv[1] = arg;
+ argv[2] = 0;
+ exec(argv[0], argv);
+ exits("failed to exec 9fs");
+ }
+ for (;;) {
+ if((w = wait()) == nil)
+ return -1;
+ if (w->pid == pid)
+ break;
+ free(w);
+ }
+ if(w->msg[0]){
+ if(s = strchr(w->msg, ':'))
+ s = s+1;
+ else
+ s = w->msg;
+ werrstr("%s", s);
+ free(w);
+ return -1;
+ } else {
+ free(w);
+ return 0;
+ }
+}
+
+static Share *shares;
+
+Share*
+mapshare(char *path)
+{
+ char *tmp, *tmp2, *name, *root, *service, *fsname, *remark;
+ int stype;
+ Share *s;
+
+ if(name = strrchr(path, '/'))
+ name++;
+ else if(name = strrchr(path, '\\'))
+ name++;
+ else
+ name = path;
+ if(name==nil || *name==0 || *name=='.' || strchrs(name, "\\* ") || strstr(name, ".."))
+ return nil;
+ root = tmp = smprint("/n/%s", name);
+ name = strtr(strrchr(root, '/')+1, tolowerrune);
+ service = "A:";
+ stype = STYPE_DISKTREE;
+ fsname = "9fs";
+ remark = tmp2 = smprint("9fs %s; cd %s", name, root);
+ if(!strcmp(name, "local")){
+ root = "/";
+ fsname = "local";
+ remark = "The standard namespace";
+ }
+ if(!strcmp(name, "ipc$")){
+ root = "/dev/null";
+ name = "IPC$";
+ fsname = "";
+ service = "IPC";
+ stype = STYPE_IPC;
+ remark = "The IPC service";
+ }
+
+ for(s = shares; s; s=s->next)
+ if(!strcmp(s->name, name))
+ goto out;
+
+ logit("mapshare %s -> %s %s %s", path, service, name, root);
+
+ if(!strcmp(service, "A:") && (stype == STYPE_DISKTREE)){
+ if(!strcmp(fsname, "9fs") && (run9fs(name) < 0)){
+ logit("9fs %s: %r", name);
+ goto out;
+ }
+ }
+
+ s = malloc(sizeof(*s));
+ s->service = strdup(service);
+ s->stype = stype;
+
+ s->name = strdup(name);
+ s->root = strdup(root);
+
+ s->remark = strdup(remark);
+ s->fsname = strdup(fsname);
+ s->namelen = 255;
+ s->sectorsize = 0x200;
+ s->blocksize = 0x2000;
+ s->allocsize = 0;
+ s->freesize = s->blocksize;
+
+ s->next = shares;
+ shares = s;
+
+out:
+ free(tmp);
+ free(tmp2);
+ return s;
+}