X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournalctl.c;h=1a441dd0d68c17d934f49634195703eadb756d8b;hb=8d98da3f1107529d5ba49aea1fa285f7264b7cba;hp=eb79c4d8537e192d61b4f31537fa339ac510b2b6;hpb=5ec76417764e19486261fb8e38e8e71b28185b37;p=elogind.git diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index eb79c4d85..1a441dd0d 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -74,6 +74,7 @@ static bool arg_this_boot = false; static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_directory = NULL; +static char **arg_file = NULL; static int arg_priorities = 0xFF; static const char *arg_verify_key = NULL; #ifdef HAVE_GCRYPT @@ -86,6 +87,7 @@ static char **arg_user_units = NULL; static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; +static int arg_journal_type = 0; static const char *arg_root = NULL; static enum { @@ -105,6 +107,8 @@ static int help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" "Flags:\n" + " --system Show only the system journal\n" + " --user Show only the user journal for current user\n" " --since=DATE Start showing entries newer or of the specified date\n" " --until=DATE Stop showing entries older or of the specified date\n" " -c --cursor=CURSOR Start showing entries from specified cursor\n" @@ -127,6 +131,7 @@ static int help(void) { " --no-pager Do not pipe output into a pager\n" " -m --merge Show entries from all available journals\n" " -D --directory=PATH Show journal files from directory\n" + " --file=PATH Show journal file\n" " --root=ROOT Operate on catalog files underneath the root ROOT\n" #ifdef HAVE_GCRYPT " --interval=TIME Time interval for changing the FSS sealing key\n" @@ -158,10 +163,13 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_NO_TAIL, ARG_NEW_ID128, + ARG_USER, + ARG_SYSTEM, ARG_ROOT, ARG_HEADER, ARG_FULL, ARG_SETUP_KEYS, + ARG_FILE, ARG_INTERVAL, ARG_VERIFY, ARG_VERIFY_KEY, @@ -171,7 +179,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_USER_UNIT, ARG_LIST_CATALOG, ARG_DUMP_CATALOG, - ARG_UPDATE_CATALOG + ARG_UPDATE_CATALOG, }; static const struct option options[] = { @@ -190,7 +198,10 @@ static int parse_argv(int argc, char *argv[]) { { "merge", no_argument, NULL, 'm' }, { "this-boot", no_argument, NULL, 'b' }, { "dmesg", no_argument, NULL, 'k' }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, { "directory", required_argument, NULL, 'D' }, + { "file", required_argument, NULL, ARG_FILE }, { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, { "priority", required_argument, NULL, 'p' }, @@ -324,10 +335,26 @@ static int parse_argv(int argc, char *argv[]) { arg_this_boot = arg_dmesg = true; break; + case ARG_SYSTEM: + arg_journal_type |= SD_JOURNAL_SYSTEM; + break; + + case ARG_USER: + arg_journal_type |= SD_JOURNAL_CURRENT_USER; + break; + case 'D': arg_directory = optarg; break; + case ARG_FILE: + r = glob_extend(&arg_file, optarg); + if (r < 0) { + log_error("Failed to add paths: %s", strerror(-r)); + return r; + }; + break; + case ARG_ROOT: arg_root = optarg; break; @@ -491,6 +518,11 @@ static int parse_argv(int argc, char *argv[]) { if (arg_follow && !arg_no_tail && arg_lines < 0) arg_lines = 10; + if (arg_directory && arg_file) { + log_error("Please specify either -D/--directory= or --file=, not both."); + return -EINVAL; + } + if (arg_since_set && arg_until_set && arg_since > arg_until) { log_error("--since= must be before --until=."); return -EINVAL; @@ -1094,11 +1126,15 @@ int main(int argc, char *argv[]) { } if (arg_directory) - r = sd_journal_open_directory(&j, arg_directory, 0); + r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); + else if (arg_file) + r = sd_journal_open_files(&j, (const char**) arg_file, 0); else - r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); + r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { - log_error("Failed to open journal: %s", strerror(-r)); + log_error("Failed to open %s: %s", + arg_directory ? arg_directory : arg_file ? "files" : "journal", + strerror(-r)); return EXIT_FAILURE; } @@ -1152,10 +1188,7 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; - /* Opening the fd now means the first sd_journal_wait() will actually wait */ - r = sd_journal_get_fd(j); - if (r < 0) - return EXIT_FAILURE; + log_debug("Journal filter: %s", j->level0 ? journal_make_match_string(j) : "none"); if (arg_field) { const void *data; @@ -1191,6 +1224,13 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } + /* Opening the fd now means the first sd_journal_wait() will actually wait */ + if (arg_follow) { + r = sd_journal_get_fd(j); + if (r < 0) + return EXIT_FAILURE; + } + if (arg_cursor) { r = sd_journal_seek_cursor(j, arg_cursor); if (r < 0) { @@ -1288,11 +1328,10 @@ int main(int argc, char *argv[]) { log_error("Failed to iterate through journal: %s", strerror(-r)); goto finish; } + if (r == 0) + break; } - if (r == 0) - break; - if (arg_until_set && !arg_reverse) { usec_t usec; @@ -1319,12 +1358,14 @@ int main(int argc, char *argv[]) { if (!arg_merge) { sd_id128_t boot_id; + const char *color_on = on_tty() ? ANSI_HIGHLIGHT_ON : "", + *color_off = on_tty() ? ANSI_HIGHLIGHT_OFF : ""; r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); if (r >= 0) { if (previous_boot_id_valid && !sd_id128_equal(boot_id, previous_boot_id)) - printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n"); + printf("%s-- Reboot --%s\n", color_on, color_off); previous_boot_id = boot_id; previous_boot_id_valid = true; @@ -1338,10 +1379,12 @@ int main(int argc, char *argv[]) { arg_catalog * OUTPUT_CATALOG; r = output_journal(stdout, j, arg_output, 0, flags); - if (r < 0 || ferror(stdout)) + need_seek = true; + if (r == -EADDRNOTAVAIL) + break; + else if (r < 0 || ferror(stdout)) goto finish; - need_seek = true; n_shown++; }