LCOV - code coverage report
Current view: top level - src/client/protocol1 - backup_phase2.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 198 0.0 %
Date: 2015-10-31 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../action.h"
       3             : #include "../../asfd.h"
       4             : #include "../../async.h"
       5             : #include "../../attribs.h"
       6             : #include "../../cmd.h"
       7             : #include "../../cntr.h"
       8             : #include "../../conf.h"
       9             : #include "../../log.h"
      10             : #include "../../protocol1/handy.h"
      11             : #include "../../protocol1/msg.h"
      12             : #include "../extrameta.h"
      13             : #include "../find.h"
      14             : 
      15           0 : static int load_signature(struct asfd *asfd,
      16             :         rs_signature_t **sumset, struct conf **confs)
      17             : {
      18             :         rs_result r;
      19             :         rs_job_t *job;
      20             : 
      21           0 :         job=rs_loadsig_begin(sumset);
      22           0 :         if((r=rs_loadsig_network_run(asfd, job, get_cntr(confs))))
      23             :         {
      24           0 :                 rs_free_sumset(*sumset);
      25           0 :                 return r;
      26             :         }
      27           0 :         if((r=rs_build_hash_table(*sumset))) return r;
      28           0 :         rs_job_free(job);
      29           0 :         return r;
      30             : }
      31             : 
      32           0 : static int load_signature_and_send_delta(struct asfd *asfd,
      33             :         BFILE *bfd, uint64_t *bytes, uint64_t *sentbytes,
      34             :         struct conf **confs)
      35             : {
      36             :         rs_job_t *job;
      37             :         rs_result r;
      38           0 :         rs_signature_t *sumset=NULL;
      39             :         uint8_t checksum[MD5_DIGEST_LENGTH];
      40           0 :         rs_filebuf_t *infb=NULL;
      41           0 :         rs_filebuf_t *outfb=NULL;
      42             :         rs_buffers_t rsbuf;
      43           0 :         memset(&rsbuf, 0, sizeof(rsbuf));
      44             : 
      45           0 :         if(load_signature(asfd, &sumset, confs)) return -1;
      46             : 
      47           0 :         if(!(job=rs_delta_begin(sumset)))
      48             :         {
      49           0 :                 logp("could not start delta job.\n");
      50           0 :                 rs_free_sumset(sumset);
      51           0 :                 return RS_IO_ERROR;
      52             :         }
      53             : 
      54           0 :         if(!(infb=rs_filebuf_new(asfd, bfd,
      55             :                 NULL, -1, ASYNC_BUF_LEN, bfd->datalen,
      56           0 :                 get_cntr(confs)))
      57           0 :           || !(outfb=rs_filebuf_new(asfd, NULL,
      58             :                 NULL, asfd->fd, ASYNC_BUF_LEN, -1,
      59           0 :                 get_cntr(confs))))
      60             :         {
      61           0 :                 logp("could not rs_filebuf_new for delta\n");
      62           0 :                 rs_filebuf_free(&infb);
      63           0 :                 return -1;
      64             :         }
      65             : 
      66             :         while(1)
      67             :         {
      68             :                 rs_result delresult;
      69           0 :                 delresult=rs_async(job, &rsbuf, infb, outfb);
      70           0 :                 if(delresult==RS_DONE)
      71             :                 {
      72           0 :                         r=delresult;
      73           0 :                         break;
      74             :                 }
      75           0 :                 else if(delresult==RS_BLOCKED || delresult==RS_RUNNING)
      76             :                 {
      77             :                         // Keep going
      78             :                 }
      79             :                 else
      80             :                 {
      81           0 :                         logp("error in rs_async for delta: %d\n", delresult);
      82           0 :                         r=delresult;
      83           0 :                         break;
      84             :                 }
      85             :                 // FIX ME: get it to read stuff (errors, for example) here too.
      86           0 :                 if(asfd->as->write(asfd->as)) return -1;
      87             :         }
      88             : 
      89           0 :         if(r!=RS_DONE)
      90           0 :                 logp("delta loop returned: %d\n", r);
      91             : 
      92           0 :         if(r==RS_DONE)
      93             :         {
      94           0 :                 *bytes=infb->bytes;
      95           0 :                 *sentbytes=outfb->bytes;
      96           0 :                 if(!MD5_Final(checksum, &(infb->md5)))
      97             :                 {
      98           0 :                         logp("MD5_Final() failed\n");
      99           0 :                         r=RS_IO_ERROR;
     100             :                 }
     101             :         }
     102           0 :         rs_filebuf_free(&infb);
     103           0 :         rs_filebuf_free(&outfb);
     104           0 :         rs_job_free(job);
     105           0 :         rs_free_sumset(sumset);
     106             : 
     107           0 :         if(r==RS_DONE && write_endfile(asfd, *bytes, checksum))
     108           0 :                 return -1;
     109             : 
     110           0 :         return r;
     111             : }
     112             : 
     113           0 : static int send_whole_file_w(struct asfd *asfd,
     114             :         struct sbuf *sb, const char *datapth,
     115             :         int quick_read, uint64_t *bytes, const char *encpassword,
     116             :         struct cntr *cntr, int compression, BFILE *bfd,
     117             :         const char *extrameta, size_t elen)
     118             : {
     119           0 :         if((compression || encpassword) && sb->path.cmd!=CMD_EFS_FILE)
     120             :                 return send_whole_file_gzl(asfd,
     121             :                   sb->path.buf, datapth, quick_read, bytes, 
     122           0 :                   encpassword, cntr, compression, bfd, extrameta, elen);
     123             :         else
     124             :                 return send_whole_filel(asfd,
     125             :                   sb->path.cmd, sb->path.buf, datapth, quick_read, bytes, 
     126           0 :                   cntr, bfd, extrameta, elen);
     127             : }
     128             : 
     129           0 : static int forget_file(struct asfd *asfd, struct sbuf *sb, struct conf **confs)
     130             : {
     131             :         // Tell the server to forget about this
     132             :         // file, otherwise it might get stuck
     133             :         // on a select waiting for it to arrive.
     134           0 :         if(asfd->write_str(asfd, CMD_INTERRUPT, sb->path.buf))
     135           0 :                 return 0;
     136             : 
     137           0 :         if(sb->path.cmd==CMD_FILE && sb->protocol1->datapth.buf)
     138             :         {
     139           0 :                 rs_signature_t *sumset=NULL;
     140             :                 // The server will be sending us a signature.
     141             :                 // Munch it up then carry on.
     142           0 :                 if(load_signature(asfd, &sumset, confs)) return -1;
     143           0 :                 else rs_free_sumset(sumset);
     144             :         }
     145           0 :         return 0;
     146             : }
     147             : 
     148           0 : static int size_checks(struct asfd *asfd, struct sbuf *sb, struct conf **confs)
     149             : {
     150           0 :         if(sb->path.cmd!=CMD_FILE
     151           0 :           && sb->path.cmd!=CMD_ENC_FILE
     152           0 :           && sb->path.cmd!=CMD_EFS_FILE)
     153           0 :                 return 0;
     154           0 :         if(get_uint64_t(confs[OPT_MIN_FILE_SIZE])
     155           0 :           && (uint64_t)sb->statp.st_size<get_uint64_t(confs[OPT_MIN_FILE_SIZE]))
     156             :         {
     157           0 :                 logw(asfd, get_cntr(confs), "File size decreased below min_file_size after initial scan: %c:%s\n", sb->path.cmd, sb->path.buf);
     158           0 :                 return -1;
     159             :         }
     160           0 :         if(get_uint64_t(confs[OPT_MAX_FILE_SIZE])
     161           0 :           && (uint64_t)sb->statp.st_size>get_uint64_t(confs[OPT_MAX_FILE_SIZE]))
     162             :         {
     163           0 :                 logw(asfd, get_cntr(confs), "File size increased above max_file_size after initial scan: %c:%s\n", sb->path.cmd, sb->path.buf);
     164           0 :                 return -1;
     165             :         }
     166           0 :         return 0;
     167             : }
     168             : 
     169           0 : static int deal_with_data(struct asfd *asfd, struct sbuf *sb,
     170             :         BFILE *bfd, struct conf **confs)
     171             : {
     172           0 :         int ret=-1;
     173           0 :         int forget=0;
     174           0 :         size_t elen=0;
     175           0 :         char *extrameta=NULL;
     176           0 :         uint64_t bytes=0;
     177           0 :         int conf_compression=get_int(confs[OPT_COMPRESSION]);
     178           0 :         struct cntr *cntr=get_cntr(confs);
     179             : 
     180           0 :         sb->compression=conf_compression;
     181             : 
     182           0 :         iobuf_copy(&sb->path, asfd->rbuf);
     183           0 :         iobuf_init(asfd->rbuf);
     184             : 
     185             : #ifdef HAVE_WIN32
     186             :         if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr))
     187             : #else
     188           0 :         if(lstat(sb->path.buf, &sb->statp))
     189             : #endif
     190             :         {
     191           0 :                 logw(asfd, cntr, "Path has vanished: %s\n", sb->path.buf);
     192           0 :                 if(forget_file(asfd, sb, confs)) goto error;
     193           0 :                 goto end;
     194             :         }
     195             : 
     196           0 :         if(size_checks(asfd, sb, confs)) forget++;
     197             : 
     198           0 :         sb->compression=in_exclude_comp(get_strlist(confs[OPT_EXCOM]),
     199           0 :                 sb->path.buf, conf_compression);
     200           0 :         if(attribs_encode(sb)) goto error;
     201             : 
     202           0 :         if(sb->path.cmd!=CMD_METADATA
     203           0 :           && sb->path.cmd!=CMD_ENC_METADATA)
     204             :         {
     205           0 :                 if(bfd->open_for_send(bfd, asfd,
     206             :                         sb->path.buf, sb->winattr,
     207           0 :                         get_int(confs[OPT_ATIME]), cntr, PROTO_1))
     208           0 :                                 forget++;
     209             :         }
     210             : 
     211           0 :         if(forget)
     212             :         {
     213           0 :                 if(forget_file(asfd, sb, confs)) goto error;
     214           0 :                 goto end;
     215             :         }
     216             : 
     217           0 :         if(sb->path.cmd==CMD_METADATA
     218           0 :           || sb->path.cmd==CMD_ENC_METADATA
     219           0 :           || sb->path.cmd==CMD_VSS
     220           0 :           || sb->path.cmd==CMD_ENC_VSS
     221             : #ifdef HAVE_WIN32
     222             :           || get_int(confs[OPT_STRIP_VSS])
     223             : #endif
     224             :           )
     225             :         {
     226           0 :                 if(get_extrameta(asfd, bfd,
     227           0 :                         sb, &extrameta, &elen, cntr))
     228             :                 {
     229             :                         logw(asfd, cntr,
     230           0 :                                 "Meta data error for %s\n", sb->path.buf);
     231           0 :                         goto end;
     232             :                 }
     233           0 :                 if(extrameta)
     234             :                 {
     235             : #ifdef HAVE_WIN32
     236             :                         if(get_int(confs[OPT_STRIP_VSS]))
     237             :                         {
     238             :                                 free(extrameta);
     239             :                                 extrameta=NULL;
     240             :                                 elen=0;
     241             :                         }
     242             : #endif
     243             :                 }
     244             :                 else
     245             :                 {
     246             :                         logw(asfd, cntr,
     247           0 :                                 "No meta data after all: %s\n", sb->path.buf);
     248           0 :                         goto end;
     249             :                 }
     250             :         }
     251             : 
     252           0 :         if(sb->path.cmd==CMD_FILE
     253           0 :           && sb->protocol1->datapth.buf)
     254             :         {
     255           0 :                 uint64_t sentbytes=0;
     256             :                 // Need to do sig/delta stuff.
     257           0 :                 if(asfd->write(asfd, &(sb->protocol1->datapth))
     258           0 :                   || asfd->write(asfd, &sb->attr)
     259           0 :                   || asfd->write(asfd, &sb->path)
     260           0 :                   || load_signature_and_send_delta(asfd, bfd,
     261           0 :                         &bytes, &sentbytes, confs))
     262             :                 {
     263             :                         logp("error in sig/delta for %s (%s)\n",
     264           0 :                                 sb->path.buf, sb->protocol1->datapth.buf);
     265           0 :                         goto end;
     266             :                 }
     267             :                 else
     268             :                 {
     269           0 :                         cntr_add(get_cntr(confs), CMD_FILE_CHANGED, 1);
     270           0 :                         cntr_add_bytes(get_cntr(confs), bytes);
     271           0 :                         cntr_add_sentbytes(get_cntr(confs), sentbytes);
     272           0 :                 }
     273             :         }
     274             :         else
     275             :         {
     276             :                 //logp("need to send whole file: %s\n", sb.path);
     277             :                 // send the whole file.
     278             : 
     279           0 :                 if((asfd->write(asfd, &sb->attr)
     280           0 :                   || asfd->write(asfd, &sb->path))
     281           0 :                   || send_whole_file_w(asfd, sb, NULL, 0, &bytes,
     282           0 :                         get_string(confs[OPT_ENCRYPTION_PASSWORD]),
     283             :                         cntr, sb->compression,
     284           0 :                         bfd, extrameta, elen))
     285           0 :                                 goto end;
     286             :                 else
     287             :                 {
     288           0 :                         cntr_add(get_cntr(confs), sb->path.cmd, 1);
     289           0 :                         cntr_add_bytes(get_cntr(confs), bytes);
     290           0 :                         cntr_add_sentbytes(get_cntr(confs), bytes);
     291             :                 }
     292             :         }
     293             : 
     294             : end:
     295           0 :         ret=0;
     296             : error:
     297             : #ifdef HAVE_WIN32
     298             :         // If using Windows do not close bfd - it needs
     299             :         // to stay open to read VSS/file data/VSS.
     300             :         // It will get closed either when given a
     301             :         // different file path, or when this function
     302             :         // exits.
     303             : #else
     304           0 :         bfd->close(bfd, asfd);
     305             : #endif
     306           0 :         sbuf_free_content(sb);
     307           0 :         if(extrameta) free(extrameta);
     308           0 :         return ret;
     309             : }
     310             : 
     311           0 : static int parse_rbuf(struct asfd *asfd, struct sbuf *sb,
     312             :         BFILE *bfd, struct conf **confs)
     313             : {
     314             :         static struct iobuf *rbuf;
     315           0 :         rbuf=asfd->rbuf;
     316             :         //printf("now %d: %c:%s\n", rbuf->len, rbuf->cmd, rbuf->buf);
     317           0 :         if(rbuf->cmd==CMD_DATAPTH)
     318             :         {
     319           0 :                 iobuf_move(&(sb->protocol1->datapth), rbuf);
     320             :         }
     321           0 :         else if(rbuf->cmd==CMD_ATTRIBS)
     322             :         {
     323             :                 // Ignore the stat data - we will fill it
     324             :                 // in again. Some time may have passed by now,
     325             :                 // and it is best to make it as fresh as
     326             :                 // possible.
     327             :         }
     328           0 :         else if(iobuf_is_filedata(rbuf)
     329           0 :           || iobuf_is_vssdata(rbuf))
     330             :         {
     331           0 :                 if(deal_with_data(asfd, sb, bfd, confs))
     332           0 :                         return -1;
     333             :         }
     334           0 :         else if(rbuf->cmd==CMD_MESSAGE
     335           0 :           || rbuf->cmd==CMD_WARNING)
     336             :         {
     337           0 :                 struct cntr *cntr=NULL;
     338           0 :                 if(confs) cntr=get_cntr(confs);
     339           0 :                 log_recvd(rbuf, cntr, 0);
     340             :         }
     341             :         else
     342             :         {
     343           0 :                 iobuf_log_unexpected(rbuf, __func__);
     344           0 :                 return -1;
     345             :         }
     346           0 :         return 0;
     347             : }
     348             : 
     349           0 : static int do_backup_phase2_client(struct asfd *asfd,
     350             :         struct conf **confs, int resume)
     351             : {
     352           0 :         int ret=-1;
     353             :         // For efficiency, open Windows files for the VSS data, and do not
     354             :         // close them until another time around the loop, when the actual
     355             :         // data is read.
     356           0 :         BFILE *bfd=NULL;
     357           0 :         struct sbuf *sb=NULL;
     358           0 :         struct iobuf *rbuf=asfd->rbuf;
     359             : 
     360           0 :         if(!(bfd=bfile_alloc())
     361           0 :           || !(sb=sbuf_alloc(PROTO_1)))
     362           0 :                 goto end;
     363           0 :         bfile_init(bfd, 0, get_cntr(confs));
     364             : 
     365           0 :         if(!resume)
     366             :         {
     367             :                 // Only do this bit if the server did not tell us to resume.
     368           0 :                 if(asfd->write_str(asfd, CMD_GEN, "backupphase2")
     369           0 :                   || asfd->read_expect(asfd, CMD_GEN, "ok"))
     370           0 :                         goto end;
     371             :         }
     372           0 :         else if(get_int(confs[OPT_SEND_CLIENT_CNTR]))
     373             :         {
     374             :                 // On resume, the server might update the client with cntr.
     375           0 :                 if(cntr_recv(asfd, confs)) goto end;
     376             :         }
     377             : 
     378             :         while(1)
     379             :         {
     380           0 :                 iobuf_free_content(rbuf);
     381           0 :                 if(asfd->read(asfd)) goto end;
     382           0 :                 else if(!rbuf->buf) continue;
     383             : 
     384           0 :                 if(rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupphase2end"))
     385             :                 {
     386           0 :                         if(asfd->write_str(asfd, CMD_GEN, "okbackupphase2end"))
     387           0 :                                 goto end;
     388           0 :                         ret=0;
     389           0 :                         break;
     390             :                 }
     391             : 
     392           0 :                 if(parse_rbuf(asfd, sb, bfd, confs))
     393           0 :                         goto end;
     394             :         }
     395             : 
     396             : end:
     397             :         // It is possible for a bfd to still be open.
     398           0 :         bfd->close(bfd, asfd);
     399           0 :         bfile_free(&bfd);
     400           0 :         iobuf_free_content(rbuf);
     401           0 :         sbuf_free(&sb);
     402           0 :         return ret;
     403             : }
     404             : 
     405           0 : int backup_phase2_client_protocol1(struct asfd *asfd,
     406             :         struct conf **confs, int resume)
     407             : {
     408           0 :         int ret=0;
     409             : 
     410           0 :         logp("Phase 2 begin (send backup data)\n");
     411           0 :         printf("\n");
     412             : 
     413           0 :         ret=do_backup_phase2_client(asfd, confs, resume);
     414             : 
     415           0 :         cntr_print_end(get_cntr(confs));
     416           0 :         cntr_print(get_cntr(confs), ACTION_BACKUP);
     417             : 
     418           0 :         if(ret) logp("Error in phase 2\n");
     419           0 :         logp("Phase 2 end (send file data)\n");
     420             : 
     421           0 :         return ret;
     422             : }

Generated by: LCOV version 1.10