LCOV - code coverage report
Current view: top level - src/server - manio.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 296 338 87.6 %
Date: 2019-02-24 03:08:19 Functions: 33 34 97.1 %

          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             : {
     556             :         int ars;
     557             :         struct iobuf copy;
     558             :         struct blk *blk;
     559          18 :         if(!(blk=blk_alloc()))
     560             :                 goto error;
     561             : 
     562             :         // Use the most recent stat for the new manifest.
     563          18 :         if(dstmanio)
     564             :         {
     565          18 :                 if(manio_write_sbuf(dstmanio, sb)) goto error;
     566          18 :                 if(dstmanio->protocol==PROTO_1)
     567             :                 {
     568           8 :                         sbuf_free_content(csb);
     569           8 :                         blk_free(&blk);
     570           8 :                         return 0;
     571             :                 }
     572             :         }
     573             : 
     574          10 :         copy.len=csb->path.len;
     575          10 :         copy.cmd=csb->path.cmd;
     576          10 :         if(!(copy.buf=strdup_w(csb->path.buf, __func__)))
     577             :                 goto error;
     578             :         while(1)
     579             :         {
     580          30 :                 if((ars=manio_read_with_blk(srcmanio, csb, blk))<0)
     581             :                         goto error;
     582          30 :                 else if(ars>0)
     583             :                 {
     584             :                         // Finished.
     585           5 :                         sbuf_free_content(csb);
     586           5 :                         blk_free(&blk);
     587           5 :                         iobuf_free_content(&copy);
     588           5 :                         return 1;
     589             :                 }
     590             : 
     591             :                 // Got something.
     592          25 :                 if(iobuf_pathcmp(&csb->path, &copy))
     593             :                 {
     594             :                         // Found the next entry.
     595           5 :                         iobuf_free_content(&copy);
     596           5 :                         blk_free(&blk);
     597           5 :                         return 0;
     598             :                 }
     599          20 :                 if(dstmanio)
     600             :                 {
     601          20 :                         if(!dstmanio->fzp
     602           0 :                           && manio_open_next_fpath(dstmanio))
     603             :                                 goto error;
     604             : 
     605          20 :                         if(csb->endfile.buf)
     606             :                         {
     607          10 :                                 if(iobuf_send_msg_fzp(&csb->endfile,
     608             :                                         dstmanio->fzp)) goto error;
     609             :                         }
     610             :                         else
     611             :                         {
     612             :                                 // Should have the next signature.
     613             :                                 // Write it to the destination manifest.
     614          10 :                                 if(manio_write_sig_and_path(dstmanio, blk))
     615             :                                         goto error;
     616             :                         }
     617             :                 }
     618             :         }
     619             : 
     620             : error:
     621           0 :         blk_free(&blk);
     622           0 :         iobuf_free_content(&copy);
     623           0 :         return -1;
     624             : }
     625             : 
     626           0 : int manio_forward_through_sigs(struct sbuf *csb, struct manio *manio)
     627             : {
     628             :         // Call manio_copy_entry with nothing to write to, so
     629             :         // that we forward through the sigs in manio.
     630           0 :         return manio_copy_entry(csb, NULL, manio, NULL);
     631             : }
     632             : 
     633       12990 : man_off_t *manio_tell(struct manio *manio)
     634             : {
     635       12990 :         man_off_t *offset=NULL;
     636       12990 :         if(!manio->fzp)
     637             :         {
     638           0 :                 logp("%s called on null fzp\n", __func__);
     639           0 :                 if(manio->offset && manio->offset->fpath)
     640           0 :                         logp("manio->offset->fpath: %s\n",
     641             :                                 manio->offset->fpath);
     642             :                 goto error;
     643             :         }
     644       12990 :         if(!(offset=man_off_t_alloc())
     645       12990 :           || !(offset->fpath=strdup_w(manio->offset->fpath, __func__))
     646       12990 :           || (offset->offset=fzp_tell(manio->fzp))<0)
     647             :                 goto error;
     648       12990 :         offset->fcount=manio->offset->fcount;
     649       12990 :         return offset;
     650             : error:
     651           0 :         man_off_t_free(&offset);
     652           0 :         return NULL;
     653             : }
     654             : 
     655         246 : int manio_seek(struct manio *manio, man_off_t *offset)
     656             : {
     657         246 :         fzp_close(&manio->fzp);
     658         246 :         if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode))
     659         246 :           || fzp_seek(manio->fzp, offset->offset, SEEK_SET))
     660             :                 return -1;
     661         492 :         man_off_t_free_content(manio->offset);
     662         246 :         if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__)))
     663             :                 return -1;
     664         246 :         manio->offset->offset=offset->offset;
     665         246 :         manio->offset->fcount=offset->fcount;
     666         246 :         return 0;
     667             : }
     668             : 
     669         100 : static int remove_trailing_files(struct manio *manio, man_off_t *offset)
     670             : {
     671         100 :         int ret=-1;
     672         100 :         char *fpath=NULL;
     673             :         struct stat statp;
     674             :         while(1)
     675             :         {
     676         100 :                 free_w(&fpath);
     677         100 :                 if(!(fpath=get_next_fpath(manio, offset)))
     678             :                         goto end;
     679         200 :                 if(lstat(fpath, &statp)) break;
     680           0 :                 if(!S_ISREG(statp.st_mode))
     681             :                         goto end;
     682           0 :                 if(recursive_delete(fpath))
     683             :                         goto end;
     684             :         }
     685             :         ret=0;
     686             : end:
     687         100 :         free_w(&fpath);
     688         100 :         return ret;
     689             : }
     690             : 
     691         200 : int manio_close_and_truncate(struct manio **manio,
     692             :         man_off_t *offset, int compression)
     693             : {
     694         200 :         int ret=-1;
     695         200 :         errno=0;
     696         400 :         if(!is_single_file(*manio)
     697         100 :           && remove_trailing_files(*manio, offset))
     698             :                 goto end;
     699         200 :         if(manio_close(manio)) goto end;
     700         200 :         if(fzp_truncate(offset->fpath, FZP_FILE, offset->offset, compression))
     701             :         {
     702           0 :                 logp("Could not fzp_truncate %s in %s(): %s\n",
     703             :                         offset->fpath, __func__, strerror(errno));
     704           0 :                 goto end;
     705             :         }
     706             :         ret=0;
     707             : end:
     708         200 :         return ret;
     709             : }

Generated by: LCOV version 1.13