blob: b9e866fc9da828b390058ae69120035b3d4be655 [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 }
87
88 return rx.data;
89}
90
91int
92vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
93{
94 int nn;
95 Packet *p;
96
97 if((p = vtreadpacket(z, score, type, n)) == nil)
98 return -1;
99 nn = packetsize(p);
100 if(packetconsume(p, buf, nn) < 0)
101 abort();
102 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 }
rsc056fe1b2003-11-23 18:19:58 +0000122 }
123 return 0;
124}
125
126int
127vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
128{
129 Packet *p;
130
131 p = packetforeign(buf, n, nil, nil);
132 return vtwritepacket(z, score, type, p);
133}
134
135int
136vtsync(VtConn *z)
137{
138 VtFcall tx, rx;
139
140 tx.type = VtTsync;
141 return vtfcallrpc(z, &tx, &rx);
142}
143
144int
145vtping(VtConn *z)
146{
147 VtFcall tx, rx;
148
149 tx.type = VtTping;
150 return vtfcallrpc(z, &tx, &rx);
151}
152
153int
154vtconnect(VtConn *z)
155{
156 if(vtversion(z) < 0)
157 return -1;
158 if(vthello(z) < 0)
159 return -1;
160 return 0;
161}
162