Small tweaks
Lots of new code imported.
diff --git a/include/9p.h b/include/9p.h
new file mode 100644
index 0000000..6703d60
--- /dev/null
+++ b/include/9p.h
@@ -0,0 +1,244 @@
+#ifndef __9P_H__
+#define __9P_H__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+#pragma src "/sys/src/lib9p"
+#pragma lib "lib9p.a"
+*/
+
+/*
+ * Maps from ulongs to void*s.
+ */
+typedef struct Intmap	Intmap;
+
+Intmap*	allocmap(void (*inc)(void*));
+void		freemap(Intmap*, void (*destroy)(void*));
+void*	lookupkey(Intmap*, ulong);
+void*	insertkey(Intmap*, ulong, void*);
+int		caninsertkey(Intmap*, ulong, void*);
+void*	deletekey(Intmap*, ulong);
+
+/*
+ * Fid and Request structures.
+ */
+typedef struct Fid		Fid;
+typedef struct Req		Req;
+typedef struct Fidpool	Fidpool;
+typedef struct Reqpool	Reqpool;
+typedef struct File		File;
+typedef struct Filelist	Filelist;
+typedef struct Tree		Tree;
+typedef struct Readdir	Readdir;
+typedef struct Srv Srv;
+
+struct Fid
+{
+	ulong	fid;
+	char		omode;	/* -1 = not open */
+	File*		file;
+	char*	uid;
+	Qid		qid;
+	void*	aux;
+
+/* below is implementation-specific; don't use */
+	Readdir*	rdir;
+	Ref		ref;
+	Fidpool*	pool;
+	vlong	diroffset;
+	long		dirindex;
+};
+
+struct Req
+{
+	ulong	tag;
+	void*	aux;
+	Fcall		ifcall;
+	Fcall		ofcall;
+	Dir		d;
+	Req*		oldreq;
+	Fid*		fid;
+	Fid*		afid;
+	Fid*		newfid;
+	Srv*		srv;
+
+/* below is implementation-specific; don't use */
+	QLock	lk;
+	Ref		ref;
+	Reqpool*	pool;
+	uchar*	buf;
+	uchar	type;
+	uchar	responded;
+	char*	error;
+	void*	rbuf;
+	Req**	flush;
+	int		nflush;
+};
+
+/*
+ * Pools to maintain Fid <-> fid and Req <-> tag maps.
+ */
+
+struct Fidpool {
+	Intmap	*map;
+	void		(*destroy)(Fid*);
+	Srv		*srv;
+};
+
+struct Reqpool {
+	Intmap	*map;
+	void		(*destroy)(Req*);
+	Srv		*srv;
+};
+
+Fidpool*	allocfidpool(void (*destroy)(Fid*));
+void		freefidpool(Fidpool*);
+Fid*		allocfid(Fidpool*, ulong);
+Fid*		lookupfid(Fidpool*, ulong);
+void		closefid(Fid*);
+Fid*		removefid(Fidpool*, ulong);
+
+Reqpool*	allocreqpool(void (*destroy)(Req*));
+void		freereqpool(Reqpool*);
+Req*		allocreq(Reqpool*, ulong);
+Req*		lookupreq(Reqpool*, ulong);
+void		closereq(Req*);
+Req*		removereq(Reqpool*, ulong);
+
+typedef	int	Dirgen(int, Dir*, void*);
+void		dirread9p(Req*, Dirgen*, void*);
+
+/*
+ * File trees.
+ */
+struct File {
+	Ref ref;
+	Dir dir;
+	File *parent;
+	void *aux;
+
+/* below is implementation-specific; don't use */
+	RWLock rwlock;
+	Filelist *filelist;
+	Tree *tree;
+	int nchild;
+	int allocd;
+};
+
+struct Tree {
+	File *root;
+	void	(*destroy)(File *file);
+
+/* below is implementation-specific; don't use */
+	Lock genlock;
+	ulong qidgen;
+	ulong dirqidgen;
+};
+
+Tree*	alloctree(char*, char*, ulong, void(*destroy)(File*));
+void		freetree(Tree*);
+File*		createfile(File*, char*, char*, ulong, void*);
+int		removefile(File*);
+void		closefile(File*);
+File*		walkfile(File*, char*);
+Readdir*	opendirfile(File*);
+long		readdirfile(Readdir*, uchar*, long);
+void		closedirfile(Readdir*);
+
+/*
+ * Kernel-style command parser
+ */
+typedef struct Cmdbuf Cmdbuf;
+typedef struct Cmdtab Cmdtab;
+Cmdbuf*		parsecmd(char *a, int n);
+void		respondcmderror(Req*, Cmdbuf*, char*, ...);
+Cmdtab*	lookupcmd(Cmdbuf*, Cmdtab*, int);
+/*
+#pragma varargck argpos respondcmderr 3
+*/
+struct Cmdbuf
+{
+	char	*buf;
+	char	**f;
+	int	nf;
+};
+
+struct Cmdtab
+{
+	int	index;	/* used by client to switch on result */
+	char	*cmd;	/* command name */
+	int	narg;	/* expected #args; 0 ==> variadic */
+};
+
+/*
+ * File service loop.
+ */
+struct Srv {
+	Tree*	tree;
+	void		(*destroyfid)(Fid*);
+	void		(*destroyreq)(Req*);
+	void		(*end)(Srv*);
+	void*	aux;
+
+	void		(*attach)(Req*);
+	void		(*auth)(Req*);
+	void		(*open)(Req*);
+	void		(*create)(Req*);
+	void		(*read)(Req*);
+	void		(*write)(Req*);
+	void		(*remove)(Req*);
+	void		(*flush)(Req*);
+	void		(*stat)(Req*);
+	void		(*wstat)(Req*);
+	void		(*walk)(Req*);
+	char*	(*clone)(Fid*, Fid*);
+	char*	(*walk1)(Fid*, char*, Qid*);
+
+	int		infd;
+	int		outfd;
+	int		nopipe;
+	int		srvfd;
+	int		leavefdsopen;	/* magic for acme win */
+
+/* below is implementation-specific; don't use */
+	Fidpool*	fpool;
+	Reqpool*	rpool;
+	uint		msize;
+
+	uchar*	rbuf;
+	QLock	rlock;
+	uchar*	wbuf;
+	QLock	wlock;
+};
+
+void		srv(Srv*);
+void		postmountsrv(Srv*, char*, char*, int);
+int 		postfd(char*, int);
+int		chatty9p;
+void		respond(Req*, char*);
+void		threadpostmountsrv(Srv*, char*, char*, int);
+
+/*
+ * Helper.  Assumes user is same as group.
+ */
+int		hasperm(File*, char*, int);
+
+void*	emalloc9p(ulong);
+void*	erealloc9p(void*, ulong);
+char*	estrdup9p(char*);
+
+enum {
+	OMASK = 3
+};
+
+void readstr(Req*, char*);
+void readbuf(Req*, void*, long);
+void	walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), char*(*clone)(Fid*,Fid*,void*), void*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif