[gnome-logs/wip/field-length: 1/3] Use the length result of sd_journal_get_data()



commit dc51e302c999f0bd7218a038a904682e40f2b37e
Author: David King <davidk gnome org>
Date:   Wed Oct 23 17:54:47 2013 +0100

    Use the length result of sd_journal_get_data()
    
    Previously, the journal fields were passed to functions which assumed a
    NUL-terminated string, and surprisngly this mostly worked. However, the
    systemd journal API does not guarantee this, and there were some reports
    of strange crashes and odd characters appearing in log messages.
    
    Fix the problem by using the length result from sd_journal_get_data() to
    read only the number of characters in the field.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=709290

 src/gl-eventview.c |    4 +-
 src/gl-journal.c   |  123 ++++++++++++++++++++--------------------------------
 src/gl-journal.h   |    8 ++--
 3 files changed, 53 insertions(+), 82 deletions(-)
---
diff --git a/src/gl-eventview.c b/src/gl-eventview.c
index 68a6c12..5feaafd 100644
--- a/src/gl-eventview.c
+++ b/src/gl-eventview.c
@@ -409,7 +409,7 @@ insert_journal_query_devices (GlJournal *journal,
         GlJournalResult result = *(GlJournalResult *)(l->data);
 
         /* Skip if the log entry does not refer to a hardware device. */
-        if (*result.kernel_device == '\0')
+        if (result.kernel_device == NULL)
         {
             continue;
         }
@@ -485,7 +485,7 @@ insert_journal_query_security (GlJournal *journal,
 
         /* Skip if the journal entry does not have an associated audit
          * session. */
-        if (*result.audit_session == '\0')
+        if (result.audit_session == NULL)
         {
             continue;
         }
diff --git a/src/gl-journal.c b/src/gl-journal.c
index 1efeb49..eb2d9b6 100644
--- a/src/gl-journal.c
+++ b/src/gl-journal.c
@@ -19,6 +19,7 @@
 #include "gl-journal.h"
 
 #include <glib-unix.h>
+#include <gio/gio.h>
 #include <stdlib.h>
 
 typedef struct
@@ -133,6 +134,39 @@ gl_journal_init (GlJournal *self)
 
 }
 
+static gchar *
+gl_journal_get_data (GlJournal *self,
+                     const gchar *field,
+                     GError **error)
+{
+    GlJournalPrivate *priv;
+    gint ret;
+    gconstpointer data;
+    gsize length;
+    gsize prefix_len;
+
+    g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+    g_return_val_if_fail (field != NULL, NULL);
+
+    priv = gl_journal_get_instance_private (self);
+    ret = sd_journal_get_data (priv->journal, field, &data, &length);
+
+    if (ret < 0)
+    {
+        /* TODO: Use custom GError enumeration. */
+        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
+                     "Unable to get field ā€˜%sā€™ from systemd journal: %s",
+                     field, g_strerror (-ret));
+        return NULL;
+    }
+
+    /* Field data proper starts after the first '='. */
+    prefix_len = strchr (data, '=') - (const gchar *)data + 1;
+
+    /* Trim the prefix off the beginning of the field. */
+    return g_strndup ((const gchar *)data + prefix_len, length - prefix_len);
+}
+
 static GlJournalResult *
 _gl_journal_query_result (GlJournal *self)
 {
@@ -140,12 +174,7 @@ _gl_journal_query_result (GlJournal *self)
     GlJournalResult *result;
     gint ret;
     sd_journal *journal;
-    const gchar *message;
-    const gchar *comm;
-    const gchar *kernel_device;
-    const gchar *audit_session;
-    const gchar *priority;
-    gsize length;
+    gchar *priority;
 
     priv = gl_journal_get_instance_private (self);
     journal = priv->journal;
@@ -201,76 +230,14 @@ _gl_journal_query_result (GlJournal *self)
         goto out;
     }
 
-    ret = sd_journal_get_data (journal, "_COMM", (const void **)&comm,
-                               &length);
-
-    if (ret < 0)
-    {
-        g_debug ("Unable to get commandline from systemd journal: %s",
-                 g_strerror (-ret));
-        comm = "_COMM=";
-    }
-
-    result->comm = strchr (comm, '=') + 1;
-
-    ret = sd_journal_get_data (journal, "_KERNEL_DEVICE",
-                               (const void **)&kernel_device, &length);
-
-    if (ret < 0)
-    {
-        g_debug ("Unable to get kernel device from systemd journal: %s",
-                 g_strerror (-ret));
-        kernel_device = "_KERNEL_DEVICE=";
-    }
-
-    result->kernel_device = strchr (kernel_device, '=') + 1;
-
-    ret = sd_journal_get_data (journal, "_AUDIT_SESSION",
-                               (const void **)&audit_session, &length);
-
-    if (ret < 0)
-    {
-        g_debug ("Unable to get audit session from systemd journal: %s",
-                 g_strerror (-ret));
-        audit_session = "_AUDIT_SESSION=";
-    }
-
-    result->audit_session = strchr (audit_session, '=') + 1;
-
-    ret = sd_journal_get_data (journal, "MESSAGE", (const void **)&message,
-                               &length);
-
-    if (ret < 0)
-    {
-        g_warning ("Error getting message from systemd journal: %s",
-                   g_strerror (-ret));
-        free (result->cursor);
-        free (result->catalog);
-        goto out;
-    }
-
-    result->message = strchr (message, '=') + 1;
-
-    ret = sd_journal_get_data (journal, "PRIORITY",
-                               (const void **)&priority, &length);
-
-    if (ret == -ENOENT)
-    {
-        g_warning ("No priority was set for this message");
-        free (result->cursor);
-        free (result->catalog);
-        goto out;
-    }
-    else if (ret < 0)
-    {
-        g_warning ("Error getting priority from systemd journal: %s",
-                   g_strerror (-ret));
-        free (result->cursor);
-        free (result->catalog);
-        goto out;
-    }
-
-    result->priority = atoi (strchr (priority, '=') + 1);
+    /* FIXME: Pass in a GError and check the result. */
+    result->comm = gl_journal_get_data (self, "_COMM", NULL);
+    result->kernel_device = gl_journal_get_data (self, "_KERNEL_DEVICE", NULL);
+    result->audit_session = gl_journal_get_data (self, "_AUDIT_SESSION", NULL);
+    result->message = gl_journal_get_data (self, "MESSAGE", NULL);
+    priority = gl_journal_get_data (self, "PRIORITY", NULL);
+    result->priority = atoi (priority);
+    g_free (priority);
 
     return result;
 
@@ -405,6 +372,10 @@ _gl_journal_result_free (GlJournalResult *result,
 {
     free (result->cursor);
     free (result->catalog);
+    g_free (result->message);
+    g_free (result->comm);
+    g_free (result->kernel_device);
+    g_free (result->audit_session);
     g_slice_free (GlJournalResult, result);
 }
 
diff --git a/src/gl-journal.h b/src/gl-journal.h
index 0220a16..86febf5 100644
--- a/src/gl-journal.h
+++ b/src/gl-journal.h
@@ -34,10 +34,10 @@ typedef struct
 {
     guint64 timestamp;
     gchar *cursor;
-    const gchar *message;
-    const gchar *comm;
-    const gchar *kernel_device;
-    const gchar *audit_session;
+    gchar *message;
+    gchar *comm;
+    gchar *kernel_device;
+    gchar *audit_session;
     gchar *catalog;
     guint priority;
 } GlJournalResult;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]