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