LCOV - code coverage report
Current view: top level - src/server/protocol1 - backup_phase2.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 324 467 69.4 %
Date: 2017-05-01 Functions: 22 26 84.6 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../alloc.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 "../../conffile.h"
      10             : #include "../../fsops.h"
      11             : #include "../../handy.h"
      12             : #include "../../iobuf.h"
      13             : #include "../../log.h"
      14             : #include "../../sbuf.h"
      15             : #include "../child.h"
      16             : #include "../compress.h"
      17             : #include "../resume.h"
      18             : #include "blocklen.h"
      19             : #include "dpth.h"
      20             : #include "backup_phase2.h"
      21             : #include "link.h"
      22             : 
      23             : static size_t treepathlen=0;
      24             : 
      25           0 : static int path_length_warn(struct iobuf *path, struct conf **cconfs)
      26             : {
      27           0 :         if(get_int(cconfs[OPT_PATH_LENGTH_WARN]))
      28           0 :                 logw(NULL, get_cntr(cconfs), "Path too long for tree - will save in data structure instead: %s\n", path->buf);
      29           0 :         return 1;
      30             : }
      31             : 
      32           4 : static int path_too_long(struct iobuf *path, struct conf **cconfs)
      33             : {
      34             :         static const char *cp;
      35           4 :         if(treepathlen+path->len+1>fs_full_path_max)
      36             :         {
      37             :                 // FIX THIS:
      38             :                 // Cannot warn down the asfd to the client, because it can
      39             :                 // arrive after the client has disconnected, which causes
      40             :                 // an error on the server side.
      41             :                 // Would need to change the way that "backupphase2end" works
      42             :                 // to be able to fix it.
      43           0 :                 return path_length_warn(path, cconfs);
      44             :         }
      45           4 :         if((cp=strrchr(path->buf, '/'))) cp++;
      46           0 :         else cp=path->buf;
      47           4 :         if(strlen(cp)>fs_name_max) return path_length_warn(path, cconfs);
      48             :         return 0;
      49             : }
      50             : 
      51           4 : static int treedata(struct sbuf *sb, struct conf **cconfs)
      52             : {
      53             :         // Windows is sending directory data as if it is file data - this
      54             :         // cannot be saved in a tree structure.
      55           4 :         if(S_ISDIR(sb->statp.st_mode)) return 0;
      56             : 
      57           8 :         if(sb->path.cmd!=CMD_FILE
      58           4 :           && sb->path.cmd!=CMD_ENC_FILE
      59           0 :           && sb->path.cmd!=CMD_EFS_FILE)
      60             :                 return 0;
      61             : 
      62           4 :         return !path_too_long(&sb->path, cconfs);
      63             : }
      64             : 
      65           4 : static char *set_new_datapth(struct asfd *asfd,
      66             :         struct sdirs *sdirs, struct conf **cconfs,
      67             :         struct sbuf *sb, struct dpth *dpth, int *istreedata)
      68             : {
      69           4 :         char *tmp=NULL;
      70           4 :         char *rpath=NULL;
      71           4 :         if(get_int(cconfs[OPT_DIRECTORY_TREE]))
      72           4 :                 *istreedata=treedata(sb, cconfs);
      73             : 
      74           4 :         if(*istreedata)
      75             :         {
      76             :                 // We want to place this file in a directory structure like
      77             :                 // the directory structure on the original client.
      78           4 :                 if(!(tmp=prepend_s(TREE_DIR, sb->path.buf)))
      79             :                 {
      80           0 :                         log_and_send_oom(asfd);
      81             :                         return NULL;
      82             :                 }
      83             :         }
      84             :         else
      85             :         {
      86           0 :                 if(!(tmp=strdup_w(dpth_protocol1_mk(dpth, sb->compression,
      87             :                         sb->path.cmd), __func__))) return NULL;
      88             :         }
      89           4 :         iobuf_from_str(&sb->protocol1->datapth, CMD_DATAPTH, tmp);
      90           4 :         if(build_path(sdirs->datadirtmp,
      91           4 :                 sb->protocol1->datapth.buf, &rpath, sdirs->datadirtmp))
      92             :         {
      93           0 :                 log_and_send(asfd, "build path failed");
      94             :                 return NULL;
      95             :         }
      96           4 :         return rpath;
      97             : }
      98             : 
      99           4 : static int start_to_receive_new_file(struct asfd *asfd,
     100             :         struct sdirs *sdirs, struct conf **cconfs,
     101             :         struct sbuf *sb, struct dpth *dpth)
     102             : {
     103           4 :         int ret=-1;
     104           4 :         char *rpath=NULL;
     105           4 :         int istreedata=0;
     106             : 
     107             : //logp("start to receive: %s\n", sb->path.buf);
     108             : 
     109           4 :         if(!(rpath=set_new_datapth(asfd,
     110             :                 sdirs, cconfs, sb, dpth, &istreedata)))
     111             :                         goto end;
     112             :         
     113           4 :         if(!(sb->protocol1->fzp=fzp_open(rpath, "wb")))
     114             :         {
     115           0 :                 log_and_send(asfd, "make file failed");
     116           0 :                 goto end;
     117             :         }
     118           4 :         if(!istreedata) dpth_incr(dpth);
     119             :         ret=0;
     120             : end:
     121           4 :         free_w(&rpath);
     122           4 :         return ret;
     123             : }
     124             : 
     125             : enum processed_e
     126             : {
     127             :         P_ERROR=-1,
     128             :         P_DONE_NEW=0,
     129             :         P_DONE_CHANGED=1,
     130             :         P_DONE_UNCHANGED=2,
     131             :         P_DONE_DELETED=3,
     132             :         P_NEW=4,
     133             :         P_CHANGED=5
     134             : };
     135             : 
     136             : #include <librsync.h>
     137             : 
     138           2 : static enum processed_e process_changed_file(struct asfd *asfd,
     139             :         struct conf **cconfs,
     140             :         struct sbuf *cb, struct sbuf *p1b,
     141             :         const char *adir)
     142             : {
     143           2 :         int ret=P_ERROR;
     144           2 :         size_t blocklen=0;
     145           2 :         char *curpath=NULL;
     146             :         //logp("need to process changed file: %s (%s)\n",
     147             :         //      cb->path, cb->datapth);
     148             : 
     149             :         // Move datapth onto p1b.
     150           2 :         iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
     151             : 
     152           2 :         if(!(curpath=prepend_s(adir, p1b->protocol1->datapth.buf)))
     153             :         {
     154           0 :                 log_out_of_memory(__func__);
     155             :                 goto end;
     156             :         }
     157           2 :         if(dpth_protocol1_is_compressed(cb->compression, curpath))
     158           0 :                 p1b->protocol1->sigfzp=fzp_gzopen(curpath, "rb");
     159             :         else
     160           2 :                 p1b->protocol1->sigfzp=fzp_open(curpath, "rb");
     161           2 :         if(!p1b->protocol1->sigfzp)
     162             :         {
     163           0 :                 logp("could not open %s: %s\n", curpath, strerror(errno));
     164             :                 goto end;
     165             :         }
     166             : 
     167           2 :         blocklen=get_librsync_block_len(cb->endfile.buf);
     168           4 :         if(!(p1b->protocol1->sigjob=
     169             : #ifdef RS_DEFAULT_STRONG_LEN
     170           2 :                 rs_sig_begin(blocklen, RS_DEFAULT_STRONG_LEN)
     171             : #else
     172             :                 // This is for librsync-1.0.0. RS_DEFAULT_STRONG_LEN was 8 in
     173             :                 // librsync-0.9.7.
     174             :                 rs_sig_begin(blocklen, 8,
     175             :                   rshash_to_magic_number(get_e_rshash(cconfs[OPT_RSHASH])))
     176             : #endif
     177             :         ))
     178             :         {
     179           0 :                 logp("could not start signature job.\n");
     180             :                 goto end;
     181             :         }
     182             :         //logp("sig begin: %s\n", p1b->protocol1->datapth.buf);
     183           2 :         if(!(p1b->protocol1->infb=rs_filebuf_new(NULL,
     184           2 :                 p1b->protocol1->sigfzp,
     185             :                 NULL, blocklen, -1)))
     186             :         {
     187           0 :                 logp("could not rs_filebuf_new for infb.\n");
     188             :                 goto end;
     189             :         }
     190           2 :         if(!(p1b->protocol1->outfb=rs_filebuf_new(NULL, NULL,
     191             :                 asfd, ASYNC_BUF_LEN, -1)))
     192             :         {
     193           0 :                 logp("could not rs_filebuf_new for in_outfb.\n");
     194             :                 goto end;
     195             :         }
     196             : 
     197             :         // Flag the things that need to be sent (to the client)
     198           2 :         p1b->flags |= SBUF_SEND_DATAPTH;
     199           2 :         p1b->flags |= SBUF_SEND_STAT;
     200           2 :         p1b->flags |= SBUF_SEND_PATH;
     201             : 
     202             :         //logp("sending sig for %s\n", p1b->path);
     203             :         //logp("(%s)\n", p1b->datapth);
     204             : 
     205           2 :         ret=P_CHANGED;
     206             : end:
     207           2 :         free_w(&curpath);
     208           2 :         return ret;
     209             : }
     210             : 
     211          68 : static enum processed_e new_non_file(struct sbuf *p1b,
     212             :         struct manio *ucmanio, struct conf **cconfs)
     213             : {
     214             :         // Is something that does not need more data backed up.
     215             :         // Like a directory or a link or something like that.
     216             :         // Goes into the unchanged file, so that it does not end up out of
     217             :         // order with normal files, which has to wait around for their data
     218             :         // to turn up.
     219          68 :         if(manio_write_sbuf(ucmanio, p1b))
     220             :                 return P_ERROR;
     221          68 :         cntr_add(get_cntr(cconfs), p1b->path.cmd, 0);
     222          68 :         return P_DONE_NEW;
     223             : }
     224             : 
     225           0 : static enum processed_e changed_non_file(struct sbuf *p1b,
     226             :         struct manio *ucmanio, enum cmd cmd, struct conf **cconfs)
     227             : {
     228             :         // As new_non_file.
     229           0 :         if(manio_write_sbuf(ucmanio, p1b))
     230             :                 return P_ERROR;
     231           0 :         cntr_add_changed(get_cntr(cconfs), cmd);
     232           0 :         return P_DONE_CHANGED;
     233             : }
     234             : 
     235         122 : static enum processed_e process_new(struct conf **cconfs,
     236             :         struct sbuf *p1b, struct manio *ucmanio)
     237             : {
     238         122 :         if(sbuf_is_filedata(p1b)
     239          68 :           || sbuf_is_vssdata(p1b))
     240             :         {
     241             :                 //logp("need to process new file: %s\n", p1b->path);
     242             :                 // Flag the things that need to be sent (to the client)
     243          54 :                 p1b->flags |= SBUF_SEND_STAT;
     244          54 :                 p1b->flags |= SBUF_SEND_PATH;
     245          54 :                 return P_NEW;
     246             :         }
     247          68 :         return new_non_file(p1b, ucmanio, cconfs);
     248             : }
     249             : 
     250           6 : static enum processed_e process_unchanged_file(struct sbuf *p1b, struct sbuf *cb,
     251             :         struct manio *ucmanio, struct conf **cconfs)
     252             : {
     253             :         // Need to re-encode the p1b attribs to include compression and
     254             :         // other bits and pieces that are recorded on cb.
     255           6 :         iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
     256           6 :         iobuf_move(&p1b->endfile, &cb->endfile);
     257           6 :         p1b->compression=cb->compression;
     258             :         // Why is winattr not getting sent in phase1?
     259           6 :         p1b->winattr=cb->winattr;
     260             :         // Need to free attr so that it is reallocated, because it may get
     261             :         // longer than what the client told us in phase1.
     262           6 :         iobuf_free_content(&p1b->attr);
     263           6 :         if(attribs_encode(p1b))
     264             :                 return P_ERROR;
     265           6 :         if(manio_write_sbuf(ucmanio, p1b))
     266             :                 return P_ERROR;
     267           6 :         cntr_add_same(get_cntr(cconfs), p1b->path.cmd);
     268           6 :         if(p1b->endfile.buf) cntr_add_bytes(get_cntr(cconfs),
     269           0 :                 strtoull(p1b->endfile.buf, NULL, 10));
     270             :         return P_DONE_UNCHANGED;
     271             : }
     272             : 
     273          10 : static int open_previous_manifest(struct manio **manio, struct sdirs *sdirs)
     274             : {
     275             :         struct stat statp;
     276          20 :         if(!lstat(sdirs->cmanifest, &statp)
     277           2 :           && !(*manio=manio_open(sdirs->cmanifest, "rb", PROTO_1)))
     278             :         {
     279           0 :                 logp("could not open old manifest %s\n", sdirs->cmanifest);
     280             :                 return -1;
     281             :         }
     282             :         return 0;
     283             : }
     284             : 
     285           0 : static int get_hardlink_master_from_hmanio(
     286             :         struct manio **hmanio,
     287             :         struct sdirs *sdirs,
     288             :         struct sbuf *cb,
     289             :         struct sbuf *hb
     290             : ) {
     291             :         int passes=0;
     292             :         while(1)
     293             :         {
     294           0 :                 sbuf_free_content(hb);
     295           0 :                 switch(manio_read(*hmanio, hb))
     296             :                 {
     297             :                         case 0: // Keep going.
     298             :                                 break;
     299             :                         case 1: // Finished OK.
     300           0 :                                 manio_close(hmanio);
     301             :                                 // Might have already been part way down the
     302             :                                 // manifest when we started. If we get to the
     303             :                                 // end, go back to the beginning once.
     304           0 :                                 if(!passes)
     305             :                                 {
     306           0 :                                         if(open_previous_manifest(hmanio,
     307             :                                                 sdirs)) return -1;
     308           0 :                                         passes++;
     309           0 :                                         continue;
     310             :                                 }
     311             :                                 return 0;
     312             :                         default: // Error;
     313             :                                 return -1;
     314             :                 }
     315           0 :                 if(hb->path.cmd!=CMD_FILE
     316           0 :                   && hb->path.cmd!=CMD_ENC_FILE)
     317           0 :                         continue;
     318           0 :                 if(!strcmp(hb->path.buf, cb->link.buf))
     319             :                         return 1; // Found it.
     320             :         }
     321             :         return -1;
     322             : }
     323             : 
     324           0 : static int relink_deleted_hardlink_master(
     325             :         struct manio **hmanio,
     326             :         struct sdirs *sdirs,
     327             :         struct sbuf *p1b,
     328             :         struct sbuf *cb,
     329             :         struct conf **cconfs
     330             : ) {
     331           0 :         int ret=-1;
     332           0 :         char *oldpath=NULL;
     333           0 :         char *newpath=NULL;
     334             :         struct stat statp;
     335           0 :         struct sbuf *hb=NULL;
     336             : 
     337           0 :         if(!(hb=sbuf_alloc(PROTO_1)))
     338             :                 goto end;
     339             : 
     340           0 :         switch(get_hardlink_master_from_hmanio(hmanio, sdirs, cb, hb))
     341             :         {
     342             :                 case 0: // Did not find it.
     343             :                         return 0;
     344             :                 case 1: // Found it.
     345             :                         break;
     346             :                 default: // Error.
     347             :                         goto end;
     348             :         }
     349             : 
     350             :         // Protect against the old file being encrypted, and the new file not
     351             :         // being encrypted - and vice versa.
     352           0 :         if(p1b->path.cmd!=hb->path.cmd)
     353             :                 return 0;
     354             : 
     355           0 :         if(!(oldpath=prepend_s(sdirs->ctreepath, cb->link.buf))
     356           0 :           || !(newpath=prepend_s(sdirs->relink, p1b->path.buf)))
     357             :                 goto end;
     358           0 :         if(lstat(oldpath, &statp) || !S_ISREG(statp.st_mode))
     359             :         {
     360             :                 ret=0;
     361             :                 goto end;
     362             :         }
     363           0 :         if(build_path_w(newpath))
     364             :                 goto end;
     365           0 :         if(do_link(oldpath, newpath, &statp, cconfs, /*overwrite*/0))
     366             :                 goto end;
     367             : 
     368           0 :         iobuf_free_content(&cb->protocol1->datapth);
     369             : 
     370           0 :         free_w(&newpath);
     371           0 :         if(!(newpath=strdup_w(p1b->path.buf, __func__)))
     372             :                 goto end;
     373           0 :         iobuf_from_str(&hb->protocol1->datapth, CMD_DATAPTH, newpath);
     374           0 :         newpath=NULL;
     375           0 :         if(!(newpath=strdup_w(p1b->path.buf, __func__)))
     376             :                 goto end;
     377           0 :         iobuf_from_str(&cb->protocol1->datapth, CMD_DATAPTH, newpath);
     378           0 :         newpath=NULL;
     379           0 :         iobuf_move(&cb->endfile, &hb->endfile);
     380             : 
     381           0 :         ret=1;
     382             : end:
     383           0 :         free_w(&oldpath);
     384           0 :         free_w(&newpath);
     385           0 :         sbuf_free(&hb);
     386             :         return ret;
     387             : }
     388             : 
     389          10 : static enum processed_e maybe_do_delta_stuff(struct asfd *asfd,
     390             :         struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
     391             :         struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
     392             : {
     393          10 :         int oldcompressed=0;
     394          10 :         int compression=p1b->compression;
     395             : 
     396             :         // If the file type changed, I think it is time to back it up again
     397             :         // (for example, EFS changing to normal file, or back again).
     398          10 :         if(cb->path.cmd!=p1b->path.cmd)
     399             :         {
     400           0 :                 if(hmanio && *hmanio
     401           0 :                   && cb->path.cmd==CMD_HARD_LINK
     402           0 :                   && (p1b->path.cmd==CMD_FILE
     403           0 :                         || p1b->path.cmd==CMD_ENC_FILE))
     404             :                 {
     405           0 :                         struct stat *p1statp=&p1b->statp;
     406           0 :                         struct stat *cstatp=&cb->statp;
     407             :                         // A hardlink changed into a file. It is possible that
     408             :                         // The file that the hardlink was pointing to got
     409             :                         // deleted. Maybe we can reuse the previous file.
     410           0 :                         if(p1statp->st_dev==cstatp->st_dev
     411           0 :                           && p1statp->st_ino==cstatp->st_ino
     412           0 :                           && p1statp->st_mtime==cstatp->st_mtime)
     413             :                         {
     414           0 :                                 switch(relink_deleted_hardlink_master(
     415             :                                         hmanio, sdirs,
     416             :                                         p1b, cb, cconfs))
     417             :                                 {
     418             :                                         case 0:
     419             :                                                 break;
     420             :                                         case 1:
     421           0 :                                                 return process_unchanged_file(
     422             :                                                         p1b, cb,
     423             :                                                         ucmanio, cconfs);
     424             :                                         default:
     425             :                                                 return P_ERROR;
     426             :                                 }
     427             :                         }
     428             :                 }
     429           0 :                 return process_new(cconfs, p1b, ucmanio);
     430             :         }
     431             : 
     432             :         // mtime is the actual file data.
     433             :         // ctime is the attributes or meta data.
     434          10 :         if(cb->statp.st_mtime==p1b->statp.st_mtime
     435           6 :           && cb->statp.st_ctime==p1b->statp.st_ctime)
     436             :         {
     437             :                 // got an unchanged file
     438             :                 //logp("got unchanged file: %s %c %c\n",
     439             :                 //      cb->path.buf, cb->path.cmd, p1b->path.cmd);
     440           6 :                 return process_unchanged_file(p1b, cb, ucmanio, cconfs);
     441             :         }
     442             : 
     443           4 :         if(cb->statp.st_mtime==p1b->statp.st_mtime
     444           0 :           && cb->statp.st_ctime!=p1b->statp.st_ctime)
     445             :         {
     446             :                 // File data stayed the same, but attributes or meta data
     447             :                 // changed. We already have the attributes, but may need to get
     448             :                 // extra meta data.
     449             :                 // FIX THIS horrible mess.
     450           0 :                 if(cb->path.cmd==CMD_ENC_METADATA
     451           0 :                   || p1b->path.cmd==CMD_ENC_METADATA
     452           0 :                   || cb->path.cmd==CMD_EFS_FILE
     453           0 :                   || p1b->path.cmd==CMD_EFS_FILE
     454             :                 // FIX THIS: make unencrypted metadata use the librsync
     455           0 :                   || cb->path.cmd==CMD_METADATA
     456           0 :                   || p1b->path.cmd==CMD_METADATA
     457           0 :                   || sbuf_is_vssdata(cb)
     458           0 :                   || sbuf_is_vssdata(p1b))
     459           0 :                         return process_new(cconfs, p1b, ucmanio);
     460             :                 // On Windows, we have to back up the whole file if ctime
     461             :                 // changed, otherwise things like permission changes do not get
     462             :                 // noticed. So, in that case, fall through to the changed stuff
     463             :                 // below.
     464             :                 // Non-Windows clients finish here.
     465           0 :                 else if(!get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
     466           0 :                         return process_unchanged_file(p1b,
     467             :                                 cb, ucmanio, cconfs);
     468             :         }
     469             : 
     470             :         // Got a changed file.
     471             :         //logp("got changed file: %s\n", p1b->path.buf);
     472             : 
     473             :         // If either old or new is encrypted, or librsync is off, we need to
     474             :         // get a new file.
     475             :         // FIX THIS horrible mess.
     476           4 :         if(!get_int(cconfs[OPT_LIBRSYNC])
     477             :         // FIX THIS: make unencrypted metadata use the librsync
     478           4 :           || cb->path.cmd==CMD_METADATA
     479           4 :           || p1b->path.cmd==CMD_METADATA
     480           4 :           || sbuf_is_encrypted(cb)
     481           2 :           || sbuf_is_encrypted(p1b)
     482           2 :           || sbuf_is_vssdata(cb)
     483           2 :           || sbuf_is_vssdata(p1b))
     484           2 :                 return process_new(cconfs, p1b, ucmanio);
     485             : 
     486             :         // Get new files if they have switched between compression on or off.
     487           2 :         if(cb->protocol1->datapth.buf
     488           2 :           && dpth_protocol1_is_compressed(cb->compression,
     489             :             cb->protocol1->datapth.buf))
     490           0 :                 oldcompressed=1;
     491           2 :         if( ( oldcompressed && !compression)
     492           2 :          || (!oldcompressed &&  compression))
     493           0 :                 return process_new(cconfs, p1b, ucmanio);
     494             : 
     495             :         // Otherwise, do the delta stuff (if possible).
     496           2 :         if(sbuf_is_filedata(p1b)
     497           0 :           || sbuf_is_vssdata(p1b))
     498           2 :                 return process_changed_file(asfd, cconfs, cb, p1b,
     499           2 :                         sdirs->currentdata);
     500           0 :         return changed_non_file(p1b, ucmanio, p1b->path.cmd, cconfs);
     501             : }
     502             : 
     503             : static enum processed_e process_deleted_file(struct sbuf *cb,
     504             :         struct conf **cconfs)
     505             : {
     506           2 :         cntr_add_deleted(get_cntr(cconfs), cb->path.cmd);
     507             :         return P_DONE_DELETED;
     508             : }
     509             : 
     510             : // return 1 to say that a file was processed
     511          12 : static enum processed_e maybe_process_file(struct asfd *asfd,
     512           2 :         struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
     513             :         struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
     514             : {
     515             :         int pcmp;
     516          12 :         if(p1b)
     517             :         {
     518          11 :                 if(!(pcmp=sbuf_pathcmp(cb, p1b)))
     519          10 :                         return maybe_do_delta_stuff(asfd, sdirs, cb, p1b,
     520             :                                 ucmanio, hmanio, cconfs);
     521           1 :                 else if(pcmp>0)
     522             :                 {
     523             :                         //logp("ahead: %s\n", p1b->path.buf);
     524             :                         // ahead - need to get the whole file
     525           0 :                         return process_new(cconfs, p1b, ucmanio);
     526             :                 }
     527             :         }
     528             :         //logp("behind: %s\n", p1b->path.buf);
     529             :         // Behind - need to read more from the old manifest.
     530             :         // Count a deleted file - it was in the old manifest
     531             :         // but not the new.
     532           4 :         return process_deleted_file(cb, cconfs);
     533             : }
     534             : 
     535             : enum sts_e
     536             : {
     537             :         STS_ERROR=-1,
     538             :         STS_OK=0,
     539             :         STS_BLOCKED=1
     540             : };
     541             : 
     542             : // Return 1 if there is still stuff needing to be sent.
     543             : // FIX THIS: lots of repeated code.
     544          63 : static enum sts_e do_stuff_to_send(struct asfd *asfd,
     545             :         struct sbuf *p1b, char **last_requested)
     546             : {
     547             :         static struct iobuf wbuf;
     548          63 :         if(p1b->flags & SBUF_SEND_DATAPTH)
     549             :         {
     550           2 :                 iobuf_copy(&wbuf, &p1b->protocol1->datapth);
     551           2 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     552             :                 {
     553             :                         case APPEND_OK: break;
     554             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     555           0 :                         default: return STS_ERROR;
     556             :                 }
     557           2 :                 p1b->flags &= ~SBUF_SEND_DATAPTH;
     558             :         }
     559          63 :         if(p1b->flags & SBUF_SEND_STAT)
     560             :         {
     561          56 :                 iobuf_copy(&wbuf, &p1b->attr);
     562          56 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     563             :                 {
     564             :                         case APPEND_OK: break;
     565             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     566           0 :                         default: return STS_ERROR;
     567             :                 }
     568          56 :                 p1b->flags &= ~SBUF_SEND_STAT;
     569             :         }
     570          63 :         if(p1b->flags & SBUF_SEND_PATH)
     571             :         {
     572          56 :                 iobuf_copy(&wbuf, &p1b->path);
     573          56 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     574             :                 {
     575             :                         case APPEND_OK: break;
     576             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     577           0 :                         default: return STS_ERROR;
     578             :                 }
     579          56 :                 p1b->flags &= ~SBUF_SEND_PATH;
     580          56 :                 free_w(last_requested);
     581          56 :                 if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
     582             :                         return STS_ERROR;
     583             :         }
     584          63 :         if(p1b->protocol1->sigjob && !(p1b->flags & SBUF_SEND_ENDOFSIG))
     585             :         {
     586             :                 rs_result sigresult;
     587             : 
     588           4 :                 switch((sigresult=rs_async(p1b->protocol1->sigjob,
     589             :                         &(p1b->protocol1->rsbuf),
     590             :                         p1b->protocol1->infb, p1b->protocol1->outfb)))
     591             :                 {
     592             :                         case RS_DONE:
     593           2 :                                 p1b->flags |= SBUF_SEND_ENDOFSIG;
     594           2 :                                 break;
     595             :                         case RS_BLOCKED:
     596             :                         case RS_RUNNING:
     597             :                                 // keep going round the loop.
     598             :                                 return STS_BLOCKED;
     599             :                         default:
     600           0 :                                 logp("error in rs_async: %d\n", sigresult);
     601           0 :                                 return STS_ERROR;
     602             :                 }
     603             :         }
     604          61 :         if(p1b->flags & SBUF_SEND_ENDOFSIG)
     605             :         {
     606           2 :                 iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
     607           2 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     608             :                 {
     609             :                         case APPEND_OK: break;
     610             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     611           0 :                         default: return STS_ERROR;
     612             :                 }
     613           2 :                 p1b->flags &= ~SBUF_SEND_ENDOFSIG;
     614             :         }
     615             :         return STS_OK;
     616             : }
     617             : 
     618           4 : static int start_to_receive_delta(struct sdirs *sdirs, struct sbuf *rb)
     619             : {
     620           4 :         if(rb->compression)
     621             :         {
     622           0 :                 if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
     623           0 :                         comp_level(rb->compression))))
     624             :                                 return -1;
     625             :         }
     626             :         else
     627             :         {
     628           4 :                 if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
     629             :                         return -1;
     630             :         }
     631           4 :         rb->flags |= SBUF_RECV_DELTA;
     632             : 
     633             :         return 0;
     634             : }
     635             : 
     636           4 : static int finish_delta(struct sdirs *sdirs, struct sbuf *rb)
     637             : {
     638           4 :         int ret=0;
     639           4 :         char *deltmp=NULL;
     640           4 :         char *delpath=NULL;
     641           4 :         if(!(deltmp=prepend_s("deltas.forward", rb->protocol1->datapth.buf))
     642           4 :           || !(delpath=prepend_s(sdirs->working, deltmp))
     643           4 :           || mkpath(&delpath, sdirs->working)
     644             :         // Rename race condition is of no consequence here, as delpath will
     645             :         // just get recreated.
     646           4 :           || do_rename(sdirs->deltmppath, delpath))
     647             :                 ret=-1;
     648           4 :         free_w(&delpath);
     649           4 :         free_w(&deltmp);
     650           4 :         return ret;
     651             : }
     652             : 
     653           8 : static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
     654           4 :         struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
     655             :         char **last_requested)
     656             : {
     657           8 :         int ret=-1;
     658             :         static char *cp=NULL;
     659             :         static struct iobuf *rbuf;
     660           8 :         struct cntr *cntr=get_cntr(cconfs);
     661           8 :         rbuf=asfd->rbuf;
     662             :         // Finished the file.
     663             :         // Write it to the phase2 file, and free the buffers.
     664             : 
     665           8 :         if(fzp_close(&(rb->protocol1->fzp)))
     666             :         {
     667           0 :                 logp("error closing delta for %s in receive\n", rb->path.buf);
     668             :                 goto end;
     669             :         }
     670           8 :         iobuf_move(&rb->endfile, rbuf);
     671          12 :         if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
     672             :                 goto end;
     673             : 
     674           8 :         if(manio_write_sbuf(chmanio, rb))
     675             :                 goto end;
     676             : 
     677           8 :         if(rb->flags & SBUF_RECV_DELTA)
     678           4 :                 cntr_add_changed(cntr, rb->path.cmd);
     679             :         else
     680           4 :                 cntr_add(cntr, rb->path.cmd, 0);
     681             : 
     682           8 :         if(*last_requested && !strcmp(rb->path.buf, *last_requested))
     683           2 :                 free_w(last_requested);
     684             : 
     685           8 :         cp=strchr(rb->endfile.buf, ':');
     686           8 :         if(rb->endfile.buf)
     687           8 :                 cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
     688             :         if(cp)
     689             :         {
     690             :                 // checksum stuff goes here
     691             :         }
     692             : 
     693             :         ret=0;
     694             : end:
     695           8 :         sbuf_free_content(rb);
     696           8 :         return ret;
     697             : }
     698             : 
     699           8 : static int deal_with_receive_append(struct asfd *asfd, struct sbuf *rb)
     700             : {
     701           8 :         int app=0;
     702             :         static struct iobuf *rbuf;
     703           8 :         rbuf=asfd->rbuf;
     704             :         //logp("rbuf->len: %d\n", rbuf->len);
     705             : 
     706           8 :         if(rb->protocol1->fzp)
     707           8 :                 app=fzp_write(rb->protocol1->fzp, rbuf->buf, rbuf->len);
     708             : 
     709           8 :         if(app>0) return 0;
     710           0 :         logp("error when appending: %d\n", app);
     711           0 :         asfd->write_str(asfd, CMD_ERROR, "write failed");
     712             :         return -1;
     713             : }
     714             : 
     715           8 : static int deal_with_filedata(struct asfd *asfd,
     716             :         struct sdirs *sdirs, struct sbuf *rb,
     717             :         struct iobuf *rbuf, struct dpth *dpth, struct conf **cconfs)
     718             : {
     719           8 :         iobuf_move(&rb->path, rbuf);
     720             : 
     721           8 :         if(rb->protocol1->datapth.buf)
     722             :         {
     723             :                 // Receiving a delta.
     724           4 :                 if(start_to_receive_delta(sdirs, rb))
     725             :                 {
     726           0 :                         logp("error in start_to_receive_delta\n");
     727           0 :                         return -1;
     728             :                 }
     729             :                 return 0;
     730             :         }
     731             : 
     732             :         // Receiving a whole new file.
     733           4 :         if(start_to_receive_new_file(asfd, sdirs, cconfs, rb, dpth))
     734             :         {
     735           0 :                 logp("error in start_to_receive_new_file\n");
     736           0 :                 return -1;
     737             :         }
     738             :         return 0;
     739             : }
     740             : 
     741             : enum str_e
     742             : {
     743             :         STR_ERROR=-1,
     744             :         STR_OK=0,
     745             :         STR_FINISHED=1
     746             : };
     747             : 
     748             : // returns 1 for finished ok.
     749          85 : static enum str_e do_stuff_to_receive(struct asfd *asfd,
     750             :         struct sdirs *sdirs, struct conf **cconfs,
     751             :         struct sbuf *rb, struct manio *chmanio,
     752             :         struct dpth *dpth, char **last_requested)
     753             : {
     754          85 :         struct iobuf *rbuf=asfd->rbuf;
     755             : 
     756         170 :         if(rbuf->cmd==CMD_MESSAGE
     757          85 :           || rbuf->cmd==CMD_WARNING)
     758             :         {
     759           0 :                 struct cntr *cntr=NULL;
     760           0 :                 if(cconfs) cntr=get_cntr(cconfs);
     761           0 :                 log_recvd(rbuf, cntr, 0);
     762           0 :                 return STR_OK;
     763             :         }
     764             : 
     765          85 :         if(rb->protocol1->fzp)
     766             :         {
     767             :                 // Currently writing a file (or meta data)
     768          16 :                 switch(rbuf->cmd)
     769             :                 {
     770             :                         case CMD_APPEND:
     771           8 :                                 if(deal_with_receive_append(asfd, rb))
     772             :                                         goto error;
     773             :                                 return STR_OK;
     774             :                         case CMD_END_FILE:
     775           8 :                                 if(deal_with_receive_end_file(asfd, sdirs, rb,
     776             :                                         chmanio, cconfs, last_requested))
     777             :                                                 goto error;
     778             :                                 return STR_OK;
     779             :                         default:
     780           0 :                                 iobuf_log_unexpected(rbuf, __func__);
     781           0 :                                 goto error;
     782             :                 }
     783             :         }
     784             : 
     785             :         // Otherwise, expecting to be told of a file to save.
     786          69 :         switch(rbuf->cmd)
     787             :         {
     788             :                 case CMD_DATAPTH:
     789           4 :                         iobuf_move(&rb->protocol1->datapth, rbuf);
     790           4 :                         return STR_OK;
     791             :                 case CMD_ATTRIBS:
     792           8 :                         iobuf_move(&rb->attr, rbuf);
     793           8 :                         attribs_decode(rb);
     794           8 :                         return STR_OK;
     795             :                 case CMD_GEN:
     796           5 :                         if(!strcmp(rbuf->buf, "okbackupphase2end"))
     797             :                                 goto end_phase2;
     798           0 :                         iobuf_log_unexpected(rbuf, __func__);
     799           0 :                         goto error;
     800             :                 case CMD_INTERRUPT:
     801             :                         // Interrupt - forget about the last requested
     802             :                         // file if it matches. Otherwise, we can get
     803             :                         // stuck on the select in the async stuff,
     804             :                         // waiting for something that will never arrive.
     805          44 :                         if(*last_requested
     806          44 :                           && !strcmp(rbuf->buf, *last_requested))
     807           1 :                                 free_w(last_requested);
     808             :                         return STR_OK;
     809             :                 default:
     810             :                         break;
     811             :         }
     812           8 :         if(iobuf_is_filedata(rbuf)
     813           0 :           || iobuf_is_vssdata(rbuf))
     814             :         {
     815           8 :                 if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
     816             :                         goto error;
     817             :                 return STR_OK;
     818             :         }
     819           0 :         iobuf_log_unexpected(rbuf, __func__);
     820             : 
     821             : error:
     822             :         return STR_ERROR;
     823             : end_phase2:
     824             :         return STR_FINISHED;
     825             : }
     826             : 
     827           5 : static int vss_opts_changed(struct sdirs *sdirs, struct conf **cconfs,
     828             :         const char *incexc)
     829             : {
     830           5 :         int ret=-1;
     831             :         struct conf **oldconfs;
     832             :         struct conf **newconfs;
     833           5 :         if(!(oldconfs=confs_alloc())
     834           5 :           || !(newconfs=confs_alloc()))
     835             :                 goto end;
     836           5 :         confs_init(oldconfs);
     837           5 :         confs_init(newconfs);
     838             : 
     839             :         // Figure out the old config, which is in the incexc file left
     840             :         // in the current backup directory on the server.
     841           5 :         if(conf_parse_incexcs_path(oldconfs, sdirs->cincexc))
     842             :         {
     843             :                 // Assume that the file did not exist, and therefore
     844             :                 // the old split_vss setting is 0.
     845           4 :                 set_int(oldconfs[OPT_SPLIT_VSS], 0);
     846           4 :                 set_int(oldconfs[OPT_STRIP_VSS], 0);
     847             :         }
     848             : 
     849             :         // Figure out the new config, which is either in the incexc file from
     850             :         // the client, or in the cconf on the server.
     851           5 :         if(incexc)
     852             :         {
     853           0 :                 if(conf_parse_incexcs_buf(newconfs, incexc))
     854             :                 {
     855             :                         // Should probably not got here.
     856           0 :                         set_int(newconfs[OPT_SPLIT_VSS], 0);
     857           0 :                         set_int(newconfs[OPT_STRIP_VSS], 0);
     858             :                 }
     859             :         }
     860             :         else
     861             :         {
     862           5 :                 set_int(newconfs[OPT_SPLIT_VSS],
     863           5 :                         get_int(cconfs[OPT_SPLIT_VSS]));
     864           5 :                 set_int(newconfs[OPT_STRIP_VSS],
     865           5 :                         get_int(cconfs[OPT_STRIP_VSS]));
     866             :         }
     867             : 
     868           5 :         if(get_int(newconfs[OPT_SPLIT_VSS])!=get_int(oldconfs[OPT_SPLIT_VSS]))
     869             :         {
     870           0 :                 logp("split_vss=%d (changed since last backup)\n",
     871           0 :                         get_int(newconfs[OPT_SPLIT_VSS]));
     872           0 :                 ret=1; goto end;
     873             :         }
     874           5 :         if(get_int(newconfs[OPT_STRIP_VSS])!=get_int(oldconfs[OPT_STRIP_VSS]))
     875             :         {
     876           0 :                 logp("strip_vss=%d (changed since last backup)\n",
     877           0 :                         get_int(newconfs[OPT_STRIP_VSS]));
     878           0 :                 ret=1; goto end;
     879             :         }
     880             :         ret=0;
     881             : end:
     882           5 :         if(ret==1) logp("All files will be treated as new\n");
     883           5 :         confs_free(&oldconfs);
     884           5 :         confs_free(&newconfs);
     885           5 :         return ret;
     886             : }
     887             : 
     888             : // Maybe open the previous (current) manifest.
     889             : // If the split_vss setting changed between the previous backup and the new
     890             : // backup, do not open the previous manifest. This will have the effect of
     891             : // making the client back up everything fresh. Need to do this, otherwise
     892             : // toggling split_vss on and off will result in backups that do not work.
     893           5 : static int maybe_open_previous_manifest(struct manio **manio,
     894             :         struct sdirs *sdirs, const char *incexc, struct conf **cconfs)
     895             : {
     896           5 :         if(vss_opts_changed(sdirs, cconfs, incexc))
     897             :                 return 0;
     898           5 :         return open_previous_manifest(manio, sdirs);
     899             : }
     900             : 
     901         135 : static int process_next_file_from_manios(struct asfd *asfd,
     902             :         struct sdirs *sdirs,
     903             :         struct manio **p1manio,
     904             :         struct manio **cmanio,
     905             :         struct manio *ucmanio,
     906             :         struct manio **hmanio,
     907             :         struct sbuf **p1b,
     908             :         struct sbuf *cb,
     909             :         struct conf **cconfs)
     910             : {
     911         135 :         if(!(*p1b=sbuf_alloc(PROTO_1)))
     912             :                 goto error;
     913         135 :         switch(manio_read(*p1manio, *p1b))
     914             :         {
     915             :                 case 0:
     916             :                         break;
     917             :                 case 1:
     918           5 :                         manio_close(p1manio);
     919           5 :                         if(asfd->write_str(asfd, CMD_GEN, "backupphase2end"))
     920             :                                 goto error;
     921           5 :                         sbuf_free(p1b);
     922           5 :                         break;
     923             :                 case -1:
     924             :                         goto error;
     925             :         }
     926             : 
     927         135 :         if(!*cmanio)
     928             :         {
     929         124 :                 if(!*p1b) return 0;
     930             :                 // No old manifest, need to ask for a new file.
     931         120 :                 switch(process_new(cconfs, *p1b, ucmanio))
     932             :                 {
     933             :                         case P_NEW:
     934             :                                 return 0;
     935             :                         case P_DONE_NEW:
     936             :                                 goto p1b_done;
     937             :                         default:
     938             :                                 goto error;
     939             :                 }
     940             :         }
     941             : 
     942             :         // Have an old manifest, look for it there.
     943             : 
     944             :         // Might already have it, or be ahead in the old
     945             :         // manifest.
     946          11 :         if(cb->path.buf)
     947             :         {
     948           2 :                 switch(maybe_process_file(asfd,
     949             :                         sdirs, cb, *p1b, ucmanio, hmanio, cconfs))
     950             :                 {
     951             :                         case P_NEW:
     952             :                                 return 0;
     953             :                         case P_CHANGED:
     954             :                                 // Free cb content for things like encrypted
     955             :                                 // files, which we only pretend are new.
     956           0 :                                 sbuf_free_content(cb);
     957           0 :                                 return 0;
     958             :                         case P_DONE_NEW:
     959             :                                 goto p1b_done;
     960             :                         case P_DONE_CHANGED:
     961             :                         case P_DONE_UNCHANGED:
     962           0 :                                 sbuf_free_content(cb);
     963           0 :                                 goto p1b_done;
     964             :                         case P_DONE_DELETED:
     965           2 :                                 sbuf_free_content(cb);
     966           2 :                                 break;
     967             :                         case P_ERROR:
     968             :                                 goto error;
     969             :                 }
     970             :         }
     971             : 
     972             :         while(1)
     973             :         {
     974          11 :                 sbuf_free_content(cb);
     975          11 :                 switch(manio_read(*cmanio, cb))
     976             :                 {
     977             :                         case 0: break;
     978           1 :                         case 1: manio_close(cmanio);
     979           1 :                                 if(*p1b) switch(process_new(cconfs,
     980             :                                         *p1b, ucmanio))
     981             :                                 {
     982             :                                         case P_NEW:
     983             :                                                 return 0;
     984             :                                         case P_DONE_NEW:
     985             :                                                 goto p1b_done;
     986             :                                         default:
     987             :                                                 goto error;
     988             :                                 }
     989             :                                 return 0;
     990             :                         case -1: goto error;
     991             :                 }
     992          10 :                 switch(maybe_process_file(asfd, sdirs,
     993             :                         cb, *p1b, ucmanio, hmanio, cconfs))
     994             :                 {
     995             :                         case P_NEW:
     996             :                                 return 0;
     997             :                         case P_CHANGED:
     998             :                                 // Free cb content for things like encrypted
     999             :                                 // files, which we only pretend are new.
    1000           2 :                                 sbuf_free_content(cb);
    1001           2 :                                 return 0;
    1002             :                         case P_DONE_NEW:
    1003             :                                 goto p1b_done;
    1004             :                         case P_DONE_CHANGED:
    1005             :                         case P_DONE_UNCHANGED:
    1006           6 :                                 sbuf_free_content(cb);
    1007           6 :                                 goto p1b_done;
    1008             :                         case P_DONE_DELETED:
    1009           0 :                                 sbuf_free_content(cb);
    1010           0 :                                 continue;
    1011             :                         case P_ERROR:
    1012             :                                 goto error;
    1013             :                 }
    1014             :         }
    1015             : error:
    1016             :         return -1;
    1017             : p1b_done:
    1018          74 :         sbuf_free(p1b);
    1019          74 :         return 0;
    1020             : }
    1021             : 
    1022          10 : int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
    1023             :         const char *incexc, int resume, struct conf **cconfs)
    1024             : {
    1025          10 :         int ret=0;
    1026          10 :         man_off_t *p1pos=NULL;
    1027          10 :         struct manio *p1manio=NULL;
    1028          10 :         struct dpth *dpth=NULL;
    1029          10 :         char *deltmppath=NULL;
    1030          10 :         char *last_requested=NULL;
    1031          10 :         struct manio *chmanio=NULL; // changed data
    1032          10 :         struct manio *ucmanio=NULL; // unchanged data
    1033          10 :         struct manio *cmanio=NULL; // previous (current) manifest
    1034          10 :         struct manio *hmanio=NULL; // to look up deleted hardlinks
    1035          10 :         struct sbuf *cb=NULL; // file list in current manifest
    1036          10 :         struct sbuf *p1b=NULL; // file list from client
    1037          10 :         struct sbuf *rb=NULL; // receiving file from client
    1038          10 :         struct asfd *asfd=NULL;
    1039          10 :         int breaking=0;
    1040          10 :         int breakcount=0;
    1041          10 :         struct cntr *cntr=NULL;
    1042             : 
    1043          10 :         if(!as)
    1044             :         {
    1045           1 :                 logp("async not provided to %s()\n", __func__);
    1046           1 :                 goto error;
    1047             :         }
    1048           9 :         if(!sdirs)
    1049             :         {
    1050           2 :                 logp("sdirs not provided to %s()\n", __func__);
    1051           2 :                 goto error;
    1052             :         }
    1053           7 :         if(!cconfs)
    1054             :         {
    1055           1 :                 logp("cconfs not provided to %s()\n", __func__);
    1056           1 :                 goto error;
    1057             :         }
    1058           6 :         asfd=as->asfd;
    1059           6 :         if(!asfd)
    1060             :         {
    1061           1 :                 logp("asfd not provided to %s()\n", __func__);
    1062           1 :                 goto error;
    1063             :         }
    1064           5 :         cntr=get_cntr(cconfs);
    1065             : 
    1066           5 :         if(get_int(cconfs[OPT_BREAKPOINT])>=2000
    1067           0 :           && get_int(cconfs[OPT_BREAKPOINT])<3000)
    1068             :         {
    1069           0 :                 breaking=get_int(cconfs[OPT_BREAKPOINT]);
    1070           0 :                 breakcount=breaking-2000;
    1071             :         }
    1072             : 
    1073           5 :         logp("Begin phase2 (receive file data)\n");
    1074             : 
    1075           5 :         if(!(dpth=dpth_alloc())
    1076           5 :           || dpth_protocol1_init(dpth, sdirs->currentdata,
    1077             :                 get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
    1078             :                         goto error;
    1079             : 
    1080           5 :         if(maybe_open_previous_manifest(&cmanio, sdirs, incexc, cconfs))
    1081             :                 goto error;
    1082             :         // If the first file that others hardlink to has been deleted, we will
    1083             :         // need to look through the previous manifest to find the information
    1084             :         // for that original file, in order to not have to copy all the data
    1085             :         // across again.
    1086           5 :         if(open_previous_manifest(&hmanio, sdirs))
    1087             :                 goto error;
    1088             : 
    1089           5 :         if(get_int(cconfs[OPT_DIRECTORY_TREE]))
    1090             :         {
    1091             :                 // Need to make sure we do not try to create a path that is
    1092             :                 // too long.
    1093           5 :                 if(build_path_w(sdirs->treepath)) goto error;
    1094           5 :                 mkdir(sdirs->treepath, 0777);
    1095           5 :                 treepathlen=strlen(sdirs->treepath);
    1096           5 :                 if(init_fs_max(sdirs->treepath))
    1097             :                         goto error;
    1098             :         }
    1099             : 
    1100           5 :         if(resume)
    1101             :         {
    1102           0 :                 if(!(p1pos=do_resume(sdirs, dpth, cconfs)))
    1103             :                         goto error;
    1104           0 :                 if(cntr_send_sdirs(asfd, sdirs, cconfs))
    1105             :                         goto error;
    1106             :         }
    1107             : 
    1108           5 :         if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", PROTO_1))
    1109           5 :           || (resume && manio_seek(p1manio, p1pos)))
    1110             :                 goto error;
    1111           5 :         if(!(cb=sbuf_alloc(PROTO_1))
    1112           5 :           || !(p1b=sbuf_alloc(PROTO_1))
    1113           5 :           || !(rb=sbuf_alloc(PROTO_1)))
    1114             :                 goto error;
    1115             : 
    1116             :         // Unchanged and changed should now be truncated correctly, we just
    1117             :         // have to open them for appending.
    1118             :         // Data is not getting written to a compressed file.
    1119             :         // This is important for recovery if the power goes.
    1120           5 :         if(!(ucmanio=manio_open_phase2(sdirs->unchanged, "ab", PROTO_1))
    1121           5 :           || !(chmanio=manio_open_phase2(sdirs->changed, "ab", PROTO_1)))
    1122             :                 goto error;
    1123             : 
    1124             :         while(1)
    1125             :         {
    1126         921 :                 if(breaking && breakcount--==0)
    1127           0 :                         return breakpoint(breaking, __func__);
    1128             : 
    1129         921 :                 if(write_status(CNTR_STATUS_BACKUP,
    1130         921 :                         rb->path.buf?rb->path.buf:"", cntr))
    1131             :                                 goto error;
    1132        1842 :                 if(last_requested
    1133         921 :                   || !p1manio
    1134          16 :                   || asfd->writebuflen)
    1135             :                 {
    1136         905 :                         iobuf_free_content(asfd->rbuf);
    1137         905 :                         if(asfd->as->read_write(asfd->as))
    1138             :                         {
    1139           0 :                                 logp("error in %s\n", __func__);
    1140           0 :                                 goto error;
    1141             :                         }
    1142             : 
    1143         905 :                         if(asfd->rbuf->buf)
    1144          85 :                           switch(do_stuff_to_receive(asfd, sdirs,
    1145             :                                 cconfs, rb, chmanio, dpth, &last_requested))
    1146             :                         {
    1147             :                                 case STR_OK:
    1148             :                                         break;
    1149             :                                 case STR_FINISHED:
    1150             :                                         goto end;
    1151             :                                 case STR_ERROR:
    1152             :                                         goto error;
    1153             :                         }
    1154             :                 }
    1155             : 
    1156         916 :                 if(p1b) switch(do_stuff_to_send(asfd, p1b, &last_requested))
    1157             :                 {
    1158             :                         case STS_OK:
    1159          61 :                                 sbuf_free(&p1b);
    1160          61 :                                 break;
    1161             :                         case STS_BLOCKED:
    1162           2 :                                 continue;
    1163             :                         case STS_ERROR:
    1164             :                                 goto error;
    1165             :                 }
    1166             : 
    1167         914 :                 if(p1manio
    1168         135 :                  && process_next_file_from_manios(asfd, sdirs,
    1169             :                         &p1manio, &cmanio, ucmanio, &hmanio, &p1b, cb, cconfs))
    1170             :                                         goto error;
    1171             :         }
    1172             : 
    1173             : error:
    1174             :         ret=-1;
    1175             : end:
    1176          10 :         if(manio_close(&chmanio))
    1177             :         {
    1178           0 :                 logp("error closing %s in %s\n", sdirs->changed, __func__);
    1179           0 :                 ret=-1;
    1180             :         }
    1181          10 :         if(manio_close(&ucmanio))
    1182             :         {
    1183           0 :                 logp("error closing %s in %s\n", sdirs->unchanged, __func__);
    1184           0 :                 ret=-1;
    1185             :         }
    1186          10 :         free_w(&deltmppath);
    1187          10 :         free_w(&last_requested);
    1188          10 :         sbuf_free(&cb);
    1189          10 :         sbuf_free(&p1b);
    1190          10 :         sbuf_free(&rb);
    1191          10 :         manio_close(&p1manio);
    1192          10 :         manio_close(&cmanio);
    1193          10 :         manio_close(&hmanio);
    1194          10 :         dpth_free(&dpth);
    1195          10 :         man_off_t_free(&p1pos);
    1196          10 :         if(!ret && sdirs)
    1197           5 :                 unlink(sdirs->phase1data);
    1198             : 
    1199          10 :         logp("End phase2 (receive file data)\n");
    1200             : 
    1201          10 :         return ret;
    1202             : }

Generated by: LCOV version 1.10