Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <venti.h>
4
 
5
int ventidoublechecksha1 = 1;
6
 
7
static int
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
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*
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
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
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
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
145
vtsync(VtConn *z)
146
{
147
	VtFcall tx, rx;
148
 
149
	tx.msgtype = VtTsync;
150
	return vtfcallrpc(z, &tx, &rx);
151
}
152
 
153
int
154
vtping(VtConn *z)
155
{
156
	VtFcall tx, rx;
157
 
158
	tx.msgtype = VtTping;
159
	return vtfcallrpc(z, &tx, &rx);
160
}
161
 
162
int
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
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
}