123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- * 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)
- {
- uint8_t 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)
- {
- uint8_t 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;
- }
|