Line data Source code
1 : #include "../burp.h"
2 : #include "../alloc.h"
3 : #include "../cmd.h"
4 : #include "../fsops.h"
5 : #include "../fzp.h"
6 : #include "../hexmap.h"
7 : #include "../log.h"
8 : #include "../msg.h"
9 : #include "../prepend.h"
10 : #include "../protocol2/blk.h"
11 : #include "../sbuf.h"
12 : #include "manio.h"
13 : #include "protocol2/champ_chooser/champ_chooser.h"
14 : #include "protocol2/dpth.h"
15 :
16 : static void man_off_t_free_content(man_off_t *offset)
17 : {
18 246 : if(!offset) return;
19 15786 : free_w(&offset->fpath);
20 15786 : free_w(&offset->ppath);
21 : }
22 :
23 15848 : void man_off_t_free(man_off_t **offset)
24 : {
25 15848 : if(!offset || !*offset) return;
26 31080 : man_off_t_free_content(*offset);
27 15540 : free_v((void **)offset);
28 : }
29 :
30 : static man_off_t *man_off_t_alloc(void)
31 : {
32 15540 : return (man_off_t *)calloc_w(1, sizeof(man_off_t), __func__);
33 : }
34 :
35 11 : static int init_write_hooks(struct manio *manio,
36 : const char *hook_dir, const char *rmanifest)
37 : {
38 11 : if(!(manio->hook_dir=strdup_w(hook_dir, __func__))
39 11 : || !(manio->rmanifest=strdup_w(rmanifest, __func__))
40 11 : || !(manio->hook_sort=(uint64_t *)calloc_w(MANIFEST_SIG_MAX,
41 : sizeof(uint64_t), __func__)))
42 : return -1;
43 : return 0;
44 : }
45 :
46 11 : static int init_write_dindex(struct manio *manio, const char *dir)
47 : {
48 11 : if(!(manio->dindex_dir=strdup_w(dir, __func__))
49 11 : || !(manio->dindex_sort=(uint64_t *)calloc_w(MANIFEST_SIG_MAX,
50 : sizeof(uint64_t), __func__)))
51 : return -1;
52 : return 0;
53 : }
54 :
55 : static int is_single_file(struct manio *manio)
56 : {
57 1710 : return manio->protocol==PROTO_1 || manio->phase==1;
58 : }
59 :
60 1132 : static char *get_next_fpath(struct manio *manio, man_off_t *offset)
61 : {
62 : static char tmp[32];
63 2264 : if(is_single_file(manio))
64 484 : return strdup_w(manio->manifest, __func__);
65 648 : snprintf(tmp, sizeof(tmp), "%08" PRIX64, offset->fcount++);
66 648 : return prepend_s(manio->manifest, tmp);
67 : }
68 :
69 1032 : static int manio_open_next_fpath(struct manio *manio)
70 : {
71 : static struct stat statp;
72 1032 : man_off_t *offset=manio->offset;
73 :
74 1032 : free_w(&offset->ppath);
75 1032 : offset->ppath=offset->fpath;
76 1032 : if(!(offset->fpath=get_next_fpath(manio, offset)))
77 : return -1;
78 :
79 1032 : if(!strcmp(manio->mode, MANIO_MODE_READ)
80 1226 : && lstat(offset->fpath, &statp))
81 : return 0;
82 :
83 864 : if(build_path_w(offset->fpath))
84 : return -1;
85 864 : switch(manio->phase)
86 : {
87 : case 2:
88 676 : if(!(manio->fzp=fzp_open(offset->fpath,
89 676 : manio->mode))) return -1;
90 676 : return 0;
91 : case 1:
92 : case 3:
93 : default:
94 188 : if(!(manio->fzp=fzp_gzopen(offset->fpath,
95 188 : manio->mode))) return -1;
96 188 : return 0;
97 : }
98 : }
99 :
100 92 : static int manio_open_last_fpath(struct manio *manio)
101 : {
102 92 : int max=-1;
103 184 : if(is_single_file(manio))
104 56 : return manio_open_next_fpath(manio);
105 36 : if(get_highest_entry(manio->manifest, &max, 8))
106 : return -1;
107 36 : if(max<0) max=0;
108 36 : manio->offset->fcount=(uint64_t)max;
109 36 : return manio_open_next_fpath(manio);
110 : }
111 :
112 : static struct manio *manio_alloc(void)
113 : {
114 806 : return (struct manio *)calloc_w(1, sizeof(struct manio), __func__);
115 : }
116 :
117 806 : static struct manio *do_manio_open(const char *manifest, const char *mode,
118 : enum protocol protocol, int phase)
119 : {
120 806 : struct manio *manio=NULL;
121 806 : if(!(manio=manio_alloc())
122 806 : || !(manio->manifest=strdup_w(manifest, __func__))
123 806 : || !(manio->mode=strdup_w(mode, __func__))
124 1612 : || !(manio->offset=man_off_t_alloc()))
125 : goto error;
126 806 : manio->protocol=protocol;
127 806 : manio->phase=phase;
128 806 : if(!strcmp(manio->mode, MANIO_MODE_APPEND))
129 : {
130 92 : if(manio->phase!=2)
131 : {
132 0 : logp("manio append mode only works for phase 2.\n");
133 0 : logp("%s has phase: %d\n",
134 0 : manio->manifest, manio->phase);
135 0 : goto error;
136 : }
137 92 : if(manio_open_last_fpath(manio))
138 : goto error;
139 : }
140 : else
141 : {
142 714 : if(manio_open_next_fpath(manio))
143 : goto error;
144 : }
145 806 : return manio;
146 : error:
147 0 : manio_close(&manio);
148 0 : return NULL;
149 : }
150 :
151 43 : struct manio *manio_open(const char *manifest, const char *mode,
152 : enum protocol protocol)
153 : {
154 43 : return do_manio_open(manifest, mode, protocol, 0);
155 : }
156 :
157 144 : struct manio *manio_open_phase1(const char *manifest, const char *mode,
158 : enum protocol protocol)
159 : {
160 144 : return do_manio_open(manifest, mode, protocol, 1);
161 : }
162 :
163 600 : struct manio *manio_open_phase2(const char *manifest, const char *mode,
164 : enum protocol protocol)
165 : {
166 600 : return do_manio_open(manifest, mode, protocol, 2);
167 : }
168 :
169 19 : struct manio *manio_open_phase3(const char *manifest, const char *mode,
170 : enum protocol protocol, const char *rmanifest)
171 : {
172 19 : struct manio *manio=NULL;
173 :
174 19 : if(!(manio=do_manio_open(manifest, mode, protocol, 3)))
175 : goto end;
176 :
177 19 : if(protocol==PROTO_2 && rmanifest)
178 : {
179 11 : char *hooksdir=NULL;
180 11 : char *dindexdir=NULL;
181 11 : if(!(hooksdir=prepend_s(manifest, "hooks"))
182 11 : || !(dindexdir=prepend_s(manifest, "dindex"))
183 11 : || init_write_hooks(manio, hooksdir, rmanifest)
184 11 : || init_write_dindex(manio, dindexdir))
185 0 : manio_close(&manio);
186 11 : free_w(&hooksdir);
187 11 : free_w(&dindexdir);
188 : }
189 :
190 : end:
191 19 : return manio;
192 : }
193 :
194 806 : static void manio_free_content(struct manio *manio)
195 : {
196 806 : if(!manio) return;
197 806 : man_off_t_free(&manio->offset);
198 806 : free_w(&manio->manifest);
199 806 : free_w(&manio->mode);
200 806 : free_w(&manio->rmanifest);
201 806 : free_w(&manio->hook_dir);
202 806 : free_v((void **)&manio->hook_sort);
203 806 : free_w(&manio->dindex_dir);
204 806 : free_v((void **)&manio->dindex_sort);
205 806 : memset(manio, 0, sizeof(struct manio));
206 : }
207 :
208 : #ifndef UTEST
209 : static
210 : #endif
211 36 : int write_hook_header(struct fzp *fzp, const char *rmanifest, const char *msg)
212 : {
213 36 : int ret=0;
214 36 : char *tmp=NULL;
215 36 : if(!(tmp=prepend_s(rmanifest, msg))
216 36 : || send_msg_fzp(fzp, CMD_MANIFEST, tmp, strlen(tmp)))
217 : ret=-1;
218 36 : free_w(&tmp);
219 36 : return ret;
220 : }
221 :
222 377847 : static int uint64_t_sort(const void *a, const void *b)
223 : {
224 377847 : uint64_t *x=(uint64_t *)a;
225 377847 : uint64_t *y=(uint64_t *)b;
226 377847 : if(*x>*y) return 1;
227 185793 : if(*x<*y) return -1;
228 0 : return 0;
229 : }
230 :
231 : static char *get_fcount_path(struct manio *manio)
232 : {
233 21 : return prepend_s(manio->manifest, "fcount");
234 : }
235 :
236 : // Backup phase4 needs to know the fcount, so leave a file behind that
237 : // contains it (otherwise phase4 will have to read and sort the directory
238 : // contents).
239 20 : static int manio_write_fcount(struct manio *manio)
240 : {
241 20 : int ret=-1;
242 20 : struct fzp *fzp=NULL;
243 20 : char *path=NULL;
244 :
245 40 : if(!(path=get_fcount_path(manio))
246 20 : || !(fzp=fzp_open(path, "wb")))
247 : goto end;
248 20 : if(fzp_printf(fzp, "%08" PRIX64 "\n", manio->offset->fcount)!=9)
249 : {
250 0 : logp("Short write when writing to %s\n", path);
251 0 : goto end;
252 : }
253 : ret=0;
254 : end:
255 20 : if(fzp_close(&fzp))
256 : {
257 0 : logp("Could not close file pointer to %s\n", path);
258 0 : ret=-1;
259 : }
260 20 : free_w(&path);
261 20 : return ret;
262 : }
263 :
264 1 : int manio_read_fcount(struct manio *manio)
265 : {
266 1 : int ret=-1;
267 : size_t s;
268 1 : struct fzp *fzp=NULL;
269 1 : char *path=NULL;
270 1 : char buf[16]="";
271 2 : if(!(path=get_fcount_path(manio))
272 1 : || !(fzp=fzp_open(path, "rb")))
273 : goto end;
274 1 : if(!fzp_gets(fzp, buf, sizeof(buf)))
275 : {
276 0 : logp("fzp_gets on %s failed\n", path);
277 0 : goto end;
278 : }
279 1 : s=strlen(buf);
280 1 : if(s!=9)
281 : {
282 0 : logp("data in %s is not the right length (%lu!=9)\n", path,
283 : (unsigned long)s);
284 0 : goto end;
285 : }
286 1 : manio->offset->fcount=strtoul(buf, NULL, 16);
287 1 : ret=0;
288 : end:
289 1 : fzp_close(&fzp);
290 1 : free_w(&path);
291 1 : return ret;
292 : }
293 :
294 1135 : static int sort_and_write_hooks(struct manio *manio)
295 : {
296 : int i;
297 1135 : int ret=-1;
298 1135 : struct fzp *fzp=NULL;
299 1135 : char msg[32]="";
300 1135 : char *path=NULL;
301 1135 : int hook_count=manio->hook_count;
302 1135 : uint64_t *hook_sort=manio->hook_sort;
303 1135 : if(!hook_sort) return 0;
304 :
305 20 : snprintf(msg, sizeof(msg), "%08" PRIX64, manio->offset->fcount-1);
306 20 : if(!(path=prepend_s(manio->hook_dir, msg))
307 20 : || build_path_w(path)
308 20 : || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
309 : goto end;
310 :
311 20 : qsort(hook_sort, hook_count, sizeof(uint64_t), uint64_t_sort);
312 :
313 20 : if(write_hook_header(fzp, manio->rmanifest, msg)) goto end;
314 2208 : for(i=0; i<hook_count; i++)
315 : {
316 : // Do not bother with duplicates.
317 2208 : if(i && hook_sort[i]==hook_sort[i-1])
318 0 : continue;
319 :
320 2208 : if(to_fzp_fingerprint(fzp, hook_sort[i]))
321 : goto end;
322 : }
323 20 : if(fzp_close(&fzp))
324 : {
325 0 : logp("Error closing %s in %s: %s\n",
326 0 : path, __func__, strerror(errno));
327 0 : goto end;
328 : }
329 20 : if(manio_write_fcount(manio)) goto end;
330 20 : manio->hook_count=0;
331 20 : ret=0;
332 : end:
333 20 : fzp_close(&fzp);
334 20 : free_w(&path);
335 20 : return ret;
336 : }
337 :
338 1135 : static int sort_and_write_dindex(struct manio *manio)
339 : {
340 : int i;
341 1135 : int ret=-1;
342 1135 : struct fzp *fzp=NULL;
343 1135 : char msg[32]="";
344 1135 : char *path=NULL;
345 : struct iobuf wbuf;
346 : struct blk blk;
347 1135 : int dindex_count=manio->dindex_count;
348 1135 : uint64_t *dindex_sort=manio->dindex_sort;
349 1135 : if(!dindex_sort) return 0;
350 :
351 20 : snprintf(msg, sizeof(msg), "%08" PRIX64, manio->offset->fcount-1);
352 20 : if(!(path=prepend_s(manio->dindex_dir, msg))
353 20 : || build_path_w(path)
354 20 : || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
355 : goto end;
356 :
357 20 : qsort(dindex_sort, dindex_count, sizeof(uint64_t), uint64_t_sort);
358 :
359 34899 : for(i=0; i<dindex_count; i++)
360 : {
361 : // Do not bother with duplicates.
362 34879 : if(i && dindex_sort[i]==dindex_sort[i-1])
363 0 : continue;
364 :
365 34879 : blk.savepath=dindex_sort[i];
366 34879 : blk_to_iobuf_savepath(&blk, &wbuf);
367 34879 : if(iobuf_send_msg_fzp(&wbuf, fzp)) return -1;
368 : }
369 20 : if(fzp_close(&fzp))
370 : {
371 0 : logp("Error closing %s in %s: %s\n",
372 0 : path, __func__, strerror(errno));
373 0 : goto end;
374 : }
375 20 : manio->dindex_count=0;
376 20 : ret=0;
377 : end:
378 20 : fzp_close(&fzp);
379 20 : free_w(&path);
380 20 : return ret;
381 : }
382 :
383 1135 : static int sort_and_write_hooks_and_dindex(struct manio *manio)
384 : {
385 1135 : return sort_and_write_hooks(manio)
386 1135 : || sort_and_write_dindex(manio);
387 : }
388 :
389 954 : int manio_close(struct manio **manio)
390 : {
391 954 : int ret=0;
392 : // int fd;
393 954 : if(!manio || !*manio) return ret;
394 806 : if(sort_and_write_hooks_and_dindex(*manio))
395 0 : ret=-1;
396 : /*
397 : There is no gzfileno()
398 : if((fd=fzp_fileno((*manio)->fzp))<0)
399 : {
400 : logp("Could not get fileno in %s for %s: %s\n", __func__,
401 : (*manio)->manifest, strerror(errno));
402 : ret=-1;
403 : }
404 : // Should probably have a flush before fsync too.
405 : if(fsync(fd))
406 : {
407 : logp("Error in fsync in %s for %s: %s\n", __func__,
408 : (*manio)->manifest, strerror(errno));
409 : ret=-1;
410 : }
411 : */
412 806 : if(fzp_close(&((*manio)->fzp)))
413 0 : ret=-1;
414 806 : sync();
415 806 : manio_free_content(*manio);
416 806 : free_v((void **)manio);
417 806 : return ret;
418 : }
419 :
420 : // Return -1 for error, 0 for stuff read OK, 1 for end of files.
421 115440 : int manio_read_with_blk(struct manio *manio, struct sbuf *sb, struct blk *blk)
422 : {
423 : while(1)
424 : {
425 115598 : if(!manio->fzp)
426 : {
427 183 : if(manio_open_next_fpath(manio)) goto error;
428 183 : if(!manio->fzp) return 1; // No more files to read.
429 : }
430 :
431 115463 : switch(sbuf_fill_from_file(sb, manio->fzp, blk))
432 : {
433 : case 0: return 0; // Got something.
434 : case 1: break; // Keep going.
435 : default: goto error; // Error.
436 : }
437 :
438 : // Reached the end of the current file.
439 : // Maybe there is another file to continue with.
440 286 : if(sort_and_write_hooks_and_dindex(manio)
441 286 : || fzp_close(&manio->fzp)) goto error;
442 :
443 572 : if(is_single_file(manio)) return 1;
444 : }
445 :
446 : error:
447 : return -1;
448 : }
449 :
450 54948 : int manio_read(struct manio *manio, struct sbuf *sb)
451 : {
452 54948 : return manio_read_with_blk(manio, sb, NULL);
453 : }
454 :
455 43 : static int reset_sig_count_and_close(struct manio *manio)
456 : {
457 43 : if(sort_and_write_hooks_and_dindex(manio)) return -1;
458 43 : if(fzp_close(&manio->fzp)) return -1;
459 43 : manio->sig_count=0;
460 43 : if(manio_open_next_fpath(manio)) return -1;
461 43 : return 0;
462 : }
463 :
464 : #ifndef UTEST
465 : static
466 : #endif
467 3574 : int manio_find_boundary(uint8_t *md5sum)
468 : {
469 : int i;
470 : uint8_t x;
471 : uint8_t y;
472 3574 : uint8_t b4=0;
473 :
474 : // I am currently making it look for four of the same consecutive
475 : // characters in the md5sum.
476 56854 : for(i=0; i<MD5_DIGEST_LENGTH-1; i++)
477 : {
478 53333 : x=md5sum[i]>>4;
479 53333 : y=md5sum[i]&0x0F;
480 53333 : if(x==y)
481 : {
482 3303 : if(x!=md5sum[i+1]>>4)
483 3106 : continue;
484 197 : if(i && x==b4)
485 : return 1;
486 175 : if(x==(md5sum[i+1]&0x0F))
487 : return 1;
488 : }
489 : b4=y;
490 : }
491 : return 0;
492 : }
493 :
494 : // After conditions are met, close the file currently being written to.
495 : // Allow the number of signatures to be vary between MANIFEST_SIG_MIN and
496 : // MANIFEST_SIG_MAX. This will hopefully allow fewer candidate manifests
497 : // generated, since the boundary will be able to vary.
498 187793 : static int check_sig_count(struct manio *manio, struct blk *blk)
499 : {
500 187793 : manio->sig_count++;
501 :
502 187793 : if(manio->sig_count<MANIFEST_SIG_MIN)
503 : return 0; // Not yet time to close.
504 :
505 3558 : if(manio->sig_count>=MANIFEST_SIG_MAX)
506 0 : return reset_sig_count_and_close(manio); // Time to close.
507 :
508 : // At this point, dynamically decide based on the current msg.
509 3558 : if(manio_find_boundary(blk->md5sum))
510 43 : return reset_sig_count_and_close(manio); // Time to close.
511 : return 0;
512 : }
513 :
514 187793 : static int write_sig_msg(struct manio *manio, struct blk *blk)
515 : {
516 : struct iobuf wbuf;
517 187793 : if(!manio->fzp && manio_open_next_fpath(manio)) return -1;
518 187793 : blk_to_iobuf_sig_and_savepath(blk, &wbuf);
519 187793 : if(iobuf_send_msg_fzp(&wbuf, manio->fzp)) return -1;
520 187793 : return check_sig_count(manio, blk);
521 : }
522 :
523 187793 : int manio_write_sig_and_path(struct manio *manio, struct blk *blk)
524 : {
525 187793 : if(manio->protocol==PROTO_1) return 0;
526 187793 : if(manio->hook_sort && blk_fingerprint_is_hook(blk))
527 : {
528 : // Add to list of hooks for this manifest chunk.
529 2208 : manio->hook_sort[manio->hook_count++]=blk->fingerprint;
530 : }
531 187793 : if(manio->dindex_sort)
532 : {
533 35171 : uint64_t savepath=blk->savepath;
534 35171 : savepath &= 0xFFFFFFFFFFFF0000ULL;
535 : // Ignore obvious duplicates.
536 35171 : if(!manio->dindex_count
537 35152 : || manio->dindex_sort[manio->dindex_count-1]!=savepath)
538 : {
539 : // Add to list of dindexes for this manifest chunk.
540 34879 : manio->dindex_sort[manio->dindex_count++]=savepath;
541 : }
542 : }
543 187793 : return write_sig_msg(manio, blk);
544 : }
545 :
546 91874 : int manio_write_sbuf(struct manio *manio, struct sbuf *sb)
547 : {
548 91874 : if(!manio->fzp && manio_open_next_fpath(manio)) return -1;
549 91874 : return sbuf_to_manifest(sb, manio->fzp);
550 : }
551 :
552 33804 : int manio_write_cntr(struct manio *manio, struct sbuf *sb,
553 : enum cntr_manio what)
554 : {
555 33804 : if(!manio->fzp && manio_open_next_fpath(manio)) return -1;
556 33804 : return sbuf_to_manifest_cntr(sb, manio->fzp, what);
557 : }
558 :
559 : // Return -1 on error, 0 on OK, 1 for srcmanio finished.
560 18 : int manio_copy_entry(struct sbuf *csb, struct sbuf *sb,
561 : struct manio *srcmanio, struct manio *dstmanio,
562 : const char *seed_src, const char *seed_dst)
563 : {
564 : int ars;
565 : struct iobuf copy1;
566 : struct iobuf copy2;
567 : struct blk *blk;
568 18 : memset(©1, 0, sizeof(copy1));
569 18 : memset(©2, 0, sizeof(copy2));
570 18 : if(!(blk=blk_alloc()))
571 : goto error;
572 :
573 : // Use the most recent stat for the new manifest.
574 18 : if(dstmanio)
575 : {
576 18 : int e=0;
577 : struct iobuf save1;
578 : struct iobuf save2;
579 18 : memset(&save1, 0, sizeof(save1));
580 18 : memset(&save2, 0, sizeof(save2));
581 :
582 : // When seeding, adjust the prefixes, but we need to remember
583 : // the original too.
584 18 : if(seed_src && seed_dst)
585 : {
586 0 : char *tmp=sb->path.buf+strlen(seed_src);
587 0 : if(!(copy1.buf=strdup_w(seed_dst, __func__)))
588 : goto error;
589 0 : if(astrcat(©1.buf, "/", __func__))
590 : goto error;
591 0 : if(*tmp=='/')
592 0 : tmp++;
593 0 : if(astrcat(©1.buf, tmp, __func__))
594 : goto error;
595 0 : copy1.len=strlen(copy1.buf);
596 0 : copy1.cmd=sb->path.cmd;
597 :
598 0 : if(sb->protocol1 && sb->protocol1->datapth.buf
599 0 : && !strncmp(sb->protocol1->datapth.buf,
600 : TREE_DIR, strlen(TREE_DIR)))
601 : {
602 0 : tmp=sb->protocol1->datapth.buf
603 : +strlen(TREE_DIR)
604 0 : +strlen(seed_src);
605 0 : if(*tmp=='/')
606 0 : tmp++;
607 0 : if(!(copy2.buf=strdup_w(TREE_DIR, __func__)))
608 : goto error;
609 0 : if(*seed_dst!='/'
610 0 : && astrcat(©2.buf, "/", __func__))
611 : goto error;
612 0 : if(astrcat(©2.buf, seed_dst, __func__)
613 0 : || astrcat(©2.buf, "/", __func__)
614 0 : || astrcat(©2.buf, tmp, __func__))
615 : goto error;
616 0 : copy2.len=strlen(copy2.buf);
617 0 : copy2.cmd=sb->protocol1->datapth.cmd;
618 : }
619 :
620 0 : save1=sb->path;
621 0 : sb->path=copy1;
622 :
623 0 : if(copy2.buf)
624 : {
625 0 : save2=sb->protocol1->datapth;
626 0 : sb->protocol1->datapth=copy2;
627 : }
628 : }
629 18 : e=manio_write_sbuf(dstmanio, sb);
630 18 : if(copy1.buf)
631 : {
632 0 : sb->path=save1;
633 0 : iobuf_free_content(©1);
634 : }
635 18 : if(copy2.buf)
636 : {
637 0 : sb->protocol1->datapth=save2;
638 0 : iobuf_free_content(©2);
639 : }
640 18 : if(e)
641 : goto error;
642 :
643 18 : if(dstmanio->protocol==PROTO_1)
644 : {
645 8 : sbuf_free_content(csb);
646 8 : blk_free(&blk);
647 8 : return 0;
648 : }
649 : }
650 :
651 10 : copy1.len=csb->path.len;
652 10 : copy1.cmd=csb->path.cmd;
653 10 : if(!(copy1.buf=strdup_w(csb->path.buf, __func__)))
654 : goto error;
655 : while(1)
656 : {
657 30 : if((ars=manio_read_with_blk(srcmanio, csb, blk))<0)
658 : goto error;
659 30 : else if(ars>0)
660 : {
661 : // Finished.
662 5 : sbuf_free_content(csb);
663 5 : blk_free(&blk);
664 5 : iobuf_free_content(©1);
665 5 : return 1;
666 : }
667 :
668 : // Got something.
669 25 : if(iobuf_pathcmp(&csb->path, ©1))
670 : {
671 : // Found the next entry.
672 5 : iobuf_free_content(©1);
673 5 : blk_free(&blk);
674 5 : return 0;
675 : }
676 20 : if(dstmanio)
677 : {
678 20 : if(!dstmanio->fzp
679 0 : && manio_open_next_fpath(dstmanio))
680 : goto error;
681 :
682 20 : if(csb->endfile.buf)
683 : {
684 10 : if(iobuf_send_msg_fzp(&csb->endfile,
685 : dstmanio->fzp)) goto error;
686 : }
687 : else
688 : {
689 : // Should have the next signature.
690 : // Write it to the destination manifest.
691 10 : if(manio_write_sig_and_path(dstmanio, blk))
692 : goto error;
693 : }
694 : }
695 : }
696 :
697 : error:
698 0 : blk_free(&blk);
699 0 : iobuf_free_content(©1);
700 0 : iobuf_free_content(©2);
701 0 : return -1;
702 : }
703 :
704 0 : int manio_forward_through_sigs(struct sbuf *csb, struct manio *manio)
705 : {
706 : // Call manio_copy_entry with nothing to write to, so
707 : // that we forward through the sigs in manio.
708 0 : return manio_copy_entry(csb, NULL, manio, NULL, NULL, NULL);
709 : }
710 :
711 14734 : man_off_t *manio_tell(struct manio *manio)
712 : {
713 14734 : man_off_t *offset=NULL;
714 14734 : if(!manio->fzp)
715 : {
716 0 : logp("%s called on null fzp\n", __func__);
717 0 : if(manio->offset && manio->offset->fpath)
718 0 : logp("manio->offset->fpath: %s\n",
719 : manio->offset->fpath);
720 : goto error;
721 : }
722 14734 : if(!(offset=man_off_t_alloc())
723 14734 : || !(offset->fpath=strdup_w(manio->offset->fpath, __func__))
724 14734 : || (offset->offset=fzp_tell(manio->fzp))<0)
725 : goto error;
726 14734 : offset->fcount=manio->offset->fcount;
727 14734 : return offset;
728 : error:
729 0 : man_off_t_free(&offset);
730 0 : return NULL;
731 : }
732 :
733 246 : int manio_seek(struct manio *manio, man_off_t *offset)
734 : {
735 246 : fzp_close(&manio->fzp);
736 246 : if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode))
737 246 : || fzp_seek(manio->fzp, offset->offset, SEEK_SET))
738 : return -1;
739 492 : man_off_t_free_content(manio->offset);
740 246 : if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__)))
741 : return -1;
742 246 : manio->offset->offset=offset->offset;
743 246 : manio->offset->fcount=offset->fcount;
744 246 : return 0;
745 : }
746 :
747 100 : static int remove_trailing_files(struct manio *manio, man_off_t *offset)
748 : {
749 100 : int ret=-1;
750 100 : char *fpath=NULL;
751 : struct stat statp;
752 : while(1)
753 : {
754 100 : free_w(&fpath);
755 100 : if(!(fpath=get_next_fpath(manio, offset)))
756 : goto end;
757 200 : if(lstat(fpath, &statp)) break;
758 0 : if(!S_ISREG(statp.st_mode))
759 : goto end;
760 0 : if(recursive_delete(fpath))
761 : goto end;
762 : }
763 : ret=0;
764 : end:
765 100 : free_w(&fpath);
766 100 : return ret;
767 : }
768 :
769 200 : int manio_close_and_truncate(struct manio **manio,
770 : man_off_t *offset, int compression)
771 : {
772 200 : int ret=-1;
773 200 : errno=0;
774 400 : if(!is_single_file(*manio)
775 100 : && remove_trailing_files(*manio, offset))
776 : goto end;
777 200 : if(manio_close(manio)) goto end;
778 200 : if(fzp_truncate(offset->fpath, FZP_FILE, offset->offset, compression))
779 : {
780 0 : logp("Could not fzp_truncate %s in %s(): %s\n",
781 : offset->fpath, __func__, strerror(errno));
782 0 : goto end;
783 : }
784 : ret=0;
785 : end:
786 200 : return ret;
787 : }
|