]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-journal/sd-journal.c
nulstr-util: Declare NULSTR_FOREACH() iterator inline
[thirdparty/systemd.git] / src / libsystemd / sd-journal / sd-journal.c
index 77d03ec95ff3c67399c2e7ada025da28afc8dbba..aa90d873a5741a10aefb2c2bd3d6ed2112b7cb59 100644 (file)
@@ -147,7 +147,7 @@ static void set_location(sd_journal *j, JournalFile *f, Object *o) {
 }
 
 static int match_is_valid(const void *data, size_t size) {
-        assert(data);
+        const char *b = ASSERT_PTR(data);
 
         if (size < 2)
                 return false;
@@ -155,7 +155,6 @@ static int match_is_valid(const void *data, size_t size) {
         if (((char*) data)[0] == '_' && ((char*) data)[1] == '_')
                 return false;
 
-        const char *b = data;
         for (const char *p = b; p < b + size; p++) {
 
                 if (*p == '=')
@@ -1829,7 +1828,6 @@ static int add_search_paths(sd_journal *j) {
         static const char search_paths[] =
                 "/run/log/journal\0"
                 "/var/log/journal\0";
-        const char *p;
 
         assert(j);
 
@@ -2265,8 +2263,8 @@ static bool field_is_valid(const char *field) {
 _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
         JournalFile *f;
         size_t field_length;
-        int r;
         Object *o;
+        int r;
 
         assert_return(j, -EINVAL);
         assert_return(!journal_pid_changed(j), -ECHILD);
@@ -2288,131 +2286,36 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
 
         field_length = strlen(field);
 
-        uint64_t n = journal_file_entry_n_items(o);
+        uint64_t n = journal_file_entry_n_items(f, o);
         for (uint64_t i = 0; i < n; i++) {
-                Object *d;
-                uint64_t p, l;
-                size_t t;
-                Compression c;
+                uint64_t p;
+                void *d;
+                size_t l;
 
-                p = le64toh(o->entry.items[i].object_offset);
-                r = journal_file_move_to_object(f, OBJECT_DATA, p, &d);
+                p = journal_file_entry_item_object_offset(f, o, i);
+                r = journal_file_data_payload(f, NULL, p, field, field_length, j->data_threshold, &d, &l);
+                if (r == 0)
+                        goto next;
                 if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                         log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
-                        continue;
+                        goto next;
                 }
                 if (r < 0)
                         return r;
 
-                l = le64toh(d->object.size) - offsetof(Object, data.payload);
-
-                c = COMPRESSION_FROM_OBJECT(d);
-                if (c < 0)
-                        return -EPROTONOSUPPORT;
-                if (c != COMPRESSION_NONE) {
-#if HAVE_COMPRESSION
-                        r = decompress_startswith(
-                                        c,
-                                        d->data.payload, l,
-                                        &f->compress_buffer,
-                                        field, field_length, '=');
-                        if (r < 0)
-                                log_debug_errno(r, "Cannot decompress %s object of length %"PRIu64" at offset "OFSfmt": %m",
-                                                compression_to_string(c), l, p);
-                        else if (r > 0) {
-
-                                size_t rsize;
-
-                                r = decompress_blob(
-                                                c,
-                                                d->data.payload, l,
-                                                &f->compress_buffer, &rsize,
-                                                j->data_threshold);
-                                if (r < 0)
-                                        return r;
-
-                                *data = f->compress_buffer;
-                                *size = (size_t) rsize;
-
-                                return 0;
-                        }
-#else
-                        return -EPROTONOSUPPORT;
-#endif
-                } else if (l >= field_length+1 &&
-                           memcmp(d->data.payload, field, field_length) == 0 &&
-                           d->data.payload[field_length] == '=') {
-
-                        t = (size_t) l;
-
-                        if ((uint64_t) t != l)
-                                return -E2BIG;
-
-                        *data = d->data.payload;
-                        *size = t;
-
-                        return 0;
-                }
-        }
-
-        return -ENOENT;
-}
-
-static int return_data(
-                sd_journal *j,
-                JournalFile *f,
-                Object *o,
-                const void **ret_data,
-                size_t *ret_size) {
+                *data = d;
+                *size = l;
 
-        Compression c;
-        uint64_t l;
-        size_t t;
-
-        assert(j);
-        assert(f);
-
-        l = le64toh(READ_NOW(o->object.size));
-        if (l < offsetof(Object, data.payload))
-                return -EBADMSG;
-        l -= offsetof(Object, data.payload);
-
-        /* We can't read objects larger than 4G on a 32bit machine */
-        t = (size_t) l;
-        if ((uint64_t) t != l)
-                return -E2BIG;
-
-        c = COMPRESSION_FROM_OBJECT(o);
-        if (c < 0)
-                return -EPROTONOSUPPORT;
-        if (c != COMPRESSION_NONE) {
-#if HAVE_COMPRESSION
-                size_t rsize;
-                int r;
+                return 0;
 
-                r = decompress_blob(
-                                c,
-                                o->data.payload, l,
-                                &f->compress_buffer, &rsize,
-                                j->data_threshold);
+        next:
+                /* journal_file_data_payload() may clear or overwrite cached object. */
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
                 if (r < 0)
                         return r;
-
-                if (ret_data)
-                        *ret_data = f->compress_buffer;
-                if (ret_size)
-                        *ret_size = (size_t) rsize;
-#else
-                return -EPROTONOSUPPORT;
-#endif
-        } else {
-                if (ret_data)
-                        *ret_data = o->data.payload;
-                if (ret_size)
-                        *ret_size = t;
         }
 
-        return 0;
+        return -ENOENT;
 }
 
 _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
@@ -2436,29 +2339,33 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
         if (r < 0)
                 return r;
 
-        for (uint64_t n = journal_file_entry_n_items(o); j->current_field < n; j->current_field++) {
+        for (uint64_t n = journal_file_entry_n_items(f, o); j->current_field < n; j->current_field++) {
                 uint64_t p;
+                void *d;
+                size_t l;
 
-                p = le64toh(o->entry.items[j->current_field].object_offset);
-                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                p = journal_file_entry_item_object_offset(f, o, j->current_field);
+                r = journal_file_data_payload(f, NULL, p, NULL, 0, j->data_threshold, &d, &l);
                 if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                         log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", j->current_field);
-                        continue;
+                        goto next;
                 }
                 if (r < 0)
                         return r;
+                assert(r > 0);
 
-                r = return_data(j, f, o, data, size);
-                if (r == -EBADMSG) {
-                        log_debug("Entry item %"PRIu64" data payload is bad, skipping over it.", j->current_field);
-                        continue;
-                }
-                if (r < 0)
-                        return r;
+                *data = d;
+                *size = l;
 
                 j->current_field++;
 
                 return 1;
+
+        next:
+                /* journal_file_data_payload() may clear or overwrite cached object. */
+                r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+                if (r < 0)
+                        return r;
         }
 
         return 0;
@@ -2926,7 +2833,7 @@ _public_ int sd_journal_enumerate_unique(
         for (;;) {
                 JournalFile *of;
                 Object *o;
-                const void *odata;
+                void *odata;
                 size_t ol;
                 bool found;
                 int r;
@@ -2970,7 +2877,8 @@ _public_ int sd_journal_enumerate_unique(
                                                j->unique_offset,
                                                o->object.type, OBJECT_DATA);
 
-                r = return_data(j, j->unique_file, o, &odata, &ol);
+                r = journal_file_data_payload(j->unique_file, o, j->unique_offset, NULL, 0,
+                                              j->data_threshold, &odata, &ol);
                 if (r < 0)
                         return r;
 
@@ -3017,9 +2925,8 @@ _public_ int sd_journal_enumerate_unique(
                 if (found)
                         continue;
 
-                r = return_data(j, j->unique_file, o, ret_data, ret_size);
-                if (r < 0)
-                        return r;
+                *ret_data = odata;
+                *ret_size = ol;
 
                 return 1;
         }
@@ -3208,13 +3115,12 @@ _public_ int sd_journal_reliable_fd(sd_journal *j) {
 }
 
 static char *lookup_field(const char *field, void *userdata) {
-        sd_journal *j = userdata;
+        sd_journal *j = ASSERT_PTR(userdata);
         const void *data;
         size_t size, d;
         int r;
 
         assert(field);
-        assert(j);
 
         r = sd_journal_get_data(j, field, &data, &size);
         if (r < 0 ||