chiark / gitweb /
journalctl: add --cursor switch
[elogind.git] / src / journal / journalctl.c
index e491c2766230a326f183639a86c2ee0ba5a4fc17..bac87294943adf9ef704fdb85287078eff398c14 100644 (file)
@@ -63,6 +63,7 @@ static bool arg_no_tail = false;
 static bool arg_quiet = false;
 static bool arg_merge = false;
 static bool arg_this_boot = false;
+static const char *arg_cursor = NULL;
 static const char *arg_directory = NULL;
 static int arg_priorities = 0xFF;
 static const char *arg_verify_key = NULL;
@@ -87,6 +88,7 @@ static int help(void) {
                "     --version           Show package version\n"
                "     --no-pager          Do not pipe output into a pager\n"
                "  -a --all               Show all fields, including long and unprintable\n"
+               "  -c --cursor=CURSOR     Jump to the specified cursor\n"
                "  -f --follow            Follow journal\n"
                "  -n --lines[=INTEGER]   Number of journal entries to show\n"
                "     --no-tail           Show all lines, even in follow mode\n"
@@ -148,6 +150,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "verify",       no_argument,       NULL, ARG_VERIFY       },
                 { "verify-key",   required_argument, NULL, ARG_VERIFY_KEY   },
                 { "disk-usage",   no_argument,       NULL, ARG_DISK_USAGE   },
+                { "cursor",       no_argument,       NULL, 'c'              },
                 { NULL,           0,                 NULL, 0                }
         };
 
@@ -156,7 +159,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:", options, NULL)) >= 0) {
 
                 switch (c) {
 
@@ -228,6 +231,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_directory = optarg;
                         break;
 
+                case 'c':
+                        arg_cursor = optarg;
+                        break;
+
                 case ARG_HEADER:
                         arg_action = ACTION_PRINT_HEADER;
                         break;
@@ -684,14 +691,14 @@ static int verify(sd_journal *j) {
 
         HASHMAP_FOREACH(f, j->files, i) {
                 int k;
-                usec_t from, to, total;
+                usec_t first, validated, last;
 
 #ifdef HAVE_GCRYPT
                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
                         log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
 #endif
 
-                k = journal_file_verify(f, arg_verify_key, &from, &to, &total, true);
+                k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
                 if (k == -EINVAL) {
                         /* If the key was invalid give up right-away. */
                         return k;
@@ -703,14 +710,14 @@ static int verify(sd_journal *j) {
                         log_info("PASS: %s", f->path);
 
                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
-                                if (from > 0) {
+                                if (validated > 0) {
                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
-                                                 format_timestamp(a, sizeof(a), from),
-                                                 format_timestamp(b, sizeof(b), to),
-                                                 format_timespan(c, sizeof(c), total > to ? total - to : 0));
-                                } else if (total > 0)
+                                                 format_timestamp(a, sizeof(a), first),
+                                                 format_timestamp(b, sizeof(b), validated),
+                                                 format_timespan(c, sizeof(c), last > validated ? last - validated : 0));
+                                } else if (last > 0)
                                         log_info("=> No sealing yet, %s of entries not sealed.",
-                                                 format_timespan(c, sizeof(c), total));
+                                                 format_timespan(c, sizeof(c), last - first));
                                 else
                                         log_info("=> No sealing yet, no entries in file.");
                         }
@@ -829,7 +836,16 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        if (arg_lines >= 0) {
+        if (arg_cursor) {
+                r = sd_journal_seek_cursor(j, arg_cursor);
+                if (r < 0) {
+                        log_error("Failed to seek to cursor: %s", strerror(-r));
+                        goto finish;
+                }
+
+                r = sd_journal_next(j);
+
+        } else if (arg_lines >= 0) {
                 r = sd_journal_seek_tail(j);
                 if (r < 0) {
                         log_error("Failed to seek to tail: %s", strerror(-r));
@@ -837,6 +853,7 @@ int main(int argc, char *argv[]) {
                 }
 
                 r = sd_journal_previous_skip(j, arg_lines);
+
         } else {
                 r = sd_journal_seek_head(j);
                 if (r < 0) {