📄 restore.c
字号:
error(_("write error: %zd instead of %d"), w, DISK_BLOCK_BYTES); /*NOTREACHED*/ } } amfree(buffer); memcpy(source->header, &tmp_hdr, SIZEOF(dumpfile_t)); } /* find out if compression or uncompression is needed here */ if(flags->compress && !file_is_compressed && !is_continuation && !flags->leave_comp && (flags->inline_assemble || source->header->type != F_SPLIT_DUMPFILE)) need_compress=1; if(!flags->raw && !flags->compress && file_is_compressed && !is_continuation && !flags->leave_comp && (flags->inline_assemble || source->header->type != F_SPLIT_DUMPFILE)) need_uncompress=1; if(!flags->raw && source->header->encrypted && !is_continuation && (flags->inline_assemble || source->header->type != F_SPLIT_DUMPFILE)) { need_decrypt=1; } /* Setup pipes for decryption / compression / uncompression */ stage = 0; if (need_decrypt) { if (pipe(&pipes[stage].pipe[0]) < 0) { error(_("error [pipe[%d]: %s]"), stage, strerror(errno)); /*NOTREACHED*/ } stage++; } if (need_compress || need_uncompress) { if (pipe(&pipes[stage].pipe[0]) < 0) { error(_("error [pipe[%d]: %s]"), stage, strerror(errno)); /*NOTREACHED*/ } stage++; } pipes[stage].pipe[0] = -1; pipes[stage].pipe[1] = out; stage = 0; /* decrypt first if it's encrypted and no -r */ if(need_decrypt) { switch(myout->comp_enc_pid = fork()) { case -1: error(_("could not fork for decrypt: %s"), strerror(errno)); /*NOTREACHED*/ default: aclose(pipes[stage].pipe[0]); aclose(pipes[stage+1].pipe[1]); stage++; break; case 0: if(dup2(pipes[stage].pipe[0], 0) == -1) { error(_("error decrypt stdin [dup2 %d %d: %s]"), stage, pipes[stage].pipe[0], strerror(errno)); /*NOTREACHED*/ } if(dup2(pipes[stage+1].pipe[1], 1) == -1) { error(_("error decrypt stdout [dup2 %d %d: %s]"), stage + 1, pipes[stage+1].pipe[1], strerror(errno)); /*NOTREACHED*/ } safe_fd(-1, 0); if (source->header->srv_encrypt[0] != '\0') { (void) execlp(source->header->srv_encrypt, source->header->srv_encrypt, source->header->srv_decrypt_opt, NULL); error("could not exec %s: %s", source->header->srv_encrypt, strerror(errno)); g_assert_not_reached(); } else if (source->header->clnt_encrypt[0] != '\0') { (void) execlp(source->header->clnt_encrypt, source->header->clnt_encrypt, source->header->clnt_decrypt_opt, NULL); error("could not exec %s: %s", source->header->clnt_encrypt, strerror(errno)); g_assert_not_reached(); } } } if (need_compress) { /* * Insert a compress pipe */ switch(myout->comp_enc_pid = fork()) { case -1: error(_("could not fork for %s: %s"), COMPRESS_PATH, strerror(errno)); /*NOTREACHED*/ default: aclose(pipes[stage].pipe[0]); aclose(pipes[stage+1].pipe[1]); stage++; break; case 0: if(dup2(pipes[stage].pipe[0], 0) == -1) { error(_("error compress stdin [dup2 %d %d: %s]"), stage, pipes[stage].pipe[0], strerror(errno)); /*NOTREACHED*/ } if(dup2(pipes[stage+1].pipe[1], 1) == -1) { error(_("error compress stdout [dup2 %d %d: %s]"), stage + 1, pipes[stage+1].pipe[1], strerror(errno)); /*NOTREACHED*/ } if (*flags->comp_type == '\0') { flags->comp_type = NULL; } safe_fd(-1, 0); (void) execlp(COMPRESS_PATH, COMPRESS_PATH, flags->comp_type, (char *)0); error(_("could not exec %s: %s"), COMPRESS_PATH, strerror(errno)); /*NOTREACHED*/ } } else if(need_uncompress) { /* * If not -r, -c, -l, and file is compressed, and split reassembly * options are sane, insert uncompress pipe */ /* * XXX for now we know that for the two compression types we * understand, .Z and optionally .gz, UNCOMPRESS_PATH will take * care of both. Later, we may need to reference a table of * possible uncompress programs. */ switch(myout->comp_enc_pid = fork()) { case -1: error(_("could not fork for %s: %s"), UNCOMPRESS_PATH, strerror(errno)); /*NOTREACHED*/ default: aclose(pipes[stage].pipe[0]); aclose(pipes[stage+1].pipe[1]); stage++; break; case 0: if(dup2(pipes[stage].pipe[0], 0) == -1) { error(_("error uncompress stdin [dup2 %d %d: %s]"), stage, pipes[stage].pipe[0], strerror(errno)); /*NOTREACHED*/ } if(dup2(pipes[stage+1].pipe[1], 1) == -1) { error(_("error uncompress stdout [dup2 %d %d: %s]"), stage + 1, pipes[stage+1].pipe[1], strerror(errno)); /*NOTREACHED*/ } safe_fd(-1, 0); if (source->header->srvcompprog[0] != '\0') { (void) execlp(source->header->srvcompprog, source->header->srvcompprog, "-d", NULL); error("could not exec %s: %s", source->header->srvcompprog, strerror(errno)); g_assert_not_reached(); } else if (source->header->clntcompprog[0] != '\0') { (void) execlp(source->header->clntcompprog, source->header->clntcompprog, "-d", NULL); error("could not exec %s: %s", source->header->clntcompprog, strerror(errno)); g_assert_not_reached(); } else { (void) execlp(UNCOMPRESS_PATH, UNCOMPRESS_PATH,#ifdef UNCOMPRESS_OPT UNCOMPRESS_OPT,#endif (char *)NULL); error(_("could not exec %s: %s"), UNCOMPRESS_PATH, strerror(errno)); /*NOTREACHED*/ } } } /* copy the rest of the file from tape to the output */ if (source->restore_mode == HOLDING_MODE) { dumpfile_t file; int fd = source->u.holding_fd; memcpy(& file, source->header, sizeof(file)); for (;;) { do_consumer_producer_queue(fd_read_producer, GINT_TO_POINTER(fd), fd_write_consumer, GINT_TO_POINTER(pipes[0].pipe[1])); /* * See if we need to switch to the next file in a holding restore */ if(file.cont_filename[0] == '\0') { break; /* no more files */ } aclose(fd); if((fd = open(file.cont_filename, O_RDONLY)) == -1) { char *cont_filename = strrchr(file.cont_filename,'/'); if(cont_filename) { cont_filename++; if((fd = open(cont_filename,O_RDONLY)) == -1) { error(_("can't open %s: %s"), file.cont_filename, strerror(errno)); /*NOTREACHED*/ } else { g_fprintf(stderr, _("cannot open %s: %s\n"), file.cont_filename, strerror(errno)); g_fprintf(stderr, _("using %s\n"), cont_filename); } } else { error(_("can't open %s: %s"), file.cont_filename, strerror(errno)); /*NOTREACHED*/ } } read_holding_disk_header(&file, fd, flags); if(file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE && file.type != F_SPLIT_DUMPFILE) { g_fprintf(stderr, _("unexpected header type: ")); print_header(stderr, source->header); exit(2); } } } else { device_read_to_fd(source->u.device, pipes[0].pipe[1]); } if(!flags->inline_assemble) { if(out != dest) aclose(out); } if(!is_continuation){ if(tmp_filename && stat(tmp_filename, &statinfo) < 0){ error(_("Can't stat the file I just created (%s)!"), tmp_filename); /*NOTREACHED*/ } else { statinfo.st_size = (off_t)0; } if (check_for_aborted && final_filename) { char *old_dump = final_filename; struct stat oldstat; if(stat(old_dump, &oldstat) >= 0){ if(oldstat.st_size <= statinfo.st_size){ dumplist_t *prev_fileentry = NULL; open_output_t *prev_out = NULL; g_fprintf(stderr, _("Newer restore is larger, using that\n")); /* nuke the old dump's entry in alldump_list */ for(fileentry=alldumps_list; fileentry->next; fileentry=fileentry->next){ if(headers_equal(source->header, fileentry->file, 0)){ if(prev_fileentry){ prev_fileentry->next = fileentry->next; } else { alldumps_list = fileentry->next; } amfree(fileentry); break; } prev_fileentry = fileentry; } myout = open_outputs; while(myout != NULL){ if(headers_equal(source->header, myout->file, 0)){ if(myout->outfd >= 0) aclose(myout->outfd); if(prev_out){ prev_out->next = myout->next; } else open_outputs = myout->next; amfree(myout); break; } prev_out = myout; myout = myout->next; } } else{ g_fprintf(stderr, _("Older restore is larger, using that\n")); if (tmp_filename) unlink(tmp_filename); amfree(tempdump->file); amfree(tempdump); amfree(tmp_filename); amfree(final_filename); amfree(filename); return; } } } if(tmp_filename && final_filename && rename(tmp_filename, final_filename) < 0) { error(_("Can't rename %s to %s: %s"), tmp_filename, final_filename, strerror(errno)); /*NOTREACHED*/ } } amfree(tmp_filename); amfree(final_filename); /* * actually insert tracking data for this file into our various * structures (we waited in case we needed to give up) */ if(!is_continuation){ oldout = alloc(SIZEOF(open_output_t)); oldout->file = alloc(SIZEOF(dumpfile_t)); memcpy(oldout->file, source->header, SIZEOF(dumpfile_t)); if(flags->inline_assemble) oldout->outfd = pipes[0].pipe[1]; else oldout->outfd = -1; oldout->comp_enc_pid = -1; oldout->lastpartnum = source->header->partnum; oldout->next = open_outputs; open_outputs = oldout; } if(alldumps_list){ fileentry = alldumps_list; while (fileentry->next != NULL) fileentry=fileentry->next; fileentry->next = tempdump; } else { alldumps_list = tempdump; }}/* return NULL if the label is not the expected one *//* returns a Device handle if it is the expected one. *//* FIXME: Was label_of_current_slot */static Device *conditional_device_open(char *tapedev, FILE *prompt_out, rst_flags_t *flags, am_feature_t *their_features, tapelist_t *desired_tape){ Device * rval; if (tapedev == NULL) { send_message(prompt_out, flags, their_features, _("Volume labeled '%s' not found."), desired_tape->label); return NULL; } rval = device_open(tapedev); if (rval == NULL) { send_message(prompt_out, flags, their_features, "Error opening device '%s'.", tapedev); return NULL; } device_set_startup_properties_from_config(rval); device_read_label(rval); if (rval->volume_label == NULL) { send_message(prompt_out, flags, their_features, "Not an amanda tape"); g_object_unref(rval); return NULL; } if (!device_start(rval, ACCESS_READ, NULL, NULL)) { send_message(prompt_out, flags, their_features, "Colud not open device %s for reading.\n", tapedev); return NULL; } if (flags->check_labels && desired_tape && strcmp(rval->volume_label, desired_tape->label) != 0) { send_message(prompt_out, flags, their_features, "Label mismatch, got %s and expected %s", rval->volume_label, desired_tape->label); g_object_unref(rval); return NULL; } return rval;}/* Do the right thing to try and load the next required tape. See LoadStatus above for return value meaning. */LoadStatusload_next_tape( char **cur_tapedev, FILE *prompt_out, int backwards, rst_flags_t *flags, am_feature_t *their_features, tapelist_t *desired_tape){ if (desired_tape) { send_message(prompt_out, flags, their_features, _("Looking for tape %s..."), desired_tape->label); if (backwards) { loadlabel_data data; data.cur_tapedev = cur_tapedev; data.searchlabel = desired_tape->label;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -