xref: /plan9/sys/src/cmd/srvold9p/9p1lib.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include	"9p1.h"
5 #pragma	varargck	type	"D"	Dir*	/* from fcall.h */
6 
7 static void dumpsome(char*, char*, long);
8 
9 int
fcallfmt9p1(Fmt * f1)10 fcallfmt9p1(Fmt *f1)
11 {
12 	Fcall9p1 *f;
13 	int fid, type, tag, n;
14 	char buf[512];
15 	Dir d;
16 
17 	f = va_arg(f1->args, Fcall9p1*);
18 	type = f->type;
19 	fid = f->fid;
20 	tag = f->tag;
21 	switch(type){
22 	case Tnop9p1:	/* 50 */
23 		sprint(buf, "old Tnop tag %ud", tag);
24 		break;
25 	case Rnop9p1:
26 		sprint(buf, "old Rnop tag %ud", tag);
27 		break;
28 	case Tsession9p1:	/* 52 */
29 		sprint(buf, "old Tsession tag %ud", tag);
30 		break;
31 	case Rsession9p1:
32 		sprint(buf, "old Rsession tag %ud", tag);
33 		break;
34 	case Rerror9p1:	/* 55 */
35 		sprint(buf, "old Rerror tag %ud error %.64s", tag, f->ename);
36 		break;
37 	case Tflush9p1:	/* 56 */
38 		sprint(buf, "old Tflush tag %ud oldtag %d", tag, f->oldtag);
39 		break;
40 	case Rflush9p1:
41 		sprint(buf, "old Rflush tag %ud", tag);
42 		break;
43 	case Tattach9p1:	/* 58 */
44 		sprint(buf, "old Tattach tag %ud fid %d uname %.28s aname %.28s auth %.28s",
45 			tag, f->fid, f->uname, f->aname, f->auth);
46 		break;
47 	case Rattach9p1:
48 		sprint(buf, "old Rattach tag %ud fid %d qid 0x%lux|0x%lux",
49 			tag, fid, f->qid.path, f->qid.version);
50 		break;
51 	case Tclone9p1:	/* 60 */
52 		sprint(buf, "old Tclone tag %ud fid %d newfid %d", tag, fid, f->newfid);
53 		break;
54 	case Rclone9p1:
55 		sprint(buf, "old Rclone tag %ud fid %d", tag, fid);
56 		break;
57 	case Twalk9p1:	/* 62 */
58 		sprint(buf, "old Twalk tag %ud fid %d name %.28s", tag, fid, f->name);
59 		break;
60 	case Rwalk9p1:
61 		sprint(buf, "old Rwalk tag %ud fid %d qid 0x%lux|0x%lux",
62 			tag, fid, f->qid.path, f->qid.version);
63 		break;
64 	case Topen9p1:	/* 64 */
65 		sprint(buf, "old Topen tag %ud fid %d mode %d", tag, fid, f->mode);
66 		break;
67 	case Ropen9p1:
68 		sprint(buf, "old Ropen tag %ud fid %d qid 0x%lux|0x%lux",
69 			tag, fid, f->qid.path, f->qid.version);
70 		break;
71 	case Tcreate9p1:	/* 66 */
72 		sprint(buf, "old Tcreate tag %ud fid %d name %.28s perm 0x%lux mode %d",
73 			tag, fid, f->name, f->perm, f->mode);
74 		break;
75 	case Rcreate9p1:
76 		sprint(buf, "old Rcreate tag %ud fid %d qid 0x%lux|0x%lux",
77 			tag, fid, f->qid.path, f->qid.version);
78 		break;
79 	case Tread9p1:	/* 68 */
80 		sprint(buf, "old Tread tag %ud fid %d offset %ld count %ld",
81 			tag, fid, f->offset, f->count);
82 		break;
83 	case Rread9p1:
84 		n = sprint(buf, "old Rread tag %ud fid %d count %ld ", tag, fid, f->count);
85 			dumpsome(buf+n, f->data, f->count);
86 		break;
87 	case Twrite9p1:	/* 70 */
88 		n = sprint(buf, "old Twrite tag %ud fid %d offset %ld count %ld ",
89 			tag, fid, f->offset, f->count);
90 		dumpsome(buf+n, f->data, f->count);
91 		break;
92 	case Rwrite9p1:
93 		sprint(buf, "old Rwrite tag %ud fid %d count %ld", tag, fid, f->count);
94 		break;
95 	case Tclunk9p1:	/* 72 */
96 		sprint(buf, "old Tclunk tag %ud fid %d", tag, fid);
97 		break;
98 	case Rclunk9p1:
99 		sprint(buf, "old Rclunk tag %ud fid %d", tag, fid);
100 		break;
101 	case Tremove9p1:	/* 74 */
102 		sprint(buf, "old Tremove tag %ud fid %d", tag, fid);
103 		break;
104 	case Rremove9p1:
105 		sprint(buf, "old Rremove tag %ud fid %d", tag, fid);
106 		break;
107 	case Tstat9p1:	/* 76 */
108 		sprint(buf, "old Tstat tag %ud fid %d", tag, fid);
109 		break;
110 	case Rstat9p1:
111 		convM2D9p1(f->stat, &d);
112 		sprint(buf, "old Rstat tag %ud fid %d stat %D", tag, fid, &d);
113 		break;
114 	case Twstat9p1:	/* 78 */
115 		convM2D9p1(f->stat, &d);
116 		sprint(buf, "old Twstat tag %ud fid %d stat %D", tag, fid, &d);
117 		break;
118 	case Rwstat9p1:
119 		sprint(buf, "old Rwstat tag %ud fid %d", tag, fid);
120 		break;
121 	case Tclwalk9p1:	/* 81 */
122 		sprint(buf, "old Tclwalk tag %ud fid %d newfid %d name %.28s",
123 			tag, fid, f->newfid, f->name);
124 		break;
125 	case Rclwalk9p1:
126 		sprint(buf, "old Rclwalk tag %ud fid %d qid 0x%lux|0x%lux",
127 			tag, fid, f->qid.path, f->qid.version);
128 		break;
129 	default:
130 		sprint(buf,  "unknown type %d", type);
131 	}
132 	return fmtstrcpy(f1, buf);
133 }
134 
135 /*
136  * dump out count (or DUMPL, if count is bigger) bytes from
137  * buf to ans, as a string if they are all printable,
138  * else as a series of hex bytes
139  */
140 #define DUMPL 64
141 
142 static void
dumpsome(char * ans,char * buf,long count)143 dumpsome(char *ans, char *buf, long count)
144 {
145 	int i, printable;
146 	char *p;
147 
148 	printable = 1;
149 	if(count > DUMPL)
150 		count = DUMPL;
151 	for(i=0; i<count && printable; i++)
152 		if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
153 			printable = 0;
154 	p = ans;
155 	*p++ = '\'';
156 	if(printable){
157 		memmove(p, buf, count);
158 		p += count;
159 	}else{
160 		for(i=0; i<count; i++){
161 			if(i>0 && i%4==0)
162 				*p++ = ' ';
163 			sprint(p, "%2.2ux", buf[i]);
164 			p += 2;
165 		}
166 	}
167 	*p++ = '\'';
168 	*p = 0;
169 }
170 
171 #define	CHAR(x)		*p++ = f->x
172 #define	SHORT(x)	{ ulong vvv = f->x; p[0] = vvv; p[1] = vvv>>8; p += 2; }
173 #define	VLONG(q)	p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
174 #define	LONG(x)		{ ulong vvv = f->x; VLONG(vvv); }
175 #define	BYTES(x,n)	memmove(p, f->x, n); p += n
176 #define	STRING(x,n)	strncpy((char*)p, f->x, n); p += n
177 
178 int
convS2M9p1(Fcall9p1 * f,char * ap)179 convS2M9p1(Fcall9p1 *f, char *ap)
180 {
181 	uchar *p;
182 	int t;
183 
184 	p = (uchar*)ap;
185 	CHAR(type);
186 	t = f->type;
187 	SHORT(tag);
188 	switch(t)
189 	{
190 	default:
191 		fprint(2, "convS2M9p1: bad type: %d\n", t);
192 		return 0;
193 
194 	case Tnop9p1:
195 	case Tosession9p1:
196 		break;
197 
198 	case Tsession9p1:
199 		BYTES(chal, sizeof(f->chal));
200 		break;
201 
202 	case Tflush9p1:
203 		SHORT(oldtag);
204 		break;
205 
206 	case Tattach9p1:
207 		SHORT(fid);
208 		STRING(uname, sizeof(f->uname));
209 		STRING(aname, sizeof(f->aname));
210 		BYTES(ticket, sizeof(f->ticket));
211 		BYTES(auth, sizeof(f->auth));
212 		break;
213 
214 	case Toattach9p1:
215 		SHORT(fid);
216 		STRING(uname, sizeof(f->uname));
217 		STRING(aname, sizeof(f->aname));
218 		BYTES(ticket, NAMEREC);
219 		break;
220 
221 	case Tclone9p1:
222 		SHORT(fid);
223 		SHORT(newfid);
224 		break;
225 
226 	case Twalk9p1:
227 		SHORT(fid);
228 		STRING(name, sizeof(f->name));
229 		break;
230 
231 	case Tclwalk9p1:
232 		SHORT(fid);
233 		SHORT(newfid);
234 		STRING(name, sizeof(f->name));
235 		break;
236 
237 	case Topen9p1:
238 		SHORT(fid);
239 		CHAR(mode);
240 		break;
241 
242 	case Tcreate9p1:
243 		SHORT(fid);
244 		STRING(name, sizeof(f->name));
245 		LONG(perm);
246 		CHAR(mode);
247 		break;
248 
249 	case Tread9p1:
250 		SHORT(fid);
251 		LONG(offset); VLONG(0);
252 		SHORT(count);
253 		break;
254 
255 	case Twrite9p1:
256 		SHORT(fid);
257 		LONG(offset); VLONG(0);
258 		SHORT(count);
259 		p++;
260 		if((uchar*)p == (uchar*)f->data) {
261 			p += f->count;
262 			break;
263 		}
264 		BYTES(data, f->count);
265 		break;
266 
267 	case Tclunk9p1:
268 	case Tremove9p1:
269 	case Tstat9p1:
270 		SHORT(fid);
271 		break;
272 
273 	case Twstat9p1:
274 		SHORT(fid);
275 		BYTES(stat, sizeof(f->stat));
276 		break;
277 /*
278  */
279 	case Rnop9p1:
280 	case Rosession9p1:
281 	case Rflush9p1:
282 		break;
283 
284 	case Rsession9p1:
285 		BYTES(chal, sizeof(f->chal));
286 		BYTES(authid, sizeof(f->authid));
287 		BYTES(authdom, sizeof(f->authdom));
288 		break;
289 
290 	case Rerror9p1:
291 		STRING(ename, sizeof(f->ename));
292 		break;
293 
294 	case Rclone9p1:
295 	case Rclunk9p1:
296 	case Rremove9p1:
297 	case Rwstat9p1:
298 		SHORT(fid);
299 		break;
300 
301 	case Rwalk9p1:
302 	case Ropen9p1:
303 	case Rcreate9p1:
304 	case Rclwalk9p1:
305 		SHORT(fid);
306 		LONG(qid.path);
307 		LONG(qid.version);
308 		break;
309 
310 	case Rattach9p1:
311 		SHORT(fid);
312 		LONG(qid.path);
313 		LONG(qid.version);
314 		BYTES(rauth, sizeof(f->rauth));
315 		break;
316 
317 	case Roattach9p1:
318 		SHORT(fid);
319 		LONG(qid.path);
320 		LONG(qid.version);
321 		break;
322 
323 	case Rread9p1:
324 		SHORT(fid);
325 		SHORT(count);
326 		p++;
327 		if((uchar*)p == (uchar*)f->data) {
328 			p += f->count;
329 			break;
330 		}
331 		BYTES(data, f->count);
332 		break;
333 
334 	case Rwrite9p1:
335 		SHORT(fid);
336 		SHORT(count);
337 		break;
338 
339 	case Rstat9p1:
340 		SHORT(fid);
341 		BYTES(stat, sizeof(f->stat));
342 		break;
343 	}
344 	return p - (uchar*)ap;
345 }
346 
347 int
convD2M9p1(Dir * f,char * ap)348 convD2M9p1(Dir *f, char *ap)
349 {
350 	uchar *p;
351 	ulong q;
352 
353 	p = (uchar*)ap;
354 	STRING(name, NAMEREC);
355 	STRING(uid, NAMEREC);
356 	STRING(gid, NAMEREC);
357 
358 	q = f->qid.path & ~0x80000000;
359 	if(f->qid.type & QTDIR)
360 		q |= 0x80000000;
361 	VLONG(q);
362 	LONG(qid.vers);
363 	LONG(mode);
364 	LONG(atime);
365 	LONG(mtime);
366 	LONG(length); VLONG(0);
367 	VLONG(0);
368 	return p - (uchar*)ap;
369 }
370 
371 int
convA2M9p1(Authenticator * f,char * ap,char * key)372 convA2M9p1(Authenticator *f, char *ap, char *key)
373 {
374 	int n;
375 	uchar *p;
376 
377 	p = (uchar*)ap;
378 	CHAR(num);
379 	STRING(chal, CHALLEN);
380 	LONG(id);
381 	n = p - (uchar*)ap;
382 	if(key)
383 		encrypt(key, ap, n);
384 	return n;
385 }
386 
387 #undef	CHAR
388 #undef	SHORT
389 #undef	LONG
390 #undef	VLONG
391 #undef	BYTES
392 #undef	STRING
393 
394 #define	CHAR(x)		f->x = *p++
395 #define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
396 #define	VLONG(q)	q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
397 #define	LONG(x)		VLONG(f->x)
398 #define	BYTES(x,n)	memmove(f->x, p, n); p += n
399 #define	STRING(x,n)	memmove(f->x, p, n); p += n
400 
401 int
convM2S9p1(char * ap,Fcall9p1 * f,int n)402 convM2S9p1(char *ap, Fcall9p1 *f, int n)
403 {
404 	uchar *p;
405 	int t;
406 
407 	p = (uchar*)ap;
408 	CHAR(type);
409 	t = f->type;
410 	SHORT(tag);
411 	switch(t)
412 	{
413 	default:
414 		fprint(2, "convM2S9p1: bad type: %d\n", f->type);
415 		return 0;
416 
417 	case Tnop9p1:
418 	case Tosession9p1:
419 		break;
420 
421 	case Tsession9p1:
422 		BYTES(chal, sizeof(f->chal));
423 		break;
424 
425 	case Tflush9p1:
426 		SHORT(oldtag);
427 		break;
428 
429 	case Tattach9p1:
430 		SHORT(fid);
431 		BYTES(uname, sizeof(f->uname));
432 		BYTES(aname, sizeof(f->aname));
433 		BYTES(ticket, sizeof(f->ticket));
434 		BYTES(auth, sizeof(f->auth));
435 		break;
436 
437 	case Toattach9p1:
438 		SHORT(fid);
439 		BYTES(uname, sizeof(f->uname));
440 		BYTES(aname, sizeof(f->aname));
441 		BYTES(ticket, NAMEREC);
442 		break;
443 
444 	case Tclone9p1:
445 		SHORT(fid);
446 		SHORT(newfid);
447 		break;
448 
449 	case Twalk9p1:
450 		SHORT(fid);
451 		BYTES(name, sizeof(f->name));
452 		break;
453 
454 	case Tclwalk9p1:
455 		SHORT(fid);
456 		SHORT(newfid);
457 		BYTES(name, sizeof(f->name));
458 		break;
459 
460 	case Tremove9p1:
461 		SHORT(fid);
462 		break;
463 
464 	case Topen9p1:
465 		SHORT(fid);
466 		CHAR(mode);
467 		break;
468 
469 	case Tcreate9p1:
470 		SHORT(fid);
471 		BYTES(name, sizeof(f->name));
472 		LONG(perm);
473 		CHAR(mode);
474 		break;
475 
476 	case Tread9p1:
477 		SHORT(fid);
478 		LONG(offset); p += 4;
479 		SHORT(count);
480 		break;
481 
482 	case Twrite9p1:
483 		SHORT(fid);
484 		LONG(offset); p += 4;
485 		SHORT(count);
486 		p++;
487 		f->data = (char*)p; p += f->count;
488 		break;
489 
490 	case Tclunk9p1:
491 	case Tstat9p1:
492 		SHORT(fid);
493 		break;
494 
495 	case Twstat9p1:
496 		SHORT(fid);
497 		BYTES(stat, sizeof(f->stat));
498 		break;
499 
500 /*
501  */
502 	case Rnop9p1:
503 	case Rosession9p1:
504 		break;
505 
506 	case Rsession9p1:
507 		BYTES(chal, sizeof(f->chal));
508 		BYTES(authid, sizeof(f->authid));
509 		BYTES(authdom, sizeof(f->authdom));
510 		break;
511 
512 	case Rerror9p1:
513 		BYTES(ename, sizeof(f->ename));
514 		break;
515 
516 	case Rflush9p1:
517 		break;
518 
519 	case Rclone9p1:
520 	case Rclunk9p1:
521 	case Rremove9p1:
522 	case Rwstat9p1:
523 		SHORT(fid);
524 		break;
525 
526 	case Rwalk9p1:
527 	case Rclwalk9p1:
528 	case Ropen9p1:
529 	case Rcreate9p1:
530 		SHORT(fid);
531 		LONG(qid.path);
532 		LONG(qid.version);
533 		break;
534 
535 	case Rattach9p1:
536 		SHORT(fid);
537 		LONG(qid.path);
538 		LONG(qid.version);
539 		BYTES(rauth, sizeof(f->rauth));
540 		break;
541 
542 	case Roattach9p1:
543 		SHORT(fid);
544 		LONG(qid.path);
545 		LONG(qid.version);
546 		break;
547 
548 	case Rread9p1:
549 		SHORT(fid);
550 		SHORT(count);
551 		p++;
552 		f->data = (char*)p; p += f->count;
553 		break;
554 
555 	case Rwrite9p1:
556 		SHORT(fid);
557 		SHORT(count);
558 		break;
559 
560 	case Rstat9p1:
561 		SHORT(fid);
562 		BYTES(stat, sizeof(f->stat));
563 		break;
564 	}
565 	if((uchar*)ap+n == p)
566 		return n;
567 	return 0;
568 }
569 
570 int
convM2D9p1(char * ap,Dir * f)571 convM2D9p1(char *ap, Dir *f)
572 {
573 	uchar *p;
574 
575 	p = (uchar*)ap;
576 	f->name = (char*)p;
577 	p += NAMEREC;
578 	f->uid = (char*)p;
579 	f->muid = (char*)p;
580 	p += NAMEREC;
581 	f->gid = (char*)p;
582 	p += NAMEREC;
583 
584 	LONG(qid.path);
585 	f->qid.path &= ~0x80000000;
586 
587 	LONG(qid.vers);
588 	LONG(mode);
589 	f->qid.type = f->mode >> 24;
590 	LONG(atime);
591 	LONG(mtime);
592 	LONG(length); p += 4;
593 	p += 4;
594 	return p - (uchar*)ap;
595 }
596 
597 void
convM2A9p1(char * ap,Authenticator * f,char * key)598 convM2A9p1(char *ap, Authenticator *f, char *key)
599 {
600 	uchar *p;
601 
602 	if(key)
603 		decrypt(key, ap, AUTHENTLEN);
604 	p = (uchar*)ap;
605 	CHAR(num);
606 	STRING(chal, CHALLEN);
607 	LONG(id);
608 	USED(p);
609 }
610 
611 void
convM2T9p1(char * ap,Ticket * f,char * key)612 convM2T9p1(char *ap, Ticket *f, char *key)
613 {
614 	uchar *p;
615 
616 	if(key)
617 		decrypt(key, ap, TICKETLEN);
618 	p = (uchar*)ap;
619 	CHAR(num);
620 	STRING(chal, CHALLEN);
621 	STRING(cuid, NAMEREC);
622 	f->cuid[NAMEREC-1] = 0;
623 	STRING(suid, NAMEREC);
624 	f->suid[NAMEREC-1] = 0;
625 	STRING(key, DESKEYLEN);
626 	USED(p);
627 };
628