fcall.c (4206B)
1 #include <u.h> 2 #include <libc.h> 3 #include <venti.h> 4 5 Packet* 6 vtfcallpack(VtFcall *f) 7 { 8 uchar buf[10]; 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 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; 75 76 case VtRread: 77 packetconcat(p, f->data); 78 break; 79 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; 90 91 case VtRwrite: 92 packetappend(p, f->score, VtScoreSize); 93 break; 94 95 case VtTsync: 96 break; 97 98 case VtRsync: 99 break; 100 } 101 102 return p; 103 104 Err: 105 packetfree(p); 106 return nil; 107 } 108 109 int 110 vtfcallunpack(VtFcall *f, Packet *p) 111 { 112 uchar buf[4]; 113 114 memset(f, 0, sizeof *f); 115 116 if(packetconsume(p, buf, 2) < 0) 117 return -1; 118 119 f->msgtype = buf[0]; 120 f->tag = buf[1]; 121 122 switch(f->msgtype){ 123 default: 124 werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype); 125 vtfcallclear(f); 126 return -1; 127 128 case VtRerror: 129 if(vtgetstring(p, &f->error) < 0) 130 goto Err; 131 break; 132 133 case VtTping: 134 break; 135 136 case VtRping: 137 break; 138 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; 150 } 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; 158 } 159 break; 160 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; 168 169 case VtTgoodbye: 170 break; 171 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; 192 } 193 break; 194 195 case VtRread: 196 f->data = packetalloc(); 197 packetconcat(f->data, p); 198 break; 199 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; 209 210 case VtRwrite: 211 if(packetconsume(p, f->score, VtScoreSize) < 0) 212 goto Err; 213 break; 214 215 case VtTsync: 216 break; 217 218 case VtRsync: 219 break; 220 } 221 222 if(packetsize(p) != 0) 223 goto Err; 224 225 return 0; 226 227 Err: 228 werrstr("bad packet"); 229 vtfcallclear(f); 230 return -1; 231 } 232 233 void 234 vtfcallclear(VtFcall *f) 235 { 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; 252 }