LCOV - code coverage report
Current view: top level - src/client - restore.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 160 297 53.9 %
Date: 2016-05-01 Functions: 9 16 56.2 %

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

Generated by: LCOV version 1.10