Add support for user-level 9P servers/clients and various bug fixes to go with them.
This commit is contained in:
parent
ac244f8d28
commit
32f69c36e0
60 changed files with 965 additions and 485 deletions
|
|
@ -3,14 +3,13 @@
|
|||
#include <bio.h>
|
||||
#include <regexp.h>
|
||||
#include <thread.h>
|
||||
#include <auth.h>
|
||||
#include <fcall.h>
|
||||
#include <plumb.h>
|
||||
#include "plumber.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Stack = 8*1024
|
||||
Stack = 32*1024
|
||||
};
|
||||
|
||||
typedef struct Dirtab Dirtab;
|
||||
|
|
@ -73,13 +72,12 @@ struct Holdq
|
|||
|
||||
struct /* needed because incref() doesn't return value */
|
||||
{
|
||||
Lock;
|
||||
int ref;
|
||||
Lock lk;
|
||||
int ref;
|
||||
} rulesref;
|
||||
|
||||
enum
|
||||
{
|
||||
DEBUG = 0,
|
||||
NDIR = 50,
|
||||
Nhash = 16,
|
||||
|
||||
|
|
@ -99,13 +97,10 @@ static Dirtab dir[NDIR] =
|
|||
static int ndir = NQID;
|
||||
|
||||
static int srvfd;
|
||||
static int srvclosefd; /* rock for end of pipe to close */
|
||||
static int clockfd;
|
||||
static int clock;
|
||||
static Fid *fids[Nhash];
|
||||
static QLock readlock;
|
||||
static QLock queue;
|
||||
static char srvfile[128];
|
||||
static int messagesize = 8192+IOHDRSZ; /* good start */
|
||||
|
||||
static void fsysproc(void*);
|
||||
|
|
@ -183,54 +178,35 @@ addport(char *port)
|
|||
static ulong
|
||||
getclock(void)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
seek(clockfd, 0, 0);
|
||||
read(clockfd, buf, sizeof buf);
|
||||
return atoi(buf);
|
||||
return time(0);
|
||||
}
|
||||
|
||||
void
|
||||
startfsys(void)
|
||||
{
|
||||
int p[2], fd;
|
||||
int p[2];
|
||||
|
||||
fmtinstall('F', fcallfmt);
|
||||
clockfd = open("/dev/time", OREAD|OCEXEC);
|
||||
clock = getclock();
|
||||
if(pipe(p) < 0)
|
||||
error("can't create pipe: %r");
|
||||
/* 0 will be server end, 1 will be client end */
|
||||
srvfd = p[0];
|
||||
srvclosefd = p[1];
|
||||
sprint(srvfile, "/srv/plumb.%s.%d", user, getpid());
|
||||
if(putenv("plumbsrv", srvfile) < 0)
|
||||
error("can't write $plumbsrv: %r");
|
||||
fd = create(srvfile, OWRITE|OCEXEC|ORCLOSE, 0600);
|
||||
if(fd < 0)
|
||||
error("can't create /srv file: %r");
|
||||
if(fprint(fd, "%d", p[1]) <= 0)
|
||||
error("can't write /srv/file: %r");
|
||||
/* leave fd open; ORCLOSE will take care of it */
|
||||
|
||||
procrfork(fsysproc, nil, Stack, RFFDG);
|
||||
|
||||
close(p[0]);
|
||||
if(mount(p[1], -1, "/mnt/plumb", MREPL, "") < 0)
|
||||
error("can't mount /mnt/plumb: %r");
|
||||
if(post9pservice(p[1], "plumb") < 0)
|
||||
sysfatal("post9pservice plumb: %r");
|
||||
close(p[1]);
|
||||
proccreate(fsysproc, nil, Stack);
|
||||
}
|
||||
|
||||
static void
|
||||
fsysproc(void*)
|
||||
fsysproc(void *v)
|
||||
{
|
||||
int n;
|
||||
Fcall *t;
|
||||
Fid *f;
|
||||
uchar *buf;
|
||||
|
||||
close(srvclosefd);
|
||||
srvclosefd = -1;
|
||||
USED(v);
|
||||
t = nil;
|
||||
for(;;){
|
||||
buf = malloc(messagesize); /* avoid memset of emalloc */
|
||||
|
|
@ -250,7 +226,7 @@ fsysproc(void*)
|
|||
t = emalloc(sizeof(Fcall));
|
||||
if(convM2S(buf, n, t) != n)
|
||||
error("convert error in convM2S");
|
||||
if(DEBUG)
|
||||
if(debug)
|
||||
fprint(2, "<= %F\n", t);
|
||||
if(fcall[t->type] == nil)
|
||||
fsysrespond(t, buf, Ebadfcall);
|
||||
|
|
@ -281,7 +257,7 @@ fsysrespond(Fcall *t, uchar *buf, char *err)
|
|||
error("convert error in convS2M");
|
||||
if(write(srvfd, buf, n) != n)
|
||||
error("write error in respond");
|
||||
if(DEBUG)
|
||||
if(debug)
|
||||
fprint(2, "=> %F\n", t);
|
||||
free(buf);
|
||||
}
|
||||
|
|
@ -555,8 +531,10 @@ dispose(Fcall *t, uchar *buf, Plumbmsg *m, Ruleset *rs, Exec *e)
|
|||
}
|
||||
|
||||
static Fcall*
|
||||
fsysversion(Fcall *t, uchar *buf, Fid*)
|
||||
fsysversion(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
USED(fid);
|
||||
|
||||
if(t->msize < 256){
|
||||
fsysrespond(t, buf, "version: message size too small");
|
||||
return t;
|
||||
|
|
@ -574,8 +552,9 @@ fsysversion(Fcall *t, uchar *buf, Fid*)
|
|||
}
|
||||
|
||||
static Fcall*
|
||||
fsysauth(Fcall *t, uchar *buf, Fid*)
|
||||
fsysauth(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
USED(fid);
|
||||
fsysrespond(t, buf, "plumber: authentication not required");
|
||||
return t;
|
||||
}
|
||||
|
|
@ -605,10 +584,11 @@ fsysattach(Fcall *t, uchar *buf, Fid *f)
|
|||
}
|
||||
|
||||
static Fcall*
|
||||
fsysflush(Fcall *t, uchar *buf, Fid*)
|
||||
fsysflush(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
int i;
|
||||
|
||||
USED(fid);
|
||||
qlock(&queue);
|
||||
for(i=NQID; i<ndir; i++)
|
||||
flushqueue(&dir[i], t->oldtag);
|
||||
|
|
@ -729,14 +709,14 @@ fsysopen(Fcall *t, uchar *buf, Fid *f)
|
|||
if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m)
|
||||
goto Deny;
|
||||
if(f->qid.path==Qrules && (mode==OWRITE || mode==ORDWR)){
|
||||
lock(&rulesref);
|
||||
lock(&rulesref.lk);
|
||||
if(rulesref.ref++ != 0){
|
||||
rulesref.ref--;
|
||||
unlock(&rulesref);
|
||||
unlock(&rulesref.lk);
|
||||
fsysrespond(t, buf, Einuse);
|
||||
return t;
|
||||
}
|
||||
unlock(&rulesref);
|
||||
unlock(&rulesref.lk);
|
||||
}
|
||||
if(clearrules){
|
||||
writerules(nil, 0);
|
||||
|
|
@ -761,8 +741,9 @@ fsysopen(Fcall *t, uchar *buf, Fid *f)
|
|||
}
|
||||
|
||||
static Fcall*
|
||||
fsyscreate(Fcall *t, uchar *buf, Fid*)
|
||||
fsyscreate(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
USED(fid);
|
||||
fsysrespond(t, buf, Eperm);
|
||||
return t;
|
||||
}
|
||||
|
|
@ -916,15 +897,17 @@ fsysstat(Fcall *t, uchar *buf, Fid *f)
|
|||
}
|
||||
|
||||
static Fcall*
|
||||
fsyswstat(Fcall *t, uchar *buf, Fid*)
|
||||
fsyswstat(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
USED(fid);
|
||||
fsysrespond(t, buf, Eperm);
|
||||
return t;
|
||||
}
|
||||
|
||||
static Fcall*
|
||||
fsysremove(Fcall *t, uchar *buf, Fid*)
|
||||
fsysremove(Fcall *t, uchar *buf, Fid *fid)
|
||||
{
|
||||
USED(fid);
|
||||
fsysrespond(t, buf, Eperm);
|
||||
return t;
|
||||
}
|
||||
|
|
@ -945,9 +928,9 @@ fsysclunk(Fcall *t, uchar *buf, Fid *f)
|
|||
* unless last write ended with a blank line
|
||||
*/
|
||||
writerules(nil, 0);
|
||||
lock(&rulesref);
|
||||
lock(&rulesref.lk);
|
||||
rulesref.ref--;
|
||||
unlock(&rulesref);
|
||||
unlock(&rulesref.lk);
|
||||
}
|
||||
prev = nil;
|
||||
for(p=d->fopen; p; p=p->nextopen){
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <plumb.h>
|
||||
#include "plumber.h"
|
||||
|
||||
/*
|
||||
static char*
|
||||
nonnil(char *s)
|
||||
{
|
||||
|
|
@ -13,6 +14,7 @@ nonnil(char *s)
|
|||
return "";
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
verbis(int obj, Plumbmsg *m, Rule *r)
|
||||
|
|
@ -44,10 +46,10 @@ setvar(Resub rs[10], char *match[10])
|
|||
free(match[i]);
|
||||
match[i] = nil;
|
||||
}
|
||||
for(i=0; i<10 && rs[i].sp!=nil; i++){
|
||||
n = rs[i].ep-rs[i].sp;
|
||||
for(i=0; i<10 && rs[i].s.sp!=nil; i++){
|
||||
n = rs[i].e.ep-rs[i].s.sp;
|
||||
match[i] = emalloc(n+1);
|
||||
memmove(match[i], rs[i].sp, n);
|
||||
memmove(match[i], rs[i].s.sp, n);
|
||||
match[i][n] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +68,7 @@ clickmatch(Reprog *re, char *text, Resub rs[10], int click)
|
|||
for(i=0; i<=click; i++){
|
||||
memset(rs, 0, 10*sizeof(Resub));
|
||||
if(regexec(re, text+i, rs, 10))
|
||||
if(rs[0].sp<=clickp && clickp<=rs[0].ep)
|
||||
if(rs[0].s.sp<=clickp && clickp<=rs[0].e.ep)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -94,8 +96,8 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e)
|
|||
}
|
||||
if(!clickmatch(r->regex, m->data, rs, atoi(clickval)))
|
||||
break;
|
||||
p0 = rs[0].sp - m->data;
|
||||
p1 = rs[0].ep - m->data;
|
||||
p0 = rs[0].s.sp - m->data;
|
||||
p1 = rs[0].e.ep - m->data;
|
||||
if(e->p0 >=0 && !(p0==e->p0 && p1==e->p1))
|
||||
break;
|
||||
e->clearclick = 1;
|
||||
|
|
@ -120,7 +122,7 @@ verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e)
|
|||
/* must match full text */
|
||||
if(ntext < 0)
|
||||
ntext = strlen(alltext);
|
||||
if(!regexec(r->regex, alltext, rs, 10) || rs[0].sp!=alltext || rs[0].ep!=alltext+ntext)
|
||||
if(!regexec(r->regex, alltext, rs, 10) || rs[0].s.sp!=alltext || rs[0].e.ep!=alltext+ntext)
|
||||
break;
|
||||
setvar(rs, e->match);
|
||||
return 1;
|
||||
|
|
@ -389,7 +391,7 @@ enum
|
|||
{
|
||||
NARGS = 100,
|
||||
NARGCHAR = 8*1024,
|
||||
EXECSTACK = 4096+(NARGS+1)*sizeof(char*)+NARGCHAR
|
||||
EXECSTACK = 32*1024+(NARGS+1)*sizeof(char*)+NARGCHAR
|
||||
};
|
||||
|
||||
/* copy argv to stack and free the incoming strings, so we don't leak argument vectors */
|
||||
|
|
@ -419,19 +421,17 @@ stackargv(char **inargv, char *argv[NARGS+1], char args[NARGCHAR])
|
|||
void
|
||||
execproc(void *v)
|
||||
{
|
||||
int fd[3];
|
||||
char **av;
|
||||
char buf[1024], *args[NARGS+1], argc[NARGCHAR];
|
||||
char *args[NARGS+1], argc[NARGCHAR];
|
||||
|
||||
rfork(RFFDG);
|
||||
close(0);
|
||||
open("/dev/null", OREAD);
|
||||
fd[0] = open("/dev/null", OREAD);
|
||||
fd[1] = dup(1, -1);
|
||||
fd[2] = dup(2, -1);
|
||||
av = v;
|
||||
stackargv(av, args, argc);
|
||||
free(av);
|
||||
procexec(nil, args[0], args);
|
||||
if(args[0][0]!='/' && strncmp(args[0], "./", 2)!=0 && strncmp(args[0], "../", 3)!=0)
|
||||
snprint(buf, sizeof buf, "/bin/%s", args[0]);
|
||||
procexec(nil, buf, args);
|
||||
procexec(nil, fd, args[0], args);
|
||||
threadexits("can't exec");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
</$objtype/mkfile
|
||||
PLAN9=../../..
|
||||
<$PLAN9/src/mkhdr
|
||||
|
||||
TARG=plumber plumb
|
||||
|
||||
|
||||
BIN=/$objtype/bin
|
||||
</sys/src/cmd/mkmany
|
||||
<$PLAN9/src/mkmany
|
||||
|
||||
PLUMBER=plumber.$O fsys.$O match.$O rules.$O
|
||||
PLUMB=plumb.$O
|
||||
|
|
@ -15,6 +14,4 @@ $PLUMB: $HFILES
|
|||
$O.plumb: $PLUMB
|
||||
$O.plumber: $PLUMBER
|
||||
|
||||
syms:V:
|
||||
8c -a plumber.c >syms
|
||||
8c -aa fsys.c match.c rules.c >>syms
|
||||
LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lregexp9 -l9 -lbio -lfmt -lutf
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
#include <regexp.h>
|
||||
#include <thread.h>
|
||||
#include <plumb.h>
|
||||
#include <auth.h>
|
||||
#include <fcall.h>
|
||||
#include "plumber.h"
|
||||
|
||||
int debug;
|
||||
char *plumbfile;
|
||||
char *user;
|
||||
char *home;
|
||||
|
|
@ -47,13 +47,18 @@ threadmain(int argc, char *argv[])
|
|||
progname = "plumber";
|
||||
|
||||
ARGBEGIN{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'p':
|
||||
plumbfile = ARGF();
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
user = getenv("user");
|
||||
user = getuser();
|
||||
home = getenv("home");
|
||||
if(home == nil)
|
||||
home = getenv("HOME");
|
||||
if(user==nil || home==nil)
|
||||
error("can't initialize $user or $home: %r");
|
||||
if(plumbfile == nil){
|
||||
|
|
|
|||
|
|
@ -91,3 +91,4 @@ jmp_buf parsejmp;
|
|||
char *lasterror;
|
||||
char **ports;
|
||||
int nports;
|
||||
int debug;
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ char*
|
|||
getline(void)
|
||||
{
|
||||
static int n = 0;
|
||||
static char *s, *incl;
|
||||
static char *s /*, *incl*/;
|
||||
int c, i;
|
||||
|
||||
i = 0;
|
||||
|
|
@ -414,7 +414,7 @@ include(char *s)
|
|||
t = args[1];
|
||||
fd = open(t, OREAD);
|
||||
if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){
|
||||
snprint(buf, sizeof buf, "/sys/lib/plumb/%s", t);
|
||||
snprint(buf, sizeof buf, "#9/plumb/%s", t);
|
||||
t = buf;
|
||||
fd = open(t, OREAD);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue