LCOV - code coverage report
Current view: top level - src/client - restore.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 56 340 16.5 %
Date: 2015-10-31 Functions: 3 19 15.8 %

          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 "../berrno.h"
       7             : #include "../cmd.h"
       8             : #include "../cntr.h"
       9             : #include "../fsops.h"
      10             : #include "../handy.h"
      11             : #include "../log.h"
      12             : #include "../prepend.h"
      13             : #include "../protocol2/blk.h"
      14             : #include "cvss.h"
      15             : #include "protocol1/restore.h"
      16             : #include "protocol2/restore.h"
      17             : #include "restore.h"
      18             : 
      19           0 : int restore_interrupt(struct asfd *asfd,
      20             :         struct sbuf *sb, const char *msg, struct cntr *cntr,
      21             :         enum protocol protocol)
      22             : {
      23           0 :         int ret=0;
      24           0 :         char *path=NULL;
      25           0 :         struct iobuf *rbuf=asfd->rbuf;
      26             : 
      27           0 :         if(cntr)
      28             :         {
      29           0 :                 cntr_add(cntr, CMD_WARNING, 1);
      30           0 :                 logp("WARNING: %s\n", msg);
      31           0 :                 if(asfd->write_str(asfd, CMD_WARNING, msg)) goto end;
      32             :         }
      33             : 
      34             :         // If it is file data, get the server
      35             :         // to interrupt the flow and move on.
      36           0 :         if(!iobuf_is_filedata(&sb->path)
      37           0 :           && !iobuf_is_vssdata(&sb->path))
      38           0 :                 return 0;
      39             : 
      40           0 :         if(protocol==PROTO_1)
      41           0 :                 path=sb->protocol1->datapth.buf;
      42           0 :         else if(protocol==PROTO_2)
      43           0 :                 path=sb->path.buf;
      44             : 
      45           0 :         if(!path) return 0;
      46             : 
      47           0 :         if(asfd->write_str(asfd, CMD_INTERRUPT, path))
      48           0 :                 goto end;
      49             : 
      50             :         // Read to the end file marker.
      51             :         while(1)
      52             :         {
      53           0 :                 iobuf_free_content(rbuf);
      54           0 :                 if(asfd->read(asfd))
      55           0 :                         goto end;
      56           0 :                 if(!rbuf->len) continue;
      57             : 
      58           0 :                 switch(rbuf->cmd)
      59             :                 {
      60             :                         case CMD_APPEND:
      61           0 :                                 continue;
      62             :                         case CMD_END_FILE:
      63           0 :                                 ret=0;
      64           0 :                                 goto end;
      65             :                         default:
      66           0 :                                 iobuf_log_unexpected(rbuf, __func__);
      67           0 :                                 goto end;
      68             :                 }
      69             :         }
      70             : end:
      71           0 :         iobuf_free_content(rbuf);
      72           0 :         return ret;
      73             : }
      74             : 
      75           0 : static int make_link(struct asfd *asfd,
      76             :         const char *fname, const char *lnk, enum cmd cmd, struct cntr *cntr,
      77             :         const char *restore_prefix)
      78             : {
      79           0 :         int ret=-1;
      80             : 
      81             : #ifdef HAVE_WIN32
      82             :         logw(asfd, cntr, "windows seems not to support hardlinks or symlinks\n");
      83             : #else
      84           0 :         unlink(fname);
      85           0 :         if(cmd==CMD_HARD_LINK)
      86             :         {
      87           0 :                 char *flnk=NULL;
      88           0 :                 if(!(flnk=prepend_s(restore_prefix, lnk)))
      89             :                 {
      90           0 :                         log_out_of_memory(__func__);
      91           0 :                         return -1;
      92             :                 }
      93             :                 //printf("%s -> %s\n", fname, flnk);
      94           0 :                 ret=link(flnk, fname);
      95           0 :                 free(flnk);
      96             :         }
      97           0 :         else if(cmd==CMD_SOFT_LINK)
      98             :         {
      99             :                 //printf("%s -> %s\n", fname, lnk);
     100           0 :                 ret=symlink(lnk, fname);
     101             :         }
     102             :         else
     103             :         {
     104           0 :                 logp("unexpected link command: %c\n", cmd);
     105           0 :                 ret=-1;
     106             :         }
     107             : #endif
     108             : 
     109           0 :         if(ret) logp("could not %slink %s -> %s: %s\n",
     110             :                 cmd==CMD_HARD_LINK?"hard":"sym",
     111           0 :                 fname, lnk, strerror(errno));
     112             : 
     113           0 :         return ret;
     114             : }
     115             : 
     116             : // FIX THIS: Maybe should be in bfile.c.
     117           0 : enum ofr_e open_for_restore(struct asfd *asfd, BFILE *bfd, const char *path,
     118             :         struct sbuf *sb, int vss_restore, struct cntr *cntr,
     119             :         enum protocol protocol)
     120             : {
     121             :         static int flags;
     122           0 :         if(bfd->mode!=BF_CLOSED)
     123             :         {
     124             : #ifdef HAVE_WIN32
     125             :                 if(bfd->path && !strcmp(bfd->path, path))
     126             :                 {
     127             :                         // Already open after restoring the VSS data.
     128             :                         // Time now for the actual file data.
     129             :                         return OFR_OK;
     130             :                 }
     131             :                 else
     132             :                 {
     133             : #endif
     134           0 :                         if(bfd->close(bfd, asfd))
     135             :                         {
     136             :                                 logp("error closing %s in %s()\n",
     137           0 :                                         path, __func__);
     138           0 :                                 return OFR_ERROR;
     139             :                         }
     140             : #ifdef HAVE_WIN32
     141             :                 }
     142             : #endif
     143             :         }
     144           0 :         bfile_init(bfd, sb->winattr, cntr);
     145             : #ifdef HAVE_WIN32
     146             :         bfd->set_win32_api(bfd, vss_restore);
     147             : #endif
     148           0 :         if(S_ISDIR(sb->statp.st_mode))
     149             :         {
     150             :                 // Windows directories are treated as having file data.
     151           0 :                 flags=O_WRONLY|O_BINARY;
     152           0 :                 mkdir(path, 0777);
     153             :         }
     154             :         else
     155           0 :                 flags=O_WRONLY|O_BINARY|O_CREAT|O_TRUNC;
     156             : 
     157           0 :         if(bfd->open(bfd, asfd, path, flags, S_IRUSR | S_IWUSR))
     158             :         {
     159             :                 berrno be;
     160           0 :                 berrno_init(&be);
     161           0 :                 char msg[256]="";
     162             :                 snprintf(msg, sizeof(msg), "Could not open for writing %s: %s",
     163           0 :                         path, berrno_bstrerror(&be, errno));
     164           0 :                 if(restore_interrupt(asfd, sb, msg, cntr, protocol))
     165           0 :                         return OFR_ERROR;
     166           0 :                 return OFR_CONTINUE;
     167             :         }
     168             :         // Add attributes to bfd so that they can be set when it is closed.
     169           0 :         bfd->winattr=sb->winattr;
     170           0 :         memcpy(&bfd->statp, &sb->statp, sizeof(struct stat));
     171           0 :         return OFR_OK;
     172             : }
     173             : 
     174           0 : static char *build_msg(const char *text, const char *param)
     175             : {
     176             :         static char msg[256]="";
     177           0 :         snprintf(msg, sizeof(msg), text, param);
     178           0 :         return msg;
     179             : }
     180             : 
     181             : #ifndef HAVE_WIN32
     182           0 : static void do_logw(struct asfd *asfd, struct cntr *cntr,
     183             :         const char *text, const char *param)
     184             : {
     185           0 :         logw(asfd, cntr, "%s", build_msg(text, param));
     186           0 : }
     187             : #endif
     188             : 
     189           0 : static int warn_and_interrupt(struct asfd *asfd, struct sbuf *sb,
     190             :         struct cntr *cntr, enum protocol protocol,
     191             :         const char *text, const char *param)
     192             : {
     193           0 :         return restore_interrupt(asfd, sb, build_msg(text, param), cntr,
     194           0 :                 protocol);
     195             : }
     196             : 
     197           0 : static int restore_special(struct asfd *asfd, struct sbuf *sb,
     198             :         const char *fname, enum action act, struct cntr *cntr,
     199             :         enum protocol protocol)
     200             : {
     201           0 :         int ret=0;
     202           0 :         char *rpath=NULL;
     203             : #ifdef HAVE_WIN32
     204             :         logw(asfd, cntr, "Cannot restore special files to Windows: %s\n", fname);
     205             :         goto end;
     206             : #else
     207           0 :         struct stat statp=sb->statp;
     208             : 
     209           0 :         if(act==ACTION_VERIFY)
     210             :         {
     211           0 :                 cntr_add(cntr, CMD_SPECIAL, 1);
     212           0 :                 return 0;
     213             :         }
     214             : 
     215           0 :         if(build_path(fname, "", &rpath, NULL))
     216             :         {
     217             :                 // failed - do a warning
     218           0 :                 if(restore_interrupt(asfd, sb,
     219           0 :                         build_msg("build path failed: %s", fname),
     220           0 :                         cntr, protocol))
     221           0 :                                 ret=-1;
     222           0 :                 goto end;
     223             :         }
     224           0 :         if(S_ISFIFO(statp.st_mode))
     225             :         {
     226           0 :                 if(mkfifo(rpath, statp.st_mode) && errno!=EEXIST)
     227             :                         do_logw(asfd, cntr,
     228           0 :                                 "Cannot make fifo: %s\n", strerror(errno));
     229             :                 else
     230             :                 {
     231           0 :                         attribs_set(asfd, rpath, &statp, sb->winattr, cntr);
     232           0 :                         cntr_add(cntr, CMD_SPECIAL, 1);
     233             :                 }
     234             :         }
     235             : //      else if(S_ISSOCK(statp.st_mode))
     236             : //              do_logw(asfd, cntr, "Skipping restore of socket: %s\n", fname);
     237             : //
     238             : #ifdef S_IFDOOR     // Solaris high speed RPC mechanism
     239             :         else if (S_ISDOOR(statp.st_mode))
     240             :                 do_logw(asfd, cntr,
     241             :                         "Skipping restore of door file: %s\n", fname);
     242             : #endif
     243             : #ifdef S_IFPORT     // Solaris event port for handling AIO
     244             :         else if (S_ISPORT(statp.st_mode))
     245             :                 do_logw(asfd, cntr,
     246             :                         "Skipping restore of event port file: %s\n", fname);
     247             : #endif
     248           0 :         else if(mknod(fname, statp.st_mode, statp.st_rdev) && errno!=EEXIST)
     249           0 :                 do_logw(asfd, cntr, "Cannot make node: %s\n", strerror(errno));
     250             :         else
     251             :         {
     252           0 :                 attribs_set(asfd, rpath, &statp, sb->winattr, cntr);
     253           0 :                 cntr_add(cntr, CMD_SPECIAL, 1);
     254             :         }
     255             : #endif
     256             : end:
     257           0 :         free_w(&rpath);
     258           0 :         return ret;
     259             : }
     260             : 
     261           0 : int restore_dir(struct asfd *asfd, struct sbuf *sb,
     262             :         const char *dname, enum action act, struct cntr *cntr,
     263             :         enum protocol protocol)
     264             : {
     265           0 :         int ret=0;
     266           0 :         char *rpath=NULL;
     267           0 :         if(act==ACTION_RESTORE)
     268             :         {
     269           0 :                 if(build_path(dname, "", &rpath, NULL))
     270             :                 {
     271             :                         ret=warn_and_interrupt(asfd, sb, cntr, protocol,
     272           0 :                                 "build path failed: %s", dname);
     273           0 :                         goto end;
     274             :                 }
     275           0 :                 else if(is_dir_lstat(rpath)<=0)
     276             :                 {
     277           0 :                         if(mkdir(rpath, 0777))
     278             :                         {
     279             :                                 ret=warn_and_interrupt(asfd, sb, cntr, protocol,
     280           0 :                                         "mkdir error: %s", strerror(errno));
     281           0 :                                 goto end;
     282             :                         }
     283             :                 }
     284           0 :                 attribs_set(asfd, rpath, &(sb->statp), sb->winattr, cntr);
     285           0 :                 if(!ret) cntr_add(cntr, sb->path.cmd, 1);
     286             :         }
     287           0 :         else cntr_add(cntr, sb->path.cmd, 1);
     288             : end:
     289           0 :         free_w(&rpath);
     290           0 :         return ret;
     291             : }
     292             : 
     293           0 : static int restore_link(struct asfd *asfd, struct sbuf *sb,
     294             :         const char *fname, enum action act, struct cntr *cntr,
     295             :         enum protocol protocol, const char *restore_prefix)
     296             : {
     297           0 :         int ret=0;
     298             : 
     299           0 :         if(act==ACTION_RESTORE)
     300             :         {
     301           0 :                 char *rpath=NULL;
     302           0 :                 if(build_path(fname, "", &rpath, NULL))
     303             :                 {
     304             :                         ret=warn_and_interrupt(asfd, sb, cntr, protocol,
     305           0 :                                 "build path failed: %s", fname);
     306           0 :                         goto end;
     307             :                 }
     308           0 :                 else if(make_link(asfd,
     309             :                         fname, sb->link.buf, sb->link.cmd,
     310           0 :                         cntr, restore_prefix))
     311             :                 {
     312             :                         ret=warn_and_interrupt(asfd, sb, cntr, protocol,
     313           0 :                                 "could not create link", "");
     314           0 :                         goto end;
     315             :                 }
     316           0 :                 else if(!ret)
     317             :                 {
     318             :                         attribs_set(asfd, fname,
     319           0 :                                 &(sb->statp), sb->winattr, cntr);
     320           0 :                         cntr_add(cntr, sb->path.cmd, 1);
     321             :                 }
     322           0 :                 free_w(&rpath);
     323             :         }
     324           0 :         else cntr_add(cntr, sb->path.cmd, 1);
     325             : end:
     326           0 :         return ret;
     327             : }
     328             : 
     329           0 : static void strip_invalid_characters(char **path)
     330             : {
     331             : #ifdef HAVE_WIN32
     332             :       char *ch = *path;
     333             :       if (ch[0] != 0 && ch[1] != 0) {
     334             :          ch += 2;
     335             :          while (*ch) {
     336             :             switch (*ch) {
     337             :             case ':':
     338             :             case '<':
     339             :             case '>':
     340             :             case '*':
     341             :             case '?':
     342             :             case '|':
     343             :                *ch = '_';
     344             :                 break;
     345             :             }
     346             :             ch++;
     347             :          }
     348             :       }
     349             : #endif
     350           0 : }
     351             : 
     352           5 : static const char *act_str(enum action act)
     353             : {
     354             :         static const char *ret=NULL;
     355           5 :         if(act==ACTION_RESTORE) ret="restore";
     356           0 :         else ret="verify";
     357           5 :         return ret;
     358             : }
     359             : 
     360             : // Return 1 for ok, -1 for error, 0 for too many components stripped.
     361           0 : static int strip_path_components(struct asfd *asfd,
     362             :         struct sbuf *sb, int strip, struct cntr *cntr, enum protocol protocol)
     363             : {
     364           0 :         int s=0;
     365           0 :         char *tmp=NULL;
     366           0 :         char *cp=sb->path.buf;
     367           0 :         char *dp=NULL;
     368           0 :         for(s=0; cp && *cp && s<strip; s++)
     369             :         {
     370           0 :                 if(!(dp=strchr(cp, '/')))
     371             :                 {
     372           0 :                         char msg[256]="";
     373             :                         snprintf(msg, sizeof(msg),
     374           0 :                           "Stripped too many components: %s", sb->path.buf);
     375           0 :                         if(restore_interrupt(asfd, sb, msg, cntr, protocol))
     376           0 :                                 return -1;
     377           0 :                         return 0;
     378             :                 }
     379           0 :                 cp=dp+1;
     380             :         }
     381           0 :         if(!cp)
     382             :         {
     383           0 :                 char msg[256]="";
     384             :                 snprintf(msg, sizeof(msg),
     385           0 :                         "Stripped too many components: %s", sb->path.buf);
     386           0 :                 if(restore_interrupt(asfd, sb, msg, cntr, protocol))
     387           0 :                         return -1;
     388           0 :                 return 0;
     389             :         }
     390           0 :         if(!(tmp=strdup_w(cp, __func__)))
     391           0 :                 return -1;
     392           0 :         free(sb->path.buf);
     393           0 :         sb->path.buf=tmp;
     394           0 :         return 1;
     395             : }
     396             : 
     397           0 : static int overwrite_ok(struct sbuf *sb,
     398             :         int overwrite,
     399             : #ifdef HAVE_WIN32
     400             :         BFILE *bfd,
     401             : #endif
     402             :         const char *fullpath)
     403             : {
     404             :         struct stat checkstat;
     405             : 
     406             :         // User specified overwrite is OK.
     407             : #ifdef HAVE_WIN32
     408             :         if(overwrite) return 1;
     409             : #else
     410             :         // User specified overwrite is OK,
     411             :         // UNLESS we are trying to overwrite the file with trailing VSS data.
     412           0 :         if(overwrite)
     413           0 :                 return (sb->path.cmd!=CMD_VSS_T
     414           0 :                         && sb->path.cmd!=CMD_ENC_VSS_T);
     415             : #endif
     416             : 
     417           0 :         if(!S_ISDIR(sb->statp.st_mode)
     418           0 :           && sb->path.cmd!=CMD_METADATA
     419           0 :           && sb->path.cmd!=CMD_ENC_METADATA
     420           0 :           && sb->path.cmd!=CMD_VSS
     421           0 :           && sb->path.cmd!=CMD_ENC_VSS)
     422             :         {
     423             : #ifdef HAVE_WIN32
     424             :                 // If Windows previously got some VSS data, it needs to append
     425             :                 // the file data to the already open bfd.
     426             :                 // And trailing VSS data.
     427             :                 if(bfd->mode!=BF_CLOSED
     428             :                   && (sb->path.cmd==CMD_FILE || sb->path.cmd==CMD_ENC_FILE
     429             :                       || sb->path.cmd==CMD_VSS_T || sb->path.cmd==CMD_ENC_VSS_T)
     430             :                   && bfd->path && !strcmp(bfd->path, fullpath))
     431             :                         return 1;
     432             : #endif
     433             :                 // If we have file data and the destination is
     434             :                 // a fifo, it is OK to write to the fifo.
     435           0 :                 if((sb->path.cmd==CMD_FILE || sb->path.cmd==CMD_ENC_FILE)
     436           0 :                   && S_ISFIFO(sb->statp.st_mode))
     437           0 :                         return 1;
     438             : 
     439             :                 // File path exists. Do not overwrite.
     440           0 :                 if(!lstat(fullpath, &checkstat)) return 0;
     441             :         }
     442             : 
     443           0 :         return 1;
     444             : }
     445             : 
     446           0 : static int write_data(struct asfd *asfd, BFILE *bfd, struct blk *blk)
     447             : {
     448           0 :         if(bfd->mode==BF_CLOSED)
     449           0 :                 logp("Got data without an open file\n");
     450             :         else
     451             :         {
     452             :                 int w;
     453           0 :                 if((w=bfd->write(bfd, blk->data, blk->length))<=0)
     454             :                 {
     455             :                         logp("%s(): error when appending %d: %d\n",
     456           0 :                                 __func__, blk->length, w);
     457           0 :                         asfd->write_str(asfd, CMD_ERROR, "write failed");
     458           0 :                         return -1;
     459             :                 }
     460             :         }
     461           0 :         return 0;
     462             : }
     463             : 
     464             : #define RESTORE_STREAM  "restore_stream"
     465             : #define RESTORE_SPOOL   "restore_spool"
     466             : 
     467             : static char *restore_style=NULL;
     468             : 
     469           0 : static enum asl_ret restore_style_func(struct asfd *asfd,
     470             :         struct conf **confs, void *param)
     471             : {
     472           0 :         char msg[32]="";
     473           0 :         restore_style=NULL;
     474           0 :         if(strcmp(asfd->rbuf->buf, RESTORE_STREAM)
     475           0 :            && strcmp(asfd->rbuf->buf, RESTORE_SPOOL))
     476             :         {
     477           0 :                 iobuf_log_unexpected(asfd->rbuf, __func__);
     478           0 :                 return ASL_END_ERROR;
     479             :         }
     480           0 :         snprintf(msg, sizeof(msg), "%s_ok", asfd->rbuf->buf);
     481           0 :         if(asfd->write_str(asfd, CMD_GEN, msg))
     482           0 :                 return ASL_END_ERROR;
     483           0 :         restore_style=asfd->rbuf->buf;
     484           0 :         iobuf_init(asfd->rbuf);
     485           0 :         return ASL_END_OK;
     486             : }
     487             : 
     488           2 : static char *get_restore_style(struct asfd *asfd, struct conf **confs)
     489             : {
     490           2 :         if(get_protocol(confs)==PROTO_1)
     491           2 :                 return strdup_w(RESTORE_STREAM, __func__);
     492           0 :         if(asfd->simple_loop(asfd, confs, NULL, __func__,
     493           0 :                 restore_style_func)) return NULL;
     494           0 :         return restore_style;
     495             : }
     496             : 
     497           0 : static enum asl_ret restore_spool_func(struct asfd *asfd,
     498             :         struct conf **confs, void *param)
     499             : {
     500             :         static char **datpath;
     501             :         static struct iobuf *rbuf;
     502           0 :         datpath=(char **)param;
     503           0 :         rbuf=asfd->rbuf;
     504           0 :         if(!strncmp_w(rbuf->buf, "dat="))
     505             :         {
     506           0 :                 char *fpath=NULL;
     507           0 :                 if(!(fpath=prepend_s(*datpath, rbuf->buf+4))
     508           0 :                   || build_path_w(fpath)
     509           0 :                   || receive_a_file(asfd, fpath, get_cntr(confs)))
     510           0 :                         return ASL_END_ERROR;
     511           0 :                 iobuf_free_content(rbuf);
     512             :         }
     513           0 :         else if(!strcmp(rbuf->buf, "datfilesend"))
     514             :         {
     515           0 :                 if(asfd->write_str(asfd, CMD_GEN, "datfilesend_ok"))
     516           0 :                         return ASL_END_ERROR;
     517           0 :                 return ASL_END_OK;
     518             :         }
     519           0 :         return ASL_CONTINUE;
     520             : }
     521             : 
     522           0 : static int restore_spool(struct asfd *asfd, struct conf **confs, char **datpath)
     523             : {
     524           0 :         const char *restore_spool=get_string(confs[OPT_RESTORE_SPOOL]);
     525           0 :         logp("Spooling restore to: %s\n", restore_spool);
     526             : 
     527           0 :         if(!(*datpath=prepend_s(restore_spool, "incoming-data")))
     528           0 :                 return -1;
     529             : 
     530             :         return asfd->simple_loop(asfd, confs, datpath,
     531           0 :                 __func__, restore_spool_func);
     532             : }
     533             : 
     534           2 : int do_restore_client(struct asfd *asfd,
     535             :         struct conf **confs, enum action act, int vss_restore)
     536             : {
     537           2 :         int ret=-1;
     538           2 :         char msg[512]="";
     539           2 :         struct sbuf *sb=NULL;
     540           2 :         struct blk *blk=NULL;
     541           2 :         BFILE *bfd=NULL;
     542           2 :         char *fullpath=NULL;
     543           2 :         char *style=NULL;
     544           2 :         char *datpath=NULL;
     545           2 :         struct cntr *cntr=get_cntr(confs);
     546           2 :         enum protocol protocol=get_protocol(confs);
     547           2 :         int strip=get_int(confs[OPT_STRIP]);
     548           2 :         int overwrite=get_int(confs[OPT_OVERWRITE]);
     549           2 :         const char *backup=get_string(confs[OPT_BACKUP]);
     550           2 :         const char *regex=get_string(confs[OPT_REGEX]);
     551           2 :         const char *restore_prefix=get_string(confs[OPT_RESTOREPREFIX]);
     552           2 :         const char *encryption_password=get_string(confs[OPT_ENCRYPTION_PASSWORD]);
     553             : 
     554           2 :         if(!(bfd=bfile_alloc())) goto end;
     555             : 
     556           2 :         bfile_init(bfd, 0, cntr);
     557             : 
     558             :         snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act),
     559           2 :                 backup?backup:"", regex?regex:"");
     560           2 :         logp("doing %s\n", msg);
     561           4 :         if(asfd->write_str(asfd, CMD_GEN, msg)
     562           2 :           || asfd->read_expect(asfd, CMD_GEN, "ok"))
     563           0 :                 goto error;
     564           2 :         logp("doing %s confirmed\n", act_str(act));
     565             : 
     566             : #if defined(HAVE_WIN32)
     567             :         if(act==ACTION_RESTORE) win32_enable_backup_privileges();
     568             : #endif
     569             : 
     570           2 :         if(!(style=get_restore_style(asfd, confs)))
     571           0 :                 goto error;
     572           2 :         if(!strcmp(style, RESTORE_SPOOL))
     573             :         {
     574           0 :                 if(restore_spool(asfd, confs, &datpath))
     575           0 :                         goto error;
     576             :         }
     577             :         else
     578           2 :                 logp("Streaming restore direct\n");
     579             : 
     580           2 :         printf("\n");
     581             : 
     582             : //      if(get_int(confs[OPT_SEND_CLIENT_CNTR]) && cntr_recv(confs))
     583             : //              goto error;
     584             : 
     585           6 :         if(!(sb=sbuf_alloc(protocol))
     586           4 :           || (protocol==PROTO_2 && !(blk=blk_alloc())))
     587             :         {
     588           0 :                 log_and_send_oom(asfd, __func__);
     589           0 :                 goto error;
     590             :         }
     591             : 
     592             :         while(1)
     593             :         {
     594           2 :                 sbuf_free_content(sb);
     595           2 :                 if(protocol==PROTO_1)
     596           2 :                         sb->flags |= SBUF_CLIENT_RESTORE_HACK;
     597             : 
     598           2 :                 switch(sbuf_fill_from_net(sb, asfd, blk, datpath, cntr))
     599             :                 {
     600           0 :                         case 0: break;
     601           1 :                         case 1: if(asfd->write_str(asfd, CMD_GEN,
     602           1 :                                 "restoreend_ok")) goto error;
     603           1 :                                 goto end; // It was OK.
     604             :                         default:
     605           1 :                         case -1: goto error;
     606             :                 }
     607             : 
     608           0 :                 if(protocol==PROTO_2 && blk->data)
     609             :                 {
     610           0 :                         int wret=0;
     611           0 :                         if(act==ACTION_VERIFY)
     612           0 :                                 cntr_add(cntr, CMD_DATA, 1);
     613             :                         else
     614           0 :                                 wret=write_data(asfd, bfd, blk);
     615           0 :                         if(!datpath) blk_free_content(blk);
     616           0 :                         blk->data=NULL;
     617           0 :                         if(wret) goto error;
     618           0 :                         continue;
     619             :                 }
     620             : 
     621           0 :                 switch(sb->path.cmd)
     622             :                 {
     623             :                         case CMD_DIRECTORY:
     624             :                         case CMD_FILE:
     625             :                         case CMD_ENC_FILE:
     626             :                         case CMD_SOFT_LINK:
     627             :                         case CMD_HARD_LINK:
     628             :                         case CMD_SPECIAL:
     629             :                         case CMD_METADATA:
     630             :                         case CMD_ENC_METADATA:
     631             :                         case CMD_VSS:
     632             :                         case CMD_ENC_VSS:
     633             :                         case CMD_VSS_T:
     634             :                         case CMD_ENC_VSS_T:
     635             :                         case CMD_EFS_FILE:
     636           0 :                                 if(strip)
     637             :                                 {
     638             :                                         int s;
     639             :                                         s=strip_path_components(asfd,
     640           0 :                                                 sb, strip, cntr, protocol);
     641           0 :                                         if(s<0) goto error;
     642           0 :                                         if(s==0)
     643             :                                         {
     644             :                                                 // Too many components stripped
     645             :                                                 // - carry on.
     646           0 :                                                 continue;
     647             :                                         }
     648             :                                         // It is OK, sb.path is now stripped.
     649             :                                 }
     650           0 :                                 free_w(&fullpath);
     651           0 :                                 if(!(fullpath=prepend_s(restore_prefix,
     652           0 :                                         sb->path.buf)))
     653             :                                 {
     654           0 :                                         log_and_send_oom(asfd, __func__);
     655           0 :                                         goto error;
     656             :                                 }
     657           0 :                                 if(act==ACTION_RESTORE)
     658             :                                 {
     659           0 :                                   strip_invalid_characters(&fullpath);
     660           0 :                                   if(!overwrite_ok(sb, overwrite,
     661             : #ifdef HAVE_WIN32
     662             :                                         bfd,
     663             : #endif
     664           0 :                                         fullpath))
     665             :                                   {
     666           0 :                                         char msg[512]="";
     667             :                                         // Something exists at that path.
     668             :                                         snprintf(msg, sizeof(msg),
     669           0 :                                                 "Path exists: %s\n", fullpath);
     670           0 :                                         if(restore_interrupt(asfd,
     671           0 :                                                 sb, msg, cntr, protocol))
     672           0 :                                                         goto error;
     673           0 :                                         continue;
     674             :                                   }
     675             :                                 }
     676           0 :                                 break;
     677             :                         case CMD_MESSAGE:
     678             :                         case CMD_WARNING:
     679           0 :                                 log_recvd(&sb->path, cntr, 1);
     680           0 :                                 printf("\n");
     681           0 :                                 continue;
     682             :                         default:
     683           0 :                                 break;
     684             :                 }
     685             : 
     686           0 :                 switch(sb->path.cmd)
     687             :                 {
     688             :                         // These are the same in both protocol1 and protocol2.
     689             :                         case CMD_DIRECTORY:
     690           0 :                                 if(restore_dir(asfd, sb, fullpath, act, cntr,
     691           0 :                                         protocol))
     692           0 :                                                 goto error;
     693           0 :                                 continue;
     694             :                         case CMD_SOFT_LINK:
     695             :                         case CMD_HARD_LINK:
     696           0 :                                 if(restore_link(asfd, sb, fullpath, act, cntr,
     697           0 :                                         protocol, restore_prefix))
     698           0 :                                                 goto error;
     699           0 :                                 continue;
     700             :                         case CMD_SPECIAL:
     701           0 :                                 if(restore_special(asfd, sb,
     702           0 :                                         fullpath, act, cntr, protocol))
     703           0 :                                                 goto error;
     704           0 :                                 continue;
     705             :                         default:
     706           0 :                                 break;
     707             :                 }
     708             : 
     709           0 :                 if(protocol==PROTO_2)
     710             :                 {
     711           0 :                         if(restore_switch_protocol2(asfd, sb, fullpath, act,
     712           0 :                                 bfd, vss_restore, cntr))
     713           0 :                                         goto error;
     714             :                 }
     715             :                 else
     716             :                 {
     717           0 :                         if(restore_switch_protocol1(asfd, sb, fullpath, act,
     718           0 :                                 bfd, vss_restore, cntr, encryption_password))
     719           0 :                                         goto error;
     720             :                 }
     721             :         }
     722             : 
     723             : end:
     724           1 :         ret=0;
     725             : error:
     726             :         // It is possible for a fd to still be open.
     727           2 :         bfd->close(bfd, asfd);
     728           2 :         bfile_free(&bfd);
     729             : 
     730           2 :         cntr_print_end(cntr);
     731           2 :         cntr_print(cntr, act);
     732             : 
     733           2 :         if(!ret) logp("%s finished\n", act_str(act));
     734           1 :         else logp("ret: %d\n", ret);
     735             : 
     736           2 :         sbuf_free(&sb);
     737           2 :         free_w(&style);
     738           2 :         if(datpath)
     739             :         {
     740           0 :                 recursive_delete(datpath);
     741           0 :                 free_w(&datpath);
     742             :         }
     743           2 :         free_w(&fullpath);
     744             : 
     745           2 :         return ret;
     746             : }

Generated by: LCOV version 1.10