chiark / gitweb /
journal: add ability to filter by current user
[elogind.git] / src / journal / sd-journal.c
index 779af62b518bff9eb6831a1c64233dcb2b00c01d..46511df6be0dfc145ed98cd264b263c64a48d66c 100644 (file)
@@ -197,9 +197,7 @@ static void match_free(Match *m) {
 }
 
 static void match_free_if_empty(Match *m) {
-        assert(m);
-
-        if (m->matches)
+        if (!m || m->matches)
                 return;
 
         match_free(m);
@@ -296,17 +294,10 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
         return 0;
 
 fail:
-        if (add_here)
-                match_free_if_empty(add_here);
-
-        if (j->level2)
-                match_free_if_empty(j->level2);
-
-        if (j->level1)
-                match_free_if_empty(j->level1);
-
-        if (j->level0)
-                match_free_if_empty(j->level0);
+        match_free_if_empty(add_here);
+        match_free_if_empty(j->level2);
+        match_free_if_empty(j->level1);
+        match_free_if_empty(j->level0);
 
         return -ENOMEM;
 }
@@ -1258,6 +1249,42 @@ static void check_network(sd_journal *j, int fd) {
                 F_TYPE_CMP(sfs.f_type, SMB_SUPER_MAGIC);
 }
 
+static bool file_has_type_prefix(const char *prefix, const char *filename) {
+        const char *full, *tilded, *atted;
+
+        full = strappend(prefix, ".journal");
+        tilded = strappenda(full, "~");
+        atted = strappenda(prefix, "@");
+
+        return streq(filename, full) ||
+               streq(filename, tilded) ||
+               startswith(filename, atted);
+}
+
+static bool file_type_wanted(int flags, const char *filename) {
+        if (!endswith(filename, ".journal") && !endswith(filename, ".journal~"))
+                return false;
+
+        /* no flags set → every type is OK */
+        if (!(flags & (SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER)))
+                return true;
+
+        if (flags & SD_JOURNAL_SYSTEM && file_has_type_prefix("system", filename))
+                return true;
+
+        if (flags & SD_JOURNAL_CURRENT_USER) {
+                char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1];
+
+                assert_se(snprintf(prefix, sizeof(prefix), "user-%lu", (unsigned long) getuid())
+                          < (int) sizeof(prefix));
+
+                if (file_has_type_prefix(prefix, filename))
+                        return true;
+        }
+
+        return false;
+}
+
 static int add_file(sd_journal *j, const char *prefix, const char *filename) {
         _cleanup_free_ char *path = NULL;
         int r;
@@ -1267,11 +1294,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
         assert(prefix);
         assert(filename);
 
-        if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) &&
-            !(streq(filename, "system.journal") ||
-              streq(filename, "system.journal~") ||
-              (startswith(filename, "system@") &&
-               (endswith(filename, ".journal") || endswith(filename, ".journal~")))))
+        if (!file_type_wanted(j->flags, filename))
                 return 0;
 
         path = strjoin(prefix, "/", filename, NULL);
@@ -1302,7 +1325,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
                 return r;
         }
 
-        log_debug("File %s got added.", f->path);
+        log_debug("File %s added.", f->path);
 
         check_network(j, f->fd);
 
@@ -1330,7 +1353,7 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename)
 
         hashmap_remove(j->files, f->path);
 
-        log_debug("File %s got removed.", f->path);
+        log_debug("File %s removed.", f->path);
 
         if (j->current_file == f) {
                 j->current_file = NULL;
@@ -1397,7 +1420,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
                 path = NULL; /* avoid freeing in cleanup */
                 j->current_invalidate_counter ++;
 
-                log_debug("Directory %s got added.", m->path);
+                log_debug("Directory %s added.", m->path);
 
         } else if (m->is_root)
                 return 0;
@@ -1476,7 +1499,7 @@ static int add_root_directory(sd_journal *j, const char *p) {
 
                 j->current_invalidate_counter ++;
 
-                log_debug("Root directory %s got added.", m->path);
+                log_debug("Root directory %s added.", m->path);
 
         } else if (!m->is_root)
                 return 0;
@@ -1537,9 +1560,9 @@ static int remove_directory(sd_journal *j, Directory *d) {
         hashmap_remove(j->directories_by_path, d->path);
 
         if (d->is_root)
-                log_debug("Root directory %s got removed.", d->path);
+                log_debug("Root directory %s removed.", d->path);
         else
-                log_debug("Directory %s got removed.", d->path);
+                log_debug("Directory %s removed.", d->path);
 
         free(d->path);
         free(d);
@@ -1628,7 +1651,8 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) {
 
         if (flags & ~(SD_JOURNAL_LOCAL_ONLY|
                       SD_JOURNAL_RUNTIME_ONLY|
-                      SD_JOURNAL_SYSTEM_ONLY))
+                      SD_JOURNAL_SYSTEM|
+                      SD_JOURNAL_CURRENT_USER))
                 return -EINVAL;
 
         j = journal_new(flags, NULL);