diff options
author | John Eckersberg <jeckersb@redhat.com> | 2012-11-01 13:35:15 -0400 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-11-01 18:22:01 +0000 |
commit | bafd8229149ccc0e05676e031bae5d1489fa74a6 (patch) | |
tree | e220da3ff72493a0ef2a2226ed11913d8c1ecd43 | |
parent | 4c285dd8f6a263ed62802af2c89c4cc75497c1ce (diff) | |
download | libguestfs-bafd8229149ccc0e05676e031bae5d1489fa74a6.tar.gz libguestfs-bafd8229149ccc0e05676e031bae5d1489fa74a6.tar.xz libguestfs-bafd8229149ccc0e05676e031bae5d1489fa74a6.zip |
lib: Add inspect_list_applications2 method (RHBZ#859949)
RWMJ:
- Fix memory leak in guestfs__inspect_list_applications wrapper.
- Don't document app2_spare* fields.
-rw-r--r-- | generator/actions.ml | 104 | ||||
-rw-r--r-- | generator/structs.ml | 24 | ||||
-rw-r--r-- | gobject/Makefile.inc | 2 | ||||
-rw-r--r-- | java/Makefile.inc | 1 | ||||
-rw-r--r-- | java/com/redhat/et/libguestfs/.gitignore | 1 | ||||
-rw-r--r-- | po/POTFILES | 1 | ||||
-rw-r--r-- | src/guestfs.pod | 2 | ||||
-rw-r--r-- | src/inspect-apps.c | 142 |
8 files changed, 233 insertions, 44 deletions
diff --git a/generator/actions.ml b/generator/actions.ml index 71aee379..5d713478 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,109 @@ 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<\"\">. + +=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 4dcb2c9a..207da90c 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 95a4b6b6..87089941 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 64b533ac..9dd39de1 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 72a1144c..00bcec96 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 3f49a05c..ba9c9d9a 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/guestfs.pod b/src/guestfs.pod index f6a759d8..f243c2c4 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -695,7 +695,7 @@ inspection and caches the results in the guest handle. Subsequent calls to C<guestfs_inspect_get_*> return this cached information, but I<do not> re-read the disks. If you change the content of the guest disks, you can redo inspection by calling L</guestfs_inspect_os> -again. (L</guestfs_inspect_list_applications> works a little +again. (L</guestfs_inspect_list_applications2> works a little differently from the other calls and does read the disks. See documentation for that function for details). diff --git a/src/inspect-apps.c b/src/inspect-apps.c index 23e68e49..9307eb28 100644 --- a/src/inspect-apps.c +++ b/src/inspect-apps.c @@ -42,24 +42,71 @@ #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 *); -/* Unlike the simple inspect-get-* calls, this one assumes that the - * disks are mounted up, and reads files from the mounted disks. +/* The deprecated guestfs_inspect_list_applications call, which is now + * just a wrapper around guestfs_inspect_list_applications2. */ 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; + + /* The other strings that we don't copy must be freed. */ + free (r->val[i].app2_arch); + free (r->val[i].app2_spare1); + free (r->val[i].app2_spare2); + free (r->val[i].app2_spare3); + free (r->val[i].app2_spare4); + } + free (r->val); /* Must not free the other 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_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 +236,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 +281,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 +292,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 +319,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 +382,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 +398,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 +453,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 +473,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 +483,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 +497,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 +531,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 +594,7 @@ list_applications_windows_from_path (guestfs_h *g, add_application (g, apps, name, display_name, 0, version ? : "", - "", + "", "", install_path ? : "", publisher ? : "", url ? : "", @@ -565,48 +615,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); } |