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

Generated by: LCOV version 1.10