Пример #1
0
static void
output (char **roots)
{
  xmlOutputBufferPtr ob = xmlOutputBufferCreateFd (1, NULL);
  if (ob == NULL) {
    fprintf (stderr,
             _("%s: xmlOutputBufferCreateFd: failed to open stdout\n"),
             guestfs_int_program_name);
    exit (EXIT_FAILURE);
  }

  /* 'ob' is freed when 'xo' is freed.. */
  CLEANUP_XMLFREETEXTWRITER xmlTextWriterPtr xo = xmlNewTextWriter (ob);
  if (xo == NULL) {
    fprintf (stderr,
             _("%s: xmlNewTextWriter: failed to create libxml2 writer\n"),
             guestfs_int_program_name);
    exit (EXIT_FAILURE);
  }

  /* Pretty-print the output. */
  XMLERROR (-1, xmlTextWriterSetIndent (xo, 1));
  XMLERROR (-1, xmlTextWriterSetIndentString (xo, BAD_CAST "  "));

  XMLERROR (-1, xmlTextWriterStartDocument (xo, NULL, NULL, NULL));
  output_roots (xo, roots);
  XMLERROR (-1, xmlTextWriterEndDocument (xo));
}
Пример #2
0
static void
output_roots (xmlTextWriterPtr xo, char **roots)
{
  size_t i;

  XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "operatingsystems"));
  for (i = 0; roots[i] != NULL; ++i)
    output_root (xo, roots[i]);
  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
