summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/journalctl.xml35
-rw-r--r--src/journal/catalog.c58
-rw-r--r--src/journal/catalog.h5
-rw-r--r--src/journal/journalctl.c17
-rw-r--r--src/journal/test-catalog.c4
5 files changed, 106 insertions, 13 deletions
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 8883da278c..6b4b7572f6 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -49,7 +49,9 @@
<refsynopsisdiv>
<cmdsynopsis>
- <command>journalctl <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">MATCHES</arg></command>
+ <command>journalctl</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="opt" rep="repeat">MATCHES</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -479,12 +481,39 @@
</varlistentry>
<varlistentry>
- <term><option>--list-catalog</option></term>
+ <term><option>--list-catalog
+ <optional><replaceable>ID128...</replaceable></optional>
+ </option></term>
<listitem><para>List the contents of
the message catalog, as table of
message IDs plus their short
- description strings.</para></listitem>
+ description strings.</para>
+
+ <para>If any
+ <replaceable>ID128</replaceable>s are
+ specified, only those entries are shown.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--dump-catalog
+ <optional><replaceable>ID128...</replaceable></optional>
+ </option></term>
+
+ <listitem><para>Show the contents of
+ the message catalog, with entries
+ separated by a line consisting of two
+ dashes and the id (the format is the
+ same as <filename>.catalog</filename>
+ files.</para>
+
+ <para>If any
+ <replaceable>ID128</replaceable>s are
+ specified, only those entries are shown.
+ </para>
+ </listitem>
</varlistentry>
<varlistentry>
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index 32256f6263..dacf5c50a1 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -551,7 +551,23 @@ static char *find_header(const char *s, const char *header) {
}
}
-int catalog_list(FILE *f) {
+static void dump_catalog_entry(FILE *f, sd_id128_t id, const char *s, bool oneline) {
+ if (oneline) {
+ _cleanup_free_ char *subject = NULL, *defined_by = NULL;
+
+ subject = find_header(s, "Subject:");
+ defined_by = find_header(s, "Defined-By:");
+
+ fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n",
+ SD_ID128_FORMAT_VAL(id),
+ strna(defined_by), strna(subject));
+ } else
+ fprintf(f, "-- " SD_ID128_FORMAT_STR "\n%s\n",
+ SD_ID128_FORMAT_VAL(id), s);
+}
+
+
+int catalog_list(FILE *f, bool oneline) {
_cleanup_close_ int fd = -1;
void *p = NULL;
struct stat st;
@@ -571,17 +587,13 @@ int catalog_list(FILE *f) {
for (n = 0; n < le64toh(h->n_items); n++) {
const char *s;
- _cleanup_free_ char *subject = NULL, *defined_by = NULL;
if (last_id_set && sd_id128_equal(last_id, items[n].id))
continue;
assert_se(s = find_id(p, items[n].id));
- subject = find_header(s, "Subject:");
- defined_by = find_header(s, "Defined-By:");
-
- fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", SD_ID128_FORMAT_VAL(items[n].id), strna(defined_by), strna(subject));
+ dump_catalog_entry(f, items[n].id, s, oneline);
last_id_set = true;
last_id = items[n].id;
@@ -591,3 +603,37 @@ int catalog_list(FILE *f) {
return 0;
}
+
+int catalog_list_items(FILE *f, bool oneline, char **items) {
+ char **item;
+ int r = 0;
+
+ STRV_FOREACH(item, items) {
+ sd_id128_t id;
+ int k;
+ char _cleanup_free_ *msg = NULL;
+
+ k = sd_id128_from_string(*item, &id);
+ if (k < 0) {
+ log_error("Failed to parse id128 '%s': %s",
+ *item, strerror(-r));
+ if (r < 0)
+ r = k;
+ continue;
+ }
+
+ k = catalog_get(id, &msg);
+ if (k < 0) {
+ log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR,
+ "Failed to retrieve catalog entry for '%s': %s",
+ *item, strerror(-r));
+ if (r < 0)
+ r = k;
+ continue;
+ }
+
+ dump_catalog_entry(f, id, msg, oneline);
+ }
+
+ return r;
+}
diff --git a/src/journal/catalog.h b/src/journal/catalog.h
index 9add773c95..8ea2c41c2d 100644
--- a/src/journal/catalog.h
+++ b/src/journal/catalog.h
@@ -21,8 +21,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdbool.h>
+
#include "sd-id128.h"
int catalog_update(void);
int catalog_get(sd_id128_t id, char **data);
-int catalog_list(FILE *f);
+int catalog_list(FILE *f, bool oneline);
+int catalog_list_items(FILE *f, bool oneline, char **items);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 8aef923bea..975c44fa9b 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -90,6 +90,7 @@ static enum {
ACTION_VERIFY,
ACTION_DISK_USAGE,
ACTION_LIST_CATALOG,
+ ACTION_DUMP_CATALOG,
ACTION_UPDATE_CATALOG
} arg_action = ACTION_SHOW;
@@ -131,6 +132,7 @@ static int help(void) {
" --disk-usage Show total disk usage\n"
" -F --field=FIELD List all values a certain field takes\n"
" --list-catalog Show message IDs of all entries in the message catalog\n"
+ " --dump-catalog Show entries in the message catalog\n"
" --update-catalog Update the message catalog database\n"
#ifdef HAVE_GCRYPT
" --setup-keys Generate new FSS key pair\n"
@@ -159,6 +161,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_UNTIL,
ARG_USER_UNIT,
ARG_LIST_CATALOG,
+ ARG_DUMP_CATALOG,
ARG_UPDATE_CATALOG
};
@@ -193,6 +196,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "field", required_argument, NULL, 'F' },
{ "catalog", no_argument, NULL, 'x' },
{ "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
+ { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
{ "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG },
{ "reverse", no_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 }
@@ -445,6 +449,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_LIST_CATALOG;
break;
+ case ARG_DUMP_CATALOG:
+ arg_action = ACTION_DUMP_CATALOG;
+ break;
+
case ARG_UPDATE_CATALOG:
arg_action = ACTION_UPDATE_CATALOG;
break;
@@ -918,8 +926,13 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (arg_action == ACTION_LIST_CATALOG) {
- r = catalog_list(stdout);
+ if (arg_action == ACTION_LIST_CATALOG ||
+ arg_action == ACTION_DUMP_CATALOG) {
+ bool oneline = arg_action == ACTION_LIST_CATALOG;
+ if (optind < argc)
+ r = catalog_list_items(stdout, oneline, argv + optind);
+ else
+ r = catalog_list(stdout, oneline);
if (r < 0)
log_error("Failed to list catalog: %s", strerror(-r));
goto finish;
diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c
index cec8a11c43..c75b1464fe 100644
--- a/src/journal/test-catalog.c
+++ b/src/journal/test-catalog.c
@@ -36,7 +36,9 @@ int main(int argc, char *argv[]) {
assert_se(catalog_update() >= 0);
- assert_se(catalog_list(stdout) >= 0);
+ assert_se(catalog_list(stdout, true) >= 0);
+
+ assert_se(catalog_list(stdout, false) >= 0);
assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0);