More files related to user-level file servers.

Also add acme!
This commit is contained in:
rsc 2003-12-11 17:50:28 +00:00
parent 32f69c36e0
commit b3994ec5c7
35 changed files with 14133 additions and 0 deletions

46
src/lib9/_p9translate.c Normal file
View file

@ -0,0 +1,46 @@
#include <u.h>
#include <libc.h>
/*
* I don't want too many of these,
* but the ones we have are just too useful.
*/
static struct {
char *old;
char *new;
} replace[] = {
"#9", nil, /* must be first */
"#d", "/dev/fd",
};
char*
_p9translate(char *old)
{
char *new;
int i, olen, nlen, len;
if(replace[0].new == nil){
replace[0].new = getenv("PLAN9");
if(replace[0].new == nil)
replace[0].new = "/usr/local/plan9";
}
for(i=0; i<nelem(replace); i++){
if(!replace[i].new)
continue;
olen = strlen(replace[i].old);
if(strncmp(old, replace[i].old, olen) != 0
|| (old[olen] != '\0' && old[olen] != '/'))
continue;
nlen = strlen(replace[i].new);
len = strlen(old)+nlen-olen;
new = malloc(len+1);
if(new == nil)
return nil;
strcpy(new, replace[i].new);
strcpy(new+nlen, old+olen);
assert(strlen(new) == len);
return new;
}
return old;
}

19
src/lib9/access.c Normal file
View file

@ -0,0 +1,19 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>
char *_p9translate(char*);
int
p9access(char *xname, int what)
{
int ret;
char *name;
if((name = _p9translate(xname)) == nil)
return -1;
ret = access(name, what);
if(name != xname)
free(name);
return ret;
}

74
src/lib9/getns.c Normal file
View file

@ -0,0 +1,74 @@
#include <u.h>
#include <libc.h>
#include <ctype.h>
/*
* Absent other hints, it works reasonably well to use
* the X11 display name as the name space identifier.
* This is how sam's B has worked since the early days.
* Since most programs using name spaces are also using X,
* this still seems reasonable. Terminal-only sessions
* can set $NAMESPACE.
*/
static char*
nsfromdisplay(void)
{
int fd;
Dir *d;
char *disp, *p;
if((disp = getenv("DISPLAY")) == nil){
werrstr("$DISPLAY not set");
return nil;
}
/* canonicalize: xxx:0.0 => xxx:0 */
p = strrchr(disp, ':');
if(p){
p++;
while(isdigit((uchar)*p))
p++;
if(strcmp(p, ".0") == 0)
*p = 0;
}
p = smprint("/tmp/ns.%s.%s", getuser(), disp);
free(disp);
if(p == nil){
werrstr("out of memory");
return p;
}
if((fd=create(p, OREAD, DMDIR|0700)) >= 0){
close(fd);
return p;
}
if((d = dirstat(p)) == nil){
free(d);
werrstr("stat %s: %r", p);
free(p);
return nil;
}
if((d->mode&0777) != 0700 || strcmp(d->uid, getuser()) != 0){
werrstr("bad name space dir %s", p);
free(p);
free(d);
return nil;
}
free(d);
return p;
}
char*
getns(void)
{
char *ns;
ns = getenv("NAMESPACE");
if(ns == nil)
ns = nsfromdisplay();
if(ns == nil){
werrstr("$NAMESPACE not set, %r");
return nil;
}
return ns;
}

11
src/lib9/malloc.c Normal file
View file

@ -0,0 +1,11 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>
void*
p9malloc(ulong n)
{
if(n == 0)
n++;
return malloc(n);
}

38
src/lib9/open.c Normal file
View file

@ -0,0 +1,38 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>
extern char* _p9translate(char*);
int
p9open(char *xname, int mode)
{
char *name;
int cexec, rclose;
int fd, umode;
umode = mode&3;
cexec = mode&OCEXEC;
rclose = mode&ORCLOSE;
mode &= ~(3|OCEXEC|ORCLOSE);
if(mode&OTRUNC){
umode |= O_TRUNC;
mode ^= OTRUNC;
}
if(mode){
werrstr("mode not supported");
return -1;
}
if((name = _p9translate(xname)) == nil)
return -1;
fd = open(name, umode);
if(fd >= 0){
if(cexec)
fcntl(fd, F_SETFL, FD_CLOEXEC);
if(rclose)
remove(name);
}
if(name != xname)
free(name);
return fd;
}

10
src/lib9/pipe.c Normal file
View file

@ -0,0 +1,10 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>
#include <sys/socket.h>
int
p9pipe(int fd[2])
{
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
}

40
src/lib9/post9p.c Normal file
View file

@ -0,0 +1,40 @@
#include <u.h>
#include <libc.h>
int
post9pservice(int fd, char *name)
{
int i;
char *ns, *s;
Waitmsg *w;
if((ns = getns()) == nil)
return -1;
s = smprint("unix!%s/%s", ns, name);
free(ns);
if(s == nil)
return -1;
switch(rfork(RFPROC|RFFDG)){
case -1:
return -1;
case 0:
dup(fd, 0);
dup(fd, 1);
for(i=3; i<20; i++)
close(i);
execlp("9pserve", "9pserve", "-u", s, (char*)0);
fprint(2, "exec 9pserve: %r\n");
_exits("exec");
default:
w = wait();
close(fd);
free(s);
if(w->msg && w->msg[0]){
free(w);
werrstr("9pserve failed");
return -1;
}
free(w);
return 0;
}
}

79
src/lib9/sendfd.c Normal file
View file

@ -0,0 +1,79 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>
typedef struct Sendfd Sendfd;
struct Sendfd {
struct cmsghdr cmsg;
int fd;
};
int
sendfd(int s, int fd)
{
char buf[1];
struct iovec iov;
struct msghdr msg;
int n;
Sendfd sfd;
buf[0] = 0;
iov.iov_base = buf;
iov.iov_len = 1;
memset(&msg, 0, sizeof msg);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sfd.cmsg.cmsg_len = sizeof sfd;
sfd.cmsg.cmsg_level = SOL_SOCKET;
sfd.cmsg.cmsg_type = SCM_RIGHTS;
sfd.fd = fd;
msg.msg_control = &sfd;
msg.msg_controllen = sizeof sfd;
if((n=sendmsg(s, &msg, 0)) != iov.iov_len)
return -1;
return 0;
}
int
recvfd(int s)
{
int n;
char buf[1];
struct iovec iov;
struct msghdr msg;
Sendfd sfd;
iov.iov_base = buf;
iov.iov_len = 1;
memset(&msg, 0, sizeof msg);
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
memset(&sfd, 0, sizeof sfd);
sfd.fd = -1;
sfd.cmsg.cmsg_len = sizeof sfd;
sfd.cmsg.cmsg_level = SOL_SOCKET;
sfd.cmsg.cmsg_type = SCM_RIGHTS;
msg.msg_control = &sfd;
msg.msg_controllen = sizeof sfd;
if((n=recvmsg(s, &msg, 0)) < 0)
return -1;
if(n==0 && sfd.fd==-1){
werrstr("eof in recvfd");
return -1;
}
return sfd.fd;
}