---
generator/actions.ml | 6 ++++++
src/inspect-apps.c | 46 +++++++++++++++++++++++++---------------------
2 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/generator/actions.ml b/generator/actions.ml
index dc71234..afafe9b 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -1527,6 +1527,12 @@ 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<app_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<app_install_path>
The installation path of the application (on operating systems
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index 3dbfb5b..c8e586f 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -31,7 +31,6 @@
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif
-#include <arpa/inet.h>
#include <pcre.h>
@@ -126,7 +125,7 @@ guestfs__inspect_list_applications (guestfs_h *g, const char *root)
#ifdef DB_DUMP
/* This data comes from the Name database, and contains the application
- * names and the first 4 bytes of the link field.
+ * names and the first 4 bytes of each link field.
*/
struct rpm_names_list {
struct rpm_name *names;
@@ -162,22 +161,30 @@ read_rpm_name (guestfs_h *g,
void *listv)
{
struct rpm_names_list *list = listv;
+ const unsigned char *link_p;
char *name;
/* Ignore bogus entries. */
if (keylen == 0 || valuelen < 4)
return 0;
- /* The name (key) field won't be NUL-terminated, so we must do that. */
- name = safe_malloc (g, keylen+1);
- memcpy (name, key, keylen);
- name[keylen] = '\0';
-
- list->names = safe_realloc (g, list->names,
- (list->len + 1) * sizeof (struct rpm_name));
- list->names[list->len].name = name;
- memcpy (list->names[list->len].link, value, 4);
- list->len++;
+ /* A name entry will have as many links as installed instances of
+ * that pacakge. For example, if glibc.i686 and glibc.x86_64 are
+ * both installed, then there will be a link for each Packages
+ * entry. Add an entry onto list for all installed instances.
+ */
+ for (link_p = value; link_p < value + valuelen; link_p += 8) {
+ /* The name (key) field won't be NUL-terminated, so we must do that. */
+ name = safe_malloc (g, keylen+1);
+ memcpy (name, key, keylen);
+ name[keylen] = '\0';
+
+ list->names = safe_realloc (g, list->names,
+ (list->len + 1) * sizeof (struct rpm_name));
+ list->names[list->len].name = name;
+ memcpy (list->names[list->len].link, link_p, 4);
+ list->len++;
+ }
return 0;
}
@@ -199,12 +206,12 @@ get_rpm_header_tag (guestfs_h *g, const void *header_start, size_t
header_len, u
*
http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html#S2-RPM...
*/
- num_fields = ntohl (*(uint32_t *) header_start);
+ num_fields = be32toh (*(uint32_t *) header_start);
store = header_start + 8 + (16 * num_fields);
- while (cursor < store ){
- if (ntohl (*(uint32_t *) cursor) == tag){
- offset = ntohl(*(uint32_t *) (cursor + 8));
+ while (cursor < store && cursor < header_start + header_len) {
+ if (be32toh (*(uint32_t *) cursor) == tag){
+ offset = be32toh(*(uint32_t *) (cursor + 8));
return safe_strdup(g, store + offset);
}
cursor += 16;
@@ -257,14 +264,11 @@ read_package (guestfs_h *g,
/* Add the application and what we know. */
add_application (g, data->apps, entry->name, "", 0, version, release,
- arch ? arch : "(none)", "", "",
"", "");
+ arch ? arch : "", "", "", "",
"");
free (version);
free (release);
- if (arch)
- /* arch will occasionally be NULL, because some packages
- * (e.g. "gpgkeys") do not have an arch */
- free (arch);
+ free (arch);
return 0;
}
--
1.7.11.4