xref: /plan9/sys/src/libventi/fcall.c (revision 368c31ab13393dea083228fdd1c3445076f83a4b)
1*368c31abSDavid du Colombier #include <u.h>
2*368c31abSDavid du Colombier #include <libc.h>
3*368c31abSDavid du Colombier #include <venti.h>
4*368c31abSDavid du Colombier 
5*368c31abSDavid du Colombier Packet*
vtfcallpack(VtFcall * f)6*368c31abSDavid du Colombier vtfcallpack(VtFcall *f)
7*368c31abSDavid du Colombier {
8*368c31abSDavid du Colombier 	uchar buf[4];
9*368c31abSDavid du Colombier 	Packet *p;
10*368c31abSDavid du Colombier 
11*368c31abSDavid du Colombier 	p = packetalloc();
12*368c31abSDavid du Colombier 
13*368c31abSDavid du Colombier 	buf[0] = f->msgtype;
14*368c31abSDavid du Colombier 	buf[1] = f->tag;
15*368c31abSDavid du Colombier 	packetappend(p, buf, 2);
16*368c31abSDavid du Colombier 
17*368c31abSDavid du Colombier 	switch(f->msgtype){
18*368c31abSDavid du Colombier 	default:
19*368c31abSDavid du Colombier 		werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
20*368c31abSDavid du Colombier 		goto Err;
21*368c31abSDavid du Colombier 
22*368c31abSDavid du Colombier 	case VtRerror:
23*368c31abSDavid du Colombier 		if(vtputstring(p, f->error) < 0)
24*368c31abSDavid du Colombier 			goto Err;
25*368c31abSDavid du Colombier 		break;
26*368c31abSDavid du Colombier 
27*368c31abSDavid du Colombier 	case VtTping:
28*368c31abSDavid du Colombier 		break;
29*368c31abSDavid du Colombier 
30*368c31abSDavid du Colombier 	case VtRping:
31*368c31abSDavid du Colombier 		break;
32*368c31abSDavid du Colombier 
33*368c31abSDavid du Colombier 	case VtThello:
34*368c31abSDavid du Colombier 		if(vtputstring(p, f->version) < 0
35*368c31abSDavid du Colombier 		|| vtputstring(p, f->uid) < 0)
36*368c31abSDavid du Colombier 			goto Err;
37*368c31abSDavid du Colombier 		buf[0] = f->strength;
38*368c31abSDavid du Colombier 		buf[1] = f->ncrypto;
39*368c31abSDavid du Colombier 		packetappend(p, buf, 2);
40*368c31abSDavid du Colombier 		packetappend(p, f->crypto, f->ncrypto);
41*368c31abSDavid du Colombier 		buf[0] = f->ncodec;
42*368c31abSDavid du Colombier 		packetappend(p, buf, 1);
43*368c31abSDavid du Colombier 		packetappend(p, f->codec, f->ncodec);
44*368c31abSDavid du Colombier 		break;
45*368c31abSDavid du Colombier 
46*368c31abSDavid du Colombier 	case VtRhello:
47*368c31abSDavid du Colombier 		if(vtputstring(p, f->sid) < 0)
48*368c31abSDavid du Colombier 			goto Err;
49*368c31abSDavid du Colombier 		buf[0] = f->rcrypto;
50*368c31abSDavid du Colombier 		buf[1] = f->rcodec;
51*368c31abSDavid du Colombier 		packetappend(p, buf, 2);
52*368c31abSDavid du Colombier 		break;
53*368c31abSDavid du Colombier 
54*368c31abSDavid du Colombier 	case VtTgoodbye:
55*368c31abSDavid du Colombier 		break;
56*368c31abSDavid du Colombier 
57*368c31abSDavid du Colombier 	case VtTread:
58*368c31abSDavid du Colombier 		packetappend(p, f->score, VtScoreSize);
59*368c31abSDavid du Colombier 		buf[0] = vttodisktype(f->blocktype);
60*368c31abSDavid du Colombier 		if(~buf[0] == 0)
61*368c31abSDavid du Colombier 			goto Err;
62*368c31abSDavid du Colombier 		buf[1] = 0;
63*368c31abSDavid du Colombier 		buf[2] = f->count >> 8;
64*368c31abSDavid du Colombier 		buf[3] = f->count;
65*368c31abSDavid du Colombier 		packetappend(p, buf, 4);
66*368c31abSDavid du Colombier 		break;
67*368c31abSDavid du Colombier 
68*368c31abSDavid du Colombier 	case VtRread:
69*368c31abSDavid du Colombier 		packetconcat(p, f->data);
70*368c31abSDavid du Colombier 		break;
71*368c31abSDavid du Colombier 
72*368c31abSDavid du Colombier 	case VtTwrite:
73*368c31abSDavid du Colombier 		buf[0] = vttodisktype(f->blocktype);
74*368c31abSDavid du Colombier 		if(~buf[0] == 0)
75*368c31abSDavid du Colombier 			goto Err;
76*368c31abSDavid du Colombier 		buf[1] = 0;
77*368c31abSDavid du Colombier 		buf[2] = 0;
78*368c31abSDavid du Colombier 		buf[3] = 0;
79*368c31abSDavid du Colombier 		packetappend(p, buf, 4);
80*368c31abSDavid du Colombier 		packetconcat(p, f->data);
81*368c31abSDavid du Colombier 		break;
82*368c31abSDavid du Colombier 
83*368c31abSDavid du Colombier 	case VtRwrite:
84*368c31abSDavid du Colombier 		packetappend(p, f->score, VtScoreSize);
85*368c31abSDavid du Colombier 		break;
86*368c31abSDavid du Colombier 
87*368c31abSDavid du Colombier 	case VtTsync:
88*368c31abSDavid du Colombier 		break;
89*368c31abSDavid du Colombier 
90*368c31abSDavid du Colombier 	case VtRsync:
91*368c31abSDavid du Colombier 		break;
92*368c31abSDavid du Colombier 	}
93*368c31abSDavid du Colombier 
94*368c31abSDavid du Colombier 	return p;
95*368c31abSDavid du Colombier 
96*368c31abSDavid du Colombier Err:
97*368c31abSDavid du Colombier 	packetfree(p);
98*368c31abSDavid du Colombier 	return nil;
99*368c31abSDavid du Colombier }
100*368c31abSDavid du Colombier 
101*368c31abSDavid du Colombier int
vtfcallunpack(VtFcall * f,Packet * p)102*368c31abSDavid du Colombier vtfcallunpack(VtFcall *f, Packet *p)
103*368c31abSDavid du Colombier {
104*368c31abSDavid du Colombier 	uchar buf[4];
105*368c31abSDavid du Colombier 
106*368c31abSDavid du Colombier 	memset(f, 0, sizeof *f);
107*368c31abSDavid du Colombier 
108*368c31abSDavid du Colombier 	if(packetconsume(p, buf, 2) < 0)
109*368c31abSDavid du Colombier 		return -1;
110*368c31abSDavid du Colombier 
111*368c31abSDavid du Colombier 	f->msgtype = buf[0];
112*368c31abSDavid du Colombier 	f->tag = buf[1];
113*368c31abSDavid du Colombier 
114*368c31abSDavid du Colombier 	switch(f->msgtype){
115*368c31abSDavid du Colombier 	default:
116*368c31abSDavid du Colombier 		werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
117*368c31abSDavid du Colombier 		vtfcallclear(f);
118*368c31abSDavid du Colombier 		return -1;
119*368c31abSDavid du Colombier 
120*368c31abSDavid du Colombier 	case VtRerror:
121*368c31abSDavid du Colombier 		if(vtgetstring(p, &f->error) < 0)
122*368c31abSDavid du Colombier 			goto Err;
123*368c31abSDavid du Colombier 		break;
124*368c31abSDavid du Colombier 
125*368c31abSDavid du Colombier 	case VtTping:
126*368c31abSDavid du Colombier 		break;
127*368c31abSDavid du Colombier 
128*368c31abSDavid du Colombier 	case VtRping:
129*368c31abSDavid du Colombier 		break;
130*368c31abSDavid du Colombier 
131*368c31abSDavid du Colombier 	case VtThello:
132*368c31abSDavid du Colombier 		if(vtgetstring(p, &f->version) < 0
133*368c31abSDavid du Colombier 		|| vtgetstring(p, &f->uid) < 0
134*368c31abSDavid du Colombier 		|| packetconsume(p, buf, 2) < 0)
135*368c31abSDavid du Colombier 			goto Err;
136*368c31abSDavid du Colombier 		f->strength = buf[0];
137*368c31abSDavid du Colombier 		f->ncrypto = buf[1];
138*368c31abSDavid du Colombier 		if(f->ncrypto){
139*368c31abSDavid du Colombier 			f->crypto = vtmalloc(f->ncrypto);
140*368c31abSDavid du Colombier 			if(packetconsume(p, buf, f->ncrypto) < 0)
141*368c31abSDavid du Colombier 				goto Err;
142*368c31abSDavid du Colombier 		}
143*368c31abSDavid du Colombier 		if(packetconsume(p, buf, 1) < 0)
144*368c31abSDavid du Colombier 			goto Err;
145*368c31abSDavid du Colombier 		f->ncodec = buf[0];
146*368c31abSDavid du Colombier 		if(f->ncodec){
147*368c31abSDavid du Colombier 			f->codec = vtmalloc(f->ncodec);
148*368c31abSDavid du Colombier 			if(packetconsume(p, buf, f->ncodec) < 0)
149*368c31abSDavid du Colombier 				goto Err;
150*368c31abSDavid du Colombier 		}
151*368c31abSDavid du Colombier 		break;
152*368c31abSDavid du Colombier 
153*368c31abSDavid du Colombier 	case VtRhello:
154*368c31abSDavid du Colombier 		if(vtgetstring(p, &f->sid) < 0
155*368c31abSDavid du Colombier 		|| packetconsume(p, buf, 2) < 0)
156*368c31abSDavid du Colombier 			goto Err;
157*368c31abSDavid du Colombier 		f->rcrypto = buf[0];
158*368c31abSDavid du Colombier 		f->rcodec = buf[1];
159*368c31abSDavid du Colombier 		break;
160*368c31abSDavid du Colombier 
161*368c31abSDavid du Colombier 	case VtTgoodbye:
162*368c31abSDavid du Colombier 		break;
163*368c31abSDavid du Colombier 
164*368c31abSDavid du Colombier 	case VtTread:
165*368c31abSDavid du Colombier 		if(packetconsume(p, f->score, VtScoreSize) < 0
166*368c31abSDavid du Colombier 		|| packetconsume(p, buf, 4) < 0)
167*368c31abSDavid du Colombier 			goto Err;
168*368c31abSDavid du Colombier 		f->blocktype = vtfromdisktype(buf[0]);
169*368c31abSDavid du Colombier 		if(~f->blocktype == 0)
170*368c31abSDavid du Colombier 			goto Err;
171*368c31abSDavid du Colombier 		f->count = (buf[2] << 8) | buf[3];
172*368c31abSDavid du Colombier 		break;
173*368c31abSDavid du Colombier 
174*368c31abSDavid du Colombier 	case VtRread:
175*368c31abSDavid du Colombier 		f->data = packetalloc();
176*368c31abSDavid du Colombier 		packetconcat(f->data, p);
177*368c31abSDavid du Colombier 		break;
178*368c31abSDavid du Colombier 
179*368c31abSDavid du Colombier 	case VtTwrite:
180*368c31abSDavid du Colombier 		if(packetconsume(p, buf, 4) < 0)
181*368c31abSDavid du Colombier 			goto Err;
182*368c31abSDavid du Colombier 		f->blocktype = vtfromdisktype(buf[0]);
183*368c31abSDavid du Colombier 		if(~f->blocktype == 0)
184*368c31abSDavid du Colombier 			goto Err;
185*368c31abSDavid du Colombier 		f->data = packetalloc();
186*368c31abSDavid du Colombier 		packetconcat(f->data, p);
187*368c31abSDavid du Colombier 		break;
188*368c31abSDavid du Colombier 
189*368c31abSDavid du Colombier 	case VtRwrite:
190*368c31abSDavid du Colombier 		if(packetconsume(p, f->score, VtScoreSize) < 0)
191*368c31abSDavid du Colombier 			goto Err;
192*368c31abSDavid du Colombier 		break;
193*368c31abSDavid du Colombier 
194*368c31abSDavid du Colombier 	case VtTsync:
195*368c31abSDavid du Colombier 		break;
196*368c31abSDavid du Colombier 
197*368c31abSDavid du Colombier 	case VtRsync:
198*368c31abSDavid du Colombier 		break;
199*368c31abSDavid du Colombier 	}
200*368c31abSDavid du Colombier 
201*368c31abSDavid du Colombier 	if(packetsize(p) != 0)
202*368c31abSDavid du Colombier 		goto Err;
203*368c31abSDavid du Colombier 
204*368c31abSDavid du Colombier 	return 0;
205*368c31abSDavid du Colombier 
206*368c31abSDavid du Colombier Err:
207*368c31abSDavid du Colombier 	werrstr("bad packet");
208*368c31abSDavid du Colombier 	vtfcallclear(f);
209*368c31abSDavid du Colombier 	return -1;
210*368c31abSDavid du Colombier }
211*368c31abSDavid du Colombier 
212*368c31abSDavid du Colombier void
vtfcallclear(VtFcall * f)213*368c31abSDavid du Colombier vtfcallclear(VtFcall *f)
214*368c31abSDavid du Colombier {
215*368c31abSDavid du Colombier 	vtfree(f->error);
216*368c31abSDavid du Colombier 	f->error = nil;
217*368c31abSDavid du Colombier 	vtfree(f->uid);
218*368c31abSDavid du Colombier 	f->uid = nil;
219*368c31abSDavid du Colombier 	vtfree(f->sid);
220*368c31abSDavid du Colombier 	f->sid = nil;
221*368c31abSDavid du Colombier 	vtfree(f->version);
222*368c31abSDavid du Colombier 	f->version = nil;
223*368c31abSDavid du Colombier 	vtfree(f->crypto);
224*368c31abSDavid du Colombier 	f->crypto = nil;
225*368c31abSDavid du Colombier 	vtfree(f->codec);
226*368c31abSDavid du Colombier 	f->codec = nil;
227*368c31abSDavid du Colombier 	vtfree(f->auth);
228*368c31abSDavid du Colombier 	f->auth = nil;
229*368c31abSDavid du Colombier 	packetfree(f->data);
230*368c31abSDavid du Colombier 	f->data = nil;
231*368c31abSDavid du Colombier }
232