Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
5 Packet*
6 vtfcallpack(VtFcall *f)
7 {
8 uchar buf[10];
9 Packet *p;
11 p = packetalloc();
13 buf[0] = f->msgtype;
14 buf[1] = f->tag;
15 packetappend(p, buf, 2);
17 switch(f->msgtype){
18 default:
19 werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
20 goto Err;
22 case VtRerror:
23 if(vtputstring(p, f->error) < 0)
24 goto Err;
25 break;
27 case VtTping:
28 break;
30 case VtRping:
31 break;
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;
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;
54 case VtTgoodbye:
55 break;
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 if(f->count >= (1<<16)) {
64 buf[2] = f->count >> 24;
65 buf[3] = f->count >> 16;
66 buf[4] = f->count >> 8;
67 buf[5] = f->count;
68 packetappend(p, buf, 6);
69 } else {
70 buf[2] = f->count >> 8;
71 buf[3] = f->count;
72 packetappend(p, buf, 4);
73 }
74 break;
76 case VtRread:
77 packetconcat(p, f->data);
78 break;
80 case VtTwrite:
81 buf[0] = vttodisktype(f->blocktype);
82 if(~buf[0] == 0)
83 goto Err;
84 buf[1] = 0;
85 buf[2] = 0;
86 buf[3] = 0;
87 packetappend(p, buf, 4);
88 packetconcat(p, f->data);
89 break;
91 case VtRwrite:
92 packetappend(p, f->score, VtScoreSize);
93 break;
95 case VtTsync:
96 break;
98 case VtRsync:
99 break;
102 return p;
104 Err:
105 packetfree(p);
106 return nil;
109 int
110 vtfcallunpack(VtFcall *f, Packet *p)
112 uchar buf[4];
114 memset(f, 0, sizeof *f);
116 if(packetconsume(p, buf, 2) < 0)
117 return -1;
119 f->msgtype = buf[0];
120 f->tag = buf[1];
122 switch(f->msgtype){
123 default:
124 werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
125 vtfcallclear(f);
126 return -1;
128 case VtRerror:
129 if(vtgetstring(p, &f->error) < 0)
130 goto Err;
131 break;
133 case VtTping:
134 break;
136 case VtRping:
137 break;
139 case VtThello:
140 if(vtgetstring(p, &f->version) < 0
141 || vtgetstring(p, &f->uid) < 0
142 || packetconsume(p, buf, 2) < 0)
143 goto Err;
144 f->strength = buf[0];
145 f->ncrypto = buf[1];
146 if(f->ncrypto){
147 f->crypto = vtmalloc(f->ncrypto);
148 if(packetconsume(p, buf, f->ncrypto) < 0)
149 goto Err;
151 if(packetconsume(p, buf, 1) < 0)
152 goto Err;
153 f->ncodec = buf[0];
154 if(f->ncodec){
155 f->codec = vtmalloc(f->ncodec);
156 if(packetconsume(p, buf, f->ncodec) < 0)
157 goto Err;
159 break;
161 case VtRhello:
162 if(vtgetstring(p, &f->sid) < 0
163 || packetconsume(p, buf, 2) < 0)
164 goto Err;
165 f->rcrypto = buf[0];
166 f->rcodec = buf[1];
167 break;
169 case VtTgoodbye:
170 break;
172 case VtTread:
173 if(packetconsume(p, f->score, VtScoreSize) < 0
174 || packetconsume(p, buf, 2) < 0)
175 goto Err;
176 f->blocktype = vtfromdisktype(buf[0]);
177 if(~f->blocktype == 0)
178 goto Err;
179 switch(packetsize(p)) {
180 default:
181 goto Err;
182 case 2:
183 if(packetconsume(p, buf, 2) < 0)
184 goto Err;
185 f->count = (buf[0] << 8) | buf[1];
186 break;
187 case 4:
188 if(packetconsume(p, buf, 4) < 0)
189 goto Err;
190 f->count = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
191 break;
193 break;
195 case VtRread:
196 f->data = packetalloc();
197 packetconcat(f->data, p);
198 break;
200 case VtTwrite:
201 if(packetconsume(p, buf, 4) < 0)
202 goto Err;
203 f->blocktype = vtfromdisktype(buf[0]);
204 if(~f->blocktype == 0)
205 goto Err;
206 f->data = packetalloc();
207 packetconcat(f->data, p);
208 break;
210 case VtRwrite:
211 if(packetconsume(p, f->score, VtScoreSize) < 0)
212 goto Err;
213 break;
215 case VtTsync:
216 break;
218 case VtRsync:
219 break;
222 if(packetsize(p) != 0)
223 goto Err;
225 return 0;
227 Err:
228 werrstr("bad packet");
229 vtfcallclear(f);
230 return -1;
233 void
234 vtfcallclear(VtFcall *f)
236 vtfree(f->error);
237 f->error = nil;
238 vtfree(f->uid);
239 f->uid = nil;
240 vtfree(f->sid);
241 f->sid = nil;
242 vtfree(f->version);
243 f->version = nil;
244 vtfree(f->crypto);
245 f->crypto = nil;
246 vtfree(f->codec);
247 f->codec = nil;
248 vtfree(f->auth);
249 f->auth = nil;
250 packetfree(f->data);
251 f->data = nil;