ref: b0377e84cf31c48afed765c433abe7eebb4135a5
dir: /sys/src/cmd/ip/cifsd/share.c/
#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; unixidmap(s); s->next = shares; shares = s; out: free(tmp); free(tmp2); return s; }