[gnome-logs/wip/larsu/listmodel: 6/18] journal: allow matching on field existence



commit 84126ad139f24e321081a32b18acf3e4e66f04b2
Author: Lars Uebernickel <lars uebernic de>
Date:   Sat Feb 14 19:41:47 2015 +0100

    journal: allow matching on field existence
    
    The event view had to manually filter results that don't have a
    _KERNEL_DEVICE or _AUDIT_SESSION (for hardware and security,
    respectively). Move this logic into the GlJournal, where all other
    matching is done. To match on existence, pass only a FIELDNAME instead
    of a FIELDNAME=VALUE pair in the query.
    
    This needs to be emulated in GlJournal, because systemd's journal API
    doesn't support it.

 src/gl-eventviewlist.c |   14 +-----------
 src/gl-journal.c       |   49 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 12 deletions(-)
---
diff --git a/src/gl-eventviewlist.c b/src/gl-eventviewlist.c
index 8b6bbe8..8c24c04 100644
--- a/src/gl-eventviewlist.c
+++ b/src/gl-eventviewlist.c
@@ -327,11 +327,6 @@ insert_devices_idle (GlEventViewList *view)
 
             if (result)
             {
-                if (result->kernel_device == NULL)
-                {
-                    continue;
-                }
-
                 row = gl_event_view_row_new (result,
                                              GL_EVENT_VIEW_ROW_STYLE_SIMPLE,
                                              priv->clock_format);
@@ -414,11 +409,6 @@ insert_security_idle (GlEventViewList *view)
 
             if (result)
             {
-                if (result->audit_session == NULL)
-                {
-                    continue;
-                }
-
                 row = gl_event_view_row_new (result,
                                              GL_EVENT_VIEW_ROW_STYLE_CMDLINE,
                                              priv->clock_format);
@@ -732,7 +722,7 @@ static void
 gl_event_view_list_add_listbox_hardware (GlEventViewList *view)
 {
     GlJournalQuery query = { N_RESULTS,
-                             (gchar *[2]){ "_TRANSPORT=kernel", NULL } };
+                             (gchar *[3]){ "_TRANSPORT=kernel", "_KERNEL_DEVICE", NULL } };
     GlEventViewListPrivate *priv;
 
     priv = gl_event_view_list_get_instance_private (view);
@@ -743,7 +733,7 @@ gl_event_view_list_add_listbox_hardware (GlEventViewList *view)
 static void
 gl_event_view_list_add_listbox_security (GlEventViewList *view)
 {
-    const GlJournalQuery query = { N_RESULTS, NULL };
+    const GlJournalQuery query = { N_RESULTS, (gchar *[2]){ "_AUDIT_SESSION", NULL } };
     GlEventViewListPrivate *priv;
 
     priv = gl_event_view_list_get_instance_private (view);
diff --git a/src/gl-journal.c b/src/gl-journal.c
index 6b64e60..35fd74c 100644
--- a/src/gl-journal.c
+++ b/src/gl-journal.c
@@ -392,6 +392,45 @@ gl_journal_query_finish (GlJournal *self,
     return g_task_propagate_pointer (G_TASK (res), error);
 }
 
+/**
+ * gl_journal_query_match:
+ * @query: a @query to match against the current log entry
+ *
+ * systemd's matching doesn't allow checking for the existance of
+ * fields. This function checks if fields in @query that don't have a
+ * value (and thus no '=' delimiter) are present at all in the current
+ * log entry.
+ *
+ * Returns: %TRUE if the current log entry contains all fields in @query
+ */
+static gboolean
+gl_journal_query_match (sd_journal           *journal,
+                        const GlJournalQuery *query)
+{
+  gint i;
+
+  for (i = 0; query->matches[i]; i++)
+  {
+      int r;
+      const void *data;
+      size_t len;
+
+      /* don't check fields that match on a value */
+      if (strchr (query->matches[i], '='))
+          continue;
+
+      r = sd_journal_get_data (journal, query->matches[i], &data, &len);
+
+      if (r == -ENOENT) /* field doesn't exist */
+          return FALSE;
+
+      else if (r < 0)
+          g_warning ("Failed to read log entry: %s", g_strerror (-r));
+  }
+
+  return TRUE;
+}
+
 GList *
 gl_journal_query (GlJournal *self, const GlJournalQuery *query)
 {
@@ -414,6 +453,10 @@ gl_journal_query (GlJournal *self, const GlJournalQuery *query)
         for (i = 0, match = query->matches[i]; match;
              match = query->matches[++i])
         {
+            /* don't add fields of which we only want to check existance */
+            if (strchr (match, '=') == NULL)
+                continue;
+
             ret = sd_journal_add_match (journal, match, 0);
 
             if (ret < 0)
@@ -479,6 +522,9 @@ gl_journal_query (GlJournal *self, const GlJournalQuery *query)
                 break;
             }
 
+            if (!gl_journal_query_match (journal, query))
+                continue;
+
             result = _gl_journal_query_result (self);
 
             results = g_list_prepend (results, result);
@@ -514,6 +560,9 @@ gl_journal_query (GlJournal *self, const GlJournalQuery *query)
                 break;
             }
 
+            if (!gl_journal_query_match (journal, query))
+                continue;
+
             result = _gl_journal_query_result (self);
 
             results = g_list_prepend (results, result);


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