LCOV - code coverage report
Current view: top level - src/server - manio.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 274 332 82.5 %
Date: 2016-02-29 Functions: 33 35 94.3 %

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

Generated by: LCOV version 1.10