예제 #1
0
void
free_drives (struct drv *drv)
{
  if (!drv) return;
  free_drives (drv->next);

  free (drv->device);

  switch (drv->type) {
  case drv_a:
    free (drv->a.filename);
    /* a.format is an optarg, so don't free it */
    break;
  case drv_uri:
    free (drv->uri.path);
    free (drv->uri.protocol);
    guestfs___free_string_list (drv->uri.server);
    free (drv->uri.username);
    break;
  case drv_d:
    /* d.filename is optarg, don't free it */
    break;
#if COMPILING_GUESTFISH
  case drv_N:
    free (drv->N.filename);
    drv->N.data_free (drv->N.data);
    break;
#endif
  default: ;                    /* keep GCC happy */
  }
  free (drv);
}
예제 #2
0
void
free_drives (struct drv *drv)
{
  if (!drv) return;
  free_drives (drv->next);

  free (drv->device);

  switch (drv->type) {
  case drv_a: /* a.filename and a.format are optargs, don't free them */ break;
  case drv_d: /* d.filename is optarg, don't free it */ break;
  case drv_N:
    free (drv->N.filename);
    drv->N.data_free (drv->N.data);
    break;
  default: ;                    /* keep GCC happy */
  }
  free (drv);
}
예제 #3
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int r;
  int option_index;

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, errno, "guestfs_create");

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else
        error (EXIT_FAILURE, 0,
               _("unknown long option: %s (%d)"),
               long_options[option_index].name, option_index);
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* User must not specify more arguments on the command line. */
  if (optind != argc) {
    fprintf (stderr, _("%s: error: extra argument '%s' on command line.\n"
             "Make sure to specify the argument for --format "
             "like '--format=%s'.\n"),
             guestfs_int_program_name, argv[optind], argv[optind]);
    usage (EXIT_FAILURE);
  }

  CHECK_OPTION_format_consumed;

  /* User must have specified some drives. */
  if (drvs == NULL) {
    fprintf (stderr, _("%s: error: you must specify at least one -a or -d option.\n"),
             guestfs_int_program_name);
    usage (EXIT_FAILURE);
  }

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  r = do_log ();

  guestfs_close (g);

  exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #4
