Blame


1 cb98c6f8 2005-01-14 devnull #include <u.h>
2 2277c5d7 2004-03-21 devnull #include <sys/stat.h>
3 3d77c87e 2004-03-15 devnull #include "stdinc.h"
4 3d77c87e 2004-03-15 devnull #include "vac.h"
5 3d77c87e 2004-03-15 devnull #include "dat.h"
6 3d77c87e 2004-03-15 devnull #include "fns.h"
7 7763a61a 2003-11-23 devnull
8 2277c5d7 2004-03-21 devnull int mainstacksize = 128*1024;
9 2277c5d7 2004-03-21 devnull
10 3d77c87e 2004-03-15 devnull typedef struct Sink Sink;
11 3d77c87e 2004-03-15 devnull typedef struct MetaSink MetaSink;
12 3d77c87e 2004-03-15 devnull typedef struct DirSink DirSink;
13 7763a61a 2003-11-23 devnull
14 3d77c87e 2004-03-15 devnull struct Sink {
15 3d77c87e 2004-03-15 devnull VtConn *z;
16 3d77c87e 2004-03-15 devnull VtEntry dir;
17 3d77c87e 2004-03-15 devnull uchar *buf;
18 3d77c87e 2004-03-15 devnull uchar *pbuf[VtPointerDepth+1];
19 3d77c87e 2004-03-15 devnull };
20 3d77c87e 2004-03-15 devnull
21 3d77c87e 2004-03-15 devnull struct DirSink {
22 3d77c87e 2004-03-15 devnull Sink *sink;
23 3d77c87e 2004-03-15 devnull MetaSink *msink;
24 3d77c87e 2004-03-15 devnull ulong nentry;
25 3d77c87e 2004-03-15 devnull uchar *buf;
26 3d77c87e 2004-03-15 devnull uchar *p; /* current pointer */
27 3d77c87e 2004-03-15 devnull uchar *ep; /* end pointer */
28 3d77c87e 2004-03-15 devnull };
29 3d77c87e 2004-03-15 devnull
30 3d77c87e 2004-03-15 devnull struct MetaSink {
31 3d77c87e 2004-03-15 devnull Sink *sink;
32 3d77c87e 2004-03-15 devnull uchar *buf;
33 3d77c87e 2004-03-15 devnull int maxindex;
34 3d77c87e 2004-03-15 devnull int nindex;
35 3d77c87e 2004-03-15 devnull uchar *rp; /* start of current record */
36 3d77c87e 2004-03-15 devnull uchar *p; /* current pointer */
37 3d77c87e 2004-03-15 devnull uchar *ep; /* end pointer */
38 3d77c87e 2004-03-15 devnull };
39 3d77c87e 2004-03-15 devnull
40 3d77c87e 2004-03-15 devnull static void usage(void);
41 3d77c87e 2004-03-15 devnull static int strpcmp(const void*, const void*);
42 3d77c87e 2004-03-15 devnull static void warn(char *fmt, ...);
43 3d77c87e 2004-03-15 devnull static void cleanup(void);
44 3d77c87e 2004-03-15 devnull static u64int unittoull(char *s);
45 3d77c87e 2004-03-15 devnull static void vac(VtConn *z, char *argv[]);
46 3d77c87e 2004-03-15 devnull static void vacfile(DirSink *dsink, char *lname, char *sname, VacFile*);
47 3d77c87e 2004-03-15 devnull static void vacstdin(DirSink *dsink, char *name, VacFile *vf);
48 3d77c87e 2004-03-15 devnull static void vacdata(DirSink *dsink, int fd, char *lname, VacFile*, Dir*);
49 3d77c87e 2004-03-15 devnull static void vacdir(DirSink *dsink, int fd, char *lname, char *sname, VacFile*);
50 3d77c87e 2004-03-15 devnull static int vacmerge(DirSink *dsink, char *lname, char *sname);
51 71f05672 2005-09-13 devnull static int vacspecial(DirSink *dsink, Dir *dir, char *lname, char *sname, VacFile *vf);
52 3d77c87e 2004-03-15 devnull Sink *sinkalloc(VtConn *z, int psize, int dsize);
53 3d77c87e 2004-03-15 devnull void sinkwrite(Sink *k, uchar *data, int n);
54 3d77c87e 2004-03-15 devnull void sinkwritescore(Sink *k, uchar *score, int n);
55 3d77c87e 2004-03-15 devnull void sinkclose(Sink *k);
56 3d77c87e 2004-03-15 devnull void sinkfree(Sink *k);
57 3d77c87e 2004-03-15 devnull
58 3d77c87e 2004-03-15 devnull DirSink *dirsinkalloc(VtConn *z, int psize, int dsize);
59 3d77c87e 2004-03-15 devnull void dirsinkwrite(DirSink *k, VtEntry*);
60 3d77c87e 2004-03-15 devnull void dirsinkwritesink(DirSink *k, Sink*);
61 3d77c87e 2004-03-15 devnull int dirsinkwritefile(DirSink *k, VacFile *vf);
62 3d77c87e 2004-03-15 devnull void dirsinkclose(DirSink *k);
63 3d77c87e 2004-03-15 devnull void dirsinkfree(DirSink *k);
64 3d77c87e 2004-03-15 devnull
65 3d77c87e 2004-03-15 devnull MetaSink *metasinkalloc(VtConn *z, int psize, int dsize);
66 3d77c87e 2004-03-15 devnull void metasinkputc(MetaSink *k, int c);
67 3d77c87e 2004-03-15 devnull void metasinkputstring(MetaSink *k, char *s);
68 3d77c87e 2004-03-15 devnull void metasinkputuint32(MetaSink *k, ulong x);
69 3d77c87e 2004-03-15 devnull void metasinkputuint64(MetaSink *k, uvlong x);
70 3d77c87e 2004-03-15 devnull void metasinkwrite(MetaSink *k, uchar *data, int n);
71 3d77c87e 2004-03-15 devnull void metasinkwritedir(MetaSink *ms, VacDir *vd);
72 3d77c87e 2004-03-15 devnull void metasinkeor(MetaSink *k);
73 3d77c87e 2004-03-15 devnull void metasinkclose(MetaSink *k);
74 3d77c87e 2004-03-15 devnull void metasinkfree(MetaSink *k);
75 3d77c87e 2004-03-15 devnull void plan9tovacdir(VacDir*, Dir*, ulong entry, uvlong qid);
76 3d77c87e 2004-03-15 devnull
77 3d77c87e 2004-03-15 devnull enum {
78 3d77c87e 2004-03-15 devnull Version = 8,
79 3d77c87e 2004-03-15 devnull BlockSize = 8*1024,
80 cbeb0b26 2006-04-01 devnull MaxExclude = 1000
81 3d77c87e 2004-03-15 devnull };
82 3d77c87e 2004-03-15 devnull
83 3d77c87e 2004-03-15 devnull struct {
84 3d77c87e 2004-03-15 devnull ulong file;
85 3d77c87e 2004-03-15 devnull ulong sfile;
86 3d77c87e 2004-03-15 devnull ulong data;
87 3d77c87e 2004-03-15 devnull ulong sdata;
88 3d77c87e 2004-03-15 devnull ulong skip;
89 3d77c87e 2004-03-15 devnull ulong meta;
90 3d77c87e 2004-03-15 devnull } stats;
91 3d77c87e 2004-03-15 devnull
92 3d77c87e 2004-03-15 devnull int bsize = BlockSize;
93 3d77c87e 2004-03-15 devnull int maxbsize;
94 3d77c87e 2004-03-15 devnull char *oname, *dfile;
95 3d77c87e 2004-03-15 devnull int verbose;
96 3d77c87e 2004-03-15 devnull uvlong fileid = 1;
97 3d77c87e 2004-03-15 devnull int qdiff;
98 3d77c87e 2004-03-15 devnull char *exclude[MaxExclude];
99 3d77c87e 2004-03-15 devnull int nexclude;
100 3d77c87e 2004-03-15 devnull int nowrite;
101 3d77c87e 2004-03-15 devnull int merge;
102 3d77c87e 2004-03-15 devnull char *isi;
103 3d77c87e 2004-03-15 devnull
104 3d77c87e 2004-03-15 devnull static void
105 7763a61a 2003-11-23 devnull usage(void)
106 7763a61a 2003-11-23 devnull {
107 3d77c87e 2004-03-15 devnull fprint(2, "usage: %s [-amqsv] [-h host] [-d vacfile] [-b blocksize] [-i name] [-e exclude] [-f vacfile] file ... \n", argv0);
108 38c10d1a 2005-01-17 devnull threadexitsall("usage");
109 7763a61a 2003-11-23 devnull }
110 7763a61a 2003-11-23 devnull
111 7763a61a 2003-11-23 devnull void
112 3d77c87e 2004-03-15 devnull threadmain(int argc, char *argv[])
113 7763a61a 2003-11-23 devnull {
114 3d77c87e 2004-03-15 devnull VtConn *z;
115 3d77c87e 2004-03-15 devnull char *p;
116 3d77c87e 2004-03-15 devnull char *host = nil;
117 3d77c87e 2004-03-15 devnull int statsflag = 0;
118 3d77c87e 2004-03-15 devnull
119 3d77c87e 2004-03-15 devnull atexit(cleanup);
120 3d77c87e 2004-03-15 devnull
121 7763a61a 2003-11-23 devnull ARGBEGIN{
122 7763a61a 2003-11-23 devnull default:
123 7763a61a 2003-11-23 devnull usage();
124 7763a61a 2003-11-23 devnull case 'b':
125 3d77c87e 2004-03-15 devnull p = ARGF();
126 3d77c87e 2004-03-15 devnull if(p == 0)
127 3d77c87e 2004-03-15 devnull usage();
128 3d77c87e 2004-03-15 devnull bsize = unittoull(p);
129 3d77c87e 2004-03-15 devnull if(bsize == ~0)
130 3d77c87e 2004-03-15 devnull usage();
131 7763a61a 2003-11-23 devnull break;
132 3d77c87e 2004-03-15 devnull case 'd':
133 3d77c87e 2004-03-15 devnull dfile = ARGF();
134 3d77c87e 2004-03-15 devnull if(dfile == nil)
135 3d77c87e 2004-03-15 devnull usage();
136 3d77c87e 2004-03-15 devnull break;
137 3d77c87e 2004-03-15 devnull case 'e':
138 3d77c87e 2004-03-15 devnull if(nexclude >= MaxExclude)
139 3d77c87e 2004-03-15 devnull sysfatal("too many exclusions\n");
140 3d77c87e 2004-03-15 devnull exclude[nexclude] = ARGF();
141 3d77c87e 2004-03-15 devnull if(exclude[nexclude] == nil)
142 3d77c87e 2004-03-15 devnull usage();
143 3d77c87e 2004-03-15 devnull nexclude++;
144 3d77c87e 2004-03-15 devnull break;
145 3d77c87e 2004-03-15 devnull case 'f':
146 3d77c87e 2004-03-15 devnull oname = ARGF();
147 3d77c87e 2004-03-15 devnull if(oname == 0)
148 3d77c87e 2004-03-15 devnull usage();
149 3d77c87e 2004-03-15 devnull break;
150 7763a61a 2003-11-23 devnull case 'h':
151 3d77c87e 2004-03-15 devnull host = ARGF();
152 3d77c87e 2004-03-15 devnull if(host == nil)
153 3d77c87e 2004-03-15 devnull usage();
154 7763a61a 2003-11-23 devnull break;
155 3d77c87e 2004-03-15 devnull case 'i':
156 3d77c87e 2004-03-15 devnull isi = ARGF();
157 3d77c87e 2004-03-15 devnull if(isi == nil)
158 3d77c87e 2004-03-15 devnull usage();
159 3d77c87e 2004-03-15 devnull break;
160 3d77c87e 2004-03-15 devnull case 'n':
161 3d77c87e 2004-03-15 devnull nowrite++;
162 3d77c87e 2004-03-15 devnull break;
163 3d77c87e 2004-03-15 devnull case 'm':
164 3d77c87e 2004-03-15 devnull merge++;
165 3d77c87e 2004-03-15 devnull break;
166 3d77c87e 2004-03-15 devnull case 'q':
167 3d77c87e 2004-03-15 devnull qdiff++;
168 3d77c87e 2004-03-15 devnull break;
169 3d77c87e 2004-03-15 devnull case 's':
170 3d77c87e 2004-03-15 devnull statsflag++;
171 3d77c87e 2004-03-15 devnull break;
172 3d77c87e 2004-03-15 devnull case 'v':
173 3d77c87e 2004-03-15 devnull verbose++;
174 3d77c87e 2004-03-15 devnull break;
175 3d77c87e 2004-03-15 devnull }ARGEND;
176 7763a61a 2003-11-23 devnull
177 2277c5d7 2004-03-21 devnull if(argc == 0)
178 2277c5d7 2004-03-21 devnull usage();
179 2277c5d7 2004-03-21 devnull
180 7763a61a 2003-11-23 devnull if(bsize < 512)
181 7763a61a 2003-11-23 devnull bsize = 512;
182 7763a61a 2003-11-23 devnull if(bsize > VtMaxLumpSize)
183 7763a61a 2003-11-23 devnull bsize = VtMaxLumpSize;
184 7763a61a 2003-11-23 devnull maxbsize = bsize;
185 7763a61a 2003-11-23 devnull
186 3d77c87e 2004-03-15 devnull fmtinstall('V', vtscorefmt);
187 7763a61a 2003-11-23 devnull
188 3d77c87e 2004-03-15 devnull z = vtdial(host);
189 7763a61a 2003-11-23 devnull if(z == nil)
190 3d77c87e 2004-03-15 devnull sysfatal("could not connect to server: %r");
191 7763a61a 2003-11-23 devnull
192 3d77c87e 2004-03-15 devnull if(vtconnect(z) < 0)
193 3d77c87e 2004-03-15 devnull sysfatal("vtconnect: %r");
194 7763a61a 2003-11-23 devnull
195 3d77c87e 2004-03-15 devnull qsort(exclude, nexclude, sizeof(char*), strpcmp);
196 7763a61a 2003-11-23 devnull
197 7763a61a 2003-11-23 devnull vac(z, argv);
198 3d77c87e 2004-03-15 devnull
199 3d77c87e 2004-03-15 devnull if(vtsync(z) < 0)
200 929fcfe0 2004-12-27 devnull fprint(2, "warning: could not ask server to flush pending writes: %r\n");
201 7763a61a 2003-11-23 devnull
202 3d77c87e 2004-03-15 devnull if(statsflag)
203 7763a61a 2003-11-23 devnull fprint(2, "files %ld:%ld data %ld:%ld:%ld meta %ld\n", stats.file, stats.sfile,
204 7763a61a 2003-11-23 devnull stats.data, stats.skip, stats.sdata, stats.meta);
205 cbeb0b26 2006-04-01 devnull /*packetStats(); */
206 3d77c87e 2004-03-15 devnull vthangup(z);
207 7763a61a 2003-11-23 devnull
208 3d77c87e 2004-03-15 devnull threadexitsall(0);
209 7763a61a 2003-11-23 devnull }
210 7763a61a 2003-11-23 devnull
211 7763a61a 2003-11-23 devnull static int
212 3d77c87e 2004-03-15 devnull strpcmp(const void *p0, const void *p1)
213 3d77c87e 2004-03-15 devnull {
214 3d77c87e 2004-03-15 devnull return strcmp(*(char**)p0, *(char**)p1);
215 3d77c87e 2004-03-15 devnull }
216 3d77c87e 2004-03-15 devnull
217 3d77c87e 2004-03-15 devnull int
218 3d77c87e 2004-03-15 devnull vacwrite(VtConn *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
219 3d77c87e 2004-03-15 devnull {
220 3d77c87e 2004-03-15 devnull assert(n > 0);
221 3d77c87e 2004-03-15 devnull if(nowrite){
222 3d77c87e 2004-03-15 devnull sha1(buf, n, score, nil);
223 3d77c87e 2004-03-15 devnull return 0;
224 3d77c87e 2004-03-15 devnull }
225 3d77c87e 2004-03-15 devnull return vtwrite(z, score, type, buf, n);
226 3d77c87e 2004-03-15 devnull }
227 3d77c87e 2004-03-15 devnull
228 3d77c87e 2004-03-15 devnull static char*
229 3d77c87e 2004-03-15 devnull lastelem(char *oname)
230 3d77c87e 2004-03-15 devnull {
231 3d77c87e 2004-03-15 devnull char *p;
232 3d77c87e 2004-03-15 devnull
233 3d77c87e 2004-03-15 devnull if(oname == nil)
234 3d77c87e 2004-03-15 devnull abort();
235 3d77c87e 2004-03-15 devnull if((p = strrchr(oname, '/')) == nil)
236 3d77c87e 2004-03-15 devnull return oname;
237 3d77c87e 2004-03-15 devnull return p+1;
238 3d77c87e 2004-03-15 devnull }
239 3d77c87e 2004-03-15 devnull
240 3d77c87e 2004-03-15 devnull static void
241 3d77c87e 2004-03-15 devnull vac(VtConn *z, char *argv[])
242 7763a61a 2003-11-23 devnull {
243 7763a61a 2003-11-23 devnull DirSink *dsink, *ds;
244 7763a61a 2003-11-23 devnull MetaSink *ms;
245 7763a61a 2003-11-23 devnull VtRoot root;
246 7763a61a 2003-11-23 devnull uchar score[VtScoreSize], buf[VtRootSize];
247 7763a61a 2003-11-23 devnull char cwd[2048];
248 3d77c87e 2004-03-15 devnull int cd;
249 7763a61a 2003-11-23 devnull char *cp2, *cp;
250 3d77c87e 2004-03-15 devnull VacFs *fs;
251 7763a61a 2003-11-23 devnull VacFile *vff;
252 7763a61a 2003-11-23 devnull int fd;
253 7763a61a 2003-11-23 devnull Dir *dir;
254 7763a61a 2003-11-23 devnull VacDir vd;
255 7763a61a 2003-11-23 devnull
256 7763a61a 2003-11-23 devnull if(getwd(cwd, sizeof(cwd)) == 0)
257 7763a61a 2003-11-23 devnull sysfatal("can't find current directory: %r\n");
258 7763a61a 2003-11-23 devnull
259 3d77c87e 2004-03-15 devnull dsink = dirsinkalloc(z, bsize, bsize);
260 7763a61a 2003-11-23 devnull
261 7763a61a 2003-11-23 devnull fs = nil;
262 7763a61a 2003-11-23 devnull if(dfile != nil) {
263 3d77c87e 2004-03-15 devnull fs = vacfsopen(z, dfile, VtOREAD, 1000);
264 7763a61a 2003-11-23 devnull if(fs == nil)
265 3d77c87e 2004-03-15 devnull fprint(2, "could not open diff: %s: %r\n", dfile);
266 7763a61a 2003-11-23 devnull }
267 7763a61a 2003-11-23 devnull
268 7763a61a 2003-11-23 devnull
269 7763a61a 2003-11-23 devnull if(oname != nil) {
270 7763a61a 2003-11-23 devnull fd = create(oname, OWRITE, 0666);
271 7763a61a 2003-11-23 devnull if(fd < 0)
272 7763a61a 2003-11-23 devnull sysfatal("could not create file: %s: %r", oname);
273 7763a61a 2003-11-23 devnull } else
274 7763a61a 2003-11-23 devnull fd = 1;
275 7763a61a 2003-11-23 devnull
276 7763a61a 2003-11-23 devnull dir = dirfstat(fd);
277 7763a61a 2003-11-23 devnull if(dir == nil)
278 7763a61a 2003-11-23 devnull sysfatal("dirfstat failed: %r");
279 3d77c87e 2004-03-15 devnull if(oname)
280 3d77c87e 2004-03-15 devnull dir->name = lastelem(oname);
281 3d77c87e 2004-03-15 devnull else
282 3d77c87e 2004-03-15 devnull dir->name = "stdin";
283 7763a61a 2003-11-23 devnull
284 7763a61a 2003-11-23 devnull for(; *argv; argv++) {
285 7763a61a 2003-11-23 devnull cp2 = *argv;
286 7763a61a 2003-11-23 devnull cd = 0;
287 7763a61a 2003-11-23 devnull for (cp = *argv; *cp; cp++)
288 7763a61a 2003-11-23 devnull if (*cp == '/')
289 7763a61a 2003-11-23 devnull cp2 = cp;
290 7763a61a 2003-11-23 devnull if (cp2 != *argv) {
291 7763a61a 2003-11-23 devnull *cp2 = '\0';
292 7763a61a 2003-11-23 devnull chdir(*argv);
293 7763a61a 2003-11-23 devnull *cp2 = '/';
294 7763a61a 2003-11-23 devnull cp2++;
295 7763a61a 2003-11-23 devnull cd = 1;
296 7763a61a 2003-11-23 devnull }
297 7763a61a 2003-11-23 devnull vff = nil;
298 7763a61a 2003-11-23 devnull if(fs)
299 3d77c87e 2004-03-15 devnull vff = vacfileopen(fs, cp2);
300 3d77c87e 2004-03-15 devnull vacfile(dsink, argv[0], cp2, vff);
301 7763a61a 2003-11-23 devnull if(vff)
302 3d77c87e 2004-03-15 devnull vacfiledecref(vff);
303 7763a61a 2003-11-23 devnull if(cd && chdir(cwd) < 0)
304 7763a61a 2003-11-23 devnull sysfatal("can't cd back to %s: %r\n", cwd);
305 7763a61a 2003-11-23 devnull }
306 7763a61a 2003-11-23 devnull
307 7763a61a 2003-11-23 devnull if(isi) {
308 7763a61a 2003-11-23 devnull vff = nil;
309 7763a61a 2003-11-23 devnull if(fs)
310 3d77c87e 2004-03-15 devnull vff = vacfileopen(fs, isi);
311 3d77c87e 2004-03-15 devnull vacstdin(dsink, isi, vff);
312 7763a61a 2003-11-23 devnull if(vff)
313 3d77c87e 2004-03-15 devnull vacfiledecref(vff);
314 7763a61a 2003-11-23 devnull }
315 7763a61a 2003-11-23 devnull
316 3d77c87e 2004-03-15 devnull dirsinkclose(dsink);
317 7763a61a 2003-11-23 devnull
318 7763a61a 2003-11-23 devnull /* build meta information for the root */
319 3d77c87e 2004-03-15 devnull ms = metasinkalloc(z, bsize, bsize);
320 7763a61a 2003-11-23 devnull /* fake into a directory */
321 23fb2edb 2005-07-24 devnull dir->mode = DMDIR|0555;
322 7763a61a 2003-11-23 devnull dir->qid.type |= QTDIR;
323 3d77c87e 2004-03-15 devnull plan9tovacdir(&vd, dir, 0, fileid++);
324 7763a61a 2003-11-23 devnull if(strcmp(vd.elem, "/") == 0){
325 3d77c87e 2004-03-15 devnull vtfree(vd.elem);
326 3d77c87e 2004-03-15 devnull vd.elem = vtstrdup("root");
327 7763a61a 2003-11-23 devnull }
328 3d77c87e 2004-03-15 devnull metasinkwritedir(ms, &vd);
329 3d77c87e 2004-03-15 devnull vdcleanup(&vd);
330 3d77c87e 2004-03-15 devnull metasinkclose(ms);
331 7763a61a 2003-11-23 devnull
332 3d77c87e 2004-03-15 devnull ds = dirsinkalloc(z, bsize, bsize);
333 3d77c87e 2004-03-15 devnull dirsinkwritesink(ds, dsink->sink);
334 3d77c87e 2004-03-15 devnull dirsinkwritesink(ds, dsink->msink->sink);
335 3d77c87e 2004-03-15 devnull dirsinkwritesink(ds, ms->sink);
336 3d77c87e 2004-03-15 devnull dirsinkclose(ds);
337 7763a61a 2003-11-23 devnull
338 7763a61a 2003-11-23 devnull memset(&root, 0, sizeof(root));
339 7763a61a 2003-11-23 devnull strncpy(root.name, dir->name, sizeof(root.name));
340 7763a61a 2003-11-23 devnull root.name[sizeof(root.name)-1] = 0;
341 7763a61a 2003-11-23 devnull free(dir);
342 7763a61a 2003-11-23 devnull sprint(root.type, "vac");
343 7763a61a 2003-11-23 devnull memmove(root.score, ds->sink->dir.score, VtScoreSize);
344 3d77c87e 2004-03-15 devnull root.blocksize = maxbsize;
345 7763a61a 2003-11-23 devnull if(fs != nil)
346 3d77c87e 2004-03-15 devnull vacfsgetscore(fs, root.prev);
347 7763a61a 2003-11-23 devnull
348 3d77c87e 2004-03-15 devnull metasinkfree(ms);
349 3d77c87e 2004-03-15 devnull dirsinkfree(ds);
350 3d77c87e 2004-03-15 devnull dirsinkfree(dsink);
351 7763a61a 2003-11-23 devnull if(fs != nil)
352 3d77c87e 2004-03-15 devnull vacfsclose(fs);
353 7763a61a 2003-11-23 devnull
354 3d77c87e 2004-03-15 devnull vtrootpack(&root, buf);
355 3d77c87e 2004-03-15 devnull if(vacwrite(z, score, VtRootType, buf, VtRootSize) < 0)
356 3d77c87e 2004-03-15 devnull sysfatal("vacWrite failed: %r");
357 7763a61a 2003-11-23 devnull
358 3d77c87e 2004-03-15 devnull fprint(fd, "vac:%V\n", score);
359 3d77c87e 2004-03-15 devnull
360 7763a61a 2003-11-23 devnull /* avoid remove at cleanup */
361 7763a61a 2003-11-23 devnull oname = nil;
362 7763a61a 2003-11-23 devnull }
363 7763a61a 2003-11-23 devnull
364 7763a61a 2003-11-23 devnull static int
365 3d77c87e 2004-03-15 devnull isexcluded(char *name)
366 7763a61a 2003-11-23 devnull {
367 7763a61a 2003-11-23 devnull int bot, top, i, x;
368 7763a61a 2003-11-23 devnull
369 7763a61a 2003-11-23 devnull bot = 0;
370 7763a61a 2003-11-23 devnull top = nexclude;
371 7763a61a 2003-11-23 devnull while(bot < top) {
372 7763a61a 2003-11-23 devnull i = (bot+top)>>1;
373 7763a61a 2003-11-23 devnull x = strcmp(exclude[i], name);
374 7763a61a 2003-11-23 devnull if(x == 0)
375 7763a61a 2003-11-23 devnull return 1;
376 7763a61a 2003-11-23 devnull if(x < 0)
377 7763a61a 2003-11-23 devnull bot = i + 1;
378 7763a61a 2003-11-23 devnull else /* x > 0 */
379 7763a61a 2003-11-23 devnull top = i;
380 7763a61a 2003-11-23 devnull }
381 7763a61a 2003-11-23 devnull return 0;
382 7763a61a 2003-11-23 devnull }
383 7763a61a 2003-11-23 devnull
384 7763a61a 2003-11-23 devnull static void
385 3d77c87e 2004-03-15 devnull vacfile(DirSink *dsink, char *lname, char *sname, VacFile *vf)
386 7763a61a 2003-11-23 devnull {
387 7763a61a 2003-11-23 devnull int fd;
388 7763a61a 2003-11-23 devnull Dir *dir;
389 7763a61a 2003-11-23 devnull VacDir vd;
390 7763a61a 2003-11-23 devnull ulong entry;
391 7763a61a 2003-11-23 devnull
392 3d77c87e 2004-03-15 devnull if(isexcluded(lname)) {
393 7763a61a 2003-11-23 devnull warn("excluding: %s", lname);
394 7763a61a 2003-11-23 devnull return;
395 7763a61a 2003-11-23 devnull }
396 7763a61a 2003-11-23 devnull
397 3d77c87e 2004-03-15 devnull if(merge && vacmerge(dsink, lname, sname) >= 0)
398 7763a61a 2003-11-23 devnull return;
399 7763a61a 2003-11-23 devnull
400 5fc55a95 2005-02-08 devnull if((dir = dirstat(sname)) == nil){
401 5fc55a95 2005-02-08 devnull warn("could not stat file %s: %r", lname);
402 6c0209f6 2005-02-11 devnull return;
403 6c0209f6 2005-02-11 devnull }
404 71f05672 2005-09-13 devnull if(dir->mode&(DMSYMLINK|DMDEVICE|DMNAMEDPIPE)){
405 71f05672 2005-09-13 devnull vacspecial(dsink, dir, lname, sname, vf);
406 5fc55a95 2005-02-08 devnull free(dir);
407 2277c5d7 2004-03-21 devnull return;
408 71f05672 2005-09-13 devnull }else if(dir->mode&DMSOCKET){
409 71f05672 2005-09-13 devnull free(dir);
410 71f05672 2005-09-13 devnull return;
411 5fc55a95 2005-02-08 devnull }
412 5fc55a95 2005-02-08 devnull free(dir);
413 5fc55a95 2005-02-08 devnull
414 7763a61a 2003-11-23 devnull fd = open(sname, OREAD);
415 7763a61a 2003-11-23 devnull if(fd < 0) {
416 3d77c87e 2004-03-15 devnull warn("could not open file: %s: %r", lname);
417 7763a61a 2003-11-23 devnull return;
418 7763a61a 2003-11-23 devnull }
419 7763a61a 2003-11-23 devnull
420 7763a61a 2003-11-23 devnull if(verbose)
421 7763a61a 2003-11-23 devnull fprint(2, "%s\n", lname);
422 7763a61a 2003-11-23 devnull
423 7763a61a 2003-11-23 devnull dir = dirfstat(fd);
424 7763a61a 2003-11-23 devnull if(dir == nil) {
425 7763a61a 2003-11-23 devnull warn("can't stat %s: %r", lname);
426 7763a61a 2003-11-23 devnull close(fd);
427 7763a61a 2003-11-23 devnull return;
428 7763a61a 2003-11-23 devnull }
429 3d77c87e 2004-03-15 devnull dir->name = lastelem(sname);
430 7763a61a 2003-11-23 devnull
431 7763a61a 2003-11-23 devnull entry = dsink->nentry;
432 7763a61a 2003-11-23 devnull
433 7763a61a 2003-11-23 devnull if(dir->mode & DMDIR)
434 3d77c87e 2004-03-15 devnull vacdir(dsink, fd, lname, sname, vf);
435 7763a61a 2003-11-23 devnull else
436 3d77c87e 2004-03-15 devnull vacdata(dsink, fd, lname, vf, dir);
437 7763a61a 2003-11-23 devnull
438 3d77c87e 2004-03-15 devnull plan9tovacdir(&vd, dir, entry, fileid++);
439 3d77c87e 2004-03-15 devnull metasinkwritedir(dsink->msink, &vd);
440 3d77c87e 2004-03-15 devnull vdcleanup(&vd);
441 7763a61a 2003-11-23 devnull
442 7763a61a 2003-11-23 devnull free(dir);
443 7763a61a 2003-11-23 devnull close(fd);
444 7763a61a 2003-11-23 devnull }
445 7763a61a 2003-11-23 devnull
446 7763a61a 2003-11-23 devnull static void
447 3d77c87e 2004-03-15 devnull vacstdin(DirSink *dsink, char *name, VacFile *vf)
448 7763a61a 2003-11-23 devnull {
449 7763a61a 2003-11-23 devnull Dir *dir;
450 7763a61a 2003-11-23 devnull VacDir vd;
451 7763a61a 2003-11-23 devnull ulong entry;
452 7763a61a 2003-11-23 devnull
453 7763a61a 2003-11-23 devnull if(verbose)
454 7763a61a 2003-11-23 devnull fprint(2, "%s\n", "<stdio>");
455 7763a61a 2003-11-23 devnull
456 7763a61a 2003-11-23 devnull dir = dirfstat(0);
457 7763a61a 2003-11-23 devnull if(dir == nil) {
458 7763a61a 2003-11-23 devnull warn("can't stat <stdio>: %r");
459 7763a61a 2003-11-23 devnull return;
460 7763a61a 2003-11-23 devnull }
461 3d77c87e 2004-03-15 devnull dir->name = "stdin";
462 7763a61a 2003-11-23 devnull
463 7763a61a 2003-11-23 devnull entry = dsink->nentry;
464 7763a61a 2003-11-23 devnull
465 3d77c87e 2004-03-15 devnull vacdata(dsink, 0, "<stdin>", vf, dir);
466 7763a61a 2003-11-23 devnull
467 3d77c87e 2004-03-15 devnull plan9tovacdir(&vd, dir, entry, fileid++);
468 3d77c87e 2004-03-15 devnull vd.elem = vtstrdup(name);
469 3d77c87e 2004-03-15 devnull metasinkwritedir(dsink->msink, &vd);
470 3d77c87e 2004-03-15 devnull vdcleanup(&vd);
471 7763a61a 2003-11-23 devnull
472 7763a61a 2003-11-23 devnull free(dir);
473 7763a61a 2003-11-23 devnull }
474 7763a61a 2003-11-23 devnull
475 3d77c87e 2004-03-15 devnull static int
476 3d77c87e 2004-03-15 devnull sha1check(u8int *score, uchar *buf, int n)
477 3d77c87e 2004-03-15 devnull {
478 edefa249 2005-03-15 devnull uchar score2[VtScoreSize];
479 3d77c87e 2004-03-15 devnull
480 3e1960ce 2005-02-18 devnull sha1(buf, n, score2, nil);
481 3d77c87e 2004-03-15 devnull if(memcmp(score, score2, VtScoreSize) == 0)
482 3d77c87e 2004-03-15 devnull return 0;
483 3d77c87e 2004-03-15 devnull return -1;
484 3d77c87e 2004-03-15 devnull }
485 3d77c87e 2004-03-15 devnull
486 7763a61a 2003-11-23 devnull static ulong
487 3d77c87e 2004-03-15 devnull vacdataskip(Sink *sink, VacFile *vf, int fd, ulong blocks, uchar *buf, char *lname)
488 7763a61a 2003-11-23 devnull {
489 7763a61a 2003-11-23 devnull int n;
490 7763a61a 2003-11-23 devnull ulong i;
491 7763a61a 2003-11-23 devnull uchar score[VtScoreSize];
492 7763a61a 2003-11-23 devnull
493 7763a61a 2003-11-23 devnull /* skip blocks for append only files */
494 7763a61a 2003-11-23 devnull if(seek(fd, (blocks-1)*bsize, 0) != (blocks-1)*bsize) {
495 7763a61a 2003-11-23 devnull warn("error seeking: %s", lname);
496 7763a61a 2003-11-23 devnull goto Err;
497 7763a61a 2003-11-23 devnull }
498 3d77c87e 2004-03-15 devnull n = readn(fd, buf, bsize);
499 7763a61a 2003-11-23 devnull if(n < bsize) {
500 7763a61a 2003-11-23 devnull warn("error checking append only file: %s", lname);
501 7763a61a 2003-11-23 devnull goto Err;
502 7763a61a 2003-11-23 devnull }
503 3d77c87e 2004-03-15 devnull if(vacfileblockscore(vf, blocks-1, score)<0 || sha1check(score, buf, n)<0) {
504 7763a61a 2003-11-23 devnull warn("last block of append file did not match: %s", lname);
505 7763a61a 2003-11-23 devnull goto Err;
506 7763a61a 2003-11-23 devnull }
507 7763a61a 2003-11-23 devnull
508 7763a61a 2003-11-23 devnull for(i=0; i<blocks; i++) {
509 3d77c87e 2004-03-15 devnull if(vacfileblockscore(vf, i, score) < 0) {
510 7763a61a 2003-11-23 devnull warn("could not get score: %s: %lud", lname, i);
511 7763a61a 2003-11-23 devnull seek(fd, i*bsize, 0);
512 7763a61a 2003-11-23 devnull return i;
513 7763a61a 2003-11-23 devnull }
514 7763a61a 2003-11-23 devnull stats.skip++;
515 3d77c87e 2004-03-15 devnull sinkwritescore(sink, score, bsize);
516 7763a61a 2003-11-23 devnull }
517 7763a61a 2003-11-23 devnull
518 7763a61a 2003-11-23 devnull return i;
519 7763a61a 2003-11-23 devnull Err:
520 7763a61a 2003-11-23 devnull seek(fd, 0, 0);
521 7763a61a 2003-11-23 devnull return 0;
522 7763a61a 2003-11-23 devnull }
523 7763a61a 2003-11-23 devnull
524 7763a61a 2003-11-23 devnull static void
525 3d77c87e 2004-03-15 devnull vacdata(DirSink *dsink, int fd, char *lname, VacFile *vf, Dir *dir)
526 7763a61a 2003-11-23 devnull {
527 7763a61a 2003-11-23 devnull uchar *buf;
528 7763a61a 2003-11-23 devnull Sink *sink;
529 7763a61a 2003-11-23 devnull int n;
530 7763a61a 2003-11-23 devnull uchar score[VtScoreSize];
531 7763a61a 2003-11-23 devnull ulong block, same;
532 7763a61a 2003-11-23 devnull VacDir vd;
533 7763a61a 2003-11-23 devnull ulong vfblocks;
534 7763a61a 2003-11-23 devnull
535 7763a61a 2003-11-23 devnull vfblocks = 0;
536 7763a61a 2003-11-23 devnull if(vf != nil && qdiff) {
537 3d77c87e 2004-03-15 devnull vacfilegetdir(vf, &vd);
538 7763a61a 2003-11-23 devnull if(vd.mtime == dir->mtime)
539 7763a61a 2003-11-23 devnull if(vd.size == dir->length)
540 7763a61a 2003-11-23 devnull if(!vd.plan9 || /* vd.p9path == dir->qid.path && */ vd.p9version == dir->qid.vers)
541 3d77c87e 2004-03-15 devnull if(dirsinkwritefile(dsink, vf)) {
542 7763a61a 2003-11-23 devnull stats.sfile++;
543 3d77c87e 2004-03-15 devnull vdcleanup(&vd);
544 7763a61a 2003-11-23 devnull return;
545 7763a61a 2003-11-23 devnull }
546 7763a61a 2003-11-23 devnull
547 7763a61a 2003-11-23 devnull /* look for an append only file */
548 7763a61a 2003-11-23 devnull if((dir->mode&DMAPPEND) != 0)
549 7763a61a 2003-11-23 devnull if(vd.size < dir->length)
550 7763a61a 2003-11-23 devnull if(vd.plan9)
551 7763a61a 2003-11-23 devnull if(vd.p9path == dir->qid.path)
552 7763a61a 2003-11-23 devnull vfblocks = vd.size/bsize;
553 7763a61a 2003-11-23 devnull
554 3d77c87e 2004-03-15 devnull vdcleanup(&vd);
555 7763a61a 2003-11-23 devnull }
556 7763a61a 2003-11-23 devnull stats.file++;
557 7763a61a 2003-11-23 devnull
558 3d77c87e 2004-03-15 devnull buf = vtmalloc(bsize);
559 3d77c87e 2004-03-15 devnull sink = sinkalloc(dsink->sink->z, bsize, bsize);
560 7763a61a 2003-11-23 devnull block = 0;
561 7763a61a 2003-11-23 devnull same = stats.sdata+stats.skip;
562 7763a61a 2003-11-23 devnull
563 7763a61a 2003-11-23 devnull if(vfblocks > 1)
564 3d77c87e 2004-03-15 devnull block += vacdataskip(sink, vf, fd, vfblocks, buf, lname);
565 7763a61a 2003-11-23 devnull
566 7763a61a 2003-11-23 devnull if(0) fprint(2, "vacData: %s: %ld\n", lname, block);
567 7763a61a 2003-11-23 devnull for(;;) {
568 3d77c87e 2004-03-15 devnull n = readn(fd, buf, bsize);
569 7763a61a 2003-11-23 devnull if(0 && n < 0)
570 3d77c87e 2004-03-15 devnull warn("file truncated due to read error: %s: %r", lname);
571 7763a61a 2003-11-23 devnull if(n <= 0)
572 7763a61a 2003-11-23 devnull break;
573 3e1960ce 2005-02-18 devnull if(vf != nil && vacfileblockscore(vf, block, score)>=0 && sha1check(score, buf, n)>=0) {
574 7763a61a 2003-11-23 devnull stats.sdata++;
575 3d77c87e 2004-03-15 devnull sinkwritescore(sink, score, n);
576 7763a61a 2003-11-23 devnull } else
577 3d77c87e 2004-03-15 devnull sinkwrite(sink, buf, n);
578 7763a61a 2003-11-23 devnull block++;
579 7763a61a 2003-11-23 devnull }
580 7763a61a 2003-11-23 devnull same = stats.sdata+stats.skip - same;
581 7763a61a 2003-11-23 devnull
582 7763a61a 2003-11-23 devnull if(same && (dir->mode&DMAPPEND) != 0)
583 7763a61a 2003-11-23 devnull if(0)fprint(2, "%s: total %lud same %lud:%lud diff %lud\n",
584 7763a61a 2003-11-23 devnull lname, block, same, vfblocks, block-same);
585 7763a61a 2003-11-23 devnull
586 3d77c87e 2004-03-15 devnull sinkclose(sink);
587 3d77c87e 2004-03-15 devnull dirsinkwritesink(dsink, sink);
588 3d77c87e 2004-03-15 devnull sinkfree(sink);
589 7763a61a 2003-11-23 devnull free(buf);
590 7763a61a 2003-11-23 devnull }
591 7763a61a 2003-11-23 devnull
592 7763a61a 2003-11-23 devnull
593 7763a61a 2003-11-23 devnull static void
594 3d77c87e 2004-03-15 devnull vacdir(DirSink *dsink, int fd, char *lname, char *sname, VacFile *vf)
595 7763a61a 2003-11-23 devnull {
596 7763a61a 2003-11-23 devnull Dir *dirs;
597 7763a61a 2003-11-23 devnull char *ln, *sn;
598 7763a61a 2003-11-23 devnull int i, nd;
599 7763a61a 2003-11-23 devnull DirSink *ds;
600 7763a61a 2003-11-23 devnull VacFile *vvf;
601 7763a61a 2003-11-23 devnull char *name;
602 7763a61a 2003-11-23 devnull
603 3d77c87e 2004-03-15 devnull ds = dirsinkalloc(dsink->sink->z, bsize, bsize);
604 7763a61a 2003-11-23 devnull while((nd = dirread(fd, &dirs)) > 0){
605 7763a61a 2003-11-23 devnull for(i = 0; i < nd; i++){
606 7763a61a 2003-11-23 devnull name = dirs[i].name;
607 7763a61a 2003-11-23 devnull /* check for bad file names */
608 7763a61a 2003-11-23 devnull if(name[0] == 0 || strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
609 7763a61a 2003-11-23 devnull continue;
610 3d77c87e 2004-03-15 devnull ln = vtmalloc(strlen(lname) + strlen(name) + 2);
611 3d77c87e 2004-03-15 devnull sn = vtmalloc(strlen(sname) + strlen(name) + 2);
612 73abc627 2005-12-29 devnull strcpy(ln, lname);
613 73abc627 2005-12-29 devnull strcat(ln, "/");
614 73abc627 2005-12-29 devnull strcat(ln, name);
615 73abc627 2005-12-29 devnull strcpy(sn, sname);
616 73abc627 2005-12-29 devnull strcat(sn, "/");
617 73abc627 2005-12-29 devnull strcat(sn, name);
618 7763a61a 2003-11-23 devnull if(vf != nil)
619 3d77c87e 2004-03-15 devnull vvf = vacfilewalk(vf, name);
620 7763a61a 2003-11-23 devnull else
621 7763a61a 2003-11-23 devnull vvf = nil;
622 3d77c87e 2004-03-15 devnull vacfile(ds, ln, sn, vvf);
623 7763a61a 2003-11-23 devnull if(vvf != nil)
624 3d77c87e 2004-03-15 devnull vacfiledecref(vvf);
625 3d77c87e 2004-03-15 devnull vtfree(ln);
626 3d77c87e 2004-03-15 devnull vtfree(sn);
627 7763a61a 2003-11-23 devnull }
628 7763a61a 2003-11-23 devnull free(dirs);
629 7763a61a 2003-11-23 devnull }
630 3d77c87e 2004-03-15 devnull dirsinkclose(ds);
631 3d77c87e 2004-03-15 devnull dirsinkwritesink(dsink, ds->sink);
632 3d77c87e 2004-03-15 devnull dirsinkwritesink(dsink, ds->msink->sink);
633 3d77c87e 2004-03-15 devnull dirsinkfree(ds);
634 7763a61a 2003-11-23 devnull }
635 7763a61a 2003-11-23 devnull
636 7763a61a 2003-11-23 devnull static int
637 3d77c87e 2004-03-15 devnull vacmergefile(DirSink *dsink, VacFile *vf, VacDir *dir, uvlong offset, uvlong *max)
638 7763a61a 2003-11-23 devnull {
639 7763a61a 2003-11-23 devnull uchar buf[VtEntrySize];
640 7763a61a 2003-11-23 devnull VtEntry dd, md;
641 7763a61a 2003-11-23 devnull int e;
642 7763a61a 2003-11-23 devnull
643 3d77c87e 2004-03-15 devnull if(vacfileread(vf, buf, VtEntrySize, (uvlong)dir->entry*VtEntrySize) != VtEntrySize) {
644 7763a61a 2003-11-23 devnull warn("could not read venti dir entry: %s\n", dir->elem);
645 3d77c87e 2004-03-15 devnull return -1;
646 7763a61a 2003-11-23 devnull }
647 3d77c87e 2004-03-15 devnull vtentryunpack(&dd, buf, 0);
648 7763a61a 2003-11-23 devnull
649 7763a61a 2003-11-23 devnull if(dir->mode & ModeDir) {
650 7763a61a 2003-11-23 devnull e = dir->mentry;
651 7763a61a 2003-11-23 devnull if(e == 0)
652 7763a61a 2003-11-23 devnull e = dir->entry + 1;
653 7763a61a 2003-11-23 devnull
654 3d77c87e 2004-03-15 devnull if(vacfileread(vf, buf, VtEntrySize, e*VtEntrySize) != VtEntrySize) {
655 7763a61a 2003-11-23 devnull warn("could not read venti dir entry: %s\n", dir->elem);
656 7763a61a 2003-11-23 devnull return 0;
657 7763a61a 2003-11-23 devnull }
658 3d77c87e 2004-03-15 devnull vtentryunpack(&md, buf, 0);
659 7763a61a 2003-11-23 devnull }
660 7763a61a 2003-11-23 devnull
661 7763a61a 2003-11-23 devnull /* max might incorrect in some old dumps */
662 7763a61a 2003-11-23 devnull if(dir->qid >= *max) {
663 7763a61a 2003-11-23 devnull warn("qid out of range: %s", dir->elem);
664 7763a61a 2003-11-23 devnull *max = dir->qid;
665 7763a61a 2003-11-23 devnull }
666 7763a61a 2003-11-23 devnull
667 7763a61a 2003-11-23 devnull dir->qid += offset;
668 7763a61a 2003-11-23 devnull dir->entry = dsink->nentry;
669 7763a61a 2003-11-23 devnull
670 3d77c87e 2004-03-15 devnull if(dir->qidspace) {
671 3d77c87e 2004-03-15 devnull dir->qidoffset += offset;
672 7763a61a 2003-11-23 devnull } else {
673 3d77c87e 2004-03-15 devnull dir->qidspace = 1;
674 3d77c87e 2004-03-15 devnull dir->qidoffset = offset;
675 3d77c87e 2004-03-15 devnull dir->qidmax = *max;
676 7763a61a 2003-11-23 devnull }
677 7763a61a 2003-11-23 devnull
678 3d77c87e 2004-03-15 devnull dirsinkwrite(dsink, &dd);
679 7763a61a 2003-11-23 devnull if(dir->mode & ModeDir)
680 3d77c87e 2004-03-15 devnull dirsinkwrite(dsink, &md);
681 3d77c87e 2004-03-15 devnull metasinkwritedir(dsink->msink, dir);
682 7763a61a 2003-11-23 devnull
683 3d77c87e 2004-03-15 devnull return 0;
684 7763a61a 2003-11-23 devnull }
685 7763a61a 2003-11-23 devnull
686 7763a61a 2003-11-23 devnull static int
687 3d77c87e 2004-03-15 devnull vacmerge(DirSink *dsink, char *lname, char *sname)
688 7763a61a 2003-11-23 devnull {
689 7763a61a 2003-11-23 devnull char *p;
690 3d77c87e 2004-03-15 devnull VacFs *fs;
691 7763a61a 2003-11-23 devnull VacFile *vf;
692 7763a61a 2003-11-23 devnull VacDirEnum *d;
693 7763a61a 2003-11-23 devnull VacDir dir;
694 7763a61a 2003-11-23 devnull uvlong max;
695 7763a61a 2003-11-23 devnull
696 5db61d62 2005-02-21 devnull if((p=strrchr(sname, '.')) == nil || strcmp(p, ".vac") != 0)
697 d24aad8f 2005-02-20 devnull return -1;
698 7763a61a 2003-11-23 devnull
699 7763a61a 2003-11-23 devnull d = nil;
700 3d77c87e 2004-03-15 devnull fs = vacfsopen(dsink->sink->z, sname, VtOREAD, 100);
701 7763a61a 2003-11-23 devnull if(fs == nil)
702 3d77c87e 2004-03-15 devnull return -1;
703 7763a61a 2003-11-23 devnull
704 3d77c87e 2004-03-15 devnull vf = vacfileopen(fs, "/");
705 7763a61a 2003-11-23 devnull if(vf == nil)
706 7763a61a 2003-11-23 devnull goto Done;
707 3d77c87e 2004-03-15 devnull max = vacfilegetid(vf);
708 3d77c87e 2004-03-15 devnull d = vdeopen(vf);
709 7763a61a 2003-11-23 devnull if(d == nil)
710 7763a61a 2003-11-23 devnull goto Done;
711 7763a61a 2003-11-23 devnull
712 7763a61a 2003-11-23 devnull if(verbose)
713 7763a61a 2003-11-23 devnull fprint(2, "merging: %s\n", lname);
714 7763a61a 2003-11-23 devnull
715 3d77c87e 2004-03-15 devnull if(maxbsize < fs->bsize)
716 3d77c87e 2004-03-15 devnull maxbsize = fs->bsize;
717 7763a61a 2003-11-23 devnull
718 7763a61a 2003-11-23 devnull for(;;) {
719 3d77c87e 2004-03-15 devnull if(vderead(d, &dir) < 1)
720 7763a61a 2003-11-23 devnull break;
721 3d77c87e 2004-03-15 devnull vacmergefile(dsink, vf, &dir, fileid, &max);
722 3d77c87e 2004-03-15 devnull vdcleanup(&dir);
723 7763a61a 2003-11-23 devnull }
724 7763a61a 2003-11-23 devnull fileid += max;
725 7763a61a 2003-11-23 devnull
726 7763a61a 2003-11-23 devnull Done:
727 7763a61a 2003-11-23 devnull if(d != nil)
728 3d77c87e 2004-03-15 devnull vdeclose(d);
729 7763a61a 2003-11-23 devnull if(vf != nil)
730 3d77c87e 2004-03-15 devnull vacfiledecref(vf);
731 3d77c87e 2004-03-15 devnull vacfsclose(fs);
732 3d77c87e 2004-03-15 devnull return 0;
733 7763a61a 2003-11-23 devnull }
734 71f05672 2005-09-13 devnull
735 71f05672 2005-09-13 devnull static int
736 71f05672 2005-09-13 devnull vacspecial(DirSink *dsink, Dir* dir, char *lname, char *sname, VacFile *vf)
737 71f05672 2005-09-13 devnull {
738 71f05672 2005-09-13 devnull char *btmp, *buf;
739 71f05672 2005-09-13 devnull int buflen, dtype, major, minor, n;
740 71f05672 2005-09-13 devnull ulong entry;
741 71f05672 2005-09-13 devnull Sink *sink;
742 71f05672 2005-09-13 devnull VacDir vd;
743 7763a61a 2003-11-23 devnull
744 71f05672 2005-09-13 devnull n = 0;
745 71f05672 2005-09-13 devnull buflen = 128;
746 71f05672 2005-09-13 devnull buf = malloc(buflen);
747 71f05672 2005-09-13 devnull if(buf == nil)
748 71f05672 2005-09-13 devnull return -1;
749 71f05672 2005-09-13 devnull
750 71f05672 2005-09-13 devnull if(verbose)
751 71f05672 2005-09-13 devnull fprint(2, "%s\n", lname);
752 71f05672 2005-09-13 devnull
753 71f05672 2005-09-13 devnull dir->name = lastelem(sname);
754 71f05672 2005-09-13 devnull
755 71f05672 2005-09-13 devnull if(dir->mode & DMSYMLINK){
756 71f05672 2005-09-13 devnull while((n = readlink(sname, buf, buflen)) == buflen){
757 71f05672 2005-09-13 devnull buflen *= 2;
758 71f05672 2005-09-13 devnull btmp = vtrealloc(buf, buflen);
759 71f05672 2005-09-13 devnull if(btmp == nil){
760 71f05672 2005-09-13 devnull free(buf);
761 71f05672 2005-09-13 devnull return -1;
762 71f05672 2005-09-13 devnull }
763 71f05672 2005-09-13 devnull buf = btmp;
764 71f05672 2005-09-13 devnull }
765 71f05672 2005-09-13 devnull dir->mode &= ~DMDIR;
766 71f05672 2005-09-13 devnull dir->mode |= DMSYMLINK;
767 71f05672 2005-09-13 devnull }else if(dir->mode & DMDEVICE){
768 71f05672 2005-09-13 devnull dtype = (dir->qid.path >> 16) & 0xFF;
769 71f05672 2005-09-13 devnull minor = dir->qid.path & 0xff;
770 71f05672 2005-09-13 devnull major = (dir->qid.path >> 8) & 0xFF;
771 71f05672 2005-09-13 devnull n = snprint(buf, buflen, "%c %d %d", dtype, major, minor);
772 71f05672 2005-09-13 devnull }
773 71f05672 2005-09-13 devnull
774 71f05672 2005-09-13 devnull entry = dsink->nentry;
775 71f05672 2005-09-13 devnull
776 71f05672 2005-09-13 devnull sink = sinkalloc(dsink->sink->z, bsize, bsize);
777 23e7c657 2005-09-13 devnull sinkwrite(sink, (uchar*)buf, n);
778 71f05672 2005-09-13 devnull sinkclose(sink);
779 71f05672 2005-09-13 devnull dirsinkwritesink(dsink, sink);
780 71f05672 2005-09-13 devnull sinkfree(sink);
781 71f05672 2005-09-13 devnull free(buf);
782 71f05672 2005-09-13 devnull
783 71f05672 2005-09-13 devnull dir->name = lastelem(sname);
784 71f05672 2005-09-13 devnull dir->length = n;
785 71f05672 2005-09-13 devnull plan9tovacdir(&vd, dir, entry, fileid++);
786 71f05672 2005-09-13 devnull metasinkwritedir(dsink->msink, &vd);
787 71f05672 2005-09-13 devnull vdcleanup(&vd);
788 71f05672 2005-09-13 devnull
789 71f05672 2005-09-13 devnull return 0;
790 71f05672 2005-09-13 devnull }
791 71f05672 2005-09-13 devnull
792 71f05672 2005-09-13 devnull
793 7763a61a 2003-11-23 devnull Sink *
794 3d77c87e 2004-03-15 devnull sinkalloc(VtConn *z, int psize, int dsize)
795 7763a61a 2003-11-23 devnull {
796 7763a61a 2003-11-23 devnull Sink *k;
797 7763a61a 2003-11-23 devnull int i;
798 7763a61a 2003-11-23 devnull
799 7763a61a 2003-11-23 devnull if(psize < 512 || psize > VtMaxLumpSize)
800 3d77c87e 2004-03-15 devnull sysfatal("sinkalloc: bad psize");
801 7763a61a 2003-11-23 devnull if(dsize < 512 || dsize > VtMaxLumpSize)
802 3d77c87e 2004-03-15 devnull sysfatal("sinkalloc: bad psize");
803 7763a61a 2003-11-23 devnull
804 7763a61a 2003-11-23 devnull psize = VtScoreSize*(psize/VtScoreSize);
805 7763a61a 2003-11-23 devnull
806 3d77c87e 2004-03-15 devnull k = vtmallocz(sizeof(Sink));
807 7763a61a 2003-11-23 devnull k->z = z;
808 7763a61a 2003-11-23 devnull k->dir.flags = VtEntryActive;
809 7763a61a 2003-11-23 devnull k->dir.psize = psize;
810 7763a61a 2003-11-23 devnull k->dir.dsize = dsize;
811 3d77c87e 2004-03-15 devnull k->buf = vtmallocz(VtPointerDepth*k->dir.psize + VtScoreSize);
812 7763a61a 2003-11-23 devnull for(i=0; i<=VtPointerDepth; i++)
813 7763a61a 2003-11-23 devnull k->pbuf[i] = k->buf + i*k->dir.psize;
814 7763a61a 2003-11-23 devnull return k;
815 7763a61a 2003-11-23 devnull }
816 7763a61a 2003-11-23 devnull
817 7763a61a 2003-11-23 devnull void
818 3d77c87e 2004-03-15 devnull sinkwritescore(Sink *k, uchar score[VtScoreSize], int n)
819 7763a61a 2003-11-23 devnull {
820 7763a61a 2003-11-23 devnull int i;
821 7763a61a 2003-11-23 devnull uchar *p;
822 7763a61a 2003-11-23 devnull VtEntry *d;
823 7763a61a 2003-11-23 devnull
824 7763a61a 2003-11-23 devnull memmove(k->pbuf[0], score, VtScoreSize);
825 7763a61a 2003-11-23 devnull
826 7763a61a 2003-11-23 devnull d = &k->dir;
827 7763a61a 2003-11-23 devnull
828 7763a61a 2003-11-23 devnull for(i=0; i<VtPointerDepth; i++) {
829 7763a61a 2003-11-23 devnull k->pbuf[i] += VtScoreSize;
830 7763a61a 2003-11-23 devnull if(k->pbuf[i] < k->buf + d->psize*(i+1))
831 7763a61a 2003-11-23 devnull break;
832 7763a61a 2003-11-23 devnull if(i == VtPointerDepth-1)
833 3d77c87e 2004-03-15 devnull sysfatal("file too big");
834 7763a61a 2003-11-23 devnull p = k->buf+i*d->psize;
835 7763a61a 2003-11-23 devnull stats.meta++;
836 3d77c87e 2004-03-15 devnull if(vacwrite(k->z, k->pbuf[i+1], VtDataType+1+i, p, d->psize) < 0)
837 3d77c87e 2004-03-15 devnull sysfatal("vacwrite failed: %r");
838 7763a61a 2003-11-23 devnull k->pbuf[i] = p;
839 7763a61a 2003-11-23 devnull }
840 7763a61a 2003-11-23 devnull
841 7763a61a 2003-11-23 devnull /* round size up to multiple of dsize */
842 7763a61a 2003-11-23 devnull d->size = d->dsize * ((d->size + d->dsize-1)/d->dsize);
843 7763a61a 2003-11-23 devnull
844 7763a61a 2003-11-23 devnull d->size += n;
845 7763a61a 2003-11-23 devnull }
846 7763a61a 2003-11-23 devnull
847 7763a61a 2003-11-23 devnull void
848 3d77c87e 2004-03-15 devnull sinkwrite(Sink *k, uchar *p, int n)
849 7763a61a 2003-11-23 devnull {
850 7763a61a 2003-11-23 devnull int type;
851 7763a61a 2003-11-23 devnull uchar score[VtScoreSize];
852 71f05672 2005-09-13 devnull
853 71f05672 2005-09-13 devnull if(n == 0)
854 71f05672 2005-09-13 devnull return;
855 7763a61a 2003-11-23 devnull
856 7763a61a 2003-11-23 devnull if(n > k->dir.dsize)
857 3d77c87e 2004-03-15 devnull sysfatal("sinkWrite: size too big");
858 7763a61a 2003-11-23 devnull
859 3d77c87e 2004-03-15 devnull if((k->dir.type&~VtTypeDepthMask) == VtDirType){
860 7763a61a 2003-11-23 devnull type = VtDirType;
861 7763a61a 2003-11-23 devnull stats.meta++;
862 7763a61a 2003-11-23 devnull } else {
863 7763a61a 2003-11-23 devnull type = VtDataType;
864 7763a61a 2003-11-23 devnull stats.data++;
865 7763a61a 2003-11-23 devnull }
866 3d77c87e 2004-03-15 devnull if(vacwrite(k->z, score, type, p, n) < 0)
867 3d77c87e 2004-03-15 devnull sysfatal("vacWrite failed: %r");
868 7763a61a 2003-11-23 devnull
869 3d77c87e 2004-03-15 devnull sinkwritescore(k, score, n);
870 7763a61a 2003-11-23 devnull }
871 7763a61a 2003-11-23 devnull
872 7763a61a 2003-11-23 devnull static int
873 3d77c87e 2004-03-15 devnull sizetodepth(uvlong s, int psize, int dsize)
874 7763a61a 2003-11-23 devnull {
875 7763a61a 2003-11-23 devnull int np;
876 7763a61a 2003-11-23 devnull int d;
877 7763a61a 2003-11-23 devnull
878 7763a61a 2003-11-23 devnull /* determine pointer depth */
879 7763a61a 2003-11-23 devnull np = psize/VtScoreSize;
880 7763a61a 2003-11-23 devnull s = (s + dsize - 1)/dsize;
881 7763a61a 2003-11-23 devnull for(d = 0; s > 1; d++)
882 7763a61a 2003-11-23 devnull s = (s + np - 1)/np;
883 7763a61a 2003-11-23 devnull return d;
884 7763a61a 2003-11-23 devnull }
885 7763a61a 2003-11-23 devnull
886 7763a61a 2003-11-23 devnull void
887 3d77c87e 2004-03-15 devnull sinkclose(Sink *k)
888 7763a61a 2003-11-23 devnull {
889 3d77c87e 2004-03-15 devnull int i, n, base;
890 7763a61a 2003-11-23 devnull uchar *p;
891 7763a61a 2003-11-23 devnull VtEntry *kd;
892 7763a61a 2003-11-23 devnull
893 7763a61a 2003-11-23 devnull kd = &k->dir;
894 7763a61a 2003-11-23 devnull
895 7763a61a 2003-11-23 devnull /* empty */
896 7763a61a 2003-11-23 devnull if(kd->size == 0) {
897 3d77c87e 2004-03-15 devnull memmove(kd->score, vtzeroscore, VtScoreSize);
898 7763a61a 2003-11-23 devnull return;
899 7763a61a 2003-11-23 devnull }
900 7763a61a 2003-11-23 devnull
901 7763a61a 2003-11-23 devnull for(n=VtPointerDepth-1; n>0; n--)
902 7763a61a 2003-11-23 devnull if(k->pbuf[n] > k->buf + kd->psize*n)
903 7763a61a 2003-11-23 devnull break;
904 7763a61a 2003-11-23 devnull
905 3d77c87e 2004-03-15 devnull base = kd->type&~VtTypeDepthMask;
906 3d77c87e 2004-03-15 devnull kd->type = base + sizetodepth(kd->size, kd->psize, kd->dsize);
907 7763a61a 2003-11-23 devnull
908 7763a61a 2003-11-23 devnull /* skip full part of tree */
909 7763a61a 2003-11-23 devnull for(i=0; i<n && k->pbuf[i] == k->buf + kd->psize*i; i++)
910 7763a61a 2003-11-23 devnull ;
911 7763a61a 2003-11-23 devnull
912 7763a61a 2003-11-23 devnull /* is the tree completely full */
913 7763a61a 2003-11-23 devnull if(i == n && k->pbuf[n] == k->buf + kd->psize*n + VtScoreSize) {
914 7763a61a 2003-11-23 devnull memmove(kd->score, k->pbuf[n] - VtScoreSize, VtScoreSize);
915 7763a61a 2003-11-23 devnull return;
916 7763a61a 2003-11-23 devnull }
917 7763a61a 2003-11-23 devnull n++;
918 7763a61a 2003-11-23 devnull
919 7763a61a 2003-11-23 devnull /* clean up the edge */
920 7763a61a 2003-11-23 devnull for(; i<n; i++) {
921 7763a61a 2003-11-23 devnull p = k->buf+i*kd->psize;
922 7763a61a 2003-11-23 devnull stats.meta++;
923 3d77c87e 2004-03-15 devnull if(vacwrite(k->z, k->pbuf[i+1], base+1+i, p, k->pbuf[i]-p) < 0)
924 3d77c87e 2004-03-15 devnull sysfatal("vacWrite failed: %r");
925 7763a61a 2003-11-23 devnull k->pbuf[i+1] += VtScoreSize;
926 7763a61a 2003-11-23 devnull }
927 7763a61a 2003-11-23 devnull memmove(kd->score, k->pbuf[i] - VtScoreSize, VtScoreSize);
928 7763a61a 2003-11-23 devnull }
929 7763a61a 2003-11-23 devnull
930 7763a61a 2003-11-23 devnull void
931 3d77c87e 2004-03-15 devnull sinkfree(Sink *k)
932 7763a61a 2003-11-23 devnull {
933 3d77c87e 2004-03-15 devnull vtfree(k->buf);
934 3d77c87e 2004-03-15 devnull vtfree(k);
935 7763a61a 2003-11-23 devnull }
936 7763a61a 2003-11-23 devnull
937 7763a61a 2003-11-23 devnull DirSink *
938 3d77c87e 2004-03-15 devnull dirsinkalloc(VtConn *z, int psize, int dsize)
939 7763a61a 2003-11-23 devnull {
940 7763a61a 2003-11-23 devnull DirSink *k;
941 7763a61a 2003-11-23 devnull int ds;
942 7763a61a 2003-11-23 devnull
943 7763a61a 2003-11-23 devnull ds = VtEntrySize*(dsize/VtEntrySize);
944 7763a61a 2003-11-23 devnull
945 3d77c87e 2004-03-15 devnull k = vtmallocz(sizeof(DirSink));
946 3d77c87e 2004-03-15 devnull k->sink = sinkalloc(z, psize, ds);
947 3d77c87e 2004-03-15 devnull k->sink->dir.type = VtDirType;
948 3d77c87e 2004-03-15 devnull k->msink = metasinkalloc(z, psize, dsize);
949 3d77c87e 2004-03-15 devnull k->buf = vtmalloc(ds);
950 7763a61a 2003-11-23 devnull k->p = k->buf;
951 7763a61a 2003-11-23 devnull k->ep = k->buf + ds;
952 7763a61a 2003-11-23 devnull return k;
953 7763a61a 2003-11-23 devnull }
954 7763a61a 2003-11-23 devnull
955 7763a61a 2003-11-23 devnull void
956 3d77c87e 2004-03-15 devnull dirsinkwrite(DirSink *k, VtEntry *dir)
957 7763a61a 2003-11-23 devnull {
958 7763a61a 2003-11-23 devnull if(k->p + VtEntrySize > k->ep) {
959 3d77c87e 2004-03-15 devnull sinkwrite(k->sink, k->buf, k->p - k->buf);
960 7763a61a 2003-11-23 devnull k->p = k->buf;
961 7763a61a 2003-11-23 devnull }
962 3d77c87e 2004-03-15 devnull vtentrypack(dir, k->p, 0);
963 7763a61a 2003-11-23 devnull k->nentry++;
964 7763a61a 2003-11-23 devnull k->p += VtEntrySize;
965 7763a61a 2003-11-23 devnull }
966 7763a61a 2003-11-23 devnull
967 7763a61a 2003-11-23 devnull void
968 3d77c87e 2004-03-15 devnull dirsinkwritesink(DirSink *k, Sink *sink)
969 7763a61a 2003-11-23 devnull {
970 3d77c87e 2004-03-15 devnull dirsinkwrite(k, &sink->dir);
971 7763a61a 2003-11-23 devnull }
972 7763a61a 2003-11-23 devnull
973 7763a61a 2003-11-23 devnull int
974 3d77c87e 2004-03-15 devnull dirsinkwritefile(DirSink *k, VacFile *vf)
975 7763a61a 2003-11-23 devnull {
976 7763a61a 2003-11-23 devnull VtEntry dir;
977 7763a61a 2003-11-23 devnull
978 3d77c87e 2004-03-15 devnull if(vacfilegetvtentry(vf, &dir) < 0)
979 3d77c87e 2004-03-15 devnull return -1;
980 3d77c87e 2004-03-15 devnull dirsinkwrite(k, &dir);
981 3d77c87e 2004-03-15 devnull return 0;
982 7763a61a 2003-11-23 devnull }
983 7763a61a 2003-11-23 devnull
984 7763a61a 2003-11-23 devnull void
985 3d77c87e 2004-03-15 devnull dirsinkclose(DirSink *k)
986 7763a61a 2003-11-23 devnull {
987 3d77c87e 2004-03-15 devnull metasinkclose(k->msink);
988 7763a61a 2003-11-23 devnull if(k->p != k->buf)
989 3d77c87e 2004-03-15 devnull sinkwrite(k->sink, k->buf, k->p - k->buf);
990 3d77c87e 2004-03-15 devnull sinkclose(k->sink);
991 7763a61a 2003-11-23 devnull }
992 7763a61a 2003-11-23 devnull
993 7763a61a 2003-11-23 devnull void
994 3d77c87e 2004-03-15 devnull dirsinkfree(DirSink *k)
995 7763a61a 2003-11-23 devnull {
996 3d77c87e 2004-03-15 devnull sinkfree(k->sink);
997 3d77c87e 2004-03-15 devnull metasinkfree(k->msink);
998 3d77c87e 2004-03-15 devnull vtfree(k->buf);
999 3d77c87e 2004-03-15 devnull vtfree(k);
1000 7763a61a 2003-11-23 devnull }
1001 7763a61a 2003-11-23 devnull
1002 3d77c87e 2004-03-15 devnull MetaSink*
1003 3d77c87e 2004-03-15 devnull metasinkalloc(VtConn *z, int psize, int dsize)
1004 7763a61a 2003-11-23 devnull {
1005 7763a61a 2003-11-23 devnull MetaSink *k;
1006 7763a61a 2003-11-23 devnull
1007 3d77c87e 2004-03-15 devnull k = vtmallocz(sizeof(MetaSink));
1008 3d77c87e 2004-03-15 devnull k->sink = sinkalloc(z, psize, dsize);
1009 3d77c87e 2004-03-15 devnull k->buf = vtmalloc(dsize);
1010 7763a61a 2003-11-23 devnull k->maxindex = dsize/100; /* 100 byte entries seems reasonable */
1011 7763a61a 2003-11-23 devnull if(k->maxindex < 1)
1012 7763a61a 2003-11-23 devnull k->maxindex = 1;
1013 7763a61a 2003-11-23 devnull k->rp = k->p = k->buf + MetaHeaderSize + k->maxindex*MetaIndexSize;
1014 7763a61a 2003-11-23 devnull k->ep = k->buf + dsize;
1015 7763a61a 2003-11-23 devnull return k;
1016 7763a61a 2003-11-23 devnull }
1017 7763a61a 2003-11-23 devnull
1018 7763a61a 2003-11-23 devnull /* hack to get base to compare routine - not reentrant */
1019 3d77c87e 2004-03-15 devnull uchar *blockbase;
1020 7763a61a 2003-11-23 devnull
1021 7763a61a 2003-11-23 devnull int
1022 3d77c87e 2004-03-15 devnull dircmp(const void *p0, const void *p1)
1023 7763a61a 2003-11-23 devnull {
1024 7763a61a 2003-11-23 devnull uchar *q0, *q1;
1025 7763a61a 2003-11-23 devnull int n0, n1, r;
1026 7763a61a 2003-11-23 devnull
1027 7763a61a 2003-11-23 devnull /* name is first element of entry */
1028 3d77c87e 2004-03-15 devnull q0 = (uchar*)p0;
1029 3d77c87e 2004-03-15 devnull q0 = blockbase + (q0[0]<<8) + q0[1];
1030 7763a61a 2003-11-23 devnull n0 = (q0[6]<<8) + q0[7];
1031 7763a61a 2003-11-23 devnull q0 += 8;
1032 7763a61a 2003-11-23 devnull
1033 3d77c87e 2004-03-15 devnull q1 = (uchar*)p1;
1034 3d77c87e 2004-03-15 devnull q1 = blockbase + (q1[0]<<8) + q1[1];
1035 7763a61a 2003-11-23 devnull n1 = (q1[6]<<8) + q1[7];
1036 7763a61a 2003-11-23 devnull q1 += 8;
1037 7763a61a 2003-11-23 devnull
1038 7763a61a 2003-11-23 devnull if(n0 == n1)
1039 7763a61a 2003-11-23 devnull return memcmp(q0, q1, n0);
1040 7763a61a 2003-11-23 devnull else if (n0 < n1) {
1041 7763a61a 2003-11-23 devnull r = memcmp(q0, q1, n0);
1042 7763a61a 2003-11-23 devnull return (r==0)?1:r;
1043 7763a61a 2003-11-23 devnull } else {
1044 7763a61a 2003-11-23 devnull r = memcmp(q0, q1, n1);
1045 7763a61a 2003-11-23 devnull return (r==0)?-1:r;
1046 7763a61a 2003-11-23 devnull }
1047 7763a61a 2003-11-23 devnull }
1048 7763a61a 2003-11-23 devnull
1049 7763a61a 2003-11-23 devnull void
1050 3d77c87e 2004-03-15 devnull metasinkflush(MetaSink *k)
1051 7763a61a 2003-11-23 devnull {
1052 7763a61a 2003-11-23 devnull uchar *p;
1053 7763a61a 2003-11-23 devnull int n;
1054 7763a61a 2003-11-23 devnull MetaBlock mb;
1055 7763a61a 2003-11-23 devnull
1056 7763a61a 2003-11-23 devnull if(k->nindex == 0)
1057 7763a61a 2003-11-23 devnull return;
1058 7763a61a 2003-11-23 devnull assert(k->nindex <= k->maxindex);
1059 7763a61a 2003-11-23 devnull
1060 7763a61a 2003-11-23 devnull p = k->buf;
1061 7763a61a 2003-11-23 devnull n = k->rp - p;
1062 7763a61a 2003-11-23 devnull
1063 7763a61a 2003-11-23 devnull mb.size = n;
1064 7763a61a 2003-11-23 devnull mb.free = 0;
1065 7763a61a 2003-11-23 devnull mb.nindex = k->nindex;
1066 7763a61a 2003-11-23 devnull mb.maxindex = k->maxindex;
1067 7763a61a 2003-11-23 devnull mb.buf = p;
1068 3d77c87e 2004-03-15 devnull mbpack(&mb);
1069 7763a61a 2003-11-23 devnull
1070 7763a61a 2003-11-23 devnull p += MetaHeaderSize;
1071 7763a61a 2003-11-23 devnull
1072 7763a61a 2003-11-23 devnull /* XXX this is not reentrant! */
1073 3d77c87e 2004-03-15 devnull blockbase = k->buf;
1074 3d77c87e 2004-03-15 devnull qsort(p, k->nindex, MetaIndexSize, dircmp);
1075 7763a61a 2003-11-23 devnull p += k->nindex*MetaIndexSize;
1076 7763a61a 2003-11-23 devnull
1077 7763a61a 2003-11-23 devnull memset(p, 0, (k->maxindex-k->nindex)*MetaIndexSize);
1078 7763a61a 2003-11-23 devnull p += (k->maxindex-k->nindex)*MetaIndexSize;
1079 7763a61a 2003-11-23 devnull
1080 3d77c87e 2004-03-15 devnull sinkwrite(k->sink, k->buf, n);
1081 7763a61a 2003-11-23 devnull
1082 7763a61a 2003-11-23 devnull /* move down partial entry */
1083 7763a61a 2003-11-23 devnull n = k->p - k->rp;
1084 7763a61a 2003-11-23 devnull memmove(p, k->rp, n);
1085 7763a61a 2003-11-23 devnull k->rp = p;
1086 7763a61a 2003-11-23 devnull k->p = p + n;
1087 7763a61a 2003-11-23 devnull k->nindex = 0;
1088 7763a61a 2003-11-23 devnull }
1089 7763a61a 2003-11-23 devnull
1090 7763a61a 2003-11-23 devnull void
1091 3d77c87e 2004-03-15 devnull metasinkputc(MetaSink *k, int c)
1092 7763a61a 2003-11-23 devnull {
1093 7763a61a 2003-11-23 devnull if(k->p+1 > k->ep)
1094 3d77c87e 2004-03-15 devnull metasinkflush(k);
1095 7763a61a 2003-11-23 devnull if(k->p+1 > k->ep)
1096 3d77c87e 2004-03-15 devnull sysfatal("directory entry too large");
1097 7763a61a 2003-11-23 devnull k->p[0] = c;
1098 7763a61a 2003-11-23 devnull k->p++;
1099 7763a61a 2003-11-23 devnull }
1100 7763a61a 2003-11-23 devnull
1101 7763a61a 2003-11-23 devnull void
1102 3d77c87e 2004-03-15 devnull metasinkputstring(MetaSink *k, char *s)
1103 7763a61a 2003-11-23 devnull {
1104 7763a61a 2003-11-23 devnull int n = strlen(s);
1105 3d77c87e 2004-03-15 devnull metasinkputc(k, n>>8);
1106 3d77c87e 2004-03-15 devnull metasinkputc(k, n);
1107 3d77c87e 2004-03-15 devnull metasinkwrite(k, (uchar*)s, n);
1108 7763a61a 2003-11-23 devnull }
1109 7763a61a 2003-11-23 devnull
1110 7763a61a 2003-11-23 devnull void
1111 3d77c87e 2004-03-15 devnull metasinkputuint32(MetaSink *k, ulong x)
1112 7763a61a 2003-11-23 devnull {
1113 3d77c87e 2004-03-15 devnull metasinkputc(k, x>>24);
1114 3d77c87e 2004-03-15 devnull metasinkputc(k, x>>16);
1115 3d77c87e 2004-03-15 devnull metasinkputc(k, x>>8);
1116 3d77c87e 2004-03-15 devnull metasinkputc(k, x);
1117 7763a61a 2003-11-23 devnull }
1118 7763a61a 2003-11-23 devnull
1119 7763a61a 2003-11-23 devnull void
1120 3d77c87e 2004-03-15 devnull metasinkputuint64(MetaSink *k, uvlong x)
1121 7763a61a 2003-11-23 devnull {
1122 3d77c87e 2004-03-15 devnull metasinkputuint32(k, x>>32);
1123 3d77c87e 2004-03-15 devnull metasinkputuint32(k, x);
1124 7763a61a 2003-11-23 devnull }
1125 7763a61a 2003-11-23 devnull
1126 7763a61a 2003-11-23 devnull void
1127 3d77c87e 2004-03-15 devnull metasinkwrite(MetaSink *k, uchar *data, int n)
1128 7763a61a 2003-11-23 devnull {
1129 7763a61a 2003-11-23 devnull if(k->p + n > k->ep)
1130 3d77c87e 2004-03-15 devnull metasinkflush(k);
1131 7763a61a 2003-11-23 devnull if(k->p + n > k->ep)
1132 3d77c87e 2004-03-15 devnull sysfatal("directory entry too large");
1133 7763a61a 2003-11-23 devnull
1134 7763a61a 2003-11-23 devnull memmove(k->p, data, n);
1135 7763a61a 2003-11-23 devnull k->p += n;
1136 7763a61a 2003-11-23 devnull }
1137 7763a61a 2003-11-23 devnull
1138 7763a61a 2003-11-23 devnull void
1139 3d77c87e 2004-03-15 devnull metasinkwritedir(MetaSink *ms, VacDir *dir)
1140 7763a61a 2003-11-23 devnull {
1141 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, DirMagic);
1142 3d77c87e 2004-03-15 devnull metasinkputc(ms, Version>>8);
1143 3d77c87e 2004-03-15 devnull metasinkputc(ms, Version);
1144 3d77c87e 2004-03-15 devnull metasinkputstring(ms, dir->elem);
1145 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->entry);
1146 3d77c87e 2004-03-15 devnull metasinkputuint64(ms, dir->qid);
1147 3d77c87e 2004-03-15 devnull metasinkputstring(ms, dir->uid);
1148 3d77c87e 2004-03-15 devnull metasinkputstring(ms, dir->gid);
1149 3d77c87e 2004-03-15 devnull metasinkputstring(ms, dir->mid);
1150 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->mtime);
1151 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->mcount);
1152 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->ctime);
1153 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->atime);
1154 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->mode);
1155 7763a61a 2003-11-23 devnull
1156 7763a61a 2003-11-23 devnull if(dir->plan9) {
1157 3d77c87e 2004-03-15 devnull metasinkputc(ms, DirPlan9Entry); /* plan9 extra info */
1158 3d77c87e 2004-03-15 devnull metasinkputc(ms, 0); /* plan9 extra size */
1159 3d77c87e 2004-03-15 devnull metasinkputc(ms, 12); /* plan9 extra size */
1160 3d77c87e 2004-03-15 devnull metasinkputuint64(ms, dir->p9path);
1161 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->p9version);
1162 7763a61a 2003-11-23 devnull }
1163 7763a61a 2003-11-23 devnull
1164 3d77c87e 2004-03-15 devnull if(dir->qidspace != 0) {
1165 3d77c87e 2004-03-15 devnull metasinkputc(ms, DirQidSpaceEntry);
1166 3d77c87e 2004-03-15 devnull metasinkputc(ms, 0);
1167 3d77c87e 2004-03-15 devnull metasinkputc(ms, 16);
1168 3d77c87e 2004-03-15 devnull metasinkputuint64(ms, dir->qidoffset);
1169 3d77c87e 2004-03-15 devnull metasinkputuint64(ms, dir->qidmax);
1170 7763a61a 2003-11-23 devnull }
1171 7763a61a 2003-11-23 devnull
1172 7763a61a 2003-11-23 devnull if(dir->gen != 0) {
1173 3d77c87e 2004-03-15 devnull metasinkputc(ms, DirGenEntry);
1174 3d77c87e 2004-03-15 devnull metasinkputc(ms, 0);
1175 3d77c87e 2004-03-15 devnull metasinkputc(ms, 4);
1176 3d77c87e 2004-03-15 devnull metasinkputuint32(ms, dir->gen);
1177 7763a61a 2003-11-23 devnull }
1178 7763a61a 2003-11-23 devnull
1179 3d77c87e 2004-03-15 devnull metasinkeor(ms);
1180 7763a61a 2003-11-23 devnull }
1181 7763a61a 2003-11-23 devnull
1182 7763a61a 2003-11-23 devnull
1183 7763a61a 2003-11-23 devnull void
1184 3d77c87e 2004-03-15 devnull plan9tovacdir(VacDir *vd, Dir *dir, ulong entry, uvlong qid)
1185 7763a61a 2003-11-23 devnull {
1186 7763a61a 2003-11-23 devnull memset(vd, 0, sizeof(VacDir));
1187 7763a61a 2003-11-23 devnull
1188 3d77c87e 2004-03-15 devnull vd->elem = vtstrdup(dir->name);
1189 7763a61a 2003-11-23 devnull vd->entry = entry;
1190 7763a61a 2003-11-23 devnull vd->qid = qid;
1191 3d77c87e 2004-03-15 devnull vd->uid = vtstrdup(dir->uid);
1192 3d77c87e 2004-03-15 devnull vd->gid = vtstrdup(dir->gid);
1193 3d77c87e 2004-03-15 devnull vd->mid = vtstrdup(dir->muid);
1194 7763a61a 2003-11-23 devnull vd->mtime = dir->mtime;
1195 7763a61a 2003-11-23 devnull vd->mcount = 0;
1196 7763a61a 2003-11-23 devnull vd->ctime = dir->mtime; /* ctime: not available on plan 9 */
1197 7763a61a 2003-11-23 devnull vd->atime = dir->atime;
1198 7763a61a 2003-11-23 devnull
1199 7763a61a 2003-11-23 devnull vd->mode = dir->mode & 0777;
1200 7763a61a 2003-11-23 devnull if(dir->mode & DMDIR)
1201 7763a61a 2003-11-23 devnull vd->mode |= ModeDir;
1202 7763a61a 2003-11-23 devnull if(dir->mode & DMAPPEND)
1203 7763a61a 2003-11-23 devnull vd->mode |= ModeAppend;
1204 7763a61a 2003-11-23 devnull if(dir->mode & DMEXCL)
1205 7763a61a 2003-11-23 devnull vd->mode |= ModeExclusive;
1206 71f05672 2005-09-13 devnull if(dir->mode & DMDEVICE)
1207 71f05672 2005-09-13 devnull vd->mode |= ModeDevice;
1208 71f05672 2005-09-13 devnull if(dir->mode & DMNAMEDPIPE)
1209 71f05672 2005-09-13 devnull vd->mode |= ModeNamedPipe;
1210 71f05672 2005-09-13 devnull if(dir->mode & DMSYMLINK)
1211 71f05672 2005-09-13 devnull vd->mode |= ModeLink;
1212 7763a61a 2003-11-23 devnull
1213 7763a61a 2003-11-23 devnull vd->plan9 = 1;
1214 7763a61a 2003-11-23 devnull vd->p9path = dir->qid.path;
1215 7763a61a 2003-11-23 devnull vd->p9version = dir->qid.vers;
1216 7763a61a 2003-11-23 devnull }
1217 7763a61a 2003-11-23 devnull
1218 7763a61a 2003-11-23 devnull
1219 7763a61a 2003-11-23 devnull void
1220 3d77c87e 2004-03-15 devnull metasinkeor(MetaSink *k)
1221 7763a61a 2003-11-23 devnull {
1222 7763a61a 2003-11-23 devnull uchar *p;
1223 7763a61a 2003-11-23 devnull int o, n;
1224 7763a61a 2003-11-23 devnull
1225 7763a61a 2003-11-23 devnull p = k->buf + MetaHeaderSize;
1226 7763a61a 2003-11-23 devnull p += k->nindex * MetaIndexSize;
1227 7763a61a 2003-11-23 devnull o = k->rp-k->buf; /* offset from start of block */
1228 7763a61a 2003-11-23 devnull n = k->p-k->rp; /* size of entry */
1229 7763a61a 2003-11-23 devnull p[0] = o >> 8;
1230 7763a61a 2003-11-23 devnull p[1] = o;
1231 7763a61a 2003-11-23 devnull p[2] = n >> 8;
1232 7763a61a 2003-11-23 devnull p[3] = n;
1233 7763a61a 2003-11-23 devnull k->rp = k->p;
1234 7763a61a 2003-11-23 devnull k->nindex++;
1235 7763a61a 2003-11-23 devnull if(k->nindex == k->maxindex)
1236 3d77c87e 2004-03-15 devnull metasinkflush(k);
1237 7763a61a 2003-11-23 devnull }
1238 7763a61a 2003-11-23 devnull
1239 7763a61a 2003-11-23 devnull void
1240 3d77c87e 2004-03-15 devnull metasinkclose(MetaSink *k)
1241 7763a61a 2003-11-23 devnull {
1242 3d77c87e 2004-03-15 devnull metasinkflush(k);
1243 3d77c87e 2004-03-15 devnull sinkclose(k->sink);
1244 7763a61a 2003-11-23 devnull }
1245 7763a61a 2003-11-23 devnull
1246 7763a61a 2003-11-23 devnull void
1247 3d77c87e 2004-03-15 devnull metasinkfree(MetaSink *k)
1248 7763a61a 2003-11-23 devnull {
1249 3d77c87e 2004-03-15 devnull sinkfree(k->sink);
1250 3d77c87e 2004-03-15 devnull vtfree(k->buf);
1251 3d77c87e 2004-03-15 devnull vtfree(k);
1252 7763a61a 2003-11-23 devnull }
1253 7763a61a 2003-11-23 devnull
1254 7763a61a 2003-11-23 devnull static void
1255 7763a61a 2003-11-23 devnull warn(char *fmt, ...)
1256 7763a61a 2003-11-23 devnull {
1257 7763a61a 2003-11-23 devnull va_list arg;
1258 7763a61a 2003-11-23 devnull
1259 7763a61a 2003-11-23 devnull va_start(arg, fmt);
1260 7763a61a 2003-11-23 devnull fprint(2, "%s: ", argv0);
1261 7763a61a 2003-11-23 devnull vfprint(2, fmt, arg);
1262 7763a61a 2003-11-23 devnull fprint(2, "\n");
1263 7763a61a 2003-11-23 devnull va_end(arg);
1264 7763a61a 2003-11-23 devnull }
1265 7763a61a 2003-11-23 devnull
1266 7763a61a 2003-11-23 devnull static void
1267 7763a61a 2003-11-23 devnull cleanup(void)
1268 7763a61a 2003-11-23 devnull {
1269 7763a61a 2003-11-23 devnull if(oname != nil)
1270 7763a61a 2003-11-23 devnull remove(oname);
1271 7763a61a 2003-11-23 devnull }
1272 7763a61a 2003-11-23 devnull
1273 7763a61a 2003-11-23 devnull #define TWID64 ((u64int)~(u64int)0)
1274 7763a61a 2003-11-23 devnull
1275 7763a61a 2003-11-23 devnull static u64int
1276 7763a61a 2003-11-23 devnull unittoull(char *s)
1277 7763a61a 2003-11-23 devnull {
1278 7763a61a 2003-11-23 devnull char *es;
1279 7763a61a 2003-11-23 devnull u64int n;
1280 7763a61a 2003-11-23 devnull
1281 7763a61a 2003-11-23 devnull if(s == nil)
1282 7763a61a 2003-11-23 devnull return TWID64;
1283 7763a61a 2003-11-23 devnull n = strtoul(s, &es, 0);
1284 7763a61a 2003-11-23 devnull if(*es == 'k' || *es == 'K'){
1285 7763a61a 2003-11-23 devnull n *= 1024;
1286 7763a61a 2003-11-23 devnull es++;
1287 7763a61a 2003-11-23 devnull }else if(*es == 'm' || *es == 'M'){
1288 7763a61a 2003-11-23 devnull n *= 1024*1024;
1289 7763a61a 2003-11-23 devnull es++;
1290 7763a61a 2003-11-23 devnull }else if(*es == 'g' || *es == 'G'){
1291 7763a61a 2003-11-23 devnull n *= 1024*1024*1024;
1292 7763a61a 2003-11-23 devnull es++;
1293 7763a61a 2003-11-23 devnull }
1294 7763a61a 2003-11-23 devnull if(*es != '\0')
1295 7763a61a 2003-11-23 devnull return TWID64;
1296 7763a61a 2003-11-23 devnull return n;
1297 7763a61a 2003-11-23 devnull }