/* * 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> Packet*vtfcallpack(VtFcall *f){ uchar buf[4]; Packet *p; p = packetalloc(); buf[0] = f->msgtype; buf[1] = f->tag; packetappend(p, buf, 2); switch(f->msgtype){ default: werrstr("vtfcallpack: unknown packet type %d", f->msgtype); 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->blocktype); 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->blocktype); 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;} intvtfcallunpack(VtFcall *f, Packet *p){ uchar buf[4]; memset(f, 0, sizeof *f); if(packetconsume(p, buf, 2) < 0) return -1; f->msgtype = buf[0]; f->tag = buf[1]; switch(f->msgtype){ default: werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype); 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->blocktype = vtfromdisktype(buf[0]); if(~f->blocktype == 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->blocktype = vtfromdisktype(buf[0]); if(~f->blocktype == 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"); vtfcallclear(f); return -1;} voidvtfcallclear(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->data = nil;}
/*
* 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>
Packet*
vtfcallpack(VtFcall *f)
{
uchar buf[4];
Packet *p;
p = packetalloc();
buf[0] = f->msgtype;
buf[1] = f->tag;
packetappend(p, buf, 2);
switch(f->msgtype){
default:
werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
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->blocktype);
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->blocktype);
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->msgtype = buf[0];
f->tag = buf[1];
switch(f->msgtype){
default:
werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
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->blocktype = vtfromdisktype(buf[0]);
if(~f->blocktype == 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->blocktype = vtfromdisktype(buf[0]);
if(~f->blocktype == 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");
vtfcallclear(f);
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->data = nil;
}