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 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 }
79 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 }
86 }
87 return rx.data;
88 }
90 int
91 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
92 {
93 int nn;
94 Packet *p;
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();
101 return nn;
104 int
105 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
107 VtFcall tx, rx;
109 tx.type = VtTwrite;
110 tx.dtype = type;
111 tx.data = p;
112 if(ventidoublechecksha1)
113 packetsha1(p, score);
114 if(vtfcallrpc(z, &tx, &rx) < 0)
115 return -1;
116 if(ventidoublechecksha1){
117 if(memcmp(score, rx.score, VtScoreSize) != 0){
118 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
119 return -1;
121 }else
122 memmove(score, rx.score, VtScoreSize);
123 return 0;
126 int
127 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
129 Packet *p;
131 p = packetforeign(buf, n, nil, nil);
132 return vtwritepacket(z, score, type, p);
135 int
136 vtsync(VtConn *z)
138 VtFcall tx, rx;
140 tx.type = VtTsync;
141 return vtfcallrpc(z, &tx, &rx);
144 int
145 vtping(VtConn *z)
147 VtFcall tx, rx;
149 tx.type = VtTping;
150 return vtfcallrpc(z, &tx, &rx);
153 int
154 vtconnect(VtConn *z)
156 if(vtversion(z) < 0)
157 return -1;
158 if(vthello(z) < 0)
159 return -1;
160 return 0;