[systemd-commits] 8 commits - catalog/systemd.catalog man/journalctl.xml man/sd_journal_get_catalog.xml src/journal src/python-systemd TODO

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Tue Mar 19 18:52:46 PDT 2013


 TODO                           |    4 -
 catalog/systemd.catalog        |   20 ------
 man/journalctl.xml             |   35 ++++++++++-
 man/sd_journal_get_catalog.xml |   12 ++-
 src/journal/catalog.c          |   58 ++++++++++++++++--
 src/journal/catalog.h          |    5 +
 src/journal/journalctl.c       |   26 +++++---
 src/journal/test-catalog.c     |    4 -
 src/python-systemd/_journal.c  |    2 
 src/python-systemd/_reader.c   |  129 +++++++++++++++++++++++++++++++++++------
 src/python-systemd/id128.c     |    2 
 src/python-systemd/journal.py  |    3 
 12 files changed, 233 insertions(+), 67 deletions(-)

New commits:
commit 9d83ad481beb9a1a7eaf68511a6f95f4a3a2bbf0
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Mar 19 20:57:25 2013 -0400

    catalog: remove broken links to wiki
    
    https://bugs.freedesktop.org/show_bug.cgi?id=58359

diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog
index 5dcbd46..62635c8 100644
--- a/catalog/systemd.catalog
+++ b/catalog/systemd.catalog
@@ -26,7 +26,6 @@
 Subject: The Journal has been started
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system journal process has been starting up, opened the journal
 files for writing and is now ready to process requests.
@@ -35,7 +34,6 @@ files for writing and is now ready to process requests.
 Subject: The Journal has been stopped
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system journal process has shut down and closed all currently
 active journal files.
@@ -45,7 +43,6 @@ Subject: Messages from a service have been suppressed
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: man:journald.conf(5)
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 A service has logged too many messages within a time period. Messages
 from the service have been dropped.
@@ -61,7 +58,6 @@ RateLimitInterval= and RateLimitBurst= in
 Subject: Journal messages have been missed
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Kernel messages have been lost as the journal system has been unable
 to process them quickly enough.
@@ -71,7 +67,6 @@ Subject: Process @COREDUMP_PID@ (@COREDUMP_COMM@) dumped core
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: man:core(5)
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Process @COREDUMP_PID@ (@COREDUMP_COMM@) crashed and dumped core.
 
@@ -83,7 +78,6 @@ Subject: Speicherabbild für Prozess @COREDUMP_PID@ (@COREDUMP_COMM) generiert
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: man:core(5)
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Prozess @COREDUMP_PID@ (@COREDUMP_COMM@) ist abgebrochen worden und
 ein Speicherabbild wurde generiert.
@@ -96,7 +90,6 @@ Subject: A new session @SESSION_ID@ has been created for user @USER_ID@
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 A new session with the ID @SESSION_ID@ has been created for the user @USER_ID at .
 
@@ -107,7 +100,6 @@ Subject: A session @SESSION_ID@ has been terminated
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 A session with the ID @SESSION_ID@ has been terminated.
 
@@ -116,7 +108,6 @@ Subject: A new seat @SEAT_ID@ is now available
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 A new seat @SEAT_ID@ has been configured and is now available.
 
@@ -125,7 +116,6 @@ Subject: A seat @SEAT_ID@ has now been removed
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
 Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 A seat @SEAT_ID@ has been removed and is no longer available.
 
@@ -133,7 +123,6 @@ A seat @SEAT_ID@ has been removed and is no longer available.
 Subject: Time change
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system clock has been changed to @REALTIME@ microseconds after January 1st, 1970.
 
@@ -141,7 +130,6 @@ The system clock has been changed to @REALTIME@ microseconds after January 1st,
 Subject: Zeitänderung
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Die System-Zeit wurde geändert auf @REALTIME@ Mikrosekunden nach dem 1. Januar 1970.
 
@@ -149,7 +137,6 @@ Die System-Zeit wurde geändert auf @REALTIME@ Mikrosekunden nach dem 1. Januar
 Subject: Time zone change to @TIMEZONE@
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system time zone has been changed to @TIMEZONE at .
 
