2003-11-23 17:55:34 +00:00
|
|
|
#include "stdinc.h"
|
|
|
|
#include "vac.h"
|
|
|
|
#include "dat.h"
|
|
|
|
#include "fns.h"
|
|
|
|
|
|
|
|
static char EBadVacFormat[] = "bad format for vac file";
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
static VacFs *
|
|
|
|
vacfsalloc(VtConn *z, int bsize, int ncache, int mode)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
VacFs *fs;
|
2003-11-23 17:55:34 +00:00
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
fs = vtmallocz(sizeof(VacFs));
|
2003-11-23 17:55:34 +00:00
|
|
|
fs->ref = 1;
|
|
|
|
fs->z = z;
|
|
|
|
fs->bsize = bsize;
|
2004-03-15 01:56:49 +00:00
|
|
|
fs->cache = vtcachealloc(z, bsize, ncache, mode);
|
2003-11-23 17:55:34 +00:00
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-03-15 01:56:49 +00:00
|
|
|
readscore(int fd, uchar score[VtScoreSize])
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
char buf[45], *pref;
|
|
|
|
int n;
|
2003-11-23 17:55:34 +00:00
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
n = readn(fd, buf, sizeof(buf)-1);
|
2003-11-23 17:55:34 +00:00
|
|
|
if(n < sizeof(buf)) {
|
2004-03-15 01:56:49 +00:00
|
|
|
werrstr("short read");
|
|
|
|
return -1;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
2004-03-15 01:56:49 +00:00
|
|
|
buf[n] = 0;
|
|
|
|
|
|
|
|
if(vtparsescore(buf, &pref, score) < 0){
|
|
|
|
werrstr(EBadVacFormat);
|
|
|
|
return -1;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
2004-03-15 01:56:49 +00:00
|
|
|
if(pref==nil || strcmp(pref, "vac") != 0) {
|
|
|
|
werrstr("not a vac file");
|
|
|
|
return -1;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
2004-03-15 01:56:49 +00:00
|
|
|
return 0;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
VacFs*
|
|
|
|
vacfsopen(VtConn *z, char *file, int mode, int ncache)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
int fd;
|
|
|
|
uchar score[VtScoreSize];
|
2003-11-23 17:55:34 +00:00
|
|
|
|
|
|
|
fd = open(file, OREAD);
|
2004-03-15 01:56:49 +00:00
|
|
|
if(fd < 0)
|
2003-11-23 17:55:34 +00:00
|
|
|
return nil;
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
if(readscore(fd, score) < 0){
|
2003-11-23 17:55:34 +00:00
|
|
|
close(fd);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
return vacfsopenscore(z, score, mode, ncache);
|
|
|
|
}
|
|
|
|
|
|
|
|
VacFs*
|
|
|
|
vacfsopenscore(VtConn *z, u8int *score, int mode, int ncache)
|
|
|
|
{
|
|
|
|
VacFs *fs;
|
|
|
|
int n;
|
|
|
|
VtRoot rt;
|
|
|
|
uchar buf[VtRootSize];
|
|
|
|
VacFile *root;
|
|
|
|
VtFile *r;
|
|
|
|
VtEntry e;
|
|
|
|
|
|
|
|
n = vtread(z, score, VtRootType, buf, VtRootSize);
|
2003-11-23 17:55:34 +00:00
|
|
|
if(n < 0)
|
|
|
|
return nil;
|
2004-03-15 01:56:49 +00:00
|
|
|
if(n != VtRootSize){
|
|
|
|
werrstr("vtread on root too short");
|
2003-11-23 17:55:34 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
if(vtrootunpack(&rt, buf) < 0)
|
2003-11-23 17:55:34 +00:00
|
|
|
return nil;
|
|
|
|
|
|
|
|
if(strcmp(rt.type, "vac") != 0) {
|
2004-03-15 01:56:49 +00:00
|
|
|
werrstr("not a vac root");
|
2003-11-23 17:55:34 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
fs = vacfsalloc(z, rt.blocksize, ncache, mode);
|
2003-11-23 17:55:34 +00:00
|
|
|
memmove(fs->score, score, VtScoreSize);
|
2004-03-15 01:56:49 +00:00
|
|
|
fs->mode = mode;
|
|
|
|
|
|
|
|
memmove(e.score, score, VtScoreSize);
|
|
|
|
e.gen = 0;
|
|
|
|
e.psize = (rt.blocksize/VtEntrySize)*VtEntrySize;
|
|
|
|
e.dsize = rt.blocksize;
|
|
|
|
e.type = VtDirType;
|
|
|
|
e.flags = VtEntryActive;
|
|
|
|
e.size = 3*VtEntrySize;
|
|
|
|
|
|
|
|
root = nil;
|
|
|
|
if((r = vtfileopenroot(fs->cache, &e)) == nil)
|
|
|
|
goto Err;
|
|
|
|
|
|
|
|
root = _vacfileroot(fs, r);
|
|
|
|
vtfileclose(r);
|
2003-11-23 17:55:34 +00:00
|
|
|
if(root == nil)
|
|
|
|
goto Err;
|
|
|
|
fs->root = root;
|
|
|
|
|
|
|
|
return fs;
|
|
|
|
Err:
|
|
|
|
if(root)
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfiledecref(root);
|
|
|
|
vacfsclose(fs);
|
2003-11-23 17:55:34 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
VacFs *
|
|
|
|
vacfscreate(VtConn *z, int bsize, int ncache)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
return vacfsalloc(z, bsize, ncache, VtORDWR);
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfsmode(VacFs *fs)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
return fs->mode;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
VacFile*
|
|
|
|
vacfsgetroot(VacFs *fs)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
return vacfileincref(fs->root);
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfsgetblocksize(VacFs *fs)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
|
|
|
return fs->bsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfsgetscore(VacFs *fs, u8int *score)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
memmove(score, fs->score, VtScoreSize);
|
|
|
|
return 0;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-15 01:56:49 +00:00
|
|
|
_vacfsnextqid(VacFs *fs, uvlong *qid)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
++fs->qid;
|
|
|
|
*qid = fs->qid;
|
|
|
|
return 0;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfssync(VacFs *fs)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
2004-03-15 01:56:49 +00:00
|
|
|
return 0;
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
2004-03-15 01:56:49 +00:00
|
|
|
void
|
|
|
|
vacfsclose(VacFs *fs)
|
2003-11-23 17:55:34 +00:00
|
|
|
{
|
|
|
|
if(fs->root)
|
2004-03-15 01:56:49 +00:00
|
|
|
vacfiledecref(fs->root);
|
2003-11-23 17:55:34 +00:00
|
|
|
fs->root = nil;
|
2004-03-15 01:56:49 +00:00
|
|
|
vtcachefree(fs->cache);
|
|
|
|
vtfree(fs);
|
2003-11-23 17:55:34 +00:00
|
|
|
}
|
|
|
|
|