git: 9front

Download patch

ref: 72391e05ef52004a927da342c7d201d5222d40c1
parent: c54b8326b7db414b1e2980b653f7e485c421f8c4
author: aiju <aiju@phicode.de>
date: Wed Jul 27 10:27:22 EDT 2011

started work on new usbd

--- /dev/null
+++ b/lib/usbdb
@@ -1,0 +1,5 @@
+nusb/disk
+	class=8
+
+nusb/serial
+	vid=0x9e88 did=0x9e8f
--- /dev/null
+++ b/sys/src/cmd/nusb/mkfile
@@ -1,0 +1,31 @@
+</$objtype/mkfile
+
+# order matters here.  build lib first and usbd last.
+DIRS=\
+	usbd\
+
+UPDATE=\
+	mkfile\
+
+default:V: all
+
+none:VQ:
+	echo mk all, install, installall, safeinstall, safeinstallall, clean, nuke, or update
+
+all clean nuke:VQ:
+	for (i in $DIRS) @{
+		cd $i && echo $i: && mk $target
+	}
+
+install installall safeinstall safeinstallall:V:
+	for (i in $DIRS) @{
+		cd $i && mk $target
+	}
+	cp probe /$objtype/bin/usb/probe
+
+update:V:
+	update $UPDATEFLAGS $UPDATE
+	for (i in $DIRS) @{
+		echo update $i
+		cd $i && mk 'UPDATEFLAGS='$"UPDATEFLAGS update
+	}
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/dat.h
@@ -1,0 +1,22 @@
+typedef struct Rule Rule;
+typedef struct Cond Cond;
+typedef struct Dev Dev;
+
+struct Rule {
+	char **argv;
+	int argc;
+	Cond *cond;
+	Rule *next;
+} *rulefirst, *rulelast;
+
+RWLock rulelock;
+
+struct Cond {
+	int field;
+	u32int value;
+	Cond *and, *or;
+};
+
+struct Dev {
+	u32int class, vid, did;
+};
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/fns.h
@@ -1,0 +1,2 @@
+void	parserules(char*);
+Rule*	rulesmatch(Dev*);
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/mkfile
@@ -1,0 +1,13 @@
+</$objtype/mkfile
+
+OFILES=\
+	usbd.$O\
+	rules.$O\
+
+HFILES=\
+	dat.h\
+	fns.h\
+
+TARG=usbd
+BIN=/$objtype/bin/nusb
+</sys/src/cmd/mkone
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/rules.c
@@ -1,0 +1,239 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <ctype.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 Dev dummy;
+
+struct field {
+	char *s;
+	void* v;
+} fields[] = {
+	"class", &dummy.class,
+	"vid", &dummy.vid,
+	"did", &dummy.did,
+	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(Dev *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;
+}
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/usbd.c
@@ -1,0 +1,68 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <fcall.h>
+#include <9p.h>
+#include "dat.h"
+#include "fns.h"
+
+char *luser;
+char *rules;
+
+static File *usbdb;
+static char Enonexist[] = "does not exist";
+
+static void
+usbdread(Req *req)
+{
+	if(usbdb->qid.path == req->fid->qid.path){
+		readstr(req, rules);
+		respond(req, nil);
+		return;
+	}
+	respond(req, Enonexist);
+}
+
+Srv usbdsrv = {
+	.read = usbdread,
+};
+
+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);
+}
+
+void
+main()
+{
+	readrules();
+	parserules(rules);
+	luser = getuser();
+	usbdsrv.tree = alloctree(luser, luser, 0555, nil);
+	usbdb = createfile(usbdsrv.tree->root, "usbdb", luser, 0775, nil);
+	postsharesrv(&usbdsrv, nil, "usb", "usbd", "b");
+}
--