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

📄 extract_list.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 4 页
字号:
				  * sizeof(char *)));    switch(dumptype) {    case IS_SAMBA:#ifdef SAMBA_CLIENT    	restore_args[j++] = stralloc("smbclient");    	smbpass = findpass(file.disk, &domain);    	if (smbpass) {            restore_args[j++] = stralloc(file.disk);	    passwd_field=j;    	    restore_args[j++] = stralloc("-U");    	    restore_args[j++] = smbpass;    	    if (domain) {            	restore_args[j++] = stralloc("-W");    	    	restore_args[j++] = stralloc(domain);   	    } else		extra_params -= 2;    	} else	    extra_params -= 6;    	restore_args[j++] = stralloc("-d0");    	restore_args[j++] = stralloc("-Tx");	restore_args[j++] = stralloc("-");	/* data on stdin */    	break;#endif    case IS_TAR:    case IS_GNUTAR:    	restore_args[j++] = stralloc("tar");	restore_args[j++] = stralloc("--numeric-owner");	restore_args[j++] = stralloc("-xpGvf");	restore_args[j++] = stralloc("-");	/* data on stdin */	break;    case IS_SAMBA_TAR:    	restore_args[j++] = stralloc("tar");	restore_args[j++] = stralloc("-xpvf");	restore_args[j++] = stralloc("-");	/* data on stdin */	break;    case IS_UNKNOWN:    case IS_DUMP:        restore_args[j++] = stralloc("restore");#ifdef AIX_BACKUP        restore_args[j++] = stralloc("-xB");#else#if defined(XFSDUMP)	if (strcmp(file.program, XFSDUMP) == 0) {            restore_args[j++] = stralloc("-v");            restore_args[j++] = stralloc("silent");	} else#endif#if defined(VDUMP)	if (strcmp(file.program, VDUMP) == 0) {            restore_args[j++] = stralloc("xf");            restore_args[j++] = stralloc("-");	/* data on stdin */	} else#endif	{        restore_args[j++] = stralloc("xbf");        restore_args[j++] = stralloc("2");	/* read in units of 1K */        restore_args[j++] = stralloc("-");	/* data on stdin */	}#endif    }      for (i = 0, fn = elist->files; i < files_off_tape; i++, fn = fn->next)    {	switch (dumptype) {    	case IS_TAR:    	case IS_GNUTAR:    	case IS_SAMBA_TAR:    	case IS_SAMBA:	    if (strcmp(fn->path, "/") == 0)	        restore_args[j++] = stralloc(".");	    else	        restore_args[j++] = stralloc2(".", fn->path);	    break;	case IS_UNKNOWN:	case IS_DUMP:#if defined(XFSDUMP)	    if (strcmp(file.program, XFSDUMP) == 0) {		/*		 * xfsrestore needs a -s option before each file to be		 * restored, and also wants them to be relative paths.		 */		restore_args[j++] = stralloc("-s");		restore_args[j++] = stralloc(fn->path + 1);	    } else#endif	    {	    restore_args[j++] = stralloc(fn->path);	    }  	}    }#if defined(XFSDUMP)    if (strcmp(file.program, XFSDUMP) == 0) {	restore_args[j++] = stralloc("-");	restore_args[j++] = stralloc(".");    }#endif    restore_args[j] = NULL;    switch (dumptype) {    case IS_SAMBA:#ifdef SAMBA_CLIENT    	cmd = stralloc(SAMBA_CLIENT);    	break;#else	/* fall through to ... */#endif    case IS_TAR:    case IS_GNUTAR:    case IS_SAMBA_TAR:#ifndef GNUTAR	g_fprintf(stderr, _("warning: GNUTAR program not available.\n"));	cmd = stralloc("tar");#else  	cmd = stralloc(GNUTAR);#endif    	break;    case IS_UNKNOWN:    case IS_DUMP:	cmd = NULL;#if defined(DUMP)	if (strcmp(file.program, DUMP) == 0) {    	    cmd = stralloc(RESTORE);	}#endif#if defined(VDUMP)	if (strcmp(file.program, VDUMP) == 0) {    	    cmd = stralloc(VRESTORE);	}#endif#if defined(VXDUMP)	if (strcmp(file.program, VXDUMP) == 0) {    	    cmd = stralloc(VXRESTORE);	}#endif#if defined(XFSDUMP)	if (strcmp(file.program, XFSDUMP) == 0) {    	    cmd = stralloc(XFSRESTORE);	}#endif	if (cmd == NULL) {	    g_fprintf(stderr, _("warning: restore program for %s not available.\n"),		    file.program);	    cmd = stralloc("restore");	}    }    if (cmd) {        dbprintf(_("Exec'ing %s with arguments:\n"), cmd);	for (i = 0; i < j; i++) {	    if( i == passwd_field)		dbprintf("\tXXXXX\n");	    else  	        dbprintf("\t%s\n", restore_args[i]);	}	safe_fd(-1, 0);        (void)execv(cmd, restore_args);	/* only get here if exec failed */	save_errno = errno;	for (i = 0; i < j; i++) {  	    amfree(restore_args[i]);  	}  	amfree(restore_args);	errno = save_errno;        perror(_("amrecover couldn't exec"));        g_fprintf(stderr, _(" problem executing %s\n"), cmd);	amfree(cmd);    }    exit(1);    /*NOT REACHED */}/* * Interpose something between the process writing out the dump (writing it to * some extraction program, really) and the socket from which we're reading, so * that we can do things like prompt for human interaction for multiple tapes. */voidwriter_intermediary(    int			ctl_fd,    int			data_fd,    EXTRACT_LIST *	elist){    int child_pipe[2];    pid_t pid;    char buffer[DISK_BLOCK_BYTES];    ssize_t bytes_read;    amwait_t extractor_status;    int max_fd, nfound;    SELECT_ARG_TYPE readset, selectset;    struct timeval timeout;    /*     * If there's no distinct data channel (such as if we're talking to an     * older server), don't bother doing anything complicated.  Just run the     * extraction.     */    if(data_fd == -1){	extract_files_child(ctl_fd, elist);	/*NOTREACHED*/    }    if(pipe(child_pipe) == -1) {	error(_("extract_list - error setting up pipe to extractor: %s\n"),	    strerror(errno));	/*NOTREACHED*/    }    /* okay, ready to extract. fork a child to do the actual work */    if ((pid = fork()) == 0) {	/* this is the child process */	/* never gets out of this clause */	aclose(child_pipe[1]);        extract_files_child(child_pipe[0], elist);	/*NOTREACHED*/    }    /* This is the parent */    if (pid == -1) {	error(_("writer_intermediary - error forking child"));	/*NOTREACHED*/    }    aclose(child_pipe[0]);    if(data_fd > ctl_fd) max_fd = data_fd+1;                    else max_fd = ctl_fd+1;    FD_ZERO(&readset);    FD_SET(data_fd, &readset);    FD_SET(ctl_fd, &readset);    do {	timeout.tv_sec = READ_TIMEOUT;	timeout.tv_usec = 0;	FD_COPY(&readset, &selectset);        	nfound = select(max_fd, &selectset, NULL, NULL,			&timeout);	if(nfound < 0) {	    g_fprintf(stderr,_("select error: %s\n"), strerror(errno));	    break;	}        	if (nfound == 0) { /* timeout */	    g_fprintf(stderr, _("timeout waiting %d seconds for restore\n"),		    READ_TIMEOUT);	    g_fprintf(stderr, _("increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n"));	    break;	}        	if(FD_ISSET(ctl_fd, &selectset)) {	    bytes_read = read(ctl_fd, buffer, sizeof(buffer)-1);	    switch(bytes_read) {            case -1:                if ((errno != EINTR) && (errno != EAGAIN)) {                    if (errno != EPIPE) {                        g_fprintf(stderr,_("writer ctl fd read error: %s"),                                strerror(errno));                    }                    FD_CLR(ctl_fd, &readset);                }                break;                            case  0:                FD_CLR(ctl_fd, &readset);                break;                            default: {                char desired_tape[MAX_TAPE_LABEL_BUF];                                buffer[bytes_read] = '\0';                /* if prompted for a tape, relay said prompt to the user */                if(sscanf(buffer, "FEEDME %132s\n", desired_tape) == 1) {                    int done = 0;                    while (!done) {                        char *input = NULL;                        g_printf(_("Please insert tape %s. Continue? [Y|n]: "),                               desired_tape);                        fflush(stdout);                                                input = agets(stdin); /* strips \n */                        if (strcasecmp("", input) == 0||                             strcasecmp("y", input) == 0||                             strcasecmp("yes", input) == 0) {                            send_to_tape_server(tape_control_sock, "OK");                            done = 1;                        } else if (strcasecmp("n", input) == 0||                                    strcasecmp("no", input) == 0) {                            send_to_tape_server(tape_control_sock, "ERROR");                            /* Abort!                               We are the middle process, so just die. */                            exit(EXIT_FAILURE);                        }                        amfree(input);                    }                } else {                    g_fprintf(stderr, _("Strange message from tape server: %s"), buffer);		    break;                }    	      }            }        }        /* now read some dump data */        if(FD_ISSET(data_fd, &selectset)) {            bytes_read = read(data_fd, buffer, sizeof(buffer)-1);            switch(bytes_read) {            case -1:                if ((errno != EINTR) && (errno != EAGAIN)) {                    if (errno != EPIPE) {                        g_fprintf(stderr,_("writer data fd read error: %s"),                                strerror(errno));                    }                    FD_CLR(data_fd, &readset);                }                break;                            case  0:                FD_CLR(data_fd, &readset);                break;                            default:                /*                 * spit what we got from the server to the child                 *  process handling actual dumpfile extraction                 */                if(fullwrite(child_pipe[1], buffer, (size_t)bytes_read) < 0) {                    if(errno == EPIPE) {                        error(_("pipe data reader has quit: %s\n"),                              strerror(errno));                        /* NOTREACHED */                    }                    error(_("Write error to extract child: %s\n"),                          strerror(errno));                    /* NOTREACHED */                }                break;	    }	}    } while(FD_ISSET(ctl_fd, &readset) || FD_ISSET(data_fd, &readset));    aclose(child_pipe[1]);    waitpid(pid, &extractor_status, 0);    if(WEXITSTATUS(extractor_status) != 0){	int ret = WEXITSTATUS(extractor_status);        if(ret == 255) ret = -1;	error(_("Extractor child exited with status %d\n"), ret);	/*NOTREACHED*/    }    exit(0);}/* exec restore to do the actual restoration *//* does the actual extraction of files *//* * The original design had the dump image being returned exactly as it * appears on the tape, and this routine getting from the index server * whether or not it is compressed, on the assumption that the tape * server may not know how to uncompress it. But * - Amrestore can't do that. It returns either compressed or uncompressed * (always). Amrestore assumes it can uncompress files. It is thus a good * idea to run the tape server on a machine with gzip. * - The information about compression in the disklist is really only * for future dumps. It is possible to change compression on a drive * so the information in the disklist may not necessarily relate to * the dump image on the tape. *   Consequently the design was changed to assuming that amrestore can * uncompress any dump image and have it return an uncompressed file * always. */voidextract_files(void){    EXTRACT_LIST *elist;    pid_t pid;    amwait_t child_stat;    char buf[STR_SIZE];    char *l;    int first;    int otc;    tapelist_t *tlist = NULL;    if (!is_extract_list_nonempty())    {	g_printf(_("Extract list empty - No files to extract!\n"));	return;    }    clean_extract_list();    /* get tape device name from index server if none specified */    if (tape_server_name == NULL) {	tape_server_name = newstralloc(tape_server_name, server_name);    }    if (tape_device_name == NULL) {	if (send_command("TAPE") == -1)	    exit(1);	if (get_reply_line() == -1)	    exit(1);	l = reply_line();	if (!server_happy())	{	    g_printf("%s\n", l);	    exit(1);	}	/* skip reply number */	tape_device_name = newstralloc(tape_device_name, l+4);    }    if (strcmp(tape_device_name, "/dev/null") == 0)    {	g_printf(_("amrecover: warning: using %s as the tape device will not work\n"),	       tape_device_name);    }    first=1;    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))	if(elist->tape[0]!='/') {	    if(first) {		g_printf(_("\nExtracting files using tape drive %s on host %s.\n"),			tape_device_name, tape_server_name);		g_printf(_("The following tapes are needed:"));		first=0;	    }	    else		g_printf("                               ");	    tlist = unmarshal_tapelist_str(elist->tape); 	    for( ; tlist != NULL; tlist = tlist->next)		g_printf(" %s", tlist->label);	    g_printf("\n");	    amfree(tlist);	}    first=1;    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))    {	if(elist->tape[0]=='/') {	    if(first) {		g_printf(_("\nExtracting files from holding disk on host %s.\n"),			tape_server_name);		g_printf(_("The following files are needed:"));		first=0;	    }	    else		g_printf("                               ");	    tlist = unmarshal_tapelist_str(elist->tape); 	    for( ; tlist != NULL; tlist = tlist->next)		g_printf(" %s", tlist->label);	    g_printf("\n");	    amfree(tlist);	}    }    g_printf("\n");    if (getcwd(buf, sizeof(buf)) == NULL) {	perror(_("extract_list: Cannot determine current working directory"));	exit(1);    }    g_printf(_("Restoring files into directory %s\n"), buf);#ifdef SAMBA_CLIENT    if (samba_extract_method == SAMBA_SMBCLIENT)      g_printf(_("(unless it is a Samba backup, that will go through to the SMB server)\n"));#endif    if (!okay_to_continue(0,0,0))	return;    g_printf("\n");    while ((elist = first_tape_list()) != NULL)    {	if(elist->tape[0]=='/') {	    dump_device_name = newstralloc(dump_device_name, elist->tape);	    g_printf(_("Extracting from file "));	    tlist = unmarshal_tapelist_str(dump_device_name); 	    for( ; tlist != NULL; tlist = tlist->next)		g_printf(" %s", tlist->label);	    g_printf("\n");	    amfree(tlist);	}	else {	    g_printf(_("Extracting files using tape drive %s on host %s.\n"),		   tape_device_name, tape_server_name);	    tlist = unmarshal_tapelist_str(elist->tape); 	    g_printf(_("Load tape %s now\n"), tlist->label);	    amfree(tlist);	    otc = okay_to_continue(1,1,0);	    if (otc == 0)	        return;	    else if (otc == SKIP_TAPE) {		delete_tape_list(elist); /* skip this tape */		continue;	    }	    dump_device_name = newstralloc(dump_device_name, tape_device_name);	}	dump_datestamp = newstralloc(dump_datestamp, elist->date);	/* connect to the tape handler daemon on the tape drive server */	if ((tape_control_sock = extract_files_setup(elist->tape, elist->fileno)) == -1)	{	    g_fprintf(stderr, _("amrecover - can't talk to tape server\n"));	    return;	}	/* okay, ready to extract. fork a child to do the actual work */	if ((pid = fork()) == 0)	{	    /* this is the child process */	    /* never gets out of this clause */	    writer_intermediary(tape_control_sock, tape_data_sock, elist);	    /*NOT REACHED*/	}	/* this is the parent */	if (pid == -1)	{	    perror(_("extract_list - error forking child"));	    aclose(tape_control_sock);	    exit(1);	}	/* store the child pid globally so that it can be killed on intr */	extract_restore_child_pid = pid;	/* wait for the child process to finish */	if ((pid = waitpid(-1, &child_stat, 0)) == (pid_t)-1)	{	    perror(_("extract_list - error waiting for child"));	    exit(1);	}	if(tape_data_sock != -1) {	    aclose(tape_data_sock);	}	if (pid == extract_restore_child_pid)	{	    extract_restore_child_pid = -1;	}	else	{	    g_fprintf(stderr, _("extract list - unknown child terminated?\n"));	    exit(1);	}	if ((WIFEXITED(child_stat) != 0) && (WEXITSTATUS(child_stat) != 0))	{	    g_fprintf(stderr,		    _("extract_list - child returned non-zero status: %d\n"),		    WEXITSTATUS(child_stat));	    otc = okay_to_continue(0,0,1);	    if(otc == 0)		return;	    if(otc == 1) {		delete_tape_list(elist); /* tape failed so delete from list */	    }	}	else {	    delete_tape_list(elist);	/* tape done so delete from list */	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -