Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
5 Packet*
6 vtfcallpack(VtFcall *f)
7 {
8 uchar buf[4];
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 buf[2] = f->count >> 8;
64 buf[3] = f->count;
65 packetappend(p, buf, 4);
66 break;
68 case VtRread:
69 packetconcat(p, f->data);
70 break;
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;
83 case VtRwrite:
84 packetappend(p, f->score, VtScoreSize);
85 break;
87 case VtTsync:
88 break;
90 case VtRsync:
91 break;
92 }
94 return p;
96 Err:
97 packetfree(p);
98 return nil;
99 }
101 int
102 vtfcallunpack(VtFcall *f, Packet *p)
104 uchar buf[4];
106 memset(f, 0, sizeof *f);
108 if(packetconsume(p, buf, 2) < 0)
109 return -1;
111 f->msgtype = buf[0];
112 f->tag = buf[1];
114 switch(f->msgtype){
115 default:
116 werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
117 vtfcallclear(f);
118 return -1;
120 case VtRerror:
121 if(vtgetstring(p, &f->error) < 0)
122 goto Err;
123 break;
125 case VtTping:
126 break;
128 case VtRping:
129 break;
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;
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;
151 break;
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;
161 case VtTgoodbye:
162 break;
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;
174 case VtRread:
175 f->data = packetalloc();
176 packetconcat(f->data, p);
177 break;
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;
189 case VtRwrite:
190 if(packetconsume(p, f->score, VtScoreSize) < 0)
191 goto Err;
192 break;
194 case VtTsync:
195 break;
197 case VtRsync:
198 break;
201 if(packetsize(p) != 0)
202 goto Err;
204 return 0;
206 Err:
207 werrstr("bad packet");
208 return -1;
211 void
212 vtfcallclear(VtFcall *f)
214 vtfree(f->error);
215 f->error = nil;
216 vtfree(f->uid);
217 f->uid = nil;
218 vtfree(f->sid);
219 f->sid = nil;
220 vtfree(f->version);
221 f->version = nil;
222 vtfree(f->crypto);
223 f->crypto = nil;
224 vtfree(f->codec);
225 f->codec = nil;
226 vtfree(f->auth);
227 f->auth = nil;
228 packetfree(f->data);
229 f->data = nil;