int main( int argc, char ** argv) { config_overrides_t *cfg_ovr; char *hostname; char *auth; char *service; char *config = NULL; int opt; extern int optind; extern char *optarg; FILE *input_file; int use_connect = 0; int got_input_file = 0; int i; unsigned char gfd[32768]; glib_init(); /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); // safe_fd(-1, 0); safe_cd(); set_pname("amservice"); /* drop root privileges */ if (!set_root_privs(0)) { error(_("amservice must be run setuid root")); } /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_SERVER); add_amanda_log_handler(amanda_log_stderr); our_features = am_init_feature_set(); our_feature_string = am_feature_to_string(our_features); /* process arguments */ for (i=0; i<argc; i++) { g_debug("argv[%d] = %s", i, argv[i]); } for (i = 0;i < 32768; i++) { gfd[i] = 0; } cfg_ovr = new_config_overrides(argc/2); input_file = stdin; while((opt = getopt_long(argc, argv, "o:f:s", long_options, NULL)) != EOF) { switch(opt) { case 1: printf("amservice-%s\n", VERSION); return(0); break; case 2: g_free(our_feature_string); g_free(our_features); our_feature_string = g_strdup(optarg); our_features = am_string_to_feature(our_feature_string); break; case 3: { gchar *copy_optarg = g_strdup(optarg); gchar *coma = strchr(copy_optarg, ','); gchar *stream_in; if (nb_lstream == DATA_FD_COUNT) { g_critical("Too many --stream, maximum is %d", DATA_FD_COUNT); exit(1); } else if (coma) { *coma++ = '\0'; stream_in = coma; coma = strchr(coma, ','); if (coma) { *coma++ = '\0'; lstreams[nb_lstream].name = g_strdup(copy_optarg); lstreams[nb_lstream].fd_in = atoi(stream_in); lstreams[nb_lstream].fd_out = atoi(coma); gfd[lstreams[nb_lstream].fd_in] = 1; gfd[lstreams[nb_lstream].fd_out] = 1; nb_lstream++; } } if (!coma) { g_critical("Invalid --stream option (%s)", optarg); exit(1); } g_free(copy_optarg); break; } case 4: g_free(config); config = g_strdup(optarg); break; case 'o': add_config_override_opt(cfg_ovr, optarg); break; case 'f': if (got_input_file == 1) { g_critical("Invalid two -f argument"); exit(1); } got_input_file = 1; if (*optarg == '/') { input_file = fopen(optarg, "r"); } else { char *name = g_strjoin(NULL, get_original_cwd(), "/", optarg, NULL); input_file = fopen(name, "r"); amfree(name); } if (!input_file) { g_critical("Cannot open input file '%s': %s", optarg, strerror(errno)); exit(1); } break; case 's': use_connect = 1; break; } } if (use_connect && !got_input_file) { g_critical("The -s option require -f"); exit(1); } /* close all unused fd */ for (i = 3;i < 32768; i++) { if (gfd[i] == 0 && i != dbfd() && (!got_input_file || i != fileno(input_file))) { close(i); } } argc -= optind, argv += optind; if(argc < 3) usage(); /* set a default config */ set_config_overrides(cfg_ovr); config_init(CONFIG_INIT_CLIENT|CONFIG_INIT_GLOBAL, NULL); if (config) { config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, config); } dbrename(get_config_name(), DBG_SUBDIR_SERVER); if (config_errors(NULL) >= CFGERR_WARNINGS) { config_print_errors(); if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } } conf_ctimeout = (time_t)getconf_int(CNF_CTIMEOUT); hostname = argv[0]; auth = argv[1]; if (g_str_equal(auth,"NULL")) { auth = getconf_str(CNF_AUTH); } service = argv[2]; /* start client side checks */ copy_stream = use_connect && got_input_file; client_protocol(hostname, auth, service, config, input_file); amfree(our_feature_string); am_release_feature_set(our_features); our_features = NULL; if (got_input_file) fclose(input_file); dbclose(); return(remote_errors != 0); }
void start_index( int createindex, int input, int mesg, int index, char * cmd) { int pipefd[2]; FILE *pipe_fp; int exitcode; if (!createindex) return; if (pipe(pipefd) != 0) { error(_("creating index pipe: %s"), strerror(errno)); /*NOTREACHED*/ } switch(indexpid = fork()) { case -1: error(_("forking index tee process: %s"), strerror(errno)); /*NOTREACHED*/ default: aclose(pipefd[0]); if (dup2(pipefd[1], input) == -1) { error(_("dup'ping index tee output: %s"), strerror(errno)); /*NOTREACHED*/ } aclose(pipefd[1]); return; case 0: break; } /* now in a child process */ save_fd(&pipefd[0], 4); save_fd(&index, 4); save_fd(&mesg, 4); save_fd(&input, 4); dup2(pipefd[0], 0); dup2(index, 1); dup2(mesg, 2); dup2(input, 3); for(index = 4; index < (int)FD_SETSIZE; index++) { if (index != dbfd()) { close(index); } } if ((pipe_fp = popen(cmd, "w")) == NULL) { error(_("couldn't start index creator [%s]"), strerror(errno)); /*NOTREACHED*/ } dbprintf(_("Started index creator: \"%s\"\n"), cmd); while(1) { char buffer[BUFSIZ], *ptr; ssize_t bytes_read; size_t bytes_written; size_t just_written; do { bytes_read = read(0, buffer, SIZEOF(buffer)); } while ((bytes_read < 0) && ((errno == EINTR) || (errno == EAGAIN))); if (bytes_read < 0) { error(_("index tee cannot read [%s]"), strerror(errno)); /*NOTREACHED*/ } if (bytes_read == 0) break; /* finished */ /* write the stuff to the subprocess */ ptr = buffer; bytes_written = 0; just_written = full_write(fileno(pipe_fp), ptr, (size_t)bytes_read); if (just_written < (size_t)bytes_read) { /* * just as we waited for write() to complete. */ if (errno != EPIPE) { dbprintf(_("Index tee cannot write to index creator [%s]\n"), strerror(errno)); } } else { bytes_written += just_written; ptr += just_written; } /* write the stuff to stdout, ensuring none lost when interrupt occurs */ ptr = buffer; bytes_written = 0; just_written = full_write(3, ptr, bytes_read); if (just_written < (size_t)bytes_read) { error(_("index tee cannot write [%s]"), strerror(errno)); /*NOTREACHED*/ } else { bytes_written += just_written; ptr += just_written; } } aclose(pipefd[1]); /* finished */ /* check the exit code of the pipe and moan if not 0 */ if ((exitcode = pclose(pipe_fp)) != 0) { char *exitstr = str_exit_status("Index pipe", exitcode); dbprintf("%s\n", exitstr); amfree(exitstr); } else { dbprintf(_("Index created successfully\n")); } pipe_fp = NULL; exit(exitcode); }