desktop: string conversion to support i18n
[barry.git] / desktop / src / os40.cc
blob0cc213928eafd0e4e27325ba69b524e9acee221c
1 ///
2 /// \file os40.cc
3 /// Wrapper class for opensync 0.22 syncing behaviour
4 ///
6 /*
7 Copyright (C) 2009-2012, Net Direct Inc. (http://www.netdirect.ca/)
9 Used code from osynctool (GPL v2+) as a guide to the API,
10 and copied some of the status messages, as well as one funcion
11 directly:
12 static const char *OSyncChangeType2String(OSyncChangeType type)
13 Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
14 Copyright (C) 2006-2007 Daniel Friedrich <daniel.friedrich@opensync.org>
15 Copyright (C) 2008-2009 Daniel Gollub <gollub@b1-systems.de>
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 See the GNU General Public License in the COPYING file at the
27 root directory of this project for more details.
30 #include "os40.h"
31 #include "os22.h"
32 #include "osprivatebase.h"
33 #include "tempdir.h"
34 #include "osconv40.h"
35 #include <barry/vsmartptr.h>
36 #include <iostream>
37 #include <sstream>
38 #include <fstream>
39 #include <errno.h>
40 #include <glib.h>
41 #include "i18n.h"
43 // use relative paths to backtrack enough to specify only 0.4x includes
44 #include <../libopensync1/opensync/opensync.h>
45 #include <../libopensync1/opensync/opensync-group.h>
46 #include <../libopensync1/opensync/opensync-format.h>
47 #include <../libopensync1/opensync/opensync-plugin.h>
48 #include <../libopensync1/opensync/opensync-engine.h>
49 #include <../libopensync1/opensync/opensync-data.h>
50 #include <../libopensync1/opensync/opensync-capabilities.h>
52 using namespace std;
53 using namespace Barry;
55 namespace OpenSync {
58 typedef Barry::vLateSmartPtr<OSyncEngine, void(*)(OSyncEngine*)> EngineHandle;
59 typedef Barry::vLateSmartPtr<OSyncList, void(*)(OSyncList*)> SyncListHandle;
63 // Private class declarations
67 class TossError
69 OSyncError *m_error;
70 OpenSync40Private *m_priv;
72 public:
73 // simple wrapper... unref's the error on destruction
74 TossError(OpenSync40Private *priv)
75 : m_error(0)
76 , m_priv(priv)
80 ~TossError()
82 Clear();
85 /// Returns NULL if no error
86 std::string GetErrorMsg();
87 bool IsSet();
88 void Clear();
90 operator OSyncError**()
92 return &m_error;
96 class OpenSync40Private
98 public:
99 // function pointers
100 const char* (*osync_get_version)();
101 const char* (*osync_error_print)(OSyncError **error);
102 char* (*osync_error_print_stack)(OSyncError **error);
103 osync_bool (*osync_error_is_set)(OSyncError **error);
104 void (*osync_error_unref)(OSyncError **error);
105 OSyncGroupEnv* (*osync_group_env_new)(OSyncError **error);
106 OSyncFormatEnv* (*osync_format_env_new)(OSyncError **error);
107 OSyncPluginEnv* (*osync_plugin_env_new)(OSyncError **error);
108 void (*osync_group_env_unref)(OSyncGroupEnv *env);
109 void (*osync_format_env_unref)(OSyncFormatEnv *env);
110 void (*osync_plugin_env_unref)(OSyncPluginEnv *env);
111 osync_bool (*osync_plugin_env_load)(OSyncPluginEnv *env,
112 const char *path, OSyncError **error);
113 OSyncList* (*osync_plugin_env_get_plugins)(
114 OSyncPluginEnv *env);
115 const char* (*osync_plugin_get_name)(OSyncPlugin *plugin);
116 void (*osync_list_free)(OSyncList *list);
117 osync_bool (*osync_group_env_load_groups)(
118 OSyncGroupEnv *env, const char *path,
119 OSyncError **error);
120 osync_bool (*osync_format_env_load_plugins)(
121 OSyncFormatEnv *env, const char *path,
122 OSyncError **error);
123 OSyncList* (*osync_group_env_get_groups)(
124 OSyncGroupEnv *env);
125 const char* (*osync_group_get_name)(OSyncGroup *group);
126 OSyncGroup* (*osync_group_env_find_group)(
127 OSyncGroupEnv *env, const char *name);
128 OSyncList* (*osync_group_get_members)(OSyncGroup *group);
129 const char* (*osync_member_get_name)(OSyncMember *member);
130 osync_memberid (*osync_member_get_id)(OSyncMember *member);
131 const char* (*osync_member_get_pluginname)(
132 OSyncMember *member);
133 OSyncList* (*osync_format_env_get_objformats)(
134 OSyncFormatEnv *env);
135 const char* (*osync_objformat_get_name)(
136 OSyncObjFormat *format);
137 const char* (*osync_objformat_get_objtype)(
138 OSyncObjFormat *format);
139 OSyncGroup* (*osync_group_new)(OSyncError **error);
140 void (*osync_group_unref)(OSyncGroup *group);
141 void (*osync_group_set_name)(OSyncGroup *group,
142 const char *name);
143 osync_bool (*osync_group_env_add_group)(OSyncGroupEnv *env,
144 OSyncGroup *group,
145 OSyncError **error);
146 osync_bool (*osync_group_save)(OSyncGroup *group,
147 OSyncError **error);
148 osync_bool (*osync_group_delete)(OSyncGroup *group,
149 OSyncError **error);
150 void (*osync_group_env_remove_group)(
151 OSyncGroupEnv *env, OSyncGroup *group);
152 OSyncPlugin* (*osync_plugin_env_find_plugin)(
153 OSyncPluginEnv *env, const char *name);
154 void (*osync_member_unref)(OSyncMember *member);
155 OSyncMember* (*osync_member_new)(OSyncError **error);
156 void (*osync_group_add_member)(OSyncGroup *group,
157 OSyncMember *member);
158 void (*osync_member_set_pluginname)(
159 OSyncMember *member,
160 const char *pluginname);
161 void (*osync_member_set_name)(OSyncMember *member,
162 const char *name);
163 osync_bool (*osync_member_save)(OSyncMember *member,
164 OSyncError **error);
165 OSyncMember* (*osync_group_find_member)(OSyncGroup *group,
166 osync_memberid id);
167 osync_bool (*osync_member_delete)(OSyncMember *member,
168 OSyncError **error);
169 void (*osync_group_remove_member)(OSyncGroup *group,
170 OSyncMember *member);
171 OSyncPluginConfig* (*osync_plugin_config_new)(OSyncError **error);
172 osync_bool (*osync_plugin_config_file_load)(
173 OSyncPluginConfig *config,
174 const char *path,
175 OSyncError **error);
176 void (*osync_member_set_config)(OSyncMember *member,
177 OSyncPluginConfig *config);
178 OSyncPluginConfig* (*osync_member_get_config_or_default)(
179 OSyncMember *member,
180 OSyncError **error);
181 osync_bool (*osync_plugin_config_file_save)(
182 OSyncPluginConfig *config,
183 const char *path, OSyncError **error);
184 OSyncPluginConfigurationType (*osync_plugin_get_config_type)(
185 OSyncPlugin *plugin);
186 OSyncEngine* (*osync_engine_new)(OSyncGroup *group,
187 OSyncError **error);
188 void (*osync_engine_unref)(OSyncEngine *engine);
189 osync_bool (*osync_engine_discover_and_block)(
190 OSyncEngine *engine,
191 OSyncMember *member,
192 OSyncError **error);
193 OSyncList* (*osync_member_get_objtypes)(
194 OSyncMember *member);
195 unsigned int (*osync_list_length)(const OSyncList *list);
196 void (*osync_error_set)(OSyncError **error,
197 OSyncErrorType type,
198 const char *format, ...);
199 osync_bool (*osync_engine_finalize)(OSyncEngine *engine,
200 OSyncError **error);
201 OSyncList* (*osync_mapping_engine_get_changes)(
202 OSyncMappingEngine *engine);
203 osync_bool (*osync_mapping_engine_supports_ignore)(
204 OSyncMappingEngine *engine);
205 osync_bool (*osync_mapping_engine_supports_use_latest)(
206 OSyncMappingEngine *engine);
207 OSyncList* (*osync_list_nth)(OSyncList *list,
208 unsigned int n);
209 osync_bool (*osync_engine_mapping_solve)(
210 OSyncEngine *engine,
211 OSyncMappingEngine *mapping_engine,
212 OSyncChange *change,
213 OSyncError **error);
214 osync_bool (*osync_engine_abort)(OSyncEngine *engine,
215 OSyncError **error);
216 osync_bool (*osync_engine_mapping_duplicate)(
217 OSyncEngine *engine,
218 OSyncMappingEngine *mapping_engine,
219 OSyncError **error);
220 osync_bool (*osync_engine_mapping_ignore_conflict)(
221 OSyncEngine *engine,
222 OSyncMappingEngine *mapping_engine,
223 OSyncError **error);
224 osync_bool (*osync_engine_mapping_use_latest)(
225 OSyncEngine *engine,
226 OSyncMappingEngine *mapping_engine,
227 OSyncError **error);
228 OSyncChangeType (*osync_change_get_changetype)(
229 OSyncChange *change);
230 OSyncMember* (*osync_mapping_engine_change_find_member)(
231 OSyncMappingEngine *engine,
232 OSyncChange *change);
233 OSyncData* (*osync_change_get_data)(OSyncChange *change);
234 char* (*osync_data_get_printable)(OSyncData *data,
235 OSyncError **error);
236 void (*osync_free)(void *ptr);
237 const char* (*osync_change_get_uid)(OSyncChange *change);
238 osync_bool (*osync_engine_continue)(OSyncEngine *engine,
239 OSyncError **error);
240 OSyncList* (*osync_engine_get_objengines)(
241 OSyncEngine *engine);
242 OSyncList* (*osync_obj_engine_get_members)(
243 OSyncObjEngine* engine);
244 const char* (*osync_obj_engine_get_objtype)(
245 OSyncObjEngine *engine);
246 const OSyncList* (*osync_obj_engine_get_mapping_entry_engines_of_member)(
247 OSyncObjEngine *engine,
248 OSyncMember *member);
249 osync_bool (*osync_entry_engine_is_dirty)(
250 OSyncMappingEntryEngine *engine);
251 OSyncChangeType (*osync_entry_engine_get_changetype)(
252 OSyncMappingEntryEngine *engine);
253 OSyncChange* (*osync_engine_change_update_get_change)(
254 OSyncEngineChangeUpdate *update);
255 OSyncMember* (*osync_engine_change_update_get_member)(
256 OSyncEngineChangeUpdate *update);
257 OSyncError* (*osync_engine_change_update_get_error)(
258 OSyncEngineChangeUpdate *update);
259 OSyncEngineChangeEvent (*osync_engine_change_update_get_event)(
260 OSyncEngineChangeUpdate *update);
261 OSyncObjFormat* (*osync_change_get_objformat)(
262 OSyncChange *change);
263 OSyncError* (*osync_engine_mapping_update_get_error)(
264 OSyncEngineMappingUpdate *update);
265 OSyncError* (*osync_engine_update_get_error)(
266 OSyncEngineUpdate *update);
267 OSyncEngineEvent (*osync_engine_update_get_event)(
268 OSyncEngineUpdate *update);
269 const char* (*osync_engine_member_update_get_objtype)(
270 OSyncEngineMemberUpdate *update);
271 OSyncMember* (*osync_engine_member_update_get_member)(
272 OSyncEngineMemberUpdate *update);
273 OSyncError* (*osync_engine_member_update_get_error)(
274 OSyncEngineMemberUpdate *update);
275 OSyncEngineMemberEvent (*osync_engine_member_update_get_event)(
276 OSyncEngineMemberUpdate *update);
277 void (*osync_engine_set_conflict_callback)(
278 OSyncEngine *engine,
279 osync_conflict_cb callback,
280 void *user_data);
281 void (*osync_engine_set_changestatus_callback)(
282 OSyncEngine *engine,
283 osync_status_change_cb callback,
284 void *user_data);
285 void (*osync_engine_set_mappingstatus_callback)(
286 OSyncEngine *engine,
287 osync_status_mapping_cb callback,
288 void *user_data);
289 void (*osync_engine_set_enginestatus_callback)(
290 OSyncEngine *engine,
291 osync_status_engine_cb callback,
292 void *user_data);
293 void (*osync_engine_set_memberstatus_callback)(
294 OSyncEngine *engine,
295 osync_status_member_cb callback,
296 void *user_data);
297 void (*osync_engine_set_multiply_callback)(
298 OSyncEngine *engine,
299 osync_multiply_cb callback,
300 void *user_data);
301 osync_bool (*osync_engine_initialize)(OSyncEngine *engine,
302 OSyncError **error);
303 osync_bool (*osync_engine_synchronize_and_block)(
304 OSyncEngine *engine,OSyncError **error);
305 OSyncEngineMappingEvent (*osync_engine_mapping_update_get_event)(
306 OSyncEngineMappingUpdate *update);
307 void (*osync_plugin_resource_unref)(
308 OSyncPluginResource *resource);
309 void (*osync_plugin_config_add_resource)(
310 OSyncPluginConfig *config,
311 OSyncPluginResource *resource);
312 osync_bool (*osync_plugin_resource_is_enabled)(
313 OSyncPluginResource *resource);
314 void (*osync_plugin_resource_enable)(
315 OSyncPluginResource *resource,
316 osync_bool enable);
317 OSyncList* (*osync_plugin_resource_get_objformat_sinks)(
318 OSyncPluginResource *resource);
319 const char* (*osync_objformat_sink_get_objformat)(
320 OSyncObjFormatSink *sink);
321 const char* (*osync_objformat_sink_get_config)(
322 OSyncObjFormatSink *sink);
323 void (*osync_objformat_sink_set_config)(
324 OSyncObjFormatSink *sink,
325 const char *config);
326 OSyncObjFormatSink* (*osync_objformat_sink_new)(
327 const char *objformat,
328 OSyncError **error);
329 void (*osync_plugin_resource_add_objformat_sink)(
330 OSyncPluginResource *resource,
331 OSyncObjFormatSink *formatsink);
332 void (*osync_objformat_sink_unref)(
333 OSyncObjFormatSink *sink);
334 const char* (*osync_plugin_resource_get_preferred_format)(
335 OSyncPluginResource *resource);
336 void (*osync_plugin_resource_set_preferred_format)(
337 OSyncPluginResource *resource,
338 const char *preferred_format);
339 const char* (*osync_plugin_resource_get_mime)(
340 OSyncPluginResource *resource);
341 void (*osync_plugin_resource_set_mime)(
342 OSyncPluginResource *resource,
343 const char *mime);
344 const char* (*osync_plugin_resource_get_objtype)(
345 OSyncPluginResource *resource);
346 void (*osync_plugin_resource_set_objtype)(
347 OSyncPluginResource *resource,
348 const char *objtype);
349 const char* (*osync_plugin_resource_get_path)(
350 OSyncPluginResource *resource);
351 void (*osync_plugin_resource_set_path)(
352 OSyncPluginResource *resource,
353 const char *path);
354 const char* (*osync_plugin_resource_get_url)(
355 OSyncPluginResource *resource);
356 void (*osync_plugin_resource_set_url)(
357 OSyncPluginResource *resource,
358 const char *url);
359 const char* (*osync_plugin_config_get_advancedoption_value_by_name)(
360 OSyncPluginConfig *config,
361 const char *name);
362 OSyncList* (*osync_plugin_config_get_advancedoptions)(
363 OSyncPluginConfig *config);
364 void (*osync_plugin_config_add_advancedoption)(
365 OSyncPluginConfig *config,
366 OSyncPluginAdvancedOption *option);
367 OSyncPluginAdvancedOption* (*osync_plugin_advancedoption_new)(
368 OSyncError **error);
369 void (*osync_plugin_advancedoption_unref)(
370 OSyncPluginAdvancedOption *option);
371 const char* (*osync_plugin_advancedoption_get_name)(
372 OSyncPluginAdvancedOption *option);
373 void (*osync_plugin_advancedoption_set_name)(
374 OSyncPluginAdvancedOption *option,
375 const char *name);
376 void (*osync_plugin_advancedoption_set_displayname)(
377 OSyncPluginAdvancedOption *option,
378 const char *displayname);
379 void (*osync_plugin_advancedoption_set_type)(
380 OSyncPluginAdvancedOption *option,
381 OSyncPluginAdvancedOptionType type);
382 void (*osync_plugin_advancedoption_set_value)(
383 OSyncPluginAdvancedOption *option,
384 const char *value);
385 OSyncList* (*osync_plugin_config_get_resources)(
386 OSyncPluginConfig *config);
387 OSyncPluginResource* (*osync_plugin_resource_ref)(
388 OSyncPluginResource *resource);
389 OSyncPluginResource* (*osync_plugin_resource_new)(
390 OSyncError **error);
391 const char* (*osync_plugin_resource_get_name)(
392 OSyncPluginResource *resource);
393 void (*osync_plugin_resource_set_name)(
394 OSyncPluginResource *resource,
395 const char *name);
396 OSyncPluginAuthentication* (*osync_plugin_config_get_authentication)(
397 OSyncPluginConfig *config);
398 const char* (*osync_plugin_authentication_get_password)(
399 OSyncPluginAuthentication *auth);
400 OSyncPluginAuthentication* (*osync_plugin_authentication_new)(
401 OSyncError **error);
402 osync_bool (*osync_plugin_authentication_option_is_supported)(
403 OSyncPluginAuthentication *auth,
404 OSyncPluginAuthenticationOptionSupportedFlag flag);
405 void (*osync_plugin_authentication_unref)(
406 OSyncPluginAuthentication *auth);
407 void (*osync_plugin_config_set_authentication)(
408 OSyncPluginConfig *config,
409 OSyncPluginAuthentication *auth);
410 void (*osync_plugin_authentication_set_password)(
411 OSyncPluginAuthentication *auth,
412 const char *password);
413 const char* (*osync_plugin_authentication_get_username)(
414 OSyncPluginAuthentication *auth);
415 void (*osync_plugin_authentication_set_username)(
416 OSyncPluginAuthentication *auth,
417 const char *password);
418 void (*osync_group_set_objtype_enabled)(
419 OSyncGroup *group, const char *objtype,
420 osync_bool enabled);
422 // data pointers
423 vLateSmartPtr<OSyncGroupEnv, void(*)(OSyncGroupEnv*)> group_env;
424 vLateSmartPtr<OSyncFormatEnv, void(*)(OSyncFormatEnv*)> format_env;
425 vLateSmartPtr<OSyncPluginEnv, void(*)(OSyncPluginEnv*)> plugin_env;
427 TossError error;
428 Converter40 converter;
430 OpenSync40Private(OpenSync40 &api)
431 : error(this)
432 , converter(api)
436 // helper functions
437 std::string osync_error_print_stack_wrapper(OSyncError **error)
439 std::string rmsg;
440 char *msg = osync_error_print_stack(error);
441 if( msg ) {
442 rmsg = msg;
443 osync_free(msg);
445 else {
446 rmsg = _C("(NULL error msg)");
448 return rmsg;
452 class SyncConflict40Private : public SyncConflictPrivateBase
454 OpenSync40Private *m_priv;
455 OSyncEngine *m_engine;
456 OSyncMappingEngine *m_mapping;
457 OSyncList *m_changes;
459 public:
460 SyncConflict40Private(OpenSync40Private *priv,
461 OSyncEngine *engine, OSyncMappingEngine *mapping);
462 ~SyncConflict40Private();
464 virtual bool IsAbortSupported() const;
465 virtual bool IsIgnoreSupported() const;
466 virtual bool IsKeepNewerSupported() const;
468 virtual void Select(int change_id); // takes the id of SyncChange
469 virtual void Abort();
470 virtual void Duplicate();
471 virtual void Ignore();
472 virtual void KeepNewer();
474 void AppendChanges(std::vector<SyncChange> &list);
477 class SyncSummary40Private : public SyncSummaryPrivateBase
479 OpenSync40Private *m_priv;
480 OSyncEngine *m_engine;
482 public:
483 SyncSummary40Private(OpenSync40Private *priv, OSyncEngine *engine);
484 ~SyncSummary40Private();
486 virtual void Abort();
487 virtual void Continue();
489 // returns true if any member is dirty
490 bool AppendMembers(std::vector<SyncMemberSummary> &list);
493 class OS40PluginConfigPrivate
495 public:
496 OSyncMember *m_member;
497 OSyncPluginConfig *m_config;
499 OS40PluginConfigPrivate()
500 : m_member(0)
501 , m_config(0)
506 class OS40ConfigResourcePrivate
508 public:
509 OpenSync40Private *m_privapi;
510 OS40PluginConfigPrivate *m_parentpriv;
511 OSyncPluginResource *m_resource;
513 OS40ConfigResourcePrivate()
514 : m_privapi(0)
515 , m_parentpriv(0)
516 , m_resource(0)
521 struct CallbackBundle
523 OpenSync40Private *m_priv;
524 SyncStatus *m_status;
526 CallbackBundle(OpenSync40Private *priv, SyncStatus &status)
527 : m_priv(priv)
528 , m_status(&status)
533 void conflict_handler(OSyncEngine *, OSyncMappingEngine *, void *);
534 void entry_status(OSyncEngineChangeUpdate *, void *);
535 void mapping_status(OSyncEngineMappingUpdate *, void *);
536 void engine_status(OSyncEngineUpdate *, void *);
537 void member_status(OSyncEngineMemberUpdate *, void *);
538 void multiply_summary(OSyncEngine *, void *);
541 /////////////////////////////////////////////////////////////////////////////
542 // Static helper functions
544 static const char *OSyncChangeType2String(OSyncChangeType type)
546 switch (type) {
547 case OSYNC_CHANGE_TYPE_ADDED: return _C("ADDED");
548 case OSYNC_CHANGE_TYPE_UNMODIFIED: return _C("UNMODIFIED");
549 case OSYNC_CHANGE_TYPE_DELETED: return _C("DELETED");
550 case OSYNC_CHANGE_TYPE_MODIFIED: return _C("MODIFIED");
551 default:
552 case OSYNC_CHANGE_TYPE_UNKNOWN: return "?";
557 /////////////////////////////////////////////////////////////////////////////
558 // SyncConflict40Private member functions
560 SyncConflict40Private::SyncConflict40Private(OpenSync40Private *priv,
561 OSyncEngine *engine, OSyncMappingEngine *mapping)
562 : m_priv(priv)
563 , m_engine(engine)
564 , m_mapping(mapping)
565 , m_changes(0)
567 m_changes = m_priv->osync_mapping_engine_get_changes(m_mapping);
570 SyncConflict40Private::~SyncConflict40Private()
572 m_priv->osync_list_free(m_changes);
575 bool SyncConflict40Private::IsAbortSupported() const
577 return true;
580 bool SyncConflict40Private::IsIgnoreSupported() const
582 return m_priv->osync_mapping_engine_supports_ignore(m_mapping);
585 bool SyncConflict40Private::IsKeepNewerSupported() const
587 return m_priv->osync_mapping_engine_supports_use_latest(m_mapping);
590 void SyncConflict40Private::Select(int change_id)
592 OSyncList *c = m_priv->osync_list_nth(m_changes, change_id);
593 if( !c )
594 throw std::logic_error("Bad change_id");
596 OSyncChange *change = (OSyncChange *) c->data;
598 if( !m_priv->osync_engine_mapping_solve(m_engine, m_mapping,
599 change, m_priv->error) )
601 throw std::runtime_error(m_priv->error.GetErrorMsg());
605 void SyncConflict40Private::Abort()
607 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) ) {
608 ostringstream oss;
609 oss << _C("Problems while aborting: ")
610 << m_priv->error.GetErrorMsg();
611 throw std::runtime_error(oss.str());
615 void SyncConflict40Private::Duplicate()
617 if( !m_priv->osync_engine_mapping_duplicate(m_engine, m_mapping, m_priv->error) )
618 throw std::runtime_error(m_priv->error.GetErrorMsg());
621 void SyncConflict40Private::Ignore()
623 if( !IsIgnoreSupported() )
624 throw std::logic_error("Ignore not supported, yet Ignore() called.");
626 if( !m_priv->osync_engine_mapping_ignore_conflict(m_engine, m_mapping,
627 m_priv->error) )
629 throw std::runtime_error(m_priv->error.GetErrorMsg());
633 void SyncConflict40Private::KeepNewer()
635 if( !IsKeepNewerSupported() )
636 throw std::logic_error("Keep Newer not supported, yet KeepNewer() called.");
638 if( !m_priv->osync_engine_mapping_use_latest(m_engine, m_mapping, m_priv->error) )
639 throw std::runtime_error(m_priv->error.GetErrorMsg());
642 void SyncConflict40Private::AppendChanges(std::vector<SyncChange> &list)
644 int i = 0;
645 for( OSyncList *c = m_changes; c; c = c->next, i++ ) {
646 OSyncChange *change = (OSyncChange *) c->data;
648 if( m_priv->osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_UNKNOWN ) {
649 OSyncMember *member = m_priv->osync_mapping_engine_change_find_member(m_mapping, change);
651 OSyncData *data = m_priv->osync_change_get_data(change);
653 SyncChange entry;
655 char *printable = m_priv->osync_data_get_printable(data, m_priv->error);
656 if( printable )
657 entry.printable_data = printable;
658 m_priv->osync_free(printable);
660 if( m_priv->error.IsSet() )
661 throw std::runtime_error(m_priv->error.GetErrorMsg());
663 entry.id = i;
664 entry.member_id = m_priv->osync_member_get_id(member);
665 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
666 entry.uid = m_priv->osync_change_get_uid(change);
668 // add to list
669 list.push_back(entry);
675 /////////////////////////////////////////////////////////////////////////////
676 // SyncSummary40Private member functions
678 SyncSummary40Private::SyncSummary40Private(OpenSync40Private *priv,
679 OSyncEngine *engine)
680 : m_priv(priv)
681 , m_engine(engine)
685 SyncSummary40Private::~SyncSummary40Private()
689 void SyncSummary40Private::Abort()
691 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) )
692 throw std::runtime_error(m_priv->error.GetErrorMsg());
695 void SyncSummary40Private::Continue()
697 if( !m_priv->osync_engine_continue(m_engine, m_priv->error) )
698 throw std::runtime_error(m_priv->error.GetErrorMsg());
701 bool SyncSummary40Private::AppendMembers(std::vector<SyncMemberSummary> &list)
703 SyncListHandle objengines(m_priv->osync_list_free);
704 objengines = m_priv->osync_engine_get_objengines(m_engine);
706 int i = 0;
707 bool dirty = false;
709 for( OSyncList *o = objengines.get(); o; o = o->next ) {
710 OSyncObjEngine *objengine = (OSyncObjEngine *) o->data;
716 SyncListHandle members(m_priv->osync_list_free);
717 members = m_priv->osync_obj_engine_get_members(objengine);
718 for( OSyncList *m = members.get(); m; m = m->next ) {
719 OSyncMember *member = (OSyncMember *) m->data;
721 // Fill in common summary data
722 SyncMemberSummary entry;
723 entry.id = i;
724 entry.objtype_name = m_priv->osync_obj_engine_get_objtype(objengine);
725 entry.member_id = m_priv->osync_member_get_id(member);
726 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
728 const OSyncList *mapping_entry_engines = m_priv->osync_obj_engine_get_mapping_entry_engines_of_member(objengine, member);
730 // Calculate summary counts
731 for( const OSyncList *e = mapping_entry_engines; e; e = e->next ) {
732 OSyncMappingEntryEngine *entry_engine = (OSyncMappingEntryEngine*) e->data;
734 if( !m_priv->osync_entry_engine_is_dirty(entry_engine) )
735 continue;
737 dirty = true;
739 OSyncChangeType type = m_priv->osync_entry_engine_get_changetype(entry_engine);
740 switch (type)
742 case OSYNC_CHANGE_TYPE_ADDED:
743 entry.added++;
744 break;
745 case OSYNC_CHANGE_TYPE_MODIFIED:
746 entry.modified++;
747 break;
748 case OSYNC_CHANGE_TYPE_DELETED:
749 entry.deleted++;
750 break;
751 default:
752 break;
756 // Add entry to list
757 list.push_back(entry);
762 return dirty;
766 /////////////////////////////////////////////////////////////////////////////
767 // Callback functions
769 void conflict_handler(OSyncEngine *engine, OSyncMappingEngine *mapping,
770 void *cbdata)
772 CallbackBundle *cb = (CallbackBundle*) cbdata;
774 try {
775 // build the SyncConflict object
776 SyncConflict40Private scp(cb->m_priv, engine, mapping);
777 SyncConflict conflict(scp);
779 // append all conflicting changes as vector objects in the same
780 // order as the opensync library mapping
781 scp.AppendChanges(conflict);
783 // call the status handler
784 cb->m_status->HandleConflict(conflict);
786 catch( std::exception &e ) {
787 cb->m_status->ReportError(
788 string(_C("Conflict not resolved. ")) + e.what());
790 catch( ... ) {
791 cb->m_status->ReportError(
792 _C("Unknown exception caught in conflict_handler()"));
796 void entry_status(OSyncEngineChangeUpdate *status, void *cbdata)
798 CallbackBundle *cb = (CallbackBundle*) cbdata;
800 try {
801 ostringstream oss;
803 OSyncChange *change = cb->m_priv->osync_engine_change_update_get_change(status);
804 OSyncMember *member = cb->m_priv->osync_engine_change_update_get_member(status);
805 OSyncError *error = cb->m_priv->osync_engine_change_update_get_error(status);
807 const char *action = NULL;
808 const char *direction = NULL;
809 string msg;
810 bool error_event = false;
812 switch( cb->m_priv->osync_engine_change_update_get_event(status) )
814 case OSYNC_ENGINE_CHANGE_EVENT_READ:
815 action = _C("Received an entry");
816 direction = _C("from");
817 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
818 break;
820 case OSYNC_ENGINE_CHANGE_EVENT_WRITTEN:
821 action = _C("Sent an entry");
822 direction = _C("to");
823 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
824 break;
826 case OSYNC_ENGINE_CHANGE_EVENT_ERROR:
827 error_event = true;
828 action = _C("Error for entry");
829 direction = _C("and");
830 msg = cb->m_priv->osync_error_print_stack_wrapper(&(error));
831 break;
834 if( action ) {
835 oss << action << " "
836 << cb->m_priv->osync_change_get_uid(change)
837 << "("
838 << cb->m_priv->osync_objformat_get_name( cb->m_priv->osync_change_get_objformat(change))
839 << ") " << direction << _C(" member ")
840 << cb->m_priv->osync_member_get_id(member)
841 << " ("
842 << cb->m_priv->osync_member_get_pluginname(member)
843 << "): "
844 << msg;
846 // call the status handler
847 cb->m_status->EntryStatus(oss.str(), error_event);
850 catch( std::exception &e ) {
851 cb->m_status->ReportError(
852 string(_C("entry_status error: ")) + e.what());
854 catch( ... ) {
855 cb->m_status->ReportError(
856 _C("Unknown exception caught in entry_status()"));
860 void mapping_status(OSyncEngineMappingUpdate *status, void *cbdata)
862 CallbackBundle *cb = (CallbackBundle*) cbdata;
864 try {
865 OSyncError *error = cb->m_priv->osync_engine_mapping_update_get_error(status);
867 ostringstream oss;
868 bool error_event = false;
870 switch( cb->m_priv->osync_engine_mapping_update_get_event(status) )
872 case OSYNC_ENGINE_MAPPING_EVENT_SOLVED:
873 oss << _C("Mapping solved");
874 break;
876 case OSYNC_ENGINE_MAPPING_EVENT_ERROR:
877 error_event = true;
878 oss << _C("Mapping error: ")
879 << cb->m_priv->osync_error_print_stack_wrapper(&(error));
880 break;
883 // call the status handler
884 if( oss.str().size() )
885 cb->m_status->MappingStatus(oss.str(), error_event);
887 catch( std::exception &e ) {
888 cb->m_status->ReportError(
889 string(_C("mapping_status error: ")) + e.what());
891 catch( ... ) {
892 cb->m_status->ReportError(
893 _C("Unknown exception caught in mapping_status()"));
897 void engine_status(OSyncEngineUpdate *status, void *cbdata)
899 CallbackBundle *cb = (CallbackBundle*) cbdata;
901 try {
902 OSyncError *error = cb->m_priv->osync_engine_update_get_error(status);
904 ostringstream oss;
905 bool error_event = false;
906 bool slow_sync = false;
908 switch( cb->m_priv->osync_engine_update_get_event(status) )
910 case OSYNC_ENGINE_EVENT_CONNECTED:
911 oss << _C("All clients connected or error");
912 break;
913 case OSYNC_ENGINE_EVENT_CONNECT_DONE:
914 /* Not of interest for regular user. */
915 break;
916 case OSYNC_ENGINE_EVENT_READ:
917 oss << _C("All clients sent changes or error");
918 break;
919 case OSYNC_ENGINE_EVENT_MAPPED:
920 oss << _C("All changes got mapped");
921 break;
922 case OSYNC_ENGINE_EVENT_MULTIPLIED:
923 oss << _C("All changes got multiplied");
924 break;
925 case OSYNC_ENGINE_EVENT_PREPARED_WRITE:
926 oss << _C("All changes got prepared for write");
927 break;
928 case OSYNC_ENGINE_EVENT_PREPARED_MAP:
929 /* Not of interest for regular user. */
930 break;
931 case OSYNC_ENGINE_EVENT_WRITTEN:
932 oss << _C("All clients have written");
933 break;
934 case OSYNC_ENGINE_EVENT_DISCONNECTED:
935 oss << _C("All clients have disconnected");
936 break;
937 case OSYNC_ENGINE_EVENT_ERROR:
938 error_event = true;
939 oss << _C("The sync failed: ") << cb->m_priv->osync_error_print_stack_wrapper(&(error));
940 break;
941 case OSYNC_ENGINE_EVENT_SUCCESSFUL:
942 oss << _C("The sync was successful");
943 break;
944 case OSYNC_ENGINE_EVENT_PREV_UNCLEAN:
945 oss << _C("The previous synchronization was unclean. Slow-syncing");
946 slow_sync = true;
947 break;
948 case OSYNC_ENGINE_EVENT_END_CONFLICTS:
949 oss << _C("All conflicts have been reported");
950 break;
951 case OSYNC_ENGINE_EVENT_SYNC_DONE:
952 oss << _C("All clients reported sync done");
953 break;
956 // call the status handler
957 if( oss.str().size() )
958 cb->m_status->EngineStatus(oss.str(),
959 error_event,
960 slow_sync);
962 catch( std::exception &e ) {
963 cb->m_status->ReportError(
964 string(_C("engine_status error: ")) + e.what());
966 catch( ... ) {
967 cb->m_status->ReportError(
968 _C("Unknown exception caught in engine_status()"));
972 void member_status(OSyncEngineMemberUpdate *status, void *cbdata)
974 CallbackBundle *cb = (CallbackBundle*) cbdata;
976 try {
977 ostringstream oss;
978 bool error_event = false;
979 bool valid = true;
981 const char *objtype = cb->m_priv->osync_engine_member_update_get_objtype(status);
982 if( objtype == NULL )
983 oss << _C("Main sink");
984 else
985 oss << objtype << _C(" sink");
988 OSyncMember *member = cb->m_priv->osync_engine_member_update_get_member(status);
990 oss << _C(" of member ")
991 << cb->m_priv->osync_member_get_id(member)
992 << " ("
993 << cb->m_priv->osync_member_get_pluginname(member)
994 << ")";
996 OSyncError *error = cb->m_priv->osync_engine_member_update_get_error(status);
998 switch( cb->m_priv->osync_engine_member_update_get_event(status) )
1000 case OSYNC_ENGINE_MEMBER_EVENT_CONNECTED:
1001 oss << _C(" just connected");
1002 break;
1003 case OSYNC_ENGINE_MEMBER_EVENT_CONNECT_DONE:
1004 // Special event - but not interesting for
1005 // the normal user.
1006 break;
1007 case OSYNC_ENGINE_MEMBER_EVENT_DISCONNECTED:
1008 oss << _C(" just disconnected");
1009 break;
1010 case OSYNC_ENGINE_MEMBER_EVENT_READ:
1011 oss << _C(" just sent all changes");
1012 break;
1013 case OSYNC_ENGINE_MEMBER_EVENT_WRITTEN:
1014 oss << _C(" committed all changes");
1015 break;
1016 case OSYNC_ENGINE_MEMBER_EVENT_SYNC_DONE:
1017 oss << _C(" reported sync done");
1018 break;
1019 case OSYNC_ENGINE_MEMBER_EVENT_DISCOVERED:
1020 oss << _C(" discovered its objtypes");
1021 break;
1022 case OSYNC_ENGINE_MEMBER_EVENT_ERROR:
1023 oss << _C(" had an error: ")
1024 << cb->m_priv->osync_error_print_stack_wrapper(&error);
1025 error_event = true;
1026 break;
1027 default:
1028 valid = false;
1029 break;
1032 // call the status handler
1033 if( oss.str().size() && valid ) {
1034 cb->m_status->MemberStatus(
1035 cb->m_priv->osync_member_get_id(member),
1036 cb->m_priv->osync_member_get_pluginname(member),
1037 oss.str(), error_event);
1040 catch( std::exception &e ) {
1041 cb->m_status->ReportError(
1042 string(_C("member_status error: ")) + e.what());
1044 catch( ... ) {
1045 cb->m_status->ReportError(
1046 _C("Unknown exception caught in member_status()"));
1050 void multiply_summary(OSyncEngine *engine, void *cbdata)
1052 CallbackBundle *cb = (CallbackBundle*) cbdata;
1054 try {
1055 // build the SyncSummary object
1056 SyncSummary40Private ssp(cb->m_priv, engine);
1057 SyncSummary summary(ssp);
1059 // append a summary for each objtype member
1060 if( ssp.AppendMembers(summary) ) {
1061 // call the status handler only if dirty
1062 cb->m_status->CheckSummary(summary);
1064 else {
1065 // nothing dirty, just continue
1066 summary.Continue();
1069 catch( std::exception &e ) {
1070 cb->m_status->ReportError(
1071 string(_C("Error handling summary item. ")) + e.what());
1073 catch( ... ) {
1074 cb->m_status->ReportError(
1075 _C("Unknown exception caught in multiply_summary()"));
1080 /////////////////////////////////////////////////////////////////////////////
1081 // OS40ConfigResource - public members
1083 OS40ConfigResource::OS40ConfigResource(const OS40PluginConfig &parent,
1084 void *resource,
1085 bool existing_resource)
1086 : m_priv( new OS40ConfigResourcePrivate )
1087 , m_exists(existing_resource)
1089 m_priv->m_privapi = parent.m_privapi;
1090 m_priv->m_parentpriv = parent.m_priv.get();
1091 m_priv->m_resource = (OSyncPluginResource*) resource;
1094 OS40ConfigResource::~OS40ConfigResource()
1096 // unref the resource, since we hold a copy
1097 m_priv->m_privapi->
1098 osync_plugin_resource_unref(m_priv->m_resource);
1099 delete m_priv;
1102 bool OS40ConfigResource::IsExistingResource() const
1104 return m_exists;
1107 // safe to call multiple times
1108 void OS40ConfigResource::AddResource()
1110 if( !IsExistingResource() ) {
1111 m_priv->m_privapi->
1112 osync_plugin_config_add_resource(
1113 m_priv->m_parentpriv->m_config,
1114 m_priv->m_resource);
1118 bool OS40ConfigResource::IsEnabled() const
1120 return m_priv->m_privapi->
1121 osync_plugin_resource_is_enabled(m_priv->m_resource);
1124 OS40ConfigResource& OS40ConfigResource::Enable(bool enabled)
1126 m_priv->m_privapi->osync_plugin_resource_enable(m_priv->m_resource,
1127 enabled);
1128 return *this;
1131 bool OS40ConfigResource::FindObjFormat(const std::string &objformat,
1132 std::string &config)
1134 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1135 sinks = m_priv->m_privapi->
1136 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1137 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1138 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1139 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1140 const char *cfg = m_priv->m_privapi->osync_objformat_sink_get_config(sink);
1141 if( cfg )
1142 config = cfg;
1143 else
1144 config.clear();
1145 return true;
1148 return false;
1151 OS40ConfigResource& OS40ConfigResource::SetObjFormat(const std::string &objformat,
1152 const std::string &config)
1154 // if it already exists, just set the config value
1155 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1156 sinks = m_priv->m_privapi->
1157 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1158 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1159 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1160 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1161 m_priv->m_privapi->osync_objformat_sink_set_config(sink, config.c_str());
1162 return *this;
1166 // if we get here, it doesn't exist, and we need to add it
1167 OSyncObjFormatSink *sink = m_priv->m_privapi->
1168 osync_objformat_sink_new(objformat.c_str(),
1169 m_priv->m_privapi->error);
1170 if( !sink )
1171 throw std::runtime_error(m_priv->m_privapi->error.GetErrorMsg());
1173 if( config.size() )
1174 m_priv->m_privapi->osync_objformat_sink_set_config(sink,
1175 config.c_str());
1176 m_priv->m_privapi->osync_plugin_resource_add_objformat_sink(
1177 m_priv->m_resource, sink);
1178 m_priv->m_privapi->osync_objformat_sink_unref(sink);
1179 return *this;
1182 std::string OS40ConfigResource::GetName() const
1184 string value;
1185 const char *pv = m_priv->m_privapi->
1186 osync_plugin_resource_get_name(m_priv->m_resource);
1187 if( pv )
1188 value = pv;
1189 return value;
1192 OS40ConfigResource& OS40ConfigResource::SetName(const std::string &name)
1194 m_priv->m_privapi->
1195 osync_plugin_resource_set_name(m_priv->m_resource, name.c_str());
1196 return *this;
1199 std::string OS40ConfigResource::GetPreferredFormat() const
1201 string value;
1202 const char *pv = m_priv->m_privapi->
1203 osync_plugin_resource_get_preferred_format(m_priv->m_resource);
1204 if( pv )
1205 value = pv;
1206 return value;
1209 OS40ConfigResource& OS40ConfigResource::SetPreferredFormat(const std::string &format)
1211 m_priv->m_privapi->
1212 osync_plugin_resource_set_preferred_format(m_priv->m_resource,
1213 format.c_str());
1214 return *this;
1217 std::string OS40ConfigResource::GetMime() const
1219 string value;
1220 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_mime(
1221 m_priv->m_resource);
1222 if( pv )
1223 value = pv;
1224 return value;
1227 OS40ConfigResource& OS40ConfigResource::SetMime(const std::string &mime)
1229 m_priv->m_privapi->osync_plugin_resource_set_mime(m_priv->m_resource,
1230 mime.c_str());
1231 return *this;
1234 std::string OS40ConfigResource::GetObjType() const
1236 string value;
1237 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_objtype(
1238 m_priv->m_resource);
1239 if( pv )
1240 value = pv;
1241 return value;
1244 OS40ConfigResource& OS40ConfigResource::SetObjType(const std::string &objtype)
1246 m_priv->m_privapi->osync_plugin_resource_set_objtype(m_priv->m_resource,
1247 objtype.c_str());
1248 return *this;
1251 std::string OS40ConfigResource::GetPath() const
1253 string value;
1254 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_path(
1255 m_priv->m_resource);
1256 if( pv )
1257 value = pv;
1258 return value;
1261 OS40ConfigResource& OS40ConfigResource::SetPath(const std::string &path)
1263 m_priv->m_privapi->osync_plugin_resource_set_path(m_priv->m_resource,
1264 path.c_str());
1265 return *this;
1268 std::string OS40ConfigResource::GetUrl() const
1270 string value;
1271 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_url(
1272 m_priv->m_resource);
1273 if( pv )
1274 value = pv;
1275 return value;
1278 OS40ConfigResource& OS40ConfigResource::SetUrl(const std::string &url)
1280 m_priv->m_privapi->osync_plugin_resource_set_url(m_priv->m_resource,
1281 url.c_str());
1282 return *this;
1286 /////////////////////////////////////////////////////////////////////////////
1287 // OS40PluginConfig - public members
1289 OS40PluginConfig::OS40PluginConfig(OpenSync40Private *privapi,
1290 void *member,
1291 void *config)
1292 : m_privapi(privapi)
1294 m_priv.reset( new OS40PluginConfigPrivate );
1295 m_priv->m_member = (OSyncMember*) member;
1296 m_priv->m_config = (OSyncPluginConfig*) config;
1299 std::string OS40PluginConfig::GetAdvanced(const std::string &name)
1301 const char *value = m_privapi->osync_plugin_config_get_advancedoption_value_by_name(m_priv->m_config, name.c_str());
1302 string val;
1303 if( value )
1304 val = value;
1305 return val;
1308 void OS40PluginConfig::SetAdvanced(const std::string &name,
1309 const std::string &display_name,
1310 const std::string &val)
1312 SetAdvanced(name, display_name, STRING_TYPE, val);
1315 void OS40PluginConfig::SetAdvanced(const std::string &name,
1316 const std::string &display_name,
1317 int val_type,
1318 const std::string &val)
1320 // find the first advanced option with this name
1321 SyncListHandle aos(m_privapi->osync_list_free);
1322 aos = m_privapi->osync_plugin_config_get_advancedoptions(m_priv->m_config);
1323 OSyncPluginAdvancedOption *option = 0;
1324 for( OSyncList *o = aos.get(); o; o = o->next ) {
1325 option = (OSyncPluginAdvancedOption*) o->data;
1327 if( name == m_privapi->osync_plugin_advancedoption_get_name(option) )
1328 break;
1331 if( option ) {
1332 // found existing option, set it with val
1333 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1335 else {
1336 // option with that name does not exist, so create it
1337 option = m_privapi->osync_plugin_advancedoption_new(m_privapi->error);
1338 if( !option )
1339 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1341 m_privapi->osync_plugin_advancedoption_set_name(option, name.c_str());
1342 m_privapi->osync_plugin_advancedoption_set_displayname(option, display_name.c_str());
1343 OSyncPluginAdvancedOptionType type;
1344 switch( val_type )
1346 case NONE_TYPE:
1347 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_NONE;
1348 break;
1349 case BOOL_TYPE:
1350 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_BOOL;
1351 break;
1352 case CHAR_TYPE:
1353 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_CHAR;
1354 break;
1355 case DOUBLE_TYPE:
1356 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_DOUBLE;
1357 break;
1358 case INT_TYPE:
1359 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_INT;
1360 break;
1361 case LONG_TYPE:
1362 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONG;
1363 break;
1364 case LONGLONG_TYPE:
1365 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONGLONG;
1366 break;
1367 case UINT_TYPE:
1368 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_UINT;
1369 break;
1370 case ULONG_TYPE:
1371 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONG;
1372 break;
1373 case ULONGLONG_TYPE:
1374 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONGLONG;
1375 break;
1376 case STRING_TYPE:
1377 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_STRING;
1378 break;
1379 default:
1380 throw std::logic_error("Bad type in SetAdvanced()");
1382 m_privapi->osync_plugin_advancedoption_set_type(option, type);
1383 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1384 m_privapi->osync_plugin_config_add_advancedoption(m_priv->m_config, option);
1385 m_privapi->osync_plugin_advancedoption_unref(option);
1389 OS40PluginConfig::OS40ConfigResourcePtr
1390 OS40PluginConfig::GetResource(const std::string &objtype)
1392 OS40ConfigResourcePtr ptr;
1394 // FIXME - get_resources() does not give us a copy, so don't use
1395 // the SyncListHandle here
1396 OSyncList *rs = m_privapi->osync_plugin_config_get_resources(m_priv->m_config);
1397 for( OSyncList *o = rs; o; o = o->next ) {
1398 OSyncPluginResource *res = (OSyncPluginResource*) o->data;
1399 if( objtype == m_privapi->osync_plugin_resource_get_objtype(res) ) {
1400 // bump the resource count, since OS40ConfigResource
1401 // will unref it in the destructor
1402 m_privapi->osync_plugin_resource_ref(res);
1403 ptr.reset( new OS40ConfigResource(*this, res, true) );
1404 return ptr;
1408 // this res has a ref bump already, no ref() needed like it is above
1409 OSyncPluginResource *res = m_privapi->osync_plugin_resource_new(m_privapi->error);
1410 if( !res )
1411 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1412 ptr.reset( new OS40ConfigResource(*this, res, false) );
1413 // we search by objtype name, so make sure this is set in
1414 // the new object
1415 ptr->SetObjType(objtype);
1416 return ptr;
1419 std::string OS40PluginConfig::GetUsername() const
1421 string username;
1423 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1424 if( !auth )
1425 return username;
1427 const char *un = m_privapi->osync_plugin_authentication_get_username(auth);
1428 if( !un )
1429 return username;
1431 username = un;
1432 return username;
1435 void OS40PluginConfig::SetUsername(const std::string &username)
1437 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1438 if( !auth ) {
1439 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1440 if( !auth )
1441 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1442 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_USERNAME) ) {
1443 m_privapi->osync_plugin_authentication_unref(auth);
1444 throw std::runtime_error(_C("Username (authentication parameter) is not supported in plugin!"));
1447 // all looks ok, add it to the config
1448 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1449 // unref our copy, since the config now has it...
1450 // our auth pointer will still be valid since config holds it
1451 m_privapi->osync_plugin_authentication_unref(auth);
1454 m_privapi->osync_plugin_authentication_set_username(auth, username.c_str());
1457 std::string OS40PluginConfig::GetPassword() const
1459 string password;
1461 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1462 if( !auth )
1463 return password;
1465 const char *pass = m_privapi->osync_plugin_authentication_get_password(auth);
1466 if( !pass )
1467 return password;
1469 password = pass;
1470 return password;
1473 void OS40PluginConfig::SetPassword(const std::string &password)
1475 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1476 if( !auth ) {
1477 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1478 if( !auth )
1479 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1480 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_PASSWORD) ) {
1481 m_privapi->osync_plugin_authentication_unref(auth);
1482 throw std::runtime_error(_C("Password authentication is not supported in plugin!"));
1485 // all looks ok, add it to the config
1486 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1487 // unref our copy, since the config now has it...
1488 // our auth pointer will still be valid since config holds it
1489 m_privapi->osync_plugin_authentication_unref(auth);
1492 m_privapi->osync_plugin_authentication_set_password(auth, password.c_str());
1495 void OS40PluginConfig::Save()
1497 if( !m_privapi->osync_member_save(m_priv->m_member, m_privapi->error) )
1498 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1502 /////////////////////////////////////////////////////////////////////////////
1503 // OpenSync40 (API override class) - public members
1505 OpenSync40::OpenSync40()
1507 // due to bugs in the way opensync 0.22 loads its modules,
1508 // (i.e. it doesn't load the plugins using RTLD_LOCAL, and
1509 // so libopensync.so.0 is loaded and pollutes the symbol table,
1510 // causing symbol clashes) we need to make sure that
1511 // OpenSync40 is only loaded first... if OpenSync22 was
1512 // loaded first, we will fail, so error out
1513 if( OpenSync22::SymbolsLoaded() )
1514 throw std::logic_error("Always load OpenSync40 before OpenSync22, to avoid symbol table conflicts.");
1516 if( !Open("libopensync.so.1") )
1517 throw DlError("Can't dlopen libopensync.so.1");
1519 // store locally in case of constructor exception in LoadSym
1520 std::auto_ptr<OpenSync40Private> p(new OpenSync40Private(*this));
1522 // load all required symbols...
1523 // we don't need to use try/catch here, since the base
1524 // class destructor will clean up for us if LoadSym() throws
1525 LoadSym(p->osync_get_version, "osync_get_version");
1526 LoadSym(p->osync_error_print, "osync_error_print");
1527 LoadSym(p->osync_error_print_stack, "osync_error_print_stack");
1528 LoadSym(p->osync_error_is_set, "osync_error_is_set");
1529 LoadSym(p->osync_error_unref, "osync_error_unref");
1530 LoadSym(p->osync_group_env_new, "osync_group_env_new");
1531 LoadSym(p->osync_format_env_new, "osync_format_env_new");
1532 LoadSym(p->osync_plugin_env_new, "osync_plugin_env_new");
1533 LoadSym(p->osync_group_env_unref, "osync_group_env_unref");
1534 LoadSym(p->osync_format_env_unref, "osync_format_env_unref");
1535 LoadSym(p->osync_plugin_env_unref, "osync_plugin_env_unref");
1536 LoadSym(p->osync_plugin_env_load, "osync_plugin_env_load");
1537 LoadSym(p->osync_plugin_env_get_plugins,"osync_plugin_env_get_plugins");
1538 LoadSym(p->osync_plugin_get_name, "osync_plugin_get_name");
1539 LoadSym(p->osync_list_free, "osync_list_free");
1540 LoadSym(p->osync_group_env_load_groups, "osync_group_env_load_groups");
1541 LoadSym(p->osync_format_env_load_plugins,
1542 "osync_format_env_load_plugins");
1543 LoadSym(p->osync_group_env_get_groups, "osync_group_env_get_groups");
1544 LoadSym(p->osync_group_get_name, "osync_group_get_name");
1545 LoadSym(p->osync_group_env_find_group, "osync_group_env_find_group");
1546 LoadSym(p->osync_group_get_members, "osync_group_get_members");
1547 LoadSym(p->osync_member_get_name, "osync_member_get_name");
1548 LoadSym(p->osync_member_get_id, "osync_member_get_id");
1549 LoadSym(p->osync_member_get_pluginname, "osync_member_get_pluginname");
1550 LoadSym(p->osync_format_env_get_objformats,
1551 "osync_format_env_get_objformats");
1552 LoadSym(p->osync_objformat_get_name, "osync_objformat_get_name");
1553 LoadSym(p->osync_objformat_get_objtype, "osync_objformat_get_objtype");
1554 LoadSym(p->osync_group_new, "osync_group_new");
1555 LoadSym(p->osync_group_unref, "osync_group_unref");
1556 LoadSym(p->osync_group_set_name, "osync_group_set_name");
1557 LoadSym(p->osync_group_env_add_group, "osync_group_env_add_group");
1558 LoadSym(p->osync_group_save, "osync_group_save");
1559 LoadSym(p->osync_group_delete, "osync_group_delete");
1560 LoadSym(p->osync_group_env_remove_group,"osync_group_env_remove_group");
1561 LoadSym(p->osync_plugin_env_find_plugin,"osync_plugin_env_find_plugin");
1562 LoadSym(p->osync_member_unref, "osync_member_unref");
1563 LoadSym(p->osync_member_new, "osync_member_new");
1564 LoadSym(p->osync_group_add_member, "osync_group_add_member");
1565 LoadSym(p->osync_member_set_pluginname, "osync_member_set_pluginname");
1566 LoadSym(p->osync_member_set_name, "osync_member_set_name");
1567 LoadSym(p->osync_member_save, "osync_member_save");
1568 LoadSym(p->osync_group_find_member, "osync_group_find_member");
1569 LoadSym(p->osync_member_delete, "osync_member_delete");
1570 LoadSym(p->osync_group_remove_member, "osync_group_remove_member");
1571 LoadSym(p->osync_plugin_config_new, "osync_plugin_config_new");
1572 LoadSym(p->osync_plugin_config_file_load,
1573 "osync_plugin_config_file_load");
1574 LoadSym(p->osync_member_set_config, "osync_member_set_config");
1575 LoadSym(p->osync_member_get_config_or_default,
1576 "osync_member_get_config_or_default");
1577 LoadSym(p->osync_plugin_config_file_save,
1578 "osync_plugin_config_file_save");
1579 LoadSym(p->osync_plugin_get_config_type,"osync_plugin_get_config_type");
1580 LoadSym(p->osync_engine_new, "osync_engine_new");
1581 LoadSym(p->osync_engine_unref, "osync_engine_unref");
1582 LoadSym(p->osync_engine_discover_and_block,
1583 "osync_engine_discover_and_block");
1584 LoadSym(p->osync_member_get_objtypes, "osync_member_get_objtypes");
1585 LoadSym(p->osync_list_length, "osync_list_length");
1586 LoadSym(p->osync_error_set, "osync_error_set");
1587 LoadSym(p->osync_engine_finalize, "osync_engine_finalize");
1588 LoadSym(p->osync_mapping_engine_get_changes,
1589 "osync_mapping_engine_get_changes");
1590 LoadSym(p->osync_mapping_engine_supports_ignore,
1591 "osync_mapping_engine_supports_ignore");
1592 LoadSym(p->osync_mapping_engine_supports_use_latest,
1593 "osync_mapping_engine_supports_use_latest");
1594 LoadSym(p->osync_list_nth, "osync_list_nth");
1595 LoadSym(p->osync_engine_mapping_solve, "osync_engine_mapping_solve");
1596 LoadSym(p->osync_engine_abort, "osync_engine_abort");
1597 LoadSym(p->osync_engine_mapping_duplicate,
1598 "osync_engine_mapping_duplicate");
1599 LoadSym(p->osync_engine_mapping_ignore_conflict,
1600 "osync_engine_mapping_ignore_conflict");
1601 LoadSym(p->osync_engine_mapping_use_latest,
1602 "osync_engine_mapping_use_latest");
1603 LoadSym(p->osync_change_get_changetype, "osync_change_get_changetype");
1604 LoadSym(p->osync_mapping_engine_change_find_member,
1605 "osync_mapping_engine_change_find_member");
1606 LoadSym(p->osync_change_get_data, "osync_change_get_data");
1607 LoadSym(p->osync_data_get_printable, "osync_data_get_printable");
1608 LoadSym(p->osync_free, "osync_free");
1609 LoadSym(p->osync_change_get_uid, "osync_change_get_uid");
1610 LoadSym(p->osync_engine_continue, "osync_engine_continue");
1611 LoadSym(p->osync_engine_get_objengines, "osync_engine_get_objengines");
1612 LoadSym(p->osync_obj_engine_get_members,
1613 "osync_obj_engine_get_members");
1614 LoadSym(p->osync_obj_engine_get_objtype,
1615 "osync_obj_engine_get_objtype");
1616 LoadSym(p->osync_obj_engine_get_mapping_entry_engines_of_member,
1617 "osync_obj_engine_get_mapping_entry_engines_of_member");
1618 LoadSym(p->osync_entry_engine_is_dirty,"osync_entry_engine_is_dirty");
1619 LoadSym(p->osync_entry_engine_get_changetype,
1620 "osync_entry_engine_get_changetype");
1621 LoadSym(p->osync_engine_change_update_get_change,
1622 "osync_engine_change_update_get_change");
1623 LoadSym(p->osync_engine_change_update_get_member,
1624 "osync_engine_change_update_get_member");
1625 LoadSym(p->osync_engine_change_update_get_error,
1626 "osync_engine_change_update_get_error");
1627 LoadSym(p->osync_engine_change_update_get_event,
1628 "osync_engine_change_update_get_event");
1629 LoadSym(p->osync_change_get_objformat, "osync_change_get_objformat");
1630 LoadSym(p->osync_engine_mapping_update_get_error,
1631 "osync_engine_mapping_update_get_error");
1632 LoadSym(p->osync_engine_update_get_error,
1633 "osync_engine_update_get_error");
1634 LoadSym(p->osync_engine_update_get_event,
1635 "osync_engine_update_get_event");
1636 LoadSym(p->osync_engine_member_update_get_objtype,
1637 "osync_engine_member_update_get_objtype");
1638 LoadSym(p->osync_engine_member_update_get_member,
1639 "osync_engine_member_update_get_member");
1640 LoadSym(p->osync_engine_member_update_get_error,
1641 "osync_engine_member_update_get_error");
1642 LoadSym(p->osync_engine_member_update_get_event,
1643 "osync_engine_member_update_get_event");
1644 LoadSym(p->osync_engine_set_conflict_callback,
1645 "osync_engine_set_conflict_callback");
1646 LoadSym(p->osync_engine_set_changestatus_callback,
1647 "osync_engine_set_changestatus_callback");
1648 LoadSym(p->osync_engine_set_mappingstatus_callback,
1649 "osync_engine_set_mappingstatus_callback");
1650 LoadSym(p->osync_engine_set_enginestatus_callback,
1651 "osync_engine_set_enginestatus_callback");
1652 LoadSym(p->osync_engine_set_memberstatus_callback,
1653 "osync_engine_set_memberstatus_callback");
1654 LoadSym(p->osync_engine_set_multiply_callback,
1655 "osync_engine_set_multiply_callback");
1656 LoadSym(p->osync_engine_initialize, "osync_engine_initialize");
1657 LoadSym(p->osync_engine_synchronize_and_block,
1658 "osync_engine_synchronize_and_block");
1659 LoadSym(p->osync_engine_mapping_update_get_event,
1660 "osync_engine_mapping_update_get_event");
1661 LoadSym(p->osync_plugin_resource_unref,
1662 "osync_plugin_resource_unref");
1663 LoadSym(p->osync_plugin_config_add_resource,
1664 "osync_plugin_config_add_resource");
1665 LoadSym(p->osync_plugin_resource_is_enabled,
1666 "osync_plugin_resource_is_enabled");
1667 LoadSym(p->osync_plugin_resource_enable,
1668 "osync_plugin_resource_enable");
1669 LoadSym(p->osync_plugin_resource_get_objformat_sinks,
1670 "osync_plugin_resource_get_objformat_sinks");
1671 LoadSym(p->osync_objformat_sink_get_objformat,
1672 "osync_objformat_sink_get_objformat");
1673 LoadSym(p->osync_objformat_sink_get_config,
1674 "osync_objformat_sink_get_config");
1675 LoadSym(p->osync_objformat_sink_set_config,
1676 "osync_objformat_sink_set_config");
1677 LoadSym(p->osync_objformat_sink_new,
1678 "osync_objformat_sink_new");
1679 LoadSym(p->osync_plugin_resource_add_objformat_sink,
1680 "osync_plugin_resource_add_objformat_sink");
1681 LoadSym(p->osync_objformat_sink_unref,
1682 "osync_objformat_sink_unref");
1683 LoadSym(p->osync_plugin_resource_get_preferred_format,
1684 "osync_plugin_resource_get_preferred_format");
1685 LoadSym(p->osync_plugin_resource_set_preferred_format,
1686 "osync_plugin_resource_set_preferred_format");
1687 LoadSym(p->osync_plugin_resource_get_mime,
1688 "osync_plugin_resource_get_mime");
1689 LoadSym(p->osync_plugin_resource_set_mime,
1690 "osync_plugin_resource_set_mime");
1691 LoadSym(p->osync_plugin_resource_get_objtype,
1692 "osync_plugin_resource_get_objtype");
1693 LoadSym(p->osync_plugin_resource_set_objtype,
1694 "osync_plugin_resource_set_objtype");
1695 LoadSym(p->osync_plugin_resource_get_path,
1696 "osync_plugin_resource_get_path");
1697 LoadSym(p->osync_plugin_resource_set_path,
1698 "osync_plugin_resource_set_path");
1699 LoadSym(p->osync_plugin_resource_get_url,
1700 "osync_plugin_resource_get_url");
1701 LoadSym(p->osync_plugin_resource_set_url,
1702 "osync_plugin_resource_set_url");
1703 LoadSym(p->osync_plugin_config_get_advancedoption_value_by_name,
1704 "osync_plugin_config_get_advancedoption_value_by_name");
1705 LoadSym(p->osync_plugin_config_get_advancedoptions,
1706 "osync_plugin_config_get_advancedoptions");
1707 LoadSym(p->osync_plugin_config_add_advancedoption,
1708 "osync_plugin_config_add_advancedoption");
1709 LoadSym(p->osync_plugin_advancedoption_new,
1710 "osync_plugin_advancedoption_new");
1711 LoadSym(p->osync_plugin_advancedoption_unref,
1712 "osync_plugin_advancedoption_unref");
1713 LoadSym(p->osync_plugin_advancedoption_get_name,
1714 "osync_plugin_advancedoption_get_name");
1715 LoadSym(p->osync_plugin_advancedoption_set_name,
1716 "osync_plugin_advancedoption_set_name");
1717 LoadSym(p->osync_plugin_advancedoption_set_displayname,
1718 "osync_plugin_advancedoption_set_displayname");
1719 LoadSym(p->osync_plugin_advancedoption_set_type,
1720 "osync_plugin_advancedoption_set_type");
1721 LoadSym(p->osync_plugin_advancedoption_set_value,
1722 "osync_plugin_advancedoption_set_value");
1723 LoadSym(p->osync_plugin_config_get_resources,
1724 "osync_plugin_config_get_resources");
1725 LoadSym(p->osync_plugin_resource_ref,
1726 "osync_plugin_resource_ref");
1727 LoadSym(p->osync_plugin_resource_new,
1728 "osync_plugin_resource_new");
1729 LoadSym(p->osync_plugin_resource_get_name,
1730 "osync_plugin_resource_get_name");
1731 LoadSym(p->osync_plugin_resource_set_name,
1732 "osync_plugin_resource_set_name");
1733 LoadSym(p->osync_plugin_config_get_authentication,
1734 "osync_plugin_config_get_authentication");
1735 LoadSym(p->osync_plugin_authentication_get_password,
1736 "osync_plugin_authentication_get_password");
1737 LoadSym(p->osync_plugin_authentication_new,
1738 "osync_plugin_authentication_new");
1739 LoadSym(p->osync_plugin_authentication_option_is_supported,
1740 "osync_plugin_authentication_option_is_supported");
1741 LoadSym(p->osync_plugin_authentication_unref,
1742 "osync_plugin_authentication_unref");
1743 LoadSym(p->osync_plugin_config_set_authentication,
1744 "osync_plugin_config_set_authentication");
1745 LoadSym(p->osync_plugin_authentication_set_password,
1746 "osync_plugin_authentication_set_password");
1747 LoadSym(p->osync_plugin_authentication_get_username,
1748 "osync_plugin_authentication_get_username");
1749 LoadSym(p->osync_plugin_authentication_set_username,
1750 "osync_plugin_authentication_set_username");
1751 LoadSym(p->osync_group_set_objtype_enabled,
1752 "osync_group_set_objtype_enabled");
1754 // fixup free pointers
1755 p->group_env.SetFreeFunc(p->osync_group_env_unref);
1756 p->format_env.SetFreeFunc(p->osync_format_env_unref);
1757 p->plugin_env.SetFreeFunc(p->osync_plugin_env_unref);
1759 // setup opensync support environment
1760 SetupEnvironment(p.get());
1762 // this pointer is ours now
1763 m_priv = p.release();
1766 OpenSync40::~OpenSync40()
1768 delete m_priv;
1769 m_priv = 0;
1772 void OpenSync40::SetupEnvironment(OpenSync40Private *p)
1774 // allocate group, format, and env
1775 p->group_env = p->osync_group_env_new(p->error);
1776 if( !p->group_env.get() )
1777 throw std::runtime_error(p->error.GetErrorMsg());
1779 p->format_env = p->osync_format_env_new(p->error);
1780 if( !p->format_env.get() )
1781 throw std::runtime_error(p->error.GetErrorMsg());
1783 p->plugin_env = p->osync_plugin_env_new(p->error);
1784 if( !p->plugin_env.get() )
1785 throw std::runtime_error(p->error.GetErrorMsg());
1787 // load group, format, and env
1788 if( !p->osync_group_env_load_groups(p->group_env.get(), NULL, p->error) ||
1789 !p->osync_format_env_load_plugins(p->format_env.get(), NULL, p->error) ||
1790 !p->osync_plugin_env_load(p->plugin_env.get(), NULL, p->error) )
1791 throw std::runtime_error(p->error.GetErrorMsg());
1794 const char* OpenSync40::GetVersion() const
1796 return m_priv->osync_get_version();
1799 const char* OpenSync40::GetEngineName() const
1801 return "0.40";
1804 void OpenSync40::GetPluginNames(string_list_type &plugins)
1806 // start fresh
1807 plugins.clear();
1809 OSyncPlugin *plugin;
1810 OSyncList *plugin_list, *p;
1812 plugin_list = m_priv->osync_plugin_env_get_plugins(m_priv->plugin_env.get());
1813 for( p = plugin_list; p; p = p->next ) {
1814 plugin = (OSyncPlugin *) p->data;
1815 plugins.push_back(m_priv->osync_plugin_get_name(plugin));
1818 m_priv->osync_list_free(plugin_list);
1821 void OpenSync40::GetFormats(format_list_type &formats)
1823 // start fresh
1824 formats.clear();
1826 OSyncList *o, *list = m_priv->osync_format_env_get_objformats(m_priv->format_env.get());
1828 for( o = list; o; o = o->next ) {
1829 OSyncObjFormat *format = (OSyncObjFormat *) o->data;
1831 Format new_format;
1832 new_format.name = m_priv->osync_objformat_get_name(format);
1833 new_format.object_type = m_priv->osync_objformat_get_objtype(format);
1835 formats.push_back(new_format);
1838 m_priv->osync_list_free(list);
1841 void OpenSync40::GetGroupNames(string_list_type &groups)
1843 // start fresh
1844 groups.clear();
1846 OSyncGroup *group;
1847 OSyncList *g, *group_list = m_priv->osync_group_env_get_groups(m_priv->group_env.get());
1849 for( g = group_list; g; g = g->next ) {
1850 group = (OSyncGroup *) g->data;
1851 groups.push_back(m_priv->osync_group_get_name(group));
1854 m_priv->osync_list_free(group_list);
1857 void OpenSync40::GetMembers(const std::string &group_name,
1858 member_list_type &members)
1860 // start fresh
1861 members.clear();
1863 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1864 if( !group ) {
1865 ostringstream oss;
1866 oss << "GetMembers(): " << _C("Unable to find group with name: ") << group_name;
1867 throw std::runtime_error(oss.str());
1870 OSyncList *member_list = m_priv->osync_group_get_members(group);
1871 for( OSyncList *m = member_list; m; m = m->next ) {
1872 Member new_member;
1873 OSyncMember *member = (OSyncMember *) m->data;
1874 const char *membername = m_priv->osync_member_get_name(member);
1875 if (membername) {
1876 new_member.friendly_name = membername;
1879 new_member.group_name = group_name;
1880 new_member.id = m_priv->osync_member_get_id(member);
1881 new_member.plugin_name = m_priv->osync_member_get_pluginname(member);
1883 // add to member list
1884 members.push_back(new_member);
1887 // cleanup
1888 m_priv->osync_list_free(member_list);
1891 void OpenSync40::AddGroup(const std::string &group_name)
1893 OSyncGroup *group = m_priv->osync_group_new(m_priv->error);
1894 if( !group )
1895 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1897 m_priv->osync_group_set_name(group, group_name.c_str());
1898 if( !m_priv->osync_group_env_add_group(m_priv->group_env.get(), group, m_priv->error) ) {
1899 m_priv->osync_group_unref(group);
1900 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1903 if( !m_priv->osync_group_save(group, m_priv->error) ) {
1904 m_priv->osync_group_unref(group);
1905 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1908 m_priv->osync_group_unref(group);
1911 void OpenSync40::DeleteGroup(const std::string &group_name)
1913 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1914 if( !group )
1915 throw std::runtime_error(string("DeleteGroup(): ") + _C("Group not found: ") + group_name);
1917 if( !m_priv->osync_group_delete(group, m_priv->error) )
1918 throw std::runtime_error("DeleteGroup(): " + m_priv->error.GetErrorMsg());
1920 m_priv->osync_group_env_remove_group(m_priv->group_env.get(), group);
1923 Converter& OpenSync40::GetConverter()
1925 return m_priv->converter;
1928 long OpenSync40::AddMember(const std::string &group_name,
1929 const std::string &plugin_name,
1930 const std::string &member_name)
1932 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1933 if( !group )
1934 throw std::runtime_error(string("AddMember(): ") + _C("Group not found: ") + group_name);
1936 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), plugin_name.c_str());
1937 if( !plugin )
1938 throw std::runtime_error(string("AddMember(): ") + _C("Plugin not found: ") + plugin_name);
1940 vLateSmartPtr<OSyncMember, void(*)(OSyncMember*)> mptr(m_priv->osync_member_unref);
1941 mptr = m_priv->osync_member_new(m_priv->error);
1942 if( !mptr.get() )
1943 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1945 m_priv->osync_group_add_member(group, mptr.get());
1946 m_priv->osync_member_set_pluginname(mptr.get(), plugin_name.c_str());
1948 if( member_name.size() )
1949 m_priv->osync_member_set_name(mptr.get(), member_name.c_str());
1951 if( !m_priv->osync_member_save(mptr.get(), m_priv->error) )
1952 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1954 return m_priv->osync_member_get_id(mptr.get());
1957 void OpenSync40::DeleteMember(const std::string &group_name, long member_id)
1959 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1960 if( !group )
1961 throw std::runtime_error(string("DeleteMember(): ") + _C("Group not found: ") + group_name);
1963 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1964 if( !member ) {
1965 ostringstream oss;
1966 oss << "DeleteMember(): " << _C("Member not found: ") << member_id;
1967 throw std::runtime_error(oss.str());
1970 if( !m_priv->osync_member_delete(member, m_priv->error) )
1971 throw std::runtime_error("DeleteMember(): " + m_priv->error.GetErrorMsg());
1973 m_priv->osync_group_remove_member(group, member);
1976 void OpenSync40::DeleteMember(const std::string &group_name,
1977 const std::string &plugin_name)
1979 member_list_type mlist;
1980 GetMembers(group_name, mlist);
1981 Member *member = mlist.Find(plugin_name.c_str());
1982 if( !member )
1983 throw std::runtime_error(string("DeleteMember(): ") + _C("Member not found: ") + plugin_name);
1985 DeleteMember(group_name, member->id);
1988 bool OpenSync40::IsConfigurable(const std::string &group_name,
1989 long member_id)
1991 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1992 if( !group )
1993 throw std::runtime_error(string("IsConfigurable(): ") + _C("Group not found: ") + group_name);
1995 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1996 if( !member ) {
1997 ostringstream oss;
1998 oss << "IsConfigurable(): " << _C("Member not found: ") << member_id;
1999 throw std::runtime_error(oss.str());
2002 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2003 if( !plugin )
2004 throw std::runtime_error(string("IsConfigurable(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2007 OSyncPluginConfigurationType type = m_priv->osync_plugin_get_config_type(plugin);
2008 return type != OSYNC_PLUGIN_NO_CONFIGURATION;
2011 std::string OpenSync40::GetConfiguration(const std::string &group_name,
2012 long member_id)
2014 if( !IsConfigurable(group_name, member_id) ) {
2015 ostringstream oss;
2016 oss << "GetConfiguration(): " << _C("Member ") << member_id << _C(" of group '") << group_name << _C("' does not accept configuration.");
2017 throw std::runtime_error(oss.str());
2020 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2021 if( !group )
2022 throw std::runtime_error(string("GetConfiguration(): ") + _C("Group not found: ") + group_name);
2024 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2025 if( !member ) {
2026 ostringstream oss;
2027 oss << "GetConfiguration(): " << _C("Member not found: ") << member_id;
2028 throw std::runtime_error(oss.str());
2031 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2032 if( !plugin )
2033 throw std::runtime_error(string("GetConfiguration(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2036 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2037 if( !config )
2038 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2040 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2041 // functions, and then load that from the file again, and
2042 // return that string as the configuratin.
2044 TempDir tempdir("opensyncapi");
2046 string filename = tempdir.GetNewFilename();
2048 if( !m_priv->osync_plugin_config_file_save(config, filename.c_str(), m_priv->error) )
2049 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2051 ifstream in(filename.c_str());
2052 string config_data;
2053 char buf[4096];
2054 while( in ) {
2055 in.read(buf, sizeof(buf));
2056 config_data.append(buf, in.gcount());
2059 return config_data;
2062 OS40PluginConfig OpenSync40::GetConfigurationObj(const std::string &group_name,
2063 long member_id)
2065 if( !IsConfigurable(group_name, member_id) ) {
2066 ostringstream oss;
2067 oss << "GetConfigurationObj(): " << _C("Member ") << member_id << _C(" of group '") << group_name << _C("' does not accept configuration.");
2068 throw std::runtime_error(oss.str());
2071 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2072 if( !group )
2073 throw std::runtime_error(string("GetConfigurationObj(): ") + _C("Group not found: ") + group_name);
2075 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2076 if( !member ) {
2077 ostringstream oss;
2078 oss << "GetConfigurationObj(): " << _C("Member not found: ") << member_id;
2079 throw std::runtime_error(oss.str());
2082 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2083 if( !plugin )
2084 throw std::runtime_error(string("GetConfigurationObj(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2087 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2088 if( !config )
2089 throw std::runtime_error("GetConfigurationObj(): " + m_priv->error.GetErrorMsg());
2091 return OS40PluginConfig(m_priv, member, config);
2094 void OpenSync40::SetConfiguration(const std::string &group_name,
2095 long member_id,
2096 const std::string &config_data)
2098 if( !IsConfigurable(group_name, member_id) ) {
2099 ostringstream oss;
2100 oss << "SetConfiguration(): " << _C("Member ") << member_id << _C(" of group '") << group_name << _C("' does not accept configuration.");
2101 throw std::runtime_error(oss.str());
2104 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2105 if( !group )
2106 throw std::runtime_error(string("SetConfiguration(): ") + _C("Group not found: ") + group_name);
2108 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2109 if( !member ) {
2110 ostringstream oss;
2111 oss << "SetConfiguration(): " << _C("Member not found: ") << member_id;
2112 throw std::runtime_error(oss.str());
2115 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2116 if( !plugin )
2117 throw std::runtime_error(string("SetConfiguration(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2120 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2121 // functions, and then load that from the file again, and
2122 // return that string as the configuratin.
2124 TempDir tempdir("opensyncapi");
2126 string filename = tempdir.GetNewFilename();
2128 // write config data to file
2130 ofstream out(filename.c_str());
2131 out << config_data;
2134 // load brand new config from file
2135 // if a new config object isn't created here, the loaded config
2136 // will be added to the existing config
2137 OSyncPluginConfig *new_config = m_priv->osync_plugin_config_new(m_priv->error);
2138 if( !m_priv->osync_plugin_config_file_load(new_config, filename.c_str(), m_priv->error) )
2139 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2141 m_priv->osync_member_set_config(member, new_config);
2143 if( !m_priv->osync_member_save(member, m_priv->error))
2144 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2147 void OpenSync40::Discover(const std::string &group_name)
2149 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2150 if( !group )
2151 throw std::runtime_error(string("Discover(): ") + _C("Group not found: ") + group_name);
2153 EngineHandle engine(m_priv->osync_engine_unref);
2154 engine = m_priv->osync_engine_new(group, m_priv->error);
2155 if( !engine.get() )
2156 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2158 SyncListHandle members(m_priv->osync_list_free);
2159 members = m_priv->osync_group_get_members(group);
2160 OSyncList *m = NULL;
2161 for( m = members.get(); m; m = m->next ) {
2162 OSyncMember *member = (OSyncMember *) m->data;
2164 /* Discover the objtypes for the members */
2165 if( !m_priv->osync_engine_discover_and_block(engine.get(), member, m_priv->error))
2166 break;
2168 SyncListHandle objtypes(m_priv->osync_list_free);
2169 objtypes = m_priv->osync_member_get_objtypes(member);
2170 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2171 m_priv->osync_error_set(m_priv->error, OSYNC_ERROR_GENERIC, _C("discover failed: no objtypes returned"));
2172 break;
2175 if( !m_priv->osync_member_save(member, m_priv->error) )
2176 break;
2179 // check for error
2180 if( m ) {
2181 m_priv->osync_engine_finalize(engine.get(), m_priv->error);
2182 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2186 void OpenSync40::Sync(const std::string &group_name,
2187 SyncStatus &status_callback,
2188 Config::pst_type sync_types)
2190 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2191 if( !group )
2192 throw std::runtime_error(string("Sync(): ") + _C("Group not found: ") + group_name);
2194 // enable/disable each objtype, as per sync_types
2195 if( !(sync_types & PST_DO_NOT_SET) ) {
2196 cerr << "enabling objtypes: " << sync_types << endl;
2197 m_priv->osync_group_set_objtype_enabled(group, "contact",
2198 (sync_types & PST_CONTACTS) ? TRUE : FALSE);
2199 m_priv->osync_group_set_objtype_enabled(group, "event",
2200 (sync_types & PST_EVENTS) ? TRUE : FALSE);
2201 m_priv->osync_group_set_objtype_enabled(group, "note",
2202 (sync_types & PST_NOTES) ? TRUE : FALSE);
2203 m_priv->osync_group_set_objtype_enabled(group, "todo",
2204 (sync_types & PST_TODOS) ? TRUE : FALSE);
2207 EngineHandle engine(m_priv->osync_engine_unref);
2208 engine = m_priv->osync_engine_new(group, m_priv->error);
2209 if( !engine.get() )
2210 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2213 CallbackBundle cbdata(m_priv, status_callback);
2215 m_priv->osync_engine_set_conflict_callback(engine.get(), conflict_handler, &cbdata);
2216 m_priv->osync_engine_set_changestatus_callback(engine.get(), entry_status, &cbdata);
2217 m_priv->osync_engine_set_mappingstatus_callback(engine.get(), mapping_status, &cbdata);
2218 m_priv->osync_engine_set_enginestatus_callback(engine.get(), engine_status, &cbdata);
2219 m_priv->osync_engine_set_memberstatus_callback(engine.get(), member_status, &cbdata);
2220 m_priv->osync_engine_set_multiply_callback(engine.get(), multiply_summary, &cbdata);
2223 SyncListHandle members(m_priv->osync_list_free);
2224 members = m_priv->osync_group_get_members(group);
2225 OSyncList *m = NULL;
2226 for( m = members.get(); m; m = m->next ) {
2227 OSyncMember *member = (OSyncMember *) m->data;
2229 SyncListHandle objtypes(m_priv->osync_list_free);
2230 objtypes = m_priv->osync_member_get_objtypes(member);
2231 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2232 cout << "Sync(): " << _C("Member ") << m_priv->osync_member_get_id(member) << _C(" has no objtypes. Has it already been discovered?") << endl;
2236 if( !m_priv->osync_engine_initialize(engine.get(), m_priv->error) )
2237 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2239 if( !m_priv->osync_engine_synchronize_and_block(engine.get(), m_priv->error) ) {
2240 m_priv->osync_engine_finalize(engine.get(), NULL);
2241 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2244 if( !m_priv->osync_engine_finalize(engine.get(), m_priv->error) )
2245 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2249 /////////////////////////////////////////////////////////////////////////////
2250 // TossError public members
2252 /// Returns NULL if no error
2253 std::string TossError::GetErrorMsg()
2255 return std::string(m_priv->osync_error_print_stack_wrapper(&m_error));
2258 bool TossError::IsSet()
2260 return m_priv->osync_error_is_set(&m_error);
2263 void TossError::Clear()
2265 if( m_error ) {
2266 m_priv->osync_error_unref(&m_error);
2267 m_error = 0;
2271 } // namespace OpenSync