/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <venti.h> int ventidoublechecksha1 = 1; static intvtfcallrpc(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;} intvthello(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;} intvtread(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;} intvtwritepacket(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;} intvtwrite(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;} intvtsync(VtConn *z){ VtFcall tx, rx; tx.msgtype = VtTsync; return vtfcallrpc(z, &tx, &rx);} intvtping(VtConn *z){ VtFcall tx, rx; tx.msgtype = VtTping; return vtfcallrpc(z, &tx, &rx);} intvtconnect(VtConn *z){ if(vtversion(z) < 0) return -1; if(vthello(z) < 0) return -1; return 0;} intvtgoodbye(VtConn *z){ VtFcall tx, rx; tx.msgtype = VtTgoodbye; vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */ return 0;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#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;
}