aboutsummaryrefslogtreecommitdiff
path: root/src/libventi/fcall.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:19:58 +0000
committerrsc <devnull@localhost>2003-11-23 18:19:58 +0000
commit056fe1ba7fa0b70f871dfb9005b24eb8e4cc230b (patch)
tree9ad42f31c3bc124cf6617cf9eb41dd525eccce83 /src/libventi/fcall.c
parent9df487d720a59bf8cb0dc4ccffc30ad8eb48256a (diff)
downloadplan9port-056fe1ba7fa0b70f871dfb9005b24eb8e4cc230b.tar.gz
plan9port-056fe1ba7fa0b70f871dfb9005b24eb8e4cc230b.tar.bz2
plan9port-056fe1ba7fa0b70f871dfb9005b24eb8e4cc230b.zip
new venti library.
Diffstat (limited to 'src/libventi/fcall.c')
-rw-r--r--src/libventi/fcall.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/libventi/fcall.c b/src/libventi/fcall.c
new file mode 100644
index 00000000..ace8962a
--- /dev/null
+++ b/src/libventi/fcall.c
@@ -0,0 +1,230 @@
+#include <u.h>
+#include <libc.h>
+#include <venti.h>
+
+Packet*
+vtfcallpack(VtFcall *f)
+{
+ uchar buf[4];
+ Packet *p;
+
+ p = packetalloc();
+
+ buf[0] = f->type;
+ buf[1] = f->tag;
+ packetappend(p, buf, 2);
+
+ switch(f->type){
+ default:
+ werrstr("vtfcallpack: unknown packet type %d", f->type);
+ goto Err;
+
+ case VtRerror:
+ if(vtputstring(p, f->error) < 0)
+ goto Err;
+ break;
+
+ case VtTping:
+ break;
+
+ case VtRping:
+ break;
+
+ case VtThello:
+ if(vtputstring(p, f->version) < 0
+ || vtputstring(p, f->uid) < 0)
+ goto Err;
+ buf[0] = f->strength;
+ buf[1] = f->ncrypto;
+ packetappend(p, buf, 2);
+ packetappend(p, f->crypto, f->ncrypto);
+ buf[0] = f->ncodec;
+ packetappend(p, buf, 1);
+ packetappend(p, f->codec, f->ncodec);
+ break;
+
+ case VtRhello:
+ if(vtputstring(p, f->sid) < 0)
+ goto Err;
+ buf[0] = f->rcrypto;
+ buf[1] = f->rcodec;
+ packetappend(p, buf, 2);
+ break;
+
+ case VtTgoodbye:
+ break;
+
+ case VtTread:
+ packetappend(p, f->score, VtScoreSize);
+ buf[0] = vttodisktype(f->dtype);
+ if(~buf[0] == 0)
+ goto Err;
+ buf[1] = 0;
+ buf[2] = f->count >> 8;
+ buf[3] = f->count;
+ packetappend(p, buf, 4);
+ break;
+
+ case VtRread:
+ packetconcat(p, f->data);
+ break;
+
+ case VtTwrite:
+ buf[0] = vttodisktype(f->dtype);
+ if(~buf[0] == 0)
+ goto Err;
+ buf[1] = 0;
+ buf[2] = 0;
+ buf[3] = 0;
+ packetappend(p, buf, 4);
+ packetconcat(p, f->data);
+ break;
+
+ case VtRwrite:
+ packetappend(p, f->score, VtScoreSize);
+ break;
+
+ case VtTsync:
+ break;
+
+ case VtRsync:
+ break;
+ }
+
+ return p;
+
+Err:
+ packetfree(p);
+ return nil;
+}
+
+int
+vtfcallunpack(VtFcall *f, Packet *p)
+{
+ uchar buf[4];
+
+ memset(f, 0, sizeof *f);
+
+ if(packetconsume(p, buf, 2) < 0)
+ return -1;
+
+ f->type = buf[0];
+ f->tag = buf[1];
+
+ switch(f->type){
+ default:
+ werrstr("vtfcallunpack: unknown bad packet type %d", f->type);
+ vtfcallclear(f);
+ return -1;
+
+ case VtRerror:
+ if(vtgetstring(p, &f->error) < 0)
+ goto Err;
+ break;
+
+ case VtTping:
+ break;
+
+ case VtRping:
+ break;
+
+ case VtThello:
+ if(vtgetstring(p, &f->version) < 0
+ || vtgetstring(p, &f->uid) < 0
+ || packetconsume(p, buf, 2) < 0)
+ goto Err;
+ f->strength = buf[0];
+ f->ncrypto = buf[1];
+ if(f->ncrypto){
+ f->crypto = vtmalloc(f->ncrypto);
+ if(packetconsume(p, buf, f->ncrypto) < 0)
+ goto Err;
+ }
+ if(packetconsume(p, buf, 1) < 0)
+ goto Err;
+ f->ncodec = buf[0];
+ if(f->ncodec){
+ f->codec = vtmalloc(f->ncodec);
+ if(packetconsume(p, buf, f->ncodec) < 0)
+ goto Err;
+ }
+ break;
+
+ case VtRhello:
+ if(vtgetstring(p, &f->sid) < 0
+ || packetconsume(p, buf, 2) < 0)
+ goto Err;
+ f->rcrypto = buf[0];
+ f->rcodec = buf[1];
+ break;
+
+ case VtTgoodbye:
+ break;
+
+ case VtTread:
+ if(packetconsume(p, f->score, VtScoreSize) < 0
+ || packetconsume(p, buf, 4) < 0)
+ goto Err;
+ f->dtype = vtfromdisktype(buf[0]);
+ if(~f->dtype == 0)
+ goto Err;
+ f->count = (buf[2] << 8) | buf[3];
+ break;
+
+ case VtRread:
+ f->data = packetalloc();
+ packetconcat(f->data, p);
+ break;
+
+ case VtTwrite:
+ if(packetconsume(p, buf, 4) < 0)
+ goto Err;
+ f->dtype = vtfromdisktype(buf[0]);
+ if(~f->dtype == 0)
+ goto Err;
+ f->data = packetalloc();
+ packetconcat(f->data, p);
+ break;
+
+ case VtRwrite:
+ if(packetconsume(p, f->score, VtScoreSize) < 0)
+ goto Err;
+ break;
+
+ case VtTsync:
+ break;
+
+ case VtRsync:
+ break;
+ }
+
+ if(packetsize(p) != 0)
+ goto Err;
+
+ return 0;
+
+Err:
+ werrstr("bad packet");
+ return -1;
+}
+
+void
+vtfcallclear(VtFcall *f)
+{
+ vtfree(f->error);
+ f->error = nil;
+ vtfree(f->uid);
+ f->uid = nil;
+ vtfree(f->sid);
+ f->sid = nil;
+ vtfree(f->version);
+ f->version = nil;
+ vtfree(f->crypto);
+ f->crypto = nil;
+ vtfree(f->codec);
+ f->codec = nil;
+ vtfree(f->auth);
+ f->auth = nil;
+ packetfree(f->data);
+ f->auth = nil;
+}