xref: /plan9/sys/src/cmd/unix/u9fs/convM2S.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include	<plan9.h>
2*9a747e4fSDavid du Colombier #include	<fcall.h>
3*9a747e4fSDavid du Colombier 
4*9a747e4fSDavid du Colombier static
5*9a747e4fSDavid du Colombier uchar*
gstring(uchar * p,uchar * ep,char ** s)6*9a747e4fSDavid du Colombier gstring(uchar *p, uchar *ep, char **s)
7*9a747e4fSDavid du Colombier {
8*9a747e4fSDavid du Colombier 	uint n;
9*9a747e4fSDavid du Colombier 
10*9a747e4fSDavid du Colombier 	if(p+BIT16SZ > ep)
11*9a747e4fSDavid du Colombier 		return nil;
12*9a747e4fSDavid du Colombier 	n = GBIT16(p);
13*9a747e4fSDavid du Colombier 	p += BIT16SZ - 1;
14*9a747e4fSDavid du Colombier 	if(p+n+1 > ep)
15*9a747e4fSDavid du Colombier 		return nil;
16*9a747e4fSDavid du Colombier 	/* move it down, on top of count, to make room for '\0' */
17*9a747e4fSDavid du Colombier 	memmove(p, p + 1, n);
18*9a747e4fSDavid du Colombier 	p[n] = '\0';
19*9a747e4fSDavid du Colombier 	*s = (char*)p;
20*9a747e4fSDavid du Colombier 	p += n+1;
21*9a747e4fSDavid du Colombier 	return p;
22*9a747e4fSDavid du Colombier }
23*9a747e4fSDavid du Colombier 
24*9a747e4fSDavid du Colombier static
25*9a747e4fSDavid du Colombier uchar*
gqid(uchar * p,uchar * ep,Qid * q)26*9a747e4fSDavid du Colombier gqid(uchar *p, uchar *ep, Qid *q)
27*9a747e4fSDavid du Colombier {
28*9a747e4fSDavid du Colombier 	if(p+QIDSZ > ep)
29*9a747e4fSDavid du Colombier 		return nil;
30*9a747e4fSDavid du Colombier 	q->type = GBIT8(p);
31*9a747e4fSDavid du Colombier 	p += BIT8SZ;
32*9a747e4fSDavid du Colombier 	q->vers = GBIT32(p);
33*9a747e4fSDavid du Colombier 	p += BIT32SZ;
34*9a747e4fSDavid du Colombier 	q->path = GBIT64(p);
35*9a747e4fSDavid du Colombier 	p += BIT64SZ;
36*9a747e4fSDavid du Colombier 	return p;
37*9a747e4fSDavid du Colombier }
38*9a747e4fSDavid du Colombier 
39*9a747e4fSDavid du Colombier /*
40*9a747e4fSDavid du Colombier  * no syntactic checks.
41*9a747e4fSDavid du Colombier  * three causes for error:
42*9a747e4fSDavid du Colombier  *  1. message size field is incorrect
43*9a747e4fSDavid du Colombier  *  2. input buffer too short for its own data (counts too long, etc.)
44*9a747e4fSDavid du Colombier  *  3. too many names or qids
45*9a747e4fSDavid du Colombier  * gqid() and gstring() return nil if they would reach beyond buffer.
46*9a747e4fSDavid du Colombier  * main switch statement checks range and also can fall through
47*9a747e4fSDavid du Colombier  * to test at end of routine.
48*9a747e4fSDavid du Colombier  */
49*9a747e4fSDavid du Colombier uint
convM2S(uchar * ap,uint nap,Fcall * f)50*9a747e4fSDavid du Colombier convM2S(uchar *ap, uint nap, Fcall *f)
51*9a747e4fSDavid du Colombier {
52*9a747e4fSDavid du Colombier 	uchar *p, *ep;
53*9a747e4fSDavid du Colombier 	uint i, size;
54*9a747e4fSDavid du Colombier 
55*9a747e4fSDavid du Colombier 	p = ap;
56*9a747e4fSDavid du Colombier 	ep = p + nap;
57*9a747e4fSDavid du Colombier 
58*9a747e4fSDavid du Colombier 	if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
59*9a747e4fSDavid du Colombier 		return 0;
60*9a747e4fSDavid du Colombier 	size = GBIT32(p);
61*9a747e4fSDavid du Colombier 	p += BIT32SZ;
62*9a747e4fSDavid du Colombier 
63*9a747e4fSDavid du Colombier 	if(size > nap)
64*9a747e4fSDavid du Colombier 		return 0;
65*9a747e4fSDavid du Colombier 	if(size < BIT32SZ+BIT8SZ+BIT16SZ)
66*9a747e4fSDavid du Colombier 		return 0;
67*9a747e4fSDavid du Colombier 
68*9a747e4fSDavid du Colombier 	f->type = GBIT8(p);
69*9a747e4fSDavid du Colombier 	p += BIT8SZ;
70*9a747e4fSDavid du Colombier 	f->tag = GBIT16(p);
71*9a747e4fSDavid du Colombier 	p += BIT16SZ;
72*9a747e4fSDavid du Colombier 
73*9a747e4fSDavid du Colombier 	switch(f->type)
74*9a747e4fSDavid du Colombier 	{
75*9a747e4fSDavid du Colombier 	default:
76*9a747e4fSDavid du Colombier 		return 0;
77*9a747e4fSDavid du Colombier 
78*9a747e4fSDavid du Colombier 	case Tversion:
79*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
80*9a747e4fSDavid du Colombier 			return 0;
81*9a747e4fSDavid du Colombier 		f->msize = GBIT32(p);
82*9a747e4fSDavid du Colombier 		p += BIT32SZ;
83*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->version);
84*9a747e4fSDavid du Colombier 		break;
85*9a747e4fSDavid du Colombier 
86*9a747e4fSDavid du Colombier /*
87*9a747e4fSDavid du Colombier 	case Tsession:
88*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
89*9a747e4fSDavid du Colombier 			return 0;
90*9a747e4fSDavid du Colombier 		f->nchal = GBIT16(p);
91*9a747e4fSDavid du Colombier 		p += BIT16SZ;
92*9a747e4fSDavid du Colombier 		if(p+f->nchal > ep)
93*9a747e4fSDavid du Colombier 			return 0;
94*9a747e4fSDavid du Colombier 		f->chal = p;
95*9a747e4fSDavid du Colombier 		p += f->nchal;
96*9a747e4fSDavid du Colombier 		break;
97*9a747e4fSDavid du Colombier */
98*9a747e4fSDavid du Colombier 
99*9a747e4fSDavid du Colombier 	case Tflush:
100*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
101*9a747e4fSDavid du Colombier 			return 0;
102*9a747e4fSDavid du Colombier 		f->oldtag = GBIT16(p);
103*9a747e4fSDavid du Colombier 		p += BIT16SZ;
104*9a747e4fSDavid du Colombier 		break;
105*9a747e4fSDavid du Colombier 
106*9a747e4fSDavid du Colombier 	case Tauth:
107*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
108*9a747e4fSDavid du Colombier 			return 0;
109*9a747e4fSDavid du Colombier 		f->afid = GBIT32(p);
110*9a747e4fSDavid du Colombier 		p += BIT32SZ;
111*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->uname);
112*9a747e4fSDavid du Colombier 		if(p == nil)
113*9a747e4fSDavid du Colombier 			break;
114*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->aname);
115*9a747e4fSDavid du Colombier 		if(p == nil)
116*9a747e4fSDavid du Colombier 			break;
117*9a747e4fSDavid du Colombier 		break;
118*9a747e4fSDavid du Colombier 
119*9a747e4fSDavid du Colombier /*
120*9a747e4fSDavid du Colombier b
121*9a747e4fSDavid du Colombier 	case Tattach:
122*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
123*9a747e4fSDavid du Colombier 			return 0;
124*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
125*9a747e4fSDavid du Colombier 		p += BIT32SZ;
126*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->uname);
127*9a747e4fSDavid du Colombier 		if(p == nil)
128*9a747e4fSDavid du Colombier 			break;
129*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->aname);
130*9a747e4fSDavid du Colombier 		if(p == nil)
131*9a747e4fSDavid du Colombier 			break;
132*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
133*9a747e4fSDavid du Colombier 			return 0;
134*9a747e4fSDavid du Colombier 		f->nauth = GBIT16(p);
135*9a747e4fSDavid du Colombier 		p += BIT16SZ;
136*9a747e4fSDavid du Colombier 		if(p+f->nauth > ep)
137*9a747e4fSDavid du Colombier 			return 0;
138*9a747e4fSDavid du Colombier 		f->auth = p;
139*9a747e4fSDavid du Colombier 		p += f->nauth;
140*9a747e4fSDavid du Colombier 		break;
141*9a747e4fSDavid du Colombier */
142*9a747e4fSDavid du Colombier 
143*9a747e4fSDavid du Colombier 	case Tattach:
144*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
145*9a747e4fSDavid du Colombier 			return 0;
146*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
147*9a747e4fSDavid du Colombier 		p += BIT32SZ;
148*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
149*9a747e4fSDavid du Colombier 			return 0;
150*9a747e4fSDavid du Colombier 		f->afid = GBIT32(p);
151*9a747e4fSDavid du Colombier 		p += BIT32SZ;
152*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->uname);
153*9a747e4fSDavid du Colombier 		if(p == nil)
154*9a747e4fSDavid du Colombier 			break;
155*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->aname);
156*9a747e4fSDavid du Colombier 		if(p == nil)
157*9a747e4fSDavid du Colombier 			break;
158*9a747e4fSDavid du Colombier 		break;
159*9a747e4fSDavid du Colombier 
160*9a747e4fSDavid du Colombier 
161*9a747e4fSDavid du Colombier 	case Twalk:
162*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
163*9a747e4fSDavid du Colombier 			return 0;
164*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
165*9a747e4fSDavid du Colombier 		p += BIT32SZ;
166*9a747e4fSDavid du Colombier 		f->newfid = GBIT32(p);
167*9a747e4fSDavid du Colombier 		p += BIT32SZ;
168*9a747e4fSDavid du Colombier 		f->nwname = GBIT16(p);
169*9a747e4fSDavid du Colombier 		p += BIT16SZ;
170*9a747e4fSDavid du Colombier 		if(f->nwname > MAXWELEM)
171*9a747e4fSDavid du Colombier 			return 0;
172*9a747e4fSDavid du Colombier 		for(i=0; i<f->nwname; i++){
173*9a747e4fSDavid du Colombier 			p = gstring(p, ep, &f->wname[i]);
174*9a747e4fSDavid du Colombier 			if(p == nil)
175*9a747e4fSDavid du Colombier 				break;
176*9a747e4fSDavid du Colombier 		}
177*9a747e4fSDavid du Colombier 		break;
178*9a747e4fSDavid du Colombier 
179*9a747e4fSDavid du Colombier 	case Topen:
180*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT8SZ > ep)
181*9a747e4fSDavid du Colombier 			return 0;
182*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
183*9a747e4fSDavid du Colombier 		p += BIT32SZ;
184*9a747e4fSDavid du Colombier 		f->mode = GBIT8(p);
185*9a747e4fSDavid du Colombier 		p += BIT8SZ;
186*9a747e4fSDavid du Colombier 		break;
187*9a747e4fSDavid du Colombier 
188*9a747e4fSDavid du Colombier 	case Tcreate:
189*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
190*9a747e4fSDavid du Colombier 			return 0;
191*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
192*9a747e4fSDavid du Colombier 		p += BIT32SZ;
193*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->name);
194*9a747e4fSDavid du Colombier 		if(p == nil)
195*9a747e4fSDavid du Colombier 			break;
196*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT8SZ > ep)
197*9a747e4fSDavid du Colombier 			return 0;
198*9a747e4fSDavid du Colombier 		f->perm = GBIT32(p);
199*9a747e4fSDavid du Colombier 		p += BIT32SZ;
200*9a747e4fSDavid du Colombier 		f->mode = GBIT8(p);
201*9a747e4fSDavid du Colombier 		p += BIT8SZ;
202*9a747e4fSDavid du Colombier 		break;
203*9a747e4fSDavid du Colombier 
204*9a747e4fSDavid du Colombier 	case Tread:
205*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
206*9a747e4fSDavid du Colombier 			return 0;
207*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
208*9a747e4fSDavid du Colombier 		p += BIT32SZ;
209*9a747e4fSDavid du Colombier 		f->offset = GBIT64(p);
210*9a747e4fSDavid du Colombier 		p += BIT64SZ;
211*9a747e4fSDavid du Colombier 		f->count = GBIT32(p);
212*9a747e4fSDavid du Colombier 		p += BIT32SZ;
213*9a747e4fSDavid du Colombier 		break;
214*9a747e4fSDavid du Colombier 
215*9a747e4fSDavid du Colombier 	case Twrite:
216*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
217*9a747e4fSDavid du Colombier 			return 0;
218*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
219*9a747e4fSDavid du Colombier 		p += BIT32SZ;
220*9a747e4fSDavid du Colombier 		f->offset = GBIT64(p);
221*9a747e4fSDavid du Colombier 		p += BIT64SZ;
222*9a747e4fSDavid du Colombier 		f->count = GBIT32(p);
223*9a747e4fSDavid du Colombier 		p += BIT32SZ;
224*9a747e4fSDavid du Colombier 		if(p+f->count > ep)
225*9a747e4fSDavid du Colombier 			return 0;
226*9a747e4fSDavid du Colombier 		f->data = (char*)p;
227*9a747e4fSDavid du Colombier 		p += f->count;
228*9a747e4fSDavid du Colombier 		break;
229*9a747e4fSDavid du Colombier 
230*9a747e4fSDavid du Colombier 	case Tclunk:
231*9a747e4fSDavid du Colombier 	case Tremove:
232*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
233*9a747e4fSDavid du Colombier 			return 0;
234*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
235*9a747e4fSDavid du Colombier 		p += BIT32SZ;
236*9a747e4fSDavid du Colombier 		break;
237*9a747e4fSDavid du Colombier 
238*9a747e4fSDavid du Colombier 	case Tstat:
239*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
240*9a747e4fSDavid du Colombier 			return 0;
241*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
242*9a747e4fSDavid du Colombier 		p += BIT32SZ;
243*9a747e4fSDavid du Colombier 		break;
244*9a747e4fSDavid du Colombier 
245*9a747e4fSDavid du Colombier 	case Twstat:
246*9a747e4fSDavid du Colombier 		if(p+BIT32SZ+BIT16SZ > ep)
247*9a747e4fSDavid du Colombier 			return 0;
248*9a747e4fSDavid du Colombier 		f->fid = GBIT32(p);
249*9a747e4fSDavid du Colombier 		p += BIT32SZ;
250*9a747e4fSDavid du Colombier 		f->nstat = GBIT16(p);
251*9a747e4fSDavid du Colombier 		p += BIT16SZ;
252*9a747e4fSDavid du Colombier 		if(p+f->nstat > ep)
253*9a747e4fSDavid du Colombier 			return 0;
254*9a747e4fSDavid du Colombier 		f->stat = p;
255*9a747e4fSDavid du Colombier 		p += f->nstat;
256*9a747e4fSDavid du Colombier 		break;
257*9a747e4fSDavid du Colombier 
258*9a747e4fSDavid du Colombier /*
259*9a747e4fSDavid du Colombier  */
260*9a747e4fSDavid du Colombier 	case Rversion:
261*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
262*9a747e4fSDavid du Colombier 			return 0;
263*9a747e4fSDavid du Colombier 		f->msize = GBIT32(p);
264*9a747e4fSDavid du Colombier 		p += BIT32SZ;
265*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->version);
266*9a747e4fSDavid du Colombier 		break;
267*9a747e4fSDavid du Colombier 
268*9a747e4fSDavid du Colombier /*
269*9a747e4fSDavid du Colombier 	case Rsession:
270*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
271*9a747e4fSDavid du Colombier 			return 0;
272*9a747e4fSDavid du Colombier 		f->nchal = GBIT16(p);
273*9a747e4fSDavid du Colombier 		p += BIT16SZ;
274*9a747e4fSDavid du Colombier 		if(p+f->nchal > ep)
275*9a747e4fSDavid du Colombier 			return 0;
276*9a747e4fSDavid du Colombier 		f->chal = p;
277*9a747e4fSDavid du Colombier 		p += f->nchal;
278*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->authid);
279*9a747e4fSDavid du Colombier 		if(p == nil)
280*9a747e4fSDavid du Colombier 			break;
281*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->authdom);
282*9a747e4fSDavid du Colombier 		break;
283*9a747e4fSDavid du Colombier */
284*9a747e4fSDavid du Colombier 
285*9a747e4fSDavid du Colombier 	case Rerror:
286*9a747e4fSDavid du Colombier 		p = gstring(p, ep, &f->ename);
287*9a747e4fSDavid du Colombier 		break;
288*9a747e4fSDavid du Colombier 
289*9a747e4fSDavid du Colombier 	case Rflush:
290*9a747e4fSDavid du Colombier 		break;
291*9a747e4fSDavid du Colombier 
292*9a747e4fSDavid du Colombier /*
293*9a747e4fSDavid du Colombier 	case Rattach:
294*9a747e4fSDavid du Colombier 		p = gqid(p, ep, &f->qid);
295*9a747e4fSDavid du Colombier 		if(p == nil)
296*9a747e4fSDavid du Colombier 			break;
297*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
298*9a747e4fSDavid du Colombier 			return 0;
299*9a747e4fSDavid du Colombier 		f->nrauth = GBIT16(p);
300*9a747e4fSDavid du Colombier 		p += BIT16SZ;
301*9a747e4fSDavid du Colombier 		if(p+f->nrauth > ep)
302*9a747e4fSDavid du Colombier 			return 0;
303*9a747e4fSDavid du Colombier 		f->rauth = p;
304*9a747e4fSDavid du Colombier 		p += f->nrauth;
305*9a747e4fSDavid du Colombier 		break;
306*9a747e4fSDavid du Colombier */
307*9a747e4fSDavid du Colombier 
308*9a747e4fSDavid du Colombier 	case Rattach:
309*9a747e4fSDavid du Colombier 		p = gqid(p, ep, &f->qid);
310*9a747e4fSDavid du Colombier 		if(p == nil)
311*9a747e4fSDavid du Colombier 			break;
312*9a747e4fSDavid du Colombier 		break;
313*9a747e4fSDavid du Colombier 
314*9a747e4fSDavid du Colombier 
315*9a747e4fSDavid du Colombier 	case Rwalk:
316*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
317*9a747e4fSDavid du Colombier 			return 0;
318*9a747e4fSDavid du Colombier 		f->nwqid = GBIT16(p);
319*9a747e4fSDavid du Colombier 		p += BIT16SZ;
320*9a747e4fSDavid du Colombier 		if(f->nwqid > MAXWELEM)
321*9a747e4fSDavid du Colombier 			return 0;
322*9a747e4fSDavid du Colombier 		for(i=0; i<f->nwqid; i++){
323*9a747e4fSDavid du Colombier 			p = gqid(p, ep, &f->wqid[i]);
324*9a747e4fSDavid du Colombier 			if(p == nil)
325*9a747e4fSDavid du Colombier 				break;
326*9a747e4fSDavid du Colombier 		}
327*9a747e4fSDavid du Colombier 		break;
328*9a747e4fSDavid du Colombier 
329*9a747e4fSDavid du Colombier 	case Ropen:
330*9a747e4fSDavid du Colombier 	case Rcreate:
331*9a747e4fSDavid du Colombier 		p = gqid(p, ep, &f->qid);
332*9a747e4fSDavid du Colombier 		if(p == nil)
333*9a747e4fSDavid du Colombier 			break;
334*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
335*9a747e4fSDavid du Colombier 			return 0;
336*9a747e4fSDavid du Colombier 		f->iounit = GBIT32(p);
337*9a747e4fSDavid du Colombier 		p += BIT32SZ;
338*9a747e4fSDavid du Colombier 		break;
339*9a747e4fSDavid du Colombier 
340*9a747e4fSDavid du Colombier 	case Rread:
341*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
342*9a747e4fSDavid du Colombier 			return 0;
343*9a747e4fSDavid du Colombier 		f->count = GBIT32(p);
344*9a747e4fSDavid du Colombier 		p += BIT32SZ;
345*9a747e4fSDavid du Colombier 		if(p+f->count > ep)
346*9a747e4fSDavid du Colombier 			return 0;
347*9a747e4fSDavid du Colombier 		f->data = (char*)p;
348*9a747e4fSDavid du Colombier 		p += f->count;
349*9a747e4fSDavid du Colombier 		break;
350*9a747e4fSDavid du Colombier 
351*9a747e4fSDavid du Colombier 	case Rwrite:
352*9a747e4fSDavid du Colombier 		if(p+BIT32SZ > ep)
353*9a747e4fSDavid du Colombier 			return 0;
354*9a747e4fSDavid du Colombier 		f->count = GBIT32(p);
355*9a747e4fSDavid du Colombier 		p += BIT32SZ;
356*9a747e4fSDavid du Colombier 		break;
357*9a747e4fSDavid du Colombier 
358*9a747e4fSDavid du Colombier 	case Rclunk:
359*9a747e4fSDavid du Colombier 	case Rremove:
360*9a747e4fSDavid du Colombier 		break;
361*9a747e4fSDavid du Colombier 
362*9a747e4fSDavid du Colombier 	case Rstat:
363*9a747e4fSDavid du Colombier 		if(p+BIT16SZ > ep)
364*9a747e4fSDavid du Colombier 			return 0;
365*9a747e4fSDavid du Colombier 		f->nstat = GBIT16(p);
366*9a747e4fSDavid du Colombier 		p += BIT16SZ;
367*9a747e4fSDavid du Colombier 		if(p+f->nstat > ep)
368*9a747e4fSDavid du Colombier 			return 0;
369*9a747e4fSDavid du Colombier 		f->stat = p;
370*9a747e4fSDavid du Colombier 		p += f->nstat;
371*9a747e4fSDavid du Colombier 		break;
372*9a747e4fSDavid du Colombier 
373*9a747e4fSDavid du Colombier 	case Rwstat:
374*9a747e4fSDavid du Colombier 		break;
375*9a747e4fSDavid du Colombier 	}
376*9a747e4fSDavid du Colombier 
377*9a747e4fSDavid du Colombier 	if(p==nil || p>ep)
378*9a747e4fSDavid du Colombier 		return 0;
379*9a747e4fSDavid du Colombier 	if(ap+size == p)
380*9a747e4fSDavid du Colombier 		return size;
381*9a747e4fSDavid du Colombier 	return 0;
382*9a747e4fSDavid du Colombier }
383