[Libguestfs] [PATCH 1/3] lib: Add inspect_list_applications2 method (RHBZ#859949)

John Eckersberg jeckersb at redhat.com
Thu Nov 1 17:35:15 UTC 2012


---
 generator/actions.ml                     | 120 ++++++++++++++++++++++++++++
 generator/structs.ml                     |  24 ++++++
 gobject/Makefile.inc                     |   2 +
 java/Makefile.inc                        |   1 +
 java/com/redhat/et/libguestfs/.gitignore |   1 +
 po/POTFILES                              |   1 +
 src/inspect-apps.c                       | 132 +++++++++++++++++++++----------
 7 files changed, 238 insertions(+), 43 deletions(-)

diff --git a/generator/actions.ml b/generator/actions.ml
index 71aee37..779c138 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -1521,6 +1521,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
   { defaults with
     name = "inspect_list_applications";
     style = RStructList ("applications", "application"), [Device "root"], [];
+    deprecated_by = Some "inspect_list_applications2";
     shortdesc = "get list of applications installed in the operating system";
     longdesc = "\
 Return the list of applications installed in the operating system.
@@ -1616,6 +1617,125 @@ If unavailable this is returned as an empty string C<\"\">.
 Please read L<guestfs(3)/INSPECTION> for more details." };
 
   { defaults with
+    name = "inspect_list_applications2";
+    style = RStructList ("applications2", "application2"), [Device "root"], [];
+    shortdesc = "get list of applications installed in the operating system";
+    longdesc = "\
+Return the list of applications installed in the operating system.
+
+I<Note:> This call works differently from other parts of the
+inspection API.  You have to call C<guestfs_inspect_os>, then
+C<guestfs_inspect_get_mountpoints>, then mount up the disks,
+before calling this.  Listing applications is a significantly
+more difficult operation which requires access to the full
+filesystem.  Also note that unlike the other
+C<guestfs_inspect_get_*> calls which are just returning
+data cached in the libguestfs handle, this call actually reads
+parts of the mounted filesystems during the call.
+
+This returns an empty list if the inspection code was not able
+to determine the list of applications.
+
+The application structure contains the following fields:
+
+=over 4
+
+=item C<app2_name>
+
+The name of the application.  For Red Hat-derived and Debian-derived
+Linux guests, this is the package name.
+
+=item C<app2_display_name>
+
+The display name of the application, sometimes localized to the
+install language of the guest operating system.
+
+If unavailable this is returned as an empty string C<\"\">.
+Callers needing to display something can use C<app2_name> instead.
+
+=item C<app2_epoch>
+
+For package managers which use epochs, this contains the epoch of
+the package (an integer).  If unavailable, this is returned as C<0>.
+
+=item C<app2_version>
+
+The version string of the application or package.  If unavailable
+this is returned as an empty string C<\"\">.
+
+=item C<app2_release>
+
+The release string of the application or package, for package
+managers that use this.  If unavailable this is returned as an
+empty string C<\"\">.
+
+=item C<app2_arch>
+
+The architecture string of the application or package, for package
+managers that use this.  If unavailable this is returned as an empty
+string C<\"\">.
+
+=item C<app2_install_path>
+
+The installation path of the application (on operating systems
+such as Windows which use installation paths).  This path is
+in the format used by the guest operating system, it is not
+a libguestfs path.
+
+If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_trans_path>
+
+The install path translated into a libguestfs path.
+If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_publisher>
+
+The name of the publisher of the application, for package
+managers that use this.  If unavailable this is returned
+as an empty string C<\"\">.
+
+=item C<app2_url>
+
+The URL (eg. upstream URL) of the application.
+If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_source_package>
+
+For packaging systems which support this, the name of the source
+package.  If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_summary>
+
+A short (usually one line) description of the application or package.
+If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_description>
+
+A longer description of the application or package.
+If unavailable this is returned as an empty string C<\"\">.
+
+=item C<app2_spare1>
+
+Reserved for future use.
+
+=item C<app2_spare2>
+
+Reserved for future use.
+
+=item C<app2_spare3>
+
+Reserved for future use.
+
+=item C<app2_spare4>
+
+Reserved for future use.
+
+=back
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+  { defaults with
     name = "inspect_get_hostname";
     style = RString "hostname", [Device "root"], [];
     shortdesc = "get hostname of the operating system";
diff --git a/generator/structs.ml b/generator/structs.ml
index 4dcb2c9..207da90 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -230,6 +230,30 @@ let structs = [
     ];
     s_camel_name = "Application" };
 
+  (* Application v2. *)
+  { defaults with
+    s_name = "application2";
+    s_cols = [
+    "app2_name", FString;
+    "app2_display_name", FString;
+    "app2_epoch", FInt32;
+    "app2_version", FString;
+    "app2_release", FString;
+    "app2_arch", FString;
+    "app2_install_path", FString;
+    "app2_trans_path", FString;
+    "app2_publisher", FString;
+    "app2_url", FString;
+    "app2_source_package", FString;
+    "app2_summary", FString;
+    "app2_description", FString;
+    "app2_spare1", FString;
+    "app2_spare2", FString;
+    "app2_spare3", FString;
+    "app2_spare4", FString;
+    ];
+    s_camel_name = "Application2" };
+
   (* ISO primary volume descriptor. *)
   { defaults with
     s_name = "isoinfo";
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 95a4b6b..8708994 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -35,6 +35,7 @@ guestfs_gobject_headers= \
   include/guestfs-gobject/struct-inotify_event.h \
   include/guestfs-gobject/struct-partition.h \
   include/guestfs-gobject/struct-application.h \
+  include/guestfs-gobject/struct-application2.h \
   include/guestfs-gobject/struct-isoinfo.h \
   include/guestfs-gobject/struct-mdstat.h \
   include/guestfs-gobject/struct-btrfssubvolume.h \
@@ -99,6 +100,7 @@ guestfs_gobject_sources= \
   src/struct-inotify_event.c \
   src/struct-partition.c \
   src/struct-application.c \
+  src/struct-application2.c \
   src/struct-isoinfo.c \
   src/struct-mdstat.c \
   src/struct-btrfssubvolume.c \
diff --git a/java/Makefile.inc b/java/Makefile.inc
index 64b533a..9dd39de 100644
--- a/java/Makefile.inc
+++ b/java/Makefile.inc
@@ -21,6 +21,7 @@
 
 java_built_sources = \
 	com/redhat/et/libguestfs/Application.java \
+	com/redhat/et/libguestfs/Application2.java \
 	com/redhat/et/libguestfs/BTRFSSubvolume.java \
 	com/redhat/et/libguestfs/Dirent.java \
 	com/redhat/et/libguestfs/HivexNode.java \
diff --git a/java/com/redhat/et/libguestfs/.gitignore b/java/com/redhat/et/libguestfs/.gitignore
index 72a1144..00bcec9 100644
--- a/java/com/redhat/et/libguestfs/.gitignore
+++ b/java/com/redhat/et/libguestfs/.gitignore
@@ -1,4 +1,5 @@
 Application.java
+Application2.java
 BTRFSSubvolume.java
 Dirent.java
 HivexNode.java
diff --git a/po/POTFILES b/po/POTFILES
index 3f49a05..ba9c9d9 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -181,6 +181,7 @@ gobject/src/optargs-xfs_growfs.c
 gobject/src/optargs-xfs_repair.c
 gobject/src/session.c
 gobject/src/struct-application.c
+gobject/src/struct-application2.c
 gobject/src/struct-btrfssubvolume.c
 gobject/src/struct-dirent.c
 gobject/src/struct-hivex_node.c
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index 23e68e4..a8bff4f 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -42,24 +42,61 @@
 #include "guestfs_protocol.h"
 
 #ifdef DB_DUMP
-static struct guestfs_application_list *list_applications_rpm (guestfs_h *g, struct inspect_fs *fs);
+static struct guestfs_application2_list *list_applications_rpm (guestfs_h *g, struct inspect_fs *fs);
 #endif
-static struct guestfs_application_list *list_applications_deb (guestfs_h *g, struct inspect_fs *fs);
-static struct guestfs_application_list *list_applications_windows (guestfs_h *g, struct inspect_fs *fs);
-static void add_application (guestfs_h *g, struct guestfs_application_list *, const char *name, const char *display_name, int32_t epoch, const char *version, const char *release, const char *install_path, const char *publisher, const char *url, const char *description);
-static void sort_applications (struct guestfs_application_list *);
+static struct guestfs_application2_list *list_applications_deb (guestfs_h *g, struct inspect_fs *fs);
+static struct guestfs_application2_list *list_applications_windows (guestfs_h *g, struct inspect_fs *fs);
+static void add_application (guestfs_h *g, struct guestfs_application2_list *, const char *name, const char *display_name, int32_t epoch, const char *version, const char *release, const char *arch, const char *install_path, const char *publisher, const char *url, const char *description);
+static void sort_applications (struct guestfs_application2_list *);
+
+struct guestfs_application_list *
+guestfs__inspect_list_applications (guestfs_h *g, const char *root)
+{
+  struct guestfs_application_list *ret;
+  struct guestfs_application2_list *r;
+  size_t i;
+
+  /* Call the new function. */
+  r = guestfs_inspect_list_applications2 (g, root);
+  if (!r)
+    return NULL;
+
+  /* Translate the structures from the new format to the old format. */
+  ret = safe_malloc (g, sizeof (struct guestfs_application_list));
+  ret->len = r->len;
+  ret->val =
+    safe_malloc (g, sizeof (struct guestfs_application) * r->len);
+  for (i = 0; i < r->len; ++i) {
+    ret->val[i].app_name = r->val[i].app2_name;
+    ret->val[i].app_display_name = r->val[i].app2_display_name;
+    ret->val[i].app_epoch = r->val[i].app2_epoch;
+    ret->val[i].app_version = r->val[i].app2_version;
+    ret->val[i].app_release = r->val[i].app2_release;
+    ret->val[i].app_install_path = r->val[i].app2_install_path;
+    ret->val[i].app_trans_path = r->val[i].app2_trans_path;
+    ret->val[i].app_publisher = r->val[i].app2_publisher;
+    ret->val[i].app_url = r->val[i].app2_url;
+    ret->val[i].app_source_package = r->val[i].app2_source_package;
+    ret->val[i].app_summary = r->val[i].app2_summary;
+    ret->val[i].app_description = r->val[i].app2_description;
+  }
+  free (r->val);                /* Must not free the strings. */
+  free (r);
+
+  return ret;
+}
 
 /* Unlike the simple inspect-get-* calls, this one assumes that the
  * disks are mounted up, and reads files from the mounted disks.
  */
-struct guestfs_application_list *
-guestfs__inspect_list_applications (guestfs_h *g, const char *root)
+struct guestfs_application2_list *
+guestfs__inspect_list_applications2 (guestfs_h *g, const char *root)
 {
   struct inspect_fs *fs = guestfs___search_for_root (g, root);
   if (!fs)
     return NULL;
 
-  struct guestfs_application_list *ret = NULL;
+  struct guestfs_application2_list *ret = NULL;
 
   /* Presently we can only list applications for installed disks.  It
    * is possible in future to get lists of packages from installers.
@@ -189,6 +226,7 @@ read_rpm_name (guestfs_h *g,
 /* tag constants, see rpmtag.h in RPM for complete list */
 #define RPMTAG_VERSION 1001
 #define RPMTAG_RELEASE 1002
+#define RPMTAG_ARCH 1022
 
 static char *
 get_rpm_header_tag (guestfs_h *g, const unsigned char *header_start,
@@ -233,7 +271,7 @@ get_rpm_header_tag (guestfs_h *g, const unsigned char *header_start,
 
 struct read_package_data {
   struct rpm_names_list *list;
-  struct guestfs_application_list *apps;
+  struct guestfs_application2_list *apps;
 };
 
 static int
@@ -244,7 +282,7 @@ read_package (guestfs_h *g,
 {
   struct read_package_data *data = datav;
   struct rpm_name nkey, *entry;
-  char *version, *release;
+  char *version, *release, *arch;
 
   /* This function reads one (key, value) pair from the Packages
    * database.  The key is the link field (see struct rpm_name).  The
@@ -271,24 +309,26 @@ read_package (guestfs_h *g,
 
   version = get_rpm_header_tag (g, value, valuelen, RPMTAG_VERSION);
   release = get_rpm_header_tag (g, value, valuelen, RPMTAG_RELEASE);
+  arch = get_rpm_header_tag (g, value, valuelen, RPMTAG_ARCH);
 
   /* Add the application and what we know. */
   if (version && release)
     add_application (g, data->apps, entry->name, "", 0, version, release,
-                     "", "", "", "");
+                     arch ? arch : "", "", "", "", "");
 
   free (version);
   free (release);
+  free (arch);
 
   return 0;
 }
 
-static struct guestfs_application_list *
+static struct guestfs_application2_list *
 list_applications_rpm (guestfs_h *g, struct inspect_fs *fs)
 {
   char *Name = NULL, *Packages = NULL;
   struct rpm_names_list list = { .names = NULL, .len = 0 };
-  struct guestfs_application_list *apps = NULL;
+  struct guestfs_application2_list *apps = NULL;
   struct read_package_data data;
 
   Name = guestfs___download_to_tmp (g, fs,
@@ -332,14 +372,14 @@ list_applications_rpm (guestfs_h *g, struct inspect_fs *fs)
   free (Packages);
   free_rpm_names_list (&list);
   if (apps != NULL)
-    guestfs_free_application_list (apps);
+    guestfs_free_application2_list (apps);
 
   return NULL;
 }
 
 #endif /* defined DB_DUMP */
 
-static struct guestfs_application_list *
+static struct guestfs_application2_list *
 list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
 {
   char *status = NULL;
@@ -348,7 +388,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
   if (status == NULL)
     return NULL;
 
-  struct guestfs_application_list *apps = NULL, *ret = NULL;
+  struct guestfs_application2_list *apps = NULL, *ret = NULL;
   FILE *fp = NULL;
   char line[1024];
   size_t len;
@@ -403,7 +443,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
     else if (STREQ (line, "")) {
       if (installed_flag && name && version)
         add_application (g, apps, name, "", 0, version, release ? : "",
-                         "", "", "", "");
+                         "", "", "", "", "");
       free (name);
       free (version);
       free (release);
@@ -423,7 +463,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
 
  out:
   if (ret == NULL && apps != NULL)
-    guestfs_free_application_list (apps);
+    guestfs_free_application2_list (apps);
   if (fp)
     fclose (fp);
   free (name);
@@ -433,9 +473,9 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
   return ret;
 }
 
-static void list_applications_windows_from_path (guestfs_h *g, struct guestfs_application_list *apps, const char **path, size_t path_len);
+static void list_applications_windows_from_path (guestfs_h *g, struct guestfs_application2_list *apps, const char **path, size_t path_len);
 
-static struct guestfs_application_list *
+static struct guestfs_application2_list *
 list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
 {
   size_t len = strlen (fs->windows_systemroot) + 64;
@@ -447,7 +487,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
   if (!software_path)
     return NULL;
 
-  struct guestfs_application_list *ret = NULL;
+  struct guestfs_application2_list *ret = NULL;
   const char *hivepath[] =
     { "Microsoft", "Windows", "CurrentVersion", "Uninstall" };
   const char *hivepath2[] =
@@ -481,7 +521,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
 
 static void
 list_applications_windows_from_path (guestfs_h *g,
-                                     struct guestfs_application_list *apps,
+                                     struct guestfs_application2_list *apps,
                                      const char **path, size_t path_len)
 {
   struct guestfs_hivex_node_list *children = NULL;
@@ -544,7 +584,7 @@ list_applications_windows_from_path (guestfs_h *g,
 
         add_application (g, apps, name, display_name, 0,
                          version ? : "",
-                         "",
+                         "", "",
                          install_path ? : "",
                          publisher ? : "",
                          url ? : "",
@@ -565,48 +605,54 @@ list_applications_windows_from_path (guestfs_h *g,
 }
 
 static void
-add_application (guestfs_h *g, struct guestfs_application_list *apps,
+add_application (guestfs_h *g, struct guestfs_application2_list *apps,
                  const char *name, const char *display_name, int32_t epoch,
-                 const char *version, const char *release,
+                 const char *version, const char *release, const char *arch,
                  const char *install_path,
                  const char *publisher, const char *url,
                  const char *description)
 {
   apps->len++;
   apps->val = safe_realloc (g, apps->val,
-                            apps->len * sizeof (struct guestfs_application));
-  apps->val[apps->len-1].app_name = safe_strdup (g, name);
-  apps->val[apps->len-1].app_display_name = safe_strdup (g, display_name);
-  apps->val[apps->len-1].app_epoch = epoch;
-  apps->val[apps->len-1].app_version = safe_strdup (g, version);
-  apps->val[apps->len-1].app_release = safe_strdup (g, release);
-  apps->val[apps->len-1].app_install_path = safe_strdup (g, install_path);
+                            apps->len * sizeof (struct guestfs_application2));
+  apps->val[apps->len-1].app2_name = safe_strdup (g, name);
+  apps->val[apps->len-1].app2_display_name = safe_strdup (g, display_name);
+  apps->val[apps->len-1].app2_epoch = epoch;
+  apps->val[apps->len-1].app2_version = safe_strdup (g, version);
+  apps->val[apps->len-1].app2_release = safe_strdup (g, release);
+  apps->val[apps->len-1].app2_arch = safe_strdup (g, arch);
+  apps->val[apps->len-1].app2_install_path = safe_strdup (g, install_path);
   /* XXX Translated path is not implemented yet. */
-  apps->val[apps->len-1].app_trans_path = safe_strdup (g, "");
-  apps->val[apps->len-1].app_publisher = safe_strdup (g, publisher);
-  apps->val[apps->len-1].app_url = safe_strdup (g, url);
+  apps->val[apps->len-1].app2_trans_path = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_publisher = safe_strdup (g, publisher);
+  apps->val[apps->len-1].app2_url = safe_strdup (g, url);
   /* XXX The next two are not yet implemented for any package
    * format, but we could easily support them for rpm and deb.
    */
-  apps->val[apps->len-1].app_source_package = safe_strdup (g, "");
-  apps->val[apps->len-1].app_summary = safe_strdup (g, "");
-  apps->val[apps->len-1].app_description = safe_strdup (g, description);
+  apps->val[apps->len-1].app2_source_package = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_summary = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_description = safe_strdup (g, description);
+  /* XXX Reserved for future use. */
+  apps->val[apps->len-1].app2_spare1 = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_spare2 = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_spare3 = safe_strdup (g, "");
+  apps->val[apps->len-1].app2_spare4 = safe_strdup (g, "");
 }
 
 /* Sort applications by name before returning the list. */
 static int
 compare_applications (const void *vp1, const void *vp2)
 {
-  const struct guestfs_application *v1 = vp1;
-  const struct guestfs_application *v2 = vp2;
+  const struct guestfs_application2 *v1 = vp1;
+  const struct guestfs_application2 *v2 = vp2;
 
-  return strcmp (v1->app_name, v2->app_name);
+  return strcmp (v1->app2_name, v2->app2_name);
 }
 
 static void
-sort_applications (struct guestfs_application_list *apps)
+sort_applications (struct guestfs_application2_list *apps)
 {
   if (apps && apps->val)
-    qsort (apps->val, apps->len, sizeof (struct guestfs_application),
+    qsort (apps->val, apps->len, sizeof (struct guestfs_application2),
            compare_applications);
 }
-- 
1.7.11.7




More information about the Libguestfs mailing list