xref: /plan9/sys/src/libventi/client.c (revision 368c31ab13393dea083228fdd1c3445076f83a4b)
1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 
5 int ventidoublechecksha1 = 1;
6 
7 static int
vtfcallrpc(VtConn * z,VtFcall * ou,VtFcall * in)8 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
9 {
10 	Packet *p;
11 
12 	p = vtfcallpack(ou);
13 	if(p == nil)
14 		return -1;
15 	if((p = _vtrpc(z, p, ou)) == nil)
16 		return -1;
17 	if(vtfcallunpack(in, p) < 0){
18 		packetfree(p);
19 		return -1;
20 	}
21 	if(chattyventi)
22 		fprint(2, "%s <- %F\n", argv0, in);
23 	if(in->msgtype == VtRerror){
24 		werrstr(in->error);
25 		vtfcallclear(in);
26 		packetfree(p);
27 		return -1;
28 	}
29 	if(in->msgtype != ou->msgtype+1){
30 		werrstr("type mismatch: sent %c%d got %c%d",
31 			"TR"[ou->msgtype&1], ou->msgtype>>1,
32 			"TR"[in->msgtype&1], in->msgtype>>1);
33 		vtfcallclear(in);
34 		packetfree(p);
35 		return -1;
36 	}
37 	packetfree(p);
38 	return 0;
39 }
40 
41 int
vthello(VtConn * z)42 vthello(VtConn *z)
43 {
44 	VtFcall tx, rx;
45 
46 	memset(&tx, 0, sizeof tx);
47 	tx.msgtype = VtThello;
48 	tx.version = z->version;
49 	tx.uid = z->uid;
50 	if(tx.uid == nil)
51 		tx.uid = "anonymous";
52 	if(vtfcallrpc(z, &tx, &rx) < 0)
53 		return -1;
54 	z->sid = rx.sid;
55 	rx.sid = 0;
56 	vtfcallclear(&rx);
57 	return 0;
58 }
59 
60 Packet*
vtreadpacket(VtConn * z,uchar score[VtScoreSize],uint type,int n)61 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
62 {
63 	VtFcall tx, rx;
64 
65 	if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
66 		return packetalloc();
67 
68 	memset(&tx, 0, sizeof tx);
69 	tx.msgtype = VtTread;
70 	tx.blocktype = type;
71 	tx.count = n;
72 	memmove(tx.score, score, VtScoreSize);
73 	if(vtfcallrpc(z, &tx, &rx) < 0)
74 		return nil;
75 	if(packetsize(rx.data) > n){
76 		werrstr("read returned too much data");
77 		packetfree(rx.data);
78 		return nil;
79 	}
80 	if(ventidoublechecksha1){
81 		packetsha1(rx.data, tx.score);
82 		if(memcmp(score, tx.score, VtScoreSize) != 0){
83 			werrstr("read asked for %V got %V", score, tx.score);
84 			packetfree(rx.data);
85 			return nil;
86 		}
87 	}
88 	return rx.data;
89 }
90 
91 int
vtread(VtConn * z,uchar score[VtScoreSize],uint type,uchar * buf,int n)92 vtread(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 	packetfree(p);
103 	return nn;
104 }
105 
106 int
vtwritepacket(VtConn * z,uchar score[VtScoreSize],uint type,Packet * p)107 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
108 {
109 	VtFcall tx, rx;
110 
111 	if(packetsize(p) == 0){
112 		memmove(score, vtzeroscore, VtScoreSize);
113 		return 0;
114 	}
115 	tx.msgtype = VtTwrite;
116 	tx.blocktype = type;
117 	tx.data = p;
118 	if(ventidoublechecksha1)
119 		packetsha1(p, score);
120 	if(vtfcallrpc(z, &tx, &rx) < 0)
121 		return -1;
122 	if(ventidoublechecksha1){
123 		if(memcmp(score, rx.score, VtScoreSize) != 0){
124 			werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
125 			return -1;
126 		}
127 	}else
128 		memmove(score, rx.score, VtScoreSize);
129 	return 0;
130 }
131 
132 int
vtwrite(VtConn * z,uchar score[VtScoreSize],uint type,uchar * buf,int n)133 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
134 {
135 	Packet *p;
136 	int nn;
137 
138 	p = packetforeign(buf, n, 0, nil);
139 	nn = vtwritepacket(z, score, type, p);
140 	packetfree(p);
141 	return nn;
142 }
143 
144 int
vtsync(VtConn * z)145 vtsync(VtConn *z)
146 {
147 	VtFcall tx, rx;
148 
149 	tx.msgtype = VtTsync;
150 	return vtfcallrpc(z, &tx, &rx);
151 }
152 
153 int
vtping(VtConn * z)154 vtping(VtConn *z)
155 {
156 	VtFcall tx, rx;
157 
158 	tx.msgtype = VtTping;
159 	return vtfcallrpc(z, &tx, &rx);
160 }
161 
162 int
vtconnect(VtConn * z)163 vtconnect(VtConn *z)
164 {
165 	if(vtversion(z) < 0)
166 		return -1;
167 	if(vthello(z) < 0)
168 		return -1;
169 	return 0;
170 }
171 
172 int
vtgoodbye(VtConn * z)173 vtgoodbye(VtConn *z)
174 {
175 	VtFcall tx, rx;
176 
177 	tx.msgtype = VtTgoodbye;
178 	vtfcallrpc(z, &tx, &rx);	/* always fails: no VtRgoodbye */
179 	return 0;
180 }
181