Imported Upstream version 1.2.99~20120606~SE~ff65aef~SYSYNC~2728cb4
[platform/upstream/syncevolution.git] / src / dbus / server / main.cpp
1 /*
2  * Copyright (C) 2011 Intel Corporation
3  *
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.
8  *
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.
13  *
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
17  * 02110-1301  USA
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <iostream>
25
26 #include "server.h"
27 #include "restart.h"
28 #include "session-common.h"
29
30 #include <syncevo/SyncContext.h>
31 #include <syncevo/SuspendFlags.h>
32 #include <syncevo/LogRedirect.h>
33 #include <syncevo/LogSyslog.h>
34
35 using namespace SyncEvo;
36 using namespace GDBusCXX;
37
38 namespace {
39     GMainLoop *loop = NULL;
40     bool shutdownRequested = false;
41     const char * const execName = "syncevo-dbus-server";
42     const char * const debugEnv = "SYNCEVOLUTION_DEBUG";
43
44 void niam(int sig)
45 {
46     shutdownRequested = true;
47     SuspendFlags::getSuspendFlags().handleSignal(sig);
48     g_main_loop_quit (loop);
49 }
50
51 bool parseDuration(int &duration, const char* value)
52 {
53     if(value == NULL) {
54         return false;
55     } else if (boost::iequals(value, "unlimited")) {
56         duration = -1;
57         return true;
58     } else if ((duration = atoi(value)) > 0) {
59         return true;
60     } else {
61         return false;
62     }
63 }
64
65 } // anonymous namespace
66
67 int main(int argc, char **argv, char **envp)
68 {
69     // remember environment for restart
70     boost::shared_ptr<Restart> restart;
71     restart.reset(new Restart(argv, envp));
72
73     int duration = 600;
74     int opt = 1;
75     while(opt < argc) {
76         if(argv[opt][0] != '-') {
77             break;
78         }
79         if (boost::iequals(argv[opt], "--duration") ||
80             boost::iequals(argv[opt], "-d")) {
81             opt++;
82             if(!parseDuration(duration, opt== argc ? NULL : argv[opt])) {
83                 std::cout << argv[opt-1] << ": unknown parameter value or not set" << std::endl;
84                 return false;
85             }
86         } else {
87             std::cout << argv[opt] << ": unknown parameter" << std::endl;
88             return false;
89         }
90         opt++;
91     }
92     try {
93         // Temporarily set G_DBUS_DEBUG. Hopefully GIO will read and
94         // remember it, because we don't want to keep it set
95         // permanently, lest it gets passed on to other processes.
96         const char *gdbus = getenv("SYNCEVOLUTION_DBUS_SERVER_GDBUS");
97         if (gdbus) {
98             setenv("G_DBUS_DEBUG", gdbus, 1);
99         }
100
101         SyncContext::initMain(execName);
102
103         loop = g_main_loop_new (NULL, FALSE);
104
105         setvbuf(stderr, NULL, _IONBF, 0);
106         setvbuf(stdout, NULL, _IONBF, 0);
107
108         const char *debugVar(getenv(debugEnv));
109         const bool debugEnabled(debugVar && *debugVar);
110
111         // TODO: redirect output *and* log it via syslog?!
112         boost::shared_ptr<LoggerBase> logger;
113         if (!gdbus) {
114             logger.reset((true ||  debugEnabled) ?
115                          static_cast<LoggerBase *>(new LogRedirect(true)) :
116                          static_cast<LoggerBase *>(new LoggerSyslog(execName)));
117         }
118
119         // make daemon less chatty - long term this should be a command line option
120         LoggerBase::instance().setLevel(debugEnabled ?
121                                         LoggerBase::DEBUG :
122                                         LoggerBase::INFO);
123
124         // syncevo-dbus-server should hardly ever produce output that
125         // is relevant for end users, so include the somewhat cryptic
126         // process name for developers in this process, and not in
127         // syncevo-dbus-helper.
128         Logger::setProcessName("syncevo-dbus-server");
129
130         SE_LOG_DEBUG(NULL, NULL, "syncevo-dbus-server: catch SIGINT/SIGTERM in our own shutdown function");
131         signal(SIGTERM, niam);
132         signal(SIGINT, niam);
133         boost::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
134
135         DBusErrorCXX err;
136         DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
137                                                          SessionCommon::SERVICE_NAME,
138                                                          true,
139                                                          &err);
140         if (!conn) {
141             err.throwFailure("dbus_get_bus_connection()", " failed - server already running?");
142         }
143         // make this object the main owner of the connection
144         boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
145
146         boost::scoped_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, shutdownRequested, restart, conn, duration));
147         server->activate();
148
149         if (gdbus) {
150             unsetenv("G_DBUS_DEBUG");
151         }
152
153         server->run();
154         SE_LOG_DEBUG(NULL, NULL, "cleaning up");
155         server.reset();
156         conn.reset();
157         obj.reset();
158         guard.reset();
159         SE_LOG_INFO(NULL, NULL, "terminating");
160         return 0;
161     } catch ( const std::exception &ex ) {
162         SE_LOG_ERROR(NULL, NULL, "%s", ex.what());
163     } catch (...) {
164         SE_LOG_ERROR(NULL, NULL, "unknown error");
165     }
166
167     return 1;
168 }