Beispiel #1
0
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);
}
Beispiel #2
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);
}