plan9port/src/libventi/client.c

174 lines
3 KiB
C
Raw Normal View History

2003-11-23 18:19:58 +00:00
#include <u.h>
#include <libc.h>
#include <venti.h>
2004-05-23 00:59:17 +00:00
int ventidoublechecksha1 = 1;
2003-11-23 18:19:58 +00:00
static int
vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
{
Packet *p;
2004-05-23 00:59:17 +00:00
if(chattyventi)
fprint(2, "%s -> %F\n", argv0, ou);
2003-11-23 18:19:58 +00:00
p = vtfcallpack(ou);
if(p == nil)
return -1;
if((p = vtrpc(z, p)) == nil)
return -1;
if(vtfcallunpack(in, p) < 0){
packetfree(p);
return -1;
}
2004-05-23 00:59:17 +00:00
if(chattyventi)
fprint(2, "%s <- %F\n", argv0, in);
2003-11-23 18:19:58 +00:00
if(in->type == VtRerror){
werrstr(in->error);
vtfcallclear(in);
packetfree(p);
return -1;
}
if(in->type != ou->type+1){
werrstr("type mismatch: sent %c%d got %c%d",
"TR"[ou->type&1], ou->type>>1,
"TR"[in->type&1], in->type>>1);
vtfcallclear(in);
packetfree(p);
return -1;
}
packetfree(p);
return 0;
}
int
vthello(VtConn *z)
{
VtFcall tx, rx;
memset(&tx, 0, sizeof tx);
tx.type = VtThello;
tx.version = z->version;
tx.uid = z->uid;
if(tx.uid == nil)
tx.uid = "anonymous";
if(vtfcallrpc(z, &tx, &rx) < 0)
return -1;
z->sid = rx.sid;
rx.sid = 0;
vtfcallclear(&rx);
return 0;
}
Packet*
vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
{
VtFcall tx, rx;
2004-06-17 18:51:50 +00:00
if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
return packetalloc();
2003-11-23 18:19:58 +00:00
memset(&tx, 0, sizeof tx);
tx.type = VtTread;
tx.dtype = type;
tx.count = n;
memmove(tx.score, score, VtScoreSize);
if(vtfcallrpc(z, &tx, &rx) < 0)
return nil;
if(packetsize(rx.data) > n){
werrstr("read returned too much data");
packetfree(rx.data);
return nil;
}
2004-05-23 00:59:17 +00:00
if(ventidoublechecksha1){
packetsha1(rx.data, tx.score);
if(memcmp(score, tx.score, VtScoreSize) != 0){
werrstr("read asked for %V got %V", score, tx.score);
packetfree(rx.data);
return nil;
}
2003-11-23 18:19:58 +00:00
}
return rx.data;
}
int
vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
{
int nn;
Packet *p;
if((p = vtreadpacket(z, score, type, n)) == nil)
return -1;
nn = packetsize(p);
if(packetconsume(p, buf, nn) < 0)
abort();
2004-06-16 03:12:39 +00:00
packetfree(p);
2003-11-23 18:19:58 +00:00
return nn;
}
int
vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
{
VtFcall tx, rx;
2004-06-17 18:51:50 +00:00
if(packetsize(p) == 0){
memmove(score, vtzeroscore, VtScoreSize);
return 0;
}
2003-11-23 18:19:58 +00:00
tx.type = VtTwrite;
tx.dtype = type;
tx.data = p;
2004-05-23 00:59:17 +00:00
if(ventidoublechecksha1)
packetsha1(p, score);
2003-11-23 18:19:58 +00:00
if(vtfcallrpc(z, &tx, &rx) < 0)
return -1;
2004-05-23 00:59:17 +00:00
if(ventidoublechecksha1){
if(memcmp(score, rx.score, VtScoreSize) != 0){
werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
return -1;
}
2004-06-09 14:03:54 +00:00
}else
memmove(score, rx.score, VtScoreSize);
2003-11-23 18:19:58 +00:00
return 0;
}
int
vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
{
Packet *p;
2005-01-18 20:15:18 +00:00
int nn;
2003-11-23 18:19:58 +00:00
2005-01-14 18:21:12 +00:00
p = packetforeign(buf, n, 0, nil);
2005-01-18 20:15:18 +00:00
nn = vtwritepacket(z, score, type, p);
packetfree(p);
return nn;
2003-11-23 18:19:58 +00:00
}
int
vtsync(VtConn *z)
{
VtFcall tx, rx;
tx.type = VtTsync;
return vtfcallrpc(z, &tx, &rx);
}
int
vtping(VtConn *z)
{
VtFcall tx, rx;
tx.type = VtTping;
return vtfcallrpc(z, &tx, &rx);
}
int
vtconnect(VtConn *z)
{
if(vtversion(z) < 0)
return -1;
if(vthello(z) < 0)
return -1;
return 0;
}