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