1 #ifndef __9P_H__
2 #define __9P_H__ 1
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 /*
9 #pragma src "/sys/src/lib9p"
10 #pragma lib "lib9p.a"
11 */
12 AUTOLIB(9p)
13 
14 /*
15  * Maps from ulongs to void*s.
16  */
17 typedef struct Intmap	Intmap;
18 
19 Intmap*	allocmap(void (*inc)(void*));
20 void		freemap(Intmap*, void (*destroy)(void*));
21 void*	lookupkey(Intmap*, ulong);
22 void*	insertkey(Intmap*, ulong, void*);
23 int		caninsertkey(Intmap*, ulong, void*);
24 void*	deletekey(Intmap*, ulong);
25 
26 /*
27  * Fid and Request structures.
28  */
29 typedef struct Fid		Fid;
30 typedef struct Req		Req;
31 typedef struct Fidpool	Fidpool;
32 typedef struct Reqpool	Reqpool;
33 typedef struct File		File;
34 typedef struct Filelist	Filelist;
35 typedef struct Tree		Tree;
36 typedef struct Readdir	Readdir;
37 typedef struct Srv Srv;
38 
39 struct Fid
40 {
41 	ulong	fid;
42 	int		omode;	/* -1 = not open */
43 	File*		file;
44 	char*	uid;
45 	Qid		qid;
46 	void*	aux;
47 
48 /* below is implementation-specific; don't use */
49 	Readdir*	rdir;
50 	Ref		ref;
51 	Fidpool*	pool;
52 	vlong	diroffset;
53 	long		dirindex;
54 };
55 
56 struct Req
57 {
58 	ulong	tag;
59 	void*	aux;
60 	Fcall		ifcall;
61 	Fcall		ofcall;
62 	Dir		d;
63 	Req*		oldreq;
64 	Fid*		fid;
65 	Fid*		afid;
66 	Fid*		newfid;
67 	Srv*		srv;
68 
69 /* below is implementation-specific; don't use */
70 	QLock	lk;
71 	Ref		ref;
72 	Reqpool*	pool;
73 	uchar*	buf;
74 	uchar	type;
75 	uchar	responded;
76 	char*	error;
77 	void*	rbuf;
78 	Req**	flush;
79 	int		nflush;
80 };
81 
82 /*
83  * Pools to maintain Fid <-> fid and Req <-> tag maps.
84  */
85 
86 struct Fidpool {
87 	Intmap	*map;
88 	void		(*destroy)(Fid*);
89 	Srv		*srv;
90 };
91 
92 struct Reqpool {
93 	Intmap	*map;
94 	void		(*destroy)(Req*);
95 	Srv		*srv;
96 };
97 
98 Fidpool*	allocfidpool(void (*destroy)(Fid*));
99 void		freefidpool(Fidpool*);
100 Fid*		allocfid(Fidpool*, ulong);
101 Fid*		lookupfid(Fidpool*, ulong);
102 void		closefid(Fid*);
103 Fid*		removefid(Fidpool*, ulong);
104 
105 Reqpool*	allocreqpool(void (*destroy)(Req*));
106 void		freereqpool(Reqpool*);
107 Req*		allocreq(Reqpool*, ulong);
108 Req*		lookupreq(Reqpool*, ulong);
109 void		closereq(Req*);
110 Req*		removereq(Reqpool*, ulong);
111 
112 typedef	int	Dirgen(int, Dir*, void*);
113 void		dirread9p(Req*, Dirgen*, void*);
114 
115 /*
116  * File trees.
117  */
118 struct File {
119 	Ref ref;
120 	Dir dir;
121 	File *parent;
122 	void *aux;
123 
124 /* below is implementation-specific; don't use */
125 	RWLock rwlock;
126 	Filelist *filelist;
127 	Tree *tree;
128 	int nchild;
129 	int allocd;
130 };
131 
132 struct Tree {
133 	File *root;
134 	void	(*destroy)(File *file);
135 
136 /* below is implementation-specific; don't use */
137 	Lock genlock;
138 	ulong qidgen;
139 	ulong dirqidgen;
140 };
141 
142 Tree*	alloctree(char*, char*, ulong, void(*destroy)(File*));
143 void		freetree(Tree*);
144 File*		createfile(File*, char*, char*, ulong, void*);
145 int		removefile(File*);
146 void		closefile(File*);
147 File*		walkfile(File*, char*);
148 Readdir*	opendirfile(File*);
149 long		readdirfile(Readdir*, uchar*, long);
150 void		closedirfile(Readdir*);
151 
152 /*
153  * Kernel-style command parser
154  */
155 typedef struct Cmdbuf Cmdbuf;
156 typedef struct Cmdtab Cmdtab;
157 Cmdbuf*		parsecmd(char *a, int n);
158 void		respondcmderror(Req*, Cmdbuf*, char*, ...);
159 Cmdtab*	lookupcmd(Cmdbuf*, Cmdtab*, int);
160 /*
161 #pragma varargck argpos respondcmderr 3
162 */
163 struct Cmdbuf
164 {
165 	char	*buf;
166 	char	**f;
167 	int	nf;
168 };
169 
170 struct Cmdtab
171 {
172 	int	index;	/* used by client to switch on result */
173 	char	*cmd;	/* command name */
174 	int	narg;	/* expected #args; 0 ==> variadic */
175 };
176 
177 /*
178  * File service loop.
179  */
180 struct Srv {
181 	Tree*	tree;
182 	void		(*destroyfid)(Fid*);
183 	void		(*destroyreq)(Req*);
184 	void		(*start)(Srv*);
185 	void		(*end)(Srv*);
186 	void*	aux;
187 
188 	void		(*attach)(Req*);
189 	void		(*auth)(Req*);
190 	void		(*open)(Req*);
191 	void		(*create)(Req*);
192 	void		(*read)(Req*);
193 	void		(*write)(Req*);
194 	void		(*remove)(Req*);
195 	void		(*flush)(Req*);
196 	void		(*stat)(Req*);
197 	void		(*wstat)(Req*);
198 	void		(*walk)(Req*);
199 	char*	(*clone)(Fid*, Fid*);
200 	char*	(*walk1)(Fid*, char*, Qid*);
201 
202 	int		infd;
203 	int		outfd;
204 	int		nopipe;
205 	int		srvfd;
206 	int		leavefdsopen;	/* magic for acme win */
207 	int		foreground;	/* run in foreground */
208 	int		fake;
209 
210 /* below is implementation-specific; don't use */
211 	Fidpool*	fpool;
212 	Reqpool*	rpool;
213 	uint		msize;
214 
215 	uchar*	rbuf;
216 	QLock	rlock;
217 	uchar*	wbuf;
218 	QLock	wlock;
219 };
220 
221 void		srv(Srv*);
222 void		postmountsrv(Srv*, char*, char*, int);
223 int 		postfd(char*, int);
224 extern	int		chatty9p;
225 void		respond(Req*, char*);
226 void		threadpostmountsrv(Srv*, char*, char*, int);
227 
228 /*
229  * Helper.  Assumes user is same as group.
230  */
231 int		hasperm(File*, char*, int);
232 
233 void*	emalloc9p(ulong);
234 void*	erealloc9p(void*, ulong);
235 char*	estrdup9p(char*);
236 
237 enum {
238 	OMASK = 3
239 };
240 
241 void readstr(Req*, char*);
242 void readbuf(Req*, void*, long);
243 void	walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), char*(*clone)(Fid*,Fid*,void*), void*);
244 
245 #ifdef __cplusplus
246 }
247 #endif
248 #endif
249