📄 amidxtaped.c
字号:
/* initialize */ /* close stderr first so that debug file becomes it - amrestore chats to stderr, which we don't want going to client */ /* if no debug file, ship to bit bucket */ (void)close(STDERR_FILENO); dbopen(DBG_SUBDIR_SERVER); startclock(); dbprintf(_("%s: version %s\n"), pgm, version()); debug_dup_stderr_to_debug(); if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) { dbprintf(_("WARNING: argv[0] not defined: check inetd.conf\n")); } if(from_amandad == 0) { socklen = SIZEOF(addr); if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1) { error(_("getpeername: %s"), strerror(errno)); /*NOTREACHED*/ } if ((addr.sin_family != (sa_family_t)AF_INET) || (ntohs(addr.sin_port) == 20)) { error(_("connection rejected from %s family %d port %d"), inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port)); /*NOTREACHED*/ } /* do the security thing */ amfree(buf); fflush(stdout); cmdout = stdout; cmdin = stdin; buf = stralloc(get_client_line(cmdin)); check_security_buffer(buf); } else { ctlfdout = DATA_FD_OFFSET + 0; ctlfdin = DATA_FD_OFFSET + 1; datafdout = DATA_FD_OFFSET + 2; close(DATA_FD_OFFSET +3); /* read the REQ packet */ for(; (line = agets(stdin)) != NULL; free(line)) { if(strncmp_const(line, "OPTIONS ") == 0) { g_options = parse_g_options(line+8, 1); if(!g_options->hostname) { g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1); gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH); g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0'; } } } amfree(line); if(amandad_auth && g_options->auth) { if(strcasecmp(amandad_auth, g_options->auth) != 0) { g_printf(_("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'\n"), g_options->auth, amandad_auth); error(_("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'"), g_options->auth, amandad_auth); /*NOTREACHED*/ } } /* send the REP packet */ g_printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1); g_printf("\n"); fflush(stdout); fclose(stdin); fclose(stdout); cmdout = fdopen(ctlfdout, "a"); if (!cmdout) { error(_("amidxtaped: Can't fdopen(ctlfdout): %s"), strerror(errno)); /*NOTREACHED*/ } cmdin = fdopen(ctlfdin, "r"); if (!cmdin) { error(_("amidxtaped: Can't fdopen(ctlfdin): %s"), strerror(errno)); /*NOTREACHED*/ } } ds = dumpspec_new(NULL, NULL, NULL, NULL); for (re_end = 0; re_end == 0; ) { char *s, ch; amfree(buf); buf = stralloc(get_client_line(cmdin)); s = buf; if(strncmp_const_skip(buf, "LABEL=", s, ch) == 0) { tapes = unmarshal_tapelist_str(s); } else if(strncmp_const_skip(buf, "FSF=", s, ch) == 0) { rst_flags->fsf = OFF_T_ATOI(s); } else if(strncmp_const_skip(buf, "HEADER", s, ch) == 0) { rst_flags->headers = 1; } else if(strncmp_const_skip(buf, "FEATURES=", s, ch) == 0) { char *our_feature_string = NULL; their_feature_string = stralloc(s); am_release_feature_set(their_features); their_features = am_string_to_feature(their_feature_string); amfree(their_feature_string); our_feature_string = am_feature_to_string(our_features); if(from_amandad == 1) g_fprintf(cmdout,"FEATURES=%s\r\n", our_feature_string); else g_fprintf(cmdout,"%s", our_feature_string); fflush(cmdout); amfree(our_feature_string); } else if(strncmp_const_skip(buf, "DEVICE=", s, ch) == 0) { rst_flags->alt_tapedev= stralloc(s); } else if(strncmp_const_skip(buf, "HOST=", s, ch) == 0) { ds->host = stralloc(s); } else if(strncmp_const_skip(buf, "DISK=", s, ch) == 0) { ds->disk = stralloc(s); } else if(strncmp_const_skip(buf, "DATESTAMP=", s, ch) == 0) { ds->datestamp = stralloc(s); } else if(strncmp_const(buf, "END") == 0) { re_end = 1; } else if(strncmp_const_skip(buf, "CONFIG=", s, ch) == 0) { re_config = stralloc(s); if(strlen(re_config) == 0) amfree(re_config); } else if(buf[0] != '\0' && buf[0] >= '0' && buf[0] <= '9') { re_end = 1; } } amfree(buf); if(re_config) { config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL, re_config); dbrename(re_config, DBG_SUBDIR_SERVER); } else { config_init(0, NULL); } check_running_as(RUNNING_AS_DUMPUSER_PREFERRED); if(tapes && (!rst_flags->alt_tapedev || (re_config && ( strcmp(rst_flags->alt_tapedev, getconf_str(CNF_AMRECOVER_CHANGER)) == 0 || strcmp(rst_flags->alt_tapedev, getconf_str(CNF_TPCHANGER)) == 0 ) ) ) ) { /* We need certain options, if restoring from more than one tape */ if(tapes->next && !am_has_feature(their_features, fe_recover_splits)) { error(_("Client must support split dumps to restore requested data.")); /*NOTREACHED*/ } dbprintf(_("Restoring from changer, checking labels\n")); rst_flags->check_labels = 1; use_changer = 1; } /* build the dumpspec list from our single dumpspec */ dumpspecs = g_slist_append(NULL, (gpointer)ds); ds = NULL; if(!tapes && rst_flags->alt_tapedev){ sleep(10); dbprintf(_("Looks like we're restoring from a holding file...\n")); tapes = unmarshal_tapelist_str(rst_flags->alt_tapedev); tapes->isafile = 1; amfree(rst_flags->alt_tapedev); rst_flags->alt_tapedev = NULL; use_changer = FALSE; } tapedev = getconf_str(CNF_TAPEDEV); /* If we'll be stepping on the tape server's devices, lock them. */ if(re_config && (use_changer || (rst_flags->alt_tapedev && tapedev && strcmp(rst_flags->alt_tapedev, tapedev) == 0) ) ) { dbprintf(_("Locking devices\n")); parent_pid = getpid(); atexit(cleanup); get_lock = lock_logfile(); } /* Init the tape changer */ if(tapes && use_changer && changer_init() == 0) { dbprintf(_("No changer available\n")); } /* Read the default block size from the tape type */ if(re_config && (conf_tapetype = getconf_str(CNF_TAPETYPE)) != NULL) { tape = lookup_tapetype(conf_tapetype); rst_flags->blocksize = tapetype_get_blocksize(tape) * 1024; } if(rst_flags->fsf && re_config && getconf_boolean(CNF_AMRECOVER_DO_FSF) == 0) { rst_flags->fsf = (off_t)0; } if (!use_changer && re_config && getconf_boolean(CNF_AMRECOVER_CHECK_LABEL) == 0) { rst_flags->check_labels = 0; } /* establish a distinct data connection for dumpfile data */ if(am_has_feature(their_features, fe_recover_splits)) { if(from_amandad == 1) { rst_flags->pipe_to_fd = datafdout; } else { int data_fd; char *buf; dbprintf(_("Client understands split dumpfiles\n")); if((data_sock = stream_server(AF_INET, &data_port, STREAM_BUFSIZE, STREAM_BUFSIZE, 0)) < 0){ error(_("could not create data socket: %s"), strerror(errno)); /*NOTREACHED*/ } dbprintf(_("Local port %d set aside for data\n"), data_port); /* tell client where to connect */ g_printf(_("CONNECT %hu\n"), (unsigned short)data_port); fflush(stdout); if((data_fd = stream_accept(data_sock, TIMEOUT, STREAM_BUFSIZE, STREAM_BUFSIZE)) < 0){ error(_("stream_accept failed for client data connection: %s\n"), strerror(errno)); /*NOTREACHED*/ } buf = get_client_line_fd(data_fd); check_security_buffer(buf); rst_flags->pipe_to_fd = data_fd; } } else { rst_flags->pipe_to_fd = fileno(stdout); cmdout = stderr; } dbprintf(_("Sending output to file descriptor %d\n"), rst_flags->pipe_to_fd); tapedev = getconf_str(CNF_TAPEDEV); if(get_lock == 0 && re_config && (use_changer || (rst_flags->alt_tapedev && tapedev && strcmp(rst_flags->alt_tapedev, tapedev) == 0) ) ) { send_message(cmdout, rst_flags, their_features, _("%s exists: amdump or amflush is already running, " "or you must run amcleanup"), rst_conf_logfile); error(_("%s exists: amdump or amflush is already running, " "or you must run amcleanup"), rst_conf_logfile); } /* make sure our restore flags aren't crazy */ if (check_rst_flags(rst_flags) == -1) { if (rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd); send_message(cmdout, rst_flags, their_features, _("restore flags are crazy")); exit(1); } /* actual restoration */ search_tapes(cmdout, cmdin, use_changer, tapes, dumpspecs, rst_flags, their_features); dbprintf(_("Restoration finished\n")); /* cleanup */ if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd); free_tapelist(tapes); am_release_feature_set(their_features); amfree(rst_flags->alt_tapedev); amfree(rst_flags); dumpspec_list_free(dumpspecs); amfree(re_config); dbclose(); return 0;}static voidcleanup(void){ if(parent_pid == getpid()) { if(get_lock) unlink(rst_conf_logfile); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -