Blob


1 #include "stdinc.h"
2 #include "vac.h"
3 #include "dat.h"
4 #include "fns.h"
6 static char EBadVacFormat[] = "bad format for vac file";
8 static VacFS *
9 vfsAlloc(VtSession *z, int bsize, long ncache)
10 {
11 VacFS *fs;
13 fs = vtMemAllocZ(sizeof(VacFS));
14 fs->ref = 1;
15 fs->z = z;
16 fs->bsize = bsize;
17 fs->cache = cacheAlloc(z, bsize, ncache);
18 return fs;
19 }
21 static int
22 readScore(int fd, uchar score[VtScoreSize])
23 {
24 char buf[44];
25 int i, n, c;
27 n = readn(fd, buf, sizeof(buf));
28 if(n < sizeof(buf)) {
29 vtSetError("short read");
30 return 0;
31 }
32 if(strncmp(buf, "vac:", 4) != 0) {
33 vtSetError("not a vac file");
34 return 0;
35 }
36 memset(score, 0, VtScoreSize);
37 for(i=4; i<sizeof(buf); i++) {
38 if(buf[i] >= '0' && buf[i] <= '9')
39 c = buf[i] - '0';
40 else if(buf[i] >= 'a' && buf[i] <= 'f')
41 c = buf[i] - 'a' + 10;
42 else if(buf[i] >= 'A' && buf[i] <= 'F')
43 c = buf[i] - 'A' + 10;
44 else {
45 vtSetError("bad format for venti score");
46 return 0;
47 }
48 if((i & 1) == 0)
49 c <<= 4;
51 score[(i>>1)-2] |= c;
52 }
53 return 1;
54 }
56 VacFS *
57 vfsOpen(VtSession *z, char *file, int readOnly, long ncache)
58 {
59 VacFS *fs;
60 int n, fd;
61 VtRoot rt;
62 uchar score[VtScoreSize], buf[VtRootSize];
63 VacFile *root;
65 fd = open(file, OREAD);
66 if(fd < 0) {
67 vtOSError();
68 return nil;
69 }
71 if(!readScore(fd, score)) {
72 close(fd);
73 return nil;
74 }
75 close(fd);
77 n = vtRead(z, score, VtRootType, buf, VtRootSize);
78 if(n < 0)
79 return nil;
80 if(n != VtRootSize) {
81 vtSetError("vtRead on root too short");
82 return nil;
83 }
85 if(!vtSha1Check(score, buf, VtRootSize)) {
86 vtSetError("vtSha1Check failed on root block");
87 return nil;
88 }
90 if(!vtRootUnpack(&rt, buf))
91 return nil;
93 if(strcmp(rt.type, "vac") != 0) {
94 vtSetError("not a vac root");
95 return nil;
96 }
98 fs = vfsAlloc(z, rt.blockSize, ncache);
99 memmove(fs->score, score, VtScoreSize);
100 fs->readOnly = readOnly;
101 root = vfRoot(fs, rt.score);
102 if(root == nil)
103 goto Err;
104 fs->root = root;
106 return fs;
107 Err:
108 if(root)
109 vfDecRef(root);
110 vfsClose(fs);
111 return nil;
114 VacFS *
115 vacFsCreate(VtSession *z, int bsize, long ncache)
117 VacFS *fs;
119 fs = vfsAlloc(z, bsize, ncache);
120 return fs;
123 int
124 vfsIsReadOnly(VacFS *fs)
126 return fs->readOnly != 0;
129 VacFile *
130 vfsGetRoot(VacFS *fs)
132 return vfIncRef(fs->root);
135 int
136 vfsGetBlockSize(VacFS *fs)
138 return fs->bsize;
141 int
142 vfsGetScore(VacFS *fs, uchar score[VtScoreSize])
144 memmove(fs, score, VtScoreSize);
145 return 1;
148 long
149 vfsGetCacheSize(VacFS *fs)
151 return cacheGetSize(fs->cache);
154 int
155 vfsSetCacheSize(VacFS *fs, long size)
157 return cacheSetSize(fs->cache, size);
160 int
161 vfsSnapshot(VacFS *fs, char *src, char *dst)
163 USED(fs);
164 USED(src);
165 USED(dst);
166 return 1;
169 int
170 vfsSync(VacFS*)
172 return 1;
175 int
176 vfsClose(VacFS *fs)
178 if(fs->root)
179 vfDecRef(fs->root);
180 fs->root = nil;
181 cacheCheck(fs->cache);
182 cacheFree(fs->cache);
183 memset(fs, 0, sizeof(VacFS));
184 vtMemFree(fs);
185 return 1;