146f546e966f269d298437fa9269d3e4020ff3aa
[platform/upstream/syncevolution.git] / src / syncevo / eds_abi_wrapper.cpp
1 /*
2  * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
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 #define EDS_ABI_WRAPPER_NO_REDEFINE 1
21 #include <syncevo/eds_abi_wrapper.h>
22 #include <syncevo/SyncContext.h>
23
24 #include <string>
25 #include <sstream>
26 #include <dlfcn.h>
27 #include <stdarg.h>
28
29 #include <syncevo/declarations.h>
30
31 namespace {
32
33 std::string lookupDebug, lookupInfo;
34
35 }
36
37 int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
38
39 #ifdef EVOLUTION_COMPATIBILITY
40
41 struct EDSAbiWrapper EDSAbiWrapperSingleton;
42
43 namespace {
44
45 /**
46  * Opens a <basename>.<num> shared object with <num> coming from a
47  * range of known compatible versions, falling back to even more
48  * recent ones only after warning about it. Then searches for
49  * function pointers.
50  *
51  * Either all or none of the function pointers are set.
52  *
53  * End user information and debug information are added to
54  * lookupDebug and lookupInfo.
55  *
56  * @param libname   full name including .so suffix; .<num> gets appended
57  * @param minver    first known compatible version
58  * @param maxver    last known compatible version
59  * @return dlhandle which must be kept or freed by caller
60  */
61 void *findSymbols(const char *libname, int minver, int maxver, ... /* function pointer address, name, ..., (void *)0 */)
62 {
63     void *dlhandle = NULL;
64     std::ostringstream debug, info;
65
66     if (!dlhandle) {
67         for (int ver = maxver;
68              ver >= minver;
69              --ver) {
70             std::ostringstream soname;
71             soname << libname << "." << ver;
72             dlhandle = dlopen(soname.str().c_str(), RTLD_GLOBAL|RTLD_LAZY);
73             if (dlhandle) {
74                 info << "using " << soname.str() << std::endl;
75                 break;
76             }
77         }
78     }
79
80     if (!dlhandle) {
81         for (int ver = maxver + 1;
82              ver < maxver + 50;
83              ++ver) {
84             std::ostringstream soname;
85             soname << libname << "." << ver;
86             dlhandle = dlopen(soname.str().c_str(), RTLD_GLOBAL|RTLD_LAZY);
87             if (dlhandle) {
88                 info << "using " << soname.str() << " - might not be compatible!" << std::endl;
89                 break;
90             }
91         }
92     }
93     
94     if (!dlhandle) {
95         debug << libname << " not found (tried major versions " << minver << " to " << maxver + 49 << ")" << std::endl;
96     } else {
97         bool allfound = true;
98
99         va_list ap;
100         va_start(ap, maxver);
101         void **funcptr = va_arg(ap, void **);
102         const char *symname = NULL;
103         while (funcptr && allfound) {
104             symname = va_arg(ap, const char *);
105             *funcptr = dlsym(dlhandle, symname);
106             if (!*funcptr) {
107                 debug << symname << " not found" << std::endl;
108                 allfound = false;
109             }
110             funcptr = va_arg(ap, void **);
111         }
112         va_end(ap);
113
114         if (!allfound) {
115             /* unusable, clear symbols and free handle */
116             va_start(ap, maxver);
117             funcptr = va_arg(ap, void **);
118             while (funcptr) {
119                 va_arg(ap, const char *);
120                 *funcptr = NULL;
121                 funcptr = va_arg(ap, void **);
122             }
123             va_end(ap);
124
125             info << libname << " unusable, required function no longer available" << std::endl;
126             dlclose(dlhandle);
127             dlhandle = NULL;
128         }
129     }
130
131     lookupInfo += info.str();
132     lookupDebug += info.str();
133     lookupDebug += debug.str();
134     return dlhandle;
135 }
136
137 # ifdef HAVE_EDS
138     void *edshandle;
139 # endif
140 # ifdef ENABLE_EBOOK
141     void *ebookhandle;
142 # endif
143 # ifdef ENABLE_ECAL
144     void *ecalhandle;
145 # endif
146
147 }
148
149 #endif // EVOLUTION_COMPATIBILITY
150
151 extern "C" int EDSAbiHaveEbook, EDSAbiHaveEcal, EDSAbiHaveEdataserver;
152
153 extern "C" void EDSAbiWrapperInit()
154 {
155     static bool initialized;
156
157     if (initialized) {
158         return;
159     } else {
160         initialized = true;
161     }
162
163 #ifdef EVOLUTION_COMPATIBILITY
164 # ifdef HAVE_EDS
165     edshandle =
166     findSymbols("libedataserver-1.2.so", 7, 11,
167                 &EDSAbiWrapperSingleton.e_source_get_type, "e_source_get_type",
168                 &EDSAbiWrapperSingleton.e_source_get_uri, "e_source_get_uri",
169                 &EDSAbiWrapperSingleton.e_source_group_get_type, "e_source_group_get_type",
170                 &EDSAbiWrapperSingleton.e_source_group_peek_sources, "e_source_group_peek_sources",
171                 &EDSAbiWrapperSingleton.e_source_list_peek_groups, "e_source_list_peek_groups",
172                 &EDSAbiWrapperSingleton.e_source_peek_name, "e_source_peek_name",
173                 (void *)0);
174     EDSAbiHaveEdataserver = EDSAbiWrapperSingleton.e_source_group_peek_sources != 0;
175 # endif // HAVE_EDS
176
177 # ifdef ENABLE_EBOOK
178     ebookhandle =
179     findSymbols("libebook-1.2.so", 5, 9,
180                 &EDSAbiWrapperSingleton.e_book_add_contact, "e_book_add_contact",
181                 &EDSAbiWrapperSingleton.e_book_authenticate_user, "e_book_authenticate_user",
182                 &EDSAbiWrapperSingleton.e_book_commit_contact, "e_book_commit_contact",
183                 &EDSAbiWrapperSingleton.e_contact_duplicate, "e_contact_duplicate",
184                 &EDSAbiWrapperSingleton.e_contact_get_const, "e_contact_get_const",
185                 &EDSAbiWrapperSingleton.e_contact_get, "e_contact_get",
186                 &EDSAbiWrapperSingleton.e_contact_name_free, "e_contact_name_free",
187                 &EDSAbiWrapperSingleton.e_contact_get_type, "e_contact_get_type",
188                 &EDSAbiWrapperSingleton.e_contact_new_from_vcard, "e_contact_new_from_vcard",
189                 &EDSAbiWrapperSingleton.e_contact_set, "e_contact_set",
190                 &EDSAbiWrapperSingleton.e_book_error_quark, "e_book_error_quark",
191                 &EDSAbiWrapperSingleton.e_book_get_addressbooks, "e_book_get_addressbooks",
192                 &EDSAbiWrapperSingleton.e_book_get_changes, "e_book_get_changes",
193                 &EDSAbiWrapperSingleton.e_book_get_contact, "e_book_get_contact",
194                 &EDSAbiWrapperSingleton.e_book_get_contacts, "e_book_get_contacts",
195                 &EDSAbiWrapperSingleton.e_book_get_supported_auth_methods, "e_book_get_supported_auth_methods",
196                 &EDSAbiWrapperSingleton.e_book_get_uri, "e_book_get_uri",
197                 &EDSAbiWrapperSingleton.e_book_new, "e_book_new",
198                 &EDSAbiWrapperSingleton.e_book_new_default_addressbook, "e_book_new_default_addressbook",
199                 &EDSAbiWrapperSingleton.e_book_new_from_uri, "e_book_new_from_uri",
200                 &EDSAbiWrapperSingleton.e_book_new_system_addressbook, "e_book_new_system_addressbook",
201                 &EDSAbiWrapperSingleton.e_book_open, "e_book_open",
202                 &EDSAbiWrapperSingleton.e_book_query_any_field_contains, "e_book_query_any_field_contains",
203                 &EDSAbiWrapperSingleton.e_book_query_unref, "e_book_query_unref",
204                 &EDSAbiWrapperSingleton.e_book_remove_contact, "e_book_remove_contact",
205                 &EDSAbiWrapperSingleton.e_vcard_to_string, "e_vcard_to_string",
206                 (void *)0);
207     EDSAbiHaveEbook = EDSAbiWrapperSingleton.e_book_new != 0;
208 # endif // ENABLE_EBOOK
209
210 # ifdef ENABLE_ECAL
211     ecalhandle =
212     findSymbols("libecal-1.2.so", 3, 7,
213                 &EDSAbiWrapperSingleton.e_cal_add_timezone, "e_cal_add_timezone",
214                 &EDSAbiWrapperSingleton.e_cal_component_get_icalcomponent, "e_cal_component_get_icalcomponent",
215                 &EDSAbiWrapperSingleton.e_cal_component_get_last_modified, "e_cal_component_get_last_modified",
216                 &EDSAbiWrapperSingleton.e_cal_component_get_type, "e_cal_component_get_type",
217                 &EDSAbiWrapperSingleton.e_cal_create_object, "e_cal_create_object",
218                 &EDSAbiWrapperSingleton.e_calendar_error_quark, "e_calendar_error_quark",
219                 &EDSAbiWrapperSingleton.e_cal_get_component_as_string, "e_cal_get_component_as_string",
220                 &EDSAbiWrapperSingleton.e_cal_get_object, "e_cal_get_object",
221                 &EDSAbiWrapperSingleton.e_cal_get_object_list_as_comp, "e_cal_get_object_list_as_comp",
222                 &EDSAbiWrapperSingleton.e_cal_get_sources, "e_cal_get_sources",
223                 &EDSAbiWrapperSingleton.e_cal_get_timezone, "e_cal_get_timezone",
224                 &EDSAbiWrapperSingleton.e_cal_modify_object, "e_cal_modify_object",
225                 &EDSAbiWrapperSingleton.e_cal_new, "e_cal_new",
226                 &EDSAbiWrapperSingleton.e_cal_new_from_uri, "e_cal_new_from_uri",
227                 &EDSAbiWrapperSingleton.e_cal_new_system_calendar, "e_cal_new_system_calendar",
228                 &EDSAbiWrapperSingleton.e_cal_new_system_tasks, "e_cal_new_system_tasks",
229                 &EDSAbiWrapperSingleton.e_cal_get_uri, "e_cal_get_uri",
230                 &EDSAbiWrapperSingleton.e_cal_open, "e_cal_open",
231                 &EDSAbiWrapperSingleton.e_cal_remove_object, "e_cal_remove_object",
232                 &EDSAbiWrapperSingleton.e_cal_remove_object_with_mod, "e_cal_remove_object_with_mod",
233                 &EDSAbiWrapperSingleton.e_cal_set_auth_func, "e_cal_set_auth_func",
234                 &EDSAbiWrapperSingleton.icalcomponent_add_component, "icalcomponent_add_component",
235                 &EDSAbiWrapperSingleton.icalcomponent_as_ical_string, "icalcomponent_as_ical_string",
236                 &EDSAbiWrapperSingleton.icalcomponent_free, "icalcomponent_free",
237                 &EDSAbiWrapperSingleton.icalcomponent_get_first_component, "icalcomponent_get_first_component",
238                 &EDSAbiWrapperSingleton.icalcomponent_get_first_property, "icalcomponent_get_first_property",
239                 &EDSAbiWrapperSingleton.icalcomponent_get_next_component, "icalcomponent_get_next_component",
240                 &EDSAbiWrapperSingleton.icalcomponent_get_next_property, "icalcomponent_get_next_property",
241                 &EDSAbiWrapperSingleton.icalcomponent_get_recurrenceid, "icalcomponent_get_recurrenceid",
242                 &EDSAbiWrapperSingleton.icalcomponent_get_timezone, "icalcomponent_get_timezone",
243                 &EDSAbiWrapperSingleton.icalcomponent_get_location, "icalcomponent_get_location",
244                 &EDSAbiWrapperSingleton.icalcomponent_get_summary, "icalcomponent_get_summary",
245                 &EDSAbiWrapperSingleton.icalcomponent_get_uid, "icalcomponent_get_uid",
246                 &EDSAbiWrapperSingleton.icalcomponent_isa, "icalcomponent_isa",
247                 &EDSAbiWrapperSingleton.icalcomponent_new_clone, "icalcomponent_new_clone",
248                 &EDSAbiWrapperSingleton.icalcomponent_new_from_string, "icalcomponent_new_from_string",
249                 &EDSAbiWrapperSingleton.icalcomponent_remove_property, "icalcomponent_remove_property",
250                 &EDSAbiWrapperSingleton.icalcomponent_set_uid, "icalcomponent_set_uid",
251                 &EDSAbiWrapperSingleton.icalcomponent_vanew, "icalcomponent_vanew",
252                 &EDSAbiWrapperSingleton.icalparameter_get_tzid, "icalparameter_get_tzid",
253                 &EDSAbiWrapperSingleton.icalparameter_set_tzid, "icalparameter_set_tzid",
254                 &EDSAbiWrapperSingleton.icalproperty_get_description, "icalproperty_get_description",
255                 &EDSAbiWrapperSingleton.icalproperty_get_first_parameter, "icalproperty_get_first_parameter",
256                 &EDSAbiWrapperSingleton.icalproperty_get_lastmodified, "icalproperty_get_lastmodified",
257                 &EDSAbiWrapperSingleton.icalproperty_get_next_parameter, "icalproperty_get_next_parameter",
258                 &EDSAbiWrapperSingleton.icalproperty_get_summary, "icalproperty_get_summary",
259                 &EDSAbiWrapperSingleton.icalproperty_new_description, "icalproperty_new_description",
260                 &EDSAbiWrapperSingleton.icalproperty_new_summary, "icalproperty_new_summary",
261                 &EDSAbiWrapperSingleton.icalproperty_set_value_from_string, "icalproperty_set_value_from_string",
262                 &EDSAbiWrapperSingleton.icaltime_as_ical_string, "icaltime_as_ical_string",
263                 &EDSAbiWrapperSingleton.icaltimezone_free, "icaltimezone_free",
264                 &EDSAbiWrapperSingleton.icaltimezone_get_builtin_timezone, "icaltimezone_get_builtin_timezone",
265                 &EDSAbiWrapperSingleton.icaltimezone_get_builtin_timezone_from_tzid, "icaltimezone_get_builtin_timezone_from_tzid",
266                 &EDSAbiWrapperSingleton.icaltimezone_get_component, "icaltimezone_get_component",
267                 &EDSAbiWrapperSingleton.icaltimezone_get_tzid, "icaltimezone_get_tzid",
268                 &EDSAbiWrapperSingleton.icaltimezone_new, "icaltimezone_new",
269                 &EDSAbiWrapperSingleton.icaltimezone_set_component, "icaltimezone_set_component",
270                 (void *)0);
271     EDSAbiHaveEcal = EDSAbiWrapperSingleton.e_cal_new != 0;
272 # endif // ENABLE_ECAL
273 #else // EVOLUTION_COMPATIBILITY
274 # ifdef HAVE_EDS
275     EDSAbiHaveEdataserver = true;
276 # endif
277 # ifdef ENABLE_EBOOK
278     EDSAbiHaveEbook = true;
279 # endif
280 # ifdef ENABLE_ECAL
281     EDSAbiHaveEcal = true;
282 # endif
283 #endif // EVOLUTION_COMPATIBILITY
284 }
285
286 extern "C" const char *EDSAbiWrapperInfo() { return lookupInfo.c_str(); }
287 extern "C" const char *EDSAbiWrapperDebug() { return lookupDebug.c_str(); }
288