コード例 #1
0
ファイル: inspector.c プロジェクト: myyyy/libguestfs
static void
output_mountpoints (xmlTextWriterPtr xo, char *root)
{
  size_t i;

  CLEANUP_FREE_STRING_LIST char **mountpoints =
    guestfs_inspect_get_mountpoints (g, root);
  if (mountpoints == NULL)
    exit (EXIT_FAILURE);

  /* Sort by key length, shortest key first, and then name, so the
   * output is stable.
   */
  qsort (mountpoints, guestfs_int_count_strings (mountpoints) / 2,
         2 * sizeof (char *),
         compare_keys_len);

  XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "mountpoints"));

  for (i = 0; mountpoints[i] != NULL; i += 2) {
    CLEANUP_FREE char *p = guestfs_canonical_device_name (g, mountpoints[i+1]);
    if (!p)
      exit (EXIT_FAILURE);

    XMLERROR (-1,
              xmlTextWriterStartElement (xo, BAD_CAST "mountpoint"));
    XMLERROR (-1,
              xmlTextWriterWriteAttribute (xo, BAD_CAST "dev", BAD_CAST p));
    XMLERROR (-1,
              xmlTextWriterWriteString (xo, BAD_CAST mountpoints[i]));
    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
コード例 #2
0
ファイル: handle.c プロジェクト: myyyy/libguestfs
int
guestfs_impl_set_backend_setting (guestfs_h *g, const char *name, const char *value)
{
  char *new_setting;
  size_t len;

  new_setting = safe_asprintf (g, "%s=%s", name, value);

  if (g->backend_settings == NULL) {
    g->backend_settings = safe_malloc (g, sizeof (char *));
    g->backend_settings[0] = NULL;
    len = 0;
  }
  else {
    ignore_value (guestfs_clear_backend_setting (g, name));
    len = guestfs_int_count_strings (g->backend_settings);
  }

  g->backend_settings =
    safe_realloc (g, g->backend_settings, (len+2) * sizeof (char *));
  g->backend_settings[len++] = new_setting;
  g->backend_settings[len++] = NULL;

  return 0;
}
コード例 #3
0
ファイル: unit-tests.c プロジェクト: AlphaStaxLLC/libguestfs
static void
test_stringsbuf (void)
{
  guestfs_h *g;
  DECLARE_STRINGSBUF (sb);

  g = guestfs_create ();
  assert (g);

  guestfs_int_add_string (g, &sb, "aaa");
  guestfs_int_add_string (g, &sb, "bbb");
  guestfs_int_add_string (g, &sb, "ccc");
  guestfs_int_add_string (g, &sb, "");
  guestfs_int_end_stringsbuf (g, &sb);

  assert (sb.size == 5 /* 4 strings + terminating NULL */);
  assert (STREQ (sb.argv[0], "aaa"));
  assert (STREQ (sb.argv[1], "bbb"));
  assert (STREQ (sb.argv[2], "ccc"));
  assert (STREQ (sb.argv[3], ""));
  assert (sb.argv[4] == NULL);

  assert (guestfs_int_count_strings (sb.argv) == 4);

  guestfs_int_free_stringsbuf (&sb);
  guestfs_close (g);
}
コード例 #4
0
ファイル: debug.c プロジェクト: libguestfs/libguestfs
/* List files in the appliance. */
static char *
debug_ll (const char *subcmd, size_t argc, char *const *const argv)
{
  const size_t len = guestfs_int_count_strings (argv);
  CLEANUP_FREE const char **cargv = NULL;
  size_t i;
  int r;
  char *out;
  CLEANUP_FREE char *err = NULL;

  cargv = malloc (sizeof (char *) * (len+3));
  if (cargv == NULL) {
    reply_with_perror ("malloc");
    return NULL;
  }

  cargv[0] = "ls";
  cargv[1] = "-la";
  for (i = 0; i < len; ++i)
    cargv[2+i] = argv[i];
  cargv[2+len] = NULL;

  r = commandv (&out, &err, (void *) cargv);
  if (r == -1) {
    reply_with_error ("ll: %s", err);
    free (out);
    return NULL;
  }

  return out;
}
コード例 #5
0
ファイル: inspector.c プロジェクト: myyyy/libguestfs
static void
output_filesystems (xmlTextWriterPtr xo, char *root)
{
  char *str;
  size_t i;

  CLEANUP_FREE_STRING_LIST char **filesystems =
    guestfs_inspect_get_filesystems (g, root);
  if (filesystems == NULL)
    exit (EXIT_FAILURE);

  /* Sort by name so the output is stable. */
  qsort (filesystems, guestfs_int_count_strings (filesystems), sizeof (char *),
         compare_keys);

  XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystems"));

  for (i = 0; filesystems[i] != NULL; ++i) {
    str = guestfs_canonical_device_name (g, filesystems[i]);
    if (!str)
      exit (EXIT_FAILURE);

    XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystem"));
    XMLERROR (-1,
              xmlTextWriterWriteAttribute (xo, BAD_CAST "dev", BAD_CAST str));
    free (str);

    guestfs_push_error_handler (g, NULL, NULL);

    str = guestfs_vfs_type (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "type",
                                           BAD_CAST str));
    free (str);

    str = guestfs_vfs_label (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "label",
                                           BAD_CAST str));
    free (str);

    str = guestfs_vfs_uuid (g, filesystems[i]);
    if (str && str[0])
      XMLERROR (-1,
                xmlTextWriterWriteElement (xo, BAD_CAST "uuid",
                                           BAD_CAST str));
    free (str);

    guestfs_pop_error_handler (g);

    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
コード例 #6
0
ファイル: kernel.c プロジェクト: libguestfs/libguestfs
/* Perform conversion using the kernel method. */
void
kernel_conversion (struct config *config, char **cmdline, int cmdline_source)
{
  const char *p;

  /* Pre-conversion command. */
  p = get_cmdline_key (cmdline, "p2v.pre");
  if (p)
    run_command ("p2v.pre", p);

  /* Connect to and interrogate virt-v2v on the conversion server. */
  p = get_cmdline_key (cmdline, "p2v.skip_test_connection");
  if (!p) {
    wait_network_online (config);
    if (test_connection (config) == -1) {
      const char *err = get_ssh_error ();

      error (EXIT_FAILURE, 0,
             "error opening control connection to %s:%d: %s",
             config->remote.server, config->remote.port, err);
    }
  }

  /* Some disks must have been specified for conversion. */
  if (config->disks == NULL || guestfs_int_count_strings (config->disks) == 0)
    error (EXIT_FAILURE, 0,
           "no non-removable disks were discovered on this machine.\n"
           "virt-p2v looked in /sys/block and in p2v.disks on the kernel command line.\n"
           "This is a fatal error and virt-p2v cannot continue.");

  /* Perform the conversion in text mode. */
  if (start_conversion (config, notify_ui_callback) == -1) {
    const char *err = get_conversion_error ();

    fprintf (stderr, "%s: error during conversion: %s\n",
             getprogname (), err);

    p = get_cmdline_key (cmdline, "p2v.fail");
    if (p)
      run_command ("p2v.fail", p);

    exit (EXIT_FAILURE);
  }

  ansi_green (stdout);
  printf ("Conversion finished successfully.");
  ansi_restore (stdout);
  putchar ('\n');

  p = get_cmdline_key (cmdline, "p2v.post");
  if (!p) {
    if (geteuid () == 0 && cmdline_source == CMDLINE_SOURCE_PROC_CMDLINE)
      p = "poweroff";
  }
  if (p)
    run_command ("p2v.post", p);
}
コード例 #7
0
ファイル: unit-tests.c プロジェクト: AlphaStaxLLC/libguestfs
/**
 * Test C<guestfs_int_split_string>.
 */
static void
test_split (void)
{
  char **ret;

  ret = guestfs_int_split_string (':', "");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 0);
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', "a");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 1);
  assert (STREQ (ret[0], "a"));
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', ":");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 2);
  assert (STREQ (ret[0], ""));
  assert (STREQ (ret[1], ""));
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', "::");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 3);
  assert (STREQ (ret[0], ""));
  assert (STREQ (ret[1], ""));
  assert (STREQ (ret[2], ""));
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', ":a");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 2);
  assert (STREQ (ret[0], ""));
  assert (STREQ (ret[1], "a"));
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', "a:");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 2);
  assert (STREQ (ret[0], "a"));
  assert (STREQ (ret[1], ""));
  guestfs_int_free_string_list (ret);

  ret = guestfs_int_split_string (':', "a:b:c");
  assert (ret);
  assert (guestfs_int_count_strings (ret) == 3);
  assert (STREQ (ret[0], "a"));
  assert (STREQ (ret[1], "b"));
  assert (STREQ (ret[2], "c"));
  guestfs_int_free_string_list (ret);
}
コード例 #8
0
ファイル: file.c プロジェクト: libguestfs/libguestfs
struct guestfs_xattr_list *
guestfs_impl_lxattrlist (guestfs_h *g, const char *dir, char *const *names)
{
  size_t len = guestfs_int_count_strings (names);
  size_t i, old_len;
  struct guestfs_xattr_list *ret;

  ret = safe_malloc (g, sizeof *ret);
  ret->len = 0;
  ret->val = NULL;

  while (len > 0) {
    CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;

    /* Note we don't need to free up the strings because take_strings
     * does not do a deep copy.
     */
    CLEANUP_FREE char **first = take_strings (g, names, LXATTRLIST_MAX, &names);
    len = len <= LXATTRLIST_MAX ? 0 : len - LXATTRLIST_MAX;

    xattrs = guestfs_internal_lxattrlist (g, dir, first);

    if (xattrs == NULL) {
      guestfs_free_xattr_list (ret);
      return NULL;
    }

    /* Append xattrs to ret. */
    old_len = ret->len;
    ret->len += xattrs->len;
    ret->val = safe_realloc (g, ret->val,
                             ret->len * sizeof (struct guestfs_xattr));
    for (i = 0; i < xattrs->len; ++i, ++old_len) {
      /* We have to make a deep copy of the attribute name and value.
       */
      ret->val[old_len].attrname = safe_strdup (g, xattrs->val[i].attrname);
      ret->val[old_len].attrval = safe_malloc (g, xattrs->val[i].attrval_len);
      ret->val[old_len].attrval_len = xattrs->val[i].attrval_len;
      memcpy (ret->val[old_len].attrval, xattrs->val[i].attrval,
              xattrs->val[i].attrval_len);
    }
  }

  return ret;
}
コード例 #9
0
ファイル: inspector.c プロジェクト: myyyy/libguestfs
static void
output_drive_mappings (xmlTextWriterPtr xo, char *root)
{
  CLEANUP_FREE_STRING_LIST char **drive_mappings = NULL;
  char *str;
  size_t i;

  guestfs_push_error_handler (g, NULL, NULL);
  drive_mappings = guestfs_inspect_get_drive_mappings (g, root);
  guestfs_pop_error_handler (g);
  if (drive_mappings == NULL)
    return;

  if (drive_mappings[0] == NULL)
    return;

  /* Sort by key. */
  qsort (drive_mappings,
         guestfs_int_count_strings (drive_mappings) / 2, 2 * sizeof (char *),
         compare_keys_nocase);

  XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "drive_mappings"));

  for (i = 0; drive_mappings[i] != NULL; i += 2) {
    str = guestfs_canonical_device_name (g, drive_mappings[i+1]);
    if (!str)
      exit (EXIT_FAILURE);

    XMLERROR (-1,
              xmlTextWriterStartElement (xo, BAD_CAST "drive_mapping"));
    XMLERROR (-1,
              xmlTextWriterWriteAttribute (xo, BAD_CAST "name",
                                           BAD_CAST drive_mappings[i]));
    XMLERROR (-1,
              xmlTextWriterWriteString (xo, BAD_CAST str));
    XMLERROR (-1, xmlTextWriterEndElement (xo));

    free (str);
  }

  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
コード例 #10
0
ファイル: file.c プロジェクト: libguestfs/libguestfs
struct guestfs_statns_list *
guestfs_impl_lstatnslist (guestfs_h *g, const char *dir, char * const*names)
{
  size_t len = guestfs_int_count_strings (names);
  size_t old_len;
  struct guestfs_statns_list *ret;

  ret = safe_malloc (g, sizeof *ret);
  ret->len = 0;
  ret->val = NULL;

  while (len > 0) {
    CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *stats = NULL;

    /* Note we don't need to free up the strings because take_strings
     * does not do a deep copy.
     */
    CLEANUP_FREE char **first = take_strings (g, names, LSTATNSLIST_MAX, &names);

    len = len <= LSTATNSLIST_MAX ? 0 : len - LSTATNSLIST_MAX;

    stats = guestfs_internal_lstatnslist (g, dir, first);

    if (stats == NULL) {
      guestfs_free_statns_list (ret);
      return NULL;
    }

    /* Append stats to ret. */
    old_len = ret->len;
    ret->len += stats->len;
    ret->val = safe_realloc (g, ret->val,
                             ret->len * sizeof (struct guestfs_statns));
    memcpy (&ret->val[old_len], stats->val,
            stats->len * sizeof (struct guestfs_statns));
  }

  return ret;
}
コード例 #11
0
ファイル: ssh.c プロジェクト: Stratoscale/libguestfs
/**
 * Start ssh subprocess with the standard arguments and possibly some
 * optional arguments.  Also handles authentication.
 */
static mexp_h *
start_ssh (struct config *config, char **extra_args, int wait_prompt)
{
  size_t i, j, nr_args, count;
  char port_str[64];
  CLEANUP_FREE /* [sic] */ const char **args = NULL;
  mexp_h *h;
  const int ovecsize = 12;
  int ovector[ovecsize];
  int saved_timeout;
  int using_password_auth;

  if (cache_ssh_identity (config) == -1)
    return NULL;

  /* Are we using password or identity authentication? */
  using_password_auth = config->identity_file == NULL;

  /* Create the ssh argument array. */
  nr_args = 0;
  if (extra_args != NULL)
    nr_args = guestfs_int_count_strings (extra_args);

  if (using_password_auth)
    nr_args += 11;
  else
    nr_args += 13;
  args = malloc (sizeof (char *) * nr_args);
  if (args == NULL)
    error (EXIT_FAILURE, errno, "malloc");

  j = 0;
  args[j++] = "ssh";
  args[j++] = "-p";             /* Port. */
  snprintf (port_str, sizeof port_str, "%d", config->port);
  args[j++] = port_str;
  args[j++] = "-l";             /* Username. */
  args[j++] = config->username ? config->username : "******";
  args[j++] = "-o";             /* Host key will always be novel. */
  args[j++] = "StrictHostKeyChecking=no";
  if (using_password_auth) {
    /* Only use password authentication. */
    args[j++] = "-o";
    args[j++] = "PreferredAuthentications=keyboard-interactive,password";
  }
  else {
    /* Use identity file (private key). */
    args[j++] = "-o";
    args[j++] = "PreferredAuthentications=publickey";
    args[j++] = "-i";
    args[j++] = config->identity_file;
  }
  if (extra_args != NULL) {
    for (i = 0; extra_args[i] != NULL; ++i)
      args[j++] = extra_args[i];
  }
  args[j++] = config->server;   /* Conversion server. */
  args[j++] = NULL;
  assert (j == nr_args);

  h = mexp_spawnv ("ssh", (char **) args);
  if (h == NULL)
    return NULL;

  if (using_password_auth &&
      config->password && strlen (config->password) > 0) {
    /* Wait for the password prompt. */
    switch (mexp_expect (h,
                         (mexp_regexp[]) {
                           { 100, .re = password_re },
                           { 0 }
                         }, ovector, ovecsize)) {
コード例 #12
0
ファイル: ssh.c プロジェクト: noxdafox/libguestfs
/**
 * Start ssh subprocess with the standard arguments and possibly some
 * optional arguments.  Also handles authentication.
 */
static mexp_h *
start_ssh (unsigned spawn_flags, struct config *config,
           char **extra_args, int wait_prompt)
{
  size_t i, j, nr_args, count;
  char port_str[64];
  char connect_timeout_str[128];
  CLEANUP_FREE /* [sic] */ const char **args = NULL;
  mexp_h *h;
  const int ovecsize = 12;
  int ovector[ovecsize];
  int saved_timeout;
  int using_password_auth;

  if (cache_ssh_identity (config) == -1)
    return NULL;

  /* Are we using password or identity authentication? */
  using_password_auth = config->identity_file == NULL;

  /* Create the ssh argument array. */
  nr_args = 0;
  if (extra_args != NULL)
    nr_args = guestfs_int_count_strings (extra_args);

  if (using_password_auth)
    nr_args += 13;
  else
    nr_args += 15;
  args = malloc (sizeof (char *) * nr_args);
  if (args == NULL)
    error (EXIT_FAILURE, errno, "malloc");

  j = 0;
  args[j++] = "ssh";
  args[j++] = "-p";             /* Port. */
  snprintf (port_str, sizeof port_str, "%d", config->port);
  args[j++] = port_str;
  args[j++] = "-l";             /* Username. */
  args[j++] = config->username ? config->username : "******";
  args[j++] = "-o";             /* Host key will always be novel. */
  args[j++] = "StrictHostKeyChecking=no";
  args[j++] = "-o";             /* ConnectTimeout */
  snprintf (connect_timeout_str, sizeof connect_timeout_str,
            "ConnectTimeout=%d", SSH_TIMEOUT);
  args[j++] = connect_timeout_str;
  if (using_password_auth) {
    /* Only use password authentication. */
    args[j++] = "-o";
    args[j++] = "PreferredAuthentications=keyboard-interactive,password";
  }
  else {
    /* Use identity file (private key). */
    args[j++] = "-o";
    args[j++] = "PreferredAuthentications=publickey";
    args[j++] = "-i";
    args[j++] = config->identity_file;
  }
  if (extra_args != NULL) {
    for (i = 0; extra_args[i] != NULL; ++i)
      args[j++] = extra_args[i];
  }
  args[j++] = config->server;   /* Conversion server. */
  args[j++] = NULL;
  assert (j == nr_args);

#if DEBUG_STDERR
  fputs ("ssh command: ", stderr);
  for (i = 0; i < nr_args - 1; ++i) {
    if (i > 0) fputc (' ', stderr);
    fputs (args[i], stderr);
  }
  fputc ('\n', stderr);
#endif

  /* Create the miniexpect handle. */
  h = mexp_spawnvf (spawn_flags, "ssh", (char **) args);
  if (h == NULL) {
    set_ssh_internal_error ("ssh: mexp_spawnvf: %m");
    return NULL;
  }

  /* We want the ssh ConnectTimeout to be less than the miniexpect
   * timeout, so that if the server is completely unresponsive we
   * still see the error from ssh, not a timeout from miniexpect.  The
   * obvious solution to this is to set ConnectTimeout (above) and to
   * set the miniexpect timeout to be a little bit larger.
   */
  mexp_set_timeout (h, SSH_TIMEOUT + 20);

  if (using_password_auth &&
      config->password && strlen (config->password) > 0) {
    CLEANUP_FREE char *ssh_message = NULL;

    /* Wait for the password prompt. */
  wait_password_again:
    switch (mexp_expect (h,
                         (mexp_regexp[]) {
                           { 100, .re = password_re },
コード例 #13
0
ファイル: kernel.c プロジェクト: carriercomm/libguestfs
void
kernel_configuration (struct config *config, char **cmdline, int cmdline_source)
{
  const char *p;

  p = get_cmdline_key (cmdline, "p2v.pre");
  if (p)
    run_command (config->verbose, "p2v.pre", p);

  p = get_cmdline_key (cmdline, "p2v.server");
  assert (p); /* checked by caller */
  free (config->server);
  config->server = strdup (p);

  p = get_cmdline_key (cmdline, "p2v.port");
  if (p) {
    if (sscanf (p, "%d", &config->port) != 1) {
      fprintf (stderr, "%s: cannot parse p2v.port from kernel command line",
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }
  }

  p = get_cmdline_key (cmdline, "p2v.username");
  if (p) {
    free (config->username);
    config->username = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.password");
  if (p) {
    free (config->password);
    config->password = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.identity");
  if (p) {
    free (config->identity_url);
    config->identity_url = strdup (p);
    config->identity_file_needs_update = 1;
  }

  p = get_cmdline_key (cmdline, "p2v.sudo");
  if (p)
    config->sudo = 1;

  /* We should now be able to connect and interrogate virt-v2v
   * on the conversion server.
   */
  p = get_cmdline_key (cmdline, "p2v.skip_test_connection");
  if (!p) {
    wait_network_online (config);
    if (test_connection (config) == -1) {
      const char *err = get_ssh_error ();

      fprintf (stderr, "%s: error opening control connection to %s:%d: %s\n",
               guestfs_int_program_name, config->server, config->port, err);
      exit (EXIT_FAILURE);
    }
  }

  p = get_cmdline_key (cmdline, "p2v.name");
  if (p) {
    free (config->guestname);
    config->guestname = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.vcpus");
  if (p) {
    if (sscanf (p, "%d", &config->vcpus) != 1) {
      fprintf (stderr, "%s: cannot parse p2v.vcpus from kernel command line\n",
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }
  }

  p = get_cmdline_key (cmdline, "p2v.memory");
  if (p) {
    char mem_code;

    if (sscanf (p, "%" SCNu64 "%c", &config->memory, &mem_code) != 2) {
      fprintf (stderr, "%s: cannot parse p2v.memory from kernel command line\n",
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }
    config->memory *= 1024;
    if (mem_code == 'M' || mem_code == 'm'
        || mem_code == 'G' || mem_code == 'g')
      config->memory *= 1024;
    if (mem_code == 'G' || mem_code == 'g')
      config->memory *= 1024;
    if (mem_code != 'M' && mem_code != 'm'
        && mem_code != 'G' && mem_code != 'g') {
      fprintf (stderr, "%s: p2v.memory on kernel command line must be followed by 'G' or 'M'\n",
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }
  }

  p = get_cmdline_key (cmdline, "p2v.disks");
  if (p) {
    CLEANUP_FREE char *t;

    t = strdup (p);
    guestfs_int_free_string_list (config->disks);
    config->disks = guestfs_int_split_string (',', t);
  }

  p = get_cmdline_key (cmdline, "p2v.removable");
  if (p) {
    CLEANUP_FREE char *t;

    t = strdup (p);
    guestfs_int_free_string_list (config->removable);
    config->removable = guestfs_int_split_string (',', t);
  }

  p = get_cmdline_key (cmdline, "p2v.interfaces");
  if (p) {
    CLEANUP_FREE char *t;

    t = strdup (p);
    guestfs_int_free_string_list (config->interfaces);
    config->interfaces = guestfs_int_split_string (',', t);
  }

  p = get_cmdline_key (cmdline, "p2v.network");
  if (p) {
    CLEANUP_FREE char *t;

    t = strdup (p);
    guestfs_int_free_string_list (config->network_map);
    config->network_map = guestfs_int_split_string (',', t);
  }

  p = get_cmdline_key (cmdline, "p2v.o");
  if (p) {
    free (config->output);
    config->output = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.oa");
  if (p) {
    if (STREQ (p, "sparse"))
      config->output_allocation = OUTPUT_ALLOCATION_SPARSE;
    else if (STREQ (p, "preallocated"))
      config->output_allocation = OUTPUT_ALLOCATION_PREALLOCATED;
    else
      fprintf (stderr, "%s: warning: don't know what p2v.oa=%s means\n",
               guestfs_int_program_name, p);
  }

  p = get_cmdline_key (cmdline, "p2v.oc");
  if (p) {
    free (config->output_connection);
    config->output_connection = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.of");
  if (p) {
    free (config->output_format);
    config->output_format = strdup (p);
  }

  p = get_cmdline_key (cmdline, "p2v.os");
  if (p) {
    free (config->output_storage);
    config->output_storage = strdup (p);
  }

  /* Undocumented command line tool used for testing command line parsing. */
  p = get_cmdline_key (cmdline, "p2v.dump_config_and_exit");
  if (p) {
    print_config (config, stdout);
    exit (EXIT_SUCCESS);
  }

  /* Some disks must have been specified for conversion. */
  if (config->disks == NULL || guestfs_int_count_strings (config->disks) == 0) {
    fprintf (stderr, "%s: error: no non-removable disks were discovered on this machine.\n",
             guestfs_int_program_name);
    fprintf (stderr, "virt-p2v looked in /sys/block and in p2v.disks on the kernel command line.\n");
    fprintf (stderr, "This is a fatal error and virt-p2v cannot continue.\n");
    exit (EXIT_FAILURE);
  }

  /* Perform the conversion in text mode. */
  if (start_conversion (config, notify_ui_callback) == -1) {
    const char *err = get_conversion_error ();

    fprintf (stderr, "%s: error during conversion: %s\n",
             guestfs_int_program_name, err);

    p = get_cmdline_key (cmdline, "p2v.fail");
    if (p)
      run_command (config->verbose, "p2v.fail", p);

    exit (EXIT_FAILURE);
  }

  p = get_cmdline_key (cmdline, "p2v.post");
  if (!p) {
    if (geteuid () == 0 && cmdline_source == CMDLINE_SOURCE_PROC_CMDLINE)
      p = "poweroff";
  }
  if (p)
    run_command (config->verbose, "p2v.post", p);
}
コード例 #14
0
ファイル: glob.c プロジェクト: rwmjones/libguestfs
int
run_glob (const char *cmd, size_t argc, char *argv[])
{
  /* For 'glob cmd foo /s* /usr/s*' this could be:
   *
   * (globs[0]) globs[1]  globs[1]  globs[2]
   * (cmd)      foo       /sbin     /usr/sbin
   *                      /srv      /usr/share
   *                      /sys      /usr/src
   *
   * and then we call every combination (ie. 1x3x3) of
   * argv[1-].
   */
  CLEANUP_FREE char ***globs = NULL;
  CLEANUP_FREE size_t *posn = NULL;
  CLEANUP_FREE size_t *count = NULL;
  size_t i;
  int r = 0;

  globs = malloc (sizeof (char **) * argc);
  posn = malloc (sizeof (size_t) * argc);
  count = malloc (sizeof (size_t) * argc);
  if (globs == NULL || posn == NULL || count == NULL) {
    perror ("malloc");
    return -1;
  }

  if (argc < 1) {
    fprintf (stderr, _("use 'glob command [args...]'\n"));
    return -1;
  }

  /* This array will record the current execution position
   * in the Cartesian product.
   * NB. globs[0], posn[0], count[0] are ignored.
   */
  for (i = 1; i < argc; ++i)
    posn[i] = 0;
  for (i = 1; i < argc; ++i)
    globs[i] = NULL;

  for (i = 1; i < argc; ++i) {
    char **pp;

    /* If it begins with "/dev/" then treat it as a globbable device
     * name.
     */
    if (STRPREFIX (argv[i], "/dev/")) {
      pp = expand_devicename (g, argv[i]);
      if (pp == NULL) {
        r = -1;
        goto error;
      }
    }
    /* If it begins with "/" it might be a globbable pathname. */
    else if (argv[i][0] == '/') {
      pp = expand_pathname (g, argv[i]);
      if (pp == NULL) {
        r = -1;
        goto error;
      }
    }
    /* Doesn't begin with '/' */
    else {
      pp = single_element_list (argv[i]);
      if (pp == NULL) {
        r = -1;
        goto error;
      }
    }

    globs[i] = pp;
    count[i] = guestfs_int_count_strings (pp);
  }

  /* Issue the commands. */
  if (glob_issue (argv[0], argc, globs, posn, count, &r) == -1) {
    r = -1;
    goto error;
  }

  /* Free resources. */
 error:
  for (i = 1; i < argc; ++i)
    if (globs[i])
      guestfs_int_free_string_list (globs[i]);
  return r;
}
コード例 #15
0
ファイル: config.c プロジェクト: FengYang/libguestfs
void
parse_config (void)
{
  const char *home;

  /* Try the global configuration first. */
  read_config_from_file (etc_filename);

  {
    /* Then read the configuration from XDG system paths. */
    const char *xdg_env, *var;
    CLEANUP_FREE_STRING_LIST char **xdg_config_dirs = NULL;
    size_t xdg_config_dirs_count;

    xdg_env = getenv ("XDG_CONFIG_DIRS");
    var = xdg_env != NULL && xdg_env[0] != 0 ? xdg_env : "/etc/xdg";
    xdg_config_dirs = guestfs_int_split_string (':', var);
    xdg_config_dirs_count = guestfs_int_count_strings (xdg_config_dirs);
    for (size_t i = xdg_config_dirs_count; i > 0; --i) {
      CLEANUP_FREE char *path = NULL;
      const char *dir = xdg_config_dirs[i - 1];

      if (asprintf (&path, "%s/libguestfs/" GLOBAL_CONFIG_FILENAME, dir) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }

      read_config_from_file (path);
    }
  }

  /* Read the configuration from $HOME, to override system settings. */
  home = getenv ("HOME");
  if (home != NULL) {
    {
      /* Old-style configuration file first. */
      CLEANUP_FREE char *path = NULL;

      if (asprintf (&path, "%s/%s", home, home_filename) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }

      read_config_from_file (path);
    }

    {
      /* Then, XDG_CONFIG_HOME path. */
      CLEANUP_FREE char *path = NULL;
      CLEANUP_FREE char *home_copy = strdup (home);
      const char *xdg_env;

      if (home_copy == NULL) {
        perror ("strdup");
        exit (EXIT_FAILURE);
      }

      xdg_env = getenv ("XDG_CONFIG_HOME");
      if (xdg_env == NULL) {
        if (asprintf (&path, "%s/.config/libguestfs/" GLOBAL_CONFIG_FILENAME,
                      home_copy) == -1) {
          perror ("asprintf");
          exit (EXIT_FAILURE);
        }
      } else {
        if (asprintf (&path, "%s/libguestfs/" GLOBAL_CONFIG_FILENAME,
                      xdg_env) == -1) {
          perror ("asprintf");
          exit (EXIT_FAILURE);
        }
      }

      read_config_from_file (path);
    }
  }
}