LCOV - code coverage report
Current view: top level - src/server - manio.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 114 195 58.5 %
Date: 2022-08-30 22:36:43 Functions: 16 18 88.9 %

          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 "../sbuf.h"
      11             : #include "manio.h"
      12             : 
      13             : static void man_off_t_free_content(man_off_t *offset)
      14             : {
      15         123 :         if(!offset) return;
      16        7829 :         free_w(&offset->fpath);
      17        7829 :         free_w(&offset->ppath);
      18             : }
      19             : 
      20        7846 : void man_off_t_free(man_off_t **offset)
      21             : {
      22        7846 :         if(!offset || !*offset) return;
      23       15412 :         man_off_t_free_content(*offset);
      24        7706 :         free_v((void **)offset);
      25             : }
      26             : 
      27             : static man_off_t *man_off_t_alloc(void)
      28             : {
      29        7706 :         return (man_off_t *)calloc_w(1, sizeof(man_off_t), __func__);
      30             : }
      31             : 
      32             : static char *get_next_fpath(struct manio *manio, man_off_t *offset)
      33             : {
      34         363 :         return strdup_w(manio->manifest, __func__);
      35             : }
      36             : 
      37         363 : static int manio_open_next_fpath(struct manio *manio)
      38             : {
      39             :         static struct stat statp;
      40         363 :         man_off_t *offset=manio->offset;
      41             : 
      42         363 :         free_w(&offset->ppath);
      43         363 :         offset->ppath=offset->fpath;
      44         726 :         if(!(offset->fpath=get_next_fpath(manio, offset)))
      45             :                 return -1;
      46             : 
      47         363 :         if(!strcmp(manio->mode, MANIO_MODE_READ)
      48         410 :           && lstat(offset->fpath, &statp))
      49             :                 return 0;
      50             : 
      51         351 :         if(build_path_w(offset->fpath))
      52             :                 return -1;
      53         351 :         switch(manio->phase)
      54             :         {
      55             :                 case 2:
      56         273 :                         if(!(manio->fzp=fzp_open(offset->fpath,
      57         273 :                                 manio->mode))) return -1;
      58         273 :                         return 0;
      59             :                 case 1:
      60             :                 case 3:
      61             :                 default:
      62          78 :                         if(!(manio->fzp=fzp_gzopen(offset->fpath,
      63          78 :                                 manio->mode))) return -1;
      64          78 :                         return 0;
      65             :         }
      66             : }
      67             : 
      68             : static int manio_open_last_fpath(struct manio *manio)
      69             : {
      70          20 :         return manio_open_next_fpath(manio);
      71             : }
      72             : 
      73             : static struct manio *manio_alloc(void)
      74             : {
      75         357 :         return (struct manio *)calloc_w(1, sizeof(struct manio), __func__);
      76             : }
      77             : 
      78         357 : static struct manio *do_manio_open(const char *manifest, const char *mode,
      79             :         int phase)
      80             : {
      81         357 :         struct manio *manio=NULL;
      82         357 :         if(!(manio=manio_alloc())
      83         357 :           || !(manio->manifest=strdup_w(manifest, __func__))
      84         357 :           || !(manio->mode=strdup_w(mode, __func__))
      85         714 :           || !(manio->offset=man_off_t_alloc()))
      86             :                 goto error;
      87         357 :         manio->phase=phase;
      88         357 :         if(!strcmp(manio->mode, MANIO_MODE_APPEND))
      89             :         {
      90          20 :                 if(manio->phase!=2)
      91             :                 {
      92           0 :                         logp("manio append mode only works for phase 2.\n");
      93           0 :                         logp("%s has phase: %d\n",
      94           0 :                                 manio->manifest, manio->phase);
      95           0 :                         goto error;
      96             :                 }
      97          40 :                 if(manio_open_last_fpath(manio))
      98             :                         goto error;
      99             :         }
     100             :         else
     101             :         {
     102         337 :                 if(manio_open_next_fpath(manio))
     103             :                         goto error;
     104             :         }
     105         357 :         return manio;
     106             : error:
     107           0 :         manio_close(&manio);
     108           0 :         return NULL;
     109             : }
     110             : 
     111          12 : struct manio *manio_open(const char *manifest, const char *mode)
     112             : {
     113          12 :         return do_manio_open(manifest, mode, 0);
     114             : }
     115             : 
     116          63 : struct manio *manio_open_phase1(const char *manifest, const char *mode)
     117             : {
     118          63 :         return do_manio_open(manifest, mode, 1);
     119             : }
     120             : 
     121         273 : struct manio *manio_open_phase2(const char *manifest, const char *mode)
     122             : {
     123         273 :         return do_manio_open(manifest, mode, 2);
     124             : }
     125             : 
     126           9 : struct manio *manio_open_phase3(const char *manifest, const char *mode,
     127             :         const char *rmanifest)
     128             : {
     129           9 :         return do_manio_open(manifest, mode, 3);
     130             : }
     131             : 
     132         357 : static void manio_free_content(struct manio *manio)
     133             : {
     134         357 :         if(!manio) return;
     135         357 :         man_off_t_free(&manio->offset);
     136         357 :         free_w(&manio->manifest);
     137         357 :         free_w(&manio->mode);
     138         357 :         free_w(&manio->rmanifest);
     139         357 :         free_w(&manio->hook_dir);
     140         357 :         free_v((void **)&manio->hook_sort);
     141         357 :         free_w(&manio->dindex_dir);
     142         357 :         free_v((void **)&manio->dindex_sort);
     143         357 :         memset(manio, 0, sizeof(struct manio));
     144             : }
     145             : 
     146             : static char *get_fcount_path(struct manio *manio)
     147             : {
     148           0 :         return prepend_s(manio->manifest, "fcount");
     149             : }
     150             : 
     151           0 : int manio_read_fcount(struct manio *manio)
     152             : {
     153           0 :         int ret=-1;
     154             :         size_t s;
     155           0 :         struct fzp *fzp=NULL;
     156           0 :         char *path=NULL;
     157           0 :         char buf[16]="";
     158           0 :         if(!(path=get_fcount_path(manio))
     159           0 :           || !(fzp=fzp_open(path, "rb")))
     160             :                 goto end;
     161           0 :         if(!fzp_gets(fzp, buf, sizeof(buf)))
     162             :         {
     163           0 :                 logp("fzp_gets on %s failed\n", path);
     164           0 :                 goto end;
     165             :         }
     166           0 :         s=strlen(buf);
     167           0 :         if(s!=9)
     168             :         {
     169           0 :                 logp("data in %s is not the right length (%lu!=9)\n", path,
     170             :                         (unsigned long)s);
     171           0 :                 goto end;
     172             :         }
     173           0 :         manio->offset->fcount=strtoul(buf, NULL, 16);
     174           0 :         ret=0;
     175             : end:
     176           0 :         fzp_close(&fzp);
     177           0 :         free_w(&path);
     178           0 :         return ret;
     179             : }
     180             : 
     181         430 : int manio_close(struct manio **manio)
     182             : {
     183         430 :         int ret=0;
     184             : //      int fd;
     185         430 :         if(!manio || !*manio) return ret;
     186             : /*
     187             :         There is no gzfileno()
     188             :         if((fd=fzp_fileno((*manio)->fzp))<0)
     189             :         {
     190             :                 logp("Could not get fileno in %s for %s: %s\n", __func__,
     191             :                         (*manio)->manifest, strerror(errno));
     192             :                 ret=-1;
     193             :         }
     194             :         // Should probably have a flush before fsync too.
     195             :         if(fsync(fd))
     196             :         {
     197             :                 logp("Error in fsync in %s for %s: %s\n", __func__,
     198             :                         (*manio)->manifest, strerror(errno));
     199             :                 ret=-1;
     200             :         }
     201             : */
     202         357 :         if(fzp_close(&((*manio)->fzp)))
     203           0 :                 ret=-1;
     204         357 :         sync();
     205         357 :         manio_free_content(*manio);
     206         357 :         free_v((void **)manio);
     207         357 :         return ret;
     208             : }
     209             : 
     210             : // Return -1 for error, 0 for stuff read OK, 1 for end of files.
     211       13581 : int manio_read(struct manio *manio, struct sbuf *sb)
     212             : {
     213             :         while(1)
     214             :         {
     215       13581 :                 if(!manio->fzp)
     216             :                 {
     217           6 :                         if(manio_open_next_fpath(manio)) goto error;
     218           6 :                         if(!manio->fzp) return 1; // No more files to read.
     219             :                 }
     220             : 
     221       13575 :                 switch(sbuf_fill_from_file(sb, manio->fzp))
     222             :                 {
     223             :                         case 0: return 0; // Got something.
     224             :                         case 1: break; // Keep going.
     225             :                         default: goto error; // Error.
     226             :                 }
     227             : 
     228             :                 // Reached the end of the current file.
     229             :                 // Maybe there is another file to continue with.
     230         107 :                 if(fzp_close(&manio->fzp)) goto error;
     231             :                 return 1;
     232             :         }
     233             : 
     234             : error:
     235             :         return -1;
     236             : }
     237             : 
     238       11932 : int manio_write_sbuf(struct manio *manio, struct sbuf *sb)
     239             : {
     240       11932 :         if(!manio->fzp && manio_open_next_fpath(manio)) return -1;
     241       11932 :         return sbuf_to_manifest(sb, manio->fzp);
     242             : }
     243             : 
     244          84 : int manio_write_cntr(struct manio *manio, struct sbuf *sb,
     245             :         enum cntr_manio what)
     246             : {
     247          84 :         if(!manio->fzp && manio_open_next_fpath(manio)) return -1;
     248          84 :         return sbuf_to_manifest_cntr(sb, manio->fzp, what);
     249             : }
     250             : 
     251             : // Return -1 on error, 0 on OK, 1 for srcmanio finished.
     252           8 : int manio_copy_entry(struct sbuf *csb, struct sbuf *sb,
     253             :         struct manio *srcmanio, struct manio *dstmanio,
     254             :         const char *seed_src, const char *seed_dst)
     255             : {
     256             :         int ars;
     257             :         struct iobuf copy1;
     258             :         struct iobuf copy2;
     259           8 :         memset(&copy1, 0, sizeof(copy1));
     260           8 :         memset(&copy2, 0, sizeof(copy2));
     261             : 
     262             :         // Use the most recent stat for the new manifest.
     263           8 :         if(dstmanio)
     264             :         {
     265           8 :                 int e=0;
     266             :                 struct iobuf save1;
     267             :                 struct iobuf save2;
     268           8 :                 memset(&save1, 0, sizeof(save1));
     269           8 :                 memset(&save2, 0, sizeof(save2));
     270             :         
     271             :                 // When seeding, adjust the prefixes, but we need to remember
     272             :                 // the original too.
     273           8 :                 if(seed_src && seed_dst)
     274             :                 {
     275           0 :                         char *tmp=sb->path.buf+strlen(seed_src);
     276           0 :                         if(!(copy1.buf=strdup_w(seed_dst, __func__)))
     277             :                                 goto error;
     278           0 :                         if(astrcat(&copy1.buf, "/", __func__))
     279             :                                 goto error;
     280           0 :                         if(*tmp=='/')
     281           0 :                                 tmp++;
     282           0 :                         if(astrcat(&copy1.buf, tmp, __func__))
     283             :                                 goto error;
     284           0 :                         copy1.len=strlen(copy1.buf);
     285           0 :                         copy1.cmd=sb->path.cmd;
     286             : 
     287           0 :                         if(sb->datapth.buf
     288           0 :                           && !strncmp(sb->datapth.buf,
     289             :                                 TREE_DIR, strlen(TREE_DIR)))
     290             :                         {
     291           0 :                                 tmp=sb->datapth.buf
     292             :                                         +strlen(TREE_DIR)
     293           0 :                                         +strlen(seed_src);
     294           0 :                                 if(*tmp=='/')
     295           0 :                                         tmp++;
     296           0 :                                 if(!(copy2.buf=strdup_w(TREE_DIR, __func__)))
     297             :                                         goto error;
     298           0 :                                 if(*seed_dst!='/'
     299           0 :                                   && astrcat(&copy2.buf, "/", __func__))
     300             :                                         goto error;
     301           0 :                                 if(astrcat(&copy2.buf, seed_dst, __func__)
     302           0 :                                   || astrcat(&copy2.buf, "/", __func__)
     303           0 :                                   || astrcat(&copy2.buf, tmp, __func__))
     304             :                                         goto error;
     305           0 :                                 copy2.len=strlen(copy2.buf);
     306           0 :                                 copy2.cmd=sb->datapth.cmd;
     307             :                         }
     308             : 
     309           0 :                         save1=sb->path;
     310           0 :                         sb->path=copy1;
     311             : 
     312           0 :                         if(copy2.buf)
     313             :                         {
     314           0 :                                 save2=sb->datapth;
     315           0 :                                 sb->datapth=copy2;
     316             :                         }
     317             :                 }
     318           8 :                 e=manio_write_sbuf(dstmanio, sb);
     319           8 :                 if(copy1.buf)
     320             :                 {
     321           0 :                         sb->path=save1;
     322           0 :                         iobuf_free_content(&copy1);
     323             :                 }
     324           8 :                 if(copy2.buf)
     325             :                 {
     326           0 :                         sb->datapth=save2;
     327           0 :                         iobuf_free_content(&copy2);
     328             :                 }
     329           8 :                 if(e)
     330             :                         goto error;
     331             : 
     332           8 :                 sbuf_free_content(csb);
     333           8 :                 return 0;
     334             :         }
     335             : 
     336           0 :         copy1.len=csb->path.len;
     337           0 :         copy1.cmd=csb->path.cmd;
     338           0 :         if(!(copy1.buf=strdup_w(csb->path.buf, __func__)))
     339             :                 goto error;
     340             :         while(1)
     341             :         {
     342           0 :                 if((ars=manio_read(srcmanio, csb))<0)
     343             :                         goto error;
     344           0 :                 else if(ars>0)
     345             :                 {
     346             :                         // Finished.
     347           0 :                         sbuf_free_content(csb);
     348           0 :                         iobuf_free_content(&copy1);
     349           0 :                         return 1;
     350             :                 }
     351             : 
     352             :                 // Got something.
     353           0 :                 if(iobuf_pathcmp(&csb->path, &copy1))
     354             :                 {
     355             :                         // Found the next entry.
     356           0 :                         iobuf_free_content(&copy1);
     357           0 :                         return 0;
     358             :                 }
     359             :                 if(dstmanio)
     360             :                 {
     361             :                         if(!dstmanio->fzp
     362             :                           && manio_open_next_fpath(dstmanio))
     363             :                                 goto error;
     364             : 
     365             :                         if(csb->endfile.buf)
     366             :                         {
     367             :                                 if(iobuf_send_msg_fzp(&csb->endfile,
     368             :                                         dstmanio->fzp)) goto error;
     369             :                         }
     370             :                 }
     371             :         }
     372             : 
     373             : error:
     374           0 :         iobuf_free_content(&copy1);
     375           0 :         iobuf_free_content(&copy2);
     376           0 :         return -1;
     377             : }
     378             : 
     379           0 : int manio_forward_through_sigs(struct sbuf *csb, struct manio *manio)
     380             : {
     381             :         // Call manio_copy_entry with nothing to write to, so
     382             :         // that we forward through the sigs in manio.
     383           0 :         return manio_copy_entry(csb, NULL, manio, NULL, NULL, NULL);
     384             : }
     385             : 
     386        7349 : man_off_t *manio_tell(struct manio *manio)
     387             : {
     388        7349 :         man_off_t *offset=NULL;
     389        7349 :         if(!manio->fzp)
     390             :         {
     391           0 :                 logp("%s called on null fzp\n", __func__);
     392           0 :                 if(manio->offset && manio->offset->fpath)
     393           0 :                         logp("manio->offset->fpath: %s\n",
     394             :                                 manio->offset->fpath);
     395             :                 goto error;
     396             :         }
     397        7349 :         if(!(offset=man_off_t_alloc())
     398        7349 :           || !(offset->fpath=strdup_w(manio->offset->fpath, __func__))
     399        7349 :           || (offset->offset=fzp_tell(manio->fzp))<0)
     400             :                 goto error;
     401        7349 :         offset->fcount=manio->offset->fcount;
     402        7349 :         return offset;
     403             : error:
     404           0 :         man_off_t_free(&offset);
     405           0 :         return NULL;
     406             : }
     407             : 
     408         123 : int manio_seek(struct manio *manio, man_off_t *offset)
     409             : {
     410         123 :         fzp_close(&manio->fzp);
     411         123 :         if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode))
     412         123 :           || fzp_seek(manio->fzp, offset->offset, SEEK_SET))
     413             :                 return -1;
     414         246 :         man_off_t_free_content(manio->offset);
     415         123 :         if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__)))
     416             :                 return -1;
     417         123 :         manio->offset->offset=offset->offset;
     418         123 :         manio->offset->fcount=offset->fcount;
     419         123 :         return 0;
     420             : }
     421             : 
     422         100 : int manio_close_and_truncate(struct manio **manio,
     423             :         man_off_t *offset, int compression)
     424             : {
     425         100 :         int ret=-1;
     426         100 :         errno=0;
     427         100 :         if(manio_close(manio)) goto end;
     428         100 :         if(fzp_truncate(offset->fpath, FZP_FILE, offset->offset, compression))
     429             :         {
     430           0 :                 logp("Could not fzp_truncate %s in %s(): %s\n",
     431             :                         offset->fpath, __func__, strerror(errno));
     432           0 :                 goto end;
     433             :         }
     434             :         ret=0;
     435             : end:
     436         100 :         return ret;
     437             : }

Generated by: LCOV version 1.13