Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
5 int ventidoublechecksha1 = 1;
7 static int
8 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
9 {
10 Packet *p;
12 if(chattyventi)
13 fprint(2, "%s -> %F\n", argv0, ou);
14 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 }
23 if(chattyventi)
24 fprint(2, "%s <- %F\n", argv0, in);
25 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 }
43 int
44 vthello(VtConn *z)
45 {
46 VtFcall tx, rx;
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 }
62 Packet*
63 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
64 {
65 VtFcall tx, rx;
67 if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
68 return packetalloc();
70 memset(&tx, 0, sizeof tx);
71 tx.type = VtTread;
72 tx.dtype = type;
73 tx.count = n;
74 memmove(tx.score, score, VtScoreSize);
75 if(vtfcallrpc(z, &tx, &rx) < 0)
76 return nil;
77 if(packetsize(rx.data) > n){
78 werrstr("read returned too much data");
79 packetfree(rx.data);
80 return nil;
81 }
82 if(ventidoublechecksha1){
83 packetsha1(rx.data, tx.score);
84 if(memcmp(score, tx.score, VtScoreSize) != 0){
85 werrstr("read asked for %V got %V", score, tx.score);
86 packetfree(rx.data);
87 return nil;
88 }
89 }
90 return rx.data;
91 }
93 int
94 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
95 {
96 int nn;
97 Packet *p;
99 if((p = vtreadpacket(z, score, type, n)) == nil)
100 return -1;
101 nn = packetsize(p);
102 if(packetconsume(p, buf, nn) < 0)
103 abort();
104 packetfree(p);
105 return nn;
108 int
109 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
111 VtFcall tx, rx;
113 if(packetsize(p) == 0){
114 memmove(score, vtzeroscore, VtScoreSize);
115 return 0;
117 tx.type = VtTwrite;
118 tx.dtype = type;
119 tx.data = p;
120 if(ventidoublechecksha1)
121 packetsha1(p, score);
122 if(vtfcallrpc(z, &tx, &rx) < 0)
123 return -1;
124 if(ventidoublechecksha1){
125 if(memcmp(score, rx.score, VtScoreSize) != 0){
126 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
127 return -1;
129 }else
130 memmove(score, rx.score, VtScoreSize);
131 return 0;
134 int
135 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
137 Packet *p;
139 p = packetforeign(buf, n, nil, nil);
140 return vtwritepacket(z, score, type, p);
143 int
144 vtsync(VtConn *z)
146 VtFcall tx, rx;
148 tx.type = VtTsync;
149 return vtfcallrpc(z, &tx, &rx);
152 int
153 vtping(VtConn *z)
155 VtFcall tx, rx;
157 tx.type = VtTping;
158 return vtfcallrpc(z, &tx, &rx);
161 int
162 vtconnect(VtConn *z)
164 if(vtversion(z) < 0)
165 return -1;
166 if(vthello(z) < 0)
167 return -1;
168 return 0;