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 13992 : free_w(&offset->fpath);
20 13992 : free_w(&offset->ppath);
21 : }
22 :
23 14020 : void man_off_t_free(man_off_t **offset)
24 : {
25 14020 : if(!offset || !*offset) return;
26 27492 : man_off_t_free_content(*offset);
27 13746 : free_v((void **)offset);
28 : }
29 :
30 : static man_off_t *man_off_t_alloc(void)
31 : {
32 13746 : 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 1610 : return manio->protocol==PROTO_1 || manio->phase==1;
58 : }
59 :
60 1078 : static char *get_next_fpath(struct manio *manio, man_off_t *offset)
61 : {
62 : static char tmp[32];
63 2156 : if(is_single_file(manio))
64 430 : 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 978 : static int manio_open_next_fpath(struct manio *manio)
70 : {
71 : static struct stat statp;
72 978 : man_off_t *offset=manio->offset;
73 :
74 978 : free_w(&offset->ppath);
75 978 : offset->ppath=offset->fpath;
76 978 : if(!(offset->fpath=get_next_fpath(manio, offset)))
77 : return -1;
78 :
79 978 : if(!strcmp(manio->mode, MANIO_MODE_READ)
80 1210 : && lstat(offset->fpath, &statp))
81 : return 0;
82 :
83 818 : if(build_path_w(offset->fpath))
84 : return -1;
85 818 : switch(manio->phase)
86 : {
87 : case 2:
88 630 : if(!(manio->fzp=fzp_open(offset->fpath,
89 630 : manio->mode))) return -1;
90 630 : 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 46 : static int manio_open_last_fpath(struct manio *manio)
101 : {
102 46 : int max=-1;
103 92 : if(is_single_file(manio))
104 10 : 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 756 : return (struct manio *)calloc_w(1, sizeof(struct manio), __func__);
115 : }
116 :
117 756 : static struct manio *do_manio_open(const char *manifest, const char *mode,
118 : enum protocol protocol, int phase)
119 : {
120 756 : struct manio *manio=NULL;
121 756 : if(!(manio=manio_alloc())
122 756 : || !(manio->manifest=strdup_w(manifest, __func__))
123 756 : || !(manio->mode=strdup_w(mode, __func__))
124 1512 : || !(manio->offset=man_off_t_alloc()))
125 : goto error;
126 756 : manio->protocol=protocol;
127 756 : manio->phase=phase;
128 756 : if(!strcmp(manio->mode, MANIO_MODE_APPEND))
129 : {
130 46 : 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 46 : if(manio_open_last_fpath(manio))
138 : goto error;
139 : }
140 : else
141 : {
142 710 : if(manio_open_next_fpath(manio))
143 : goto error;
144 : }
145 756 : return manio;
146 : error:
147 0 : manio_close(&manio);
148 0 : return NULL;
149 : }
150 :
151 39 : struct manio *manio_open(const char *manifest, const char *mode,
152 : enum protocol protocol)
153 : {
154 39 : 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 554 : struct manio *manio_open_phase2(const char *manifest, const char *mode,
164 : enum protocol protocol)
165 : {
166 554 : 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 756 : static void manio_free_content(struct manio *manio)
195 : {
196 756 : if(!manio) return;
197 756 : man_off_t_free(&manio->offset);
198 756 : free_w(&manio->manifest);
199 756 : free_w(&manio->mode);
200 756 : free_w(&manio->rmanifest);
201 756 : free_w(&manio->hook_dir);
202 756 : free_v((void **)&manio->hook_sort);
203 756 : free_w(&manio->dindex_dir);
204 756 : free_v((void **)&manio->dindex_sort);
205 756 : 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 1085 : static int sort_and_write_hooks(struct manio *manio)
295 : {
296 : int i;
297 1085 : int ret=-1;
298 1085 : struct fzp *fzp=NULL;
299 1085 : char msg[32]="";
300 1085 : char *path=NULL;
301 1085 : int hook_count=manio->hook_count;
302 1085 : uint64_t *hook_sort=manio->hook_sort;
303 1085 : 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 1085 : static int sort_and_write_dindex(struct manio *manio)
339 : {
340 : int i;
341 1085 : int ret=-1;
342 1085 : struct fzp *fzp=NULL;
343 1085 : char msg[32]="";
344 1085 : char *path=NULL;
345 : struct iobuf wbuf;
346 : struct blk blk;
347 1085 : int dindex_count=manio->dindex_count;
348 1085 : uint64_t *dindex_sort=manio->dindex_sort;
349 1085 : 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 1085 : static int sort_and_write_hooks_and_dindex(struct manio *manio)
384 : {
385 1085 : return sort_and_write_hooks(manio)
386 1085 : || sort_and_write_dindex(manio);
387 : }
388 :
389 924 : int manio_close(struct manio **manio)
390 : {
391 924 : int ret=0;
392 : // int fd;
393 924 : if(!manio || !*manio) return ret;
394 756 : 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 756 : if(fzp_close(&((*manio)->fzp)))
413 0 : ret=-1;
414 756 : sync();
415 756 : manio_free_content(*manio);
416 756 : free_v((void **)manio);
417 756 : return ret;
418 : }
419 :
420 : // Return -1 for error, 0 for stuff read OK, 1 for end of files.
421 115436 : int manio_read_with_blk(struct manio *manio, struct sbuf *sb, struct blk *blk)
422 : {
423 : while(1)
424 : {
425 115594 : if(!manio->fzp)
426 : {
427 179 : if(manio_open_next_fpath(manio)) goto error;
428 179 : 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 54944 : int manio_read(struct manio *manio, struct sbuf *sb)
451 : {
452 54944 : 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 : // Return -1 on error, 0 on OK, 1 for srcmanio finished.
553 18 : int manio_copy_entry(struct sbuf *csb, struct sbuf *sb,
554 : struct manio *srcmanio, struct manio *dstmanio,
555 : const char *seed_src, const char *seed_dst)
556 : {
557 : int ars;
558 : struct iobuf copy1;
559 : struct iobuf copy2;
560 : struct blk *blk;
561 18 : memset(©1, 0, sizeof(copy1));
562 18 : memset(©2, 0, sizeof(copy2));
563 18 : if(!(blk=blk_alloc()))
564 : goto error;
565 :
566 : // Use the most recent stat for the new manifest.
567 18 : if(dstmanio)
568 : {
569 18 : int e=0;
570 : struct iobuf save1;
571 : struct iobuf save2;
572 18 : memset(&save1, 0, sizeof(save1));
573 18 : memset(&save2, 0, sizeof(save2));
574 :
575 : // When seeding, adjust the prefixes, but we need to remember
576 : // the original too.
577 18 : if(seed_src && seed_dst)
578 : {
579 0 : char *tmp=sb->path.buf+strlen(seed_src);
580 0 : if(!(copy1.buf=strdup_w(seed_dst, __func__)))
581 : goto error;
582 0 : if(astrcat(©1.buf, "/", __func__))
583 : goto error;
584 0 : if(*tmp=='/')
585 0 : tmp++;
586 0 : if(astrcat(©1.buf, tmp, __func__))
587 : goto error;
588 0 : copy1.len=strlen(copy1.buf);
589 0 : copy1.cmd=sb->path.cmd;
590 :
591 0 : if(sb->protocol1 && sb->protocol1->datapth.buf
592 0 : && !strncmp(sb->protocol1->datapth.buf,
593 : TREE_DIR, strlen(TREE_DIR)))
594 : {
595 0 : tmp=sb->protocol1->datapth.buf
596 : +strlen(TREE_DIR)
597 0 : +strlen(seed_src);
598 0 : if(*tmp=='/')
599 0 : tmp++;
600 0 : if(!(copy2.buf=strdup_w(TREE_DIR, __func__)))
601 : goto error;
602 0 : if(*seed_dst!='/'
603 0 : && astrcat(©2.buf, "/", __func__))
604 : goto error;
605 0 : if(astrcat(©2.buf, seed_dst, __func__)
606 0 : || astrcat(©2.buf, "/", __func__)
607 0 : || astrcat(©2.buf, tmp, __func__))
608 : goto error;
609 0 : copy2.len=strlen(copy2.buf);
610 0 : copy2.cmd=sb->protocol1->datapth.cmd;
611 : }
612 :
613 0 : save1=sb->path;
614 0 : sb->path=copy1;
615 :
616 0 : if(copy2.buf)
617 : {
618 0 : save2=sb->protocol1->datapth;
619 0 : sb->protocol1->datapth=copy2;
620 : }
621 : }
622 18 : e=manio_write_sbuf(dstmanio, sb);
623 18 : if(copy1.buf)
624 : {
625 0 : sb->path=save1;
626 0 : iobuf_free_content(©1);
627 : }
628 18 : if(copy2.buf)
629 : {
630 0 : sb->protocol1->datapth=save2;
631 0 : iobuf_free_content(©2);
632 : }
633 18 : if(e)
634 : goto error;
635 :
636 18 : if(dstmanio->protocol==PROTO_1)
637 : {
638 8 : sbuf_free_content(csb);
639 8 : blk_free(&blk);
640 8 : return 0;
641 : }
642 : }
643 :
644 10 : copy1.len=csb->path.len;
645 10 : copy1.cmd=csb->path.cmd;
646 10 : if(!(copy1.buf=strdup_w(csb->path.buf, __func__)))
647 : goto error;
648 : while(1)
649 : {
650 30 : if((ars=manio_read_with_blk(srcmanio, csb, blk))<0)
651 : goto error;
652 30 : else if(ars>0)
653 : {
654 : // Finished.
655 5 : sbuf_free_content(csb);
656 5 : blk_free(&blk);
657 5 : iobuf_free_content(©1);
658 5 : return 1;
659 : }
660 :
661 : // Got something.
662 25 : if(iobuf_pathcmp(&csb->path, ©1))
663 : {
664 : // Found the next entry.
665 5 : iobuf_free_content(©1);
666 5 : blk_free(&blk);
667 5 : return 0;
668 : }
669 20 : if(dstmanio)
670 : {
671 20 : if(!dstmanio->fzp
672 0 : && manio_open_next_fpath(dstmanio))
673 : goto error;
674 :
675 20 : if(csb->endfile.buf)
676 : {
677 10 : if(iobuf_send_msg_fzp(&csb->endfile,
678 : dstmanio->fzp)) goto error;
679 : }
680 : else
681 : {
682 : // Should have the next signature.
683 : // Write it to the destination manifest.
684 10 : if(manio_write_sig_and_path(dstmanio, blk))
685 : goto error;
686 : }
687 : }
688 : }
689 :
690 : error:
691 0 : blk_free(&blk);
692 0 : iobuf_free_content(©1);
693 0 : iobuf_free_content(©2);
694 0 : return -1;
695 : }
696 :
697 0 : int manio_forward_through_sigs(struct sbuf *csb, struct manio *manio)
698 : {
699 : // Call manio_copy_entry with nothing to write to, so
700 : // that we forward through the sigs in manio.
701 0 : return manio_copy_entry(csb, NULL, manio, NULL, NULL, NULL);
702 : }
703 :
704 12990 : man_off_t *manio_tell(struct manio *manio)
705 : {
706 12990 : man_off_t *offset=NULL;
707 12990 : if(!manio->fzp)
708 : {
709 0 : logp("%s called on null fzp\n", __func__);
710 0 : if(manio->offset && manio->offset->fpath)
711 0 : logp("manio->offset->fpath: %s\n",
712 : manio->offset->fpath);
713 : goto error;
714 : }
715 12990 : if(!(offset=man_off_t_alloc())
716 12990 : || !(offset->fpath=strdup_w(manio->offset->fpath, __func__))
717 12990 : || (offset->offset=fzp_tell(manio->fzp))<0)
718 : goto error;
719 12990 : offset->fcount=manio->offset->fcount;
720 12990 : return offset;
721 : error:
722 0 : man_off_t_free(&offset);
723 0 : return NULL;
724 : }
725 :
726 246 : int manio_seek(struct manio *manio, man_off_t *offset)
727 : {
728 246 : fzp_close(&manio->fzp);
729 246 : if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode))
730 246 : || fzp_seek(manio->fzp, offset->offset, SEEK_SET))
731 : return -1;
732 492 : man_off_t_free_content(manio->offset);
733 246 : if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__)))
734 : return -1;
735 246 : manio->offset->offset=offset->offset;
736 246 : manio->offset->fcount=offset->fcount;
737 246 : return 0;
738 : }
739 :
740 100 : static int remove_trailing_files(struct manio *manio, man_off_t *offset)
741 : {
742 100 : int ret=-1;
743 100 : char *fpath=NULL;
744 : struct stat statp;
745 : while(1)
746 : {
747 100 : free_w(&fpath);
748 100 : if(!(fpath=get_next_fpath(manio, offset)))
749 : goto end;
750 200 : if(lstat(fpath, &statp)) break;
751 0 : if(!S_ISREG(statp.st_mode))
752 : goto end;
753 0 : if(recursive_delete(fpath))
754 : goto end;
755 : }
756 : ret=0;
757 : end:
758 100 : free_w(&fpath);
759 100 : return ret;
760 : }
761 :
762 200 : int manio_close_and_truncate(struct manio **manio,
763 : man_off_t *offset, int compression)
764 : {
765 200 : int ret=-1;
766 200 : errno=0;
767 400 : if(!is_single_file(*manio)
768 100 : && remove_trailing_files(*manio, offset))
769 : goto end;
770 200 : if(manio_close(manio)) goto end;
771 200 : if(fzp_truncate(offset->fpath, FZP_FILE, offset->offset, compression))
772 : {
773 0 : logp("Could not fzp_truncate %s in %s(): %s\n",
774 : offset->fpath, __func__, strerror(errno));
775 0 : goto end;
776 : }
777 : ret=0;
778 : end:
779 200 : return ret;
780 : }
|