@@ -157,7 +144,6 @@ The system time zone has been changed to @TIMEZONE at .
 Subject: System start-up is now complete
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 All system services necessary queued for starting at boot have been
 successfully started. Note that this does not mean that the machine is
@@ -173,7 +159,6 @@ Userspace start-up required @USERSPACE_USEC@ microseconds.
 Subject: System sleep state @SLEEP@ entered
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system has now entered the @SLEEP@ sleep state.
 
@@ -181,7 +166,6 @@ The system has now entered the @SLEEP@ sleep state.
 Subject: System sleep state @SLEEP@ left
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 The system has now left the @SLEEP@ sleep state.
 
@@ -189,7 +173,6 @@ The system has now left the @SLEEP@ sleep state.
 Subject: System shutdown initiated
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Systemd shutdown has been initiated. The shutdown has now begun and
 all system services are terminated and all file systems unmounted.
@@ -198,7 +181,6 @@ all system services are terminated and all file systems unmounted.
 Subject: Unit @UNIT@ has begun with start-up
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Unit @UNIT@ has begun starting up.
 
@@ -206,7 +188,6 @@ Unit @UNIT@ has begun starting up.
 Subject: Unit @UNIT@ has finished start-up
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Unit @UNIT@ has finished starting up.
 
@@ -216,7 +197,6 @@ The start-up result is @RESULT at .
 Subject: Unit @UNIT@ has begun shutting down
 Defined-By: systemd
 Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/catalog/@MESSAGE_ID@
 
 Unit @UNIT@ has begun shutting down.
 

commit 54b7254c1fa629937f92fd6fa34bdf127b696a00
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Mar 19 20:54:04 2013 -0400

    journalct: beef up entry listing
    
    The ability to dump catalog entries in full and by id is added.

diff --git a/man/journalctl.xml b/man/journalctl.xml
index 8883da2..6b4b757 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 32256f6..dacf5c5 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 9add773..8ea2c41 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 8aef923..975c44f 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 cec8a11..c75b146 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);
 

commit ab3a162c0194fd92884798488eeafdcc5c4d7d57
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:10:51 2013 -0400

    systemd-python: small cleanups
    
    - separate methods with two empty lines for clarity
    - avoid malloc(0) by specyfing private data size as -1
    - add method name in error messages

diff --git a/src/python-systemd/_journal.c b/src/python-systemd/_journal.c
index ced52b2..2de0d4f 100644
--- a/src/python-systemd/_journal.c
+++ b/src/python-systemd/_journal.c
@@ -128,7 +128,7 @@ static struct PyModuleDef module = {
         PyModuleDef_HEAD_INIT,
         "_journal", /* name of module */
         NULL, /* module documentation, may be NULL */
-        0, /* size of per-interpreter state of the module */
+        -1, /* size of per-interpreter state of the module */
         methods
 };
 
diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c
index 2feb091..908d911 100644
--- a/src/python-systemd/_reader.c
+++ b/src/python-systemd/_reader.c
@@ -75,6 +75,7 @@ static PyStructSequence_Desc Monotonic_desc = {
 };
 #endif
 
+
 static void Reader_dealloc(Reader* self)
 {
     sd_journal_close(self->j);
@@ -121,6 +122,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds)
     return set_error(r, path, "Invalid flags or path");
 }
 
+
 PyDoc_STRVAR(Reader_fileno__doc__,
              "fileno() -> int\n\n"
              "Get a file descriptor to poll for changes in the journal.\n"
@@ -136,6 +138,7 @@ static PyObject* Reader_fileno(Reader *self, PyObject *args)
     return long_FromLong(r);
 }
 
+
 PyDoc_STRVAR(Reader_reliable_fd__doc__,
              "reliable_fd() -> bool\n\n"
              "Returns True iff the journal can be polled reliably.\n"
@@ -151,6 +154,7 @@ static PyObject* Reader_reliable_fd(Reader *self, PyObject *args)
     return PyBool_FromLong(r);
 }
 
