xref: /plan9/sys/src/cmd/disk/kfs/9p1lib.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 #include "all.h"
2 #include "9p1.h"
3 
4 #define	CHAR(x)		*p++ = f->x
5 #define	SHORT(x)	{ ulong vvv = f->x; p[0] = vvv; p[1] = vvv>>8; p += 2; }
6 #define	VLONG(q)	p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
7 #define	LONG(x)		{ ulong vvv = f->x; VLONG(vvv); }
8 #define	BYTES(x,n)	memmove(p, f->x, n); p += n
9 #define	STRING(x,n)	strncpy((char*)p, f->x, n); p += n
10 
11 int
convS2M9p1(Oldfcall * f,uchar * ap)12 convS2M9p1(Oldfcall *f, uchar *ap)
13 {
14 	uchar *p;
15 	int t;
16 
17 	p = ap;
18 	CHAR(type);
19 	t = f->type;
20 	SHORT(tag);
21 	switch(t)
22 	{
23 	default:
24 		print("convS2M9p1: bad type: %d\n", t);
25 		return 0;
26 
27 	case Tnop9p1:
28 	case Tosession9p1:
29 		break;
30 
31 	case Tsession9p1:
32 		BYTES(chal, sizeof(f->chal));
33 		break;
34 
35 	case Tflush9p1:
36 		SHORT(oldtag);
37 		break;
38 
39 	case Tattach9p1:
40 		SHORT(fid);
41 		STRING(uname, sizeof(f->uname));
42 		STRING(aname, sizeof(f->aname));
43 		BYTES(ticket, sizeof(f->ticket));
44 		BYTES(auth, sizeof(f->auth));
45 		break;
46 
47 	case Toattach9p1:
48 		SHORT(fid);
49 		STRING(uname, sizeof(f->uname));
50 		STRING(aname, sizeof(f->aname));
51 		BYTES(ticket, NAMELEN);
52 		break;
53 
54 	case Tclone9p1:
55 		SHORT(fid);
56 		SHORT(newfid);
57 		break;
58 
59 	case Twalk9p1:
60 		SHORT(fid);
61 		STRING(name, sizeof(f->name));
62 		break;
63 
64 	case Tclwalk9p1:
65 		SHORT(fid);
66 		SHORT(newfid);
67 		STRING(name, sizeof(f->name));
68 		break;
69 
70 	case Topen9p1:
71 		SHORT(fid);
72 		CHAR(mode);
73 		break;
74 
75 	case Tcreate9p1:
76 		SHORT(fid);
77 		STRING(name, sizeof(f->name));
78 		LONG(perm);
79 		CHAR(mode);
80 		break;
81 
82 	case Tread9p1:
83 		SHORT(fid);
84 		LONG(offset); VLONG(0);
85 		SHORT(count);
86 		break;
87 
88 	case Twrite9p1:
89 		SHORT(fid);
90 		LONG(offset); VLONG(0);
91 		SHORT(count);
92 		p++;
93 		if((uchar*)p == (uchar*)f->data) {
94 			p += f->count;
95 			break;
96 		}
97 		BYTES(data, f->count);
98 		break;
99 
100 	case Tclunk9p1:
101 	case Tremove9p1:
102 	case Tstat9p1:
103 		SHORT(fid);
104 		break;
105 
106 	case Twstat9p1:
107 		SHORT(fid);
108 		BYTES(stat, sizeof(f->stat));
109 		break;
110 /*
111  */
112 	case Rnop9p1:
113 	case Rosession9p1:
114 	case Rflush9p1:
115 		break;
116 
117 	case Rsession9p1:
118 		BYTES(chal, sizeof(f->chal));
119 		BYTES(authid, sizeof(f->authid));
120 		BYTES(authdom, sizeof(f->authdom));
121 		break;
122 
123 	case Rerror9p1:
124 		STRING(ename, sizeof(f->ename));
125 		break;
126 
127 	case Rclone9p1:
128 	case Rclunk9p1:
129 	case Rremove9p1:
130 	case Rwstat9p1:
131 		SHORT(fid);
132 		break;
133 
134 	case Rwalk9p1:
135 	case Ropen9p1:
136 	case Rcreate9p1:
137 	case Rclwalk9p1:
138 		SHORT(fid);
139 		LONG(qid.path);
140 		LONG(qid.version);
141 		break;
142 
143 	case Rattach9p1:
144 		SHORT(fid);
145 		LONG(qid.path);
146 		LONG(qid.version);
147 		BYTES(rauth, sizeof(f->rauth));
148 		break;
149 
150 	case Roattach9p1:
151 		SHORT(fid);
152 		LONG(qid.path);
153 		LONG(qid.version);
154 		break;
155 
156 	case Rread9p1:
157 		SHORT(fid);
158 		SHORT(count);
159 		p++;
160 		if((uchar*)p == (uchar*)f->data) {
161 			p += f->count;
162 			break;
163 		}
164 		BYTES(data, f->count);
165 		break;
166 
167 	case Rwrite9p1:
168 		SHORT(fid);
169 		SHORT(count);
170 		break;
171 
172 	case Rstat9p1:
173 		SHORT(fid);
174 		BYTES(stat, sizeof(f->stat));
175 		break;
176 	}
177 	return p - (uchar*)ap;
178 }
179 
180 /*
181  * buggery to give false qid for
182  * the top 2 levels of the dump fs
183  */
184 static ulong
fakeqid9p1(Dentry * f)185 fakeqid9p1(Dentry *f)
186 {
187 	ulong q;
188 	int c;
189 
190 	q = f->qid.path;
191 	if(q == (QPROOT|QPDIR)) {
192 		c = f->name[0];
193 		if(c >= '0' && c <= '9') {
194 			q = 3|QPDIR;
195 			c = (c-'0')*10 + (f->name[1]-'0');
196 			if(c >= 1 && c <= 12)
197 				q = 4|QPDIR;
198 		}
199 	}
200 	return q;
201 }
202 
203 int
convD2M9p1(Dentry * f,char * ap)204 convD2M9p1(Dentry *f, char *ap)
205 {
206 	uchar *p;
207 	ulong q;
208 
209 	p = (uchar*)ap;
210 	STRING(name, sizeof(f->name));
211 
212 	memset(p, 0, 2*NAMELEN);
213 	uidtostr((char*)p, f->uid);
214 	p += NAMELEN;
215 
216 	uidtostr((char*)p, f->gid);
217 	p += NAMELEN;
218 
219 	q = fakeqid9p1(f);
220 	VLONG(q);
221 	LONG(qid.version);
222 	{
223 		q = f->mode & 0x0fff;
224 		if(f->mode & DDIR)
225 			q |= PDIR;
226 		if(f->mode & DAPND)
227 			q |= PAPND;
228 		if(f->mode & DLOCK)
229 			q |= PLOCK;
230 		VLONG(q);
231 	}
232 	LONG(atime);
233 	LONG(mtime);
234 	LONG(size); VLONG(0);
235 	VLONG(0);
236 	return p - (uchar*)ap;
237 }
238 
239 #undef	CHAR
240 #undef	SHORT
241 #undef	LONG
242 #undef	VLONG
243 #undef	BYTES
244 #undef	STRING
245 
246 #define	CHAR(x)		f->x = *p++
247 #define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
248 #define	VLONG(q)	q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
249 #define	LONG(x)		VLONG(f->x)
250 #define	BYTES(x,n)	memmove(f->x, p, n); p += n
251 #define	STRING(x,n)	memmove(f->x, p, n); p += n
252 
253 int
convM2S9p1(uchar * ap,Oldfcall * f,int n)254 convM2S9p1(uchar *ap, Oldfcall *f, int n)
255 {
256 	uchar *p;
257 	int t;
258 
259 	p = ap;
260 	CHAR(type);
261 	t = f->type;
262 	SHORT(tag);
263 	switch(t)
264 	{
265 	default:
266 		/*
267 		 * only whine if it couldn't be a 9P2000 Tversion9p1.
268 		 */
269 		if(t != 19 || ap[4] != 100)
270 			print("convM2S9p1: bad type: %d\n", f->type);
271 		return 0;
272 
273 	case Tnop9p1:
274 	case Tosession9p1:
275 		break;
276 
277 	case Tsession9p1:
278 		BYTES(chal, sizeof(f->chal));
279 		break;
280 
281 	case Tflush9p1:
282 		SHORT(oldtag);
283 		break;
284 
285 	case Tattach9p1:
286 		SHORT(fid);
287 		BYTES(uname, sizeof(f->uname));
288 		BYTES(aname, sizeof(f->aname));
289 		BYTES(ticket, sizeof(f->ticket));
290 		BYTES(auth, sizeof(f->auth));
291 		break;
292 
293 	case Toattach9p1:
294 		SHORT(fid);
295 		BYTES(uname, sizeof(f->uname));
296 		BYTES(aname, sizeof(f->aname));
297 		BYTES(ticket, NAMELEN);
298 		break;
299 
300 	case Tclone9p1:
301 		SHORT(fid);
302 		SHORT(newfid);
303 		break;
304 
305 	case Twalk9p1:
306 		SHORT(fid);
307 		BYTES(name, sizeof(f->name));
308 		break;
309 
310 	case Tclwalk9p1:
311 		SHORT(fid);
312 		SHORT(newfid);
313 		BYTES(name, sizeof(f->name));
314 		break;
315 
316 	case Tremove9p1:
317 		SHORT(fid);
318 		break;
319 
320 	case Topen9p1:
321 		SHORT(fid);
322 		CHAR(mode);
323 		break;
324 
325 	case Tcreate9p1:
326 		SHORT(fid);
327 		BYTES(name, sizeof(f->name));
328 		LONG(perm);
329 		CHAR(mode);
330 		break;
331 
332 	case Tread9p1:
333 		SHORT(fid);
334 		LONG(offset); p += 4;
335 		SHORT(count);
336 		break;
337 
338 	case Twrite9p1:
339 		SHORT(fid);
340 		LONG(offset); p += 4;
341 		SHORT(count);
342 		p++;
343 		f->data = (char*)p; p += f->count;
344 		break;
345 
346 	case Tclunk9p1:
347 	case Tstat9p1:
348 		SHORT(fid);
349 		break;
350 
351 	case Twstat9p1:
352 		SHORT(fid);
353 		BYTES(stat, sizeof(f->stat));
354 		break;
355 
356 /*
357  */
358 	case Rnop9p1:
359 	case Rosession9p1:
360 		break;
361 
362 	case Rsession9p1:
363 		BYTES(chal, sizeof(f->chal));
364 		BYTES(authid, sizeof(f->authid));
365 		BYTES(authdom, sizeof(f->authdom));
366 		break;
367 
368 	case Rerror9p1:
369 		BYTES(ename, sizeof(f->ename));
370 		break;
371 
372 	case Rflush9p1:
373 		break;
374 
375 	case Rclone9p1:
376 	case Rclunk9p1:
377 	case Rremove9p1:
378 	case Rwstat9p1:
379 		SHORT(fid);
380 		break;
381 
382 	case Rwalk9p1:
383 	case Rclwalk9p1:
384 	case Ropen9p1:
385 	case Rcreate9p1:
386 		SHORT(fid);
387 		LONG(qid.path);
388 		LONG(qid.version);
389 		break;
390 
391 	case Rattach9p1:
392 		SHORT(fid);
393 		LONG(qid.path);
394 		LONG(qid.version);
395 		BYTES(rauth, sizeof(f->rauth));
396 		break;
397 
398 	case Roattach9p1:
399 		SHORT(fid);
400 		LONG(qid.path);
401 		LONG(qid.version);
402 		break;
403 
404 	case Rread9p1:
405 		SHORT(fid);
406 		SHORT(count);
407 		p++;
408 		f->data = (char*)p; p += f->count;
409 		break;
410 
411 	case Rwrite9p1:
412 		SHORT(fid);
413 		SHORT(count);
414 		break;
415 
416 	case Rstat9p1:
417 		SHORT(fid);
418 		BYTES(stat, sizeof(f->stat));
419 		break;
420 	}
421 	if((uchar*)ap+n == p)
422 		return n;
423 	return 0;
424 }
425 
426 int
convM2D9p1(char * ap,Dentry * f)427 convM2D9p1(char *ap, Dentry *f)
428 {
429 	uchar *p;
430 	char str[28];
431 
432 	p = (uchar*)ap;
433 	BYTES(name, sizeof(f->name));
434 
435 	memmove(str, p, NAMELEN);
436 	p += NAMELEN;
437 	f->uid = strtouid(str);
438 
439 	memmove(str, p, NAMELEN);
440 	p += NAMELEN;
441 	f->gid = strtouid(str);
442 
443 	LONG(qid.path);
444 	LONG(qid.version);
445 	{
446 		LONG(atime);
447 		f->mode = (f->atime & 0x0fff) | DALLOC;
448 		if(f->atime & PDIR)
449 			f->mode |= DDIR;
450 		if(f->atime & PAPND)
451 			f->mode |= DAPND;
452 		if(f->atime & PLOCK)
453 			f->mode |= DLOCK;
454 	}
455 	LONG(atime);
456 	LONG(mtime);
457 	LONG(size); p += 4;
458 	p += 4;
459 	return p - (uchar*)ap;
460 }
461 
462