plan9port

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

client.c (3366B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <venti.h>
      4 
      5 int ventidoublechecksha1 = 1;
      6 
      7 static int
      8 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
      9 {
     10 	Packet *p;
     11 
     12 	p = vtfcallpack(ou);
     13 	if(p == nil)
     14 		return -1;
     15 	if((p = _vtrpc(z, p, ou)) == nil)
     16 		return -1;
     17 	if(vtfcallunpack(in, p) < 0){
     18 		packetfree(p);
     19 		return -1;
     20 	}
     21 	if(chattyventi)
     22 		fprint(2, "%s <- %F\n", argv0, in);
     23 	if(in->msgtype == VtRerror){
     24 		werrstr(in->error);
     25 		vtfcallclear(in);
     26 		packetfree(p);
     27 		return -1;
     28 	}
     29 	if(in->msgtype != ou->msgtype+1){
     30 		werrstr("type mismatch: sent %c%d got %c%d",
     31 			"TR"[ou->msgtype&1], ou->msgtype>>1,
     32 			"TR"[in->msgtype&1], in->msgtype>>1);
     33 		vtfcallclear(in);
     34 		packetfree(p);
     35 		return -1;
     36 	}
     37 	packetfree(p);
     38 	return 0;
     39 }
     40 
     41 int
     42 vthello(VtConn *z)
     43 {
     44 	VtFcall tx, rx;
     45 
     46 	memset(&tx, 0, sizeof tx);
     47 	tx.msgtype = VtThello;
     48 	tx.version = z->version;
     49 	tx.uid = z->uid;
     50 	if(tx.uid == nil)
     51 		tx.uid = "anonymous";
     52 	if(vtfcallrpc(z, &tx, &rx) < 0)
     53 		return -1;
     54 	z->sid = rx.sid;
     55 	rx.sid = 0;
     56 	vtfcallclear(&rx);
     57 	return 0;
     58 }
     59 
     60 Packet*
     61 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
     62 {
     63 	VtFcall tx, rx;
     64 
     65 	if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
     66 		return packetalloc();
     67 
     68 	if(z == nil){
     69 		werrstr("not connected");
     70 		return nil;
     71 	}
     72 
     73 	if(z->version[1] == '2' && n >= (1<<16)) {
     74 		werrstr("read count too large for protocol");
     75 		return nil;
     76 	}
     77 	memset(&tx, 0, sizeof tx);
     78 	tx.msgtype = VtTread;
     79 	tx.blocktype = type;
     80 	tx.count = n;
     81 	memmove(tx.score, score, VtScoreSize);
     82 	if(vtfcallrpc(z, &tx, &rx) < 0)
     83 		return nil;
     84 	if(packetsize(rx.data) > n){
     85 		werrstr("read returned too much data");
     86 		packetfree(rx.data);
     87 		return nil;
     88 	}
     89 	if(ventidoublechecksha1){
     90 		packetsha1(rx.data, tx.score);
     91 		if(memcmp(score, tx.score, VtScoreSize) != 0){
     92 			werrstr("read asked for %V got %V", score, tx.score);
     93 			packetfree(rx.data);
     94 			return nil;
     95 		}
     96 	}
     97 	return rx.data;
     98 }
     99 
    100 int
    101 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
    102 {
    103 	int nn;
    104 	Packet *p;
    105 
    106 	if((p = vtreadpacket(z, score, type, n)) == nil)
    107 		return -1;
    108 	nn = packetsize(p);
    109 	if(packetconsume(p, buf, nn) < 0)
    110 		abort();
    111 	packetfree(p);
    112 	return nn;
    113 }
    114 
    115 int
    116 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
    117 {
    118 	VtFcall tx, rx;
    119 
    120 	if(packetsize(p) == 0){
    121 		memmove(score, vtzeroscore, VtScoreSize);
    122 		return 0;
    123 	}
    124 	tx.msgtype = VtTwrite;
    125 	tx.blocktype = type;
    126 	tx.data = p;
    127 	if(ventidoublechecksha1)
    128 		packetsha1(p, score);
    129 	if(vtfcallrpc(z, &tx, &rx) < 0)
    130 		return -1;
    131 	if(ventidoublechecksha1){
    132 		if(memcmp(score, rx.score, VtScoreSize) != 0){
    133 			werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
    134 			return -1;
    135 		}
    136 	}else
    137 		memmove(score, rx.score, VtScoreSize);
    138 	return 0;
    139 }
    140 
    141 int
    142 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
    143 {
    144 	Packet *p;
    145 	int nn;
    146 
    147 	p = packetforeign(buf, n, 0, nil);
    148 	nn = vtwritepacket(z, score, type, p);
    149 	packetfree(p);
    150 	return nn;
    151 }
    152 
    153 int
    154 vtsync(VtConn *z)
    155 {
    156 	VtFcall tx, rx;
    157 
    158 	tx.msgtype = VtTsync;
    159 	return vtfcallrpc(z, &tx, &rx);
    160 }
    161 
    162 int
    163 vtping(VtConn *z)
    164 {
    165 	VtFcall tx, rx;
    166 
    167 	tx.msgtype = VtTping;
    168 	return vtfcallrpc(z, &tx, &rx);
    169 }
    170 
    171 int
    172 vtconnect(VtConn *z)
    173 {
    174 	if(vtversion(z) < 0)
    175 		return -1;
    176 	if(vthello(z) < 0)
    177 		return -1;
    178 	return 0;
    179 }
    180 
    181 int
    182 vtgoodbye(VtConn *z)
    183 {
    184 	VtFcall tx, rx;
    185 
    186 	tx.msgtype = VtTgoodbye;
    187 	vtfcallrpc(z, &tx, &rx);	/* always fails: no VtRgoodbye */
    188 	return 0;
    189 }