plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }