+ return 0;
+}
+
+struct read_package_data {
+ struct rpm_names_list *list;
+ struct guestfs_application_list *apps;
+};
+
+static int
+read_package (guestfs_h *g,
+ const unsigned char *key, size_t keylen,
+ const unsigned char *value, size_t valuelen,
+ void *datav)
+{
+ struct read_package_data *data = datav;
+ struct rpm_name nkey, *entry;
+ char *p;
+ size_t len;
+ ssize_t max;
+ char *nul_name_nul, *version, *release;
+
+ /* This function reads one (key, value) pair from the Packages
+ * database. The key is the link field (see struct rpm_name). The
+ * value is a long binary string, but we can extract the version
+ * number from it as below. First we have to look up the link field
+ * in the list of links (which is sorted by link field).
+ */
+
+ /* Ignore bogus entries. */
+ if (keylen < 4 || valuelen == 0)
+ return 0;
+
+ /* Look up the link (key) in the list. */
+ memcpy (nkey.link, key, 4);
+ entry = bsearch (&nkey, data->list->names, data->list->len,
+ sizeof (struct rpm_name), compare_links);
+ if (!entry)
+ return 0; /* Not found - ignore it. */
+
+ /* We found a matching link entry, so that gives us the application
+ * name (entry->name). Now we can get other data for this
+ * application out of the binary value string. XXX This is a real
+ * hack.
+ */
+
+ /* Look for \0<name>\0 */
+ len = strlen (entry->name);
+ nul_name_nul = safe_malloc (g, len + 2);
+ nul_name_nul[0] = '\0';
+ memcpy (&nul_name_nul[1], entry->name, len);
+ nul_name_nul[len+1] = '\0';
+ p = memmem (value, valuelen, nul_name_nul, len+2);
+ free (nul_name_nul);
+ if (!p)
+ return 0;
+
+ /* Following that are \0-delimited version and release fields. */
+ p += len + 2; /* Note we have to skip \0 + name + \0. */
+ max = valuelen - (p - (char *) value);
+ if (max < 0)
+ max = 0;
+ version = safe_strndup (g, p, max);
+
+ len = strlen (version);
+ p += len + 1;
+ max = valuelen - (p - (char *) value);
+ if (max < 0)
+ max = 0;
+ release = safe_strndup (g, p, max);
+
+ /* Add the application and what we know. */
+ add_application (g, data->apps, entry->name, "", 0, version, release,
+ "", "", "", "");
+
+ free (version);
+ free (release);