chiark / gitweb /
rename CMP_F_TYPE to F_TYPE_CMP
[elogind.git] / src / journal / sd-journal.c
index bb9967193474d26e41375f51c4e3bca4405754ed..bc9e41e0471518a37ef5603896659cb06ef6a029 100644 (file)
@@ -203,7 +203,7 @@ static void match_free_if_empty(Match *m) {
 }
 
 _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
-        Match *l2, *l3, *add_here = NULL, *m;
+        Match *l3, *l4, *add_here = NULL, *m;
         le64_t le_hash;
 
         if (!j)
@@ -218,44 +218,52 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
         if (!match_is_valid(data, size))
                 return -EINVAL;
 
-        /* level 0: OR term
-         * level 1: AND terms
-         * level 2: OR terms
-         * level 3: concrete matches */
+        /* level 0: AND term
+         * level 1: OR terms
+         * level 2: AND terms
+         * level 3: OR terms
+         * level 4: concrete matches */
 
         if (!j->level0) {
-                j->level0 = match_new(NULL, MATCH_OR_TERM);
+                j->level0 = match_new(NULL, MATCH_AND_TERM);
                 if (!j->level0)
                         return -ENOMEM;
         }
 
         if (!j->level1) {
-                j->level1 = match_new(j->level0, MATCH_AND_TERM);
+                j->level1 = match_new(j->level0, MATCH_OR_TERM);
                 if (!j->level1)
                         return -ENOMEM;
         }
 
-        assert(j->level0->type == MATCH_OR_TERM);
-        assert(j->level1->type == MATCH_AND_TERM);
+        if (!j->level2) {
+                j->level2 = match_new(j->level1, MATCH_AND_TERM);
+                if (!j->level2)
+                        return -ENOMEM;
+        }
+
+        assert(j->level0->type == MATCH_AND_TERM);
+        assert(j->level1->type == MATCH_OR_TERM);
+        assert(j->level2->type == MATCH_AND_TERM);
 
         le_hash = htole64(hash64(data, size));
 
-        LIST_FOREACH(matches, l2, j->level1->matches) {
-                assert(l2->type == MATCH_OR_TERM);
+        LIST_FOREACH(matches, l3, j->level2->matches) {
+                assert(l3->type == MATCH_OR_TERM);
 
-                LIST_FOREACH(matches, l3, l2->matches) {
-                        assert(l3->type == MATCH_DISCRETE);
+                LIST_FOREACH(matches, l4, l3->matches) {
+                        assert(l4->type == MATCH_DISCRETE);
 
                         /* Exactly the same match already? Then ignore
                          * this addition */
-                        if (l3->le_hash == le_hash &&
-                            l3->size == size &&
-                            memcmp(l3->data, data, size) == 0)
+                        if (l4->le_hash == le_hash &&
+                            l4->size == size &&
+                            memcmp(l4->data, data, size) == 0)
                                 return 0;
 
                         /* Same field? Then let's add this to this OR term */
-                        if (same_field(data, size, l3->data, l3->size)) {
-                                add_here = l2;
+                        if (same_field(data, size, l4->data, l4->size)) {
+                                add_here = l3;
                                 break;
                         }
                 }
@@ -265,7 +273,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)
         }
 
         if (!add_here) {
-                add_here = match_new(j->level1, MATCH_OR_TERM);
+                add_here = match_new(j->level2, MATCH_OR_TERM);
                 if (!add_here)
                         goto fail;
         }
@@ -288,6 +296,9 @@ 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);
 
@@ -297,9 +308,7 @@ fail:
         return -ENOMEM;
 }
 
-_public_ int sd_journal_add_disjunction(sd_journal *j) {
-        Match *m;
-
+_public_ int sd_journal_add_conjunction(sd_journal *j) {
         assert(j);
 
         if (!j->level0)
@@ -311,11 +320,28 @@ _public_ int sd_journal_add_disjunction(sd_journal *j) {
         if (!j->level1->matches)
                 return 0;
 
-        m = match_new(j->level0, MATCH_AND_TERM);
-        if (!m)
-                return -ENOMEM;
+        j->level1 = NULL;
+        j->level2 = NULL;
+
+        return 0;
+}
+
+_public_ int sd_journal_add_disjunction(sd_journal *j) {
+        assert(j);
+
+        if (!j->level0)
+                return 0;
+
+        if (!j->level1)
+                return 0;
+
+        if (!j->level2)
+                return 0;
+
+        if (!j->level2->matches)
+                return 0;
 
-        j->level1 = m;
+        j->level2 = NULL;
         return 0;
 }
 
@@ -380,7 +406,7 @@ _public_ void sd_journal_flush_matches(sd_journal *j) {
         if (j->level0)
                 match_free(j->level0);
 
-        j->level0 = j->level1 = NULL;
+        j->level0 = j->level1 = j->level2 = NULL;
 
         detach_location(j);
 }
@@ -602,7 +628,7 @@ static int next_for_match(
                                         return r;
 
                                 if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) &&
-                                    (np == 0 || (direction == DIRECTION_DOWN ? cp > np : np < cp))) {
+                                    (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np))) {
                                         np = cp;
                                         continue_looking = true;
                                 }
@@ -1222,11 +1248,11 @@ static void check_network(sd_journal *j, int fd) {
                 return;
 
         j->on_network =
-                (long)sfs.f_type == (long)CIFS_MAGIC_NUMBER ||
-                sfs.f_type == CODA_SUPER_MAGIC ||
-                sfs.f_type == NCP_SUPER_MAGIC ||
-                sfs.f_type == NFS_SUPER_MAGIC ||
-                sfs.f_type == SMB_SUPER_MAGIC;
+                F_TYPE_CMP(sfs.f_type, CIFS_MAGIC_NUMBER) ||
+                F_TYPE_CMP(sfs.f_type, CODA_SUPER_MAGIC) ||
+                F_TYPE_CMP(sfs.f_type, NCP_SUPER_MAGIC) ||
+                F_TYPE_CMP(sfs.f_type, NFS_SUPER_MAGIC) ||
+                F_TYPE_CMP(sfs.f_type, SMB_SUPER_MAGIC);
 }
 
 static int add_file(sd_journal *j, const char *prefix, const char *filename) {
@@ -1981,6 +2007,43 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
         return j->inotify_fd;
 }
 
+_public_ int sd_journal_get_events(sd_journal *j) {
+        int fd;
+
+        if (!j)
+                return -EINVAL;
+
+        fd = sd_journal_get_fd(j);
+        if (fd < 0)
+                return fd;
+
+        return POLLIN;
+}
+
+_public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {
+        int fd;
+
+        if (!j)
+                return -EINVAL;
+        if (!timeout_usec)
+                return -EINVAL;
+
+        fd = sd_journal_get_fd(j);
+        if (fd < 0)
+                return fd;
+
+        if (!j->on_network) {
+                *timeout_usec = (uint64_t) -1;
+                return 0;
+        }
+
+        /* If we are on the network we need to regularly check for
+         * changes manually */
+
+        *timeout_usec = j->last_process_usec + JOURNAL_FILES_RECHECK_USEC;
+        return 1;
+}
+
 static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
         Directory *d;
         int r;
@@ -2063,6 +2126,8 @@ _public_ int sd_journal_process(sd_journal *j) {
         if (!j)
                 return -EINVAL;
 
+        j->last_process_usec = now(CLOCK_MONOTONIC);
+
         for (;;) {
                 struct inotify_event *e;
                 ssize_t l;
@@ -2096,6 +2161,7 @@ _public_ int sd_journal_process(sd_journal *j) {
 
 _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
         int r;
+        uint64_t t;
 
         assert(j);
 
@@ -2114,12 +2180,18 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
                 return determine_change(j);
         }
 
-        if (j->on_network) {
-                /* If we are on the network we need to regularly check
-                 * for changes manually */
+        r = sd_journal_get_timeout(j, &t);
+        if (r < 0)
+                return r;
+
+        if (t != (uint64_t) -1) {
+                usec_t n;
+
+                n = now(CLOCK_MONOTONIC);
+                t = t > n ? t - n : 0;
 
-                if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC)
-                        timeout_usec = JOURNAL_FILES_RECHECK_USEC;
+                if (timeout_usec == (uint64_t) -1 || timeout_usec > t)
+                        timeout_usec = t;
         }
 
         do {