|  | #ifndef __9P_H__ | 
|  | #define __9P_H__ 1 | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | #pragma src "/sys/src/lib9p" | 
|  | #pragma lib "lib9p.a" | 
|  | */ | 
|  | AUTOLIB(9p) | 
|  |  | 
|  | /* | 
|  | * 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; | 
|  | int		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		(*start)(Srv*); | 
|  | 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 */ | 
|  | int		foreground;	/* run in foreground */ | 
|  | int		fake; | 
|  |  | 
|  | /* 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); | 
|  | extern	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 |