d7bc87ad625b71855acba4fddcdbdb9cf07f7e75
[platform/upstream/syncevolution.git] / src / syncevolution.cpp
1 /*
2  * Copyright (C) 2005-2009 Patrick Ohly <patrick.ohly@gmx.de>
3  * Copyright (C) 2009 Intel Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) version 3.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301  USA
19  */
20
21 #include "config.h"
22 #include <stddef.h>
23 #include <iostream>
24 #include <memory>
25 using namespace std;
26
27 #include <libgen.h>
28 #ifdef HAVE_GLIB
29 #include <glib-object.h>
30 #endif
31
32 #include <syncevo/Cmdline.h>
33 #include "EvolutionSyncSource.h"
34 #include <syncevo/SyncContext.h>
35 #include <syncevo/LogRedirect.h>
36 #include "CmdlineSyncClient.h"
37
38 #include <dlfcn.h>
39
40 #include <syncevo/declarations.h>
41 SE_BEGIN_CXX
42
43 #if defined(ENABLE_MAEMO) && defined (ENABLE_EBOOK)
44
45 // really override the symbol, even if redefined by EDSAbiWrapper
46 #undef e_contact_new_from_vcard
47 extern "C" EContact *e_contact_new_from_vcard(const char *vcard)
48 {
49     static typeof(e_contact_new_from_vcard) *impl;
50
51     if (!impl) {
52         impl = (typeof(impl))dlsym(RTLD_NEXT, "e_contact_new_from_vcard");
53     }
54
55     // Old versions of EDS-DBus parse_changes_array() call
56     // e_contact_new_from_vcard() with a pointer which starts
57     // with a line break; Evolution is not happy with that and
58     // refuses to parse it. This code forwards until it finds
59     // the first non-whitespace, presumably the BEGIN:VCARD.
60     while (*vcard && isspace(*vcard)) {
61         vcard++;
62     }
63
64     return impl ? impl(vcard) : NULL;
65 }
66 #endif
67
68 /**
69  * This is a class derived from Cmdline. The purpose
70  * is to implement the factory method 'createSyncClient' to create
71  * new implemented 'CmdlineSyncClient' objects.
72  */
73 class KeyringSyncCmdline : public Cmdline {
74  public:
75     KeyringSyncCmdline(int argc, const char * const * argv, ostream &out, ostream &err):
76         Cmdline(argc, argv, out, err) 
77     {}
78     /**
79      * create a user implemented sync client.
80      */
81     SyncContext* createSyncClient() {
82         return new CmdlineSyncClient(m_server, true, m_keyring);
83     }
84 };
85
86 extern "C"
87 int main( int argc, char **argv )
88 {
89 #ifdef ENABLE_MAEMO
90     // EDS-DBus uses potentially long-running calls which may fail due
91     // to the default 25s timeout. Some of these can be replaced by
92     // their async version, but e_book_async_get_changes() still
93     // triggered it.
94     //
95     // The workaround for this is to link the binary against a libdbus
96     // which has the dbus-timeout.patch and thus let's users and
97     // the application increase the default timeout.
98     setenv("DBUS_DEFAULT_TIMEOUT", "600000", 0);
99 #endif
100
101     // Intercept stderr and route it through our logging.
102     // stdout is printed normally. Deconstructing it when
103     // leaving main() does one final processing of pending
104     // output.
105     LogRedirect redirect(false);
106
107 #if defined(HAVE_GLIB)
108     // this is required when using glib directly or indirectly
109     g_type_init();
110     g_thread_init(NULL);
111 #endif
112
113     setvbuf(stderr, NULL, _IONBF, 0);
114     setvbuf(stdout, NULL, _IONBF, 0);
115
116     // Expand PATH to cover the directory we were started from?
117     // This might be needed to find normalize_vcard.
118     char *exe = strdup(argv[0]);
119     if (strchr(exe, '/') ) {
120         char *dir = dirname(exe);
121         string path;
122         char *oldpath = getenv("PATH");
123         if (oldpath) {
124             path += oldpath;
125             path += ":";
126         }
127         path += dir;
128         setenv("PATH", path.c_str(), 1);
129     }
130     free(exe);
131
132     try {
133         EDSAbiWrapperInit();
134
135         /*
136          * don't log errors to cerr: LogRedirect cannot distinguish
137          * between our valid error messages and noise from other
138          * libs, therefore it would get suppressed (logged at
139          * level DEVELOPER, while output is at most INFO)
140          */
141         KeyringSyncCmdline cmdline(argc, argv, cout, cout);
142         if (cmdline.parse() &&
143             cmdline.run()) {
144             return 0;
145         } else {
146             return 1;
147         }
148     } catch ( const std::exception &ex ) {
149         SE_LOG_ERROR(NULL, NULL, "%s", ex.what());
150     } catch (...) {
151         SE_LOG_ERROR(NULL, NULL, "unknown error");
152     }
153
154     return 1;
155 }
156
157 SE_END_CXX