extract_list.c

来自「开源备份软件源码 AMANDA, the Advanced Marylan」· C语言 代码 · 共 2,253 行 · 第 1/4 页

C
2,253
字号
			      ditem->path);		    break;		}	    }	}    }    amfree(cmd);    amfree(ditem_path);    amfree(path_on_disk);    amfree(path_on_disk_slash);    if(! found_one) {	g_printf(_("File %s doesn't exist in directory\n"), path);	dbprintf(_("delete_file: (Failed) File %s doesn't exist in directory\n"),	          path);    }}/* print extract list into file. If NULL ptr passed print to screen */voiddisplay_extract_list(    char *	file){    EXTRACT_LIST *this;    EXTRACT_LIST_ITEM *that;    FILE *fp;    char *pager;    char *pager_command;    char *uqfile;    if (file == NULL)    {	if ((pager = getenv("PAGER")) == NULL)	{	    pager = "more";	}	/*	 * Set up the pager command so if the pager is terminated, we do	 * not get a SIGPIPE back.	 */	pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");	if ((fp = popen(pager_command, "w")) == NULL)	{	    g_printf(_("Warning - can't pipe through %s\n"), pager);	    fp = stdout;	}	amfree(pager_command);    }    else    {	uqfile = unquote_string(file);	if ((fp = fopen(uqfile, "w")) == NULL)	{	    g_printf(_("Can't open file %s to print extract list into\n"), file);	    amfree(uqfile);	    return;	}	amfree(uqfile);    }    for (this = extract_list; this != NULL; this = this->next)    {	g_fprintf(fp, _("TAPE %s LEVEL %d DATE %s\n"),		this->tape, this->level, this->date);	for (that = this->files; that != NULL; that = that->next)	    g_fprintf(fp, "\t%s\n", that->path);    }    if (file == NULL) {	apclose(fp);    } else {	g_printf(_("Extract list written to file %s\n"), file);	afclose(fp);    }}/* returns 0 if extract list empty and 1 if it isn't */intis_extract_list_nonempty(void){    return (extract_list != NULL);}/* prints continue prompt and waits for response,   returns 0 if don't, non-0 if do */static intokay_to_continue(    int		allow_tape,    int		allow_skip,    int		allow_retry){    int ch;    int ret = -1;    char *line = NULL;    char *s;    char *prompt;    int get_tape;    get_tape = 0;    while (ret < 0) {	if (get_tape) {	    prompt = _("New tape device [?]: ");	} else if (allow_tape && allow_skip) {	    prompt = _("Continue [?/Y/n/s/t]? ");	} else if (allow_tape && !allow_skip) {	    prompt = _("Continue [?/Y/n/t]? ");	} else if (allow_retry) {	    prompt = _("Continue [?/Y/n/r]? ");	} else {	    prompt = _("Continue [?/Y/n]? ");	}	fputs(prompt, stdout);	fflush(stdout); fflush(stderr);	amfree(line);	if ((line = agets(stdin)) == NULL) {	    putchar('\n');	    clearerr(stdin);	    if (get_tape) {		get_tape = 0;		continue;	    }	    ret = 0;	    break;	}	s = line;	while ((ch = *s++) != '\0' && isspace(ch)) {	    (void)ch;  /* Quiet empty loop body warning */	}	if (ch == '?') {	    if (get_tape) {		g_printf(_("Enter a new device ([host:]device) or \"default\"\n"));	    } else {		g_printf(_("Enter \"y\"es to continue, \"n\"o to stop"));		if(allow_skip) {		    g_printf(_(", \"s\"kip this tape"));		}		if(allow_retry) {		    g_printf(_(" or \"r\"etry this tape"));		}		if (allow_tape) {		    g_printf(_(" or \"t\"ape to change tape drives"));		}		putchar('\n');	    }	} else if (get_tape) {	    set_tape(s - 1);	    get_tape = 0;	} else if (ch == '\0' || ch == 'Y' || ch == 'y') {	    ret = 1;	} else if (allow_tape && (ch == 'T' || ch == 't')) {	    get_tape = 1;	} else if (ch == 'N' || ch == 'n') {	    ret = 0;	} else if (allow_retry && (ch == 'R' || ch == 'r')) {	    ret = RETRY_TAPE;	} else if (allow_skip && (ch == 'S' || ch == 's')) {	    ret = SKIP_TAPE;	}    }    /*@ignore@*/    amfree(line);    /*@end@*/    return ret;}static voidsend_to_tape_server(    int		tss,    char *	cmd){    char *msg = stralloc2(cmd, "\r\n");    if (fullwrite(tss, msg, strlen(msg)) < 0)    {	error(_("Error writing to tape server"));	/*NOTREACHED*/    }    amfree(msg);}/* start up connection to tape server and set commands to initiate   transfer of dump image.   Return tape server socket on success, -1 on error. */static intextract_files_setup(    char *	label,    off_t	fsf){    struct servent *sp;    in_port_t my_port, my_data_port;    char *disk_regex = NULL;    char *host_regex = NULL;    char *service_name = NULL;    char *line = NULL;    char *clean_datestamp, *ch, *ch1;    char *our_feature_string = NULL;    char *tt = NULL;    service_name = stralloc2("amidxtape", SERVICE_SUFFIX);    /* get tape server details */    if ((sp = getservbyname(service_name, "tcp")) == NULL)    {	g_printf(_("%s/tcp unknown protocol - config error?\n"), service_name);	amfree(service_name);	return -1;    }    amfree(service_name);    seteuid(0);					/* it either works ... */    setegid(0);    tape_control_sock = stream_client_privileged(tape_server_name,						  (in_port_t)ntohs((in_port_t)sp->s_port),						  0,						  STREAM_BUFSIZE,						  &my_port,						  0);    if (tape_control_sock < 0)    {	g_printf(_("cannot connect to %s: %s\n"), tape_server_name, strerror(errno));	return -1;    }    if (my_port >= IPPORT_RESERVED) {	aclose(tape_control_sock);	g_printf(_("did not get a reserved port: %u\n"), (unsigned)my_port);	return -1;    }     setegid(getgid());    seteuid(getuid());				/* put it back */    /* do the security thing */    line = get_security();    send_to_tape_server(tape_control_sock, line);    memset(line, '\0', strlen(line));    amfree(line);    disk_regex = alloc(strlen(disk_name) * 2 + 3);    ch = disk_name;    ch1 = disk_regex;    /* we want to force amrestore to only match disk_name exactly */    *(ch1++) = '^';    /* We need to escape some characters first... NT compatibilty crap */    for (; *ch != 0; ch++, ch1++) {	switch (*ch) {     /* done this way in case there are more */	case '$':	    *(ch1++) = '\\';	    /* no break; we do want to fall through... */	default:	    *ch1 = *ch;	}    }    /* we want to force amrestore to only match disk_name exactly */    *(ch1++) = '$';    *ch1 = '\0';    host_regex = alloc(strlen(dump_hostname) * 2 + 3);    ch = dump_hostname;    ch1 = host_regex;    /* we want to force amrestore to only match dump_hostname exactly */    *(ch1++) = '^';    /* We need to escape some characters first... NT compatibilty crap */    for (; *ch != 0; ch++, ch1++) {	switch (*ch) {     /* done this way in case there are more */	case '$':	    *(ch1++) = '\\';	    /* no break; we do want to fall through... */	default:	    *ch1 = *ch;	}    }    /* we want to force amrestore to only match dump_hostname exactly */    *(ch1++) = '$';    *ch1 = '\0';    clean_datestamp = stralloc(dump_datestamp);    for(ch=ch1=clean_datestamp;*ch1 != '\0';ch1++) {	if(*ch1 != '-') {	    *ch = *ch1;	    ch++;	}    }    *ch = '\0';    /* push our feature list off to the tape server */    /* XXX assumes that index server and tape server are equivalent, ew */    if(am_has_feature(indexsrv_features, fe_amidxtaped_exchange_features)){	char buffer[32768] = "\0";	our_feature_string = am_feature_to_string(our_features);	tt = newstralloc2(tt, "FEATURES=", our_feature_string);	send_to_tape_server(tape_control_sock, tt);	if (read(tape_control_sock, buffer, sizeof(buffer)) <= 0) {	    error(_("Could not read features from control socket\n"));	    /*NOTREACHED*/	}	tapesrv_features = am_string_to_feature(buffer);	amfree(our_feature_string);    }    if(am_has_feature(indexsrv_features, fe_amidxtaped_header) &&       am_has_feature(indexsrv_features, fe_amidxtaped_device) &&       am_has_feature(indexsrv_features, fe_amidxtaped_host) &&       am_has_feature(indexsrv_features, fe_amidxtaped_disk) &&       am_has_feature(indexsrv_features, fe_amidxtaped_datestamp)) {	if(am_has_feature(indexsrv_features, fe_amidxtaped_config)) {	    tt = newstralloc2(tt, "CONFIG=", config_name);	    send_to_tape_server(tape_control_sock, tt);	}	if(am_has_feature(indexsrv_features, fe_amidxtaped_label) &&	   label && label[0] != '/') {	    tt = newstralloc2(tt,"LABEL=",label);	    send_to_tape_server(tape_control_sock, tt);	}	if(am_has_feature(indexsrv_features, fe_amidxtaped_fsf)) {	    char v_fsf[100];	    g_snprintf(v_fsf, 99, "%lld", (long long)fsf);	    tt = newstralloc2(tt, "FSF=",v_fsf);	    send_to_tape_server(tape_control_sock, tt);	}	send_to_tape_server(tape_control_sock, "HEADER");	tt = newstralloc2(tt, "DEVICE=", dump_device_name);	send_to_tape_server(tape_control_sock, tt);	tt = newstralloc2(tt, "HOST=", host_regex);	send_to_tape_server(tape_control_sock, tt);	tt = newstralloc2(tt, "DISK=", disk_regex);	send_to_tape_server(tape_control_sock, tt);	tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);	send_to_tape_server(tape_control_sock, tt);	send_to_tape_server(tape_control_sock, "END");	amfree(tt);    }    else if(am_has_feature(indexsrv_features, fe_amidxtaped_nargs)) {	/* send to the tape server what tape file we want */	/* 6 args:	 *   "-h"	 *   "-p"	 *   "tape device"	 *   "hostname"	 *   "diskname"	 *   "datestamp"	 */	send_to_tape_server(tape_control_sock, "6");	send_to_tape_server(tape_control_sock, "-h");	send_to_tape_server(tape_control_sock, "-p");	send_to_tape_server(tape_control_sock, dump_device_name);	send_to_tape_server(tape_control_sock, host_regex);	send_to_tape_server(tape_control_sock, disk_regex);	send_to_tape_server(tape_control_sock, clean_datestamp);	dbprintf(_("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n"),		  dump_device_name, host_regex, disk_regex, clean_datestamp);    }    /*     * split-restoring amidxtaped versions will expect to set up a data     * connection for dumpfile data, distinct from the socket we're already     * using for control data     */    if(am_has_feature(tapesrv_features, fe_recover_splits)){	char buffer[32768];	in_port_t data_port = (in_port_t)-1;        ssize_t nread;        nread = read(tape_control_sock, buffer, sizeof(buffer));	if (nread <= 0) {	    error(_("Could not read from control socket: %s\n"),                   strerror(errno));	    /*NOTREACHED*/        }	buffer[nread] = '\0';        if (sscanf(buffer, "CONNECT %hu\n",		(unsigned short *)&data_port) != 1) {	    error(_("Recieved invalid port number message from control socket: %s\n"),                  buffer);	    /*NOTREACHED*/        }		tape_data_sock = stream_client_privileged(server_name,						  data_port,						  0,						  STREAM_BUFSIZE,						  &my_data_port,						  0);	if(tape_data_sock == -1){	    error(_("Unable to make data connection to server: %s\n"),		      strerror(errno));	    /*NOTREACHED*/	}	amfree(our_feature_string);    	line = get_security();	send_to_tape_server(tape_data_sock, line);	memset(line, '\0', strlen(line));	amfree(line);    }    amfree(disk_regex);    amfree(host_regex);    amfree(clean_datestamp);    return tape_control_sock;}/* * Reads the first block of a tape file. */voidread_file_header(    char *	buffer,    dumpfile_t *file,    size_t	buflen,    int		tapedev){    ssize_t bytes_read;    bytes_read = read_buffer(tapedev, buffer, buflen, READ_TIMEOUT);    if(bytes_read < 0) {	error(_("error reading header (%s), check amidxtaped.*.debug on server"),	      strerror(errno));	/*NOTREACHED*/    }    if((size_t)bytes_read < buflen) {	g_fprintf(stderr, plural(_("%s: short block %d byte\n"),			       _("%s: short block %d bytes\n"), bytes_read),		get_pname(), (int)bytes_read);	print_header(stdout, file);	error(_("Can't read file header"));	/*NOTREACHED*/    }    /* bytes_read == buflen */    parse_file_header(buffer, file, (size_t)bytes_read);}enum dumptypes {	IS_UNKNOWN,	IS_DUMP,	IS_GNUTAR,	IS_TAR,	IS_SAMBA,	IS_SAMBA_TAR};static voidextract_files_child(    int			in_fd,    EXTRACT_LIST *	elist){    int save_errno;    int extra_params = 0;    int i,j=0;    char **restore_args = NULL;    int files_off_tape;    EXTRACT_LIST_ITEM *fn;    enum dumptypes dumptype = IS_UNKNOWN;    char buffer[DISK_BLOCK_BYTES];    dumpfile_t file;    size_t len_program;    char *cmd = NULL;    int passwd_field = -1;#ifdef SAMBA_CLIENT    char *domain = NULL, *smbpass = NULL;#endif    /* code executed by child to do extraction */    /* never returns */    /* make in_fd be our stdin */    if (dup2(in_fd, STDIN_FILENO) == -1)    {	error(_("dup2 failed in extract_files_child: %s"), strerror(errno));	/*NOTREACHED*/    }    /* read the file header */    fh_init(&file);    read_file_header(buffer, &file, sizeof(buffer), STDIN_FILENO);    if(file.type != F_DUMPFILE) {	print_header(stdout, &file);	error(_("bad header"));	/*NOTREACHED*/    }    if (file.program != NULL) {#ifdef GNUTAR	if (strcmp(file.program, GNUTAR) == 0)	    dumptype = IS_GNUTAR;#endif	if (dumptype == IS_UNKNOWN) {	    len_program = strlen(file.program);	    if(len_program >= 3 &&	       strcmp(&file.program[len_program-3],"tar") == 0)		dumptype = IS_TAR;	}#ifdef SAMBA_CLIENT	if (dumptype == IS_UNKNOWN && strcmp(file.program, SAMBA_CLIENT) ==0) {	    if (samba_extract_method == SAMBA_TAR)	      dumptype = IS_SAMBA_TAR;	    else	      dumptype = IS_SAMBA;	}#endif    }    /* form the arguments to restore */    files_off_tape = length_of_tape_list(elist);    switch (dumptype) {    case IS_SAMBA:#ifdef SAMBA_CLIENT    	extra_params = 10;    	break;#endif    case IS_TAR:    case IS_GNUTAR:        extra_params = 4;        break;    case IS_SAMBA_TAR:        extra_params = 3;        break;    case IS_UNKNOWN:    case IS_DUMP:#ifdef AIX_BACKUP        extra_params = 2;#else#if defined(XFSDUMP)	if (strcmp(file.program, XFSDUMP) == 0) {            extra_params = 4 + files_off_tape;	} else#endif	{        extra_params = 4;	}#endif    	break;    }    restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1)

⌨️ 快捷键说明

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