0
int
main (int argc, char *argv[])
{
  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  /* We use random(3) below. */
  srandom (time (NULL));

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:b:c:d:e:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "backup", 1, 0, 'b' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "expr", 1, 0, 'e' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
  char *root, **roots;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  argv[0] = bad_cast (program_name);

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'b':
      if (backup_extension) {
        fprintf (stderr, _("%s: -b option given multiple times\n"),
                 program_name);
        exit (EXIT_FAILURE);
      }
      backup_extension = optarg;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'e':
      if (perl_expr) {
        fprintf (stderr, _("%s: -e option given multiple times\n"),
                 program_name);
        exit (EXIT_FAILURE);
      }
      perl_expr = optarg;
      break;

    case 'h':
      usage (EXIT_SUCCESS);

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-edit which is how we detect this.
   */
  if (drvs == NULL) {
    /* argc - 1 because last parameter is the single filename. */
    while (optind < argc - 1) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = malloc (sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = argv[optind];
        drv->a.format = NULL;
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = malloc (sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 0);
  assert (inspector == 1);
  assert (live == 0);

  /* User must specify at least one filename on the command line. */
  if (optind >= argc || argc - optind < 1)
    usage (EXIT_FAILURE);

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives. */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  /* Get root mountpoint. */
  roots = guestfs_inspect_get_roots (g);
  if (!roots)
    exit (EXIT_FAILURE);
  /* see fish/inspect.c:inspect_mount */
  assert (roots[0] != NULL && roots[1] == NULL);
  root = roots[0];
  free (roots);

  while (optind < argc) {
    edit (argv[optind], root);
    optind++;
  }

  free (root);

  /* Cleanly unmount the disks after editing. */
  if (guestfs_umount_all (g) == -1 || guestfs_sync (g) == -1)
    exit (EXIT_FAILURE);

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #5
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hlvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "all", 0, 0, 0 },
    { "blkdevs", 0, 0, 0 },
    { "block-devices", 0, 0, 0 },
    { "connect", 1, 0, 'c' },
    { "csv", 0, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "extra", 0, 0, 0 },
    { "filesystems", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "keys-from-stdin", 0, 0, 0 },
    { "logical-volumes", 0, 0, 0 },
    { "logvols", 0, 0, 0 },
    { "long", 0, 0, 'l' },
    { "long-options", 0, 0, 0 },
    { "lvs", 0, 0, 0 },
    { "no-title", 0, 0, 0 },
    { "parts", 0, 0, 0 },
    { "partitions", 0, 0, 0 },
    { "physical-volumes", 0, 0, 0 },
    { "physvols", 0, 0, 0 },
    { "pvs", 0, 0, 0 },
    { "uuid", 0, 0, 0 },
    { "uuids", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { "vgs", 0, 0, 0 },
    { "volgroups", 0, 0, 0 },
    { "volume-groups", 0, 0, 0 },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
  int no_title = 0;             /* --no-title */
  int long_mode = 0;            /* --long|-l */
  int uuid = 0;                 /* --uuid */
  int title;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "all")) {
        output = OUTPUT_ALL;
      } else if (STREQ (long_options[option_index].name, "blkdevs") ||
                 STREQ (long_options[option_index].name, "block-devices")) {
        output |= OUTPUT_BLOCKDEVS;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "extra")) {
        output |= OUTPUT_FILESYSTEMS;
        output |= OUTPUT_FILESYSTEMS_EXTRA;
      } else if (STREQ (long_options[option_index].name, "filesystems")) {
        output |= OUTPUT_FILESYSTEMS;
      } else if (STREQ (long_options[option_index].name, "logical-volumes") ||
                 STREQ (long_options[option_index].name, "logvols") ||
                 STREQ (long_options[option_index].name, "lvs")) {
        output |= OUTPUT_LVS;
      } else if (STREQ (long_options[option_index].name, "no-title")) {
        no_title = 1;
      } else if (STREQ (long_options[option_index].name, "parts") ||
                 STREQ (long_options[option_index].name, "partitions")) {
        output |= OUTPUT_PARTITIONS;
      } else if (STREQ (long_options[option_index].name, "physical-volumes") ||
                 STREQ (long_options[option_index].name, "physvols") ||
                 STREQ (long_options[option_index].name, "pvs")) {
        output |= OUTPUT_PVS;
      } else if (STREQ (long_options[option_index].name, "uuid") ||
                 STREQ (long_options[option_index].name, "uuids")) {
        uuid = 1;
      } else if (STREQ (long_options[option_index].name, "vgs") ||
                 STREQ (long_options[option_index].name, "volgroups") ||
                 STREQ (long_options[option_index].name, "volume-groups")) {
        output |= OUTPUT_VGS;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'l':
      long_mode = 1;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  /* -h and --csv doesn't make sense.  Spreadsheets will corrupt these
   * fields.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* Nothing selected for output, means --filesystems is implied. */
  if (output == 0)
    output = OUTPUT_FILESYSTEMS;

  /* What columns will be displayed? */
  columns = COLUMN_NAME;
  if (long_mode) {
    columns |= COLUMN_TYPE;
    columns |= COLUMN_SIZE;
    if ((output & OUTPUT_FILESYSTEMS)) {
      columns |= COLUMN_VFS_TYPE;
      columns |= COLUMN_VFS_LABEL;
    }
    columns |= COLUMN_PARENTS;
    if ((output & OUTPUT_PARTITIONS))
      columns |= COLUMN_MBR;
    if (uuid)
      columns |= COLUMN_UUID;
  }

  /* Display title by default only in long mode. */
  title = long_mode;
  if (no_title)
    title = 0;

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives. */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  if (title)
    do_output_title ();
  do_output ();
  do_output_end ();

  free_pvs ();

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #6
0
파일: scan.c 프로젝트: msmhrt/libguestfs
int
main (int argc, char *argv[])
{
  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:qvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "quiet", 0, 0, 'q' },
    { "uuid", 0, 0, 0, },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
  int uuid = 0;
  /* This just needs to be larger than any alignment we care about. */
  size_t worst_alignment = UINT_MAX;
  int exit_code;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  argv[0] = bad_cast (program_name);

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "uuid")) {
        uuid = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'q':
      quiet = 1;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  /* The user didn't specify any drives to scan. */
  if (drvs == NULL) {
#if defined(HAVE_LIBVIRT) && defined(HAVE_LIBXML2)
    get_domains_from_libvirt (uuid, &worst_alignment);
#else
    fprintf (stderr, _("%s: compiled without support for libvirt and/or libxml2.\n"),
             program_name);
    exit (EXIT_FAILURE);
#endif
  } else {
    if (uuid) {
      fprintf (stderr, _("%s: --uuid option cannot be used with -a or -d\n"),
               program_name);
      exit (EXIT_FAILURE);
    }

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    /* Free up data structures, no longer needed after this point. */
    free_drives (drvs);

    /* Perform the scan. */
    scan (&worst_alignment, NULL);

    guestfs_close (g);
  }

  /* Decide on an appropriate exit code. */
  if (worst_alignment < 10) /* 2^10 = 4096 */
    exit_code = 3;
  else if (worst_alignment < 16) /* 2^16 = 65536 */
    exit_code = 2;
  else
    exit_code = 0;

  exit (exit_code);
}
예제 #7
0
파일: main.c 프로젝트: skalkoto/libguestfs
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hiP:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "csv", 0, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "inodes", 0, 0, 'i' },
    { "long-options", 0, 0, 0 },
    { "one-per-guest", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "uuid", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;
  size_t max_threads = 0;
  int err;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "one-per-guest")) {
        /* nothing - left for backwards compatibility */
      } else if (STREQ (long_options[option_index].name, "uuid")) {
        uuid = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'i':
      inodes = 1;
      break;

    case 'P':
      if (sscanf (optarg, "%zu", &max_threads) != 1) {
        fprintf (stderr, _("%s: -P option is not numeric\n"), program_name);
        exit (EXIT_FAILURE);
      }
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-df which is how we detect this.
   */
  if (drvs == NULL) {
    while (optind < argc) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* -h and --csv doesn't make sense.  Spreadsheets will corrupt these
   * fields.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* virt-df has two modes.  If the user didn't specify any drives,
   * then we do the df on every libvirt guest.  That's the if-clause
   * below.  If the user specified domains/drives, then we assume they
   * belong to a single guest.  That's the else-clause below.
   */
  if (drvs == NULL) {
#if defined(HAVE_LIBVIRT)
    get_all_libvirt_domains (libvirt_uri);
    print_title ();
    err = start_threads (max_threads, g, df_work);
    free_domains ();
#else
    fprintf (stderr, _("%s: compiled without support for libvirt.\n"),
             program_name);
    exit (EXIT_FAILURE);
#endif
  }
  else {                        /* Single guest. */
    CLEANUP_FREE char *name = NULL;

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    print_title ();

    /* Synthesize a display name. */
    name = make_display_name (drvs);

    /* XXX regression: in the Perl version we cached the UUID from the
     * libvirt domain handle so it was available to us here.  In this
     * version the libvirt domain handle is hidden inside
     * guestfs_add_domain so the UUID is not available easily for
     * single '-d' command-line options.
     */
    err = df_on_handle (g, name, NULL, stdout);

    /* Free up data structures, no longer needed after this point. */
    free_drives (drvs);
  }

  guestfs_close (g);

  exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #8
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  /* We use random(3) below. */
  srandom (time (NULL));

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:b:c:d:e:m:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "backup", 1, 0, 'b' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "edit", 1, 0, 'e' },
    { "expr", 1, 0, 'e' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "mount", 1, 0, 'm' },
    { "short-options", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  struct mp *mps = NULL;
  struct mp *mp;
  char *p;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 guestfs_int_program_name,
                 long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'b':
      if (backup_extension) {
        fprintf (stderr, _("%s: -b option given multiple times\n"),
                 guestfs_int_program_name);
        exit (EXIT_FAILURE);
      }
      backup_extension = optarg;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'e':
      if (perl_expr) {
        fprintf (stderr, _("%s: -e option given multiple times\n"),
                 guestfs_int_program_name);
        exit (EXIT_FAILURE);
      }
      perl_expr = optarg;
      break;

    case 'm':
      OPTION_m;
      inspector = 0;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-edit which is how we detect this.
   */
  if (drvs == NULL) {
    /* argc - 1 because last parameter is the single filename. */
    while (optind < argc - 1) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 0);
  assert (inspector == 1 || mps != NULL);
  assert (live == 0);

  /* User must specify at least one filename on the command line. */
  if (optind >= argc || argc - optind < 1)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives. */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  if (mps != NULL)
    mount_mps (mps);
  else
    inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);
  free_mps (mps);

  edit_files (argc - optind, &argv[optind]);

  /* Cleanly unmount the disks after editing. */
  if (guestfs_shutdown (g) == -1)
    exit (EXIT_FAILURE);

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #9
0
int
main (int argc, char *argv[])
{
  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hivVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "csv", 0, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "inodes", 0, 0, 'i' },
    { "one-per-guest", 0, 0, 0 },
    { "uuid", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  argv[0] = bad_cast (program_name);

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "one-per-guest")) {
        one_per_guest = 1;
      } else if (STREQ (long_options[option_index].name, "uuid")) {
        uuid = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'i':
      inodes = 1;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-df which is how we detect this.
   */
  if (drvs == NULL) {
    while (optind < argc) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = malloc (sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = argv[optind];
        drv->a.format = NULL;
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = malloc (sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  /* -h and --csv doesn't make sense.  Spreadsheets will corrupt these
   * fields.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* If the user didn't specify any drives, then we ask libvirt for
   * the full list of guests and drives, which we add in batches.
   */
  if (drvs == NULL) {
#ifdef HAVE_LIBVIRT
    get_domains_from_libvirt ();
#else
    fprintf (stderr, _("%s: compiled without support for libvirt.\n"),
             program_name);
    exit (EXIT_FAILURE);
#endif
  }
  else {
    const char *name;

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    print_title ();

    /* Synthesize a display name. */
    switch (drvs->type) {
    case drv_a:
      name = strrchr (drvs->a.filename, '/');
      if (name == NULL)
        name = drvs->a.filename;
      else
        name++; /* skip '/' character */
      break;
    case drv_d:
      name = drvs->d.guest;
      break;
    case drv_N:
    default:
      abort ();
    }

    /* XXX regression: in the Perl version we cached the UUID from the
     * libvirt domain handle so it was available to us here.  In this
     * version the libvirt domain handle is hidden inside
     * guestfs_add_domain so the UUID is not available easily for
     * single '-d' command-line options.
     */
    (void) df_on_handle (name, NULL, NULL, 0);

    /* Free up data structures, no longer needed after this point. */
    free_drives (drvs);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #10
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  parse_config ();

  enum { HELP_OPTION = CHAR_MAX + 1 };

  /* The command line arguments are broadly compatible with (a subset
   * of) guestfish.  Thus we have to deal mainly with -a, -m and --ro.
   */
  static const char options[] = "a:c:d:im:no:rvVwx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "dir-cache-timeout", 1, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "fd", 1, 0, 0 },
    { "format", 2, 0, 0 },
    { "fuse-help", 0, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "inspector", 0, 0, 'i' },
    { "keys-from-stdin", 0, 0, 0 },
    { "live", 0, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "mount", 1, 0, 'm' },
    { "no-fork", 0, 0, 0 },
    { "no-sync", 0, 0, 'n' },
    { "option", 1, 0, 'o' },
    { "pid-file", 1, 0, 0 },
    { "ro", 0, 0, 'r' },
    { "rw", 0, 0, 'w' },
    { "selinux", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "trace", 0, 0, 'x' },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };

  struct drv *drvs = NULL;
  struct mp *mps = NULL;
  struct mp *mp;
  char *p;
  const char *format = NULL;
  bool format_consumed = true;
  int c, r;
  int option_index;
  struct sigaction sa;

  int debug_calls = 0;
  int dir_cache_timeout = -1;
  int do_fork = 1;
  char *fuse_options = NULL;
  char *pid_file = NULL;
  int pipe_fd = -1;

  struct guestfs_mount_local_argv optargs;

  /* LC_ALL=C is required so we can parse error messages. */
  setenv ("LC_ALL", "C", 1);

  memset (&sa, 0, sizeof sa);
  sa.sa_handler = SIG_IGN;
  sa.sa_flags = SA_RESTART;
  sigaction (SIGPIPE, &sa, NULL);

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, errno, "guestfs_create");

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "dir-cache-timeout"))
        dir_cache_timeout = atoi (optarg);
      else if (STREQ (long_options[option_index].name, "fuse-help"))
        fuse_help ();
      else if (STREQ (long_options[option_index].name, "selinux")) {
        /* nothing */
      } else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "live")) {
        live = 1;
      } else if (STREQ (long_options[option_index].name, "pid-file")) {
        pid_file = optarg;
      } else if (STREQ (long_options[option_index].name, "no-fork")) {
        do_fork = 0;
      } else if (STREQ (long_options[option_index].name, "fd")) {
        if (sscanf (optarg, "%d", &pipe_fd) != 1 || pipe_fd < 0)
          error (EXIT_FAILURE, 0,
                 _("unable to parse --fd option value: %s"), optarg);
      } else
        error (EXIT_FAILURE, 0,
               _("unknown long option: %s (%d)"),
               long_options[option_index].name, option_index);
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'i':
      OPTION_i;
      break;

    case 'm':
      OPTION_m;
      break;

    case 'n':
      OPTION_n;
      break;

    case 'o':
      fuse_opt_add_opt_escaped (&fuse_options, optarg);
      break;

    case 'r':
      OPTION_r;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'w':
      OPTION_w;
      break;

    case 'x':
      OPTION_x;
      debug_calls = 1;
      do_fork = 0;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  CHECK_OPTION_format_consumed;

  /* Check we have the right options. */
  if (!live) {
    if (drvs == NULL) {
      fprintf (stderr, _("%s: error: you must specify at least one -a or -d option.\n"),
               getprogname ());
      usage (EXIT_FAILURE);
    }
    if (!(mps || inspector)) {
      fprintf (stderr, _("%s: error: you must specify either -i at least one -m option.\n"),
               getprogname ());
      usage (EXIT_FAILURE);
    }
  } else {
    size_t count_d = 0, count_other = 0;
    struct drv *drv;

    if (read_only)
      error (EXIT_FAILURE, 0, _("--live is not compatible with --ro option"));

    if (inspector)
      error (EXIT_FAILURE, 0, _("--live is not compatible with -i option"));

    /* --live: make sure there was one -d option and no -a options */
    for (drv = drvs; drv; drv = drv->next) {
      if (drv->type == drv_d)
        count_d++;
      else
        count_other++;
    }

    if (count_d != 1)
      error (EXIT_FAILURE, 0,
             _("with --live, you must use exactly one -d option"));

    if (count_other != 0)
      error (EXIT_FAILURE, 0, _("--live is not compatible with -a option"));
  }

  /* We'd better have a mountpoint. */
  if (optind+1 != argc)
    error (EXIT_FAILURE, 0,
           _("you must specify a mountpoint in the host filesystem"));

  /* If we're forking, we can't use the recovery process. */
  if (guestfs_set_recovery_proc (g, !do_fork) == -1)
    exit (EXIT_FAILURE);

  /* Do the guest drives and mountpoints. */
  add_drives (drvs, 'a');
  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);
  if (inspector)
    inspect_mount ();
  mount_mps (mps);

  free_drives (drvs);
  free_mps (mps);

  /* FUSE example does this, not clear if it's necessary, but ... */
  if (guestfs_umask (g, 0) == -1)
    exit (EXIT_FAILURE);

  optargs.bitmask = 0;
  if (read_only) {
    optargs.bitmask |= GUESTFS_MOUNT_LOCAL_READONLY_BITMASK;
    optargs.readonly = 1;
  }
  if (debug_calls) {
    optargs.bitmask |= GUESTFS_MOUNT_LOCAL_DEBUGCALLS_BITMASK;
    optargs.debugcalls = 1;
  }
  if (dir_cache_timeout > 0) {
    optargs.bitmask |= GUESTFS_MOUNT_LOCAL_CACHETIMEOUT_BITMASK;
    optargs.cachetimeout = dir_cache_timeout;
  }
  if (fuse_options != NULL) {
    optargs.bitmask |= GUESTFS_MOUNT_LOCAL_OPTIONS_BITMASK;
    optargs.options = fuse_options;
  }

  if (guestfs_mount_local_argv (g, argv[optind], &optargs) == -1)
    exit (EXIT_FAILURE);

  /* Daemonize. */
  if (do_fork) {
    pid_t pid;
    int fd;

    pid = fork ();
    if (pid == -1)
      error (EXIT_FAILURE, errno, "fork");

    if (pid != 0) {             /* parent */
      if (write_pid_file (pid_file, pid) == -1)
        _exit (EXIT_FAILURE);
      if (write_pipe_fd (pipe_fd) == -1)
        _exit (EXIT_FAILURE);

      _exit (EXIT_SUCCESS);
    }

    /* Emulate what old fuse_daemonize used to do. */
    if (setsid () == -1)
      error (EXIT_FAILURE, errno, "setsid");

    ignore_value (chdir ("/"));

    fd = open ("/dev/null", O_RDWR);
    if (fd >= 0) {
      dup2 (fd, 0);
      dup2 (fd, 1);
      dup2 (fd, 2);
      if (fd > 2)
        close (fd);
    }
  }
  else {
    /* not forking, write PID file and pipe FD anyway */
    if (write_pid_file (pid_file, getpid ()) == -1)
      exit (EXIT_FAILURE);
    if (write_pipe_fd (pipe_fd) == -1)
      exit (EXIT_FAILURE);
  }

  /* At the last minute, remove the libguestfs error handler.  In code
   * above this point, the default error handler has been used which
   * sends all errors to stderr.  From now on, the FUSE code will
   * convert errors into error codes (errnos) when appropriate.
   */
  guestfs_push_error_handler (g, NULL, NULL);

  /* Main loop. */
  r = guestfs_mount_local_run (g);

  guestfs_pop_error_handler (g);

  /* Cleanup. */
  if (guestfs_shutdown (g) == -1)
    r = -1;
  guestfs_close (g);

  /* Don't delete PID file until the cleanup has been completed. */
  if (pid_file)
    unlink (pid_file);

  exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #11
0
파일: diff.c 프로젝트: kelledge/libguestfs
int
main (int argc, char *argv[])
{
    /* Current time for --time-days, --time-relative output. */
    time (&now);

    setlocale (LC_ALL, "");
    bindtextdomain (PACKAGE, LOCALEBASEDIR);
    textdomain (PACKAGE);

    enum { HELP_OPTION = CHAR_MAX + 1 };

    static const char *options = "a:A:c:d:D:hvVx";
    static const struct option long_options[] = {
        { "add", 1, 0, 'a' },
        { "all", 0, 0, 0 },
        { "atime", 0, 0, 0 },
        { "checksum", 2, 0, 0 },
        { "checksums", 2, 0, 0 },
        { "csv", 0, 0, 0 },
        { "connect", 1, 0, 'c' },
        { "dir-link", 0, 0, 0 },
        { "dir-links", 0, 0, 0 },
        { "dir-nlink", 0, 0, 0 },
        { "dir-nlinks", 0, 0, 0 },
        { "dir-time", 0, 0, 0 },
        { "dir-times", 0, 0, 0 },
        { "domain", 1, 0, 'd' },
        { "echo-keys", 0, 0, 0 },
        { "extra-stat", 0, 0, 0 },
        { "extra-stats", 0, 0, 0 },
        { "format", 2, 0, 0 },
        { "help", 0, 0, HELP_OPTION },
        { "human-readable", 0, 0, 'h' },
        { "keys-from-stdin", 0, 0, 0 },
        { "short-options", 0, 0, 0 },
        { "time", 0, 0, 0 },
        { "times", 0, 0, 0 },
        { "time-days", 0, 0, 0 },
        { "time-relative", 0, 0, 0 },
        { "time-t", 0, 0, 0 },
        { "uid", 0, 0, 0 },
        { "uids", 0, 0, 0 },
        { "verbose", 0, 0, 'v' },
        { "version", 0, 0, 'V' },
        { "xattr", 0, 0, 0 },
        { "xattrs", 0, 0, 0 },
        { 0, 0, 0, 0 }
    };
    struct drv *drvs = NULL;      /* First guest. */
    struct drv *drvs2 = NULL;     /* Second guest. */
    const char *format = NULL;
    bool format_consumed = true;
    int c;
    int option_index;
    struct tree *tree1, *tree2;

    g = guestfs_create ();
    if (g == NULL) {
        fprintf (stderr, _("guestfs_create: failed to create handle\n"));
        exit (EXIT_FAILURE);
    }

    g2 = guestfs_create ();
    if (g2 == NULL) {
        fprintf (stderr, _("guestfs_create: failed to create handle\n"));
        exit (EXIT_FAILURE);
    }

    for (;;) {
        c = getopt_long (argc, argv, options, long_options, &option_index);
        if (c == -1) break;

        switch (c) {
        case 0:			/* options which are long only */
            if (STREQ (long_options[option_index].name, "long-options"))
                display_long_options (long_options);
            else if (STREQ (long_options[option_index].name, "short-options"))
                display_short_options (options);
            else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
                keys_from_stdin = 1;
            } else if (STREQ (long_options[option_index].name, "echo-keys")) {
                echo_keys = 1;
            } else if (STREQ (long_options[option_index].name, "format")) {
                OPTION_format;
            } else if (STREQ (long_options[option_index].name, "all")) {
                enable_extra_stats = enable_times = enable_uids = enable_xattrs = 1;
            } else if (STREQ (long_options[option_index].name, "atime")) {
                atime = 1;
            } else if (STREQ (long_options[option_index].name, "csv")) {
                csv = 1;
            } else if (STREQ (long_options[option_index].name, "checksum") ||
                       STREQ (long_options[option_index].name, "checksums")) {
                if (!optarg || STREQ (optarg, ""))
                    checksum = "md5";
                else
                    checksum = optarg;
            } else if (STREQ (long_options[option_index].name, "dir-link") ||
                       STREQ (long_options[option_index].name, "dir-links") ||
                       STREQ (long_options[option_index].name, "dir-nlink") ||
                       STREQ (long_options[option_index].name, "dir-nlinks")) {
                dir_links = 1;
            } else if (STREQ (long_options[option_index].name, "dir-time") ||
                       STREQ (long_options[option_index].name, "dir-times")) {
                dir_times = 1;
            } else if (STREQ (long_options[option_index].name, "extra-stat") ||
                       STREQ (long_options[option_index].name, "extra-stats")) {
                enable_extra_stats = 1;
            } else if (STREQ (long_options[option_index].name, "time") ||
                       STREQ (long_options[option_index].name, "times")) {
                enable_times = 1;
            } else if (STREQ (long_options[option_index].name, "time-t")) {
                enable_times = 1;
                time_t_output = 1;
            } else if (STREQ (long_options[option_index].name, "time-relative")) {
                enable_times = 1;
                time_t_output = 1;
                time_relative = 1;
            } else if (STREQ (long_options[option_index].name, "time-days")) {
                enable_times = 1;
                time_t_output = 1;
                time_relative = 2;
            } else if (STREQ (long_options[option_index].name, "uid") ||
                       STREQ (long_options[option_index].name, "uids")) {
                enable_uids = 1;
            } else if (STREQ (long_options[option_index].name, "xattr") ||
                       STREQ (long_options[option_index].name, "xattrs")) {
                enable_xattrs = 1;
            } else {
                fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                         guestfs_int_program_name, long_options[option_index].name, option_index);
                exit (EXIT_FAILURE);
            }
            break;

        case 'a':
            OPTION_a;
            break;

        case 'A':
            OPTION_A;
            break;

        case 'c':
            OPTION_c;
            break;

        case 'd':
            OPTION_d;
            break;

        case 'D':
            OPTION_D;
            break;

        case 'h':
            human = 1;
            break;

        case 'v':
            /* OPTION_v; */
            verbose++;
            guestfs_set_verbose (g, verbose);
            guestfs_set_verbose (g2, verbose);
            break;

        case 'V':
            OPTION_V;
            break;

        case 'x':
            /* OPTION_x; */
            guestfs_set_trace (g, 1);
            guestfs_set_trace (g2, 1);
            break;

        case HELP_OPTION:
            usage (EXIT_SUCCESS);

        default:
            usage (EXIT_FAILURE);
        }
    }

    if (drvs == NULL || drvs2 == NULL) {
        fprintf (stderr,
                 _("%s: you must specify some -a|-A|-d|-D options, see %s(1)\n"),
                 guestfs_int_program_name, guestfs_int_program_name);
        usage (EXIT_FAILURE);
    }

    /* CSV && human is unsafe because spreadsheets fail to parse these
     * fields correctly.  (RHBZ#600977).
     */
    if (human && csv) {
        fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
                 guestfs_int_program_name);
        exit (EXIT_FAILURE);
    }

    if (optind != argc) {
        fprintf (stderr, _("%s: extra arguments on the command line\n"),
                 guestfs_int_program_name);
        usage (EXIT_FAILURE);
    }

    /* These are really constants, but they have to be variables for the
     * options parsing code.  Assert here that they have known-good
     * values.
     */
    assert (read_only == 1);
    assert (inspector == 1);
    assert (live == 0);

    CHECK_OPTION_format_consumed;

    unsigned errors = 0;

    /* Mount up first guest. */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
        exit (EXIT_FAILURE);

    inspect_mount ();

    if ((tree1 = visit_guest (g)) == NULL)
        errors++;

    /* Mount up second guest. */
    add_drives_handle (g2, drvs2, 'a');

    if (guestfs_launch (g2) == -1)
        exit (EXIT_FAILURE);

    inspect_mount_handle (g2);

    if ((tree2 = visit_guest (g2)) == NULL)
        errors++;

    if (errors == 0) {
        if (diff_guests (tree1, tree2) == -1)
            errors++;
    }

    free_tree (tree1);
    free_tree (tree2);

    free_drives (drvs);
    free_drives (drvs2);

    guestfs_close (g);
    guestfs_close (g2);

    exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #12
