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