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