blob: a58b2089894f4894d12228f7b24fec1229212add [file] [log] [blame]
rsc056fe1b2003-11-23 18:19:58 +00001#include <u.h>
2#include <libc.h>
3#include <venti.h>
4
rsca09e80f2004-05-23 00:59:17 +00005int ventidoublechecksha1 = 1;
6
rsc056fe1b2003-11-23 18:19:58 +00007static int
8vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
9{
10 Packet *p;
11
rsca09e80f2004-05-23 00:59:17 +000012 if(chattyventi)
13 fprint(2, "%s -> %F\n", argv0, ou);
rsc056fe1b2003-11-23 18:19:58 +000014 p = vtfcallpack(ou);
15 if(p == nil)
16 return -1;
17 if((p = vtrpc(z, p)) == nil)
18 return -1;
19 if(vtfcallunpack(in, p) < 0){
20 packetfree(p);
21 return -1;
22 }
rsca09e80f2004-05-23 00:59:17 +000023 if(chattyventi)
24 fprint(2, "%s <- %F\n", argv0, in);
rsc056fe1b2003-11-23 18:19:58 +000025 if(in->type == VtRerror){
26 werrstr(in->error);
27 vtfcallclear(in);
28 packetfree(p);
29 return -1;
30 }
31 if(in->type != ou->type+1){
32 werrstr("type mismatch: sent %c%d got %c%d",
33 "TR"[ou->type&1], ou->type>>1,
34 "TR"[in->type&1], in->type>>1);
35 vtfcallclear(in);
36 packetfree(p);
37 return -1;
38 }
39 packetfree(p);
40 return 0;
41}
42
43int
44vthello(VtConn *z)
45{
46 VtFcall tx, rx;
47
48 memset(&tx, 0, sizeof tx);
49 tx.type = VtThello;
50 tx.version = z->version;
51 tx.uid = z->uid;
52 if(tx.uid == nil)
53 tx.uid = "anonymous";
54 if(vtfcallrpc(z, &tx, &rx) < 0)
55 return -1;
56 z->sid = rx.sid;
57 rx.sid = 0;
58 vtfcallclear(&rx);
59 return 0;
60}
61
62Packet*
63vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
64{
65 VtFcall tx, rx;
66
67 memset(&tx, 0, sizeof tx);
68 tx.type = VtTread;
69 tx.dtype = type;
70 tx.count = n;
71 memmove(tx.score, score, VtScoreSize);
72 if(vtfcallrpc(z, &tx, &rx) < 0)
73 return nil;
74 if(packetsize(rx.data) > n){
75 werrstr("read returned too much data");
76 packetfree(rx.data);
77 return nil;
78 }
rsca09e80f2004-05-23 00:59:17 +000079 if(ventidoublechecksha1){
80 packetsha1(rx.data, tx.score);
81 if(memcmp(score, tx.score, VtScoreSize) != 0){
82 werrstr("read asked for %V got %V", score, tx.score);
83 packetfree(rx.data);
84 return nil;
85 }
rsc056fe1b2003-11-23 18:19:58 +000086 }
rsc056fe1b2003-11-23 18:19:58 +000087 return rx.data;
88}
89
90int
91vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
92{
93 int nn;
94 Packet *p;
95
96 if((p = vtreadpacket(z, score, type, n)) == nil)
97 return -1;
98 nn = packetsize(p);
99 if(packetconsume(p, buf, nn) < 0)
100 abort();
rscc5eb6862004-06-16 03:12:39 +0000101 packetfree(p);
rsc056fe1b2003-11-23 18:19:58 +0000102 return nn;
103}
104
105int
106vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
107{
108 VtFcall tx, rx;
109
110 tx.type = VtTwrite;
111 tx.dtype = type;
112 tx.data = p;
rsca09e80f2004-05-23 00:59:17 +0000113 if(ventidoublechecksha1)
114 packetsha1(p, score);
rsc056fe1b2003-11-23 18:19:58 +0000115 if(vtfcallrpc(z, &tx, &rx) < 0)
116 return -1;
rsca09e80f2004-05-23 00:59:17 +0000117 if(ventidoublechecksha1){
118 if(memcmp(score, rx.score, VtScoreSize) != 0){
119 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
120 return -1;
121 }
rsc4192ac12004-06-09 14:03:54 +0000122 }else
123 memmove(score, rx.score, VtScoreSize);
rsc056fe1b2003-11-23 18:19:58 +0000124 return 0;
125}
126
127int
128vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
129{
130 Packet *p;
131
132 p = packetforeign(buf, n, nil, nil);
133 return vtwritepacket(z, score, type, p);
134}
135
136int
137vtsync(VtConn *z)
138{
139 VtFcall tx, rx;
140
141 tx.type = VtTsync;
142 return vtfcallrpc(z, &tx, &rx);
143}
144
145int
146vtping(VtConn *z)
147{
148 VtFcall tx, rx;
149
150 tx.type = VtTping;
151 return vtfcallrpc(z, &tx, &rx);
152}
153
154int
155vtconnect(VtConn *z)
156{
157 if(vtversion(z) < 0)
158 return -1;
159 if(vthello(z) < 0)
160 return -1;
161 return 0;
162}
163