[systemd-commits] 10 commits - Makefile.am man/systemd-journal-gatewayd.service.xml src/journal src/shared

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Thu Jan 17 22:42:49 PST 2013


 Makefile.am                              |   38 +----
 man/systemd-journal-gatewayd.service.xml |   50 +++++++
 src/journal/journal-gatewayd.c           |  200 ++++++++++++++++++++++++-------
 src/journal/microhttpd-util.c            |   37 +++++
 src/journal/microhttpd-util.h            |   26 ++++
 src/shared/log.c                         |   87 ++++++-------
 6 files changed, 318 insertions(+), 120 deletions(-)

New commits:
commit c3a7cfb7dee251cab01e98a399e7d2a0f787b6b9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Jan 18 01:41:01 2013 -0500

    journal-gatewayd,man: document new HTTPS options

diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index 562d221..37b39c2 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -52,7 +52,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
   <refsynopsisdiv>
     <para><filename>systemd-journal-gatewayd.service</filename></para>
     <para><filename>systemd-journal-gatewayd.socket</filename></para>
-    <cmdsynopsis><command>/usr/lib/systemd/systemd-journal-gatewayd</command>
+    <cmdsynopsis>
+      <command>/usr/lib/systemd/systemd-journal-gatewayd</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -61,7 +63,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
     <para><command>systemd-journal-gatewayd</command> serves journal
     events over the network. Clients must connect using
-    HTTP. The server listens on port 19531 by default.</para>
+    HTTP. The server listens on port 19531 by default.
+    If <option>--cert=</option> is specified, the server expects
+    HTTPS connections.</para>
 
     <para>The program is started by
     <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
@@ -72,6 +76,48 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
   </refsect1>
 
   <refsect1>
+    <title>Options</title>
+
+    <para>The following options are understood:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>--help</option></term>
+        <term><option>-h</option></term>
+
+        <listitem><para>Prints a short help
+        text and exits.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--version</option></term>
+
+        <listitem><para>Prints a short version
+        string and exits.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cert=</option></term>
+
+        <listitem><para>Specify the path to a file containing a server
+        certificate in PEM format. This option switches
+        <command>systemd-journal-gatewayd</command> into HTTPS mode
+        and must be used together with
+        <option>--key=</option>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--key=</option></term>
+
+        <listitem><para>Specify the path to a file containing a server
+        key in PEM format corresponding to the certificate specified
+        with <option>--cert=</option>.</para></listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
     <title>Supported URLs</title>
 
     <para>The following URLs are recognized:</para>
diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 4a4905d..dfec835 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -862,6 +862,19 @@ static int request_handler(
         return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
 }
 
+static int help(void) {
+
+        printf("%s [OPTIONS...] ...\n\n"
+               "HTTP server for journal events.\n\n"
+               "  -h --help           Show this help\n"
+               "     --version        Show package version\n"
+               "     --cert=CERT.PEM  Specify server certificate in PEM format\n"
+               "     --key=KEY.PEM    Specify server key in PEM format\n",
+               program_invocation_short_name);
+
+        return 0;
+}
+
 static char *key_pem = NULL;
 static char *cert_pem = NULL;
 
@@ -875,6 +888,7 @@ static int parse_argv(int argc, char *argv[]) {
         int r, c;
 
         static const struct option options[] = {
+                { "help",    no_argument,       NULL, 'h'         },
                 { "version", no_argument,       NULL, ARG_VERSION },
                 { "key",     required_argument, NULL, ARG_KEY     },
                 { "cert",    required_argument, NULL, ARG_CERT    },
@@ -884,13 +898,16 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
                 switch(c) {
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
                         puts(SYSTEMD_FEATURES);
                         return 0;
 
+                case 'h':
+                        return help();
+
                 case ARG_KEY:
                         if (key_pem) {
                                 log_error("Key file specified twice");

commit a93035cee3df135b72b8ff6c1d8361e2e647ed0b
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Jan 17 01:53:01 2013 -0500

    journal-gatewayd: return nice error on unsupported methods
    
    Returns "HTTP/1.0 406 Not Acceptable" instead of silently
    closing the connection.

diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 23939cc..4a4905d 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -834,7 +834,9 @@ static int request_handler(
         assert(method);
 
         if (!streq(method, "GET"))
-                return MHD_NO;
+                return respond_error(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE,
+                                     "Unsupported method.\n");
+
 
         if (!*connection_cls) {
                 if (!request_meta(connection_cls))

commit 8530a1436a50b3cfb6dc6231834bd04f56118d31
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Nov 28 18:32:01 2012 +0100

    journal-gatewayd: allow pipelining
    
    The request must not be answered immediately (at first call to
    response_handler()), but on the second. This is also important
    for authentication, which cannot be performed on the first call.
    
    Before:
    
    % wget -O/dev/null -S https://localhost:19531/
    --2012-11-28 18:29:43--  https://localhost:19531/
    Resolving localhost (localhost)... 127.0.0.1
    Connecting to localhost (localhost)|127.0.0.1|:19531... connected.
    HTTP request sent, awaiting response...
      HTTP/1.1 301 Moved Permanently
      Connection: close
      Content-Length: 87
      Location: /browse
      Content-Type: text/html
      Date: Wed, 28 Nov 2012 17:29:44 GMT
    Location: /browse [following]
    --2012-11-28 18:29:43--  https://localhost:19531/browse
    Connecting to localhost (localhost)|127.0.0.1|:19531... connected.
    HTTP request sent, awaiting response...
      HTTP/1.1 200 OK
      Connection: close
      Content-Length: 23260
      Content-Type: text/html
      Date: Wed, 28 Nov 2012 17:29:44 GMT
    Length: 23260 (23K) [text/html]
    
    After:
    
    % wget --no-check-certificate -O/dev/null -S https://localhost:19531/
    --2012-11-28 18:30:05--  https://localhost:19531/
    Resolving localhost (localhost)... 127.0.0.1
    Connecting to localhost (localhost)|127.0.0.1|:19531... connected.
    HTTP request sent, awaiting response...
      HTTP/1.1 301 Moved Permanently
      Content-Length: 87
      Location: /browse
      Content-Type: text/html
      Date: Wed, 28 Nov 2012 17:30:05 GMT
    Location: /browse [following]
    --2012-11-28 18:30:05--  https://localhost:19531/browse
    Reusing existing connection to localhost:19531.
    HTTP request sent, awaiting response...
      HTTP/1.1 200 OK
      Content-Length: 23260
      Content-Type: text/html
      Date: Wed, 28 Nov 2012 17:30:06 GMT
    Length: 23260 (23K) [text/html]

diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 613b539..23939cc 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -482,18 +482,14 @@ static int request_parse_arguments(
 
 static int request_handler_entries(
                 struct MHD_Connection *connection,
-                void **connection_cls) {
+                void *connection_cls) {
 
         struct MHD_Response *response;
-        RequestMeta *m;
+        RequestMeta *m = connection_cls;
         int r;
 
         assert(connection);
-        assert(connection_cls);
-
-        m = request_meta(connection_cls);
-        if (!m)
-                return respond_oom(connection);
+        assert(m);
 
         r = open_journal(m);
         if (r < 0)
@@ -651,15 +647,11 @@ static int request_handler_fields(
                 void *connection_cls) {
 
         struct MHD_Response *response;
-        RequestMeta *m;
+        RequestMeta *m = connection_cls;
         int r;
 
         assert(connection);
-        assert(connection_cls);
-
-        m = request_meta(connection_cls);
-        if (!m)
-                return respond_oom(connection);
+        assert(m);
 
         r = open_journal(m);
         if (r < 0)
@@ -750,10 +742,10 @@ static int request_handler_file(
 
 static int request_handler_machine(
                 struct MHD_Connection *connection,
-                void **connection_cls) {
+                void *connection_cls) {
 
         struct MHD_Response *response;
-        RequestMeta *m;
+        RequestMeta *m = connection_cls;
         int r;
         _cleanup_free_ char* hostname = NULL, *os_name = NULL;
         uint64_t cutoff_from, cutoff_to, usage;
@@ -762,10 +754,7 @@ static int request_handler_machine(
         const char *v = "bare";
 
         assert(connection);
-
-        m = request_meta(connection_cls);
-        if (!m)
-                return respond_oom(connection);
+        assert(m);
 
         r = open_journal(m);
         if (r < 0)
@@ -840,26 +829,33 @@ static int request_handler(
                 void **connection_cls) {
 
         assert(connection);
+        assert(connection_cls);
         assert(url);
         assert(method);
 
         if (!streq(method, "GET"))
                 return MHD_NO;
 
+        if (!*connection_cls) {
+                if (!request_meta(connection_cls))
+                        return respond_oom(connection);
+                return MHD_YES;
+        }
+
         if (streq(url, "/"))
                 return request_handler_redirect(connection, "/browse");
 
         if (streq(url, "/entries"))
-                return request_handler_entries(connection, connection_cls);
+                return request_handler_entries(connection, *connection_cls);
 
         if (startswith(url, "/fields/"))
-                return request_handler_fields(connection, url + 8, connection_cls);
+                return request_handler_fields(connection, url + 8, *connection_cls);
 
         if (streq(url, "/browse"))
                 return request_handler_file(connection, DOCUMENT_ROOT "/browse.html", "text/html");
 
         if (streq(url, "/machine"))
-                return request_handler_machine(connection, connection_cls);
+                return request_handler_machine(connection, *connection_cls);
 
         return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
 }

commit 9775033d260f62869d29654a27113b809a03dad9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Wed Nov 28 18:00:09 2012 +0100

    journal-gatewayd: always log oom() in addition to returning error

diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index bb9bd44..613b539 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -110,7 +110,7 @@ static int open_journal(RequestMeta *m) {
 }
 
 
-static int respond_oom(struct MHD_Connection *connection) {
+static int respond_oom_internal(struct MHD_Connection *connection) {
         struct MHD_Response *response;
         const char m[] = "Out of memory.\n";
         int ret;
@@ -128,6 +128,8 @@ static int respond_oom(struct MHD_Connection *connection) {
         return ret;
 }
 
+#define respond_oom(connection) log_oom(), respond_oom_internal(connection)
+
 static int respond_error(
                 struct MHD_Connection *connection,
                 unsigned code,

commit e429981ba45894fe51d93956278badb61311bb99
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Nov 26 16:39:46 2012 +0100

    share/log: skip file/line/func info if empty
    
    The new microhttpd logger doesn't know this information. It is
    better to log nothing than fake values.

diff --git a/src/shared/log.c b/src/shared/log.c
index b39b5ac..293c261 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -448,16 +448,22 @@ static int log_do_header(char *header, size_t size,
         snprintf(header, size,
                  "PRIORITY=%i\n"
                  "SYSLOG_FACILITY=%i\n"
-                 "CODE_FILE=%s\n"
-                 "CODE_LINE=%i\n"
-                 "CODE_FUNCTION=%s\n"
+                 "%s%.*s%s"
+                 "%s%.*i%s"
+                 "%s%.*s%s"
                  "%s%.*s%s"
                  "SYSLOG_IDENTIFIER=%s\n",
                  LOG_PRI(level),
                  LOG_FAC(level),
-                 file,
-                 line,
-                 func,
+                 file ? "CODE_FILE=" : "",
+                 file ? LINE_MAX : 0, file, /* %.0s means no output */
+                 file ? "\n" : "",
+                 line ? "CODE_LINE=" : "",
+                 line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
+                 line ? "\n" : "",
+                 func ? "CODE_FUNCTION=" : "",
+                 func ? LINE_MAX : 0, func,
+                 func ? "\n" : "",
                  object ? object_name : "",
                  object ? LINE_MAX : 0, object, /* %.0s means no output */
                  object ? "\n" : "",

commit 41a79f1062d77f95248b92b91b3b788f886aa93f
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Nov 26 16:39:46 2012 +0100

    share/log: unify two code paths
    
    Explicit zeroing is replaced with initialization to {0}.
    
    No functional change.

diff --git a/src/shared/log.c b/src/shared/log.c
index 8d3458e..b39b5ac 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -441,31 +441,18 @@ static int write_to_kmsg(
         return 1;
 }
 
-static int write_to_journal(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *buffer) {
-
-        char header[LINE_MAX];
-        struct iovec iovec[3];
-        struct msghdr mh;
-
-        if (journal_fd < 0)
-                return 0;
-
-        snprintf(header, sizeof(header),
+static int log_do_header(char *header, size_t size,
+                         int level,
+                         const char *file, int line, const char *func,
+                         const char *object_name, const char *object) {
+        snprintf(header, size,
                  "PRIORITY=%i\n"
                  "SYSLOG_FACILITY=%i\n"
                  "CODE_FILE=%s\n"
                  "CODE_LINE=%i\n"
                  "CODE_FUNCTION=%s\n"
                  "%s%.*s%s"
-                 "SYSLOG_IDENTIFIER=%s\n"
-                 "MESSAGE=",
+                 "SYSLOG_IDENTIFIER=%s\n",
                  LOG_PRI(level),
                  LOG_FAC(level),
                  file,
@@ -475,15 +462,34 @@ static int write_to_journal(
                  object ? LINE_MAX : 0, object, /* %.0s means no output */
                  object ? "\n" : "",
                  program_invocation_short_name);
+        header[size - 1] = '\0';
+        return 0;
+}
 
-        char_array_0(header);
+static int write_to_journal(
+        int level,
+        const char*file,
+        int line,
+        const char *func,
+        const char *object_name,
+        const char *object,
+        const char *buffer) {
+
+        char header[LINE_MAX];
+        struct iovec iovec[4] = {{0}};
+        struct msghdr mh = {0};
+
+        if (journal_fd < 0)
+                return 0;
+
+        log_do_header(header, sizeof(header), level,
+                      file, line, func, object_name, object);
 
-        zero(iovec);
         IOVEC_SET_STRING(iovec[0], header);
-        IOVEC_SET_STRING(iovec[1], buffer);
-        IOVEC_SET_STRING(iovec[2], "\n");
+        IOVEC_SET_STRING(iovec[1], "MESSAGE=");
+        IOVEC_SET_STRING(iovec[2], buffer);
+        IOVEC_SET_STRING(iovec[3], "\n");
 
-        zero(mh);
         mh.msg_iov = iovec;
         mh.msg_iovlen = ELEMENTSOF(iovec);
 
@@ -744,29 +750,14 @@ int log_struct_internal(
             journal_fd >= 0) {
 
                 char header[LINE_MAX];
-                struct iovec iovec[17];
+                struct iovec iovec[17] = {{0}};
                 unsigned n = 0, i;
                 struct msghdr mh;
-                const char nl = '\n';
+                static const char nl = '\n';
 
                 /* If the journal is available do structured logging */
-
-                snprintf(header, sizeof(header),
-                        "PRIORITY=%i\n"
-                        "SYSLOG_FACILITY=%i\n"
-                        "CODE_FILE=%s\n"
-                        "CODE_LINE=%i\n"
-                        "CODE_FUNCTION=%s\n"
-                        "SYSLOG_IDENTIFIER=%s\n",
-                        LOG_PRI(level),
-                        LOG_FAC(level),
-                        file,
-                        line,
-                        func,
-                        program_invocation_short_name);
-                char_array_0(header);
-
-                zero(iovec);
+                log_do_header(header, sizeof(header), level,
+                              file, line, func, NULL, NULL);
                 IOVEC_SET_STRING(iovec[n++], header);
 
                 va_start(ap, format);

commit e64690a85772fc77ba9e825333eb1ced5a202ad1
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Nov 25 23:54:31 2012 +0100

    journal-gatewayd: redirect microhttpd messages to journal
    
    A prefix ("microhttpd: ") is added to the log lines to make it easy to
    distinguish the source.

diff --git a/Makefile.am b/Makefile.am
index 752857a..ab9fb99 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2799,7 +2799,9 @@ rootlibexec_PROGRAMS += \
 	systemd-journal-gatewayd
 
 systemd_journal_gatewayd_SOURCES = \
-	src/journal/journal-gatewayd.c
+	src/journal/journal-gatewayd.c \
+	src/journal/microhttpd-util.h \
+	src/journal/microhttpd-util.c
 
 systemd_journal_gatewayd_LDADD = \
 	libsystemd-shared.la \
diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 6922ebc..bb9bd44 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -32,6 +32,7 @@
 #include "sd-journal.h"
 #include "sd-daemon.h"
 #include "logs-show.h"
+#include "microhttpd-util.h"
 #include "virt.h"
 #include "build.h"
 
@@ -962,11 +963,13 @@ int main(int argc, char *argv[]) {
                 struct MHD_OptionItem opts[] = {
                         { MHD_OPTION_NOTIFY_COMPLETED,
                           (intptr_t) request_meta_free, NULL },
+                        { MHD_OPTION_EXTERNAL_LOGGER,
+                          (intptr_t) microhttpd_logger, NULL },
                         { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL }};
-                int opts_pos = 1;
+                int opts_pos = 2;
                 int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG;
 
                 if (n > 0)
diff --git a/src/journal/microhttpd-util.c b/src/journal/microhttpd-util.c
new file mode 100644
index 0000000..dc91b81
--- /dev/null
+++ b/src/journal/microhttpd-util.c
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "microhttpd-util.h"
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+
+void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
+        char _cleanup_free_ *f;
+        if (asprintf(&f, "microhttpd: %s", fmt) <= 0) {
+                log_oom();
+                return;
+        }
+        log_metav(LOG_INFO, NULL, 0, NULL, f, ap);
+}
diff --git a/src/journal/microhttpd-util.h b/src/journal/microhttpd-util.h
new file mode 100644
index 0000000..d4fefa7
--- /dev/null
+++ b/src/journal/microhttpd-util.h
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdarg.h>
+
+void microhttpd_logger(void *arg, const char *fmt, va_list ap);

commit 858634ff0e158757dfd630f4da72e790a42e60dd
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Nov 25 23:26:15 2012 +0100

    journal-gatewayd: SSL support
    
    For now the certificates are passed around as options to the
    program. This might not be the most convenient under "production",
    but makes for fairly easy testing.

diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 9c33218..6922ebc 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <getopt.h>
 
 #include <microhttpd.h>
 
@@ -32,6 +33,7 @@
 #include "sd-daemon.h"
 #include "logs-show.h"
 #include "virt.h"
+#include "build.h"
 
 typedef struct RequestMeta {
         sd_journal *journal;
@@ -859,19 +861,96 @@ static int request_handler(
         return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
 }
 
-int main(int argc, char *argv[]) {
-        struct MHD_Daemon *d = NULL;
-        int r = EXIT_FAILURE, n;
+static char *key_pem = NULL;
+static char *cert_pem = NULL;
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_KEY,
+                ARG_CERT,
+        };
+
+        int r, c;
+
+        static const struct option options[] = {
+                { "version", no_argument,       NULL, ARG_VERSION },
+                { "key",     required_argument, NULL, ARG_KEY     },
+                { "cert",    required_argument, NULL, ARG_CERT    },
+                { NULL,      0,                 NULL, 0           }
+        };
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
+                switch(c) {
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_KEY:
+                        if (key_pem) {
+                                log_error("Key file specified twice");
+                                return -EINVAL;
+                        }
+                        r = read_full_file(optarg, &key_pem, NULL);
+                        if (r < 0) {
+                                log_error("Failed to read key file: %s", strerror(-r));
+                                return r;
+                        }
+                        assert(key_pem);
+                        break;
 
-        if (argc > 1) {
+                case ARG_CERT:
+                        if (cert_pem) {
+                                log_error("Certificate file specified twice");
+                                return -EINVAL;
+                        }
+                        r = read_full_file(optarg, &cert_pem, NULL);
+                        if (r < 0) {
+                                log_error("Failed to read certificate file: %s", strerror(-r));
+                                return r;
+                        }
+                        assert(cert_pem);
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        log_error("Unknown option code %c", c);
+                        return -EINVAL;
+                }
+
+        if (optind < argc) {
                 log_error("This program does not take arguments.");
-                goto finish;
+                return -EINVAL;
+        }
+
+        if (!!key_pem != !!cert_pem) {
+                log_error("Certificate and key files must be specified together");
+                return -EINVAL;
         }
 
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        struct MHD_Daemon *d = NULL;
+        int r, n;
+
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
 
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                return EXIT_FAILURE;
+        if (r == 0)
+                return EXIT_SUCCESS;
+
         n = sd_listen_fds(1);
         if (n < 0) {
                 log_error("Failed to determine passed sockets: %s", strerror(-n));
@@ -884,18 +963,29 @@ int main(int argc, char *argv[]) {
                         { MHD_OPTION_NOTIFY_COMPLETED,
                           (intptr_t) request_meta_free, NULL },
                         { MHD_OPTION_END, 0, NULL },
+                        { MHD_OPTION_END, 0, NULL },
+                        { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL }};
+                int opts_pos = 1;
+                int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG;
+
                 if (n > 0)
-                        opts[1] = (struct MHD_OptionItem)
-                                {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, NULL};
-
-                d = MHD_start_daemon(
-                                MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG,
-                                19531,
-                                NULL, NULL,
-                                request_handler, NULL,
-                                MHD_OPTION_ARRAY, opts,
-                                MHD_OPTION_END);
+                        opts[opts_pos++] = (struct MHD_OptionItem)
+                                {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START};
+                if (key_pem) {
+                        assert(cert_pem);
+                        opts[opts_pos++] = (struct MHD_OptionItem)
+                                {MHD_OPTION_HTTPS_MEM_KEY, 0, key_pem};
+                        opts[opts_pos++] = (struct MHD_OptionItem)
+                                {MHD_OPTION_HTTPS_MEM_CERT, 0, cert_pem};
+                        flags |= MHD_USE_SSL;
+                }
+
+                d = MHD_start_daemon(flags, 19531,
+                                     NULL, NULL,
+                                     request_handler, NULL,
+                                     MHD_OPTION_ARRAY, opts,
+                                     MHD_OPTION_END);
         }
 
         if (!d) {

commit c54ff8e3586adec9e21c525bf0fa1fa0b73006d6
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Nov 25 23:21:22 2012 +0100

    journal-gatewayd: unify two code paths
    
    In preparation for adding more options, split out the option
    handling code.

diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c
index 63d9744..9c33218 100644
--- a/src/journal/journal-gatewayd.c
+++ b/src/journal/journal-gatewayd.c
@@ -879,22 +879,22 @@ int main(int argc, char *argv[]) {
         } else if (n > 1) {
                 log_error("Can't listen on more than one socket.");
                 goto finish;
-        } else if (n > 0) {
-                d = MHD_start_daemon(
-                                MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG,
-                                19531,
-                                NULL, NULL,
-                                request_handler, NULL,
-                                MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START,
-                                MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL,
-                                MHD_OPTION_END);
         } else {
+                struct MHD_OptionItem opts[] = {
+                        { MHD_OPTION_NOTIFY_COMPLETED,
+                          (intptr_t) request_meta_free, NULL },
+                        { MHD_OPTION_END, 0, NULL },
+                        { MHD_OPTION_END, 0, NULL }};
+                if (n > 0)
+                        opts[1] = (struct MHD_OptionItem)
+                                {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, NULL};
+
                 d = MHD_start_daemon(
-                                MHD_USE_DEBUG|MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL,
+                                MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG,
                                 19531,
                                 NULL, NULL,
                                 request_handler, NULL,
-                                MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL,
+                                MHD_OPTION_ARRAY, opts,
                                 MHD_OPTION_END);
         }
 

commit a6c4586586af4656e827014a4df1918103d9d5f2
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Jan 17 23:49:05 2013 -0500

    build-sys: keep noninstallable tests in noinst_tests
    
    Repeating all tests in noinst_PROGRAMS and TESTS is pointless.
    This way it is also clearer which noinst_PROGRAMs are not
    part of the test suite.

diff --git a/Makefile.am b/Makefile.am
index db68522..752857a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -118,8 +118,9 @@ dbusinterface_DATA =
 dist_dbussystemservice_DATA =
 check_PROGRAMS =
 check_DATA =
-noinst_PROGRAMS =
-TESTS =
+noinst_tests=
+noinst_PROGRAMS = $(noinst_tests)
+TESTS = $(noinst_tests)
 udevlibexec_PROGRAMS =
 
 AM_CPPFLAGS = \
@@ -1173,27 +1174,16 @@ CLEANFILES += \
 # ------------------------------------------------------------------------------
 noinst_PROGRAMS += \
 	test-engine \
-	test-job-type \
 	test-ns \
 	test-loopback \
 	test-hostname \
 	test-daemon \
 	test-cgroup \
-	test-env-replace \
-	test-strv \
 	test-install \
 	test-watchdog \
-	test-unit-name \
-	test-log \
-	test-unit-file \
-	test-date \
-	test-sleep \
-	test-replace-var \
-	test-sched-prio \
-	test-calendarspec \
-	test-strip-tab-ansi
+	test-log
 
-TESTS += \
+noinst_tests += \
 	test-job-type \
 	test-env-replace \
 	test-strv \
@@ -2438,10 +2428,7 @@ test_id128_LDADD = \
 	libsystemd-shared.la \
 	libsystemd-id128-internal.la
 
-noinst_PROGRAMS += \
-	test-id128
-
-TESTS += \
+noinst_tests += \
 	test-id128
 
 pkginclude_HEADERS += \
@@ -2731,17 +2718,10 @@ UNINSTALL_DATA_HOOKS += \
 	catalog-remove-hook
 
 noinst_PROGRAMS += \
-	test-journal \
-	test-journal-send \
-	test-journal-syslog \
-	test-journal-match \
 	test-journal-enum \
-	test-journal-stream \
-	test-journal-verify \
-	test-mmap-cache \
 	test-catalog
 
-TESTS += \
+noinst_tests += \
 	test-journal \
 	test-journal-send \
 	test-journal-syslog \



More information about the systemd-commits mailing list