Пример #3
0
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));
}
Пример #4
0
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));
}
Пример #5
0
static void
output (char **roots)
{
  xmlOutputBufferPtr ob = xmlOutputBufferCreateFd (1, NULL);
  if (ob == NULL)
    error (EXIT_FAILURE, 0,
           _("xmlOutputBufferCreateFd: failed to open stdout"));

  /* 'ob' is freed when 'xo' is freed.. */
  CLEANUP_XMLFREETEXTWRITER xmlTextWriterPtr xo = xmlNewTextWriter (ob);
  if (xo == NULL)
    error (EXIT_FAILURE, 0,
           _("xmlNewTextWriter: failed to create libxml2 writer"));

  /* Pretty-print the output. */
  XMLERROR (-1, xmlTextWriterSetIndent (xo, 1));
  XMLERROR (-1, xmlTextWriterSetIndentString (xo, BAD_CAST "  "));

  XMLERROR (-1, xmlTextWriterStartDocument (xo, NULL, NULL, NULL));
  output_roots (xo, roots);
  XMLERROR (-1, xmlTextWriterEndDocument (xo));
}
Пример #6
0
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));
}
Пример #7
0
static void
output_applications (xmlTextWriterPtr xo, char *root)
{
  size_t i;

  /* This returns an empty list if we simply couldn't determine the
   * applications, so if it returns NULL then it's a real error.
   */
  CLEANUP_FREE_APPLICATION2_LIST struct guestfs_application2_list *apps =
    guestfs_inspect_list_applications2 (g, root);
  if (apps == NULL)
    exit (EXIT_FAILURE);

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

  for (i = 0; i < apps->len; ++i) {
    XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "application"));

    assert (apps->val[i].app2_name && apps->val[i].app2_name[0]);
    XMLERROR (-1,
              xmlTextWriterWriteElement (xo, BAD_CAST "name",
                                         BAD_CAST apps->val[i].app2_name));

    if (apps->val[i].app2_display_name && apps->val[i].app2_display_name[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "display_name",
					   BAD_CAST apps->val[i].app2_display_name));

    if (apps->val[i].app2_epoch != 0) {
      char buf[32];

      snprintf (buf, sizeof buf, "%d", apps->val[i].app2_epoch);

      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "epoch", BAD_CAST buf));
    }

    if (apps->val[i].app2_version && apps->val[i].app2_version[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "version",
					   BAD_CAST apps->val[i].app2_version));
    if (apps->val[i].app2_release && apps->val[i].app2_release[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "release",
					   BAD_CAST apps->val[i].app2_release));
    if (apps->val[i].app2_arch && apps->val[i].app2_arch[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "arch",
					   BAD_CAST apps->val[i].app2_arch));
    if (apps->val[i].app2_install_path && apps->val[i].app2_install_path[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "install_path",
					   BAD_CAST apps->val[i].app2_install_path));
    if (apps->val[i].app2_publisher && apps->val[i].app2_publisher[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "publisher",
					   BAD_CAST apps->val[i].app2_publisher));
    if (apps->val[i].app2_url && apps->val[i].app2_url[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "url",
					   BAD_CAST apps->val[i].app2_url));
    if (apps->val[i].app2_source_package && apps->val[i].app2_source_package[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "source_package",
					   BAD_CAST apps->val[i].app2_source_package));
    if (apps->val[i].app2_summary && apps->val[i].app2_summary[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "summary",
					   BAD_CAST apps->val[i].app2_summary));
    if (apps->val[i].app2_description && apps->val[i].app2_description[0])
      XMLERROR (-1,
		xmlTextWriterWriteElement (xo, BAD_CAST "description",
					   BAD_CAST apps->val[i].app2_description));

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

  XMLERROR (-1, xmlTextWriterEndElement (xo));
}
Пример #8
0
static void
output_root (xmlTextWriterPtr xo, char *root)
{
  char *str;
  int i, r;
  char buf[32];
  char *canonical_root;
  size_t size;

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

  canonical_root = guestfs_canonical_device_name (g, root);
  if (canonical_root == NULL)
    exit (EXIT_FAILURE);
  XMLERROR (-1,
	    xmlTextWriterWriteElement (xo, BAD_CAST "root", BAD_CAST canonical_root));
  free (canonical_root);

  str = guestfs_inspect_get_type (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "name", BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_arch (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "arch", BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_distro (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "distro", BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_product_name (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "product_name", BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_product_variant (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "product_variant", BAD_CAST str));
  free (str);

  i = guestfs_inspect_get_major_version (g, root);
  snprintf (buf, sizeof buf, "%d", i);
  XMLERROR (-1,
	    xmlTextWriterWriteElement (xo, BAD_CAST "major_version", BAD_CAST buf));
  i = guestfs_inspect_get_minor_version (g, root);
  snprintf (buf, sizeof buf, "%d", i);
  XMLERROR (-1,
	    xmlTextWriterWriteElement (xo, BAD_CAST "minor_version", BAD_CAST buf));

  str = guestfs_inspect_get_package_format (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "package_format", BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_package_management (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "package_management",
					 BAD_CAST str));
  free (str);

  /* inspect-get-windows-systemroot will fail with non-windows guests,
   * or if the systemroot could not be determined for a windows guest.
   * Disable error output around this call.
   */
  guestfs_push_error_handler (g, NULL, NULL);
  str = guestfs_inspect_get_windows_systemroot (g, root);
  if (str)
    XMLERROR (-1,
              xmlTextWriterWriteElement (xo, BAD_CAST "windows_systemroot",
                                         BAD_CAST str));
  free (str);
  str = guestfs_inspect_get_windows_current_control_set (g, root);
  if (str)
    XMLERROR (-1,
              xmlTextWriterWriteElement (xo, BAD_CAST "windows_current_control_set",
                                         BAD_CAST str));
  free (str);
  guestfs_pop_error_handler (g);

  str = guestfs_inspect_get_hostname (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "hostname",
					 BAD_CAST str));
  free (str);

  str = guestfs_inspect_get_format (g, root);
  if (!str) exit (EXIT_FAILURE);
  if (STRNEQ (str, "unknown"))
    XMLERROR (-1,
	      xmlTextWriterWriteElement (xo, BAD_CAST "format",
					 BAD_CAST str));
  free (str);

  r = guestfs_inspect_is_live (g, root);
  if (r > 0) {
    XMLERROR (-1,
              xmlTextWriterStartElement (xo, BAD_CAST "live"));
    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  r = guestfs_inspect_is_netinst (g, root);
  if (r > 0) {
    XMLERROR (-1,
              xmlTextWriterStartElement (xo, BAD_CAST "netinst"));
    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  r = guestfs_inspect_is_multipart (g, root);
  if (r > 0) {
    XMLERROR (-1,
              xmlTextWriterStartElement (xo, BAD_CAST "multipart"));
    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }

  output_mountpoints (xo, root);

  output_filesystems (xo, root);

  output_drive_mappings (xo, root);

  /* We need to mount everything up in order to read out the list of
   * applications and the icon, ie. everything below this point.
   */
  inspect_mount_root (g, root);

  output_applications (xo, root);

  /* Don't return favicon.  RHEL 7 and Fedora have crappy 16x16
   * favicons in the base distro.
   */
  str = guestfs_inspect_get_icon (g, root, &size,
                                  GUESTFS_INSPECT_GET_ICON_FAVICON, 0,
                                  -1);
  if (!str) exit (EXIT_FAILURE);
  if (size > 0) {
    XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "icon"));
    XMLERROR (-1, xmlTextWriterWriteBase64 (xo, str, 0, size));
    XMLERROR (-1, xmlTextWriterEndElement (xo));
  }
  /* Note we must free (str) even if size == 0, because that indicates
   * there was no icon.
   */
  free (str);

  /* Unmount (see inspect_mount_root above). */
  if (guestfs_umount_all (g) == -1)
    exit (EXIT_FAILURE);

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