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 + -
显示快捷键?