chiark / gitweb /
docs: install README files into /var/log and 7etc/rc.d/init.d
[elogind.git] / src / journal / sd-journal.c
index 05a8445b3703f0ad737d12eeee3647cf23ec202e..16ed4239cee2a1e716d15f7319e5d8c2999b1693 100644 (file)
@@ -58,12 +58,13 @@ static void reset_location(sd_journal *j) {
         zero(j->current_location);
 }
 
-static void init_location(Location *l, JournalFile *f, Object *o) {
+static void init_location(Location *l, LocationType type, JournalFile *f, Object *o) {
         assert(l);
+        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
         assert(f);
         assert(o->object.type == OBJECT_ENTRY);
 
-        l->type = LOCATION_DISCRETE;
+        l->type = type;
         l->seqnum = le64toh(o->entry.seqnum);
         l->seqnum_id = f->header->seqnum_id;
         l->realtime = le64toh(o->entry.realtime);
@@ -74,12 +75,13 @@ static void init_location(Location *l, JournalFile *f, Object *o) {
         l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true;
 }
 
-static void set_location(sd_journal *j, JournalFile *f, Object *o, uint64_t offset) {
+static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) {
         assert(j);
+        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
         assert(f);
         assert(o);
 
-        init_location(&j->current_location, f, o);
+        init_location(&j->current_location, type, f, o);
 
         j->current_file = f;
         j->current_field = 0;
@@ -447,7 +449,7 @@ static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
         assert(af);
         assert(ao);
         assert(l);
-        assert(l->type == LOCATION_DISCRETE);
+        assert(l->type == LOCATION_DISCRETE || l->type == LOCATION_SEEK);
 
         if (l->monotonic_set &&
             sd_id128_equal(ao->entry.boot_id, l->boot_id) &&
@@ -866,7 +868,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
         if (r < 0)
                 return r;
 
-        set_location(j, new_file, o, new_offset);
+        set_location(j, LOCATION_DISCRETE, new_file, o, new_offset);
 
         return 1;
 }
@@ -938,21 +940,19 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
         sd_id128_to_string(o->entry.boot_id, bid);
 
         if (asprintf(cursor,
-                     "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx;p=%s",
+                     "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx",
                      sid, (unsigned long long) le64toh(o->entry.seqnum),
                      bid, (unsigned long long) le64toh(o->entry.monotonic),
                      (unsigned long long) le64toh(o->entry.realtime),
-                     (unsigned long long) le64toh(o->entry.xor_hash),
-                     path_get_file_name(j->current_file->path)) < 0)
+                     (unsigned long long) le64toh(o->entry.xor_hash)) < 0)
                 return -ENOMEM;
 
         return 1;
 }
 
 _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
-        char *w;
+        char *w, *state;
         size_t l;
-        char *state;
         unsigned long long seqnum, monotonic, realtime, xor_hash;
         bool
                 seqnum_id_set = false,
@@ -965,7 +965,7 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
 
         if (!j)
                 return -EINVAL;
-        if (!cursor)
+        if (isempty(cursor))
                 return -EINVAL;
 
         FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
@@ -1029,7 +1029,7 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
 
         reset_location(j);
 
-        j->current_location.type = LOCATION_DISCRETE;
+        j->current_location.type = LOCATION_SEEK;
 
         if (realtime_set) {
                 j->current_location.realtime = (uint64_t) realtime;
@@ -1056,12 +1056,95 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
         return 0;
 }
 
+_public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
+        int r;
+        char *w, *state;
+        size_t l;
+        Object *o;
+
+        if (!j)
+                return -EINVAL;
+        if (isempty(cursor))
+                return -EINVAL;
+
+        if (!j->current_file || j->current_file->current_offset <= 0)
+                return -EADDRNOTAVAIL;
+
+        r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o);
+        if (r < 0)
+                return r;
+
+        FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+                _cleanup_free_ char *item = NULL;
+                sd_id128_t id;
+                unsigned long long ll;
+                int k = 0;
+
+                if (l < 2 || w[1] != '=')
+                        return -EINVAL;
+
+                item = strndup(w, l);
+                if (!item)
+                        return -ENOMEM;
+
+                switch (w[0]) {
+
+                case 's':
+                        k = sd_id128_from_string(item+2, &id);
+                        if (k < 0)
+                                return k;
+                        if (!sd_id128_equal(id, j->current_file->header->seqnum_id))
+                                return 0;
+                        break;
+
+                case 'i':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.seqnum))
+                                return 0;
+                        break;
+
+                case 'b':
+                        k = sd_id128_from_string(item+2, &id);
+                        if (k < 0)
+                                return k;
+                        if (!sd_id128_equal(id, o->entry.boot_id))
+                                return 0;
+                        break;
+
+                case 'm':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.monotonic))
+                                return 0;
+                        break;
+
+                case 't':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.realtime))
+                                return 0;
+                        break;
+
+                case 'x':
+                        if (sscanf(item+2, "%llx", &ll) != 1)
+                                return -EINVAL;
+                        if (ll != le64toh(o->entry.xor_hash))
+                                return 0;
+                        break;
+                }
+        }
+
+        return 1;
+}
+
+
 _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {
         if (!j)
                 return -EINVAL;
 
         reset_location(j);
-        j->current_location.type = LOCATION_DISCRETE;
+        j->current_location.type = LOCATION_SEEK;
         j->current_location.boot_id = boot_id;
         j->current_location.monotonic = usec;
         j->current_location.monotonic_set = true;
@@ -1074,7 +1157,7 @@ _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {
                 return -EINVAL;
 
         reset_location(j);
-        j->current_location.type = LOCATION_DISCRETE;
+        j->current_location.type = LOCATION_SEEK;
         j->current_location.realtime = usec;
         j->current_location.realtime_set = true;
 
@@ -1175,11 +1258,13 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename)
                 return 0;
 
         hashmap_remove(j->files, f->path);
+
+        log_debug("File %s got removed.", f->path);
+
         journal_file_close(f);
 
         j->current_invalidate_counter ++;
 
-        log_debug("File %s got removed.", f->path);
         return 0;
 }
 
@@ -1248,7 +1333,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
 
                 m->wd = inotify_add_watch(j->inotify_fd, m->path,
                                           IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
-                                          IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|
+                                          IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM|
                                           IN_ONLYDIR);
 
                 if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
@@ -1866,7 +1951,7 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
                                 if (r < 0)
                                         log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r));
 
-                        } else if (e->mask & (IN_DELETE|IN_UNMOUNT)) {
+                        } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
 
                                 r = remove_file(j, d->path, e->name);
                                 if (r < 0)