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) < 035 || 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;100 }102 return p;104 Err:105 packetfree(p);106 return nil;107 }109 int110 vtfcallunpack(VtFcall *f, Packet *p)111 {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) < 0141 || vtgetstring(p, &f->uid) < 0142 || 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;161 case VtRhello:162 if(vtgetstring(p, &f->sid) < 0163 || 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) < 0174 || 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;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;220 }222 if(packetsize(p) != 0)223 goto Err;225 return 0;227 Err:228 werrstr("bad packet");229 vtfcallclear(f);230 return -1;231 }233 void234 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 }