sd-journal.c revision 7827b1a10f4dfe2c6771b515f28f7ae22e0ae039
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2011 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <fcntl.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stddef.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/inotify.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/poll.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include "sd-journal.h"
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include "journal-def.h"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering#include "journal-file.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "hashmap.h"
eef46c372f64f40dd75415b2c504c73138719c8dLennart Poettering#include "list.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "path-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "lookup3.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "compress.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "journal-internal.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering#define JOURNAL_FILES_MAX 1024
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic void detach_location(sd_journal *j) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Iterator i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering JournalFile *f;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(j);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering j->current_file = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering j->current_field = 0;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering HASHMAP_FOREACH(f, j->files, i)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering f->current_offset = 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void reset_location(sd_journal *j) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(j);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering detach_location(j);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering zero(j->current_location);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void init_location(Location *l, JournalFile *f, Object *o) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(l);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering assert(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(o->object.type == OBJECT_ENTRY);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering l->type = LOCATION_DISCRETE;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering l->seqnum = le64toh(o->entry.seqnum);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering l->seqnum_id = f->header->seqnum_id;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering l->realtime = le64toh(o->entry.realtime);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering l->monotonic = le64toh(o->entry.monotonic);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering l->boot_id = o->entry.boot_id;
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering l->xor_hash = le64toh(o->entry.xor_hash);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void set_location(sd_journal *j, JournalFile *f, Object *o, uint64_t offset) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(j);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(o);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering init_location(&j->current_location, f, o);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering j->current_file = f;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering j->current_field = 0;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering f->current_offset = offset;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering}
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic int match_is_valid(const void *data, size_t size) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering const char *b, *p;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering assert(data);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (size < 2)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return false;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (startswith(data, "__"))
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return false;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering b = data;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering for (p = b; p < b + size; p++) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (*p == '=')
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return p > b;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (*p == '_')
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering continue;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (*p >= 'A' && *p <= 'Z')
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering continue;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (*p >= '0' && *p <= '9')
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering continue;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return false;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return false;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic bool same_field(const void *_a, size_t s, const void *_b, size_t t) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const uint8_t *a = _a, *b = _b;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering size_t j;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < s && j < t; j++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (a[j] != b[j])
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (a[j] == '=')
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return true;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return true;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic Match *match_new(Match *p, MatchType t) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Match *m;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen m = new0(Match, 1);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (!m)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering m->type = t;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (p) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering m->parent = p;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_PREPEND(Match, matches, p->matches, m);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return m;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void match_free(Match *m) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(m);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering while (m->matches)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering match_free(m->matches);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (m->parent)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering LIST_REMOVE(Match, matches, m->parent->matches, m);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(m->data);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(m);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic void match_free_if_empty(Match *m) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(m);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (m->matches)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen match_free(m);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Match *l2, *l3, *add_here = NULL, *m;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering le64_t le_hash;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!j)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EINVAL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!data)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EINVAL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (size == 0)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering size = strlen(data);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!match_is_valid(data, size))
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EINVAL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* level 0: OR term
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering * level 1: AND terms
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen * level 2: OR terms
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering * level 3: concrete matches */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!j->level0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering j->level0 = match_new(NULL, MATCH_OR_TERM);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!j->level0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -ENOMEM;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!j->level1) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering j->level1 = match_new(j->level0, MATCH_AND_TERM);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!j->level1)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -ENOMEM;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(j->level0->type == MATCH_OR_TERM);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(j->level1->type == MATCH_AND_TERM);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering le_hash = htole64(hash64(data, size));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LIST_FOREACH(matches, l2, j->level1->matches) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(l2->type == MATCH_OR_TERM);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LIST_FOREACH(matches, l3, l2->matches) {
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering assert(l3->type == MATCH_DISCRETE);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* Exactly the same match already? Then ignore
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * this addition */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (l3->le_hash == le_hash &&
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering l3->size == size &&
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering memcmp(l3->data, data, size) == 0)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering /* Same field? Then let's add this to this OR term */
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (same_field(data, size, l3->data, l3->size)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering add_here = l2;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering break;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (add_here)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering break;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!add_here) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering add_here = match_new(j->level1, MATCH_OR_TERM);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!add_here)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto fail;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering m = match_new(add_here, MATCH_DISCRETE);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!m)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto fail;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering m->le_hash = le_hash;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering m->size = size;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering m->data = memdup(data, size);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!m->data)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto fail;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering detach_location(j);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringfail:
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (add_here)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering match_free_if_empty(add_here);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (j->level1)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering match_free_if_empty(j->level1);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (j->level0)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering match_free_if_empty(j->level0);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return -ENOMEM;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering_public_ int sd_journal_add_disjunction(sd_journal *j) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering Match *m;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(j);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!j->level0)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!j->level1)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!j->level1->matches)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering m = match_new(j->level0, MATCH_AND_TERM);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!m)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -ENOMEM;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering j->level1 = m;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic char *match_make_string(Match *m) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char *p, *r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering Match *i;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bool enclose = false;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!m)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return strdup("");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (m->type == MATCH_DISCRETE)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return strndup(m->data, m->size);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering p = NULL;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering LIST_FOREACH(matches, i, m->matches) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering char *t, *k;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering t = match_make_string(i);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!t) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering free(p);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (p) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering free(p);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering free(t);
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!k)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return NULL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering p = k;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering enclose = true;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } else {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering free(p);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering p = t;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (enclose) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = strjoin("(", p, ")", NULL);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering free(p);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return p;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringchar *journal_make_match_string(sd_journal *j) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering assert(j);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return match_make_string(j->level0);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering_public_ void sd_journal_flush_matches(sd_journal *j) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (!j)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (j->level0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering match_free(j->level0);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering j->level0 = j->level1 = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering detach_location(j);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int compare_order(JournalFile *af, Object *ao,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering JournalFile *bf, Object *bo) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering uint64_t a, b;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(af);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(ao);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert(bf);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert(bo);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering /* We operate on two different files here, hence we can access
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering * two objects at the same time, which we normally can't.
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering *
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering * If contents and timestamps match, these entries are
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering * identical, even if the seqnum does not match */
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) &&
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ao->entry.monotonic == bo->entry.monotonic &&
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ao->entry.realtime == bo->entry.realtime &&
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering ao->entry.xor_hash == bo->entry.xor_hash)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* If this is from the same seqnum source, compare
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * seqnums */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering a = le64toh(ao->entry.seqnum);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering b = le64toh(bo->entry.seqnum);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a < b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a > b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* Wow! This is weird, different data but the same
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * seqnums? Something is borked, but let's make the
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * best of it and compare by time. */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* If the boot id matches compare monotonic time */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering a = le64toh(ao->entry.monotonic);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering b = le64toh(bo->entry.monotonic);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a < b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -1;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (a > b)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return 1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* Otherwise compare UTC time */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering a = le64toh(ao->entry.realtime);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering b = le64toh(bo->entry.realtime);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a < b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a > b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* Finally, compare by contents */
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering a = le64toh(ao->entry.xor_hash);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering b = le64toh(bo->entry.xor_hash);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (a < b)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (a > b)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int compare_with_location(JournalFile *af, Object *ao, Location *l) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering uint64_t a;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(af);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(ao);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(l);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(l->type == LOCATION_DISCRETE);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (l->monotonic_set &&
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering sd_id128_equal(ao->entry.boot_id, l->boot_id) &&
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering l->realtime_set &&
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering le64toh(ao->entry.realtime) == l->realtime &&
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering l->xor_hash_set &&
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering le64toh(ao->entry.xor_hash) == l->xor_hash)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (l->seqnum_set &&
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering sd_id128_equal(af->header->seqnum_id, l->seqnum_id)) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering a = le64toh(ao->entry.seqnum);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a < l->seqnum)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a > l->seqnum)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (l->monotonic_set &&
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering sd_id128_equal(ao->entry.boot_id, l->boot_id)) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering a = le64toh(ao->entry.monotonic);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a < l->monotonic)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a > l->monotonic)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (l->realtime_set) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering a = le64toh(ao->entry.realtime);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a < l->realtime)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a > l->realtime)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (l->xor_hash_set) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering a = le64toh(ao->entry.xor_hash);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a < l->xor_hash)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (a > l->xor_hash)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return 0;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers}
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int next_for_match(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_journal *j,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering Match *m,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering JournalFile *f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering uint64_t after_offset,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering direction_t direction,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Object **ret,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen uint64_t *offset) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering uint64_t np = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering Object *n;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(j);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->type == MATCH_DISCRETE) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t dp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r <= 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return r;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return journal_file_move_to_entry_by_offset_for_data(f, dp, after_offset, direction, ret, offset);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (m->type == MATCH_OR_TERM) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Match *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Find the earliest match beyond after_offset */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_FOREACH(matches, i, m->matches) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t cp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = next_for_match(j, i, f, after_offset, direction, NULL, &cp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (r > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering np = cp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (m->type == MATCH_AND_TERM) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Match *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bool continue_looking;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Always jump to the next matching entry and repeat
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * this until we fine and offset that matches for all
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * matches. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!m->matches)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering np = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering do {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering continue_looking = false;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering LIST_FOREACH(matches, i, m->matches) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering uint64_t cp, limit;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (np == 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering limit = after_offset;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering else if (direction == DIRECTION_DOWN)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering limit = MAX(np, after_offset);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering else
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering limit = MIN(np, after_offset);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = next_for_match(j, i, f, limit, direction, NULL, &cp);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r <= 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) &&
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering (np == 0 || (direction == DIRECTION_DOWN ? cp > np : np < cp))) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering np = cp;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering continue_looking = true;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering } while (continue_looking);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (np == 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return r;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (ret)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering *ret = n;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (offset)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering *offset = np;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return 1;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering}
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic int find_location_for_match(
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering sd_journal *j,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering Match *m,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering JournalFile *f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering direction_t direction,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering Object **ret,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t *offset) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(j);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(m);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(f);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (m->type == MATCH_DISCRETE) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering uint64_t dp;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), NULL, &dp);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r <= 0)
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek return r;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering /* FIXME: missing: find by monotonic */
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (j->current_location.type == LOCATION_HEAD)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_DOWN, ret, offset);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (j->current_location.type == LOCATION_TAIL)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_UP, ret, offset);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return journal_file_move_to_entry_by_seqnum_for_data(f, dp, j->current_location.seqnum, direction, ret, offset);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (j->current_location.monotonic_set) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = journal_file_move_to_entry_by_monotonic_for_data(f, dp, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
a6c616024db23fef34152c1432892824a07799ccLennart Poettering if (r != -ENOENT)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (j->current_location.realtime_set)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return journal_file_move_to_entry_by_realtime_for_data(f, dp, j->current_location.realtime, direction, ret, offset);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return journal_file_next_entry_for_data(f, NULL, 0, dp, direction, ret, offset);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering } else if (m->type == MATCH_OR_TERM) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering uint64_t np = 0;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering Object *n;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering Match *i;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* Find the earliest match */
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
a6c616024db23fef34152c1432892824a07799ccLennart Poettering LIST_FOREACH(matches, i, m->matches) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen uint64_t cp;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = find_location_for_match(j, i, f, direction, NULL, &cp);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (r > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp))
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers np = cp;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (np == 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return 0;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (ret)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers *ret = n;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (offset)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers *offset = np;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return 1;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers } else {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering Match *i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t np = 0;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(m->type == MATCH_AND_TERM);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* First jump to the last match, and then find the
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * next one where all matches match */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (!m->matches)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering LIST_FOREACH(matches, i, m->matches) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers uint64_t cp;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = find_location_for_match(j, i, f, direction, NULL, &cp);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (r <= 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (np == 0 || (direction == DIRECTION_DOWN ? np < cp : np > cp))
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt np = cp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return next_for_match(j, m, f, np, direction, ret, offset);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int find_location_with_matches(
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_journal *j,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers JournalFile *f,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering direction_t direction,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering Object **ret,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t *offset) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(j);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(ret);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(offset);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (!j->level0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* No matches is simple */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni if (j->current_location.type == LOCATION_HEAD)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, ret, offset);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (j->current_location.type == LOCATION_TAIL)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return journal_file_next_entry(f, NULL, 0, DIRECTION_UP, ret, offset);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, ret, offset);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (j->current_location.monotonic_set) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r != -ENOENT)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (j->current_location.realtime_set)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, ret, offset);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return journal_file_next_entry(f, NULL, 0, direction, ret, offset);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering } else
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return find_location_for_match(j, j->level0, f, direction, ret, offset);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int next_with_matches(
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen sd_journal *j,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen JournalFile *f,
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering direction_t direction,
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering Object **ret,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t *offset) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering Object *c;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers uint64_t cp;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(j);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(f);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(ret);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(offset);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering c = *ret;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering cp = *offset;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* No matches is easy. We simple advance the file
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * pointer by one. */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!j->level0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return journal_file_next_entry(f, c, cp, direction, ret, offset);
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering /* If we have a match then we look for the next matching entry
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering * with an offset at least one step larger */
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return next_for_match(j, j->level0, f, direction == DIRECTION_DOWN ? cp+1 : cp-1, direction, ret, offset);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering Object *c;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t cp;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering int r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(j);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(f);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (f->current_offset > 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering cp = f->current_offset;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
9a14fb6285bdb089d4fc195410de3362cb4f586fThomas Hindoe Paaboel Andersen
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = next_with_matches(j, f, direction, &c, &cp);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r <= 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } else {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = find_location_with_matches(j, f, direction, &c, &cp);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r <= 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* OK, we found the spot, now let's advance until to an entry
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * that is actually different from what we were previously
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * looking at. This is necessary to handle entries which exist
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * in two (or more) journal files, and which shall all be
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * suppressed but one. */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering for (;;) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bool found;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (j->current_location.type == LOCATION_DISCRETE) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering int k;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering k = compare_with_location(f, c, &j->current_location);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (direction == DIRECTION_DOWN)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering found = k > 0;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering else
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering found = k < 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering } else
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering found = true;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering if (found) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (ret)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering *ret = c;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (offset)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering *offset = cp;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return 1;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = next_with_matches(j, f, direction, &c, &cp);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r <= 0)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int real_journal_next(sd_journal *j, direction_t direction) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering JournalFile *f, *new_current = NULL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering Iterator i;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering int r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering uint64_t new_offset = 0;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering Object *new_entry = NULL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering if (!j)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering HASHMAP_FOREACH(f, j->files, i) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering Object *o;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t p;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bool found;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = next_beyond_location(j, f, direction, &o, &p);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r));
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering continue;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } else if (r == 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering continue;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!new_current)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering found = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int k;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering k = compare_order(f, o, new_current, new_entry);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (direction == DIRECTION_DOWN)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering found = k < 0;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering found = k > 0;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (found) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering new_current = f;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering new_entry = o;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering new_offset = p;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering }
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (!new_current)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return 0;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering set_location(j, new_current, new_entry, new_offset);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return 1;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering_public_ int sd_journal_next(sd_journal *j) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return real_journal_next(j, DIRECTION_DOWN);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering_public_ int sd_journal_previous(sd_journal *j) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return real_journal_next(j, DIRECTION_UP);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poetteringstatic int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering int c = 0, r;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (!j)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return -EINVAL;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (skip == 0) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering /* If this is not a discrete skip, then at least
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering * resolve the current location */
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (j->current_location.type != LOCATION_DISCRETE)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return real_journal_next(j, direction);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return 0;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering }
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering do {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = real_journal_next(j, direction);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (r < 0)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return r;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (r == 0)
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return c;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering skip--;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering c++;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering } while (skip > 0);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return c;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering_public_ int sd_journal_next_skip(sd_journal *j, uint64_t skip) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return real_journal_next_skip(j, DIRECTION_DOWN, skip);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering_public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return real_journal_next_skip(j, DIRECTION_UP, skip);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering Object *o;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char bid[33], sid[33];
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!j)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!cursor)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!j->current_file || j->current_file->current_offset <= 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EADDRNOTAVAIL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_id128_to_string(j->current_file->header->seqnum_id, sid);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_id128_to_string(o->entry.boot_id, bid);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (asprintf(cursor,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx;p=%s",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sid, (unsigned long long) le64toh(o->entry.seqnum),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bid, (unsigned long long) le64toh(o->entry.monotonic),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering (unsigned long long) le64toh(o->entry.realtime),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering (unsigned long long) le64toh(o->entry.xor_hash),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering path_get_file_name(j->current_file->path)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 1;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char *w;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering size_t l;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering char *state;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering unsigned long long seqnum, monotonic, realtime, xor_hash;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering bool
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering seqnum_id_set = false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering seqnum_set = false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering boot_id_set = false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering monotonic_set = false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering realtime_set = false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering xor_hash_set = false;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_id128_t seqnum_id, boot_id;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!j)
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering return -EINVAL;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering if (!cursor)
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering return -EINVAL;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering char *item;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering int k = 0;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (l < 2 || w[1] != '=')
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering item = strndup(w, l);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (!item)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering switch (w[0]) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 's':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering seqnum_id_set = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering k = sd_id128_from_string(w+2, &seqnum_id);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'i':
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers seqnum_set = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (sscanf(w+2, "%llx", &seqnum) != 1)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering break;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering case 'b':
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering boot_id_set = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = sd_id128_from_string(w+2, &boot_id);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering case 'm':
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering monotonic_set = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (sscanf(w+2, "%llx", &monotonic) != 1)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k = -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen case 't':
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering realtime_set = true;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (sscanf(w+2, "%llx", &realtime) != 1)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering k = -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering break;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering case 'x':
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering xor_hash_set = true;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (sscanf(w+2, "%llx", &xor_hash) != 1)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen k = -EINVAL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(item);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (k < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering if ((!seqnum_set || !seqnum_id_set) &&
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering (!monotonic_set || !boot_id_set) &&
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering !realtime_set)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return -EINVAL;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering reset_location(j);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering j->current_location.type = LOCATION_DISCRETE;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (realtime_set) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering j->current_location.realtime = (uint64_t) realtime;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering j->current_location.realtime_set = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (seqnum_set && seqnum_id_set) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering j->current_location.seqnum = (uint64_t) seqnum;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering j->current_location.seqnum_id = seqnum_id;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering j->current_location.seqnum_set = true;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (monotonic_set && boot_id_set) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering j->current_location.monotonic = (uint64_t) monotonic;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering j->current_location.boot_id = boot_id;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering j->current_location.monotonic_set = true;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (xor_hash_set) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering j->current_location.xor_hash = (uint64_t) xor_hash;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering j->current_location.xor_hash_set = true;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 0;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering}
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (!j)
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering return -EINVAL;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering reset_location(j);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering j->current_location.type = LOCATION_DISCRETE;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering j->current_location.boot_id = boot_id;
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering j->current_location.monotonic = usec;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering j->current_location.monotonic_set = true;
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering if (!j)
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering return -EINVAL;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering reset_location(j);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering j->current_location.type = LOCATION_DISCRETE;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering j->current_location.realtime = usec;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering j->current_location.realtime_set = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering_public_ int sd_journal_seek_head(sd_journal *j) {
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering if (!j)
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering return -EINVAL;
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering reset_location(j);
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering j->current_location.type = LOCATION_HEAD;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
0370612e0522191f929e3feb7d4937fff3d421e2Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering_public_ int sd_journal_seek_tail(sd_journal *j) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (!j)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EINVAL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering reset_location(j);
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering j->current_location.type = LOCATION_TAIL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int add_file(sd_journal *j, const char *prefix, const char *filename) {
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering char *path;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering int r;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering JournalFile *f;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering assert(j);
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering assert(prefix);
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering assert(filename);
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) &&
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering !(streq(filename, "system.journal") ||
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering (startswith(filename, "system@") && endswith(filename, ".journal"))))
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering return 0;
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering path = strjoin(prefix, "/", filename, NULL);
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering if (!path)
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering return -ENOMEM;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering if (hashmap_get(j->files, path)) {
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering free(path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
90adaa25e894a580930ef2c3e65ab8db8295515aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_debug("Too many open journal files, not adding %s, ignoring.", path);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering free(path);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return 0;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = journal_file_open(path, O_RDONLY, 0, NULL, NULL, &f);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering free(path);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (r < 0) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (errno == ENOENT)
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return 0;
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering return r;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering /* journal_file_dump(f); */
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = hashmap_put(j->files, f->path, f);
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering if (r < 0) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering journal_file_close(f);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return r;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering j->current_invalidate_counter ++;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering log_debug("File %s got added.", f->path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering}
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int remove_file(sd_journal *j, const char *prefix, const char *filename) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering char *path;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering JournalFile *f;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(j);
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering assert(prefix);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(filename);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering path = strjoin(prefix, "/", filename, NULL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!path)
bf441e3d9371a7e5aa1def66cfc40f0118884644Lennart Poettering return -ENOMEM;
de33fc625725d199629ed074d6278504deb23debLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering f = hashmap_get(j->files, path);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering free(path);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!f)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering hashmap_remove(j->files, f->path);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering journal_file_close(f);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt j->current_invalidate_counter ++;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_debug("File %s got removed.", f->path);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return 0;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt}
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poetteringstatic int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering char *path;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering int r;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering DIR *d;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering sd_id128_t id, mid;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering Directory *m;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(j);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(prefix);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(dirname);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering (sd_id128_from_string(dirname, &id) < 0 ||
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering sd_id128_get_machine(&mid) < 0 ||
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering !sd_id128_equal(id, mid)))
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering return 0;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering path = strjoin(prefix, "/", dirname, NULL);
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering if (!path)
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering return -ENOMEM;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering d = opendir(path);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering if (!d) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering log_debug("Failed to open %s: %m", path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering free(path);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (errno == ENOENT)
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering return 0;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering return -errno;
ee451d766a64117a41ec36dd71e61683c9d9b83cLennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
813c65c34beae2eed1f93d9317f97d7e806389f5Lennart Poettering m = hashmap_get(j->directories_by_path, path);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!m) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering m = new0(Directory, 1);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!m) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering closedir(d);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering free(path);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return -ENOMEM;
9c857b9d160c10b4454fc9f83442c1878343422fLennart Poettering }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt m->is_root = false;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering m->path = path;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt closedir(d);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering free(m->path);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering free(m);
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering return -ENOMEM;
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering j->current_invalidate_counter ++;
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering log_debug("Directory %s got added.", m->path);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering } else if (m->is_root) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering free (path);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering closedir(d);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering } else
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering free(path);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (m->wd <= 0 && j->inotify_fd >= 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering m->wd = inotify_add_watch(j->inotify_fd, m->path,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering IN_DONT_FOLLOW|IN_ONLYDIR);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering inotify_rm_watch(j->inotify_fd, m->wd);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering }
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering for (;;) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering struct dirent buf, *de;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = readdir_r(d, &buf, &de);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (r != 0 || !de)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering break;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (dirent_is_file_with_suffix(de, ".journal")) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = add_file(j, m->path, de->d_name);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (r < 0)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering closedir(d);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering return 0;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering}
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringstatic int add_root_directory(sd_journal *j, const char *p) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering DIR *d;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering Directory *m;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering int r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering assert(j);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering assert(p);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if ((j->flags & SD_JOURNAL_RUNTIME_ONLY) &&
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering !path_startswith(p, "/run"))
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return -EINVAL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering d = opendir(p);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (!d)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return -errno;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering m = hashmap_get(j->directories_by_path, p);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (!m) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering m = new0(Directory, 1);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (!m) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering closedir(d);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return -ENOMEM;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering m->is_root = true;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering m->path = strdup(p);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (!m->path) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering closedir(d);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering free(m);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering return -ENOMEM;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering closedir(d);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering free(m->path);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering free(m);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return -ENOMEM;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering j->current_invalidate_counter ++;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering log_debug("Root directory %s got added.", m->path);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering } else if (!m->is_root) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering closedir(d);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return 0;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (m->wd <= 0 && j->inotify_fd >= 0) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering m->wd = inotify_add_watch(j->inotify_fd, m->path,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering IN_DONT_FOLLOW|IN_ONLYDIR);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering inotify_rm_watch(j->inotify_fd, m->wd);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering for (;;) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering struct dirent buf, *de;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering sd_id128_t id;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering r = readdir_r(d, &buf, &de);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r != 0 || !de)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering break;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (dirent_is_file_with_suffix(de, ".journal")) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = add_file(j, m->path, de->d_name);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r));
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering } else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) &&
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering sd_id128_from_string(de->d_name, &id) >= 0) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = add_directory(j, m->path, de->d_name);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering log_debug("Failed to add directory %s/%s: %s", m->path, de->d_name, strerror(-r));
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering closedir(d);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return 0;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering}
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poetteringstatic int remove_directory(sd_journal *j, Directory *d) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering assert(j);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (d->wd > 0) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering hashmap_remove(j->directories_by_wd, INT_TO_PTR(d->wd));
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (j->inotify_fd >= 0)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering inotify_rm_watch(j->inotify_fd, d->wd);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering hashmap_remove(j->directories_by_path, d->path);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (d->is_root)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering log_debug("Root directory %s got removed.", d->path);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering else
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering log_debug("Directory %s got removed.", d->path);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering free(d->path);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering free(d);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return 0;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering}
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poetteringstatic int add_search_paths(sd_journal *j) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering const char search_paths[] =
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering "/run/log/journal\0"
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering "/var/log/journal\0";
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering const char *p;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering assert(j);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering /* We ignore most errors here, since the idea is to only open
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering * what's actually accessible, and ignore the rest. */
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering NULSTR_FOREACH(p, search_paths)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering add_root_directory(j, p);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return 0;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering}
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poetteringstatic int allocate_inotify(sd_journal *j) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering assert(j);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (j->inotify_fd < 0) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering j->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (j->inotify_fd < 0)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return -errno;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j->directories_by_wd) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering j->directories_by_wd = hashmap_new(trivial_hash_func, trivial_compare_func);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (!j->directories_by_wd)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return -ENOMEM;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return 0;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic sd_journal *journal_new(int flags, const char *path) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering sd_journal *j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j = new0(sd_journal, 1);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return NULL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j->inotify_fd = -1;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering j->flags = flags;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (path) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j->path = strdup(path);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j->path) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering free(j);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return NULL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j->files = hashmap_new(string_hash_func, string_compare_func);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j->files) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering free(j->path);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering free(j);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return NULL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j->directories_by_path = hashmap_new(string_hash_func, string_compare_func);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j->directories_by_path) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering hashmap_free(j->files);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering free(j->path);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering free(j);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return NULL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering_public_ int sd_journal_open(sd_journal **ret, int flags) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering sd_journal *j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering int r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!ret)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -EINVAL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (flags & ~(SD_JOURNAL_LOCAL_ONLY|
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering SD_JOURNAL_RUNTIME_ONLY|
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering SD_JOURNAL_SYSTEM_ONLY))
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -EINVAL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j = journal_new(flags, NULL);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!j)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -ENOMEM;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering r = add_search_paths(j);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering *ret = j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return 0;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringfail:
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering sd_journal_close(j);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering_public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int flags) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering sd_journal *j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering int r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!ret)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -EINVAL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (!path || !path_is_absolute(path))
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -EINVAL;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (flags != 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return -EINVAL;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering j = journal_new(flags, path);
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering if (!j)
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering return -ENOMEM;
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering
2723b3b51d409340558e46e37e90525d4f880fe1Lennart Poettering r = add_root_directory(j, path);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering *ret = j;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return 0;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringfail:
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering sd_journal_close(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ void sd_journal_close(sd_journal *j) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Directory *d;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering JournalFile *f;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering while ((f = hashmap_steal_first(j->files)))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering journal_file_close(f);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering hashmap_free(j->files);
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering while ((d = hashmap_first(j->directories_by_path)))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering remove_directory(j, d);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering while ((d = hashmap_first(j->directories_by_wd)))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering remove_directory(j, d);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering hashmap_free(j->directories_by_path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering hashmap_free(j->directories_by_wd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (j->inotify_fd >= 0)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering close_nointr_nofail(j->inotify_fd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering sd_journal_flush_matches(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering free(j->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering free(j);
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Object *o;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering JournalFile *f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!ret)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering f = j->current_file;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (!f)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return -EADDRNOTAVAIL;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (f->current_offset <= 0)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return -EADDRNOTAVAIL;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø if (r < 0)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return r;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *ret = le64toh(o->entry.realtime);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Object *o;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering JournalFile *f;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering int r;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering sd_id128_t id;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering f = j->current_file;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!f)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EADDRNOTAVAIL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (f->current_offset <= 0)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return -EADDRNOTAVAIL;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (r < 0)
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return r;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (ret_boot_id)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *ret_boot_id = o->entry.boot_id;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = sd_id128_get_boot(&id);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!sd_id128_equal(id, o->entry.boot_id))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -ESTALE;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (ret)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *ret = le64toh(o->entry.monotonic);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic bool field_is_valid(const char *field) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering const char *p;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering assert(field);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (isempty(field))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (startswith(field, "__"))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering for (p = field; *p; p++) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (*p == '_')
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering continue;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (*p >= 'A' && *p <= 'Z')
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering continue;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering if (*p >= '0' && *p <= '9')
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering continue;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return false;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering }
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering return true;
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering}
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
6adf7b5e46d32376868feef0197e6ada352aa6f2Lennart Poettering JournalFile *f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint64_t i, n;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering size_t field_length;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Object *o;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!field)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!data)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!size)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!field_is_valid(field))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering f = j->current_file;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!f)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EADDRNOTAVAIL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (f->current_offset <= 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EADDRNOTAVAIL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering field_length = strlen(field);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering n = journal_file_entry_n_items(o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering for (i = 0; i < n; i++) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint64_t p, l;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering le64_t le_hash;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering size_t t;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering p = le64toh(o->entry.items[i].object_offset);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering le_hash = o->entry.items[i].hash;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (le_hash != o->data.hash)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EBADMSG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering l = le64toh(o->object.size) - offsetof(Object, data.payload);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (o->object.flags & OBJECT_COMPRESSED) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#ifdef HAVE_XZ
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (uncompress_startswith(o->data.payload, l,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering &f->compress_buffer, &f->compress_buffer_size,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering field, field_length, '=')) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint64_t rsize;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!uncompress_blob(o->data.payload, l,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering &f->compress_buffer, &f->compress_buffer_size, &rsize))
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return -EBADMSG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *data = f->compress_buffer;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *size = (size_t) rsize;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EPROTONOSUPPORT;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#endif
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (l >= field_length+1 &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering memcmp(o->data.payload, field, field_length) == 0 &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering o->data.payload[field_length] == '=') {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering t = (size_t) l;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if ((uint64_t) t != l)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -E2BIG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *data = o->data.payload;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *size = t;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -ENOENT;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering JournalFile *f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint64_t p, l, n;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering le64_t le_hash;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Object *o;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering size_t t;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!data)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!size)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering f = j->current_file;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!f)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EADDRNOTAVAIL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (f->current_offset <= 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EADDRNOTAVAIL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering n = journal_file_entry_n_items(o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (j->current_field >= n)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering p = le64toh(o->entry.items[j->current_field].object_offset);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering le_hash = o->entry.items[j->current_field].hash;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (le_hash != o->data.hash)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EBADMSG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering l = le64toh(o->object.size) - offsetof(Object, data.payload);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering t = (size_t) l;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* We can't read objects larger than 4G on a 32bit machine */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if ((uint64_t) t != l)
56e6c2abb8f18bba2bb9d96d66ac7e633349ddfbLennart Poettering return -E2BIG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (o->object.flags & OBJECT_COMPRESSED) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#ifdef HAVE_XZ
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint64_t rsize;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EBADMSG;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *data = f->compress_buffer;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *size = (size_t) rsize;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EPROTONOSUPPORT;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering#endif
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *data = o->data.payload;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering *size = t;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering j->current_field ++;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 1;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ void sd_journal_restart_data(sd_journal *j) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering j->current_field = 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_get_fd(sd_journal *j) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (j->inotify_fd >= 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return j->inotify_fd;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = allocate_inotify(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Iterate through all dirs again, to add them to the
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * inotify */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (j->path)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = add_root_directory(j, j->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = add_search_paths(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return j->inotify_fd;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void process_inotify_event(sd_journal *j, struct inotify_event *e) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Directory *d;
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(e);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Is this a subdirectory we watch? */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering d = hashmap_get(j->directories_by_wd, INT_TO_PTR(e->wd));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (d) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering sd_id128_t id;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!(e->mask & IN_ISDIR) && e->len > 0 && endswith(e->name, ".journal")) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Event for a journal file */
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = add_file(j, d->path, e->name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (e->mask & (IN_DELETE|IN_UNMOUNT)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = remove_file(j, d->path, e->name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_debug("Failed to remove file %s/%s: %s", d->path, e->name, strerror(-r));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (!d->is_root && e->len == 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Event for a subdirectory */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (e->mask & (IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)) {
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering r = remove_directory(j, d);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_debug("Failed to remove directory %s: %s", d->path, strerror(-r));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (d->is_root && (e->mask & IN_ISDIR) && e->len > 0 && sd_id128_from_string(e->name, &id) >= 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Event for root directory */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = add_directory(j, d->path, e->name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_debug("Failed to add directory %s/%s: %s", d->path, e->name, strerror(-r));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (e->mask & IN_IGNORED)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering log_warning("Unknown inotify event.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int determine_change(sd_journal *j) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering bool b;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering b = j->current_invalidate_counter != j->last_invalidate_counter;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering j->last_invalidate_counter = j->current_invalidate_counter;
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return b ? SD_JOURNAL_INVALIDATE : SD_JOURNAL_APPEND;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_process(sd_journal *j) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering uint8_t buffer[sizeof(struct inotify_event) + FILENAME_MAX] _alignas_(struct inotify_event);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering bool got_something = false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering for (;;) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering struct inotify_event *e;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering ssize_t l;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering l = read(j->inotify_fd, buffer, sizeof(buffer));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (l < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (errno == EAGAIN || errno == EINTR)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return got_something ? determine_change(j) : SD_JOURNAL_NOP;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -errno;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering got_something = true;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering e = (struct inotify_event*) buffer;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering while (l > 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering size_t step;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering process_inotify_event(j, e);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering step = sizeof(struct inotify_event) + e->len;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(step <= (size_t) l);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering e = (struct inotify_event*) ((uint8_t*) e + step);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering l -= step;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
7079cfeffb6d520f20ddff53fd78467e72e6cc94Lennart Poettering return determine_change(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (j->inotify_fd < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* This is the first invocation, hence create the
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * inotify watch */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = sd_journal_get_fd(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* The journal might have changed since the context
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * object was created and we weren't watching before,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * hence don't wait for anything, and return
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * immediately. */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return determine_change(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering do {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = fd_wait_for_event(j->inotify_fd, POLLIN, timeout_usec);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } while (r == -EINTR);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return sd_journal_process(j);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Iterator i;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering JournalFile *f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering bool first = true;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!j)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!from && !to)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering HASHMAP_FOREACH(f, j->files, i) {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering usec_t fr, t;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering r = journal_file_get_cutoff_realtime_usec(f, &fr, &t);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r == -ENOENT)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering continue;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r < 0)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering return r;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r == 0)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering continue;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (first) {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (from)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering *from = fr;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (to)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering *to = t;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering first = false;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering } else {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (from)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering *from = MIN(fr, *from);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (to)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering *to = MIN(t, *to);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering }
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering }
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering return first ? 0 : 1;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering}
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering Iterator i;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering JournalFile *f;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering bool first = true;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering int r;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (!j)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering return -EINVAL;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (!from && !to)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering return -EINVAL;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering HASHMAP_FOREACH(f, j->files, i) {
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering usec_t fr, t;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t);
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r == -ENOENT)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering continue;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r < 0)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering return r;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (r == 0)
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering continue;
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering if (first) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (from)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering *from = fr;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (to)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering *to = t;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering first = false;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering } else {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (from)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering *from = MIN(fr, *from);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (to)
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering *to = MIN(t, *to);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return first ? 0 : 1;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringvoid journal_print_header(sd_journal *j) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering Iterator i;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering JournalFile *f;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering bool newline = false;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering assert(j);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering HASHMAP_FOREACH(f, j->files, i) {
7f444afa1b62920265fec99a61cb4dc53d521956Lennart Poettering if (newline)
7f444afa1b62920265fec99a61cb4dc53d521956Lennart Poettering putchar('\n');
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering newline = true;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering journal_file_print_header(f);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering/* _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { */
e45fc5e738b0b7700e8b4f3c4b25c58a49b44b27Lennart Poettering/* if (!j) */
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering/* return -EINVAL; */
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering/* if (!field) */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering/* return -EINVAL; */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering/* return -ENOTSUP; */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering/* } */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering/* _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) { */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering/* if (!j) */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering/* return -EINVAL; */
56b921c3d863f0e098f60f934e6c5880575c68abZbigniew Jędrzejewski-Szmek/* if (!data) */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering/* return -EINVAL; */
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering/* if (!l) */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering/* return -EINVAL; */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering/* return -ENOTSUP; */
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering/* } */
d6ce17c7f02ed3facdb45f65f546e587c2f00950Lennart Poettering
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering/* _public_ void sd_journal_restart_unique(sd_journal *j) { */
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering/* if (!j) */
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering/* return; */
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering/* } */
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering