1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 40e996e..fc4fb01 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -19,6 +19,7 @@ option(LINK_SUPPORT "Allow hub linking" OFF)
6 option(SSL_SUPPORT "Enable SSL support" ON)
7 option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
8 option(SQLITE_SUPPORT "Enable SQLite support" ON)
9+option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
10 option(ADC_STRESS "Enable the stress tester client" OFF)
11
12 find_package(Git)
13@@ -34,6 +35,12 @@ if (SSL_SUPPORT)
14 endif()
15 endif()
16
17+if (SYSTEMD_SUPPORT)
18+ INCLUDE(FindPkgConfig)
19+ pkg_search_module(SD_DAEMON REQUIRED libsystemd-daemon)
20+ pkg_search_module(SD_JOURNAL REQUIRED libsystemd-journal)
21+endif()
22+
23 if (MSVC)
24 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
25 endif()
26@@ -175,6 +182,18 @@ if(SSL_SUPPORT)
27 endif()
28 endif()
29
30+if (SYSTEMD_SUPPORT)
31+ target_link_libraries(uhub ${SD_DAEMON_LIBRARIES})
32+ target_link_libraries(uhub ${SD_JOURNAL_LIBRARIES})
33+ target_link_libraries(test ${SD_DAEMON_LIBRARIES})
34+ target_link_libraries(test ${SD_JOURNAL_LIBRARIES})
35+ target_link_libraries(uhub-passwd ${SD_JOURNAL_LIBRARIES})
36+ target_link_libraries(uhub-admin ${SD_JOURNAL_LIBRARIES})
37+ include_directories(${SD_DAEMON_INCLUDE_DIRS})
38+ include_directories(${SD_JOURNAL_INCLUDE_DIRS})
39+ add_definitions(-DSYSTEMD)
40+endif()
41+
42 configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
43
44 mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
45diff --git a/src/core/main.c b/src/core/main.c
46index bb78672..ac2d2a8 100644
47--- a/src/core/main.c
48+++ b/src/core/main.c
49@@ -19,6 +19,10 @@
50
51 #include "uhub.h"
52
53+#ifdef SYSTEMD
54+#include <systemd/sd-daemon.h>
55+#endif
56+
57 static int arg_verbose = 5;
58 static int arg_fork = 0;
59 static int arg_check_config = 0;
60@@ -145,7 +149,16 @@ int main_loop()
61 }
62 #if !defined(WIN32)
63 setup_signal_handlers(hub);
64-#endif
65+#ifdef SYSTEMD
66+ /* Notify the service manager that this daemon has
67+ * been successfully initalized and shall enter the
68+ * main loop.
69+ */
70+ sd_notifyf(0, "READY=1\n"
71+ "MAINPID=%lu", (unsigned long) getpid());
72+#endif /* SYSTEMD */
73+
74+#endif /* ! WIN32 */
75 }
76
77 hub_set_variables(hub, &acl);
78@@ -216,13 +229,17 @@ void print_usage(char* program)
79 " -q Quiet mode - no output\n"
80 " -f Fork to background\n"
81 " -l <file> Log messages to given file (default: stderr)\n"
82- " -L Log messages to syslog\n"
83 " -c <file> Specify configuration file (default: " SERVER_CONFIG ")\n"
84 " -C Check configuration and return\n"
85 " -s Show configuration parameters\n"
86 " -S Show configuration parameters, but ignore defaults\n"
87 " -h This message\n"
88 #ifndef WIN32
89+#ifdef SYSTEMD
90+ " -L Log messages to journal\n"
91+#else
92+ " -L Log messages to syslog\n"
93+#endif
94 " -u <user> Run as given user\n"
95 " -g <group> Run with given group permissions\n"
96 " -p <file> Store pid in file (process id)\n"
97diff --git a/src/util/log.c b/src/util/log.c
98index 42badb3..2d97528 100644
99--- a/src/util/log.c
100+++ b/src/util/log.c
101@@ -21,7 +21,15 @@
102 #include <locale.h>
103
104 #ifndef WIN32
105+
106+#ifdef SYSTEMD
107+#define SD_JOURNAL_SUPPRESS_LOCATION
108+#include <systemd/sd-journal.h>
109+
110+#else
111 #include <syslog.h>
112+#endif
113+
114 static int use_syslog = 0;
115 #endif
116
117@@ -83,7 +91,9 @@ void hub_log_initialize(const char* file, int syslog)
118 if (syslog)
119 {
120 use_syslog = 1;
121+ #ifndef SYSTEMD
122 openlog("uhub", LOG_PID, LOG_USER);
123+ #endif
124 }
125 #endif
126
127@@ -132,7 +142,9 @@ void hub_log_shutdown()
128 if (use_syslog)
129 {
130 use_syslog = 0;
131+ #ifndef SYSTEMD
132 closelog();
133+ #endif
134 }
135 #endif
136 }
137@@ -212,7 +224,12 @@ void hub_log(int log_verbosity, const char *format, ...)
138 case log_fatal: level = LOG_CRIT; break;
139 case log_error: level = LOG_ERR; break;
140 case log_warning: level = LOG_WARNING; break;
141- case log_user: level = LOG_INFO | LOG_AUTH; break;
142+ #ifdef SYSTEMD
143+ case log_user: level = LOG_INFO; break;
144+
145+ #else
146+ case log_user: level = LOG_INFO | LOG_AUTH; break;
147+ #endif
148 case log_info: level = LOG_INFO; break;
149 case log_debug: level = LOG_DEBUG; break;
150
151@@ -224,8 +241,13 @@ void hub_log(int log_verbosity, const char *format, ...)
152 if (level == 0)
153 return;
154
155+ #ifdef SYSTEMD
156+ sd_journal_print(level, "%s", logmsg);
157+
158+ #else
159 level |= (LOG_USER | LOG_DAEMON);
160 syslog(level, "%s", logmsg);
161+ #endif
162 }
163 #endif
164