Browse Source

Moving ratfs to legacy, it's upas family

Signed-off-by: Álvaro Jurado <elbingmiss@gmail.com>
Álvaro Jurado 6 years ago
parent
commit
9df7be49db

+ 0 - 15
sys/src/cmd/proof/mkfile

@@ -1,15 +0,0 @@
-</$objtype/mkfile
-
-TARG=proof
-OFILES=main.$O\
-	font.$O\
-	htroff.$O\
-	screen.$O\
-
-HFILES=proof.h
-
-BIN=/$objtype/bin
-</sys/src/cmd/mkone
-
-$O.pout: $OFILES
-	$LD -o $O.pout -p $OFILES

+ 0 - 406
sys/src/cmd/ratfs/ctlfiles.c

@@ -1,406 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "ratfs.h"
-#include <ip.h>
-
-enum {
-	ACCEPT = 0,		/* verbs in control file */
-	REFUSED,
-	DENIED,
-	DIALUP,
-	BLOCKED,
-	DELAY,
-	NONE,
-
-	Subchar	=	'#',	/* character substituted for '/' in file names */
-};
-
-static	Keyword actions[] = {
-	"allow",		ACCEPT,
-	"accept",		ACCEPT,
-	"block",		BLOCKED,
-	"deny",			DENIED,
-	"dial",			DIALUP,
-	"relay",		DELAY,
-	"delay",		DELAY,
-	0,			NONE,
-};
-
-static void	acctinsert(Node*, char*);
-static char*	getline(Biobuf*);
-static void	ipinsert(Node*, char*);
-static void	ipsort(void);
-
-/*
- *	Input the configuration file
- *	Currently we only process the "ournets"
- *	specification.
- */
-void
-getconf(void)
-{
-	Biobuf *bp;
-	char *cp;
-	Node *np, *dir, **l;
-
-	if(debugfd >= 0)
-		fprint(debugfd, "loading %s\n", conffile);
-
-	bp = Bopen(conffile, OREAD);
-	if(bp == 0)
-		return;
-
-	dir = finddir(Trusted);
-	if(dir == 0)
-		return;
-
-	/*
-	 * if this isn't the first time, purge permanent entries
-	 */
-	trustedqid = Qtrustedfile;
-	if(lastconftime){
-		l = &dir->children;
-		for(np = dir->children; np; np = *l){
-			if(np->d.type == Trustedperm){
-				*l = np->sibs;
-				free(np);
-			} else {
-				np->d.qid.path = trustedqid++;
-				l = &np->sibs;
-			}
-		}
-		dir->count = 0;
-	}
-
-	for(;;){
-		cp = getline(bp);
-		if(cp == 0)
-			break;
-		if (strcmp(cp, "ournets") == 0){
-			for(cp += strlen(cp)+1; cp && *cp; cp += strlen(cp)+1){
-				np = newnode(dir, cp, Trustedperm, 0111, trustedqid++);
-				cidrparse(&np->ip, cp);
-				subslash(cp);
-				np->d.name = atom(cp);
-			}
-		}
-	}
-	Bterm(bp);
-	lastconftime = time(0);
-}
-
-/*
- *	Reload the control file, if necessary
- */
-void
-reload(void)
-{
-	int type, action;
-	Biobuf *bp;
-	char *cp;
-	Node *np, *dir;
-
-	if(debugfd >= 0)
-		fprint(debugfd,"loading %s\n", ctlfile);
-
-	bp = Bopen(ctlfile, OREAD);
-	if(bp == 0)
-		return;
-
-	if(lastctltime){
-		for(dir = root->children; dir; dir = dir->sibs){
-			if (dir->d.type != Addrdir)
-				continue;
-			for(np = dir->children; np; np = np->sibs)
-				np->count = 0;
-		}
-	}
-
-	for(;;){
-		cp = getline(bp);
-		if(cp == 0)
-			break;
-		type = *cp;
-		if(type == '*'){
-			cp++;
-			if(*cp == 0)		/* space before keyword */
-				cp++;
-		}
-		action = findkey(cp, actions);
-		if (action == NONE)
-			continue;
-		if (action == ACCEPT)
-			dir = dirwalk("allow", root);
-		else
-		if (action == DELAY)
-			dir = dirwalk("delay", root);
-		else
-			dir = dirwalk(cp, root);
-		if(dir == 0)
-			continue;
-
-		for(cp += strlen(cp)+1; cp && *cp; cp += strlen(cp)+1){
-			if(type == '*')
-				acctinsert(dir, cp);
-			else
-				ipinsert(dir, cp);
-		}
-	}
-	Bterm(bp);
-	ipsort();
-	dummy.d.mtime = dummy.d.atime = lastctltime = time(0);
-}
-
-/*
- * get a canonicalized line: a string of null-terminated lower-case
- * tokens with a two null bytes at the end.
- */
-static char*
-getline(Biobuf *bp)
-{
-	char c, *cp, *p, *q;
-	int n;
-
-	static char *buf;
-	static int bufsize;
-
-	for(;;){
-		cp = Brdline(bp, '\n');
-		if(cp == 0)
-			return 0;
-		n = Blinelen(bp);
-		cp[n-1] = 0;
-		if(buf == 0 || bufsize < n+1){
-			bufsize += 512;
-			if(bufsize < n+1)
-				bufsize = n+1;
-			buf = realloc(buf, bufsize);
-			if(buf == 0)
-				break;
-		}
-		q = buf;
-		for (p = cp; *p; p++){
-			c = *p;
-			if(c == '\\' && p[1])	/* we don't allow \<newline> */
-				c = *++p;
-			else
-			if(c == '#')
-				break;
-			else
-			if(c == ' ' || c == '\t' || c == ',')
-				if(q == buf || q[-1] == 0)
-					continue;
-				else
-					c = 0;
-			*q++ = tolower(c);
-		}
-		if(q != buf){
-			if(q[-1])
-				*q++ = 0;
-			*q = 0;
-			break;
-		}
-	}
-	return buf;
-}
-
-/*
- *	Match a keyword
- */
-int
-findkey(char *val, Keyword *p)
-{
-
-	for(; p->name; p++)
-		if(strcmp(val, p->name) == 0)
-				break;
-	return p->code;
-}
-
-/*
- *	parse a cidr specification in either IP/mask or IP#mask format
- */
-void
-cidrparse(Cidraddr *cidr, char *cp)
-{
-
-	char *p, *slash;
-	int c;
-	uint32_t a, m;
-	uint8_t addr[IPv4addrlen];
-	uint8_t mask[IPv4addrlen];
-	char buf[64];
-
-	/*
-	 * find '/' or '#' character in the cidr specification
-	 */
-	slash = 0;
-	for(p = buf; p < buf+sizeof(buf)-1 && *cp; p++) {
-		c = *cp++;
-		switch(c) {
-		case Subchar:
-			c = '/';
-			slash = p;
-			break;
-		case '/':
-			slash = p;
-			break;
-		default:
-			break;
-		}
-		*p = c;
-	}
-	*p = 0;
-
-	v4parsecidr(addr, mask, buf);
-	a = nhgetl(addr);
-	m = nhgetl(mask);
-	/*
-	 * if a mask isn't specified, we build a minimal mask
-	 * instead of using the default mask for that net.  in this
-	 * case we never allow a class A mask (0xff000000).
-	 */
-	if(slash == 0){
-		m = 0xff000000;
-		p = buf;
-		for(p = strchr(p, '.'); p && p[1]; p = strchr(p+1, '.'))
-				m = (m>>8)|0xff000000;
-
-		/* force at least a class B */
-		m |= 0xffff0000;
-	}
-	cidr->ipaddr = a;
-	cidr->mask = m;
-}
-
-/*
- *	Substitute Subchar ('#') for '/'
- */
-char*
-subslash(char *os)
-{
-	char *s;
-
-	for(s=os; *s; s++)
-		if(*s == '/')
-			*s = Subchar;
-	return os;
-}
-
-/*
- *	Insert an account pseudo-file in a directory
- */
-static void
-acctinsert(Node *np, char *cp)
-{
-	int i;
-	char *tmp;
-	Address *ap;
-
-	static char *dangerous[] = { "*", "!", "*!", "!*", "*!*", 0 };
-
-	if(cp == 0 || *cp == 0)
-		return;
-
-	/* rule out dangerous patterns */
-	for (i = 0; dangerous[i]; i++)
-		if(strcmp(cp, dangerous[i])== 0)
-			return;
-
-	np = dirwalk("account", np);
-	if(np == 0)
-		return;
-
-	i = np->count++;
-	if(i >= np->allocated){
-		np->allocated = np->count;
-		np->addrs = realloc(np->addrs, np->allocated*sizeof(Address));
-		if(np->addrs == 0)
-			fatal("out of memory");
-	}
-
-	ap = &np->addrs[i];			/* new entry on end */
-	tmp = strdup(cp);
-	if(tmp == nil)
-		fatal("out of memory");
-	subslash(tmp);
-	ap->name = atom(tmp);
-	free(tmp);
-}
-
-/*
- *	Insert an IP address pseudo-file in a directory
- */
-static void
-ipinsert(Node *np, char *cp)
-{
-	char *tmp;
-	int i;
-	Address *ap;
-	if(cp == 0 || *cp == 0)
-		return;
-
-	np = dirwalk("ip", np);
-	if(np == 0)
-		return;
-
-	i = np->count++;
-	if(i >= np->allocated){
-		np->allocated = np->count;
-		np->addrs = realloc(np->addrs, np->allocated*sizeof(Address));
-		if(np->addrs == 0)
-			fatal("out of memory");
-	}
-
-	ap = &np->addrs[i];				/* new entry on end */
-	tmp = strdup(cp);
-	if(tmp == nil)
-		fatal("out of memory");
-	subslash(tmp);
-	ap->name = atom(tmp);
-	free(tmp);
-	cidrparse(&ap->ip, cp);
-}
-
-int
-ipcomp(const void *a, const void *b)
-{
-	uint32_t aip, bip;
-
-	aip = ((Address*)a)->ip.ipaddr;
-	bip = ((Address*)b)->ip.ipaddr;
-	if(aip > bip)
-		return 1;
-	if(aip < bip)
-		return -1;
-	return 0;
-}
-
-/*
- *	Sort a directory of IP addresses
- */
-static void
-ipsort(void)
-{
-	int base;
-	Node *dir, *np;
-
-	base = Qaddrfile;
-	for(dir = root->children; dir; dir = dir->sibs){
-		if (dir->d.type != Addrdir)
-			continue;
-		for(np = dir->children; np; np = np->sibs){
-			if(np->d.type == IPaddr && np->count && np->addrs)
-				qsort(np->addrs, np->count, sizeof(Address), ipcomp);
-			np->baseqid = base;
-			base += np->count;
-		}
-	}
-}

