chiark / gitweb /
docs: install README files into /var/log and 7etc/rc.d/init.d
[elogind.git] / src / journal / sd-journal.c
index 6764f2ee6cf21265a88fcb162f8f0e25d1d14ee9..16ed4239cee2a1e716d15f7319e5d8c2999b1693 100644 (file)
@@ -940,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,
@@ -967,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) {
@@ -1058,6 +1056,89 @@ _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;
@@ -1177,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;
 }
 
@@ -1250,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)
@@ -1868,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)