xref: /plan9/sys/src/cmd/cwfs/9p1lib.c (revision 01a344a29f2ff35133953eaef092a50fc8c3163b)
1 #include "all.h"
2 
3 /* BUG transition */
4 // int client9p = 2;
5 // int kernel9p = 2;
6 
7 #include "9p1.h"
8 
9 #define	CHAR(x)		*p++ = f->x
10 #define	SHORT(x)	{ ulong vvv = f->x; *p++ = vvv; *p++ = vvv>>8; }
11 #define	LONGINT(q) {*p++ = (q); *p++ = (q)>>8; *p++ = (q)>>16; *p++ = (q)>>24;}
12 #define	LONG(x)		{ ulong vvv = f->x; LONGINT(vvv); }
13 #define	VLONG(x) { \
14 	uvlong q = f->x; \
15 	*p++ = (q)>> 0; *p++ = (q)>> 8; *p++ = (q)>>16; *p++ = (q)>>24; \
16 	*p++ = (q)>>32; *p++ = (q)>>40; *p++ = (q)>>48; *p++ = (q)>>56; \
17 	}
18 
19 #define	BYTES(x,n)	memmove(p, f->x, n); p += n
20 #define	STRING(x,n)	strncpy((char*)p, f->x, n); p += n
21 
22 int
convS2M9p1(Fcall * f,uchar * ap)23 convS2M9p1(Fcall *f, uchar *ap)
24 {
25 	uchar *p;
26 	int t;
27 
28 	p = ap;
29 	CHAR(type);
30 	t = f->type;
31 	SHORT(tag);
32 	switch(t) {
33 	default:
34 		print("convS2M9p1: bad type: %d\n", t);
35 		return 0;
36 
37 	case Tnop:
38 	case Tosession:
39 		break;
40 
41 	case Tsession:
42 		BYTES(chal, sizeof(f->chal));
43 		break;
44 
45 	case Tflush:
46 		SHORT(oldtag);
47 		break;
48 
49 	case Tattach:
50 		SHORT(fid);
51 		STRING(uname, sizeof(f->uname));
52 		STRING(aname, sizeof(f->aname));
53 		BYTES(ticket, sizeof(f->ticket));
54 		BYTES(auth, sizeof(f->auth));
55 		break;
56 
57 	case Toattach:
58 		SHORT(fid);
59 		STRING(uname, sizeof(f->uname));
60 		STRING(aname, sizeof(f->aname));
61 		BYTES(ticket, NAMELEN);
62 		break;
63 
64 	case Tclone:
65 		SHORT(fid);
66 		SHORT(newfid);
67 		break;
68 
69 	case Twalk:
70 		SHORT(fid);
71 		STRING(name, sizeof(f->name));
72 		break;
73 
74 	case Tclwalk:
75 		SHORT(fid);
76 		SHORT(newfid);
77 		STRING(name, sizeof(f->name));
78 		break;
79 
80 	case Topen:
81 		SHORT(fid);
82 		CHAR(mode);
83 		break;
84 
85 	case Tcreate:
86 		SHORT(fid);
87 		STRING(name, sizeof(f->name));
88 		LONG(perm);
89 		CHAR(mode);
90 		break;
91 
92 	case Tread:
93 		SHORT(fid);
94 		VLONG(offset);
95 		SHORT(count);
96 		break;
97 
98 	case Twrite:
99 		SHORT(fid);
100 		VLONG(offset);
101 		SHORT(count);
102 		p++;
103 		if((uchar*)p == (uchar*)f->data) {
104 			p += f->count;
105 			break;
106 		}
107 		BYTES(data, f->count);
108 		break;
109 
110 	case Tclunk:
111 	case Tremove:
112 	case Tstat:
113 		SHORT(fid);
114 		break;
115 
116 	case Twstat:
117 		SHORT(fid);
118 		BYTES(stat, sizeof(f->stat));
119 		break;
120 /*
121  */
122 	case Rnop:
123 	case Rosession:
124 	case Rflush:
125 		break;
126 
127 	case Rsession:
128 		BYTES(chal, sizeof(f->chal));
129 		BYTES(authid, sizeof(f->authid));
130 		BYTES(authdom, sizeof(f->authdom));
131 		break;
132 
133 	case Rerror:
134 		STRING(ename, sizeof(f->ename));
135 		break;
136 
137 	case Rclone:
138 	case Rclunk:
139 	case Rremove:
140 	case Rwstat:
141 		SHORT(fid);
142 		break;
143 
144 	case Rwalk:
145 	case Ropen:
146 	case Rcreate:
147 	case Rclwalk:
148 		SHORT(fid);
149 		LONG(qid.path);
150 		LONG(qid.version);
151 		break;
152 
153 	case Rattach:
154 		SHORT(fid);
155 		LONG(qid.path);
156 		LONG(qid.version);
157 		BYTES(rauth, sizeof(f->rauth));
158 		break;
159 
160 	case Roattach:
161 		SHORT(fid);
162 		LONG(qid.path);
163 		LONG(qid.version);
164 		break;
165 
166 	case Rread:
167 		SHORT(fid);
168 		SHORT(count);
169 		p++;
170 		if((uchar*)p == (uchar*)f->data) {
171 			p += f->count;
172 			break;
173 		}
174 		BYTES(data, f->count);
175 		break;
176 
177 	case Rwrite:
178 		SHORT(fid);
179 		SHORT(count);
180 		break;
181 
182 	case Rstat:
183 		SHORT(fid);
184 		BYTES(stat, sizeof(f->stat));
185 		break;
186 	}
187 	return p - (uchar*)ap;
188 }
189 
190 /*
191  * buggery to give false qid for
192  * the top 2 levels of the dump fs
193  */
194 static ulong
fakeqid9p1(Dentry * f)195 fakeqid9p1(Dentry *f)
196 {
197 	ulong q;
198 	int c;
199 
200 	q = f->qid.path;
201 	if(q == (QPROOT|QPDIR)) {
202 		c = f->name[0];
203 		if(isascii(c) && isdigit(c)) {
204 			q = 3|QPDIR;
205 			c = (c-'0')*10 + (f->name[1]-'0');
206 			if(c >= 1 && c <= 12)
207 				q = 4|QPDIR;
208 		}
209 	}
210 	return q;
211 }
212 
213 int
convD2M9p1(Dentry * f,char * ap)214 convD2M9p1(Dentry *f, char *ap)
215 {
216 	uchar *p;
217 	ulong q;
218 
219 	p = (uchar*)ap;
220 	STRING(name, sizeof(f->name));
221 
222 	memset(p, 0, 2*NAMELEN);
223 	uidtostr((char*)p, f->uid, 1);
224 	p += NAMELEN;
225 
226 	uidtostr((char*)p, f->gid, 1);
227 	p += NAMELEN;
228 
229 	q = fakeqid9p1(f);
230 	LONGINT(q);
231 	LONG(qid.version);
232 
233 	q = f->mode & 0x0fff;
234 	if(f->mode & DDIR)
235 		q |= PDIR;
236 	if(f->mode & DAPND)
237 		q |= PAPND;
238 	if(f->mode & DLOCK)
239 		q |= PLOCK;
240 	LONGINT(q);
241 
242 	LONG(atime);
243 	LONG(mtime);
244 	VLONG(size);
245 	LONGINT(0);
246 	return p - (uchar*)ap;
247 }
248 
249 int
convA2M9p1(Authenticator * f,char * ap,char * key)250 convA2M9p1(Authenticator *f, char *ap, char *key)
251 {
252 	int n;
253 	uchar *p;
254 
255 	p = (uchar*)ap;
256 	CHAR(num);
257 	BYTES(chal, CHALLEN);
258 	LONG(id);
259 	n = p - (uchar*)ap;
260 	if(key)
261 		encrypt(key, ap, n);
262 	return n;
263 }
264 
265 #undef	CHAR
266 #undef	SHORT
267 #undef	LONG
268 #undef	LONGINT
269 #undef	VLONG
270 #undef	BYTES
271 #undef	STRING
272 
273 #define	CHAR(x)		f->x = *p++
274 #define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
275 #define	LONG(x)	f->x = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); p += 4
276 #define	VLONG(x) { \
277 	f->x =	    (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)) | \
278 	    (uvlong)(p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24)) << 32; \
279 	p += 8; \
280 }
281 
282 #define	BYTES(x,n)	memmove(f->x, p, n); p += n
283 #define	STRING(x,n)	memmove(f->x, p, n); p += n
284 
285 int
convM2S9p1(uchar * ap,Fcall * f,int n)286 convM2S9p1(uchar *ap, Fcall *f, int n)
287 {
288 	uchar *p;
289 	int t;
290 
291 	p = ap;
292 	CHAR(type);
293 	t = f->type;
294 	SHORT(tag);
295 	switch(t) {
296 	default:
297 		/*
298 		 * only whine if it couldn't be a 9P2000 Tversion.
299 		 */
300 		if(t != 19 || ap[4] != 100)
301 			print("convM2S9p1: bad type: %d\n", f->type);
302 		return 0;
303 
304 	case Tnop:
305 	case Tosession:
306 		break;
307 
308 	case Tsession:
309 		BYTES(chal, sizeof(f->chal));
310 		break;
311 
312 	case Tflush:
313 		SHORT(oldtag);
314 		break;
315 
316 	case Tattach:
317 		SHORT(fid);
318 		BYTES(uname, sizeof(f->uname));
319 		BYTES(aname, sizeof(f->aname));
320 		BYTES(ticket, sizeof(f->ticket));
321 		BYTES(auth, sizeof(f->auth));
322 		break;
323 
324 	case Toattach:
325 		SHORT(fid);
326 		BYTES(uname, sizeof(f->uname));
327 		BYTES(aname, sizeof(f->aname));
328 		BYTES(ticket, NAMELEN);
329 		break;
330 
331 	case Tclone:
332 		SHORT(fid);
333 		SHORT(newfid);
334 		break;
335 
336 	case Twalk:
337 		SHORT(fid);
338 		BYTES(name, sizeof(f->name));
339 		break;
340 
341 	case Tclwalk:
342 		SHORT(fid);
343 		SHORT(newfid);
344 		BYTES(name, sizeof(f->name));
345 		break;
346 
347 	case Tremove:
348 		SHORT(fid);
349 		break;
350 
351 	case Topen:
352 		SHORT(fid);
353 		CHAR(mode);
354 		break;
355 
356 	case Tcreate:
357 		SHORT(fid);
358 		BYTES(name, sizeof(f->name));
359 		LONG(perm);
360 		CHAR(mode);
361 		break;
362 
363 	case Tread:
364 		SHORT(fid);
365 		VLONG(offset);
366 		SHORT(count);
367 		break;
368 
369 	case Twrite:
370 		SHORT(fid);
371 		VLONG(offset);
372 		SHORT(count);
373 		p++;
374 		f->data = (char*)p; p += f->count;
375 		break;
376 
377 	case Tclunk:
378 	case Tstat:
379 		SHORT(fid);
380 		break;
381 
382 	case Twstat:
383 		SHORT(fid);
384 		BYTES(stat, sizeof(f->stat));
385 		break;
386 
387 /*
388  */
389 	case Rnop:
390 	case Rosession:
391 		break;
392 
393 	case Rsession:
394 		BYTES(chal, sizeof(f->chal));
395 		BYTES(authid, sizeof(f->authid));
396 		BYTES(authdom, sizeof(f->authdom));
397 		break;
398 
399 	case Rerror:
400 		BYTES(ename, sizeof(f->ename));
401 		break;
402 
403 	case Rflush:
404 		break;
405 
406 	case Rclone:
407 	case Rclunk:
408 	case Rremove:
409 	case Rwstat:
410 		SHORT(fid);
411 		break;
412 
413 	case Rwalk:
414 	case Rclwalk:
415 	case Ropen:
416 	case Rcreate:
417 		SHORT(fid);
418 		LONG(qid.path);
419 		LONG(qid.version);
420 		break;
421 
422 	case Rattach:
423 		SHORT(fid);
424 		LONG(qid.path);
425 		LONG(qid.version);
426 		BYTES(rauth, sizeof(f->rauth));
427 		break;
428 
429 	case Roattach:
430 		SHORT(fid);
431 		LONG(qid.path);
432 		LONG(qid.version);
433 		break;
434 
435 	case Rread:
436 		SHORT(fid);
437 		SHORT(count);
438 		p++;
439 		f->data = (char*)p; p += f->count;
440 		break;
441 
442 	case Rwrite:
443 		SHORT(fid);
444 		SHORT(count);
445 		break;
446 
447 	case Rstat:
448 		SHORT(fid);
449 		BYTES(stat, sizeof(f->stat));
450 		break;
451 	}
452 	if((uchar*)ap+n == p)
453 		return n;
454 	return 0;
455 }
456 
457 int
convM2D9p1(char * ap,Dentry * f)458 convM2D9p1(char *ap, Dentry *f)
459 {
460 	uchar *p;
461 	char str[NAMELEN];
462 
463 	p = (uchar*)ap;
464 	BYTES(name, sizeof(f->name));
465 
466 	memmove(str, p, NAMELEN);
467 	p += NAMELEN;
468 	f->uid = strtouid(str);
469 
470 	memmove(str, p, NAMELEN);
471 	p += NAMELEN;
472 	f->gid = strtouid(str);
473 
474 	LONG(qid.path);
475 	LONG(qid.version);
476 
477 	LONG(atime);
478 	f->mode = (f->atime & 0x0fff) | DALLOC;
479 	if(f->atime & PDIR)
480 		f->mode |= DDIR;
481 	if(f->atime & PAPND)
482 		f->mode |= DAPND;
483 	if(f->atime & PLOCK)
484 		f->mode |= DLOCK;
485 
486 	LONG(atime);
487 	LONG(mtime);
488 	VLONG(size);
489 	p += 4;
490 	return p - (uchar*)ap;
491 }
492 
493 void
convM2A9p1(char * ap,Authenticator * f,char * key)494 convM2A9p1(char *ap, Authenticator *f, char *key)
495 {
496 	uchar *p;
497 
498 	if(key)
499 		decrypt(key, ap, AUTHENTLEN);
500 	p = (uchar*)ap;
501 	CHAR(num);
502 	BYTES(chal, CHALLEN);
503 	LONG(id);
504 	USED(p);
505 }
506 
507 void
convM2T9p1(char * ap,Ticket * f,char * key)508 convM2T9p1(char *ap, Ticket *f, char *key)
509 {
510 	uchar *p;
511 
512 	if(key)
513 		decrypt(key, ap, TICKETLEN);
514 	p = (uchar*)ap;
515 	CHAR(num);
516 	BYTES(chal, CHALLEN);
517 	STRING(cuid, NAMELEN);
518 	f->cuid[NAMELEN-1] = 0;
519 	STRING(suid, NAMELEN);
520 	f->suid[NAMELEN-1] = 0;
521 	BYTES(key, DESKEYLEN);
522 	USED(p);
523 }
524