[Libguestfs] [PATCH 2/3] inspect: read more fields for Debian packages

Pino Toscano ptoscano at redhat.com
Thu Feb 23 17:55:30 UTC 2017


In particular, read the URL, the source name, and both the summary and
the description.  For the long description, add a small system to read
continuation lines.
---
 lib/inspect-apps.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 6 deletions(-)

diff --git a/lib/inspect-apps.c b/lib/inspect-apps.c
index eabe565..b7adaa2 100644
--- a/lib/inspect-apps.c
+++ b/lib/inspect-apps.c
@@ -437,7 +437,11 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
   size_t len;
   int32_t epoch = 0;
   CLEANUP_FREE char *name = NULL, *version = NULL, *release = NULL, *arch = NULL;
+  CLEANUP_FREE char *url = NULL, *source = NULL, *summary = NULL;
+  CLEANUP_FREE char *description = NULL;
   int installed_flag = 0;
+  char **continuation_field = NULL;
+  size_t continuation_field_len = 0;
 
   status = guestfs_int_download_to_tmp (g, fs, "/var/lib/dpkg/status", "status",
 					MAX_PKG_DB_SIZE);
@@ -457,10 +461,6 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
 
   /* Read the temporary file.  Each package entry is separated by
    * a blank line.
-   * XXX Strictly speaking this is in mailbox header format, so it
-   * would be possible for fields to spread across multiple lines,
-   * although for the short fields that we are concerned about this is
-   * unlikely and not seen in practice.
    */
   while (fgets (line, sizeof line, fp) != NULL) {
     len = strlen (line);
@@ -469,6 +469,35 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
       len--;
     }
 
+    /* Handling of continuation lines, which must be done before
+     * checking for other headers.
+     */
+    if (line[0] == ' ' && continuation_field) {
+      /* This is a continuation line, and this is the first line of
+       * the field.
+       */
+      if (*continuation_field == NULL) {
+        *continuation_field = safe_strdup (g, &line[1]);
+        continuation_field_len = len - 1;
+      }
+      else {
+        /* Not the first line, so append to the existing buffer
+         * (with a new line before).
+         */
+        size_t new_len = continuation_field_len + 1 + (len - 1);
+        *continuation_field = safe_realloc (g, *continuation_field,
+                                            new_len + 1);
+        (*continuation_field)[continuation_field_len] = '\n';
+        strcpy (*continuation_field + continuation_field_len + 1, &line[1]);
+        continuation_field_len = new_len;
+      }
+    }
+    else {
+      /* Not a continuation line, or not interested in it -- reset. */
+      continuation_field = NULL;
+      continuation_field = 0;
+    }
+
     if (STRPREFIX (line, "Package: ")) {
       free (name);
       name = safe_strdup (g, &line[9]);
@@ -501,15 +530,39 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
       free (arch);
       arch = safe_strdup (g, &line[14]);
     }
+    else if (STRPREFIX (line, "Homepage: ")) {
+      free (url);
+      url = safe_strdup (g, &line[10]);
+    }
+    else if (STRPREFIX (line, "Source: ")) {
+      /* A 'Source' entry may be both 'foo' and 'foo (1.0)', so make sure
+       * to read only the name in the latter case.
+       */
+      char *space_pos = strchr (&line[8], ' ');
+      if (space_pos)
+        *space_pos = '\0';
+      free (source);
+      source = safe_strdup (g, &line[8]);
+    }
+    else if (STRPREFIX (line, "Description: ")) {
+      free (summary);
+      summary = safe_strdup (g, &line[13]);
+      continuation_field = &description;
+    }
     else if (STREQ (line, "")) {
       if (installed_flag && name && version && (epoch >= 0))
         add_application (g, apps, name, "", epoch, version, release ? : "",
-                         arch ? : "", "", "", "", "", "", "");
+                         arch ? : "", "", "", url ? : "", source ? : "",
+                         summary ? : "", description ? : "");
       free (name);
       free (version);
       free (release);
       free (arch);
-      name = version = release = arch = NULL;
+      free (url);
+      free (source);
+      free (summary);
+      free (description);
+      name = version = release = arch = url = source = summary = description = NULL;
       installed_flag = 0;
     }
   }
-- 
2.9.3




More information about the Libguestfs mailing list