chiark / gitweb /
journalct: beef up entry listing
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Mar 2013 00:54:04 +0000 (20:54 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Mar 2013 01:50:43 +0000 (21:50 -0400)
The ability to dump catalog entries in full and by id is added.

man/journalctl.xml
src/journal/catalog.c
src/journal/catalog.h
src/journal/journalctl.c
src/journal/test-catalog.c

index 8883da278c82293050f009345a29364b950ff713..6b4b7572f633b3a5c149159196157672fc93c539 100644 (file)
@@ -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>
 
                         </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>
index 32256f6263a6c43df3e6f07cd238faf87d701d00..dacf5c50a197cb608e07877f63421e222706846c 100644 (file)
@@ -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;
+}
index 9add773c95c1fe4dcd0743b8cdb55e0b557b6c2d..8ea2c41c2d30d9bc52b2901a35b36411441fc516 100644 (file)
   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);
index 8aef923bea7c626231505c1f65e0f177c3ecd5ab..975c44fa9b76572cd32dc74434e5c1a38aeda73f 100644 (file)
@@ -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;
index cec8a11c438696d95afddbee420ee126840f88a8..c75b1464fe943b4cddc601f82eafe3768575aac0 100644 (file)
@@ -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);