+
 PyDoc_STRVAR(Reader_close__doc__,
              "close() -> None\n\n"
              "Free resources allocated by this Reader object.\n"
@@ -166,6 +170,7 @@ static PyObject* Reader_close(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader___enter____doc__,
              "__enter__() -> self\n\n"
              "Part of the context manager protocol.\n"
@@ -192,6 +197,7 @@ static PyObject* Reader___exit__(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_get_next__doc__,
              "get_next([skip]) -> dict\n\n"
              "Return dictionary of the next log entry. Optional skip value will\n"
@@ -204,7 +210,7 @@ static PyObject* Reader_get_next(Reader *self, PyObject *args)
     int64_t skip = 1LL;
     int r;
 
-    if (!PyArg_ParseTuple(args, "|L", &skip))
+    if (!PyArg_ParseTuple(args, "|L:_Reader.get_next", &skip))
         return NULL;
 
     if (skip == 0LL) {
@@ -371,6 +377,7 @@ error:
     return NULL;
 }
 
+
 PyDoc_STRVAR(Reader_get_previous__doc__,
              "get_previous([skip]) -> dict\n\n"
              "Return dictionary of the previous log entry. Optional skip value\n"
@@ -378,13 +385,14 @@ PyDoc_STRVAR(Reader_get_previous__doc__,
 static PyObject* Reader_get_previous(Reader *self, PyObject *args)
 {
     int64_t skip = 1LL;
-    if (!PyArg_ParseTuple(args, "|L", &skip))
+    if (!PyArg_ParseTuple(args, "|L:_Reader.get_previous", &skip))
         return NULL;
 
     return PyObject_CallMethod((PyObject *)self, (char*) "get_next",
                                (char*) "L", -skip);
 }
 
+
 PyDoc_STRVAR(Reader_add_match__doc__,
              "add_match(match) -> None\n\n"
              "Add a match to filter journal log entries. All matches of different\n"
@@ -395,7 +403,7 @@ static PyObject* Reader_add_match(Reader *self, PyObject *args, PyObject *keywds
 {
     char *match;
     int match_len, r;
-    if (!PyArg_ParseTuple(args, "s#", &match, &match_len))
+    if (!PyArg_ParseTuple(args, "s#:_Reader.add_match", &match, &match_len))
         return NULL;
 
     r = sd_journal_add_match(self->j, match, match_len);
@@ -406,6 +414,7 @@ static PyObject* Reader_add_match(Reader *self, PyObject *args, PyObject *keywds
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_add_disjunction__doc__,
              "add_disjunction() -> None\n\n"
              "Inserts a logical OR between matches added before and afterwards.");
@@ -419,6 +428,7 @@ static PyObject* Reader_add_disjunction(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_flush_matches__doc__,
              "flush_matches() -> None\n\n"
              "Clear all current match filters.");
@@ -428,6 +438,7 @@ static PyObject* Reader_flush_matches(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_seek_head__doc__,
              "seek_head() -> None\n\n"
              "Jump to the beginning of the journal.\n"
@@ -444,6 +455,7 @@ static PyObject* Reader_seek_head(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_seek_tail__doc__,
              "seek_tail() -> None\n\n"
              "Jump to the end of the journal.\n"
@@ -460,6 +472,7 @@ static PyObject* Reader_seek_tail(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_seek_realtime__doc__,
              "seek_realtime(realtime) -> None\n\n"
              "Seek to nearest matching journal entry to `realtime`. Argument\n"
@@ -470,7 +483,7 @@ static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
     uint64_t timestamp;
     int r;
 
-    if (!PyArg_ParseTuple(args, "d", &timedouble))
+    if (!PyArg_ParseTuple(args, "d:_Reader.seek_realtime", &timedouble))
         return NULL;
 
     timestamp = (uint64_t) (timedouble * 1.0E6);
@@ -487,6 +500,7 @@ static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_seek_monotonic__doc__,
              "seek_monotonic(monotonic[, bootid]) -> None\n\n"
              "Seek to nearest matching journal entry to `monotonic`. Argument\n"
@@ -501,7 +515,7 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
     sd_id128_t id;
     int r;
 
-    if (!PyArg_ParseTuple(args, "d|z", &timedouble, &bootid))
+    if (!PyArg_ParseTuple(args, "d|z:_Reader.seek_monotonic", &timedouble, &bootid))
         return NULL;
 
     timestamp = (uint64_t) (timedouble * 1.0E6);
@@ -531,6 +545,7 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 PyDoc_STRVAR(Reader_wait__doc__,
              "wait([timeout]) -> state change (integer)\n\n"
              "Wait for a change in the journal. Argument `timeout` specifies\n"
@@ -545,7 +560,7 @@ static PyObject* Reader_wait(Reader *self, PyObject *args, PyObject *keywds)
     int r;
     int64_t timeout = 0LL;
 
-    if (!PyArg_ParseTuple(args, "|L", &timeout))
+    if (!PyArg_ParseTuple(args, "|L:_Reader.wait", &timeout))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -558,6 +573,7 @@ static PyObject* Reader_wait(Reader *self, PyObject *args, PyObject *keywds)
     return long_FromLong(r);
 }
 
+
 PyDoc_STRVAR(Reader_seek_cursor__doc__,
              "seek_cursor(cursor) -> None\n\n"
              "Seek to journal entry by given unique reference `cursor`.");
@@ -566,7 +582,7 @@ static PyObject* Reader_seek_cursor(Reader *self, PyObject *args)
     const char *cursor;
     int r;
 
-    if (!PyArg_ParseTuple(args, "s", &cursor))
+    if (!PyArg_ParseTuple(args, "s:_Reader.seek_cursor", &cursor))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -577,6 +593,7 @@ static PyObject* Reader_seek_cursor(Reader *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
+
 static PyObject* Reader_iter(PyObject *self)
 {
     Py_INCREF(self);
@@ -601,6 +618,7 @@ static PyObject* Reader_iternext(PyObject *self)
     }
 }
 
+
 PyDoc_STRVAR(Reader_query_unique__doc__,
              "query_unique(field) -> a set of values\n\n"
              "Return a set of unique values appearing in journal for the\n"
@@ -613,7 +631,7 @@ static PyObject* Reader_query_unique(Reader *self, PyObject *args)
     size_t uniq_len;
     PyObject *value_set, *key, *value;
 
-    if (!PyArg_ParseTuple(args, "s", &query))
+    if (!PyArg_ParseTuple(args, "s:_Reader.query_unique", &query))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -676,7 +694,7 @@ static PyObject* get_catalog(PyObject *self, PyObject *args)
     assert(!self);
     assert(args);
 
-    if (!PyArg_ParseTuple(args, "z", &id_))
+    if (!PyArg_ParseTuple(args, "z:get_catalog", &id_))
         return NULL;
 
     r = sd_id128_from_string(id_, &id);
@@ -725,6 +743,7 @@ static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closur
     return set_error(r, NULL, NULL);
 }
 
+
 PyDoc_STRVAR(closed__doc__,
              "True iff journal is closed");
 static PyObject* Reader_get_closed(Reader *self, void *closure)
@@ -732,6 +751,7 @@ static PyObject* Reader_get_closed(Reader *self, void *closure)
     return PyBool_FromLong(self->j == NULL);
 }
 
+
 static PyGetSetDef Reader_getsetters[] = {
     {(char*) "data_threshold",
      (getter) Reader_get_data_threshold,
diff --git a/src/python-systemd/id128.c b/src/python-systemd/id128.c
index a6711a5..865cc3c 100644
--- a/src/python-systemd/id128.c
+++ b/src/python-systemd/id128.c
@@ -134,7 +134,7 @@ static struct PyModuleDef module = {
         PyModuleDef_HEAD_INIT,
         "id128", /* name of module */
         module__doc__, /* module documentation, may be NULL */
-        0, /* size of per-interpreter state of the module */
+        -1, /* size of per-interpreter state of the module */
         methods
 };
 

commit 2b01924cda5257531867119e11ee950741af2ff6
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:10:51 2013 -0400

    systemd-python: add journal.get_catalog()
    
    This one wraps sd_journal_get_catalog_from_message_id.
    Thanks to Python namespacing, we can stick to a shorter name.

diff --git a/TODO b/TODO
index 750540f..b441700 100644
--- a/TODO
+++ b/TODO
@@ -581,7 +581,6 @@ Features:
 * drop cap bounding set in readahead and other services
 
 * systemd-python:
-   - export sd_journal_get_catalog_for_message_id (in systemd.id128)
    - allow reading of only select fields in systemd.journal._reader.Reader
    - export sd_journal_test_cursor in systemd.journal._reader.Reader
    - export sd_journal_get_usage in systemd.journal._reader.Reader
diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c
index a257757..2feb091 100644
--- a/src/python-systemd/_reader.c
+++ b/src/python-systemd/_reader.c
@@ -50,6 +50,11 @@ static int set_error(int r, const char* path, const char* invalid_message) {
     return -1;
 }
 
+
+PyDoc_STRVAR(module__doc__,
+             "Class to reads the systemd journal similar to journalctl.");
+
+
 #if PY_MAJOR_VERSION >= 3
 static PyTypeObject MonotonicType;
 
@@ -657,6 +662,37 @@ static PyObject* Reader_get_catalog(Reader *self, PyObject *args)
 }
 
 
+PyDoc_STRVAR(get_catalog__doc__,
+             "get_catalog(id128) -> str\n\n"
+             "Retrieve a message catalog entry for the given id.\n"
+             "Wraps man:sd_journal_get_catalog_for_message_id(3).");
+static PyObject* get_catalog(PyObject *self, PyObject *args)
+{
+    int r;
+    char *id_ = NULL;
+    sd_id128_t id;
+    char _cleanup_free_ *msg = NULL;
+
+    assert(!self);
+    assert(args);
+
+    if (!PyArg_ParseTuple(args, "z", &id_))
+        return NULL;
+
+    r = sd_id128_from_string(id_, &id);
+    if (set_error(r, NULL, "Invalid id128"))
+        return NULL;
+
+    Py_BEGIN_ALLOW_THREADS
+    r = sd_journal_get_catalog_for_message_id(id, &msg);
+    Py_END_ALLOW_THREADS
+    if (set_error(r, NULL, NULL))
+        return NULL;
+
+    return unicode_FromString(msg);
+}
+
+
 PyDoc_STRVAR(data_threshold__doc__,
              "Threshold for field size truncation in bytes.\n\n"
              "Fields longer than this will be truncated to the threshold size.\n"
@@ -774,16 +810,19 @@ static PyTypeObject ReaderType = {
     PyType_GenericNew,                        /* tp_new */
 };
 
-#define SUMMARY \
-    "Module that reads the systemd journal similar to journalctl."
+static PyMethodDef methods[] = {
+        { "get_catalog", get_catalog, METH_VARARGS, get_catalog__doc__},
+        { NULL, NULL, 0, NULL }        /* Sentinel */
+};
 
 #if PY_MAJOR_VERSION >= 3
-static PyModuleDef _reader_module = {
+static PyModuleDef module = {
     PyModuleDef_HEAD_INIT,
     "_reader",
-    SUMMARY,
+    module__doc__,
     -1,
-    NULL, NULL, NULL, NULL, NULL
+    methods,
+    NULL, NULL, NULL, NULL
 };
 #endif
 
@@ -813,7 +852,7 @@ init_reader(void)
 #endif
 
 #if PY_MAJOR_VERSION >= 3
-    m = PyModule_Create(&_reader_module);
+    m = PyModule_Create(&module);
     if (m == NULL)
         return NULL;
 
@@ -822,7 +861,7 @@ init_reader(void)
         initialized = true;
     }
 #else
-    m = Py_InitModule3("_reader", NULL, SUMMARY);
+    m = Py_InitModule3("_reader", methods, module__doc__);
     if (m == NULL)
         return;
 #endif
diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py
index 146f59f..fee39c9 100644
--- a/src/python-systemd/journal.py
+++ b/src/python-systemd/journal.py
@@ -34,7 +34,8 @@ from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
                     LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG)
 from ._journal import sendv, stream_fd
 from ._reader import (_Reader, NOP, APPEND, INVALIDATE,
-                      LOCAL_ONLY, RUNTIME_ONLY, SYSTEM_ONLY)
+                      LOCAL_ONLY, RUNTIME_ONLY, SYSTEM_ONLY,
+                      get_catalog)
 from . import id128 as _id128
 
 if _sys.version_info >= (3,):

commit 6808412dad4a8c4379dda4453658ec756a0542b9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:10:51 2013 -0400

    systemd-python: add _Reader.get_catalog()
    
    This one wraps sd_journaal_get_catalog.

diff --git a/TODO b/TODO
index 715dd9d..750540f 100644
--- a/TODO
+++ b/TODO
@@ -581,7 +581,6 @@ Features:
 * drop cap bounding set in readahead and other services
 
 * systemd-python:
-   - export sd_journal_get_catalog (in systemd.journal._reader)
    - export sd_journal_get_catalog_for_message_id (in systemd.id128)
    - allow reading of only select fields in systemd.journal._reader.Reader
    - export sd_journal_test_cursor in systemd.journal._reader.Reader
diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c
index 67358e3..a257757 100644
--- a/src/python-systemd/_reader.c
+++ b/src/python-systemd/_reader.c
@@ -634,6 +634,29 @@ static PyObject* Reader_query_unique(Reader *self, PyObject *args)
     return value_set;
 }
 
+
+PyDoc_STRVAR(Reader_get_catalog__doc__,
+             "get_catalog() -> str\n\n"
+             "Retrieve a message catalog entry for the current journal entry.\n"
+             "Wraps man:sd_journal_get_catalog(3).");
+static PyObject* Reader_get_catalog(Reader *self, PyObject *args)
+{
+    int r;
+    char _cleanup_free_ *msg = NULL;
+
+    assert(self);
+    assert(!args);
+
+    Py_BEGIN_ALLOW_THREADS
+    r = sd_journal_get_catalog(self->j, &msg);
+    Py_END_ALLOW_THREADS
+    if (set_error(r, NULL, NULL))
+        return NULL;
+
+    return unicode_FromString(msg);
+}
+
+
 PyDoc_STRVAR(data_threshold__doc__,
              "Threshold for field size truncation in bytes.\n\n"
              "Fields longer than this will be truncated to the threshold size.\n"
@@ -706,6 +729,7 @@ static PyMethodDef Reader_methods[] = {
     {"wait",            (PyCFunction) Reader_wait, METH_VARARGS, Reader_wait__doc__},
     {"seek_cursor",     (PyCFunction) Reader_seek_cursor, METH_VARARGS, Reader_seek_cursor__doc__},
     {"query_unique",    (PyCFunction) Reader_query_unique, METH_VARARGS, Reader_query_unique__doc__},
+    {"get_catalog",     (PyCFunction) Reader_get_catalog, METH_NOARGS, Reader_get_catalog__doc__},
     {NULL}  /* Sentinel */
 };
 

commit 0d1aaec2282ee8e82908f9f12d820dab397adc0b
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:10:51 2013 -0400

    man/catalog: fix synopsis and remind to free

diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
index b3c7b58..719d77f 100644
--- a/man/sd_journal_get_catalog.xml
+++ b/man/sd_journal_get_catalog.xml
@@ -55,13 +55,13 @@
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_catalog</function></funcdef>
                                 <paramdef>sd_journal* <parameter>j</parameter></paramdef>
-                                <paramdef>const char** <parameter>ret</parameter></paramdef>
+                                <paramdef>char** <parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_catalog_for_message_id</function></funcdef>
                                 <paramdef>sd_id128_t <parameter>id</parameter></paramdef>
-                                <paramdef>const char** <parameter>ret</parameter></paramdef>
+                                <paramdef>char** <parameter>ret</parameter></paramdef>
                         </funcprototype>
 
 
@@ -89,7 +89,7 @@
                 <function>sd_journal_get_catalog()</function> but the
                 entry is looked up by the specified message ID (no
                 open journal context is necessary for this), and no
-                field substitution is done.</para>
+                field substitution is performed.</para>
 
                 <para>For more information about the journal message
                 catalog please refer to the <ulink
@@ -106,6 +106,11 @@
                 return 0 on success or a negative errno-style error
                 code. If no matching message catalog entry is found
                 -ENOENT is returned.</para>
+
+                <para>On successful return, <parameter>ret</parameter>
+                points to a new string, which must be freed with
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                </para>
         </refsect1>
 
         <refsect1>
@@ -130,6 +135,7 @@
                         <citerefentry><refentrytitle>sd_journal_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_get_data</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 </para>
         </refsect1>
 

commit 6531dac67cc2e707e4a2b62f3ae11f7330f7c049
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:10:51 2013 -0400

    systemd-python: add _Reader.closed attribute
    
    This should make the file interface of _Reader complete.

diff --git a/TODO b/TODO
index c73e8dc..715dd9d 100644
--- a/TODO
+++ b/TODO
@@ -586,8 +586,6 @@ Features:
    - allow reading of only select fields in systemd.journal._reader.Reader
    - export sd_journal_test_cursor in systemd.journal._reader.Reader
    - export sd_journal_get_usage in systemd.journal._reader.Reader
-   - add systemd.journal._reader._Reader.closed attribute (it can
-     be just "return self->j != NULL")
    - figure out a simple way to wait for journal events in a way that
      works with ^C
    - add documentation to systemd.daemon
diff --git a/src/python-systemd/_reader.c b/src/python-systemd/_reader.c
index 6759555..67358e3 100644
--- a/src/python-systemd/_reader.c
+++ b/src/python-systemd/_reader.c
@@ -666,12 +666,24 @@ static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closur
     return set_error(r, NULL, NULL);
 }
 
-static PyGetSetDef Reader_getseters[] = {
+PyDoc_STRVAR(closed__doc__,
+             "True iff journal is closed");
+static PyObject* Reader_get_closed(Reader *self, void *closure)
+{
+    return PyBool_FromLong(self->j == NULL);
+}
+
+static PyGetSetDef Reader_getsetters[] = {
     {(char*) "data_threshold",
      (getter) Reader_get_data_threshold,
      (setter) Reader_set_data_threshold,
      (char*) data_threshold__doc__,
      NULL},
+    {(char*) "closed",
+     (getter) Reader_get_closed,
+     NULL,
+     (char*) closed__doc__,
+     NULL},
     {NULL}
 };
 
@@ -727,7 +739,7 @@ static PyTypeObject ReaderType = {
     Reader_iternext,                          /* tp_iternext */
     Reader_methods,                           /* tp_methods */
     0,                                        /* tp_members */
-    Reader_getseters,                         /* tp_getset */
+    Reader_getsetters,                        /* tp_getset */
     0,                                        /* tp_base */
     0,                                        /* tp_dict */
     0,                                        /* tp_descr_get */

commit 52aeb63cffcdb3701cdc2ca41868208de2347318
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Mar 15 18:00:57 2013 -0400

    journalctl: use _cleanup_ in one function

diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index a6ad055..8aef923 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -513,16 +513,16 @@ static int generate_new_id128(void) {
 
 static int add_matches(sd_journal *j, char **args) {
         char **i;
-        int r;
 
         assert(j);
 
         STRV_FOREACH(i, args) {
+                int r;
 
                 if (streq(*i, "+"))
                         r = sd_journal_add_disjunction(j);
                 else if (path_is_absolute(*i)) {
-                        char *p, *t = NULL;
+                        char _cleanup_free_ *p, *t = NULL;
                         const char *path;
                         struct stat st;
 
@@ -530,7 +530,6 @@ static int add_matches(sd_journal *j, char **args) {
                         path = p ? p : *i;
 
                         if (stat(path, &st) < 0)  {
-                                free(p);
                                 log_error("Couldn't stat file: %m");
                                 return -errno;
                         }
@@ -542,18 +541,14 @@ static int add_matches(sd_journal *j, char **args) {
                         else if (S_ISBLK(st.st_mode))
                                 asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
                         else {
-                                free(p);
                                 log_error("File is not a device node, regular file or is not executable: %s", *i);
                                 return -EINVAL;
                         }
 
-                        free(p);
-
                         if (!t)
                                 return log_oom();
 
                         r = sd_journal_add_match(j, t, 0);
-                        free(t);
                 } else
                         r = sd_journal_add_match(j, *i, 0);
 



More information about the systemd-commits mailing list