+ 0 - 326
sys/src/cmd/ratfs/main.c

@@ -1,326 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "ratfs.h"
-
-#define	SRVFILE		"/srv/ratify"
-#define MOUNTPOINT	"/mail/ratify"
-#define	CTLFILE		"/mail/lib/blocked"
-#define	CONFFILE	"/mail/lib/smtpd.conf.ext"
-
-typedef struct Filetree	Filetree;
-
-	/* prototype file tree */
-struct	Filetree
-{
-	int	level;
-	char	*name;
-	uint16_t	type;
-	int	mode;
-	uint32_t	qid;
-};
-
-	/* names of first-level directories - must be in order of level*/
-Filetree	filetree[] =
-{
-	0,	"/",		Directory,	0555|DMDIR,	Qroot,
-	1,	"allow",	Addrdir,	0555|DMDIR,	Qallow,
-	1,	"delay",	Addrdir,	0555|DMDIR,	Qdelay,
-	1,	"block",	Addrdir,	0555|DMDIR,	Qblock,
-	1,	"dial",		Addrdir,	0555|DMDIR,	Qdial,
-	1,	"deny",		Addrdir,	0555|DMDIR,	Qdeny,
-	1,	"trusted",	Trusted,	0777|DMDIR,	Qtrusted,	/* creation allowed */
-	1,	"ctl",		Ctlfile,	0222,		Qctl,
-	2,	"ip",		IPaddr,		0555|DMDIR,	Qaddr,
-	2,	"account",	Acctaddr,	0555|DMDIR,	Qaddr,
-	0,	0,		0,		0,		0,
-
-};
-
-int	debugfd = -1;
-int	trustedqid = Qtrustedfile;
-char	*ctlfile =	CTLFILE;
-char	*conffile =	CONFFILE;
-
-
-static	int	ipconv(Fmt*);
-static	void	post(int, char*);
-static	void	setroot(void);
-
-void
-usage(void)
-{
-	fprint(2, "ratfs [-d] [-c conffile] [-f ctlfile] [-m mountpoint]\n");
-	exits("usage");
-}
-
-void
-main(int argc, char *argv[])
-{
-	char *mountpoint = MOUNTPOINT;
-	int p[2];
-
-	ARGBEGIN {
-	case 'c':
-		conffile = ARGF();
-		break;
-	case 'd':
-		debugfd = 2;		/* stderr*/
-		break;
-	case 'f':
-		ctlfile = ARGF();
-		break;
-	case 'm':
-		mountpoint = ARGF();
-		break;
-	} ARGEND
-	if(argc != 0)
-		usage();
-
-	fmtinstall('I', ipconv);
-	setroot();
-	getconf();
-	reload();
-
-	/* get a pipe and mount it in /srv */
-	if(pipe(p) < 0)
-		fatal("pipe failed: %r");
-	srvfd = p[0];
-	post(p[1], mountpoint);
-
-	/* start the 9fs protocol */
-	switch(rfork(RFPROC|RFNAMEG|RFENVG|RFFDG|RFNOTEG|RFREND)){
-	case -1:
-		fatal("fork: %r");
-	case 0:
-		/* seal off standard input/output */
-		close(0);
-		open("/dev/null", OREAD);
-		close(1);
-		open("/dev/null", OWRITE);
-
-		close(p[1]);
-		fmtinstall('F', fcallfmt); /* debugging */
-		io();
-		fprint(2, "ratfs dying\n");
-		break;
-	default:
-		close(p[0]);
-		if(mount(p[1], -1, mountpoint, MREPL|MCREATE, "") < 0)
-			fatal("mount failed: %r");
-	}
-	exits(0);
-}
-
-static void
-setroot(void)
-{
-	Filetree *fp;
-	Node *np;
-	int qid;
-
-	root = 0;
-	qid = Qaddr;
-	for(fp = filetree; fp->name; fp++) {
-		switch(fp->level) {
-		case 0:		/* root */
-		case 1:		/* second level directory */
-			newnode(root, fp->name, fp->type, fp->mode, fp->qid);
-			break;
-		case 2:		/* lay down the Ipaddr and Acctaddr subdirectories */
-			for (np = root->children; np; np = np->sibs){
-				if(np->d.type == Addrdir)
-					newnode(np, fp->name, fp->type, fp->mode, qid++);
-			}
-			break;
-		default:
-			fatal("bad filetree");
-		}
-	}
-	dummy.d.type = Dummynode;
-	dummy.d.mode = 0444;
-	dummy.d.uid = "upas";
-	dummy.d.gid = "upas";
-	dummy.d.atime = dummy.d.mtime = time(0);
-	dummy.d.qid.path = Qdummy;				/* for now */
-}
-
-static void
-post(int fd, char *mountpoint)
-{
-
-	int f;
-	char buf[128];
-
-	if(access(SRVFILE,0) >= 0){
-		/*
-		 * If we can open and mount the /srv node,
-		 * another server is already running, so just exit.
-		 */
-		f = open(SRVFILE, ORDWR);
-		if(f >= 0 && mount(f, -1, mountpoint, MREPL|MCREATE, "", 'M') >= 0){
-				unmount(0, mountpoint);
-				close(f);
-				exits(0);
-		}
-		remove(SRVFILE);
-	}
-
-	/*
-	 * create the server node and post our pipe to it
-	 */
-	f = create(SRVFILE, OWRITE, 0666);
-	if(f < 0)
-		fatal("can't create %s", SRVFILE);
-
-	sprint(buf, "%d", fd);
-	if(write(f, buf, strlen(buf)) != strlen(buf))
-		fatal("can't write %s", SRVFILE);
-
-	close(f);
-}
-
-/*
- *  print message and die
- */
-void
-fatal(char *fmt, ...)
-{
-	va_list arg;
-	char buf[8*1024];
-
-	va_start(arg, fmt);
-	vseprint(buf, buf + (sizeof(buf)-1) / sizeof(*buf), fmt, arg);
-	va_end(arg);
-
-	fprint(2, "%s: %s\n", argv0, buf);
-	exits(buf);
-}
-
-/*
- *  create a new directory node
- */
-Node*
-newnode(Node *parent, char *name, uint16_t type, int mode, uint32_t qid)
-{
-	Node *np;
-
-	np = mallocz(sizeof(Node), 1);
-	if(np == 0)
-		fatal("out of memory");
-	np->d.name = atom(name);
-	np->d.type = type;
-	np->d.mode = mode;
-	np->d.mtime = np->d.atime = time(0);
-	np->d.uid = atom("upas");
-	np->d.gid = atom("upas");
-	np->d.muid = atom("upas");
-	if(np->d.mode&DMDIR)
-		np->d.qid.type = QTDIR;
-	np->d.qid.path = qid;
-	np->d.qid.vers = 0;
-	if(parent){
-		np->parent = parent;
-		np->sibs = parent->children;
-		parent->children = np;
-		parent->count++;
-	} else {
-		/* the root node */
-		root = np;
-		np->parent = np;
-		np->children = 0;
-		np->sibs = 0;
-	}
-	return np;
-}
-
-void
-printnode(Node *np)
-{
-	fprint(debugfd, "Node at %p: %s (%s %s)", np, np->d.name, np->d.uid, np->d.gid);
-	if(np->d.qid.type&QTDIR)
-		fprint(debugfd, " QTDIR");
-	fprint(debugfd, "\n");
-	fprint(debugfd,"\tQID: %llu.%lu Mode: %lo Type: %d\n", np->d.qid.path,
-			np->d.qid.vers, np->d.mode, np->d.type);
-	fprint(debugfd, "\tMod: %.15s  Acc: %.15s Count: %d\n", ctime(np->d.mtime)+4,
-			ctime(np->d.atime)+4, np->count);
-	switch(np->d.type)
-	{
-	case Directory:
-		fprint(debugfd, "\tDirectory Child: %p", np->children);
-		break;
-	case Addrdir:
-		fprint(debugfd, "\tAddrdir Child: %p", np->children);
-		break;
-	case IPaddr:
-		fprint(debugfd, "\tIPaddr Base: %p Alloc: %d BaseQid %lu", np->addrs,
-			np->allocated, np->baseqid);
-		break;
-	case Acctaddr:
-		fprint(debugfd, "\tAcctaddr Base: %p Alloc: %d BaseQid %lu", np->addrs,
-			np->allocated, np->baseqid);
-		break;
-	case Trusted:
-		fprint(debugfd, "\tTrusted Child: %p", np->children);
-		break;
-	case Trustedperm:
-		fprint(debugfd, "\tPerm Trustedfile: %I", &np->ip);
-		break;
-	case Trustedtemp:
-		fprint(debugfd, "\tTemp Trustedfile: %I", &np->ip);
-		break;
-	case Ctlfile:
-		fprint(debugfd, "\tCtlfile");
-		break;
-	case Dummynode:
-		fprint(debugfd, "\tDummynode");
-		break;
-	default:
-		fprint(debugfd, "\tUnknown Node Type\n\n");
-		return;
-	}
-	fprint(debugfd, " Parent %p Sib: %p\n\n", np->parent, np->sibs);
-}
-
-void
-printfid(Fid *fp)
-{
-	fprint(debugfd, "FID: %d (%s %s) Busy: %d Open: %d\n", fp->fid, fp->name,
-		fp->uid, fp->busy, fp->open);
-	printnode(fp->node);
-}
-
-void
-printtree(Node *np)
-{
-	printnode(np);
-	if(np->d.type == IPaddr
-		|| np->d.type == Acctaddr
-		|| np->d.type == Trustedperm
-		|| np->d.type == Trustedtemp)
-			return;
-	for (np = np->children; np; np = np->sibs)
-		printtree(np);
-}
-
-static int
-ipconv(Fmt *f)
-{
-	Cidraddr *ip;
-	int i, j;
-	char *p;
-
-	ip = va_arg(f->args, Cidraddr*);
-	p = (char*)&ip->ipaddr;
-	i = 0;
-	for (j = ip->mask; j; j <<= 1)
-		i++;
-	return fmtprint(f, "%d.%d.%d.%d/%d", p[3]&0xff, p[2]&0xff, p[1]&0xff, p[0]&0xff, i);
-}

+ 0 - 476
sys/src/cmd/ratfs/misc.c

@@ -1,476 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "ratfs.h"
-#include <ip.h>
-
-enum {
-	Maxdoms	=	10,		/* max domains in a path */
-	Timeout =	2*60*60,	/* seconds until temporarily trusted addr times out */
-};
-
-static	int	accountmatch(char*, char**, int, char*);
-static	Node*	acctwalk(char*,  Node*);
-static	int	dommatch(char*, char*);
-static	Address* ipsearch(uint32_t, Address*, int);
-static	Node*	ipwalk(char*,  Node*);
-static	Node*	trwalk(char*, Node*);
-static	int	usermatch(char*, char*);
-
-/*
- *	Do a walk
- */
-char*
-walk(char *name, Fid *fidp)
-{
-	Node *np;
-
-	if((fidp->node->d.mode & DMDIR) == 0)
-		return "not a directory";
-
-	if(strcmp(name, ".") == 0)
-		return 0;
-	if(strcmp(name, "..") == 0){
-		fidp->node = fidp->node->parent;
-		fidp->name = 0;
-		return 0;
-	}
-
-	switch(fidp->node->d.type){
-	case Directory:
-	case Addrdir:
-		np = dirwalk(name, fidp->node);
-		break;
-	case Trusted:
-		np = trwalk(name, fidp->node);
-		break;
-	case IPaddr:
-		np = ipwalk(name, fidp->node);
-		break;
-	case Acctaddr:
-		np = acctwalk(name, fidp->node);
-		break;
-	default:
-		return "directory botch in walk";
-	}
-	if(np) {
-		fidp->node = np;
-		fidp->name = np->d.name;
-		return 0;
-	}
-	return "file does not exist";
-}
-
-/*
- *	Walk to a subdirectory
- */
-Node*
-dirwalk(char *name, Node *np)
-{
-	Node *p;
-
-	for(p = np->children; p; p = p->sibs)
-		if(strcmp(name, p->d.name) == 0)
-			break;
-	return p;
-}
-
-/*
- *	Walk the directory of trusted files
- */
-static Node*
-trwalk(char *name, Node *np)
-{
-	Node *p;
-	uint32_t peerip;
-	uint8_t addr[IPv4addrlen];
-
-	v4parseip(addr, name);
-	peerip = nhgetl(addr);
-
-	for(p = np->children; p; p = p->sibs)
-		if((peerip&p->ip.mask) == p->ip.ipaddr)
-			break;
-	return p;
-}
-
-/*
- *	Walk a directory of IP addresses
- */
-static Node*
-ipwalk(char *name,  Node *np)
-{
-	Address *ap;
-	uint32_t peerip;
-	uint8_t addr[IPv4addrlen];
-
-	v4parseip(addr, name);
-	peerip = nhgetl(addr);
-
-	if(debugfd >= 0)
-		fprint(debugfd, "%d.%d.%d.%d - ", addr[0]&0xff, addr[1]&0xff,
-				addr[2]&0xff, addr[3]&0xff);
-	ap = ipsearch(peerip, np->addrs, np->count);
-	if(ap == 0)
-		return 0;
-
-	dummy.d.name = ap->name;
-	return &dummy;
-}
-
-/*
- *	Walk a directory of account names
- */
-static Node*
-acctwalk(char *name, Node *np)
-{
-	int i, n;
-	Address *ap;
-	char *p, *cp, *user;
-	char buf[512];
-	char *doms[Maxdoms];
-
-	strecpy(buf, buf+sizeof buf, name);
-	subslash(buf);
-
-	p = buf;
-	for(n = 0; n < Maxdoms; n++) {
-		cp = strchr(p, '!');
-		if(cp == 0)
-			break;
-		*cp = 0;
-		doms[n] = p;
-		p = cp+1;
-	}
-	user = p;
-
-	for(i = 0; i < np->count; i++){
-		ap = &np->addrs[i];
-		if (accountmatch(ap->name, doms, n, user)) {
-			dummy.d.name = ap->name;
-			return &dummy;
-		}
-	}
-	return 0;
-}
-
-/*
- * binary search sorted IP address list
- */
-
-static Address*
-ipsearch(uint32_t addr, Address *base, int n)
-{
-	uint32_t top, bot, mid;
-	Address *ap;
-
-	bot = 0;
-	top = n;
-	for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
-		ap = &base[mid];
-		if((addr&ap->ip.mask) == ap->ip.ipaddr)
-			return ap;
-		if(addr < ap->ip.ipaddr)
-			top = mid;
-		else if(mid != n-1 && addr >= base[mid+1].ip.ipaddr)
-			bot = mid;
-		else
-			break;
-	}
-	return 0;
-}
-
-/*
- *	Read a directory
- */
-int
-dread(Fid *fidp, int cnt)
-{
-	uint8_t *q, *eq, *oq;
-	int n, skip;
-	Node *np;
-
-	if(debugfd >= 0)
-		fprint(debugfd, "dread %d\n", cnt);
-
-	np = fidp->node;
-	oq = q = rbuf+IOHDRSZ;
-	eq = q+cnt;
-	if(fidp->dirindex >= np->count)
-		return 0;
-
-	skip = fidp->dirindex;
-	for(np = np->children; skip > 0 && np; np = np->sibs)
-		skip--;
-	if(np == 0)
-		return 0;
-
-	for(; q < eq && np; np = np->sibs){
-		if(debugfd >= 0)
-			printnode(np);
-		if((n=convD2M(&np->d, q, eq-q)) <= BIT16SZ)
-			break;
-		q += n;
-		fidp->dirindex++;
-	}
-	return q - oq;
-}
-
-/*
- *	Read a directory of IP addresses or account names
- */
-int
-hread(Fid *fidp, int cnt)
-{
-	uint8_t *q, *eq, *oq;
-	int i, n, path;
-	Address *p;
-	Node *np;
-
-	if(debugfd >= 0)
-		fprint(debugfd, "hread %d\n", cnt);
-
-	np = fidp->node;
-	oq = q = rbuf+IOHDRSZ;
-	eq = q+cnt;
-	if(fidp->dirindex >= np->count)
-		return 0;
-
-	path = np->baseqid;
-	for(i = fidp->dirindex; q < eq && i < np->count; i++){
-		p = &np->addrs[i];
-		dummy.d.name = p->name;
-		dummy.d.qid.path = path++;
-		if((n=convD2M(&dummy.d, q, eq-q)) <= BIT16SZ)
-			break;
-		q += n;
-	}
-	fidp->dirindex = i;
-	return q - oq;
-}
-
-/*
- *	Find a directory node by type
- */
-Node*
-finddir(int type)
-{
-	Node *np;
-
-	for(np = root->children; np; np = np->sibs)
-		if (np->d.type == type)
-			return np;
-	return 0;
-}
-
-/*
- *	Remove temporary pseudo-files that have timed-out
- *	from the trusted directory
- */
-void
-cleantrusted(void)
-{
-	Node *np, **l;
-	uint32_t t;
-
-	np = finddir(Trusted);
-	if (np == 0)
-		return;
-
-	t = time(0)-Timeout;
-	l = &np->children;
-	for (np = np->children; np; np = *l) {
-		if(np->d.type == Trustedtemp && t >= np->d.mtime) {
-			*l = np->sibs;
-			if(debugfd >= 0)
-				fprint(debugfd, "Deleting %s\n", np->d.name);
-			np->parent->count--;
-			free(np);
-		} else
-			l = &np->sibs;
-	}
-}
-
-/*
- * match path components to prohibited domain & user specifications.  patterns include:
- *	domain, domain! or domain!*	  - all users in domain
- *	*.domain, *.domain! or *.domain!* - all users in domain and its subdomains
- *	!user or *!user			  - user in all domains
- *	domain!user			  - user in domain
- *	*.domain!user			  - user in domain and its subdomains
- *
- *	if "user" has a trailing '*', it matches all user names beginning with "user"
- *
- * there are special semantics for the "domain, domain! or domain!*" specifications:
- * the first two forms match when the domain is anywhere in at list of source-routed
- * domains while the latter matches only when the domain is the last hop.  the same is
- * true for the *.domain!* form of the pattern.
- */
-static int
-accountmatch(char *spec, char **doms, int ndoms, char *user)
-{
-	char *cp, *userp;
-	int i, ret;
-
-	userp = 0;
-	ret = 0;
-	cp = strchr(spec, '!');
-	if(cp){
-		*cp++ = 0;		/* restored below */
-		if(*cp)
-		if(strcmp(cp, "*"))	/* "!*" is the same as no user field */
-			userp = cp;	/* there is a user name */
-	}
-
-	if(userp == 0){			/* no user field - domain match only */
-		for(i = 0; i < ndoms && doms[i]; i++)
-			if(dommatch(doms[i], spec) == 0)
-				ret = 1;
-	} else {
-		/* check for "!user", "*!user" or "domain!user" */
-		if(usermatch(user, userp) == 0){
-			if(*spec == 0 || strcmp(spec, "*") == 0)
-				ret = 1;
-			else if(ndoms > 0  && dommatch(doms[ndoms-1], spec) == 0)
-				ret = 1;
-		}
-	}
-	if(cp)
-		cp[-1] = '!';
-	return ret;
-}
-
-/*
- *	match a user name.  the only meta-char is '*' which matches all
- *	characters.  we only allow it as "*", which matches anything or
- *	an * at the end of the name (e.g., "username*") which matches
- *	trailing characters.
- */
-static int
-usermatch(char *pathuser, char *specuser)
-{
-	int n;
-
-	n = strlen(specuser)-1;
-	if(specuser[n] == '*'){
-		if(n == 0)		/* match everything */
-			return 0;
-		return strncmp(pathuser, specuser, n);
-	}
-	return strcmp(pathuser, specuser);
-}
-
-/*
- *	Match a domain specification
- */
-static int
-dommatch(char *pathdom, char *specdom)
-{
-	int n;
-
-	if (*specdom == '*'){
-		if (specdom[1] == '.' && specdom[2]){
-			specdom += 2;
-			n = strlen(pathdom)-strlen(specdom);
-			if(n == 0 || (n > 0 && pathdom[n-1] == '.'))
-				return strcmp(pathdom+n, specdom);
-			return n;
-		}
-	}
-	return strcmp(pathdom, specdom);
-}
-
-/*
- *	Custom allocators to avoid malloc overheads on small objects.
- * 	We never free these.  (See below.)
- */
-typedef struct Stringtab	Stringtab;
-struct Stringtab {
-	Stringtab *link;
-	char *str;
-};
-static Stringtab*
-taballoc(void)
-{
-	static Stringtab *t;
-	static uint nt;
-
-	if(nt == 0){
-		t = malloc(64*sizeof(Stringtab));
-		if(t == 0)
-			fatal("out of memory");
-		nt = 64;
-	}
-	nt--;
-	return t++;
-}
-
-static char*
-xstrdup(char *s)
-{
-	char *r;
-	int len;
-	static char *t;
-	static int nt;
-
-	len = strlen(s)+1;
-	if(len >= 8192)
-		fatal("strdup big string");
-
-	if(nt < len){
-		t = malloc(8192);
-		if(t == 0)
-			fatal("out of memory");
-		nt = 8192;
-	}
-	r = t;
-	t += len;
-	nt -= len;
-	strcpy(r, s);
-	return r;
-}
-
-/*
- *	Return a uniquely allocated copy of a string.
- *	Don't free these -- they stay in the table for the
- *	next caller who wants that particular string.
- *	String comparison can be done with pointer comparison
- *	if you know both strings are atoms.
- */
-static Stringtab *stab[1024];
-
-static uint
-hash(char *s)
-{
-	uint h;
-	uint8_t *p;
-
-	h = 0;
-	for(p=(uint8_t*)s; *p; p++)
-		h = h*37 + *p;
-	return h;
-}
-
-char*
-atom(char *str)
-{
-	uint h;
-	Stringtab *tab;
-
-	h = hash(str) % nelem(stab);
-	for(tab=stab[h]; tab; tab=tab->link)
-		if(strcmp(str, tab->str) == 0)
-			return tab->str;
-
-	tab = taballoc();
-	tab->str = xstrdup(str);
-	tab->link = stab[h];
-	stab[h] = tab;
-	return tab->str;
-}

