📄 extract_list.c
字号:
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)){ tt = newstralloc2(tt, "FEATURES=", our_features_string); send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt); get_amidxtaped_line(); if(strncmp_const(amidxtaped_line,"FEATURES=") == 0) { tapesrv_features = am_string_to_feature(amidxtaped_line+9); } else { g_fprintf(stderr, _("amrecover - expecting FEATURES line from amidxtaped\n")); stop_amidxtaped(); amfree(disk_regex); amfree(host_regex); amfree(clean_datestamp); return -1; } am_release_feature_set(tapesrv_features); } 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(amidxtaped_streams[CTLFD].fd, tt); } if(am_has_feature(indexsrv_features, fe_amidxtaped_label) && label && label[0] != '/') { tt = newstralloc2(tt,"LABEL=",label); send_to_tape_server(amidxtaped_streams[CTLFD].fd, 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(amidxtaped_streams[CTLFD].fd, tt); } send_to_tape_server(amidxtaped_streams[CTLFD].fd, "HEADER"); tt = newstralloc2(tt, "DEVICE=", dump_device_name); send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt); tt = newstralloc2(tt, "HOST=", host_regex); send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt); tt = newstralloc2(tt, "DISK=", disk_regex); send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt); tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp); send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt); send_to_tape_server(amidxtaped_streams[CTLFD].fd, "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(amidxtaped_streams[CTLFD].fd, "6"); send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-h"); send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-p"); send_to_tape_server(amidxtaped_streams[CTLFD].fd, dump_device_name); send_to_tape_server(amidxtaped_streams[CTLFD].fd, host_regex); send_to_tape_server(amidxtaped_streams[CTLFD].fd, disk_regex); send_to_tape_server(amidxtaped_streams[CTLFD].fd, clean_datestamp); dbprintf(_("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n"), dump_device_name, host_regex, disk_regex, clean_datestamp); } amfree(disk_regex); amfree(host_regex); amfree(clean_datestamp); return 0;}/* * 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, IS_BACKUP_API};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) { if (strcmp(file.program, "BACKUP") == 0) dumptype = IS_BACKUP_API;#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; case IS_BACKUP_API: extra_params = 5; break; } restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1) * 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 break; case IS_BACKUP_API: restore_args[j++] = stralloc(file.dumper); restore_args[j++] = stralloc("restore"); restore_args[j++] = stralloc("--config"); restore_args[j++] = stralloc(config_name); restore_args[j++] = stralloc("--disk"); restore_args[j++] = stralloc(file.disk); break; } for (i = 0, fn = elist->files; i < files_off_tape; i++, fn = fn->next) { switch (dumptype) { case IS_BACKUP_API: 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); } break; } }#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"); } break; case IS_BACKUP_API: cmd = vstralloc(DUMPER_DIR, "/", file.dumper, NULL); break; } 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. */intwriter_intermediary( EXTRACT_LIST * elist){ int child_pipe[2]; pid_t pid; amwait_t extractor_status; 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) { g_printf(_("writer_intermediary - error forking child")); return -1; } aclose(child_pipe[0]); security_stream_read(amidxtaped_streams[DATAFD].fd, read_amidxtaped_data, &(child_pipe[1])); while(get_amidxtaped_line() >= 0) { char desired_tape[MAX_TAPE_LABEL_BUF];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -