journalct: beef up entry listing

The ability to dump catalog entries in full and by id is added.
parent ab3a162c
......@@ -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>
......
......@@ -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;
}
......@@ -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);
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment