⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 restore.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -