Extend the guestfs_inspect_list_applications2 API call to work on Arch
Linux guest images.
---
src/inspect-apps.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 125 insertions(+)
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index b62b432..b7a3b0e 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -60,6 +60,7 @@
static struct guestfs_application2_list *list_applications_rpm (guestfs_h *g, struct
inspect_fs *fs);
#endif
static struct guestfs_application2_list *list_applications_deb (guestfs_h *g, struct
inspect_fs *fs);
+static struct guestfs_application2_list *list_applications_pacman (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 *);
@@ -145,6 +146,11 @@ guestfs__inspect_list_applications2 (guestfs_h *g, const char *root)
break;
case OS_PACKAGE_FORMAT_PACMAN:
+ ret = list_applications_pacman (g, fs);
+ if (ret == NULL)
+ return NULL;
+ break;
+
case OS_PACKAGE_FORMAT_EBUILD:
case OS_PACKAGE_FORMAT_PISI:
case OS_PACKAGE_FORMAT_PKGSRC:
@@ -494,6 +500,125 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
return ret;
}
+static struct guestfs_application2_list *
+list_applications_pacman (guestfs_h *g, struct inspect_fs *fs)
+{
+ CLEANUP_FREE char *desc_file = NULL, *fname = NULL;
+ struct guestfs_application2_list *apps = NULL, *ret = NULL;
+ struct guestfs_dirent *curr = NULL;
+ FILE *fp;
+ char line[1024];
+ size_t i, len;
+ CLEANUP_FREE char *name = NULL, *version = NULL, *desc = NULL;
+ CLEANUP_FREE char *arch = NULL, *url = NULL;
+ char *release = NULL;
+ char **key = NULL;
+ const size_t path_len = strlen ("/var/lib/pacman/local/") + strlen
("/desc");
+ struct guestfs_dirent_list *local_db = NULL;
+
+ local_db = guestfs_readdir (g, "/var/lib/pacman/local");
+ if (local_db == NULL)
+ return NULL;
+
+ /* Allocate 'apps' list. */
+ apps = safe_malloc (g, sizeof *apps);
+ apps->len = 0;
+ apps->val = NULL;
+
+
+ for (i = 0; i < local_db->len; i++) {
+ curr = &local_db->val[i];
+
+ if (curr->ftyp != 'd' || STREQ (curr->name, ".") || STREQ
(curr->name, ".."))
+ continue;
+
+ free (fname);
+ fname = safe_malloc (g, strlen (curr->name) + path_len + 1);
+ sprintf (fname, "/var/lib/pacman/local/%s/desc", curr->name);
+ free (desc_file);
+ desc_file = guestfs___download_to_tmp (g, fs, fname, curr->name, 8192);
+
+ /* The desc files are small (4K). If the desc file does not exist, or is
+ * larger than the 8K limit we've used, the database is probably corrupted,
+ * but we'll continue with the next package anyway.
+ */
+ if (desc_file == NULL)
+ continue;
+
+ fp = fopen (desc_file, "r");
+ if (fp == NULL) {
+ perrorf (g, "fopen: %s", desc_file);
+ goto out;
+ }
+
+ while (fgets (line, sizeof line, fp) != NULL) {
+ len = strlen (line);
+ if (len > 0 && line[len-1] == '\n') {
+ line[--len] = '\0';
+ }
+
+ /* empty line */
+ if (len == 0) {
+ key = NULL;
+ continue;
+ }
+
+ if (key != NULL) {
+ *key = safe_strdup (g, line);
+ key = NULL;
+ continue;
+ }
+
+ if (STREQ(line, "%NAME%"))
+ key = &name;
+ else if (STREQ(line, "%VERSION%"))
+ key = &version;
+ else if (STREQ(line, "%DESC%"))
+ key = &desc;
+ else if (STREQ(line, "%URL%"))
+ key = &url;
+ else if (STREQ(line, "%ARCH%"))
+ key = &arch;
+ }
+
+ if (name) {
+ if (version) {
+ char *p = strchr (version, '-');
+ if (p) {
+ *p = '\0';
+ release = p + 1;
+ }
+ }
+ add_application (g, apps, name, "", 0, version ? : "", release
? : "",
+ arch ? : "", "", "", url ? :
"", desc ? : "");
+ }
+
+ free (name);
+ free (version);
+ free (desc);
+ free (arch);
+ free (url);
+ name = version = desc = arch = url = NULL;
+ release = NULL; /* Haven't allocated memory for release */
+
+ if (fclose (fp) == -1) {
+ perrorf (g, "fclose: %s", desc_file);
+ goto out;
+ }
+
+ }
+
+ ret = apps;
+
+ out:
+ guestfs_free_dirent_list (local_db);
+
+ if (ret == NULL)
+ guestfs_free_application2_list (apps);
+
+ return ret;
+}
+
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_application2_list *
--
2.1.3