LCOV - code coverage report
Current view: top level - src/client - restore.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 164 290 56.6 %
Date: 2017-08-09 Functions: 10 15 66.7 %

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

Generated by: LCOV version 1.10