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 456 71.1 %
Date: 2017-04-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           0 : static int get_hardlink_master_from_hmanio(
     274             :         struct manio **hmanio,
     275             :         struct sbuf *cb,
     276             :         struct sbuf *hb
     277             : ) {
     278             :         while(1)
     279             :         {
     280           0 :                 sbuf_free_content(hb);
     281           0 :                 switch(manio_read(*hmanio, hb))
     282             :                 {
     283             :                         case 0: // Keep going.
     284             :                                 break;
     285             :                         case 1: // Finished OK.
     286           0 :                                 manio_close(hmanio);
     287             :                                 return 0;
     288             :                         default: // Error;
     289             :                                 return -1;
     290             :                 }
     291           0 :                 if(hb->path.cmd!=CMD_FILE
     292           0 :                   && hb->path.cmd!=CMD_ENC_FILE)
     293           0 :                         continue;
     294           0 :                 if(!strcmp(hb->path.buf, cb->link.buf))
     295             :                         return 1; // Found it.
     296             :         }
     297             :         return -1;
     298             : }
     299             : 
     300           0 : static int relink_deleted_hardlink_master(
     301             :         struct manio **hmanio,
     302             :         struct sdirs *sdirs,
     303             :         struct sbuf *p1b,
     304             :         struct sbuf *cb,
     305             :         struct conf **cconfs
     306             : ) {
     307           0 :         int ret=-1;
     308           0 :         char *oldpath=NULL;
     309           0 :         char *newpath=NULL;
     310             :         struct stat statp;
     311           0 :         struct sbuf *hb=NULL;
     312             : 
     313           0 :         if(!(hb=sbuf_alloc(PROTO_1)))
     314             :                 goto end;
     315             : 
     316           0 :         switch(get_hardlink_master_from_hmanio(hmanio, cb, hb))
     317             :         {
     318             :                 case 0: // Did not find it.
     319             :                         return 0;
     320             :                 case 1: // Found it.
     321             :                         break;
     322             :                 default: // Error.
     323             :                         goto end;
     324             :         }
     325             : 
     326             :         // Protect against the old file being encrypted, and the new file not
     327             :         // being encrypted - and vice versa.
     328           0 :         if(p1b->path.cmd!=hb->path.cmd)
     329             :                 return 0;
     330             : 
     331           0 :         if(!(oldpath=prepend_s(sdirs->ctreepath, cb->link.buf))
     332           0 :           || !(newpath=prepend_s(sdirs->treepath, p1b->path.buf)))
     333             :                 goto end;
     334           0 :         if(lstat(oldpath, &statp) || !S_ISREG(statp.st_mode))
     335             :         {
     336             :                 ret=0;
     337             :                 goto end;
     338             :         }
     339           0 :         if(build_path_w(newpath))
     340             :                 goto end;
     341           0 :         if(do_link(oldpath, newpath, &statp, cconfs, /*overwrite*/0))
     342             :                 goto end;
     343             : 
     344           0 :         iobuf_move(&cb->protocol1->datapth, &hb->protocol1->datapth);
     345           0 :         iobuf_move(&cb->endfile, &hb->endfile);
     346             : 
     347           0 :         ret=1;
     348             : end:
     349           0 :         free_w(&oldpath);
     350           0 :         free_w(&newpath);
     351           0 :         sbuf_free(&hb);
     352             :         return ret;
     353             : }
     354             : 
     355          10 : static enum processed_e maybe_do_delta_stuff(struct asfd *asfd,
     356             :         struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
     357             :         struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
     358             : {
     359          10 :         int oldcompressed=0;
     360          10 :         int compression=p1b->compression;
     361             : 
     362             :         // If the file type changed, I think it is time to back it up again
     363             :         // (for example, EFS changing to normal file, or back again).
     364          10 :         if(cb->path.cmd!=p1b->path.cmd)
     365             :         {
     366           0 :                 if(hmanio && *hmanio
     367           0 :                   && cb->path.cmd==CMD_HARD_LINK
     368           0 :                   && (p1b->path.cmd==CMD_FILE
     369           0 :                         || p1b->path.cmd==CMD_ENC_FILE))
     370             :                 {
     371           0 :                         struct stat *p1statp=&p1b->statp;
     372           0 :                         struct stat *cstatp=&cb->statp;
     373             :                         // A hardlink changed into a file. It is possible that
     374             :                         // The file that the hardlink was pointing to got
     375             :                         // deleted. Maybe we can reuse the previous file.
     376           0 :                         if(p1statp->st_dev==cstatp->st_dev
     377           0 :                           && p1statp->st_ino==cstatp->st_ino
     378           0 :                           && p1statp->st_mtime==cstatp->st_mtime)
     379             :                         {
     380           0 :                                 switch(relink_deleted_hardlink_master(
     381             :                                         hmanio, sdirs,
     382             :                                         p1b, cb, cconfs))
     383             :                                 {
     384             :                                         case 0:
     385             :                                                 break;
     386             :                                         case 1:
     387           0 :                                                 return process_unchanged_file(
     388             :                                                         p1b, cb,
     389             :                                                         ucmanio, cconfs);
     390             :                                         default:
     391             :                                                 return P_ERROR;
     392             :                                 }
     393             :                         }
     394             :                 }
     395           0 :                 return process_new(cconfs, p1b, ucmanio);
     396             :         }
     397             : 
     398             :         // mtime is the actual file data.
     399             :         // ctime is the attributes or meta data.
     400          10 :         if(cb->statp.st_mtime==p1b->statp.st_mtime
     401           6 :           && cb->statp.st_ctime==p1b->statp.st_ctime)
     402             :         {
     403             :                 // got an unchanged file
     404             :                 //logp("got unchanged file: %s %c %c\n",
     405             :                 //      cb->path.buf, cb->path.cmd, p1b->path.cmd);
     406           6 :                 return process_unchanged_file(p1b, cb, ucmanio, cconfs);
     407             :         }
     408             : 
     409           4 :         if(cb->statp.st_mtime==p1b->statp.st_mtime
     410           0 :           && cb->statp.st_ctime!=p1b->statp.st_ctime)
     411             :         {
     412             :                 // File data stayed the same, but attributes or meta data
     413             :                 // changed. We already have the attributes, but may need to get
     414             :                 // extra meta data.
     415             :                 // FIX THIS horrible mess.
     416           0 :                 if(cb->path.cmd==CMD_ENC_METADATA
     417           0 :                   || p1b->path.cmd==CMD_ENC_METADATA
     418           0 :                   || cb->path.cmd==CMD_EFS_FILE
     419           0 :                   || p1b->path.cmd==CMD_EFS_FILE
     420             :                 // FIX THIS: make unencrypted metadata use the librsync
     421           0 :                   || cb->path.cmd==CMD_METADATA
     422           0 :                   || p1b->path.cmd==CMD_METADATA
     423           0 :                   || sbuf_is_vssdata(cb)
     424           0 :                   || sbuf_is_vssdata(p1b))
     425           0 :                         return process_new(cconfs, p1b, ucmanio);
     426             :                 // On Windows, we have to back up the whole file if ctime
     427             :                 // changed, otherwise things like permission changes do not get
     428             :                 // noticed. So, in that case, fall through to the changed stuff
     429             :                 // below.
     430             :                 // Non-Windows clients finish here.
     431           0 :                 else if(!get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
     432           0 :                         return process_unchanged_file(p1b,
     433             :                                 cb, ucmanio, cconfs);
     434             :         }
     435             : 
     436             :         // Got a changed file.
     437             :         //logp("got changed file: %s\n", p1b->path.buf);
     438             : 
     439             :         // If either old or new is encrypted, or librsync is off, we need to
     440             :         // get a new file.
     441             :         // FIX THIS horrible mess.
     442           4 :         if(!get_int(cconfs[OPT_LIBRSYNC])
     443             :         // FIX THIS: make unencrypted metadata use the librsync
     444           4 :           || cb->path.cmd==CMD_METADATA
     445           4 :           || p1b->path.cmd==CMD_METADATA
     446           4 :           || sbuf_is_encrypted(cb)
     447           2 :           || sbuf_is_encrypted(p1b)
     448           2 :           || sbuf_is_vssdata(cb)
     449           2 :           || sbuf_is_vssdata(p1b))
     450           2 :                 return process_new(cconfs, p1b, ucmanio);
     451             : 
     452             :         // Get new files if they have switched between compression on or off.
     453           2 :         if(cb->protocol1->datapth.buf
     454           2 :           && dpth_protocol1_is_compressed(cb->compression,
     455             :             cb->protocol1->datapth.buf))
     456           0 :                 oldcompressed=1;
     457           2 :         if( ( oldcompressed && !compression)
     458           2 :          || (!oldcompressed &&  compression))
     459           0 :                 return process_new(cconfs, p1b, ucmanio);
     460             : 
     461             :         // Otherwise, do the delta stuff (if possible).
     462           2 :         if(sbuf_is_filedata(p1b)
     463           0 :           || sbuf_is_vssdata(p1b))
     464           2 :                 return process_changed_file(asfd, cconfs, cb, p1b,
     465           2 :                         sdirs->currentdata);
     466           0 :         return changed_non_file(p1b, ucmanio, p1b->path.cmd, cconfs);
     467             : }
     468             : 
     469             : static enum processed_e process_deleted_file(struct sbuf *cb,
     470             :         struct conf **cconfs)
     471             : {
     472           2 :         cntr_add_deleted(get_cntr(cconfs), cb->path.cmd);
     473             :         return P_DONE_DELETED;
     474             : }
     475             : 
     476             : // return 1 to say that a file was processed
     477          12 : static enum processed_e maybe_process_file(struct asfd *asfd,
     478           2 :         struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
     479             :         struct manio *ucmanio, struct manio **hmanio, struct conf **cconfs)
     480             : {
     481             :         int pcmp;
     482          12 :         if(p1b)
     483             :         {
     484          11 :                 if(!(pcmp=sbuf_pathcmp(cb, p1b)))
     485          10 :                         return maybe_do_delta_stuff(asfd, sdirs, cb, p1b,
     486             :                                 ucmanio, hmanio, cconfs);
     487           1 :                 else if(pcmp>0)
     488             :                 {
     489             :                         //logp("ahead: %s\n", p1b->path.buf);
     490             :                         // ahead - need to get the whole file
     491           0 :                         return process_new(cconfs, p1b, ucmanio);
     492             :                 }
     493             :         }
     494             :         //logp("behind: %s\n", p1b->path.buf);
     495             :         // Behind - need to read more from the old manifest.
     496             :         // Count a deleted file - it was in the old manifest
     497             :         // but not the new.
     498           4 :         return process_deleted_file(cb, cconfs);
     499             : }
     500             : 
     501             : enum sts_e
     502             : {
     503             :         STS_ERROR=-1,
     504             :         STS_OK=0,
     505             :         STS_BLOCKED=1
     506             : };
     507             : 
     508             : // Return 1 if there is still stuff needing to be sent.
     509             : // FIX THIS: lots of repeated code.
     510          63 : static enum sts_e do_stuff_to_send(struct asfd *asfd,
     511             :         struct sbuf *p1b, char **last_requested)
     512             : {
     513             :         static struct iobuf wbuf;
     514          63 :         if(p1b->flags & SBUF_SEND_DATAPTH)
     515             :         {
     516           2 :                 iobuf_copy(&wbuf, &p1b->protocol1->datapth);
     517           2 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     518             :                 {
     519             :                         case APPEND_OK: break;
     520             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     521           0 :                         default: return STS_ERROR;
     522             :                 }
     523           2 :                 p1b->flags &= ~SBUF_SEND_DATAPTH;
     524             :         }
     525          63 :         if(p1b->flags & SBUF_SEND_STAT)
     526             :         {
     527          56 :                 iobuf_copy(&wbuf, &p1b->attr);
     528          56 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     529             :                 {
     530             :                         case APPEND_OK: break;
     531             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     532           0 :                         default: return STS_ERROR;
     533             :                 }
     534          56 :                 p1b->flags &= ~SBUF_SEND_STAT;
     535             :         }
     536          63 :         if(p1b->flags & SBUF_SEND_PATH)
     537             :         {
     538          56 :                 iobuf_copy(&wbuf, &p1b->path);
     539          56 :                 switch(asfd->append_all_to_write_buffer(asfd, &wbuf))
     540             :                 {
     541             :                         case APPEND_OK: break;
     542             :                         case APPEND_BLOCKED: return STS_BLOCKED;
     543           0 :                         default: return STS_ERROR;
     544             :                 }
     545          56 :                 p1b->flags &= ~SBUF_SEND_PATH;
     546          56 :                 free_w(last_requested);
     547          56 :                 if(!(*last_requested=strdup_w(p1b->path.buf, __func__)))
     548             :                         return STS_ERROR;
     549             :         }
     550          63 :         if(p1b->protocol1->sigjob && !(p1b->flags & SBUF_SEND_ENDOFSIG))
     551             :         {
     552             :                 rs_result sigresult;
     553             : 
     554           4 :                 switch((sigresult=rs_async(p1b->protocol1->sigjob,
     555             :                         &(p1b->protocol1->rsbuf),
     556             :                         p1b->protocol1->infb, p1b->protocol1->outfb)))
     557             :                 {
     558             :                         case RS_DONE:
     559           2 :                                 p1b->flags |= SBUF_SEND_ENDOFSIG;
     560           2 :                                 break;
     561             :                         case RS_BLOCKED:
     562             :                         case RS_RUNNING:
     563             :                                 // keep going round the loop.
     564             :                                 return STS_BLOCKED;
     565             :                         default:
     566           0 :                                 logp("error in rs_async: %d\n", sigresult);
     567           0 :                                 return STS_ERROR;
     568             :                 }
     569             :         }
     570          61 :         if(p1b->flags & SBUF_SEND_ENDOFSIG)
     571             :         {
     572           2 :                 iobuf_from_str(&wbuf, CMD_END_FILE, (char *)"endfile");
     573           2 :                 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           2 :                 p1b->flags &= ~SBUF_SEND_ENDOFSIG;
     580             :         }
     581             :         return STS_OK;
     582             : }
     583             : 
     584           4 : static int start_to_receive_delta(struct sdirs *sdirs, struct sbuf *rb)
     585             : {
     586           4 :         if(rb->compression)
     587             :         {
     588           0 :                 if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
     589           0 :                         comp_level(rb->compression))))
     590             :                                 return -1;
     591             :         }
     592             :         else
     593             :         {
     594           4 :                 if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
     595             :                         return -1;
     596             :         }
     597           4 :         rb->flags |= SBUF_RECV_DELTA;
     598             : 
     599             :         return 0;
     600             : }
     601             : 
     602           4 : static int finish_delta(struct sdirs *sdirs, struct sbuf *rb)
     603             : {
     604           4 :         int ret=0;
     605           4 :         char *deltmp=NULL;
     606           4 :         char *delpath=NULL;
     607           4 :         if(!(deltmp=prepend_s("deltas.forward", rb->protocol1->datapth.buf))
     608           4 :           || !(delpath=prepend_s(sdirs->working, deltmp))
     609           4 :           || mkpath(&delpath, sdirs->working)
     610             :         // Rename race condition is of no consequence here, as delpath will
     611             :         // just get recreated.
     612           4 :           || do_rename(sdirs->deltmppath, delpath))
     613             :                 ret=-1;
     614           4 :         free_w(&delpath);
     615           4 :         free_w(&deltmp);
     616           4 :         return ret;
     617             : }
     618             : 
     619           8 : static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
     620           4 :         struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
     621             :         char **last_requested)
     622             : {
     623           8 :         int ret=-1;
     624             :         static char *cp=NULL;
     625             :         static struct iobuf *rbuf;
     626           8 :         struct cntr *cntr=get_cntr(cconfs);
     627           8 :         rbuf=asfd->rbuf;
     628             :         // Finished the file.
     629             :         // Write it to the phase2 file, and free the buffers.
     630             : 
     631           8 :         if(fzp_close(&(rb->protocol1->fzp)))
     632             :         {
     633           0 :                 logp("error closing delta for %s in receive\n", rb->path.buf);
     634             :                 goto end;
     635             :         }
     636           8 :         iobuf_move(&rb->endfile, rbuf);
     637          12 :         if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
     638             :                 goto end;
     639             : 
     640           8 :         if(manio_write_sbuf(chmanio, rb))
     641             :                 goto end;
     642             : 
     643           8 :         if(rb->flags & SBUF_RECV_DELTA)
     644           4 :                 cntr_add_changed(cntr, rb->path.cmd);
     645             :         else
     646           4 :                 cntr_add(cntr, rb->path.cmd, 0);
     647             : 
     648           8 :         if(*last_requested && !strcmp(rb->path.buf, *last_requested))
     649           2 :                 free_w(last_requested);
     650             : 
     651           8 :         cp=strchr(rb->endfile.buf, ':');
     652           8 :         if(rb->endfile.buf)
     653           8 :                 cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
     654             :         if(cp)
     655             :         {
     656             :                 // checksum stuff goes here
     657             :         }
     658             : 
     659             :         ret=0;
     660             : end:
     661           8 :         sbuf_free_content(rb);
     662           8 :         return ret;
     663             : }
     664             : 
     665           8 : static int deal_with_receive_append(struct asfd *asfd, struct sbuf *rb)
     666             : {
     667           8 :         int app=0;
     668             :         static struct iobuf *rbuf;
     669           8 :         rbuf=asfd->rbuf;
     670             :         //logp("rbuf->len: %d\n", rbuf->len);
     671             : 
     672           8 :         if(rb->protocol1->fzp)
     673           8 :                 app=fzp_write(rb->protocol1->fzp, rbuf->buf, rbuf->len);
     674             : 
     675           8 :         if(app>0) return 0;
     676           0 :         logp("error when appending: %d\n", app);
     677           0 :         asfd->write_str(asfd, CMD_ERROR, "write failed");
     678             :         return -1;
     679             : }
     680             : 
     681           8 : static int deal_with_filedata(struct asfd *asfd,
     682             :         struct sdirs *sdirs, struct sbuf *rb,
     683             :         struct iobuf *rbuf, struct dpth *dpth, struct conf **cconfs)
     684             : {
     685           8 :         iobuf_move(&rb->path, rbuf);
     686             : 
     687           8 :         if(rb->protocol1->datapth.buf)
     688             :         {
     689             :                 // Receiving a delta.
     690           4 :                 if(start_to_receive_delta(sdirs, rb))
     691             :                 {
     692           0 :                         logp("error in start_to_receive_delta\n");
     693           0 :                         return -1;
     694             :                 }
     695             :                 return 0;
     696             :         }
     697             : 
     698             :         // Receiving a whole new file.
     699           4 :         if(start_to_receive_new_file(asfd, sdirs, cconfs, rb, dpth))
     700             :         {
     701           0 :                 logp("error in start_to_receive_new_file\n");
     702           0 :                 return -1;
     703             :         }
     704             :         return 0;
     705             : }
     706             : 
     707             : enum str_e
     708             : {
     709             :         STR_ERROR=-1,
     710             :         STR_OK=0,
     711             :         STR_FINISHED=1
     712             : };
     713             : 
     714             : // returns 1 for finished ok.
     715          85 : static enum str_e do_stuff_to_receive(struct asfd *asfd,
     716             :         struct sdirs *sdirs, struct conf **cconfs,
     717             :         struct sbuf *rb, struct manio *chmanio,
     718             :         struct dpth *dpth, char **last_requested)
     719             : {
     720          85 :         struct iobuf *rbuf=asfd->rbuf;
     721             : 
     722         170 :         if(rbuf->cmd==CMD_MESSAGE
     723          85 :           || rbuf->cmd==CMD_WARNING)
     724             :         {
     725           0 :                 struct cntr *cntr=NULL;
     726           0 :                 if(cconfs) cntr=get_cntr(cconfs);
     727           0 :                 log_recvd(rbuf, cntr, 0);
     728           0 :                 return STR_OK;
     729             :         }
     730             : 
     731          85 :         if(rb->protocol1->fzp)
     732             :         {
     733             :                 // Currently writing a file (or meta data)
     734          16 :                 switch(rbuf->cmd)
     735             :                 {
     736             :                         case CMD_APPEND:
     737           8 :                                 if(deal_with_receive_append(asfd, rb))
     738             :                                         goto error;
     739             :                                 return STR_OK;
     740             :                         case CMD_END_FILE:
     741           8 :                                 if(deal_with_receive_end_file(asfd, sdirs, rb,
     742             :                                         chmanio, cconfs, last_requested))
     743             :                                                 goto error;
     744             :                                 return STR_OK;
     745             :                         default:
     746           0 :                                 iobuf_log_unexpected(rbuf, __func__);
     747           0 :                                 goto error;
     748             :                 }
     749             :         }
     750             : 
     751             :         // Otherwise, expecting to be told of a file to save.
     752          69 :         switch(rbuf->cmd)
     753             :         {
     754             :                 case CMD_DATAPTH:
     755           4 :                         iobuf_move(&rb->protocol1->datapth, rbuf);
     756           4 :                         return STR_OK;
     757             :                 case CMD_ATTRIBS:
     758           8 :                         iobuf_move(&rb->attr, rbuf);
     759           8 :                         attribs_decode(rb);
     760           8 :                         return STR_OK;
     761             :                 case CMD_GEN:
     762           5 :                         if(!strcmp(rbuf->buf, "okbackupphase2end"))
     763             :                                 goto end_phase2;
     764           0 :                         iobuf_log_unexpected(rbuf, __func__);
     765           0 :                         goto error;
     766             :                 case CMD_INTERRUPT:
     767             :                         // Interrupt - forget about the last requested
     768             :                         // file if it matches. Otherwise, we can get
     769             :                         // stuck on the select in the async stuff,
     770             :                         // waiting for something that will never arrive.
     771          44 :                         if(*last_requested
     772          44 :                           && !strcmp(rbuf->buf, *last_requested))
     773           1 :                                 free_w(last_requested);
     774             :                         return STR_OK;
     775             :                 default:
     776             :                         break;
     777             :         }
     778           8 :         if(iobuf_is_filedata(rbuf)
     779           0 :           || iobuf_is_vssdata(rbuf))
     780             :         {
     781           8 :                 if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
     782             :                         goto error;
     783             :                 return STR_OK;
     784             :         }
     785           0 :         iobuf_log_unexpected(rbuf, __func__);
     786             : 
     787             : error:
     788             :         return STR_ERROR;
     789             : end_phase2:
     790             :         return STR_FINISHED;
     791             : }
     792             : 
     793           5 : static int vss_opts_changed(struct sdirs *sdirs, struct conf **cconfs,
     794             :         const char *incexc)
     795             : {
     796           5 :         int ret=-1;
     797             :         struct conf **oldconfs;
     798             :         struct conf **newconfs;
     799           5 :         if(!(oldconfs=confs_alloc())
     800           5 :           || !(newconfs=confs_alloc()))
     801             :                 goto end;
     802           5 :         confs_init(oldconfs);
     803           5 :         confs_init(newconfs);
     804             : 
     805             :         // Figure out the old config, which is in the incexc file left
     806             :         // in the current backup directory on the server.
     807           5 :         if(conf_parse_incexcs_path(oldconfs, sdirs->cincexc))
     808             :         {
     809             :                 // Assume that the file did not exist, and therefore
     810             :                 // the old split_vss setting is 0.
     811           4 :                 set_int(oldconfs[OPT_SPLIT_VSS], 0);
     812           4 :                 set_int(oldconfs[OPT_STRIP_VSS], 0);
     813             :         }
     814             : 
     815             :         // Figure out the new config, which is either in the incexc file from
     816             :         // the client, or in the cconf on the server.
     817           5 :         if(incexc)
     818             :         {
     819           0 :                 if(conf_parse_incexcs_buf(newconfs, incexc))
     820             :                 {
     821             :                         // Should probably not got here.
     822           0 :                         set_int(newconfs[OPT_SPLIT_VSS], 0);
     823           0 :                         set_int(newconfs[OPT_STRIP_VSS], 0);
     824             :                 }
     825             :         }
     826             :         else
     827             :         {
     828           5 :                 set_int(newconfs[OPT_SPLIT_VSS],
     829           5 :                         get_int(cconfs[OPT_SPLIT_VSS]));
     830           5 :                 set_int(newconfs[OPT_STRIP_VSS],
     831           5 :                         get_int(cconfs[OPT_STRIP_VSS]));
     832             :         }
     833             : 
     834           5 :         if(get_int(newconfs[OPT_SPLIT_VSS])!=get_int(oldconfs[OPT_SPLIT_VSS]))
     835             :         {
     836           0 :                 logp("split_vss=%d (changed since last backup)\n",
     837           0 :                         get_int(newconfs[OPT_SPLIT_VSS]));
     838           0 :                 ret=1; goto end;
     839             :         }
     840           5 :         if(get_int(newconfs[OPT_STRIP_VSS])!=get_int(oldconfs[OPT_STRIP_VSS]))
     841             :         {
     842           0 :                 logp("strip_vss=%d (changed since last backup)\n",
     843           0 :                         get_int(newconfs[OPT_STRIP_VSS]));
     844           0 :                 ret=1; goto end;
     845             :         }
     846             :         ret=0;
     847             : end:
     848           5 :         if(ret==1) logp("All files will be treated as new\n");
     849           5 :         confs_free(&oldconfs);
     850           5 :         confs_free(&newconfs);
     851           5 :         return ret;
     852             : }
     853             : 
     854          10 : static int open_previous_manifest(struct manio **manio, struct sdirs *sdirs)
     855             : {
     856             :         struct stat statp;
     857          20 :         if(!lstat(sdirs->cmanifest, &statp)
     858           2 :           && !(*manio=manio_open(sdirs->cmanifest, "rb", PROTO_1)))
     859             :         {
     860           0 :                 logp("could not open old manifest %s\n", sdirs->cmanifest);
     861             :                 return -1;
     862             :         }
     863             :         return 0;
     864             : }
     865             : 
     866             : // Maybe open the previous (current) manifest.
     867             : // If the split_vss setting changed between the previous backup and the new
     868             : // backup, do not open the previous manifest. This will have the effect of
     869             : // making the client back up everything fresh. Need to do this, otherwise
     870             : // toggling split_vss on and off will result in backups that do not work.
     871           5 : static int maybe_open_previous_manifest(struct manio **manio,
     872             :         struct sdirs *sdirs, const char *incexc, struct conf **cconfs)
     873             : {
     874           5 :         if(vss_opts_changed(sdirs, cconfs, incexc))
     875             :                 return 0;
     876           5 :         return open_previous_manifest(manio, sdirs);
     877             : }
     878             : 
     879         135 : static int process_next_file_from_manios(struct asfd *asfd,
     880             :         struct sdirs *sdirs,
     881             :         struct manio **p1manio,
     882             :         struct manio **cmanio,
     883             :         struct manio *ucmanio,
     884             :         struct manio **hmanio,
     885             :         struct sbuf **p1b,
     886             :         struct sbuf *cb,
     887             :         struct conf **cconfs)
     888             : {
     889         135 :         if(!(*p1b=sbuf_alloc(PROTO_1)))
     890             :                 goto error;
     891         135 :         switch(manio_read(*p1manio, *p1b))
     892             :         {
     893             :                 case 0:
     894             :                         break;
     895             :                 case 1:
     896           5 :                         manio_close(p1manio);
     897           5 :                         if(asfd->write_str(asfd, CMD_GEN, "backupphase2end"))
     898             :                                 goto error;
     899           5 :                         sbuf_free(p1b);
     900           5 :                         break;
     901             :                 case -1:
     902             :                         goto error;
     903             :         }
     904             : 
     905         135 :         if(!*cmanio)
     906             :         {
     907         124 :                 if(!*p1b) return 0;
     908             :                 // No old manifest, need to ask for a new file.
     909         120 :                 switch(process_new(cconfs, *p1b, ucmanio))
     910             :                 {
     911             :                         case P_NEW:
     912             :                                 return 0;
     913             :                         case P_DONE_NEW:
     914             :                                 goto p1b_done;
     915             :                         default:
     916             :                                 goto error;
     917             :                 }
     918             :         }
     919             : 
     920             :         // Have an old manifest, look for it there.
     921             : 
     922             :         // Might already have it, or be ahead in the old
     923             :         // manifest.
     924          11 :         if(cb->path.buf)
     925             :         {
     926           2 :                 switch(maybe_process_file(asfd,
     927             :                         sdirs, cb, *p1b, ucmanio, hmanio, cconfs))
     928             :                 {
     929             :                         case P_NEW:
     930             :                                 return 0;
     931             :                         case P_CHANGED:
     932             :                                 // Free cb content for things like encrypted
     933             :                                 // files, which we only pretend are new.
     934           0 :                                 sbuf_free_content(cb);
     935           0 :                                 return 0;
     936             :                         case P_DONE_NEW:
     937             :                                 goto p1b_done;
     938             :                         case P_DONE_CHANGED:
     939             :                         case P_DONE_UNCHANGED:
     940           0 :                                 sbuf_free_content(cb);
     941           0 :                                 goto p1b_done;
     942             :                         case P_DONE_DELETED:
     943           2 :                                 sbuf_free_content(cb);
     944           2 :                                 break;
     945             :                         case P_ERROR:
     946             :                                 goto error;
     947             :                 }
     948             :         }
     949             : 
     950             :         while(1)
     951             :         {
     952          11 :                 sbuf_free_content(cb);
     953          11 :                 switch(manio_read(*cmanio, cb))
     954             :                 {
     955             :                         case 0: break;
     956           1 :                         case 1: manio_close(cmanio);
     957           1 :                                 if(*p1b) switch(process_new(cconfs,
     958             :                                         *p1b, ucmanio))
     959             :                                 {
     960             :                                         case P_NEW:
     961             :                                                 return 0;
     962             :                                         case P_DONE_NEW:
     963             :                                                 goto p1b_done;
     964             :                                         default:
     965             :                                                 goto error;
     966             :                                 }
     967             :                                 return 0;
     968             :                         case -1: goto error;
     969             :                 }
     970          10 :                 switch(maybe_process_file(asfd, sdirs,
     971             :                         cb, *p1b, ucmanio, hmanio, cconfs))
     972             :                 {
     973             :                         case P_NEW:
     974             :                                 return 0;
     975             :                         case P_CHANGED:
     976             :                                 // Free cb content for things like encrypted
     977             :                                 // files, which we only pretend are new.
     978           2 :                                 sbuf_free_content(cb);
     979           2 :                                 return 0;
     980             :                         case P_DONE_NEW:
     981             :                                 goto p1b_done;
     982             :                         case P_DONE_CHANGED:
     983             :                         case P_DONE_UNCHANGED:
     984           6 :                                 sbuf_free_content(cb);
     985           6 :                                 goto p1b_done;
     986             :                         case P_DONE_DELETED:
     987           0 :                                 sbuf_free_content(cb);
     988           0 :                                 continue;
     989             :                         case P_ERROR:
     990             :                                 goto error;
     991             :                 }
     992             :         }
     993             : error:
     994             :         return -1;
     995             : p1b_done:
     996          74 :         sbuf_free(p1b);
     997          74 :         return 0;
     998             : }
     999             : 
    1000          10 : int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
    1001             :         const char *incexc, int resume, struct conf **cconfs)
    1002             : {
    1003          10 :         int ret=0;
    1004          10 :         man_off_t *p1pos=NULL;
    1005          10 :         struct manio *p1manio=NULL;
    1006          10 :         struct dpth *dpth=NULL;
    1007          10 :         char *deltmppath=NULL;
    1008          10 :         char *last_requested=NULL;
    1009          10 :         struct manio *chmanio=NULL; // changed data
    1010          10 :         struct manio *ucmanio=NULL; // unchanged data
    1011          10 :         struct manio *cmanio=NULL; // previous (current) manifest
    1012          10 :         struct manio *hmanio=NULL; // to look up deleted hardlinks
    1013          10 :         struct sbuf *cb=NULL; // file list in current manifest
    1014          10 :         struct sbuf *p1b=NULL; // file list from client
    1015          10 :         struct sbuf *rb=NULL; // receiving file from client
    1016          10 :         struct asfd *asfd=NULL;
    1017          10 :         int breaking=0;
    1018          10 :         int breakcount=0;
    1019          10 :         struct cntr *cntr=NULL;
    1020             : 
    1021          10 :         if(!as)
    1022             :         {
    1023           1 :                 logp("async not provided to %s()\n", __func__);
    1024           1 :                 goto error;
    1025             :         }
    1026           9 :         if(!sdirs)
    1027             :         {
    1028           2 :                 logp("sdirs not provided to %s()\n", __func__);
    1029           2 :                 goto error;
    1030             :         }
    1031           7 :         if(!cconfs)
    1032             :         {
    1033           1 :                 logp("cconfs not provided to %s()\n", __func__);
    1034           1 :                 goto error;
    1035             :         }
    1036           6 :         asfd=as->asfd;
    1037           6 :         if(!asfd)
    1038             :         {
    1039           1 :                 logp("asfd not provided to %s()\n", __func__);
    1040           1 :                 goto error;
    1041             :         }
    1042           5 :         cntr=get_cntr(cconfs);
    1043             : 
    1044           5 :         if(get_int(cconfs[OPT_BREAKPOINT])>=2000
    1045           0 :           && get_int(cconfs[OPT_BREAKPOINT])<3000)
    1046             :         {
    1047           0 :                 breaking=get_int(cconfs[OPT_BREAKPOINT]);
    1048           0 :                 breakcount=breaking-2000;
    1049             :         }
    1050             : 
    1051           5 :         logp("Begin phase2 (receive file data)\n");
    1052             : 
    1053           5 :         if(!(dpth=dpth_alloc())
    1054           5 :           || dpth_protocol1_init(dpth, sdirs->currentdata,
    1055             :                 get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
    1056             :                         goto error;
    1057             : 
    1058           5 :         if(maybe_open_previous_manifest(&cmanio, sdirs, incexc, cconfs))
    1059             :                 goto error;
    1060             :         // If the first file that others hardlink to has been deleted, we will
    1061             :         // need to look through the previous manifest to find the information
    1062             :         // for that original file, in order to not have to copy all the data
    1063             :         // across again.
    1064           5 :         if(open_previous_manifest(&hmanio, sdirs))
    1065             :                 goto error;
    1066             : 
    1067           5 :         if(get_int(cconfs[OPT_DIRECTORY_TREE]))
    1068             :         {
    1069             :                 // Need to make sure we do not try to create a path that is
    1070             :                 // too long.
    1071           5 :                 if(build_path_w(sdirs->treepath)) goto error;
    1072           5 :                 mkdir(sdirs->treepath, 0777);
    1073           5 :                 treepathlen=strlen(sdirs->treepath);
    1074           5 :                 if(init_fs_max(sdirs->treepath))
    1075             :                         goto error;
    1076             :         }
    1077             : 
    1078           5 :         if(resume)
    1079             :         {
    1080           0 :                 if(!(p1pos=do_resume(sdirs, dpth, cconfs)))
    1081             :                         goto error;
    1082           0 :                 if(cntr_send_sdirs(asfd, sdirs, cconfs))
    1083             :                         goto error;
    1084             :         }
    1085             : 
    1086           5 :         if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", PROTO_1))
    1087           5 :           || (resume && manio_seek(p1manio, p1pos)))
    1088             :                 goto error;
    1089           5 :         if(!(cb=sbuf_alloc(PROTO_1))
    1090           5 :           || !(p1b=sbuf_alloc(PROTO_1))
    1091           5 :           || !(rb=sbuf_alloc(PROTO_1)))
    1092             :                 goto error;
    1093             : 
    1094             :         // Unchanged and changed should now be truncated correctly, we just
    1095             :         // have to open them for appending.
    1096             :         // Data is not getting written to a compressed file.
    1097             :         // This is important for recovery if the power goes.
    1098           5 :         if(!(ucmanio=manio_open_phase2(sdirs->unchanged, "ab", PROTO_1))
    1099           5 :           || !(chmanio=manio_open_phase2(sdirs->changed, "ab", PROTO_1)))
    1100             :                 goto error;
    1101             : 
    1102             :         while(1)
    1103             :         {
    1104         921 :                 if(breaking && breakcount--==0)
    1105           0 :                         return breakpoint(breaking, __func__);
    1106             : 
    1107         921 :                 if(write_status(CNTR_STATUS_BACKUP,
    1108         921 :                         rb->path.buf?rb->path.buf:"", cntr))
    1109             :                                 goto error;
    1110        1842 :                 if(last_requested
    1111         921 :                   || !p1manio
    1112          16 :                   || asfd->writebuflen)
    1113             :                 {
    1114         905 :                         iobuf_free_content(asfd->rbuf);
    1115         905 :                         if(asfd->as->read_write(asfd->as))
    1116             :                         {
    1117           0 :                                 logp("error in %s\n", __func__);
    1118           0 :                                 goto error;
    1119             :                         }
    1120             : 
    1121         905 :                         if(asfd->rbuf->buf)
    1122          85 :                           switch(do_stuff_to_receive(asfd, sdirs,
    1123             :                                 cconfs, rb, chmanio, dpth, &last_requested))
    1124             :                         {
    1125             :                                 case STR_OK:
    1126             :                                         break;
    1127             :                                 case STR_FINISHED:
    1128             :                                         goto end;
    1129             :                                 case STR_ERROR:
    1130             :                                         goto error;
    1131             :                         }
    1132             :                 }
    1133             : 
    1134         916 :                 if(p1b) switch(do_stuff_to_send(asfd, p1b, &last_requested))
    1135             :                 {
    1136             :                         case STS_OK:
    1137          61 :                                 sbuf_free(&p1b);
    1138          61 :                                 break;
    1139             :                         case STS_BLOCKED:
    1140           2 :                                 continue;
    1141             :                         case STS_ERROR:
    1142             :                                 goto error;
    1143             :                 }
    1144             : 
    1145         914 :                 if(p1manio
    1146         135 :                  && process_next_file_from_manios(asfd, sdirs,
    1147             :                         &p1manio, &cmanio, ucmanio, &hmanio, &p1b, cb, cconfs))
    1148             :                                         goto error;
    1149             :         }
    1150             : 
    1151             : error:
    1152             :         ret=-1;
    1153             : end:
    1154          10 :         if(manio_close(&chmanio))
    1155             :         {
    1156           0 :                 logp("error closing %s in %s\n", sdirs->changed, __func__);
    1157           0 :                 ret=-1;
    1158             :         }
    1159          10 :         if(manio_close(&ucmanio))
    1160             :         {
    1161           0 :                 logp("error closing %s in %s\n", sdirs->unchanged, __func__);
    1162           0 :                 ret=-1;
    1163             :         }
    1164          10 :         free_w(&deltmppath);
    1165          10 :         free_w(&last_requested);
    1166          10 :         sbuf_free(&cb);
    1167          10 :         sbuf_free(&p1b);
    1168          10 :         sbuf_free(&rb);
    1169          10 :         manio_close(&p1manio);
    1170          10 :         manio_close(&cmanio);
    1171          10 :         manio_close(&hmanio);
    1172          10 :         dpth_free(&dpth);
    1173          10 :         man_off_t_free(&p1pos);
    1174          10 :         if(!ret && sdirs)
    1175           5 :                 unlink(sdirs->phase1data);
    1176             : 
    1177          10 :         logp("End phase2 (receive file data)\n");
    1178             : 
    1179          10 :         return ret;
    1180             : }

Generated by: LCOV version 1.10