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) < 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 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 int102 vtfcallunpack(VtFcall *f, Packet *p)103 {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) < 0133 || vtgetstring(p, &f->uid) < 0134 || 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;153 case VtRhello:154 if(vtgetstring(p, &f->sid) < 0155 || 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) < 0166 || 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;199 }201 if(packetsize(p) != 0)202 goto Err;204 return 0;206 Err:207 werrstr("bad packet");208 vtfcallclear(f);209 return -1;210 }212 void213 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 }