Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
5 static int
6 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
7 {
8 Packet *p;
10 p = vtfcallpack(ou);
11 if(p == nil)
12 return -1;
13 if((p = vtrpc(z, p)) == nil)
14 return -1;
15 if(vtfcallunpack(in, p) < 0){
16 packetfree(p);
17 return -1;
18 }
19 if(in->type == VtRerror){
20 werrstr(in->error);
21 vtfcallclear(in);
22 packetfree(p);
23 return -1;
24 }
25 if(in->type != ou->type+1){
26 werrstr("type mismatch: sent %c%d got %c%d",
27 "TR"[ou->type&1], ou->type>>1,
28 "TR"[in->type&1], in->type>>1);
29 vtfcallclear(in);
30 packetfree(p);
31 return -1;
32 }
33 packetfree(p);
34 return 0;
35 }
37 int
38 vthello(VtConn *z)
39 {
40 VtFcall tx, rx;
42 memset(&tx, 0, sizeof tx);
43 tx.type = VtThello;
44 tx.version = z->version;
45 tx.uid = z->uid;
46 if(tx.uid == nil)
47 tx.uid = "anonymous";
48 if(vtfcallrpc(z, &tx, &rx) < 0)
49 return -1;
50 z->sid = rx.sid;
51 rx.sid = 0;
52 vtfcallclear(&rx);
53 return 0;
54 }
56 Packet*
57 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
58 {
59 VtFcall tx, rx;
61 memset(&tx, 0, sizeof tx);
62 tx.type = VtTread;
63 tx.dtype = type;
64 tx.count = n;
65 memmove(tx.score, score, VtScoreSize);
66 if(vtfcallrpc(z, &tx, &rx) < 0)
67 return nil;
68 if(packetsize(rx.data) > n){
69 werrstr("read returned too much data");
70 packetfree(rx.data);
71 return nil;
72 }
73 packetsha1(rx.data, tx.score);
74 if(memcmp(score, tx.score, VtScoreSize) != 0){
75 werrstr("read asked for %V got %V", score, tx.score);
76 packetfree(rx.data);
77 return nil;
78 }
80 return rx.data;
81 }
83 int
84 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
85 {
86 int nn;
87 Packet *p;
89 if((p = vtreadpacket(z, score, type, n)) == nil)
90 return -1;
91 nn = packetsize(p);
92 if(packetconsume(p, buf, nn) < 0)
93 abort();
94 return nn;
95 }
97 int
98 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
99 {
100 VtFcall tx, rx;
102 tx.type = VtTwrite;
103 tx.dtype = type;
104 tx.data = p;
105 packetsha1(p, score);
106 if(vtfcallrpc(z, &tx, &rx) < 0)
107 return -1;
108 if(memcmp(score, rx.score, VtScoreSize) != 0){
109 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
110 return -1;
112 return 0;
115 int
116 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
118 Packet *p;
120 p = packetforeign(buf, n, nil, nil);
121 return vtwritepacket(z, score, type, p);
124 int
125 vtsync(VtConn *z)
127 VtFcall tx, rx;
129 tx.type = VtTsync;
130 return vtfcallrpc(z, &tx, &rx);
133 int
134 vtping(VtConn *z)
136 VtFcall tx, rx;
138 tx.type = VtTping;
139 return vtfcallrpc(z, &tx, &rx);
142 int
143 vtconnect(VtConn *z)
145 if(vtversion(z) < 0)
146 return -1;
147 if(vthello(z) < 0)
148 return -1;
149 return 0;