X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournalctl.c;h=7564c48e1f15f8e1a10b689cc5d7b4f0805f7495;hb=fd6e88753716d8136037277c7db2196e0f979675;hp=665b325a94937821b3ce3363edb0b137fdf8bc9b;hpb=c3f60ec54da2a5d1ba00cec6bb2c282f079aa3f6;p=elogind.git diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 665b325a9..7564c48e1 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -74,6 +74,7 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; static usec_t arg_since, arg_until; static bool arg_since_set = false, arg_until_set = false; static const char *arg_unit = NULL; +static const char *arg_field = NULL; static enum { ACTION_SHOW, @@ -87,9 +88,8 @@ static enum { static int help(void) { printf("%s [OPTIONS...] [MATCH]\n\n" - "Send control commands to or query the journal.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" + "Query the journal.\n\n" + "Flags:\n" " -c --cursor=CURSOR Start showing entries from specified cursor\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" @@ -106,15 +106,20 @@ 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" - "Commands:\n" +#ifdef HAVE_GCRYPT + " --interval=TIME Time interval for changing the FSS sealing key\n" + " --verify-key=KEY Specify FSS verification key\n" +#endif + "\nCommands:\n" + " -h --help Show this help\n" + " --version Show package version\n" " --new-id128 Generate a new 128 Bit ID\n" " --header Show journal header information\n" " --disk-usage Show total disk usage\n" + " -F --field=FIELD List all values a certain field takes\n" #ifdef HAVE_GCRYPT " --setup-keys Generate new FSS key pair\n" - " --interval=TIME Time interval for changing the FSS sealing key\n" " --verify Verify journal file consistency\n" - " --verify-key=KEY Specify FSS verification key\n" #endif , program_invocation_short_name); @@ -163,6 +168,7 @@ static int parse_argv(int argc, char *argv[]) { { "since", required_argument, NULL, ARG_SINCE }, { "until", required_argument, NULL, ARG_UNTIL }, { "unit", required_argument, NULL, 'u' }, + { "field", required_argument, NULL, 'F' }, { NULL, 0, NULL, 0 } }; @@ -171,7 +177,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:", options, NULL)) >= 0) { switch (c) { @@ -368,6 +374,10 @@ static int parse_argv(int argc, char *argv[]) { case '?': return -EINVAL; + case 'F': + arg_field = optarg; + break; + default: log_error("Unknown option code %c", c); return -EINVAL; @@ -804,6 +814,26 @@ static int verify(sd_journal *j) { return r; } +static int access_check(void) { + +#ifdef HAVE_ACL + if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) { + log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages."); + return -EACCES; + } + + if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0) + log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off."); +#else + if (geteuid() != 0 && in_group("adm") <= 0) { + log_error("No access to messages. Only users in the group 'adm' can see messages."); + return -EACCES; + } +#endif + + return 0; +} + int main(int argc, char *argv[]) { int r; sd_journal *j = NULL; @@ -830,11 +860,14 @@ int main(int argc, char *argv[]) { goto finish; } + r = access_check(); + if (r < 0) + goto finish; + if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, 0); else r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); - if (r < 0) { log_error("Failed to open journal: %s", strerror(-r)); goto finish; @@ -864,23 +897,6 @@ int main(int argc, char *argv[]) { goto finish; } -#ifdef HAVE_ACL - if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) { - log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages."); - r = -EACCES; - goto finish; - } - - if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0) - log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off."); -#else - if (geteuid() != 0 && in_group("adm") <= 0) { - log_error("No access to messages. Only users in the group 'adm' can see messages."); - r = -EACCES; - goto finish; - } -#endif - r = add_this_boot(j); if (r < 0) goto finish; @@ -897,6 +913,35 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; + if (arg_field) { + const void *data; + size_t size; + + r = sd_journal_query_unique(j, arg_field); + if (r < 0) { + log_error("Failed to query unique data objects: %s", strerror(-r)); + goto finish; + } + + SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { + const void *eq; + + if (arg_lines > 0 && n_shown >= arg_lines) + break; + + eq = memchr(data, '=', size); + if (eq) + printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1); + else + printf("%.*s\n", (int) size, (const char*) data); + + n_shown ++; + } + + r = 0; + goto finish; + } + if (arg_cursor) { r = sd_journal_seek_cursor(j, arg_cursor); if (r < 0) {