#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;
}