Пример #1
0
/* Easy ways to run external commands.  For full documentation, see
 * 'commandrvf' below.
 */
int
commandf (char **stdoutput, char **stderror, int flags, const char *name, ...)
{
  va_list args;
  const char **argv;
  char *s;
  size_t i;
  int r;

  /* Collect the command line arguments into an array. */
  i = 2;
  argv = malloc (sizeof (char *) * i);
  if (argv == NULL) {
    perror ("malloc");
    return -1;
  }
  argv[0] = (char *) name;
  argv[1] = NULL;

  va_start (args, name);

  while ((s = va_arg (args, char *)) != NULL) {
    const char **p = realloc (argv, sizeof (char *) * (++i));
    if (p == NULL) {
      perror ("realloc");
      free (argv);
      va_end (args);
      return -1;
    }
    argv = p;
    argv[i-2] = s;
    argv[i-1] = NULL;
  }

  va_end (args);

  r = commandvf (stdoutput, stderror, flags, (const char * const*) argv);

  /* NB: Mustn't free the strings which are on the stack. */
  free (argv);

  return r;
}
Пример #2
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_ntfsresize (const char *device, int64_t size, int force)
{
  CLEANUP_FREE char *err = NULL;
  int r;
  const char *argv[MAX_ARGS];
  size_t i = 0;
  char size_str[32];

  ADD_ARG (argv, i, str_ntfsresize);
  ADD_ARG (argv, i, "-P");

  if (optargs_bitmask & GUESTFS_NTFSRESIZE_SIZE_BITMASK) {
    if (size <= 0) {
      reply_with_error ("size is zero or negative");
      return -1;
    }

    snprintf (size_str, sizeof size_str, "%" PRIi64, size);
    ADD_ARG (argv, i, "--size");
    ADD_ARG (argv, i, size_str);
  }

  if (optargs_bitmask & GUESTFS_NTFSRESIZE_FORCE_BITMASK && force)
    ADD_ARG (argv, i, "--force");

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandvf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    return -1;
  }

  return 0;
}
Пример #3
0
char *
do_command (char *const *argv)
{
  char *out;
  CLEANUP_FREE char *err = NULL;
  int r, flags;
  CLEANUP_BIND_STATE struct bind_state bind_state = { .mounted = false };
  CLEANUP_RESOLVER_STATE struct resolver_state resolver_state =
    { .mounted = false };

  /* We need a root filesystem mounted to do this. */
  NEED_ROOT (, return NULL);

  /* Conveniently, argv is already a NULL-terminated argv-style array
   * of parameters, so we can pass it straight in to our internal
   * commandv.  We just have to check the list is non-empty.
   */
  if (argv[0] == NULL) {
    reply_with_error ("passed an empty list");
    return NULL;
  }

  if (bind_mount (&bind_state) == -1)
    return NULL;
  if (enable_network) {
    if (set_up_etc_resolv_conf (&resolver_state) == -1)
      return NULL;
  }

  flags = COMMAND_FLAG_DO_CHROOT;

  r = commandvf (&out, &err, flags, (const char * const *) argv);

  free_bind_state (&bind_state);
  free_resolver_state (&resolver_state);

  if (r == -1) {
    reply_with_error ("%s", err);
    free (out);
    return NULL;
  }

  return out;			/* Caller frees. */
}

char **
do_command_lines (char *const *argv)
{
  CLEANUP_FREE char *out = NULL;
  char **lines;

  out = do_command (argv);
  if (out == NULL)
    return NULL;

  lines = split_lines (out);

  if (lines == NULL)
    return NULL;

  return lines;			/* Caller frees. */
}

char *
do_sh (const char *cmd)
{
  const char *argv[] = { "/bin/sh", "-c", cmd, NULL };

  return do_command ((char **) argv);
}

char **
do_sh_lines (const char *cmd)
{
  const char *argv[] = { "/bin/sh", "-c", cmd, NULL };

  return do_command_lines ((char **) argv);
}