2 * Copyright (C) 2011 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include <glib/gi18n.h>
30 #include "session-common.h"
32 #include <syncevo/SyncContext.h>
33 #include <syncevo/SuspendFlags.h>
34 #include <syncevo/LogRedirect.h>
35 #include <syncevo/LogSyslog.h>
36 #include <syncevo/GLibSupport.h>
38 using namespace SyncEvo;
39 using namespace GDBusCXX;
42 GMainLoop *loop = NULL;
43 bool shutdownRequested = false;
44 const char * const execName = "syncevo-dbus-server";
45 const char * const debugEnv = "SYNCEVOLUTION_DEBUG";
49 shutdownRequested = true;
50 SuspendFlags::getSuspendFlags().handleSignal(sig);
51 g_main_loop_quit (loop);
54 bool parseDuration(int &duration, const char* value)
58 } else if (boost::iequals(value, "unlimited")) {
61 } else if ((duration = atoi(value)) > 0) {
68 } // anonymous namespace
70 static Logger::Level checkLogLevel(const char *option, int logLevel)
73 case 0: return Logger::NONE;
74 case 1: return Logger::ERROR;
75 case 2: return Logger::INFO;
76 case 3: return Logger::DEBUG;
78 SE_THROW(StringPrintf("invalid parameter value %d for %s: must be one of 0, 1, 2 or 3", logLevel, option));
83 int main(int argc, char **argv, char **envp)
85 // remember environment for restart
86 boost::shared_ptr<Restart> restart;
87 restart.reset(new Restart(argv, envp));
89 // Internationalization for auto sync messages.
90 setlocale(LC_ALL, "");
91 bindtextdomain(GETTEXT_PACKAGE,
92 getEnv("SYNCEVOLUTION_LOCALE_DIR", SYNCEVOLUTION_LOCALEDIR));
93 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
94 textdomain(GETTEXT_PACKAGE);
97 gchar *durationString = NULL;
100 int logLevelDBus = 2;
101 gboolean stdoutEnabled = false;
102 gboolean syslogEnabled = true;
103 #ifdef ENABLE_DBUS_PIM
104 gboolean startPIM = false;
106 static GOptionEntry entries[] = {
107 { "duration", 'd', 0, G_OPTION_ARG_STRING, &durationString, "Shut down automatically when idle for this duration", "seconds/'unlimited'" },
108 { "verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevel,
109 "Choose amount of output, 0 = no output, 1 = errors, 2 = info, 3 = debug; default is 1.",
111 { "dbus-verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevelDBus,
112 "Choose amount of output via D-Bus signals, 0 = no output, 1 = errors, 2 = info, 3 = debug; default is 2.",
114 { "stdout", 'o', 0, G_OPTION_ARG_NONE, &stdoutEnabled,
115 "Enable printing to stdout (result of operations) and stderr (errors/info/debug).",
117 { "no-syslog", 's', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &syslogEnabled, "Disable printing to syslog.", NULL },
118 #ifdef ENABLE_DBUS_PIM
119 { "start-pim", 'p', 0, G_OPTION_ARG_NONE, &startPIM,
120 "Activate the PIM Manager (= unified address book) immediately.",
126 static GOptionContext *context = g_option_context_new("- SyncEvolution D-Bus Server");
127 g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
128 bool success = g_option_context_parse(context, &argc, &argv, gerror);
129 PlainGStr durationOwner(durationString);
131 gerror.throwError("parsing command line options");
133 if (durationString && !parseDuration(duration, durationString)) {
134 SE_THROW(StringPrintf("invalid parameter value '%s' for --duration/-d: must be positive number of seconds or 'unlimited'", durationString));
136 Logger::Level level = checkLogLevel("--debug", logLevel);
137 Logger::Level levelDBus = checkLogLevel("--dbus-debug", logLevelDBus);
139 // Temporarily set G_DBUS_DEBUG. Hopefully GIO will read and
140 // remember it, because we don't want to keep it set
141 // permanently, lest it gets passed on to other processes.
142 const char *gdbus = getenv("SYNCEVOLUTION_DBUS_SERVER_GDBUS");
144 setenv("G_DBUS_DEBUG", gdbus, 1);
147 SyncContext::initMain(execName);
149 loop = g_main_loop_new (NULL, FALSE);
151 setvbuf(stderr, NULL, _IONBF, 0);
152 setvbuf(stdout, NULL, _IONBF, 0);
154 // Redirect output and optionally log to syslog.
155 PushLogger<LogRedirect> redirect(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
156 redirect->setLevel(stdoutEnabled ? level : Logger::NONE);
157 PushLogger<LoggerSyslog> syslogger;
158 if (syslogEnabled && level > Logger::NONE) {
159 syslogger.reset(new LoggerSyslog(execName));
160 syslogger->setLevel(level);
163 // syncevo-dbus-server should hardly ever produce output that
164 // is relevant for end users, so include the somewhat cryptic
165 // process name for developers in this process, and not in
166 // syncevo-dbus-helper.
167 Logger::setProcessName("syncevo-dbus-server");
169 SE_LOG_DEBUG(NULL, "syncevo-dbus-server: catch SIGINT/SIGTERM in our own shutdown function");
170 signal(SIGTERM, niam);
171 signal(SIGINT, niam);
172 boost::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
175 DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
176 SessionCommon::SERVICE_NAME,
180 err.throwFailure("dbus_get_bus_connection()", " failed - server already running?");
182 // make this object the main owner of the connection
183 boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
185 boost::shared_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, shutdownRequested, restart, conn, duration));
186 server->setDBusLogLevel(levelDBus);
189 #ifdef ENABLE_DBUS_PIM
190 boost::shared_ptr<GDBusCXX::DBusObjectHelper> manager(SyncEvo::CreateContactManager(server, startPIM));
194 unsetenv("G_DBUS_DEBUG");
197 dbus_bus_connection_undelay(conn);
199 SE_LOG_DEBUG(NULL, "cleaning up");
200 #ifdef ENABLE_DBUS_PIM
206 SE_LOG_DEBUG(NULL, "flushing D-Bus connection");
209 SE_LOG_INFO(NULL, "terminating, closing logging");
212 SE_LOG_INFO(NULL, "terminating");
214 } catch ( const std::exception &ex ) {
215 SE_LOG_ERROR(NULL, "%s", ex.what());
217 SE_LOG_ERROR(NULL, "unknown error");