summaryrefslogtreecommitdiff
path: root/sys/src/libventi/client.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libventi/client.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libventi/client.c')
-rwxr-xr-xsys/src/libventi/client.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/sys/src/libventi/client.c b/sys/src/libventi/client.c
new file mode 100755
index 000000000..40ee85175
--- /dev/null
+++ b/sys/src/libventi/client.c
@@ -0,0 +1,180 @@
+#include <u.h>
+#include <libc.h>
+#include <venti.h>
+
+int ventidoublechecksha1 = 1;
+
+static int
+vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
+{
+ Packet *p;
+
+ p = vtfcallpack(ou);
+ if(p == nil)
+ return -1;
+ if((p = _vtrpc(z, p, ou)) == nil)
+ return -1;
+ if(vtfcallunpack(in, p) < 0){
+ packetfree(p);
+ return -1;
+ }
+ if(chattyventi)
+ fprint(2, "%s <- %F\n", argv0, in);
+ if(in->msgtype == VtRerror){
+ werrstr(in->error);
+ vtfcallclear(in);
+ packetfree(p);
+ return -1;
+ }
+ if(in->msgtype != ou->msgtype+1){
+ werrstr("type mismatch: sent %c%d got %c%d",
+ "TR"[ou->msgtype&1], ou->msgtype>>1,
+ "TR"[in->msgtype&1], in->msgtype>>1);
+ vtfcallclear(in);
+ packetfree(p);
+ return -1;
+ }
+ packetfree(p);
+ return 0;
+}
+
+int
+vthello(VtConn *z)
+{
+ VtFcall tx, rx;
+
+ memset(&tx, 0, sizeof tx);
+ tx.msgtype = 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;
+
+ if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
+ return packetalloc();
+
+ memset(&tx, 0, sizeof tx);
+ tx.msgtype = VtTread;
+ tx.blocktype = 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;
+ }
+ 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;
+ }
+ }
+ 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();
+ packetfree(p);
+ return nn;
+}
+
+int
+vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
+{
+ VtFcall tx, rx;
+
+ if(packetsize(p) == 0){
+ memmove(score, vtzeroscore, VtScoreSize);
+ return 0;
+ }
+ tx.msgtype = VtTwrite;
+ tx.blocktype = type;
+ tx.data = p;
+ if(ventidoublechecksha1)
+ packetsha1(p, score);
+ if(vtfcallrpc(z, &tx, &rx) < 0)
+ return -1;
+ if(ventidoublechecksha1){
+ if(memcmp(score, rx.score, VtScoreSize) != 0){
+ werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
+ return -1;
+ }
+ }else
+ memmove(score, rx.score, VtScoreSize);
+ return 0;
+}
+
+int
+vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
+{
+ Packet *p;
+ int nn;
+
+ p = packetforeign(buf, n, 0, nil);
+ nn = vtwritepacket(z, score, type, p);
+ packetfree(p);
+ return nn;
+}
+
+int
+vtsync(VtConn *z)
+{
+ VtFcall tx, rx;
+
+ tx.msgtype = VtTsync;
+ return vtfcallrpc(z, &tx, &rx);
+}
+
+int
+vtping(VtConn *z)
+{
+ VtFcall tx, rx;
+
+ tx.msgtype = VtTping;
+ return vtfcallrpc(z, &tx, &rx);
+}
+
+int
+vtconnect(VtConn *z)
+{
+ if(vtversion(z) < 0)
+ return -1;
+ if(vthello(z) < 0)
+ return -1;
+ return 0;
+}
+
+int
+vtgoodbye(VtConn *z)
+{
+ VtFcall tx, rx;
+
+ tx.msgtype = VtTgoodbye;
+ vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */
+ return 0;
+}