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

Generated by: LCOV version 1.10