0
int
main (int argc, char *argv[])
{
  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:qvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "filesystem", 1, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "lvm", 2, 0, 0 },
    { "partition", 2, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { "wipe", 0, 0, 0 },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
  int retry, retries;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  argv[0] = bad_cast (program_name);

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "filesystem")) {
        if (STREQ (optarg, "none"))
          filesystem = NULL;
        else if (optarg[0] == '-') { /* eg: --filesystem --lvm */
          fprintf (stderr, _("%s: no filesystem was specified\n"),
                   program_name);
          exit (EXIT_FAILURE);
        } else
          filesystem = optarg;
      } else if (STREQ (long_options[option_index].name, "lvm")) {
        if (vg || lv) {
          fprintf (stderr,
                   _("%s: --lvm option cannot be given multiple times\n"),
                   program_name);
          exit (EXIT_FAILURE);
        }
        if (optarg == NULL) {
          vg = strdup ("VG");
          lv = strdup ("LV");
          if (!vg || !lv) { perror ("strdup"); exit (EXIT_FAILURE); }
        }
        else if (STREQ (optarg, "none"))
          vg = lv = NULL;
        else
          parse_vg_lv (optarg);
      } else if (STREQ (long_options[option_index].name, "partition")) {
        if (optarg == NULL)
          partition = "DEFAULT";
        else if (STREQ (optarg, "none"))
          partition = NULL;
        else
          partition = optarg;
      } else if (STREQ (long_options[option_index].name, "wipe")) {
        wipe = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 0);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  /* The user didn't specify any drives to format. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Because the libguestfs kernel can get stuck rereading the
   * partition table after things have been erased, we sometimes need
   * to completely restart the guest.  Hence this complex retry logic.
   */
  for (retries = 0; retries <= 1; ++retries) {
    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    /* Test if the wipefs API is available. */
    have_wipefs = feature_available (g, "wipefs");

    /* Perform the format. */
    retry = do_format ();
    if (!retry)
      break;

    if (retries == 0) {
      /* We're going to silently retry, after reopening the connection. */
      guestfs_h *g2;

      g2 = guestfs_create ();
      guestfs_set_verbose (g2, guestfs_get_verbose (g));
      guestfs_set_trace (g2, guestfs_get_trace (g));

      if (guestfs_shutdown (g) == -1)
        exit (EXIT_FAILURE);
      guestfs_close (g);
      g = g2;
    }
    else {
      /* Failed. */
      fprintf (stderr,
               _("%s: failed to rescan the disks after two attempts.  This\n"
                 "may mean there is some sort of partition table or disk\n"
                 "data which we are unable to remove.  If you think this\n"
                 "is a bug, please file a bug at http://libguestfs.org/\n"),
               program_name);
      exit (EXIT_FAILURE);
    }
  }

  /* Free up data structures. */
  free_drives (drvs);

  if (guestfs_shutdown (g) == -1)
    exit (EXIT_FAILURE);
  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #13
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  parse_config ();

  enum { HELP_OPTION = CHAR_MAX + 1 };

  /* The command line arguments are broadly compatible with (a subset
   * of) guestfish.  Thus we have to deal mainly with -a, -m and --ro.
   */
  static const char *options = "a:c:d:im:no:rv?Vwx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "dir-cache-timeout", 1, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "fuse-help", 0, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "inspector", 0, 0, 'i' },
    { "keys-from-stdin", 0, 0, 0 },
    { "live", 0, 0, 0 },
    { "mount", 1, 0, 'm' },
    { "no-sync", 0, 0, 'n' },
    { "option", 1, 0, 'o' },
    { "ro", 0, 0, 'r' },
    { "rw", 0, 0, 'w' },
    { "selinux", 0, 0, 0 },
    { "trace", 0, 0, 'x' },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };

  struct drv *drvs = NULL;
  struct drv *drv;
  struct mp *mps = NULL;
  struct mp *mp;
  char *p;
  const char *format = NULL;
  int c, r;
  int option_index;
  struct sigaction sa;

  int fuse_argc = 0;
  const char **fuse_argv = NULL;

