new venti library.
This commit is contained in:
parent
9df487d720
commit
056fe1ba7f
28 changed files with 4635 additions and 0 deletions
115
src/libventi/version.c
Normal file
115
src/libventi/version.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <venti.h>
|
||||
|
||||
static char *okvers[] = {
|
||||
"02",
|
||||
nil,
|
||||
};
|
||||
|
||||
/*
|
||||
static char EBigString[] = "string too long";
|
||||
static char EBigPacket[] = "packet too long";
|
||||
static char ENullString[] = "missing string";
|
||||
*/
|
||||
static char EBadVersion[] = "bad format in version string";
|
||||
|
||||
static int
|
||||
vtreadversion(VtConn *z, char *q, char *v, int nv)
|
||||
{
|
||||
int n;
|
||||
|
||||
for(;;){
|
||||
if(nv <= 1){
|
||||
werrstr("version too long");
|
||||
return -1;
|
||||
}
|
||||
n = read(z->infd, v, 1);
|
||||
if(n <= 0){
|
||||
if(n == 0)
|
||||
werrstr("unexpected eof");
|
||||
return -1;
|
||||
}
|
||||
if(*v == '\n'){
|
||||
*v = 0;
|
||||
break;
|
||||
}
|
||||
if((uchar)*v < ' ' || (uchar)*v > 0x7f || (*q && *v != *q)){
|
||||
werrstr(EBadVersion);
|
||||
return -1;
|
||||
}
|
||||
v++;
|
||||
nv--;
|
||||
if(*q)
|
||||
q++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vtversion(VtConn *z)
|
||||
{
|
||||
char buf[VtMaxStringSize], *p, *ep, *prefix, *pp;
|
||||
int i;
|
||||
|
||||
qlock(&z->lk);
|
||||
if(z->state != VtStateAlloc){
|
||||
werrstr("bad session state");
|
||||
qunlock(&z->lk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qlock(&z->inlk);
|
||||
qlock(&z->outlk);
|
||||
|
||||
p = buf;
|
||||
ep = buf + sizeof buf;
|
||||
prefix = "venti-";
|
||||
p = seprint(p, ep, "%s", prefix);
|
||||
p += strlen(p);
|
||||
for(i=0; okvers[i]; i++)
|
||||
p = seprint(p, ep, "%s%s", i ? ":" : "", okvers[i]);
|
||||
p = seprint(p, ep, "-libventi\n");
|
||||
assert(p-buf < sizeof buf);
|
||||
|
||||
if(write(z->outfd, buf, p-buf) != p-buf)
|
||||
goto Err;
|
||||
vtdebug(z, "version string out: %s", buf);
|
||||
|
||||
if(vtreadversion(z, prefix, buf, sizeof buf) < 0)
|
||||
goto Err;
|
||||
vtdebug(z, "version string in: %s", buf);
|
||||
|
||||
p = buf+strlen(prefix);
|
||||
for(;;){
|
||||
pp = strpbrk(p, ":-");
|
||||
for(i=0; okvers[i]; i++)
|
||||
if(strlen(okvers[i]) == pp-p && memcmp(okvers[i], p, pp-p) == 0){
|
||||
*pp = 0;
|
||||
z->version = vtstrdup(p);
|
||||
goto Okay;
|
||||
}
|
||||
}
|
||||
werrstr("unable to negotiate version");
|
||||
goto Err;
|
||||
|
||||
Okay:
|
||||
z->state = VtStateConnected;
|
||||
qunlock(&z->inlk);
|
||||
qunlock(&z->outlk);
|
||||
qunlock(&z->lk);
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
if(z->infd >= 0)
|
||||
close(z->infd);
|
||||
if(z->outfd >= 0 && z->outfd != z->infd)
|
||||
close(z->outfd);
|
||||
z->infd = -1;
|
||||
z->outfd = -1;
|
||||
z->state = VtStateClosed;
|
||||
qunlock(&z->inlk);
|
||||
qunlock(&z->outlk);
|
||||
qunlock(&z->lk);
|
||||
return -1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue