Nikos Skalkotos
2014-Nov-17 19:24 UTC
[Libguestfs] [PATCH] list-applications: Add support for pacman
Extend the guestfs_inspect_list_applications2 API call to work on Arch Linux guest images. Signed-off-by: Nikos Skalkotos <skalkoto@gmail.com> --- src/inspect-apps.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/src/inspect-apps.c b/src/inspect-apps.c index 6fb9665..8e645b7 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: @@ -520,6 +526,137 @@ 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, *line = NULL; + CLEANUP_FREE_DIRENT_LIST struct guestfs_dirent_list *local_db = NULL; + struct guestfs_application2_list *apps = NULL, *ret = NULL; + struct guestfs_dirent *curr = NULL; + FILE *fp; + size_t i, allocsize = 0; + ssize_t len; + CLEANUP_FREE char *name = NULL, *version = NULL, *desc = NULL; + CLEANUP_FREE char *arch = NULL, *url = NULL; + char **key = NULL, *rel = NULL, *ver = NULL, *p; + int32_t epoch; + const size_t path_len = strlen ("/var/lib/pacman/local/") + strlen ("/desc"); + + 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 ((len = getline(&line, &allocsize, fp)) != -1) { + 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 == NULL) || (version == NULL) || (arch == NULL)) + /* Those are mandatory fields. The file is corrupted */ + goto after_add_application; + + /* version: [epoch:]ver-rel */ + p = strchr (version, ':'); + if (p) { + *p = '\0'; + epoch = guestfs___parse_unsigned_int (g, version); /* -1 on error */ + ver = p + 1; + } else { + epoch = 0; + ver = version; + } + + p = strchr (ver, '-'); + if (p) { + *p = '\0'; + rel = p + 1; + } else /* release is a mandatory field */ + goto after_add_application; + + if ((epoch >= 0) && (ver[0] != '\0') && (rel[0] != '\0')) + add_application (g, apps, name, "", epoch, ver, rel, arch, "", "", + url ? : "", desc ? : ""); + + after_add_application: + key = NULL; + free (name); + free (version); + free (desc); + free (arch); + free (url); + name = version = desc = arch = url = NULL; + rel = ver = NULL; /* haven't allocated memory for those */ + + if (fclose (fp) == -1) { + perrorf (g, "fclose: %s", desc_file); + goto out; + } + + } + + ret = apps; + + out: + 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
Richard W.M. Jones
2014-Nov-17 19:56 UTC
Re: [Libguestfs] [PATCH] list-applications: Add support for pacman
On Mon, Nov 17, 2014 at 07:24:03PM +0000, Nikos Skalkotos wrote:> Extend the guestfs_inspect_list_applications2 API call to work on Arch > Linux guest images. > > Signed-off-by: Nikos Skalkotos <skalkoto@gmail.com>ACKed and pushed. Thanks for your contribution. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Reasonably Related Threads
- Re: [PATCH] list-applications: Add support for pacman
- Re: [PATCH] list-applications: Add support for pacman
- [PATCH] list-applications: Add support for pacman
- [PATCH] inspect: list applications with APK
- [PATCH 1/3] inspect: add source and summary to internal add_application