+ 0 - 12
sys/src/cmd/ratfs/mkfile

@@ -1,12 +0,0 @@
-</$objtype/mkfile
-
-TARG=ratfs
-OFILES=main.$O\
-	proto.$O\
-	misc.$O\
-	ctlfiles.$O\
-
-HFILES=ratfs.h\
-
-BIN=/$objtype/bin/upas
-</sys/src/cmd/mkone

+ 0 - 520
sys/src/cmd/ratfs/proto.c

@@ -1,520 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include "ratfs.h"
-
-/*
- *	9P protocol interface
- */
-
-enum {
-	RELOAD = 0,		/* commands written to ctl file */
-	RDEBUG,
-	RNODEBUG,
-	RNONE,
-};
-
-static void	rflush(Fcall*),		rnop(Fcall*),
-		rauth(Fcall*),	rattach(Fcall*),
-		rclone(Fcall*),		rwalk(Fcall*),
-		rclwalk(Fcall*),	ropen(Fcall*),
-		rcreate(Fcall*),	rread(Fcall*),
-		rwrite(Fcall*),		rclunk(Fcall*),
-		rremove(Fcall*),	rstat(Fcall*),
-		rwstat(Fcall*),	rversion(Fcall*);
-
-static	Fid*	newfid(int);
-static	void	reply(Fcall*, char*);
-
-static	void 	(*fcalls[])(Fcall*) = {
-	[Tversion] =	rversion,
-	[Tflush] =	rflush,
-	[Tauth] =	rauth,
-	[Tattach] =	rattach,
-	[Twalk] =	rwalk,
-	[Topen] =	ropen,
-	[Tcreate] =	rcreate,
-	[Tread] =	rread,
-	[Twrite] =	rwrite,
-	[Tclunk] =	rclunk,
-	[Tremove] =	rremove,
-	[Tstat] =	rstat,
-	[Twstat] =	rwstat,
-};
-
-
-static	Keyword cmds[] = {
-	"reload",		RELOAD,
-	"debug",		RDEBUG,
-	"nodebug",		RNODEBUG,
-	0,			RNONE,
-};
-
-/*
- *	Main protocol loop
- */
-void
-io(void)
-{
-	Fcall	rhdr;
-	int n;
-
-	for(;;){
-		n = read9pmsg(srvfd, rbuf, sizeof rbuf-1);
-		if(n <= 0)
-			fatal("mount read");
-		if(convM2S(rbuf, n, &rhdr) == 0){
-			if(debugfd >= 0)
-				fprint(2, "%s: malformed message\n", argv0);
-			continue;
-		}
-
-		if(debugfd >= 0)
-			fprint(debugfd, "<-%F\n", &rhdr);/**/
-
-		if(!fcalls[rhdr.type])
-			reply(&rhdr, "bad fcall type");
-		else
-			(*fcalls[rhdr.type])(&rhdr);
-	}
-}
-
-/*
- *	write a protocol reply to the client
- */
-static void
-reply(Fcall *r, char *error)
-{
-	int n;
-
-	if(error == nil)
-		r->type++;
-	else {
-		r->type = Rerror;
-		r->ename = error;
-	}
-	if(debugfd >= 0)
-		fprint(debugfd, "->%F\n", r);/**/
-	n = convS2M(r, rbuf, sizeof rbuf);
-	if(n == 0)
-		sysfatal("convS2M: %r");
-	if(write(srvfd, rbuf, n) < 0)
-		sysfatal("reply: %r");
-}
-
-
-/*
- *  lookup a fid. if not found, create a new one.
- */
-
-static Fid*
-newfid(int fid)
-{
-	Fid *f, *ff;
-
-	static Fid *fids;
-
-	ff = 0;
-	for(f = fids; f; f = f->next){
-		if(f->fid == fid){
-			if(!f->busy)
-				f->node = 0;
-			return f;
-		} else if(!ff && !f->busy)
-			ff = f;
-	}
-	if(ff == 0){
-		ff = mallocz(sizeof(*f), 1);
-		ff->next = fids;
-		fids = ff;
-	}
-	ff->node = 0;
-	ff->fid = fid;
-	return ff;
-}
-
-static void
-rversion(Fcall *f)
-{
-	f->version = "9P2000";
-	if(f->msize > MAXRPC)
-		f->msize = MAXRPC;
-	reply(f, 0);
-}
-
-static void
-rauth(Fcall *f)
-{
-	reply(f, "ratfs: authentication not required");
-}
-
-static void
-rflush(Fcall *f)
-{
-	reply(f, 0);
-}
-
-static void
-rattach(Fcall *f)
-{
-	Fid *fidp;
-	Dir *d;
-
-	if((d=dirstat(conffile)) != nil && d->mtime > lastconftime)
-		getconf();
-	free(d);
-	if((d=dirstat(ctlfile)) != nil && d->mtime > lastctltime)
-		reload();
-	free(d);
-	cleantrusted();
-
-	fidp = newfid(f->fid);
-	fidp->busy = 1;
-	fidp->node = root;
-	fidp->name = root->d.name;
-	fidp->uid = atom(f->uname);
-	f->qid = root->d.qid;
-	reply(f,0);
-}
-
-static void
-rclone(Fcall *f)
-{
-	Fid *fidp, *nf;
-
-	fidp = newfid(f->fid);
-	if(fidp->node && fidp->node->d.type == Dummynode){
-		reply(f, "can't clone an address");
-		return;
-	}
-	nf = newfid(f->newfid);
-	nf->busy = 1;
-	nf->node = fidp->node;
-	nf->uid = fidp->uid;
-	nf->name = fidp->name;
-	if(debugfd >= 0)
-		printfid(nf);
-	reply(f,0);
-}
-
-static void
-rwalk(Fcall *f)
-{
-	int i, j;
-	Fcall r;
-	Fid *fidp, *nf;
-	char *err;
-
-	fidp = newfid(f->fid);
-	if(fidp->node && fidp->node->d.type == Dummynode){
-		reply(f, "can't walk an address node");
-		return;
-	}
-	if(f->fid == f->newfid)
-		nf = fidp;
-	else{
-		nf = newfid(f->newfid);
-		nf->busy = 1;
-		nf->node = fidp->node;
-		nf->uid = fidp->uid;
-		nf->name = fidp->name;
-		if(debugfd >= 0)
-			printfid(nf);
-	}
-
-	err = nil;
-	for(i=0; i<f->nwname; i++){
-		err = walk(f->wname[i], nf);
-		if(err)
-			break;
-		r.wqid[i] = nf->node->d.qid;
-	}
-
-
-	if(i < f->nwname && f->fid != f->newfid){
-		nf->busy = 0;
-		nf->node = 0;
-		nf->name = 0;
-		nf->uid = 0;
-	}
-	if(i > 0 && i < f->nwname && f->fid == f->newfid){
-		/*
-		 * try to put things back;
-		 * we never get this sort of call from the kernel
-		 */
-		for(j=0; j<i; j++)
-			walk("..", nf);
-	}
-	memmove(f->wqid, r.wqid, sizeof f->wqid);
-	f->nwqid = i;
-	if(err && i==0)
-		reply(f, err);
-	else
-		reply(f, 0);
-}
-
-/*
- *	We don't have to do full permission checking because most files
- *	have restricted semantics:
- *		The ctl file is only writable
- *		All others, including directories, are only readable
- */
-static void
-ropen(Fcall *f)
-{
-	Fid *fidp;
-	int mode;
-
-	fidp = newfid(f->fid);
-
-	if(debugfd >= 0)
-		printfid(fidp);
-
-	mode = f->mode&(OREAD|OWRITE|ORDWR);
-	if(fidp->node->d.type == Ctlfile) {
-		if(mode != OWRITE) {
-			reply(f, "permission denied");
-			return;
-		}
-	} else
-	if (mode != OREAD) {
-		reply(f, "permission denied or operation not supported");
-		return;
-	}
-
-	f->qid = fidp->node->d.qid;
-	fidp->open = 1;
-	reply(f, 0);
-}
-
-static int
-permitted(Fid *fp, Node *np, int mask)
-{
-	int mode;
-
-	mode = np->d.mode;
-	return (fp->uid==np->d.uid && (mode&(mask<<6)))
-		|| (fp->uid==np->d.gid && (mode&(mask<<3)))
-		|| (mode&mask);
-}
-
-/*
- *	creates are only allowed in the "trusted" subdirectory
- *	we also assume that the groupid == the uid
- */
-static void
-rcreate(Fcall *f)
-{
-	Fid *fidp;
-	Node *np;
-
-	fidp = newfid(f->fid);
-	np = fidp->node;
-	if((np->d.mode&DMDIR) == 0){
-		reply(f, "not a directory");
-		return;
-	}
-
-	if(!permitted(fidp, np, AWRITE)) {
-		reply(f, "permission denied");
-		return;
-	}
-
-	/* Ignore the supplied mode and force it to be non-writable */
-
-	np = newnode(np, f->name, Trustedtemp, 0444, trustedqid++);
-	if(trustedqid >= Qaddrfile)			/* wrap QIDs */
-		trustedqid = Qtrustedfile;
-	cidrparse(&np->ip, f->name);
-	f->qid = np->d.qid;
-	np->d.uid = fidp->uid;
-	np->d.gid = np->d.uid;
-	np->d.muid = np->d.muid;
-	fidp->node = np;
-	fidp->open = 1;
-	reply(f, 0);
-	return;
-}
-
-/*
- *	only directories can be read.  everthing else returns EOF.
- */
-static void
-rread(Fcall *f)
-{
-	int32_t cnt;
-	Fid *fidp;
-
-	cnt = f->count;
-	f->count = 0;
-	fidp = newfid(f->fid);
-	f->data = (char*)rbuf+IOHDRSZ;
-	if(fidp->open == 0) {
-		reply(f, "file not open");
-		return;
-	}
-	if ((fidp->node->d.mode&DMDIR) == 0){
-		reply(f, 0);				/*EOF*/
-		return;
-	}
-	if(cnt > MAXRPC)
-		cnt = MAXRPC;
-
-	if(f->offset == 0)
-		fidp->dirindex = 0;
-
-	switch(fidp->node->d.type) {
-	case Directory:
-	case Addrdir:
-	case Trusted:
-		f->count = dread(fidp, cnt);
-		break;
-	case IPaddr:
-	case Acctaddr:
-		f->count = hread(fidp, cnt);
-		break;
-	default:
-		reply(f, "can't read this type of file");
-		return;
-	}
-	reply(f, 0);
-}
-
-
-/*
- * 	only the 'ctl' file in the top level directory is writable
- */
-
-static void
-rwrite(Fcall *f)
-{
-	Fid *fidp;
-	int n;
-	char *err, *argv[10];
-
-	fidp = newfid(f->fid);
-	if(fidp->node->d.mode & DMDIR){
-		reply(f, "directories are not writable");
-		return;
-	}
-	if(fidp->open == 0) {
-		reply(f, "file not open");
-		return;
-	}
-
-	if (!permitted(fidp, fidp->node, AWRITE)) {
-		reply(f, "permission denied");
-		return;
-	}
-
-	f->data[f->count] = 0;			/* the extra byte in rbuf leaves room */
-	n = tokenize(f->data, argv, 10);
-	err = 0;
-	switch(findkey(argv[0], cmds)){
-	case RELOAD:
-		getconf();
-		reload();
-		break;
-	case RDEBUG:
-		if(n > 1){
-			debugfd = create(argv[1], OWRITE, 0666);
-			if(debugfd < 0)
-				err = "create failed";
-		} else
-			debugfd = 2;
-		break;
-	case RNODEBUG:
-		if(debugfd >= 0)
-			close(debugfd);
-		debugfd = -1;
-		break;
-	default:
-		err = "unknown command";
-		break;
-	}
-	reply(f, err);
-}
-
-static void
-rclunk(Fcall *f)
-{
-	Fid *fidp;
-
-	fidp = newfid(f->fid);
-	fidp->open = 0;
-	fidp->busy = 0;
-	fidp->node = 0;
-	fidp->name = 0;
-	fidp->uid = 0;
-	reply(f, 0);
-}
-
-/*
- *  no files or directories are removable; this becomes clunk;
- */
-static void
-rremove(Fcall *f)
-{
-	Fid *fidp;
-	Node *dir, *np;
-
-	fidp = newfid(f->fid);
-
-	/*
-	 * only trusted temporary files can be removed
-	 * and only by their owner.
-	 */
-	if(fidp->node->d.type != Trustedtemp){
-		reply(f, "can't be removed");
-		return;
-	}
-	if(fidp->uid != fidp->node->d.uid){
-		reply(f, "permission denied");
-		return;
-	}
-	dir = fidp->node->parent;
-	for(np = dir->children; np; np = np->sibs)
-		if(np->sibs == fidp->node)
-			break;
-	if(np)
-		np->sibs = fidp->node->sibs;
-	else
-		dir->children = fidp->node->sibs;
-	dir->count--;
-	free(fidp->node);
-	fidp->node = 0;
-	fidp->open = 0;
-	fidp->busy = 0;
-	fidp->name = 0;
-	fidp->uid = 0;
-	reply(f, 0);
-}
-
-static void
-rstat(Fcall *f)
-{
-	Fid *fidp;
-
-	fidp = newfid(f->fid);
-	if (fidp->node->d.type == Dummynode)
-		dummy.d.name = fidp->name;
-	f->stat = (uint8_t*)rbuf+4+1+2+2;	/* knows about stat(5) */
-	f->nstat = convD2M(&fidp->node->d, f->stat, MAXRPC);
-	if(f->nstat <= BIT16SZ)
-		reply(f, "ratfs: convD2M");
-	else
-		reply(f, 0);
-	return;
-}
-
-static void
-rwstat(Fcall *f)
-{
-	reply(f, "wstat not implemented");
-}

