1 #include <plan9.h>
2 #include <fcall.h>
3 #include <oldfcall.h>
4
5 /*
6 * routines to package the old protocol in the new structures.
7 */
8
9 #define SHORT(x) p[0]=f->x; p[1]=f->x>>8; p += 2
10 #define LONG(x) p[0]=f->x; p[1]=f->x>>8; p[2]=f->x>>16; p[3]=f->x>>24; p += 4
11 #define VLONG(x) p[0]=f->x; p[1]=f->x>>8;\
12 p[2]=f->x>>16; p[3]=f->x>>24;\
13 p[4]=f->x>>32; p[5]=f->x>>40;\
14 p[6]=f->x>>48; p[7]=f->x>>56;\
15 p += 8
16 #define STRING(x,n) strecpy((char*)p, (char*)p+n, f->x); p += n;
17 #define FIXQID(q) q.path ^= (q.path>>33); q.path &= 0x7FFFFFFF; q.path |= (q.type&0x80)<<24
18
19 uint
oldhdrsize(uchar type)20 oldhdrsize(uchar type)
21 {
22 switch(type){
23 default:
24 return 0;
25 case oldTnop:
26 return 3;
27 case oldTflush:
28 return 3+2;
29 case oldTclone:
30 return 3+2+2;
31 case oldTwalk:
32 return 3+2+28;
33 case oldTopen:
34 return 3+2+1;
35 case oldTcreate:
36 return 3+2+28+4+1;
37 case oldTread:
38 return 3+2+8+2;
39 case oldTwrite:
40 return 3+2+8+2+1;
41 case oldTclunk:
42 return 3+2;
43 case oldTremove:
44 return 3+2;
45 case oldTstat:
46 return 3+2;
47 case oldTwstat:
48 return 3+2+116;
49 case oldTsession:
50 return 3+8;
51 case oldTattach:
52 return 3+2+28+28+72+13;
53 }
54 }
55
56 uint
iosize(uchar * p)57 iosize(uchar *p)
58 {
59 if(p[0] != oldTwrite)
60 return 0;
61 return p[3+2+8] | (p[3+2+8+1]<<8);
62 }
63
64 uint
sizeS2M(Fcall * f)65 sizeS2M(Fcall *f)
66 {
67 switch(f->type)
68 {
69 default:
70 abort();
71 return 0;
72
73 /* no T messages */
74
75 /*
76 */
77 case Rversion:
78 return 1+2;
79
80 /*
81 case Rsession:
82 return 1+2+8+28+48;
83 */
84
85 case Rattach:
86 return 1+2+2+4+4+13;
87
88 case Rerror:
89 return 1+2+64;
90
91 case Rflush:
92 if(f->tag&0x8000)
93 return 1+2+8+28+48; /* session */
94 return 1+2;
95
96 /* assumes we don't ever see Tclwalk requests ... */
97 case Rwalk:
98 if(f->nwqid == 0)
99 return 1+2+2;
100 else
101 return 1+2+2+4+4;
102
103 case Ropen:
104 return 1+2+2+4+4;
105
106 case Rcreate:
107 return 1+2+2+4+4;
108
109 case Rread:
110 return 1+2+2+2+1+f->count;
111
112 case Rwrite:
113 return 1+2+2+2;
114
115 case Rclunk:
116 return 1+2+2;
117
118 case Rremove:
119 return 1+2+2;
120
121 case Rstat:
122 return 1+2+2+116;
123
124 case Rwstat:
125 return 1+2+2;
126 }
127 }
128
129 uint
convS2Mold(Fcall * f,uchar * ap,uint nap)130 convS2Mold(Fcall *f, uchar *ap, uint nap)
131 {
132 uchar *p;
133
134 if(nap < sizeS2M(f))
135 return 0;
136
137 p = ap;
138 switch(f->type)
139 {
140 default:
141 abort();
142 return 0;
143
144 /* no T messages */
145
146 /*
147 */
148 case Rversion:
149 *p++ = oldRnop;
150 SHORT(tag);
151 break;
152
153 /*
154 case Rsession:
155 *p++ = oldRsession;
156 SHORT(tag);
157
158 if(f->nchal > 8)
159 f->nchal = 8;
160 memmove(p, f->chal, f->nchal);
161 p += f->nchal;
162 if(f->nchal < 8){
163 memset(p, 0, 8 - f->nchal);
164 p += 8 - f->nchal;
165 }
166
167 STRING(authid, 28);
168 STRING(authdom, 48);
169 break;
170 */
171
172 case Rattach:
173 *p++ = oldRattach;
174 SHORT(tag);
175 SHORT(fid);
176 FIXQID(f->qid);
177 LONG(qid.path);
178 LONG(qid.vers);
179 memset(p, 0, 13);
180 p += 13;
181 break;
182
183 case Rerror:
184 *p++ = oldRerror;
185 SHORT(tag);
186 STRING(ename, 64);
187 break;
188
189 case Rflush:
190 if(f->tag&0x8000){
191 *p++ = oldRsession;
192 f->tag &= ~0x8000;
193 SHORT(tag);
194 memset(p, 0, 8+28+48);
195 p += 8+28+48;
196 }else{
197 *p++ = oldRflush;
198 SHORT(tag);
199 }
200 break;
201
202 /* assumes we don't ever see Tclwalk requests ... */
203 case Rwalk:
204 if(f->nwqid == 0){ /* successful clone */
205 *p++ = oldRclone;
206 SHORT(tag);
207 SHORT(fid);
208 }else{ /* successful 1-element walk */
209 *p++ = oldRwalk;
210 SHORT(tag);
211 SHORT(fid);
212 FIXQID(f->wqid[0]);
213 LONG(wqid[0].path);
214 LONG(wqid[0].vers);
215 }
216 break;
217
218 case Ropen:
219 *p++ = oldRopen;
220 SHORT(tag);
221 SHORT(fid);
222 FIXQID(f->qid);
223 LONG(qid.path);
224 LONG(qid.vers);
225 break;
226
227 case Rcreate:
228 *p++ = oldRcreate;
229 SHORT(tag);
230 SHORT(fid);
231 FIXQID(f->qid);
232 LONG(qid.path);
233 LONG(qid.vers);
234 break;
235
236 case Rread:
237 *p++ = oldRread;
238 SHORT(tag);
239 SHORT(fid);
240 SHORT(count);
241 p++; /* pad(1) */
242 memmove(p, f->data, f->count);
243 p += f->count;
244 break;
245
246 case Rwrite:
247 *p++ = oldRwrite;
248 SHORT(tag);
249 SHORT(fid);
250 SHORT(count);
251 break;
252
253 case Rclunk:
254 *p++ = oldRclunk;
255 SHORT(tag);
256 SHORT(fid);
257 break;
258
259 case Rremove:
260 *p++ = oldRremove;
261 SHORT(tag);
262 SHORT(fid);
263 break;
264
265 case Rstat:
266 *p++ = oldRstat;
267 SHORT(tag);
268 SHORT(fid);
269 memmove(p, f->stat, 116);
270 p += 116;
271 break;
272
273 case Rwstat:
274 *p++ = oldRwstat;
275 SHORT(tag);
276 SHORT(fid);
277 break;
278 }
279 return p - ap;
280 }
281
282 uint
sizeD2Mold(Dir * d)283 sizeD2Mold(Dir *d)
284 {
285 return 116;
286 }
287
288 uint
convD2Mold(Dir * f,uchar * ap,uint nap)289 convD2Mold(Dir *f, uchar *ap, uint nap)
290 {
291 uchar *p;
292
293 if(nap < 116)
294 return 0;
295
296 p = ap;
297 STRING(name, 28);
298 STRING(uid, 28);
299 STRING(gid, 28);
300 FIXQID(f->qid);
301 LONG(qid.path);
302 LONG(qid.vers);
303 LONG(mode);
304 LONG(atime);
305 LONG(mtime);
306 VLONG(length);
307 SHORT(type);
308 SHORT(dev);
309
310 return p - ap;
311 }
312
313 #undef SHORT
314 #undef LONG
315 #undef VLONG
316 #undef STRING
317 #define CHAR(x) f->x = *p++
318 #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2
319 #define LONG(x) f->x = (p[0] | (p[1]<<8) |\
320 (p[2]<<16) | (p[3]<<24)); p += 4
321 #define VLONG(x) f->x = (ulong)(p[0] | (p[1]<<8) |\
322 (p[2]<<16) | (p[3]<<24)) |\
323 ((vlong)(p[4] | (p[5]<<8) |\
324 (p[6]<<16) | (p[7]<<24)) << 32); p += 8
325 #define STRING(x,n) f->x = (char*)p; p += n
326
327 uint
convM2Sold(uchar * ap,uint nap,Fcall * f)328 convM2Sold(uchar *ap, uint nap, Fcall *f)
329 {
330 uchar *p, *q, *ep;
331
332 p = ap;
333 ep = p + nap;
334
335 if(p+3 > ep)
336 return 0;
337
338 switch(*p++){
339 case oldTnop:
340 f->type = Tversion;
341 SHORT(tag);
342 f->msize = 0;
343 f->version = "9P1";
344 break;
345
346 case oldTflush:
347 f->type = Tflush;
348 SHORT(tag);
349 if(p+2 > ep)
350 return 0;
351 SHORT(oldtag);
352 break;
353
354 case oldTclone:
355 f->type = Twalk;
356 SHORT(tag);
357 if(p+2+2 > ep)
358 return 0;
359 SHORT(fid);
360 SHORT(newfid);
361 f->nwname = 0;
362 break;
363
364 case oldTwalk:
365 f->type = Twalk;
366 SHORT(tag);
367 if(p+2+28 > ep)
368 return 0;
369 SHORT(fid);
370 f->newfid = f->fid;
371 f->nwname = 1;
372 f->wname[0] = (char*)p;
373 p += 28;
374 break;
375
376 case oldTopen:
377 f->type = Topen;
378 SHORT(tag);
379 if(p+2+1 > ep)
380 return 0;
381 SHORT(fid);
382 CHAR(mode);
383 break;
384
385 case oldTcreate:
386 f->type = Tcreate;
387 SHORT(tag);
388 if(p+2+28+4+1 > ep)
389 return 0;
390 SHORT(fid);
391 f->name = (char*)p;
392 p += 28;
393 LONG(perm);
394 CHAR(mode);
395 break;
396
397 case oldTread:
398 f->type = Tread;
399 SHORT(tag);
400 if(p+2+8+2 > ep)
401 return 0;
402 SHORT(fid);
403 VLONG(offset);
404 SHORT(count);
405 break;
406
407 case oldTwrite:
408 f->type = Twrite;
409 SHORT(tag);
410 if(p+2+8+2+1 > ep)
411 return 0;
412 SHORT(fid);
413 VLONG(offset);
414 SHORT(count);
415 p++; /* pad(1) */
416 if(p+f->count > ep)
417 return 0;
418 f->data = (char*)p;
419 p += f->count;
420 break;
421
422 case oldTclunk:
423 f->type = Tclunk;
424 SHORT(tag);
425 if(p+2 > ep)
426 return 0;
427 SHORT(fid);
428 break;
429
430 case oldTremove:
431 f->type = Tremove;
432 SHORT(tag);
433 if(p+2 > ep)
434 return 0;
435 SHORT(fid);
436 break;
437
438 case oldTstat:
439 f->type = Tstat;
440 f->nstat = 116;
441 SHORT(tag);
442 if(p+2 > ep)
443 return 0;
444 SHORT(fid);
445 break;
446
447 case oldTwstat:
448 f->type = Twstat;
449 SHORT(tag);
450 if(p+2+116 > ep)
451 return 0;
452 SHORT(fid);
453 f->stat = p;
454 q = p+28*3+5*4;
455 memset(q, 0xFF, 8); /* clear length to ``don't care'' */
456 p += 116;
457 break;
458
459 /*
460 case oldTsession:
461 f->type = Tsession;
462 SHORT(tag);
463 if(p+8 > ep)
464 return 0;
465 f->chal = p;
466 p += 8;
467 f->nchal = 8;
468 break;
469 */
470 case oldTsession:
471 f->type = Tflush;
472 SHORT(tag);
473 f->tag |= 0x8000;
474 f->oldtag = f->tag;
475 p += 8;
476 break;
477
478 case oldTattach:
479 f->type = Tattach;
480 SHORT(tag);
481 if(p+2+28+28+72+13 > ep)
482 return 0;
483 SHORT(fid);
484 STRING(uname, 28);
485 STRING(aname, 28);
486 p += 72+13;
487 f->afid = NOFID;
488 break;
489
490 default:
491 return 0;
492 }
493
494 return p-ap;
495 }
496
497 uint
convM2Dold(uchar * ap,uint nap,Dir * f,char * strs)498 convM2Dold(uchar *ap, uint nap, Dir *f, char *strs)
499 {
500 uchar *p;
501
502 USED(strs);
503
504 if(nap < 116)
505 return 0;
506
507 p = (uchar*)ap;
508 STRING(name, 28);
509 STRING(uid, 28);
510 STRING(gid, 28);
511 LONG(qid.path);
512 LONG(qid.vers);
513 LONG(mode);
514 LONG(atime);
515 LONG(mtime);
516 VLONG(length);
517 SHORT(type);
518 SHORT(dev);
519 f->qid.type = (f->mode>>24)&0xF0;
520 return p - (uchar*)ap;
521 }
522