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