+ 0 - 126
sys/src/cmd/ratfs/ratfs.h

@@ -1,126 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <bio.h>
-
-enum {
-	MAXRPC = 8192,
-
-	Qroot = 1,		/* fixed QID's */
-	Qallow,
-	Qdelay,
-	Qblock,
-	Qdial,
-	Qdeny,
-	Qtrusted,
-	Qctl,
-	Qdummy,
-	Qaddr,			/* Qid's for "ip" & "account" subdirs (Qaddr-99) */
-
-	Qtrustedfile = 100,	/* Qid's for trusted files (100-999)*/
-	Qaddrfile   = 1000,	/* Qid's for address files (> 1000) */
-
-				/* type codes in node.d.type */
-	Directory =	0,	/* normal directory */
-	Addrdir,		/* contains "ip" and "account" directories */
-	IPaddr,			/* contains IP address "files" */
-	Acctaddr,		/* contains Account address "files" */
-	Trusted,		/* contains trusted IP files */
-	Trustedperm,		/* permanently trusted IP pseudo-file */
-	Trustedtemp,		/* temporarily trusted IP pseudo-file */
-	Ctlfile,		/* ctl file under root */
-	Dummynode,		/* place holder for Address pseudo-files */
-};
-
-typedef struct Fid	Fid;
-typedef struct Node	Node;
-typedef	struct Address	Address;
-typedef struct Cidraddr	Cidraddr;
-typedef struct Keyword	Keyword;
-
-	/* an active fid */
-struct Fid
-{
-	int	fid;
-	int	dirindex;
-	Node	*node;		/* current position in path */
-	int	busy;
-	int	open;		/* directories only */
-	char	*name;
-	char *uid;
-	Fid	*next;
-};
-
-struct	Cidraddr
-{
-	uint32_t	ipaddr;		/* CIDR base addr */
-	uint32_t	mask;		/* CIDR mask */
-};
-
-	/* an address is either an account name (domain!user) or Ip address */
-struct	Address
-{
-	char	*name;		/* from the control file */
-	Cidraddr ip;		/* CIDR Address */
-};
-
-/* Fids point to either a directory or pseudo-file */
-struct Node
-{
-	Dir	d;		/* d.name, d.uid, d.gid, d.muid are atoms */
-	int	count;
-	int	allocated;	/* number of Address structs allocated */
-	uint32_t	baseqid;	/* base of Qid's in this set */
-	Node	*parent;	/* points to self in root node*/
-	Node	*sibs;		/* 0 in Ipaddr and Acctaddr dirs */
-	union {
-		Node	*children;	/* type == Directory || Addrdir || Trusted */
-		Address	*addrs;		/* type == Ipaddr || Acctaddr */
-		Cidraddr ip;		/* type == Trustedfile */
-	};
-};
-
-struct Keyword {
-	char	*name;
-	int	code;
-};
-
-Node	*root;			/* root of directory tree */
-Node	dummy;			/* dummy node for fid's pointing to an Address */
-int	srvfd;			/* fd for 9fs */
-uchar rbuf[IOHDRSZ+MAXRPC+1];
-int	debugfd;
-char	*ctlfile;
-char	*conffile;
-long	lastconftime;
-long	lastctltime;
-int	trustedqid;
-
-char*	atom(char*);
-void	cidrparse(Cidraddr*, char*);
-void	cleantrusted(void);
-Node*	dirwalk(char*, Node*);
-int	dread(Fid*, int);
-void	fatal(char*, ...);
-Node*	finddir(int);
-int	findkey(char*, Keyword*);
-void	getconf(void);
-int	hread(Fid*, int);
-void	io(void);
-Node*	newnode(Node*, char*, ushort, int, uint32_t);
-void	printfid(Fid*);
-void	printnode(Node*);
-void	printtree(Node*);
-void	reload(void);
-char*	subslash(char*);
-char*	walk(char*, Fid*);