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