#define ADD_FUSE_ARG(str)                                               \
  do {                                                                  \
    fuse_argc ++;                                                       \
    fuse_argv = realloc (fuse_argv, (1+fuse_argc) * sizeof (char *));   \
    if (!fuse_argv) {                                                   \
      perror ("realloc");                                               \
      exit (EXIT_FAILURE);                                                         \
    }                                                                   \
    fuse_argv[fuse_argc-1] = (str);                                     \
    fuse_argv[fuse_argc] = NULL;                                        \
  } while (0)

  /* LC_ALL=C is required so we can parse error messages. */
  setenv ("LC_ALL", "C", 1);

  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  memset (&sa, 0, sizeof sa);
  sa.sa_handler = SIG_IGN;
  sa.sa_flags = SA_RESTART;
  sigaction (SIGPIPE, &sa, NULL);

  /* Various initialization. */
  init_dir_caches ();

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  guestfs_set_recovery_proc (g, 0);

  ADD_FUSE_ARG (program_name);
  /* MUST be single-threaded.  You cannot have two threads accessing the
   * same libguestfs handle, and opening more than one handle is likely
   * to be very expensive.
   */
  ADD_FUSE_ARG ("-s");

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "dir-cache-timeout"))
        dir_cache_timeout = atoi (optarg);
      else if (STREQ (long_options[option_index].name, "fuse-help"))
        fuse_help ();
      else if (STREQ (long_options[option_index].name, "selinux"))
        guestfs_set_selinux (g, 1);
      else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "live")) {
        live = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'i':
      OPTION_i;
      break;

    case 'm':
      OPTION_m;
      break;

    case 'n':
      OPTION_n;
      break;

    case 'o':
      ADD_FUSE_ARG ("-o");
      ADD_FUSE_ARG (optarg);
      break;

    case 'r':
      OPTION_r;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'w':
      OPTION_w;
      break;

    case 'x':
      OPTION_x;
      ADD_FUSE_ARG ("-f");
      guestfs_set_recovery_proc (g, 1);
      trace_calls = 1;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Check we have the right options. */
  if (!live) {
    if (!drvs || !(mps || inspector)) {
      fprintf (stderr,
               _("%s: must have at least one -a/-d and at least one -m/-i option\n"),
               program_name);
      exit (EXIT_FAILURE);
    }
  } else {
    size_t count_d = 0, count_other = 0;
    struct drv *drv;

    if (read_only) {
      fprintf (stderr,
               _("%s: --live is not compatible with --ro option\n"),
               program_name);
      exit (EXIT_FAILURE);
    }

    if (inspector) {
      fprintf (stderr,
               _("%s: --live is not compatible with -i option\n"),
               program_name);
      exit (EXIT_FAILURE);
    }

    /* --live: make sure there was one -d option and no -a options */
    for (drv = drvs; drv; drv = drv->next) {
      if (drv->type == drv_d)
        count_d++;
      else
        count_other++;
    }

    if (count_d != 1) {
      fprintf (stderr,
               _("%s: with --live, you must use exactly one -d option\n"),
               program_name);
      exit (EXIT_FAILURE);
    }

    if (count_other != 0) {
      fprintf (stderr,
               _("%s: --live is not compatible with -a option\n"),
               program_name);
      exit (EXIT_FAILURE);
    }
  }

  /* We'd better have a mountpoint. */
  if (optind+1 != argc) {
    fprintf (stderr,
             _("%s: you must specify a mountpoint in the host filesystem\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* Do the guest drives and mountpoints. */
  add_drives (drvs, 'a');
  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);
  if (inspector)
    inspect_mount ();
  mount_mps (mps);

  free_drives (drvs);
  free_mps (mps);

  /* FUSE example does this, not clear if it's necessary, but ... */
  if (guestfs_umask (g, 0) == -1)
    exit (EXIT_FAILURE);

  /* At the last minute, remove the libguestfs error handler.  In code
   * above this point, the default error handler has been used which
   * sends all errors to stderr.  Now before entering FUSE itself we
   * want to silence errors so we can convert them (see error()
   * function above).
   */
  guestfs_set_error_handler (g, NULL, NULL);

  /* Finish off FUSE args. */
  ADD_FUSE_ARG (argv[optind]);

  /*
    It says about the line containing the for-statement:
    error: assuming signed overflow does not occur when simplifying conditional to constant [-Wstrict-overflow]

  if (verbose) {
    fprintf (stderr, "guestmount: invoking FUSE with args [");
    for (i = 0; i < fuse_argc; ++i) {
      if (i > 0) fprintf (stderr, ", ");
      fprintf (stderr, "%s", fuse_argv[i]);
    }
    fprintf (stderr, "]\n");
  }
  */

  r = fuse_main (fuse_argc, (char **) fuse_argv, &fg_operations, NULL);

  /* Cleanup. */
  guestfs_close (g);
  free_dir_caches ();

  exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #14
0
파일: scan.c 프로젝트: Thecca/libguestfs
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:P:qvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "long-options", 0, 0, 0 },
    { "quiet", 0, 0, 'q' },
    { "uuid", 0, 0, 0, },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;
  int exit_code;
  size_t max_threads = 0;
  int r;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "uuid")) {
        uuid = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'P':
      if (sscanf (optarg, "%zu", &max_threads) != 1) {
        fprintf (stderr, _("%s: -P option is not numeric\n"), program_name);
        exit (EXIT_FAILURE);
      }
      break;

    case 'q':
      quiet = 1;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* virt-alignment-scan has two modes.  If the user didn't specify
   * any drives, then we do the scan on every libvirt guest.  That's
   * the if-clause below.  If the user specified domains/drives, then
   * we assume they belong to a single guest.  That's the else-clause
   * below.
   */
  if (drvs == NULL) {
#if defined(HAVE_LIBVIRT)
    get_all_libvirt_domains (libvirt_uri);
    r = start_threads (max_threads, g, scan_work);
    free_domains ();
    if (r == -1)
      exit (EXIT_FAILURE);
#else
    fprintf (stderr, _("%s: compiled without support for libvirt.\n"),
             program_name);
    exit (EXIT_FAILURE);
#endif
  } else {                      /* Single guest. */
    if (uuid) {
      fprintf (stderr, _("%s: --uuid option cannot be used with -a or -d\n"),
               program_name);
      exit (EXIT_FAILURE);
    }

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    /* Free up data structures, no longer needed after this point. */
    free_drives (drvs);

    /* Perform the scan. */
    r = scan (g, NULL, stdout);

    guestfs_close (g);

    if (r == -1)
      exit (EXIT_FAILURE);
  }

  /* Decide on an appropriate exit code. */
  if (worst_alignment < 10) /* 2^10 = 4096 */
    exit_code = 3;
  else if (worst_alignment < 16) /* 2^16 = 65536 */
    exit_code = 2;
  else
    exit_code = 0;

  exit (exit_code);
}
예제 #15
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { "xpath", 1, 0, 0 },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "xpath")) {
        xpath = optarg;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 guestfs_int_program_name,
                 long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-inspector which is how we detect this.
   */
  if (drvs == NULL) {
    while (optind < argc) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* XPath is modal: no drives should be specified.  There must be
   * one extra parameter on the command line.
   */
  if (xpath) {
    if (drvs != NULL) {
      fprintf (stderr, _("%s: cannot use --xpath together with other options.\n"),
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }

    do_xpath (xpath);

    exit (EXIT_SUCCESS);
  }

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  /* NB. Can't call inspect_mount () here (ie. normal processing of
   * the -i option) because it can only handle a single root.  So we
   * use low-level APIs.
   */
  inspect_do_decrypt (g);

  {
    CLEANUP_FREE_STRING_LIST char **roots = guestfs_inspect_os (g);
    if (roots == NULL) {
      fprintf (stderr, _("%s: no operating system could be detected inside this disk image.\n\nThis may be because the file is not a disk image, or is not a virtual machine\nimage, or because the OS type is not understood by libguestfs.\n\nNOTE for Red Hat Enterprise Linux 6 users: for Windows guest support you must\ninstall the separate libguestfs-winsupport package.\n\nIf you feel this is an error, please file a bug report including as much\ninformation about the disk image as possible.\n"),
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }

    output (roots);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
예제 #16
0
파일: ls.c 프로젝트: DanLipsitt/libguestfs
int
main (int argc, char *argv[])
{
  /* Current time for --time-days, --time-relative output. */
  time (&now);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hlRvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "checksum", 2, 0, 0 },
    { "checksums", 2, 0, 0 },
    { "csv", 0, 0, 0 },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "extra-stat", 0, 0, 0 },
    { "extra-stats", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "keys-from-stdin", 0, 0, 0 },
    { "long", 0, 0, 'l' },
    { "long-options", 0, 0, 0 },
    { "recursive", 0, 0, 'R' },
    { "time", 0, 0, 0 },
    { "times", 0, 0, 0 },
    { "time-days", 0, 0, 0 },
    { "time-relative", 0, 0, 0 },
    { "time-t", 0, 0, 0 },
    { "uid", 0, 0, 0 },
    { "uids", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;
#define MODE_LS_L  1
#define MODE_LS_R  2
#define MODE_LS_LR (MODE_LS_L|MODE_LS_R)
  int mode = 0;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else if (STREQ (long_options[option_index].name, "checksum") ||
                 STREQ (long_options[option_index].name, "checksums")) {
        if (!optarg || STREQ (optarg, ""))
          checksum = "md5";
        else
          checksum = optarg;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "extra-stat") ||
                 STREQ (long_options[option_index].name, "extra-stats")) {
        enable_extra_stats = 1;
      } else if (STREQ (long_options[option_index].name, "time") ||
                 STREQ (long_options[option_index].name, "times")) {
        enable_times = 1;
      } else if (STREQ (long_options[option_index].name, "time-t")) {
        enable_times = 1;
        time_t_output = 1;
      } else if (STREQ (long_options[option_index].name, "time-relative")) {
        enable_times = 1;
        time_t_output = 1;
        time_relative = 1;
      } else if (STREQ (long_options[option_index].name, "time-days")) {
        enable_times = 1;
        time_t_output = 1;
        time_relative = 2;
      } else if (STREQ (long_options[option_index].name, "uid") ||
                 STREQ (long_options[option_index].name, "uids")) {
        enable_uids = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'l':
      mode |= MODE_LS_L;
      break;

    case 'R':
      mode |= MODE_LS_R;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-ls which is how we detect this.
   */
  if (drvs == NULL) {
    /* argc - 1 because last parameter is the single directory name. */
    while (optind < argc - 1) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* Many flags only apply to -lR mode. */
  if (mode != MODE_LS_LR &&
      (csv || human || enable_uids || enable_times || enable_extra_stats ||
       checksum)) {
    fprintf (stderr, _("%s: used a flag which can only be combined with -lR mode\nFor more information, read the virt-ls(1) man page.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* CSV && human is unsafe because spreadsheets fail to parse these
   * fields correctly.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* User must specify at least one directory name on the command line. */
  if (optind >= argc || argc - optind < 1)
    usage (EXIT_FAILURE);

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  unsigned errors = 0;

  while (optind < argc) {
    const char *dir = argv[optind];

    switch (mode) {
    case 0:                     /* no -l or -R option */
      if (do_ls (dir) == -1)
        errors++;
      break;

    case MODE_LS_L:             /* virt-ls -l */
      if (do_ls_l (dir) == -1)
        errors++;
      break;

    case MODE_LS_R:             /* virt-ls -R */
      if (do_ls_R (dir) == -1)
        errors++;
      break;

    case MODE_LS_LR:            /* virt-ls -lR */
      if (do_ls_lR (dir) == -1)
        errors++;
      break;

    default:
      abort ();                 /* can't happen */
    }

    optind++;
  }

  guestfs_close (g);

  exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
예제 #17
0
int
main (int argc, char *argv[])
{
  /* Set global program name that is not polluted with libtool artifacts.  */
  set_program_name (argv[0]);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  int c;
  int option_index;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  argv[0] = bad_cast (program_name);

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        if (!optarg || STREQ (optarg, ""))
          format = NULL;
        else
          format = optarg;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-cat which is how we detect this.
   */
  if (drvs == NULL) {
    /* argc - 1 because last parameter is the single filename. */
    while (optind < argc - 1) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = argv[optind];
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* User must specify at least one filename on the command line. */
  if (optind >= argc || argc - optind < 1)
    usage (EXIT_FAILURE);

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  inspect_mount ();

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  unsigned errors = 0;
  int windows;
  char *root, **roots;

  /* Get root mountpoint.  See: fish/inspect.c:inspect_mount */
  roots = guestfs_inspect_get_roots (g);
  assert (roots);
  assert (roots[0] != NULL);
  assert (roots[1] == NULL);
  root = roots[0];
  free (roots);

  /* Windows?  Special handling is required. */
  windows = is_windows (g, root);

  for (; optind < argc; optind++) {
    char *filename_to_free = NULL;
    const char *filename = argv[optind];

    if (windows) {
      filename = filename_to_free = windows_path (g, root, filename);
      if (filename == NULL) {
        errors++;
        continue;
      }
    }

    if (guestfs_download (g, filename, "/dev/stdout") == -1)
      errors++;

    free (filename_to_free);
  }

  free (root);

  guestfs_close (g);

  exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}