From: "Richard W.M. Jones" <rjones(a)redhat.com>
This breaks the ABI, but by using symbol versioning existing callers
will not be affected. Also this change is source compatible, so
existing code does not need to be modified.
---
generator/actions.ml | 1 +
generator/structs.ml | 8 +++-
src/compat.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/inspect-apps.c | 5 +++
4 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index e1db3db..3b0806a 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -1522,6 +1522,7 @@ Please read L<guestfs(3)/INSPECTION> for more details."
};
{ defaults with
name = "inspect_list_applications";
style = RStructList ("applications", "application"), [Device
"root"], [];
+ symbol_version = Some "GUESTFS_1.20";
shortdesc = "get list of applications installed in the operating system";
longdesc = "\
Return the list of applications installed in the operating system.
diff --git a/generator/structs.ml b/generator/structs.ml
index e378224..a75388c 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -222,6 +222,7 @@ let structs = [
"app_epoch", FInt32;
"app_version", FString;
"app_release", FString;
+ "app_arch", FString;
"app_install_path", FString;
"app_trans_path", FString;
"app_publisher", FString;
@@ -229,8 +230,13 @@ let structs = [
"app_source_package", FString;
"app_summary", FString;
"app_description", FString;
+ "app_spare1", FString;
+ "app_spare2", FString;
+ "app_spare3", FString;
+ "app_spare4", FString;
];
- s_camel_name = "Application" };
+ s_camel_name = "Application";
+ s_symbol_version = Some "GUESTFS_1.20" };
(* ISO primary volume descriptor. *)
{ defaults with
diff --git a/src/compat.c b/src/compat.c
index 27ffd05..520400b 100644
--- a/src/compat.c
+++ b/src/compat.c
@@ -24,3 +24,107 @@
* instead of being compiled as a separate unit. The cpp symbols
* COMPAT_ACTIONS or COMPAT_STRUCTS are defined as appropriate.
*/
+
+#define DEBUG_COMPAT debug (g, "%s: compatibility wrapper invoked", __func__)
+
+/* guestfs_inspect_list_applications did not return the C<app_arch>
+ * field in libguestfs < 1.20. We cannot add fields to structs
+ * without breaking compatibility.
+ */
+struct guestfs_application__v1 {
+ char *app_name;
+ char *app_display_name;
+ int32_t app_epoch;
+ char *app_version;
+ char *app_release;
+ char *app_install_path;
+ char *app_trans_path;
+ char *app_publisher;
+ char *app_url;
+ char *app_source_package;
+ char *app_summary;
+ char *app_description;
+};
+
+struct guestfs_application_list__v1 {
+ uint32_t len;
+ struct guestfs_application__v1 *val;
+};
+
+#if COMPAT_ACTIONS
+
+/* Declare a prototype to make GCC happy. */
+GUESTFS_DLL_PUBLIC struct guestfs_application_list__v1
*guestfs_inspect_list_applications__v1 (guestfs_h *g, const char *root);
+
+GUESTFS_DLL_PUBLIC
+struct guestfs_application_list__v1 *
+guestfs_inspect_list_applications__v1 (guestfs_h *g, const char *root)
+{
+ struct guestfs_application_list__v1 *ret;
+ struct guestfs_application_list *r;
+ size_t i;
+
+ DEBUG_COMPAT;
+
+ /* Call the new function. */
+ r = guestfs_inspect_list_applications (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__v1));
+ ret->len = r->len;
+ ret->val =
+ safe_malloc (g, sizeof (struct guestfs_application__v1) * r->len);
+ for (i = 0; i < r->len; ++i) {
+ ret->val[i].app_name = r->val[i].app_name;
+ ret->val[i].app_display_name = r->val[i].app_display_name;
+ ret->val[i].app_epoch = r->val[i].app_epoch;
+ ret->val[i].app_version = r->val[i].app_version;
+ ret->val[i].app_release = r->val[i].app_release;
+ ret->val[i].app_install_path = r->val[i].app_install_path;
+ ret->val[i].app_trans_path = r->val[i].app_trans_path;
+ ret->val[i].app_publisher = r->val[i].app_publisher;
+ ret->val[i].app_url = r->val[i].app_url;
+ ret->val[i].app_source_package = r->val[i].app_source_package;
+ ret->val[i].app_summary = r->val[i].app_summary;
+ ret->val[i].app_description = r->val[i].app_description;
+ }
+ free (r->val); /* Must not free the strings. */
+ free (r);
+
+ return ret;
+}
+
+__asm__(".symver
guestfs_inspect_list_applications__v1,guestfs_inspect_list_applications@");
+__asm__(".symver
guestfs_inspect_list_applications__GUESTFS_1_20,guestfs_inspect_list_applications@(a)GUESTFS_1.20");
+
+#endif /* COMPAT_ACTIONS */
+
+#if COMPAT_STRUCTS
+
+GUESTFS_DLL_PUBLIC void guestfs_free_application__v1 (struct guestfs_application__v1
*x);
+
+GUESTFS_DLL_PUBLIC void
+guestfs_free_application__v1 (struct guestfs_application__v1 *x)
+{
+ /* XXX */
+ free (x);
+}
+
+__asm__(".symver guestfs_free_application__v1,guestfs_free_application@");
+__asm__(".symver
guestfs_free_application__GUESTFS_1_20,guestfs_free_application@(a)GUESTFS_1.20");
+
+GUESTFS_DLL_PUBLIC void guestfs_free_application_list__v1 (struct
guestfs_application_list__v1 *x);
+
+GUESTFS_DLL_PUBLIC void
+guestfs_free_application_list__v1 (struct guestfs_application_list__v1 *x)
+{
+ /* XXX */
+ free (x);
+}
+
+__asm__(".symver
guestfs_free_application_list__v1,guestfs_free_application_list@");
+__asm__(".symver
guestfs_free_application_list__GUESTFS_1_20,guestfs_free_application_list@(a)GUESTFS_1.20");
+
+#endif /* COMPAT_STRUCTS */
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index 23e68e4..e5db4b3 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -580,6 +580,7 @@ add_application (guestfs_h *g, struct guestfs_application_list *apps,
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_arch = safe_strdup (g, "");
apps->val[apps->len-1].app_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, "");
@@ -591,6 +592,10 @@ add_application (guestfs_h *g, struct guestfs_application_list
*apps,
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].app_spare1 = safe_strdup (g, "");
+ apps->val[apps->len-1].app_spare2 = safe_strdup (g, "");
+ apps->val[apps->len-1].app_spare3 = safe_strdup (g, "");
+ apps->val[apps->len-1].app_spare4 = safe_strdup (g, "");
}
/* Sort applications by name before returning the list. */
--
1.7.11.4