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