usbd: added event file, removed usbdb
This commit is contained in:
parent
27fd88af23
commit
4792c6bef9
5 changed files with 245 additions and 327 deletions
|
@ -1,24 +1,7 @@
|
||||||
typedef struct Rule Rule;
|
|
||||||
typedef struct Cond Cond;
|
|
||||||
typedef struct Hub Hub;
|
typedef struct Hub Hub;
|
||||||
typedef struct DHub DHub;
|
typedef struct DHub DHub;
|
||||||
typedef struct Port Port;
|
typedef struct Port Port;
|
||||||
|
|
||||||
struct Rule {
|
|
||||||
char **argv;
|
|
||||||
int argc;
|
|
||||||
Cond *cond;
|
|
||||||
Rule *next;
|
|
||||||
} *rulefirst, *rulelast;
|
|
||||||
|
|
||||||
RWLock rulelock;
|
|
||||||
|
|
||||||
struct Cond {
|
|
||||||
int field;
|
|
||||||
u32int value;
|
|
||||||
Cond *and, *or;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Stack = 32*1024,
|
Stack = 32*1024,
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
void parserules(char*);
|
|
||||||
Rule* rulesmatch(Usbdev*);
|
|
||||||
int startdev(Port*);
|
int startdev(Port*);
|
||||||
void work(void);
|
void work(void);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
usbd.$O\
|
usbd.$O\
|
||||||
rules.$O\
|
|
||||||
hub.$O\
|
hub.$O\
|
||||||
|
|
||||||
HFILES=\
|
HFILES=\
|
||||||
|
|
|
@ -1,241 +0,0 @@
|
||||||
#include <u.h>
|
|
||||||
#include <libc.h>
|
|
||||||
#include <thread.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "usb.h"
|
|
||||||
#include "dat.h"
|
|
||||||
#include "fns.h"
|
|
||||||
|
|
||||||
static char *pos;
|
|
||||||
static int lineno;
|
|
||||||
|
|
||||||
static void
|
|
||||||
skipempty(void)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
for(;;){
|
|
||||||
s = pos;
|
|
||||||
if(*s == 0)
|
|
||||||
return;
|
|
||||||
while(*s != '\n' && isspace(*s))
|
|
||||||
s++;
|
|
||||||
if(*s == '#')
|
|
||||||
while(*s != 0 && *s != '\n')
|
|
||||||
s++;
|
|
||||||
if(*s != 0 && *s != '\n')
|
|
||||||
return;
|
|
||||||
pos = s;
|
|
||||||
if(*pos != 0){
|
|
||||||
pos++;
|
|
||||||
lineno++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
parsesh(int *argc, char ***argv)
|
|
||||||
{
|
|
||||||
char *e;
|
|
||||||
|
|
||||||
*argc = 0;
|
|
||||||
*argv = nil;
|
|
||||||
for(;;){
|
|
||||||
while(isspace(*pos) && *pos != '\n')
|
|
||||||
pos++;
|
|
||||||
if(*pos == '\n' || *pos == 0 || *pos == '#')
|
|
||||||
break;
|
|
||||||
e = pos;
|
|
||||||
while(*e != 0 && *e != '#' && !isspace(*e))
|
|
||||||
e++;
|
|
||||||
(*argc)++;
|
|
||||||
*argv = realloc(*argv, (*argc + 2) * sizeof(char *));
|
|
||||||
if(*argv == nil)
|
|
||||||
sysfatal("realloc: %r");
|
|
||||||
(*argv)[*argc - 1] = mallocz(e - pos + 1, 1);
|
|
||||||
if((*argv)[*argc - 1] == nil)
|
|
||||||
sysfatal("malloc: %r");
|
|
||||||
memmove((*argv)[*argc - 1], pos, e - pos);
|
|
||||||
pos = e;
|
|
||||||
}
|
|
||||||
if(*argv != nil){
|
|
||||||
(*argv)[*argc] = nil;
|
|
||||||
(*argv)[*argc + 1] = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Usbdev dummy;
|
|
||||||
|
|
||||||
struct field {
|
|
||||||
char *s;
|
|
||||||
void* v;
|
|
||||||
} fields[] = {
|
|
||||||
"class", &dummy.class,
|
|
||||||
"vid", &dummy.vid,
|
|
||||||
"did", &dummy.did,
|
|
||||||
"csp", &dummy.csp,
|
|
||||||
nil, nil,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
parsecond(Rule *r, Cond **last)
|
|
||||||
{
|
|
||||||
Cond *c, *cc, **l;
|
|
||||||
char *e;
|
|
||||||
struct field *f;
|
|
||||||
|
|
||||||
skipempty();
|
|
||||||
if(!isspace(*pos))
|
|
||||||
return 0;
|
|
||||||
l = nil;
|
|
||||||
for(;;){
|
|
||||||
while(isspace(*pos) && *pos != '\n')
|
|
||||||
pos++;
|
|
||||||
if(*pos == '\n' || *pos == '#')
|
|
||||||
return 1;
|
|
||||||
e = pos;
|
|
||||||
while(*e != 0 && *e != '\n' && *e != '=')
|
|
||||||
e++;
|
|
||||||
if(*e != '=')
|
|
||||||
return -1;
|
|
||||||
c = mallocz(sizeof(*c), 1);
|
|
||||||
if(c == nil)
|
|
||||||
sysfatal("malloc: %r");
|
|
||||||
for(f = fields; f->s != nil; f++)
|
|
||||||
if(strlen(f->s) == e - pos && strncmp(pos, f->s, e - pos) == 0){
|
|
||||||
c->field = (int)((char*)f->v - (char*)&dummy);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(f->s == nil)
|
|
||||||
goto Error;
|
|
||||||
pos = e + 1;
|
|
||||||
c->value = strtol(pos, &e, 0);
|
|
||||||
if(pos == e)
|
|
||||||
goto Error;
|
|
||||||
pos = e;
|
|
||||||
if(l != nil)
|
|
||||||
*l = c;
|
|
||||||
else if(*last){
|
|
||||||
for(cc = *last; cc != nil; cc = cc->and)
|
|
||||||
cc->or = c;
|
|
||||||
*last = c;
|
|
||||||
}else
|
|
||||||
*last = r->cond = c;
|
|
||||||
l = &c->and;
|
|
||||||
}
|
|
||||||
Error:
|
|
||||||
free(c);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
parserule(void)
|
|
||||||
{
|
|
||||||
Rule *r;
|
|
||||||
int rc;
|
|
||||||
Cond *c;
|
|
||||||
|
|
||||||
skipempty();
|
|
||||||
if(*pos == 0)
|
|
||||||
return 0;
|
|
||||||
if(isspace(*pos))
|
|
||||||
return -1;
|
|
||||||
r = mallocz(sizeof(*r), 1);
|
|
||||||
if(r == nil)
|
|
||||||
sysfatal("malloc: %r");
|
|
||||||
parsesh(&r->argc, &r->argv);
|
|
||||||
c = nil;
|
|
||||||
do
|
|
||||||
rc = parsecond(r, &c);
|
|
||||||
while(rc > 0);
|
|
||||||
if(rc < 0)
|
|
||||||
return -1;
|
|
||||||
if(rulefirst != nil)
|
|
||||||
rulelast->next = r;
|
|
||||||
else
|
|
||||||
rulefirst = r;
|
|
||||||
rulelast = r;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
freerules(void)
|
|
||||||
{
|
|
||||||
Rule *r, *rr;
|
|
||||||
Cond *c, *cc;
|
|
||||||
|
|
||||||
wlock(&rulelock);
|
|
||||||
for(r = rulefirst; r != nil; r = rr){
|
|
||||||
for(c = r->cond; c != nil; c = cc){
|
|
||||||
cc = c->and;
|
|
||||||
if(cc == nil)
|
|
||||||
cc = c->or;
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
rr = r->next;
|
|
||||||
free(r);
|
|
||||||
}
|
|
||||||
rulefirst = rulelast = nil;
|
|
||||||
wunlock(&rulelock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
printrules(void)
|
|
||||||
{
|
|
||||||
Rule *r;
|
|
||||||
Cond *c;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(r = rulefirst; r != nil; r = r->next){
|
|
||||||
for(i = 0; i < r->argc; i++)
|
|
||||||
print("[%s] ", r->argv[i]);
|
|
||||||
print("\n\t");
|
|
||||||
for(c = r->cond; c != nil; ){
|
|
||||||
print("%d=%ud", c->field, c->value);
|
|
||||||
if(c->and == nil){
|
|
||||||
print("\n\t");
|
|
||||||
c = c->or;
|
|
||||||
}else{
|
|
||||||
print(" ");
|
|
||||||
c = c->and;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
parserules(char *s)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
freerules();
|
|
||||||
lineno = 1;
|
|
||||||
pos = s;
|
|
||||||
do
|
|
||||||
rc = parserule();
|
|
||||||
while(rc > 0);
|
|
||||||
if(rc < 0)
|
|
||||||
sysfatal("syntax error in line %d", lineno);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rule *
|
|
||||||
rulesmatch(Usbdev *dev)
|
|
||||||
{
|
|
||||||
Rule *r;
|
|
||||||
Cond *c;
|
|
||||||
|
|
||||||
for(r = rulefirst; r != nil; r = r->next){
|
|
||||||
c = r->cond;
|
|
||||||
while(c){
|
|
||||||
if(*(u32int*)((char*)dev + c->field) == c->value){
|
|
||||||
if(c->and == nil)
|
|
||||||
goto yes;
|
|
||||||
c = c->and;
|
|
||||||
}else
|
|
||||||
c = c->or;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yes:
|
|
||||||
return r;
|
|
||||||
}
|
|
|
@ -7,87 +7,272 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
char *luser;
|
enum {
|
||||||
char *rules;
|
Qroot,
|
||||||
|
Qusbevent,
|
||||||
|
Qmax
|
||||||
|
};
|
||||||
|
|
||||||
|
char *names[] = {
|
||||||
|
"",
|
||||||
|
"usbevent",
|
||||||
|
};
|
||||||
|
|
||||||
static File *usbdb;
|
|
||||||
static char Enonexist[] = "does not exist";
|
static char Enonexist[] = "does not exist";
|
||||||
|
|
||||||
|
typedef struct Event Event;
|
||||||
|
|
||||||
|
struct Event {
|
||||||
|
char *data;
|
||||||
|
int len;
|
||||||
|
Event *link;
|
||||||
|
int ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Event *evfirst, *evlast;
|
||||||
|
static Req *reqfirst, *reqlast;
|
||||||
|
static QLock evlock;
|
||||||
|
|
||||||
|
static void
|
||||||
|
addreader(Req *req)
|
||||||
|
{
|
||||||
|
req->aux = nil;
|
||||||
|
if(reqfirst == nil)
|
||||||
|
reqfirst = req;
|
||||||
|
else
|
||||||
|
reqlast->aux = req;
|
||||||
|
reqlast = req;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fulfill(Req *req, Event *e)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = e->len;
|
||||||
|
if(n > req->ifcall.count)
|
||||||
|
n = req->ifcall.count;
|
||||||
|
memmove(req->ofcall.data, e->data, n);
|
||||||
|
req->ofcall.count = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initevent(void)
|
||||||
|
{
|
||||||
|
evfirst = mallocz(sizeof(*evfirst), 1);
|
||||||
|
if(evfirst == nil)
|
||||||
|
sysfatal("malloc: %r");
|
||||||
|
evlast = evfirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
readevent(Req *req)
|
||||||
|
{
|
||||||
|
Event *e;
|
||||||
|
|
||||||
|
qlock(&evlock);
|
||||||
|
e = req->fid->aux;
|
||||||
|
if(e == evlast){
|
||||||
|
addreader(req);
|
||||||
|
qunlock(&evlock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fulfill(req, e);
|
||||||
|
req->fid->aux = e->link;
|
||||||
|
e->link->ref++;
|
||||||
|
if(--e->ref == 0 && e == evfirst){
|
||||||
|
evfirst = e->link;
|
||||||
|
free(e->data);
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
qunlock(&evlock);
|
||||||
|
respond(req, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushevent(char *data)
|
||||||
|
{
|
||||||
|
Event *e, *ee;
|
||||||
|
Req *r, *rr;
|
||||||
|
|
||||||
|
qlock(&evlock);
|
||||||
|
e = evlast;
|
||||||
|
ee = emallocz(sizeof(Event), 1);
|
||||||
|
if(ee == nil)
|
||||||
|
sysfatal("malloc: %r");
|
||||||
|
evlast = ee;
|
||||||
|
e->data = data;
|
||||||
|
e->len = strlen(data);
|
||||||
|
e->link = ee;
|
||||||
|
for(r = reqfirst; r != nil; r = rr){
|
||||||
|
rr = r->aux;
|
||||||
|
r->aux = nil;
|
||||||
|
r->fid->aux = ee;
|
||||||
|
ee->ref++;
|
||||||
|
e->ref--;
|
||||||
|
fulfill(r, e);
|
||||||
|
respond(r, nil);
|
||||||
|
}
|
||||||
|
if(e->ref == 0 && e == evfirst){
|
||||||
|
evfirst = ee;
|
||||||
|
free(e->data);
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
reqfirst = nil;
|
||||||
|
reqlast = nil;
|
||||||
|
qunlock(&evlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dirgen(int n, Dir *d, void *)
|
||||||
|
{
|
||||||
|
if(n >= Qmax - 1)
|
||||||
|
return -1;
|
||||||
|
d->qid.path = n + 1;
|
||||||
|
d->qid.vers = 0;
|
||||||
|
if(n >= 0)
|
||||||
|
d->qid.type = 0;
|
||||||
|
else
|
||||||
|
d->qid.type = QTDIR;
|
||||||
|
d->uid = strdup(getuser());
|
||||||
|
d->gid = strdup(d->uid);
|
||||||
|
d->muid = strdup(d->uid);
|
||||||
|
d->name = strdup(names[n+1]);
|
||||||
|
d->mode = 0555 | (d->qid.type << 24);
|
||||||
|
d->atime = d->mtime = time(0);
|
||||||
|
d->length = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usbdattach(Req *req)
|
||||||
|
{
|
||||||
|
req->fid->qid = (Qid) {Qroot, 0, QTDIR};
|
||||||
|
req->ofcall.qid = req->fid->qid;
|
||||||
|
respond(req, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
usbdwalk(Fid *fid, char *name, Qid *qid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(strcmp(name, "..") == 0){
|
||||||
|
fid->qid = (Qid) {Qroot, 0, QTDIR};
|
||||||
|
*qid = fid->qid;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(fid->qid.path != Qroot)
|
||||||
|
return "not a directory";
|
||||||
|
for(i = 0; i < Qmax; i++)
|
||||||
|
if(strcmp(name, names[i]) == 0){
|
||||||
|
fid->qid = (Qid) {i, 0, 0};
|
||||||
|
*qid = fid->qid;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return "does not exist";
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usbdread(Req *req)
|
usbdread(Req *req)
|
||||||
{
|
{
|
||||||
if(usbdb->qid.path == req->fid->qid.path){
|
switch((long)req->fid->qid.path){
|
||||||
readstr(req, rules);
|
case Qroot:
|
||||||
|
dirread9p(req, dirgen, nil);
|
||||||
respond(req, nil);
|
respond(req, nil);
|
||||||
return;
|
break;
|
||||||
|
case Qusbevent:
|
||||||
|
readevent(req);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
respond(req, Enonexist);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
respond(req, Enonexist);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usbdstat(Req *req)
|
||||||
|
{
|
||||||
|
if(dirgen(req->fid->qid.path - 1, &req->d, nil) < 0)
|
||||||
|
respond(req, "the front fell off");
|
||||||
|
else
|
||||||
|
respond(req, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usbdopen(Req *req)
|
||||||
|
{
|
||||||
|
if(req->fid->qid.path == Qusbevent){
|
||||||
|
qlock(&evlock);
|
||||||
|
req->fid->aux = evlast;
|
||||||
|
evlast->ref++;
|
||||||
|
qunlock(&evlock);
|
||||||
|
}
|
||||||
|
respond(req, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usbddestroyfid(Fid *fid)
|
||||||
|
{
|
||||||
|
Event *e, *ee;
|
||||||
|
|
||||||
|
if(fid->qid.path == Qusbevent){
|
||||||
|
qlock(&evlock);
|
||||||
|
e = fid->aux;
|
||||||
|
if(--e->ref == 0 && e == evfirst){
|
||||||
|
while(e->ref == 0 && e != evlast){
|
||||||
|
ee = e->link;
|
||||||
|
free(e->data);
|
||||||
|
free(e);
|
||||||
|
e = ee;
|
||||||
|
}
|
||||||
|
evfirst = e;
|
||||||
|
}
|
||||||
|
qunlock(&evlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usbdflush(Req *req)
|
||||||
|
{
|
||||||
|
Req **l, *r;
|
||||||
|
qlock(&evlock);
|
||||||
|
l = &reqfirst;
|
||||||
|
while(r = *l){
|
||||||
|
if(r == req->oldreq){
|
||||||
|
*l = r->aux;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l = &r->aux;
|
||||||
|
}
|
||||||
|
qunlock(&evlock);
|
||||||
|
respond(req->oldreq, "interrupted");
|
||||||
|
respond(req, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
Srv usbdsrv = {
|
Srv usbdsrv = {
|
||||||
|
.attach = usbdattach,
|
||||||
|
.walk1 = usbdwalk,
|
||||||
.read = usbdread,
|
.read = usbdread,
|
||||||
|
.stat = usbdstat,
|
||||||
|
.open = usbdopen,
|
||||||
|
.flush = usbdflush,
|
||||||
|
.destroyfid = usbddestroyfid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
readrules(void)
|
|
||||||
{
|
|
||||||
int fd, rc, n;
|
|
||||||
char buf[4096];
|
|
||||||
|
|
||||||
fd = open("/lib/usbdb", OREAD);
|
|
||||||
if(fd < 0)
|
|
||||||
sysfatal("open /lib/usbdb: %r");
|
|
||||||
rules = nil;
|
|
||||||
n = 0;
|
|
||||||
for(;;){
|
|
||||||
rc = readn(fd, buf, sizeof buf);
|
|
||||||
if(rc == 0)
|
|
||||||
break;
|
|
||||||
if(rc < 0)
|
|
||||||
sysfatal("read: %r");
|
|
||||||
rules = realloc(rules, 1 + n + rc);
|
|
||||||
if(rules == nil)
|
|
||||||
sysfatal("realloc: %r");
|
|
||||||
memmove(rules + n, buf, rc);
|
|
||||||
n += rc;
|
|
||||||
rules[n] = 0;
|
|
||||||
}
|
|
||||||
if(rules == nil)
|
|
||||||
rules = "";
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
startdev(Port *p)
|
startdev(Port *p)
|
||||||
{
|
{
|
||||||
Rule *r;
|
Dev *d;
|
||||||
char buf[14];
|
Usbdev *u;
|
||||||
|
|
||||||
if(p->dev == nil || p->dev->usb == nil){
|
if((d = p->dev) == nil || (u = p->dev->usb) == nil){
|
||||||
fprint(2, "okay what?\n");
|
fprint(2, "okay what?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rlock(&rulelock);
|
pushevent(smprint("in id %d vid 0x%.4x did 0x%.4x csp 0x%.8x\n",
|
||||||
r = rulesmatch(p->dev->usb);
|
d->id, u->vid, u->did, u->csp));
|
||||||
if(r == nil || r->argv == nil){
|
|
||||||
fprint(2, "no driver for device\n");
|
|
||||||
runlock(&rulelock);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
snprint(buf, sizeof buf, "%d", p->dev->id);
|
|
||||||
r->argv[r->argc] = buf;
|
|
||||||
closedev(p->dev);
|
closedev(p->dev);
|
||||||
switch(fork()){
|
|
||||||
case -1:
|
|
||||||
fprint(2, "fork: %r");
|
|
||||||
runlock(&rulelock);
|
|
||||||
return -1;
|
|
||||||
case 0:
|
|
||||||
chdir("/bin");
|
|
||||||
exec(r->argv[0], r->argv);
|
|
||||||
sysfatal("exec: %r");
|
|
||||||
}
|
|
||||||
runlock(&rulelock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,13 +281,9 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int fd, i, nd;
|
int fd, i, nd;
|
||||||
Dir *d;
|
Dir *d;
|
||||||
|
|
||||||
readrules();
|
|
||||||
parserules(rules);
|
|
||||||
luser = getuser();
|
|
||||||
|
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
|
initevent();
|
||||||
rfork(RFNOTEG);
|
rfork(RFNOTEG);
|
||||||
switch(rfork(RFPROC|RFMEM)){
|
switch(rfork(RFPROC|RFMEM)){
|
||||||
case -1: sysfatal("rfork: %r");
|
case -1: sysfatal("rfork: %r");
|
||||||
|
@ -124,7 +305,5 @@ main(int argc, char **argv)
|
||||||
for(i = 0; i < argc; i++)
|
for(i = 0; i < argc; i++)
|
||||||
rendezvous(work, strdup(argv[i]));
|
rendezvous(work, strdup(argv[i]));
|
||||||
rendezvous(work, nil);
|
rendezvous(work, nil);
|
||||||
usbdsrv.tree = alloctree(luser, luser, 0555, nil);
|
|
||||||
usbdb = createfile(usbdsrv.tree->root, "usbdb", luser, 0775, nil);
|
|
||||||
postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");
|
postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue