lib: added implicit ctor converter from DatabaseDatabase to DBListType
[barry/progweb.git] / desktop / src / os40.cc
blob033303069c6789e093c0a815e6d1ca100eb3739f
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>
42 // use relative paths to backtrack enough to specify only 0.4x includes
43 #include <../libopensync1/opensync/opensync.h>
44 #include <../libopensync1/opensync/opensync-group.h>
45 #include <../libopensync1/opensync/opensync-format.h>
46 #include <../libopensync1/opensync/opensync-plugin.h>
47 #include <../libopensync1/opensync/opensync-engine.h>
48 #include <../libopensync1/opensync/opensync-data.h>
49 #include <../libopensync1/opensync/opensync-capabilities.h>
51 using namespace std;
52 using namespace Barry;
54 namespace OpenSync {
57 typedef Barry::vLateSmartPtr<OSyncEngine, void(*)(OSyncEngine*)> EngineHandle;
58 typedef Barry::vLateSmartPtr<OSyncList, void(*)(OSyncList*)> SyncListHandle;
62 // Private class declarations
66 class TossError
68 OSyncError *m_error;
69 OpenSync40Private *m_priv;
71 public:
72 // simple wrapper... unref's the error on destruction
73 TossError(OpenSync40Private *priv)
74 : m_error(0)
75 , m_priv(priv)
79 ~TossError()
81 Clear();
84 /// Returns NULL if no error
85 std::string GetErrorMsg();
86 bool IsSet();
87 void Clear();
89 operator OSyncError**()
91 return &m_error;
95 class OpenSync40Private
97 public:
98 // function pointers
99 const char* (*osync_get_version)();
100 const char* (*osync_error_print)(OSyncError **error);
101 osync_bool (*osync_error_is_set)(OSyncError **error);
102 void (*osync_error_unref)(OSyncError **error);
103 OSyncGroupEnv* (*osync_group_env_new)(OSyncError **error);
104 OSyncFormatEnv* (*osync_format_env_new)(OSyncError **error);
105 OSyncPluginEnv* (*osync_plugin_env_new)(OSyncError **error);
106 void (*osync_group_env_unref)(OSyncGroupEnv *env);
107 void (*osync_format_env_unref)(OSyncFormatEnv *env);
108 void (*osync_plugin_env_unref)(OSyncPluginEnv *env);
109 osync_bool (*osync_plugin_env_load)(OSyncPluginEnv *env,
110 const char *path, OSyncError **error);
111 OSyncList* (*osync_plugin_env_get_plugins)(
112 OSyncPluginEnv *env);
113 const char* (*osync_plugin_get_name)(OSyncPlugin *plugin);
114 void (*osync_list_free)(OSyncList *list);
115 osync_bool (*osync_group_env_load_groups)(
116 OSyncGroupEnv *env, const char *path,
117 OSyncError **error);
118 osync_bool (*osync_format_env_load_plugins)(
119 OSyncFormatEnv *env, const char *path,
120 OSyncError **error);
121 OSyncList* (*osync_group_env_get_groups)(
122 OSyncGroupEnv *env);
123 const char* (*osync_group_get_name)(OSyncGroup *group);
124 OSyncGroup* (*osync_group_env_find_group)(
125 OSyncGroupEnv *env, const char *name);
126 OSyncList* (*osync_group_get_members)(OSyncGroup *group);
127 const char* (*osync_member_get_name)(OSyncMember *member);
128 osync_memberid (*osync_member_get_id)(OSyncMember *member);
129 const char* (*osync_member_get_pluginname)(
130 OSyncMember *member);
131 OSyncList* (*osync_format_env_get_objformats)(
132 OSyncFormatEnv *env);
133 const char* (*osync_objformat_get_name)(
134 OSyncObjFormat *format);
135 const char* (*osync_objformat_get_objtype)(
136 OSyncObjFormat *format);
137 OSyncGroup* (*osync_group_new)(OSyncError **error);
138 void (*osync_group_unref)(OSyncGroup *group);
139 void (*osync_group_set_name)(OSyncGroup *group,
140 const char *name);
141 osync_bool (*osync_group_env_add_group)(OSyncGroupEnv *env,
142 OSyncGroup *group,
143 OSyncError **error);
144 osync_bool (*osync_group_save)(OSyncGroup *group,
145 OSyncError **error);
146 osync_bool (*osync_group_delete)(OSyncGroup *group,
147 OSyncError **error);
148 void (*osync_group_env_remove_group)(
149 OSyncGroupEnv *env, OSyncGroup *group);
150 OSyncPlugin* (*osync_plugin_env_find_plugin)(
151 OSyncPluginEnv *env, const char *name);
152 void (*osync_member_unref)(OSyncMember *member);
153 OSyncMember* (*osync_member_new)(OSyncError **error);
154 void (*osync_group_add_member)(OSyncGroup *group,
155 OSyncMember *member);
156 void (*osync_member_set_pluginname)(
157 OSyncMember *member,
158 const char *pluginname);
159 void (*osync_member_set_name)(OSyncMember *member,
160 const char *name);
161 osync_bool (*osync_member_save)(OSyncMember *member,
162 OSyncError **error);
163 OSyncMember* (*osync_group_find_member)(OSyncGroup *group,
164 osync_memberid id);
165 osync_bool (*osync_member_delete)(OSyncMember *member,
166 OSyncError **error);
167 void (*osync_group_remove_member)(OSyncGroup *group,
168 OSyncMember *member);
169 OSyncPluginConfig* (*osync_plugin_config_new)(OSyncError **error);
170 osync_bool (*osync_plugin_config_file_load)(
171 OSyncPluginConfig *config,
172 const char *path,
173 OSyncError **error);
174 void (*osync_member_set_config)(OSyncMember *member,
175 OSyncPluginConfig *config);
176 OSyncPluginConfig* (*osync_member_get_config_or_default)(
177 OSyncMember *member,
178 OSyncError **error);
179 osync_bool (*osync_plugin_config_file_save)(
180 OSyncPluginConfig *config,
181 const char *path, OSyncError **error);
182 OSyncPluginConfigurationType (*osync_plugin_get_config_type)(
183 OSyncPlugin *plugin);
184 OSyncEngine* (*osync_engine_new)(OSyncGroup *group,
185 OSyncError **error);
186 void (*osync_engine_unref)(OSyncEngine *engine);
187 osync_bool (*osync_engine_discover_and_block)(
188 OSyncEngine *engine,
189 OSyncMember *member,
190 OSyncError **error);
191 OSyncList* (*osync_member_get_objtypes)(
192 OSyncMember *member);
193 unsigned int (*osync_list_length)(const OSyncList *list);
194 void (*osync_error_set)(OSyncError **error,
195 OSyncErrorType type,
196 const char *format, ...);
197 osync_bool (*osync_engine_finalize)(OSyncEngine *engine,
198 OSyncError **error);
199 OSyncList* (*osync_mapping_engine_get_changes)(
200 OSyncMappingEngine *engine);
201 osync_bool (*osync_mapping_engine_supports_ignore)(
202 OSyncMappingEngine *engine);
203 osync_bool (*osync_mapping_engine_supports_use_latest)(
204 OSyncMappingEngine *engine);
205 OSyncList* (*osync_list_nth)(OSyncList *list,
206 unsigned int n);
207 osync_bool (*osync_engine_mapping_solve)(
208 OSyncEngine *engine,
209 OSyncMappingEngine *mapping_engine,
210 OSyncChange *change,
211 OSyncError **error);
212 osync_bool (*osync_engine_abort)(OSyncEngine *engine,
213 OSyncError **error);
214 osync_bool (*osync_engine_mapping_duplicate)(
215 OSyncEngine *engine,
216 OSyncMappingEngine *mapping_engine,
217 OSyncError **error);
218 osync_bool (*osync_engine_mapping_ignore_conflict)(
219 OSyncEngine *engine,
220 OSyncMappingEngine *mapping_engine,
221 OSyncError **error);
222 osync_bool (*osync_engine_mapping_use_latest)(
223 OSyncEngine *engine,
224 OSyncMappingEngine *mapping_engine,
225 OSyncError **error);
226 OSyncChangeType (*osync_change_get_changetype)(
227 OSyncChange *change);
228 OSyncMember* (*osync_mapping_engine_change_find_member)(
229 OSyncMappingEngine *engine,
230 OSyncChange *change);
231 OSyncData* (*osync_change_get_data)(OSyncChange *change);
232 char* (*osync_data_get_printable)(OSyncData *data,
233 OSyncError **error);
234 void (*osync_free)(void *ptr);
235 const char* (*osync_change_get_uid)(OSyncChange *change);
236 osync_bool (*osync_engine_continue)(OSyncEngine *engine,
237 OSyncError **error);
238 OSyncList* (*osync_engine_get_objengines)(
239 OSyncEngine *engine);
240 OSyncList* (*osync_obj_engine_get_members)(
241 OSyncObjEngine* engine);
242 const char* (*osync_obj_engine_get_objtype)(
243 OSyncObjEngine *engine);
244 const OSyncList* (*osync_obj_engine_get_mapping_entry_engines_of_member)(
245 OSyncObjEngine *engine,
246 OSyncMember *member);
247 osync_bool (*osync_entry_engine_is_dirty)(
248 OSyncMappingEntryEngine *engine);
249 OSyncChangeType (*osync_entry_engine_get_changetype)(
250 OSyncMappingEntryEngine *engine);
251 OSyncChange* (*osync_engine_change_update_get_change)(
252 OSyncEngineChangeUpdate *update);
253 OSyncMember* (*osync_engine_change_update_get_member)(
254 OSyncEngineChangeUpdate *update);
255 OSyncError* (*osync_engine_change_update_get_error)(
256 OSyncEngineChangeUpdate *update);
257 OSyncEngineChangeEvent (*osync_engine_change_update_get_event)(
258 OSyncEngineChangeUpdate *update);
259 OSyncObjFormat* (*osync_change_get_objformat)(
260 OSyncChange *change);
261 OSyncError* (*osync_engine_mapping_update_get_error)(
262 OSyncEngineMappingUpdate *update);
263 OSyncError* (*osync_engine_update_get_error)(
264 OSyncEngineUpdate *update);
265 OSyncEngineEvent (*osync_engine_update_get_event)(
266 OSyncEngineUpdate *update);
267 const char* (*osync_engine_member_update_get_objtype)(
268 OSyncEngineMemberUpdate *update);
269 OSyncMember* (*osync_engine_member_update_get_member)(
270 OSyncEngineMemberUpdate *update);
271 OSyncError* (*osync_engine_member_update_get_error)(
272 OSyncEngineMemberUpdate *update);
273 OSyncEngineMemberEvent (*osync_engine_member_update_get_event)(
274 OSyncEngineMemberUpdate *update);
275 void (*osync_engine_set_conflict_callback)(
276 OSyncEngine *engine,
277 osync_conflict_cb callback,
278 void *user_data);
279 void (*osync_engine_set_changestatus_callback)(
280 OSyncEngine *engine,
281 osync_status_change_cb callback,
282 void *user_data);
283 void (*osync_engine_set_mappingstatus_callback)(
284 OSyncEngine *engine,
285 osync_status_mapping_cb callback,
286 void *user_data);
287 void (*osync_engine_set_enginestatus_callback)(
288 OSyncEngine *engine,
289 osync_status_engine_cb callback,
290 void *user_data);
291 void (*osync_engine_set_memberstatus_callback)(
292 OSyncEngine *engine,
293 osync_status_member_cb callback,
294 void *user_data);
295 void (*osync_engine_set_multiply_callback)(
296 OSyncEngine *engine,
297 osync_multiply_cb callback,
298 void *user_data);
299 osync_bool (*osync_engine_initialize)(OSyncEngine *engine,
300 OSyncError **error);
301 osync_bool (*osync_engine_synchronize_and_block)(
302 OSyncEngine *engine,OSyncError **error);
303 OSyncEngineMappingEvent (*osync_engine_mapping_update_get_event)(
304 OSyncEngineMappingUpdate *update);
305 void (*osync_plugin_resource_unref)(
306 OSyncPluginResource *resource);
307 void (*osync_plugin_config_add_resource)(
308 OSyncPluginConfig *config,
309 OSyncPluginResource *resource);
310 osync_bool (*osync_plugin_resource_is_enabled)(
311 OSyncPluginResource *resource);
312 void (*osync_plugin_resource_enable)(
313 OSyncPluginResource *resource,
314 osync_bool enable);
315 OSyncList* (*osync_plugin_resource_get_objformat_sinks)(
316 OSyncPluginResource *resource);
317 const char* (*osync_objformat_sink_get_objformat)(
318 OSyncObjFormatSink *sink);
319 const char* (*osync_objformat_sink_get_config)(
320 OSyncObjFormatSink *sink);
321 void (*osync_objformat_sink_set_config)(
322 OSyncObjFormatSink *sink,
323 const char *config);
324 OSyncObjFormatSink* (*osync_objformat_sink_new)(
325 const char *objformat,
326 OSyncError **error);
327 void (*osync_plugin_resource_add_objformat_sink)(
328 OSyncPluginResource *resource,
329 OSyncObjFormatSink *formatsink);
330 void (*osync_objformat_sink_unref)(
331 OSyncObjFormatSink *sink);
332 const char* (*osync_plugin_resource_get_preferred_format)(
333 OSyncPluginResource *resource);
334 void (*osync_plugin_resource_set_preferred_format)(
335 OSyncPluginResource *resource,
336 const char *preferred_format);
337 const char* (*osync_plugin_resource_get_mime)(
338 OSyncPluginResource *resource);
339 void (*osync_plugin_resource_set_mime)(
340 OSyncPluginResource *resource,
341 const char *mime);
342 const char* (*osync_plugin_resource_get_objtype)(
343 OSyncPluginResource *resource);
344 void (*osync_plugin_resource_set_objtype)(
345 OSyncPluginResource *resource,
346 const char *objtype);
347 const char* (*osync_plugin_resource_get_path)(
348 OSyncPluginResource *resource);
349 void (*osync_plugin_resource_set_path)(
350 OSyncPluginResource *resource,
351 const char *path);
352 const char* (*osync_plugin_resource_get_url)(
353 OSyncPluginResource *resource);
354 void (*osync_plugin_resource_set_url)(
355 OSyncPluginResource *resource,
356 const char *url);
357 const char* (*osync_plugin_config_get_advancedoption_value_by_name)(
358 OSyncPluginConfig *config,
359 const char *name);
360 OSyncList* (*osync_plugin_config_get_advancedoptions)(
361 OSyncPluginConfig *config);
362 void (*osync_plugin_config_add_advancedoption)(
363 OSyncPluginConfig *config,
364 OSyncPluginAdvancedOption *option);
365 OSyncPluginAdvancedOption* (*osync_plugin_advancedoption_new)(
366 OSyncError **error);
367 void (*osync_plugin_advancedoption_unref)(
368 OSyncPluginAdvancedOption *option);
369 const char* (*osync_plugin_advancedoption_get_name)(
370 OSyncPluginAdvancedOption *option);
371 void (*osync_plugin_advancedoption_set_name)(
372 OSyncPluginAdvancedOption *option,
373 const char *name);
374 void (*osync_plugin_advancedoption_set_displayname)(
375 OSyncPluginAdvancedOption *option,
376 const char *displayname);
377 void (*osync_plugin_advancedoption_set_type)(
378 OSyncPluginAdvancedOption *option,
379 OSyncPluginAdvancedOptionType type);
380 void (*osync_plugin_advancedoption_set_value)(
381 OSyncPluginAdvancedOption *option,
382 const char *value);
383 OSyncList* (*osync_plugin_config_get_resources)(
384 OSyncPluginConfig *config);
385 OSyncPluginResource* (*osync_plugin_resource_ref)(
386 OSyncPluginResource *resource);
387 OSyncPluginResource* (*osync_plugin_resource_new)(
388 OSyncError **error);
389 const char* (*osync_plugin_resource_get_name)(
390 OSyncPluginResource *resource);
391 void (*osync_plugin_resource_set_name)(
392 OSyncPluginResource *resource,
393 const char *name);
394 OSyncPluginAuthentication* (*osync_plugin_config_get_authentication)(
395 OSyncPluginConfig *config);
396 const char* (*osync_plugin_authentication_get_password)(
397 OSyncPluginAuthentication *auth);
398 OSyncPluginAuthentication* (*osync_plugin_authentication_new)(
399 OSyncError **error);
400 osync_bool (*osync_plugin_authentication_option_is_supported)(
401 OSyncPluginAuthentication *auth,
402 OSyncPluginAuthenticationOptionSupportedFlag flag);
403 void (*osync_plugin_authentication_unref)(
404 OSyncPluginAuthentication *auth);
405 void (*osync_plugin_config_set_authentication)(
406 OSyncPluginConfig *config,
407 OSyncPluginAuthentication *auth);
408 void (*osync_plugin_authentication_set_password)(
409 OSyncPluginAuthentication *auth,
410 const char *password);
411 const char* (*osync_plugin_authentication_get_username)(
412 OSyncPluginAuthentication *auth);
413 void (*osync_plugin_authentication_set_username)(
414 OSyncPluginAuthentication *auth,
415 const char *password);
416 void (*osync_group_set_objtype_enabled)(
417 OSyncGroup *group, const char *objtype,
418 osync_bool enabled);
420 // data pointers
421 vLateSmartPtr<OSyncGroupEnv, void(*)(OSyncGroupEnv*)> group_env;
422 vLateSmartPtr<OSyncFormatEnv, void(*)(OSyncFormatEnv*)> format_env;
423 vLateSmartPtr<OSyncPluginEnv, void(*)(OSyncPluginEnv*)> plugin_env;
425 TossError error;
426 Converter40 converter;
428 OpenSync40Private(OpenSync40 &api)
429 : error(this)
430 , converter(api)
435 class SyncConflict40Private : public SyncConflictPrivateBase
437 OpenSync40Private *m_priv;
438 OSyncEngine *m_engine;
439 OSyncMappingEngine *m_mapping;
440 OSyncList *m_changes;
442 public:
443 SyncConflict40Private(OpenSync40Private *priv,
444 OSyncEngine *engine, OSyncMappingEngine *mapping);
445 ~SyncConflict40Private();
447 virtual bool IsAbortSupported() const;
448 virtual bool IsIgnoreSupported() const;
449 virtual bool IsKeepNewerSupported() const;
451 virtual void Select(int change_id); // takes the id of SyncChange
452 virtual void Abort();
453 virtual void Duplicate();
454 virtual void Ignore();
455 virtual void KeepNewer();
457 void AppendChanges(std::vector<SyncChange> &list);
460 class SyncSummary40Private : public SyncSummaryPrivateBase
462 OpenSync40Private *m_priv;
463 OSyncEngine *m_engine;
465 public:
466 SyncSummary40Private(OpenSync40Private *priv, OSyncEngine *engine);
467 ~SyncSummary40Private();
469 virtual void Abort();
470 virtual void Continue();
472 // returns true if any member is dirty
473 bool AppendMembers(std::vector<SyncMemberSummary> &list);
476 class OS40PluginConfigPrivate
478 public:
479 OSyncMember *m_member;
480 OSyncPluginConfig *m_config;
482 OS40PluginConfigPrivate()
483 : m_member(0)
484 , m_config(0)
489 class OS40ConfigResourcePrivate
491 public:
492 OpenSync40Private *m_privapi;
493 OS40PluginConfigPrivate *m_parentpriv;
494 OSyncPluginResource *m_resource;
496 OS40ConfigResourcePrivate()
497 : m_privapi(0)
498 , m_parentpriv(0)
499 , m_resource(0)
504 struct CallbackBundle
506 OpenSync40Private *m_priv;
507 SyncStatus *m_status;
509 CallbackBundle(OpenSync40Private *priv, SyncStatus &status)
510 : m_priv(priv)
511 , m_status(&status)
516 void conflict_handler(OSyncEngine *, OSyncMappingEngine *, void *);
517 void entry_status(OSyncEngineChangeUpdate *, void *);
518 void mapping_status(OSyncEngineMappingUpdate *, void *);
519 void engine_status(OSyncEngineUpdate *, void *);
520 void member_status(OSyncEngineMemberUpdate *, void *);
521 void multiply_summary(OSyncEngine *, void *);
524 /////////////////////////////////////////////////////////////////////////////
525 // Static helper functions
527 static const char *OSyncChangeType2String(OSyncChangeType type)
529 switch (type) {
530 case OSYNC_CHANGE_TYPE_ADDED: return "ADDED";
531 case OSYNC_CHANGE_TYPE_UNMODIFIED: return "UNMODIFIED";
532 case OSYNC_CHANGE_TYPE_DELETED: return "DELETED";
533 case OSYNC_CHANGE_TYPE_MODIFIED: return "MODIFIED";
534 default:
535 case OSYNC_CHANGE_TYPE_UNKNOWN: return "?";
540 /////////////////////////////////////////////////////////////////////////////
541 // SyncConflict40Private member functions
543 SyncConflict40Private::SyncConflict40Private(OpenSync40Private *priv,
544 OSyncEngine *engine, OSyncMappingEngine *mapping)
545 : m_priv(priv)
546 , m_engine(engine)
547 , m_mapping(mapping)
548 , m_changes(0)
550 m_changes = m_priv->osync_mapping_engine_get_changes(m_mapping);
553 SyncConflict40Private::~SyncConflict40Private()
555 m_priv->osync_list_free(m_changes);
558 bool SyncConflict40Private::IsAbortSupported() const
560 return true;
563 bool SyncConflict40Private::IsIgnoreSupported() const
565 return m_priv->osync_mapping_engine_supports_ignore(m_mapping);
568 bool SyncConflict40Private::IsKeepNewerSupported() const
570 return m_priv->osync_mapping_engine_supports_use_latest(m_mapping);
573 void SyncConflict40Private::Select(int change_id)
575 OSyncList *c = m_priv->osync_list_nth(m_changes, change_id);
576 if( !c )
577 throw std::logic_error("Bad change_id");
579 OSyncChange *change = (OSyncChange *) c->data;
581 if( !m_priv->osync_engine_mapping_solve(m_engine, m_mapping,
582 change, m_priv->error) )
584 throw std::runtime_error(m_priv->error.GetErrorMsg());
588 void SyncConflict40Private::Abort()
590 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) ) {
591 ostringstream oss;
592 oss << "Problems while aborting: "
593 << m_priv->error.GetErrorMsg();
594 throw std::runtime_error(oss.str());
598 void SyncConflict40Private::Duplicate()
600 if( !m_priv->osync_engine_mapping_duplicate(m_engine, m_mapping, m_priv->error) )
601 throw std::runtime_error(m_priv->error.GetErrorMsg());
604 void SyncConflict40Private::Ignore()
606 if( !IsIgnoreSupported() )
607 throw std::logic_error("Ignore not supported, yet Ignore() called.");
609 if( !m_priv->osync_engine_mapping_ignore_conflict(m_engine, m_mapping,
610 m_priv->error) )
612 throw std::runtime_error(m_priv->error.GetErrorMsg());
616 void SyncConflict40Private::KeepNewer()
618 if( !IsKeepNewerSupported() )
619 throw std::logic_error("Keep Newer not supported, yet KeepNewer() called.");
621 if( !m_priv->osync_engine_mapping_use_latest(m_engine, m_mapping, m_priv->error) )
622 throw std::runtime_error(m_priv->error.GetErrorMsg());
625 void SyncConflict40Private::AppendChanges(std::vector<SyncChange> &list)
627 int i = 0;
628 for( OSyncList *c = m_changes; c; c = c->next, i++ ) {
629 OSyncChange *change = (OSyncChange *) c->data;
631 if( m_priv->osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_UNKNOWN ) {
632 OSyncMember *member = m_priv->osync_mapping_engine_change_find_member(m_mapping, change);
634 OSyncData *data = m_priv->osync_change_get_data(change);
636 SyncChange entry;
638 char *printable = m_priv->osync_data_get_printable(data, m_priv->error);
639 if( printable )
640 entry.printable_data = printable;
641 m_priv->osync_free(printable);
643 if( m_priv->error.IsSet() )
644 throw std::runtime_error(m_priv->error.GetErrorMsg());
646 entry.id = i;
647 entry.member_id = m_priv->osync_member_get_id(member);
648 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
649 entry.uid = m_priv->osync_change_get_uid(change);
651 // add to list
652 list.push_back(entry);
658 /////////////////////////////////////////////////////////////////////////////
659 // SyncSummary40Private member functions
661 SyncSummary40Private::SyncSummary40Private(OpenSync40Private *priv,
662 OSyncEngine *engine)
663 : m_priv(priv)
664 , m_engine(engine)
668 SyncSummary40Private::~SyncSummary40Private()
672 void SyncSummary40Private::Abort()
674 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) )
675 throw std::runtime_error(m_priv->error.GetErrorMsg());
678 void SyncSummary40Private::Continue()
680 if( !m_priv->osync_engine_continue(m_engine, m_priv->error) )
681 throw std::runtime_error(m_priv->error.GetErrorMsg());
684 bool SyncSummary40Private::AppendMembers(std::vector<SyncMemberSummary> &list)
686 SyncListHandle objengines(m_priv->osync_list_free);
687 objengines = m_priv->osync_engine_get_objengines(m_engine);
689 int i = 0;
690 bool dirty = false;
692 for( OSyncList *o = objengines.get(); o; o = o->next ) {
693 OSyncObjEngine *objengine = (OSyncObjEngine *) o->data;
699 SyncListHandle members(m_priv->osync_list_free);
700 members = m_priv->osync_obj_engine_get_members(objengine);
701 for( OSyncList *m = members.get(); m; m = m->next ) {
702 OSyncMember *member = (OSyncMember *) m->data;
704 // Fill in common summary data
705 SyncMemberSummary entry;
706 entry.id = i;
707 entry.objtype_name = m_priv->osync_obj_engine_get_objtype(objengine);
708 entry.member_id = m_priv->osync_member_get_id(member);
709 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
711 const OSyncList *mapping_entry_engines = m_priv->osync_obj_engine_get_mapping_entry_engines_of_member(objengine, member);
713 // Calculate summary counts
714 for( const OSyncList *e = mapping_entry_engines; e; e = e->next ) {
715 OSyncMappingEntryEngine *entry_engine = (OSyncMappingEntryEngine*) e->data;
717 if( !m_priv->osync_entry_engine_is_dirty(entry_engine) )
718 continue;
720 dirty = true;
722 OSyncChangeType type = m_priv->osync_entry_engine_get_changetype(entry_engine);
723 switch (type)
725 case OSYNC_CHANGE_TYPE_ADDED:
726 entry.added++;
727 break;
728 case OSYNC_CHANGE_TYPE_MODIFIED:
729 entry.modified++;
730 break;
731 case OSYNC_CHANGE_TYPE_DELETED:
732 entry.deleted++;
733 break;
734 default:
735 break;
739 // Add entry to list
740 list.push_back(entry);
745 return dirty;
749 /////////////////////////////////////////////////////////////////////////////
750 // Callback functions
752 void conflict_handler(OSyncEngine *engine, OSyncMappingEngine *mapping,
753 void *cbdata)
755 CallbackBundle *cb = (CallbackBundle*) cbdata;
757 try {
758 // build the SyncConflict object
759 SyncConflict40Private scp(cb->m_priv, engine, mapping);
760 SyncConflict conflict(scp);
762 // append all conflicting changes as vector objects in the same
763 // order as the opensync library mapping
764 scp.AppendChanges(conflict);
766 // call the status handler
767 cb->m_status->HandleConflict(conflict);
769 catch( std::exception &e ) {
770 cb->m_status->ReportError(
771 string("Conflict not resolved. ") + e.what());
773 catch( ... ) {
774 cb->m_status->ReportError(
775 "Unknown exception caught in conflict_handler()");
779 void entry_status(OSyncEngineChangeUpdate *status, void *cbdata)
781 CallbackBundle *cb = (CallbackBundle*) cbdata;
783 try {
784 ostringstream oss;
786 OSyncChange *change = cb->m_priv->osync_engine_change_update_get_change(status);
787 OSyncMember *member = cb->m_priv->osync_engine_change_update_get_member(status);
788 OSyncError *error = cb->m_priv->osync_engine_change_update_get_error(status);
790 const char *action = NULL;
791 const char *direction = NULL;
792 const char *msg = NULL;
793 bool error_event = false;
795 switch( cb->m_priv->osync_engine_change_update_get_event(status) )
797 case OSYNC_ENGINE_CHANGE_EVENT_READ:
798 action = "Received an entry";
799 direction = "from";
800 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
801 break;
803 case OSYNC_ENGINE_CHANGE_EVENT_WRITTEN:
804 action = "Sent an entry";
805 direction = "to";
806 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
807 break;
809 case OSYNC_ENGINE_CHANGE_EVENT_ERROR:
810 error_event = true;
811 action = "Error for entry";
812 direction = "and";
813 msg = cb->m_priv->osync_error_print(&(error));
814 break;
817 if( action ) {
818 oss << action << " "
819 << cb->m_priv->osync_change_get_uid(change)
820 << "("
821 << cb->m_priv->osync_objformat_get_name( cb->m_priv->osync_change_get_objformat(change))
822 << ") " << direction << " member "
823 << cb->m_priv->osync_member_get_id(member)
824 << " ("
825 << cb->m_priv->osync_member_get_pluginname(member)
826 << "): "
827 << msg;
829 // call the status handler
830 cb->m_status->EntryStatus(oss.str(), error_event);
833 catch( std::exception &e ) {
834 cb->m_status->ReportError(
835 string("entry_status error:") + e.what());
837 catch( ... ) {
838 cb->m_status->ReportError(
839 "Unknown exception caught in entry_status()");
843 void mapping_status(OSyncEngineMappingUpdate *status, void *cbdata)
845 CallbackBundle *cb = (CallbackBundle*) cbdata;
847 try {
848 OSyncError *error = cb->m_priv->osync_engine_mapping_update_get_error(status);
850 ostringstream oss;
851 bool error_event = false;
853 switch( cb->m_priv->osync_engine_mapping_update_get_event(status) )
855 case OSYNC_ENGINE_MAPPING_EVENT_SOLVED:
856 oss << "Mapping solved";
857 break;
859 case OSYNC_ENGINE_MAPPING_EVENT_ERROR:
860 error_event = true;
861 oss << "Mapping error: "
862 << cb->m_priv->osync_error_print(&(error));
863 break;
866 // call the status handler
867 if( oss.str().size() )
868 cb->m_status->MappingStatus(oss.str(), error_event);
870 catch( std::exception &e ) {
871 cb->m_status->ReportError(
872 string("mapping_status error: ") + e.what());
874 catch( ... ) {
875 cb->m_status->ReportError(
876 "Unknown exception caught in mapping_status()");
880 void engine_status(OSyncEngineUpdate *status, void *cbdata)
882 CallbackBundle *cb = (CallbackBundle*) cbdata;
884 try {
885 OSyncError *error = cb->m_priv->osync_engine_update_get_error(status);
887 ostringstream oss;
888 bool error_event = false;
889 bool slow_sync = false;
891 switch( cb->m_priv->osync_engine_update_get_event(status) )
893 case OSYNC_ENGINE_EVENT_CONNECTED:
894 oss << "All clients connected or error";
895 break;
896 case OSYNC_ENGINE_EVENT_CONNECT_DONE:
897 /* Not of interest for regular user. */
898 break;
899 case OSYNC_ENGINE_EVENT_READ:
900 oss << "All clients sent changes or error";
901 break;
902 case OSYNC_ENGINE_EVENT_MAPPED:
903 oss << "All changes got mapped";
904 break;
905 case OSYNC_ENGINE_EVENT_MULTIPLIED:
906 oss << "All changes got multiplied";
907 break;
908 case OSYNC_ENGINE_EVENT_PREPARED_WRITE:
909 oss << "All changes got prepared for write";
910 break;
911 case OSYNC_ENGINE_EVENT_PREPARED_MAP:
912 /* Not of interest for regular user. */
913 break;
914 case OSYNC_ENGINE_EVENT_WRITTEN:
915 oss << "All clients have written";
916 break;
917 case OSYNC_ENGINE_EVENT_DISCONNECTED:
918 oss << "All clients have disconnected";
919 break;
920 case OSYNC_ENGINE_EVENT_ERROR:
921 error_event = true;
922 oss << "The sync failed: " << cb->m_priv->osync_error_print(&(error));
923 break;
924 case OSYNC_ENGINE_EVENT_SUCCESSFUL:
925 oss << "The sync was successful";
926 break;
927 case OSYNC_ENGINE_EVENT_PREV_UNCLEAN:
928 oss << "The previous synchronization was unclean. Slow-syncing";
929 slow_sync = true;
930 break;
931 case OSYNC_ENGINE_EVENT_END_CONFLICTS:
932 oss << "All conflicts have been reported";
933 break;
934 case OSYNC_ENGINE_EVENT_SYNC_DONE:
935 oss << "All clients reported sync done";
936 break;
939 // call the status handler
940 if( oss.str().size() )
941 cb->m_status->EngineStatus(oss.str(),
942 error_event,
943 slow_sync);
945 catch( std::exception &e ) {
946 cb->m_status->ReportError(
947 string("engine_status error: ") + e.what());
949 catch( ... ) {
950 cb->m_status->ReportError(
951 "Unknown exception caught in engine_status()");
955 void member_status(OSyncEngineMemberUpdate *status, void *cbdata)
957 CallbackBundle *cb = (CallbackBundle*) cbdata;
959 try {
960 ostringstream oss;
961 bool error_event = false;
962 bool valid = true;
964 const char *objtype = cb->m_priv->osync_engine_member_update_get_objtype(status);
965 if( objtype == NULL )
966 oss << "Main sink";
967 else
968 oss << objtype << " sink";
971 OSyncMember *member = cb->m_priv->osync_engine_member_update_get_member(status);
973 oss << " of member "
974 << cb->m_priv->osync_member_get_id(member)
975 << " ("
976 << cb->m_priv->osync_member_get_pluginname(member)
977 << ")";
979 OSyncError *error = cb->m_priv->osync_engine_member_update_get_error(status);
981 switch( cb->m_priv->osync_engine_member_update_get_event(status) )
983 case OSYNC_ENGINE_MEMBER_EVENT_CONNECTED:
984 oss << " just connected";
985 break;
986 case OSYNC_ENGINE_MEMBER_EVENT_CONNECT_DONE:
987 // Special event - but not interesting for
988 // the normal user.
989 break;
990 case OSYNC_ENGINE_MEMBER_EVENT_DISCONNECTED:
991 oss << " just disconnected";
992 break;
993 case OSYNC_ENGINE_MEMBER_EVENT_READ:
994 oss << " just sent all changes";
995 break;
996 case OSYNC_ENGINE_MEMBER_EVENT_WRITTEN:
997 oss << " committed all changes";
998 break;
999 case OSYNC_ENGINE_MEMBER_EVENT_SYNC_DONE:
1000 oss << " reported sync done";
1001 break;
1002 case OSYNC_ENGINE_MEMBER_EVENT_DISCOVERED:
1003 oss << " discovered its objtypes";
1004 break;
1005 case OSYNC_ENGINE_MEMBER_EVENT_ERROR:
1006 oss << " had an error: "
1007 << cb->m_priv->osync_error_print(&error);
1008 error_event = true;
1009 break;
1010 default:
1011 valid = false;
1012 break;
1015 // call the status handler
1016 if( oss.str().size() && valid ) {
1017 cb->m_status->MemberStatus(
1018 cb->m_priv->osync_member_get_id(member),
1019 cb->m_priv->osync_member_get_pluginname(member),
1020 oss.str(), error_event);
1023 catch( std::exception &e ) {
1024 cb->m_status->ReportError(
1025 string("member_status error: ") + e.what());
1027 catch( ... ) {
1028 cb->m_status->ReportError(
1029 "Unknown exception caught in member_status()");
1033 void multiply_summary(OSyncEngine *engine, void *cbdata)
1035 CallbackBundle *cb = (CallbackBundle*) cbdata;
1037 try {
1038 // build the SyncSummary object
1039 SyncSummary40Private ssp(cb->m_priv, engine);
1040 SyncSummary summary(ssp);
1042 // append a summary for each objtype member
1043 if( ssp.AppendMembers(summary) ) {
1044 // call the status handler only if dirty
1045 cb->m_status->CheckSummary(summary);
1047 else {
1048 // nothing dirty, just continue
1049 summary.Continue();
1052 catch( std::exception &e ) {
1053 cb->m_status->ReportError(
1054 string("Error handling summary. ") + e.what());
1056 catch( ... ) {
1057 cb->m_status->ReportError(
1058 "Unknown exception caught in multiply_summary()");
1063 /////////////////////////////////////////////////////////////////////////////
1064 // OS40ConfigResource - public members
1066 OS40ConfigResource::OS40ConfigResource(const OS40PluginConfig &parent,
1067 void *resource,
1068 bool existing_resource)
1069 : m_priv( new OS40ConfigResourcePrivate )
1070 , m_exists(existing_resource)
1072 m_priv->m_privapi = parent.m_privapi;
1073 m_priv->m_parentpriv = parent.m_priv.get();
1074 m_priv->m_resource = (OSyncPluginResource*) resource;
1077 OS40ConfigResource::~OS40ConfigResource()
1079 // unref the resource, since we hold a copy
1080 m_priv->m_privapi->
1081 osync_plugin_resource_unref(m_priv->m_resource);
1082 delete m_priv;
1085 bool OS40ConfigResource::IsExistingResource() const
1087 return m_exists;
1090 // safe to call multiple times
1091 void OS40ConfigResource::AddResource()
1093 if( !IsExistingResource() ) {
1094 m_priv->m_privapi->
1095 osync_plugin_config_add_resource(
1096 m_priv->m_parentpriv->m_config,
1097 m_priv->m_resource);
1101 bool OS40ConfigResource::IsEnabled() const
1103 return m_priv->m_privapi->
1104 osync_plugin_resource_is_enabled(m_priv->m_resource);
1107 OS40ConfigResource& OS40ConfigResource::Enable(bool enabled)
1109 m_priv->m_privapi->osync_plugin_resource_enable(m_priv->m_resource,
1110 enabled);
1111 return *this;
1114 bool OS40ConfigResource::FindObjFormat(const std::string &objformat,
1115 std::string &config)
1117 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1118 sinks = m_priv->m_privapi->
1119 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1120 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1121 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1122 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1123 const char *cfg = m_priv->m_privapi->osync_objformat_sink_get_config(sink);
1124 if( cfg )
1125 config = cfg;
1126 else
1127 config.clear();
1128 return true;
1131 return false;
1134 OS40ConfigResource& OS40ConfigResource::SetObjFormat(const std::string &objformat,
1135 const std::string &config)
1137 // if it already exists, just set the config value
1138 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1139 sinks = m_priv->m_privapi->
1140 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1141 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1142 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1143 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1144 m_priv->m_privapi->osync_objformat_sink_set_config(sink, config.c_str());
1145 return *this;
1149 // if we get here, it doesn't exist, and we need to add it
1150 OSyncObjFormatSink *sink = m_priv->m_privapi->
1151 osync_objformat_sink_new(objformat.c_str(),
1152 m_priv->m_privapi->error);
1153 if( !sink )
1154 throw std::runtime_error(m_priv->m_privapi->error.GetErrorMsg());
1156 if( config.size() )
1157 m_priv->m_privapi->osync_objformat_sink_set_config(sink,
1158 config.c_str());
1159 m_priv->m_privapi->osync_plugin_resource_add_objformat_sink(
1160 m_priv->m_resource, sink);
1161 m_priv->m_privapi->osync_objformat_sink_unref(sink);
1162 return *this;
1165 std::string OS40ConfigResource::GetName() const
1167 string value;
1168 const char *pv = m_priv->m_privapi->
1169 osync_plugin_resource_get_name(m_priv->m_resource);
1170 if( pv )
1171 value = pv;
1172 return value;
1175 OS40ConfigResource& OS40ConfigResource::SetName(const std::string &name)
1177 m_priv->m_privapi->
1178 osync_plugin_resource_set_name(m_priv->m_resource, name.c_str());
1179 return *this;
1182 std::string OS40ConfigResource::GetPreferredFormat() const
1184 string value;
1185 const char *pv = m_priv->m_privapi->
1186 osync_plugin_resource_get_preferred_format(m_priv->m_resource);
1187 if( pv )
1188 value = pv;
1189 return value;
1192 OS40ConfigResource& OS40ConfigResource::SetPreferredFormat(const std::string &format)
1194 m_priv->m_privapi->
1195 osync_plugin_resource_set_preferred_format(m_priv->m_resource,
1196 format.c_str());
1197 return *this;
1200 std::string OS40ConfigResource::GetMime() const
1202 string value;
1203 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_mime(
1204 m_priv->m_resource);
1205 if( pv )
1206 value = pv;
1207 return value;
1210 OS40ConfigResource& OS40ConfigResource::SetMime(const std::string &mime)
1212 m_priv->m_privapi->osync_plugin_resource_set_mime(m_priv->m_resource,
1213 mime.c_str());
1214 return *this;
1217 std::string OS40ConfigResource::GetObjType() const
1219 string value;
1220 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_objtype(
1221 m_priv->m_resource);
1222 if( pv )
1223 value = pv;
1224 return value;
1227 OS40ConfigResource& OS40ConfigResource::SetObjType(const std::string &objtype)
1229 m_priv->m_privapi->osync_plugin_resource_set_objtype(m_priv->m_resource,
1230 objtype.c_str());
1231 return *this;
1234 std::string OS40ConfigResource::GetPath() const
1236 string value;
1237 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_path(
1238 m_priv->m_resource);
1239 if( pv )
1240 value = pv;
1241 return value;
1244 OS40ConfigResource& OS40ConfigResource::SetPath(const std::string &path)
1246 m_priv->m_privapi->osync_plugin_resource_set_path(m_priv->m_resource,
1247 path.c_str());
1248 return *this;
1251 std::string OS40ConfigResource::GetUrl() const
1253 string value;
1254 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_url(
1255 m_priv->m_resource);
1256 if( pv )
1257 value = pv;
1258 return value;
1261 OS40ConfigResource& OS40ConfigResource::SetUrl(const std::string &url)
1263 m_priv->m_privapi->osync_plugin_resource_set_url(m_priv->m_resource,
1264 url.c_str());
1265 return *this;
1269 /////////////////////////////////////////////////////////////////////////////
1270 // OS40PluginConfig - public members
1272 OS40PluginConfig::OS40PluginConfig(OpenSync40Private *privapi,
1273 void *member,
1274 void *config)
1275 : m_privapi(privapi)
1277 m_priv.reset( new OS40PluginConfigPrivate );
1278 m_priv->m_member = (OSyncMember*) member;
1279 m_priv->m_config = (OSyncPluginConfig*) config;
1282 std::string OS40PluginConfig::GetAdvanced(const std::string &name)
1284 const char *value = m_privapi->osync_plugin_config_get_advancedoption_value_by_name(m_priv->m_config, name.c_str());
1285 string val;
1286 if( value )
1287 val = value;
1288 return val;
1291 void OS40PluginConfig::SetAdvanced(const std::string &name,
1292 const std::string &display_name,
1293 const std::string &val)
1295 SetAdvanced(name, display_name, STRING_TYPE, val);
1298 void OS40PluginConfig::SetAdvanced(const std::string &name,
1299 const std::string &display_name,
1300 int val_type,
1301 const std::string &val)
1303 // find the first advanced option with this name
1304 SyncListHandle aos(m_privapi->osync_list_free);
1305 aos = m_privapi->osync_plugin_config_get_advancedoptions(m_priv->m_config);
1306 OSyncPluginAdvancedOption *option = 0;
1307 for( OSyncList *o = aos.get(); o; o = o->next ) {
1308 option = (OSyncPluginAdvancedOption*) o->data;
1310 if( name == m_privapi->osync_plugin_advancedoption_get_name(option) )
1311 break;
1314 if( option ) {
1315 // found existing option, set it with val
1316 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1318 else {
1319 // option with that name does not exist, so create it
1320 option = m_privapi->osync_plugin_advancedoption_new(m_privapi->error);
1321 if( !option )
1322 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1324 m_privapi->osync_plugin_advancedoption_set_name(option, name.c_str());
1325 m_privapi->osync_plugin_advancedoption_set_displayname(option, display_name.c_str());
1326 OSyncPluginAdvancedOptionType type;
1327 switch( val_type )
1329 case NONE_TYPE:
1330 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_NONE;
1331 break;
1332 case BOOL_TYPE:
1333 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_BOOL;
1334 break;
1335 case CHAR_TYPE:
1336 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_CHAR;
1337 break;
1338 case DOUBLE_TYPE:
1339 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_DOUBLE;
1340 break;
1341 case INT_TYPE:
1342 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_INT;
1343 break;
1344 case LONG_TYPE:
1345 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONG;
1346 break;
1347 case LONGLONG_TYPE:
1348 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONGLONG;
1349 break;
1350 case UINT_TYPE:
1351 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_UINT;
1352 break;
1353 case ULONG_TYPE:
1354 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONG;
1355 break;
1356 case ULONGLONG_TYPE:
1357 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONGLONG;
1358 break;
1359 case STRING_TYPE:
1360 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_STRING;
1361 break;
1362 default:
1363 throw std::logic_error("Bad type in SetAdvanced()");
1365 m_privapi->osync_plugin_advancedoption_set_type(option, type);
1366 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1367 m_privapi->osync_plugin_config_add_advancedoption(m_priv->m_config, option);
1368 m_privapi->osync_plugin_advancedoption_unref(option);
1372 OS40PluginConfig::OS40ConfigResourcePtr
1373 OS40PluginConfig::GetResource(const std::string &objtype)
1375 OS40ConfigResourcePtr ptr;
1377 // FIXME - get_resources() does not give us a copy, so don't use
1378 // the SyncListHandle here
1379 OSyncList *rs = m_privapi->osync_plugin_config_get_resources(m_priv->m_config);
1380 for( OSyncList *o = rs; o; o = o->next ) {
1381 OSyncPluginResource *res = (OSyncPluginResource*) o->data;
1382 if( objtype == m_privapi->osync_plugin_resource_get_objtype(res) ) {
1383 // bump the resource count, since OS40ConfigResource
1384 // will unref it in the destructor
1385 m_privapi->osync_plugin_resource_ref(res);
1386 ptr.reset( new OS40ConfigResource(*this, res, true) );
1387 return ptr;
1391 // this res has a ref bump already, no ref() needed like it is above
1392 OSyncPluginResource *res = m_privapi->osync_plugin_resource_new(m_privapi->error);
1393 if( !res )
1394 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1395 ptr.reset( new OS40ConfigResource(*this, res, false) );
1396 // we search by objtype name, so make sure this is set in
1397 // the new object
1398 ptr->SetObjType(objtype);
1399 return ptr;
1402 std::string OS40PluginConfig::GetUsername() const
1404 string username;
1406 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1407 if( !auth )
1408 return username;
1410 const char *un = m_privapi->osync_plugin_authentication_get_username(auth);
1411 if( !un )
1412 return username;
1414 username = un;
1415 return username;
1418 void OS40PluginConfig::SetUsername(const std::string &username)
1420 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1421 if( !auth ) {
1422 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1423 if( !auth )
1424 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1425 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_USERNAME) ) {
1426 m_privapi->osync_plugin_authentication_unref(auth);
1427 throw std::runtime_error("Username (authentication parameter) is not supported in plugin!");
1430 // all looks ok, add it to the config
1431 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1432 // unref our copy, since the config now has it...
1433 // our auth pointer will still be valid since config holds it
1434 m_privapi->osync_plugin_authentication_unref(auth);
1437 m_privapi->osync_plugin_authentication_set_username(auth, username.c_str());
1440 std::string OS40PluginConfig::GetPassword() const
1442 string password;
1444 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1445 if( !auth )
1446 return password;
1448 const char *pass = m_privapi->osync_plugin_authentication_get_password(auth);
1449 if( !pass )
1450 return password;
1452 password = pass;
1453 return password;
1456 void OS40PluginConfig::SetPassword(const std::string &password)
1458 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1459 if( !auth ) {
1460 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1461 if( !auth )
1462 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1463 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_PASSWORD) ) {
1464 m_privapi->osync_plugin_authentication_unref(auth);
1465 throw std::runtime_error("Password authentication is not supported in plugin!");
1468 // all looks ok, add it to the config
1469 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1470 // unref our copy, since the config now has it...
1471 // our auth pointer will still be valid since config holds it
1472 m_privapi->osync_plugin_authentication_unref(auth);
1475 m_privapi->osync_plugin_authentication_set_password(auth, password.c_str());
1478 void OS40PluginConfig::Save()
1480 if( !m_privapi->osync_member_save(m_priv->m_member, m_privapi->error) )
1481 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1485 /////////////////////////////////////////////////////////////////////////////
1486 // OpenSync40 (API override class) - public members
1488 OpenSync40::OpenSync40()
1490 // due to bugs in the way opensync 0.22 loads its modules,
1491 // (i.e. it doesn't load the plugins using RTLD_LOCAL, and
1492 // so libopensync.so.0 is loaded and pollutes the symbol table,
1493 // causing symbol clashes) we need to make sure that
1494 // OpenSync40 is only loaded first... if OpenSync22 was
1495 // loaded first, we will fail, so error out
1496 if( OpenSync22::SymbolsLoaded() )
1497 throw std::logic_error("Always load OpenSync40 before OpenSync22, to avoid symbol table conflicts.");
1499 if( !Open("libopensync.so.1") )
1500 throw DlError("Can't dlopen libopensync.so.1");
1502 // store locally in case of constructor exception in LoadSym
1503 std::auto_ptr<OpenSync40Private> p(new OpenSync40Private(*this));
1505 // load all required symbols...
1506 // we don't need to use try/catch here, since the base
1507 // class destructor will clean up for us if LoadSym() throws
1508 LoadSym(p->osync_get_version, "osync_get_version");
1509 LoadSym(p->osync_error_print, "osync_error_print");
1510 LoadSym(p->osync_error_is_set, "osync_error_is_set");
1511 LoadSym(p->osync_error_unref, "osync_error_unref");
1512 LoadSym(p->osync_group_env_new, "osync_group_env_new");
1513 LoadSym(p->osync_format_env_new, "osync_format_env_new");
1514 LoadSym(p->osync_plugin_env_new, "osync_plugin_env_new");
1515 LoadSym(p->osync_group_env_unref, "osync_group_env_unref");
1516 LoadSym(p->osync_format_env_unref, "osync_format_env_unref");
1517 LoadSym(p->osync_plugin_env_unref, "osync_plugin_env_unref");
1518 LoadSym(p->osync_plugin_env_load, "osync_plugin_env_load");
1519 LoadSym(p->osync_plugin_env_get_plugins,"osync_plugin_env_get_plugins");
1520 LoadSym(p->osync_plugin_get_name, "osync_plugin_get_name");
1521 LoadSym(p->osync_list_free, "osync_list_free");
1522 LoadSym(p->osync_group_env_load_groups, "osync_group_env_load_groups");
1523 LoadSym(p->osync_format_env_load_plugins,
1524 "osync_format_env_load_plugins");
1525 LoadSym(p->osync_group_env_get_groups, "osync_group_env_get_groups");
1526 LoadSym(p->osync_group_get_name, "osync_group_get_name");
1527 LoadSym(p->osync_group_env_find_group, "osync_group_env_find_group");
1528 LoadSym(p->osync_group_get_members, "osync_group_get_members");
1529 LoadSym(p->osync_member_get_name, "osync_member_get_name");
1530 LoadSym(p->osync_member_get_id, "osync_member_get_id");
1531 LoadSym(p->osync_member_get_pluginname, "osync_member_get_pluginname");
1532 LoadSym(p->osync_format_env_get_objformats,
1533 "osync_format_env_get_objformats");
1534 LoadSym(p->osync_objformat_get_name, "osync_objformat_get_name");
1535 LoadSym(p->osync_objformat_get_objtype, "osync_objformat_get_objtype");
1536 LoadSym(p->osync_group_new, "osync_group_new");
1537 LoadSym(p->osync_group_unref, "osync_group_unref");
1538 LoadSym(p->osync_group_set_name, "osync_group_set_name");
1539 LoadSym(p->osync_group_env_add_group, "osync_group_env_add_group");
1540 LoadSym(p->osync_group_save, "osync_group_save");
1541 LoadSym(p->osync_group_delete, "osync_group_delete");
1542 LoadSym(p->osync_group_env_remove_group,"osync_group_env_remove_group");
1543 LoadSym(p->osync_plugin_env_find_plugin,"osync_plugin_env_find_plugin");
1544 LoadSym(p->osync_member_unref, "osync_member_unref");
1545 LoadSym(p->osync_member_new, "osync_member_new");
1546 LoadSym(p->osync_group_add_member, "osync_group_add_member");
1547 LoadSym(p->osync_member_set_pluginname, "osync_member_set_pluginname");
1548 LoadSym(p->osync_member_set_name, "osync_member_set_name");
1549 LoadSym(p->osync_member_save, "osync_member_save");
1550 LoadSym(p->osync_group_find_member, "osync_group_find_member");
1551 LoadSym(p->osync_member_delete, "osync_member_delete");
1552 LoadSym(p->osync_group_remove_member, "osync_group_remove_member");
1553 LoadSym(p->osync_plugin_config_new, "osync_plugin_config_new");
1554 LoadSym(p->osync_plugin_config_file_load,
1555 "osync_plugin_config_file_load");
1556 LoadSym(p->osync_member_set_config, "osync_member_set_config");
1557 LoadSym(p->osync_member_get_config_or_default,
1558 "osync_member_get_config_or_default");
1559 LoadSym(p->osync_plugin_config_file_save,
1560 "osync_plugin_config_file_save");
1561 LoadSym(p->osync_plugin_get_config_type,"osync_plugin_get_config_type");
1562 LoadSym(p->osync_engine_new, "osync_engine_new");
1563 LoadSym(p->osync_engine_unref, "osync_engine_unref");
1564 LoadSym(p->osync_engine_discover_and_block,
1565 "osync_engine_discover_and_block");
1566 LoadSym(p->osync_member_get_objtypes, "osync_member_get_objtypes");
1567 LoadSym(p->osync_list_length, "osync_list_length");
1568 LoadSym(p->osync_error_set, "osync_error_set");
1569 LoadSym(p->osync_engine_finalize, "osync_engine_finalize");
1570 LoadSym(p->osync_mapping_engine_get_changes,
1571 "osync_mapping_engine_get_changes");
1572 LoadSym(p->osync_mapping_engine_supports_ignore,
1573 "osync_mapping_engine_supports_ignore");
1574 LoadSym(p->osync_mapping_engine_supports_use_latest,
1575 "osync_mapping_engine_supports_use_latest");
1576 LoadSym(p->osync_list_nth, "osync_list_nth");
1577 LoadSym(p->osync_engine_mapping_solve, "osync_engine_mapping_solve");
1578 LoadSym(p->osync_engine_abort, "osync_engine_abort");
1579 LoadSym(p->osync_engine_mapping_duplicate,
1580 "osync_engine_mapping_duplicate");
1581 LoadSym(p->osync_engine_mapping_ignore_conflict,
1582 "osync_engine_mapping_ignore_conflict");
1583 LoadSym(p->osync_engine_mapping_use_latest,
1584 "osync_engine_mapping_use_latest");
1585 LoadSym(p->osync_change_get_changetype, "osync_change_get_changetype");
1586 LoadSym(p->osync_mapping_engine_change_find_member,
1587 "osync_mapping_engine_change_find_member");
1588 LoadSym(p->osync_change_get_data, "osync_change_get_data");
1589 LoadSym(p->osync_data_get_printable, "osync_data_get_printable");
1590 LoadSym(p->osync_free, "osync_free");
1591 LoadSym(p->osync_change_get_uid, "osync_change_get_uid");
1592 LoadSym(p->osync_engine_continue, "osync_engine_continue");
1593 LoadSym(p->osync_engine_get_objengines, "osync_engine_get_objengines");
1594 LoadSym(p->osync_obj_engine_get_members,
1595 "osync_obj_engine_get_members");
1596 LoadSym(p->osync_obj_engine_get_objtype,
1597 "osync_obj_engine_get_objtype");
1598 LoadSym(p->osync_obj_engine_get_mapping_entry_engines_of_member,
1599 "osync_obj_engine_get_mapping_entry_engines_of_member");
1600 LoadSym(p->osync_entry_engine_is_dirty,"osync_entry_engine_is_dirty");
1601 LoadSym(p->osync_entry_engine_get_changetype,
1602 "osync_entry_engine_get_changetype");
1603 LoadSym(p->osync_engine_change_update_get_change,
1604 "osync_engine_change_update_get_change");
1605 LoadSym(p->osync_engine_change_update_get_member,
1606 "osync_engine_change_update_get_member");
1607 LoadSym(p->osync_engine_change_update_get_error,
1608 "osync_engine_change_update_get_error");
1609 LoadSym(p->osync_engine_change_update_get_event,
1610 "osync_engine_change_update_get_event");
1611 LoadSym(p->osync_change_get_objformat, "osync_change_get_objformat");
1612 LoadSym(p->osync_engine_mapping_update_get_error,
1613 "osync_engine_mapping_update_get_error");
1614 LoadSym(p->osync_engine_update_get_error,
1615 "osync_engine_update_get_error");
1616 LoadSym(p->osync_engine_update_get_event,
1617 "osync_engine_update_get_event");
1618 LoadSym(p->osync_engine_member_update_get_objtype,
1619 "osync_engine_member_update_get_objtype");
1620 LoadSym(p->osync_engine_member_update_get_member,
1621 "osync_engine_member_update_get_member");
1622 LoadSym(p->osync_engine_member_update_get_error,
1623 "osync_engine_member_update_get_error");
1624 LoadSym(p->osync_engine_member_update_get_event,
1625 "osync_engine_member_update_get_event");
1626 LoadSym(p->osync_engine_set_conflict_callback,
1627 "osync_engine_set_conflict_callback");
1628 LoadSym(p->osync_engine_set_changestatus_callback,
1629 "osync_engine_set_changestatus_callback");
1630 LoadSym(p->osync_engine_set_mappingstatus_callback,
1631 "osync_engine_set_mappingstatus_callback");
1632 LoadSym(p->osync_engine_set_enginestatus_callback,
1633 "osync_engine_set_enginestatus_callback");
1634 LoadSym(p->osync_engine_set_memberstatus_callback,
1635 "osync_engine_set_memberstatus_callback");
1636 LoadSym(p->osync_engine_set_multiply_callback,
1637 "osync_engine_set_multiply_callback");
1638 LoadSym(p->osync_engine_initialize, "osync_engine_initialize");
1639 LoadSym(p->osync_engine_synchronize_and_block,
1640 "osync_engine_synchronize_and_block");
1641 LoadSym(p->osync_engine_mapping_update_get_event,
1642 "osync_engine_mapping_update_get_event");
1643 LoadSym(p->osync_plugin_resource_unref,
1644 "osync_plugin_resource_unref");
1645 LoadSym(p->osync_plugin_config_add_resource,
1646 "osync_plugin_config_add_resource");
1647 LoadSym(p->osync_plugin_resource_is_enabled,
1648 "osync_plugin_resource_is_enabled");
1649 LoadSym(p->osync_plugin_resource_enable,
1650 "osync_plugin_resource_enable");
1651 LoadSym(p->osync_plugin_resource_get_objformat_sinks,
1652 "osync_plugin_resource_get_objformat_sinks");
1653 LoadSym(p->osync_objformat_sink_get_objformat,
1654 "osync_objformat_sink_get_objformat");
1655 LoadSym(p->osync_objformat_sink_get_config,
1656 "osync_objformat_sink_get_config");
1657 LoadSym(p->osync_objformat_sink_set_config,
1658 "osync_objformat_sink_set_config");
1659 LoadSym(p->osync_objformat_sink_new,
1660 "osync_objformat_sink_new");
1661 LoadSym(p->osync_plugin_resource_add_objformat_sink,
1662 "osync_plugin_resource_add_objformat_sink");
1663 LoadSym(p->osync_objformat_sink_unref,
1664 "osync_objformat_sink_unref");
1665 LoadSym(p->osync_plugin_resource_get_preferred_format,
1666 "osync_plugin_resource_get_preferred_format");
1667 LoadSym(p->osync_plugin_resource_set_preferred_format,
1668 "osync_plugin_resource_set_preferred_format");
1669 LoadSym(p->osync_plugin_resource_get_mime,
1670 "osync_plugin_resource_get_mime");
1671 LoadSym(p->osync_plugin_resource_set_mime,
1672 "osync_plugin_resource_set_mime");
1673 LoadSym(p->osync_plugin_resource_get_objtype,
1674 "osync_plugin_resource_get_objtype");
1675 LoadSym(p->osync_plugin_resource_set_objtype,
1676 "osync_plugin_resource_set_objtype");
1677 LoadSym(p->osync_plugin_resource_get_path,
1678 "osync_plugin_resource_get_path");
1679 LoadSym(p->osync_plugin_resource_set_path,
1680 "osync_plugin_resource_set_path");
1681 LoadSym(p->osync_plugin_resource_get_url,
1682 "osync_plugin_resource_get_url");
1683 LoadSym(p->osync_plugin_resource_set_url,
1684 "osync_plugin_resource_set_url");
1685 LoadSym(p->osync_plugin_config_get_advancedoption_value_by_name,
1686 "osync_plugin_config_get_advancedoption_value_by_name");
1687 LoadSym(p->osync_plugin_config_get_advancedoptions,
1688 "osync_plugin_config_get_advancedoptions");
1689 LoadSym(p->osync_plugin_config_add_advancedoption,
1690 "osync_plugin_config_add_advancedoption");
1691 LoadSym(p->osync_plugin_advancedoption_new,
1692 "osync_plugin_advancedoption_new");
1693 LoadSym(p->osync_plugin_advancedoption_unref,
1694 "osync_plugin_advancedoption_unref");
1695 LoadSym(p->osync_plugin_advancedoption_get_name,
1696 "osync_plugin_advancedoption_get_name");
1697 LoadSym(p->osync_plugin_advancedoption_set_name,
1698 "osync_plugin_advancedoption_set_name");
1699 LoadSym(p->osync_plugin_advancedoption_set_displayname,
1700 "osync_plugin_advancedoption_set_displayname");
1701 LoadSym(p->osync_plugin_advancedoption_set_type,
1702 "osync_plugin_advancedoption_set_type");
1703 LoadSym(p->osync_plugin_advancedoption_set_value,
1704 "osync_plugin_advancedoption_set_value");
1705 LoadSym(p->osync_plugin_config_get_resources,
1706 "osync_plugin_config_get_resources");
1707 LoadSym(p->osync_plugin_resource_ref,
1708 "osync_plugin_resource_ref");
1709 LoadSym(p->osync_plugin_resource_new,
1710 "osync_plugin_resource_new");
1711 LoadSym(p->osync_plugin_resource_get_name,
1712 "osync_plugin_resource_get_name");
1713 LoadSym(p->osync_plugin_resource_set_name,
1714 "osync_plugin_resource_set_name");
1715 LoadSym(p->osync_plugin_config_get_authentication,
1716 "osync_plugin_config_get_authentication");
1717 LoadSym(p->osync_plugin_authentication_get_password,
1718 "osync_plugin_authentication_get_password");
1719 LoadSym(p->osync_plugin_authentication_new,
1720 "osync_plugin_authentication_new");
1721 LoadSym(p->osync_plugin_authentication_option_is_supported,
1722 "osync_plugin_authentication_option_is_supported");
1723 LoadSym(p->osync_plugin_authentication_unref,
1724 "osync_plugin_authentication_unref");
1725 LoadSym(p->osync_plugin_config_set_authentication,
1726 "osync_plugin_config_set_authentication");
1727 LoadSym(p->osync_plugin_authentication_set_password,
1728 "osync_plugin_authentication_set_password");
1729 LoadSym(p->osync_plugin_authentication_get_username,
1730 "osync_plugin_authentication_get_username");
1731 LoadSym(p->osync_plugin_authentication_set_username,
1732 "osync_plugin_authentication_set_username");
1733 LoadSym(p->osync_group_set_objtype_enabled,
1734 "osync_group_set_objtype_enabled");
1736 // fixup free pointers
1737 p->group_env.SetFreeFunc(p->osync_group_env_unref);
1738 p->format_env.SetFreeFunc(p->osync_format_env_unref);
1739 p->plugin_env.SetFreeFunc(p->osync_plugin_env_unref);
1741 // setup opensync support environment
1742 SetupEnvironment(p.get());
1744 // this pointer is ours now
1745 m_priv = p.release();
1748 OpenSync40::~OpenSync40()
1750 delete m_priv;
1751 m_priv = 0;
1754 void OpenSync40::SetupEnvironment(OpenSync40Private *p)
1756 // allocate group, format, and env
1757 p->group_env = p->osync_group_env_new(p->error);
1758 if( !p->group_env.get() )
1759 throw std::runtime_error(p->error.GetErrorMsg());
1761 p->format_env = p->osync_format_env_new(p->error);
1762 if( !p->format_env.get() )
1763 throw std::runtime_error(p->error.GetErrorMsg());
1765 p->plugin_env = p->osync_plugin_env_new(p->error);
1766 if( !p->plugin_env.get() )
1767 throw std::runtime_error(p->error.GetErrorMsg());
1769 // load group, format, and env
1770 if( !p->osync_group_env_load_groups(p->group_env.get(), NULL, p->error) ||
1771 !p->osync_format_env_load_plugins(p->format_env.get(), NULL, p->error) ||
1772 !p->osync_plugin_env_load(p->plugin_env.get(), NULL, p->error) )
1773 throw std::runtime_error(p->error.GetErrorMsg());
1776 const char* OpenSync40::GetVersion() const
1778 return m_priv->osync_get_version();
1781 const char* OpenSync40::GetEngineName() const
1783 return "0.40";
1786 void OpenSync40::GetPluginNames(string_list_type &plugins)
1788 // start fresh
1789 plugins.clear();
1791 OSyncPlugin *plugin;
1792 OSyncList *plugin_list, *p;
1794 plugin_list = m_priv->osync_plugin_env_get_plugins(m_priv->plugin_env.get());
1795 for( p = plugin_list; p; p = p->next ) {
1796 plugin = (OSyncPlugin *) p->data;
1797 plugins.push_back(m_priv->osync_plugin_get_name(plugin));
1800 m_priv->osync_list_free(plugin_list);
1803 void OpenSync40::GetFormats(format_list_type &formats)
1805 // start fresh
1806 formats.clear();
1808 OSyncList *o, *list = m_priv->osync_format_env_get_objformats(m_priv->format_env.get());
1810 for( o = list; o; o = o->next ) {
1811 OSyncObjFormat *format = (OSyncObjFormat *) o->data;
1813 Format new_format;
1814 new_format.name = m_priv->osync_objformat_get_name(format);
1815 new_format.object_type = m_priv->osync_objformat_get_objtype(format);
1817 formats.push_back(new_format);
1820 m_priv->osync_list_free(list);
1823 void OpenSync40::GetGroupNames(string_list_type &groups)
1825 // start fresh
1826 groups.clear();
1828 OSyncGroup *group;
1829 OSyncList *g, *group_list = m_priv->osync_group_env_get_groups(m_priv->group_env.get());
1831 for( g = group_list; g; g = g->next ) {
1832 group = (OSyncGroup *) g->data;
1833 groups.push_back(m_priv->osync_group_get_name(group));
1836 m_priv->osync_list_free(group_list);
1839 void OpenSync40::GetMembers(const std::string &group_name,
1840 member_list_type &members)
1842 // start fresh
1843 members.clear();
1845 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1846 if( !group ) {
1847 ostringstream oss;
1848 oss << "GetMembers: Unable to find group with name: " << group_name;
1849 throw std::runtime_error(oss.str());
1852 OSyncList *member_list = m_priv->osync_group_get_members(group);
1853 for( OSyncList *m = member_list; m; m = m->next ) {
1854 Member new_member;
1855 OSyncMember *member = (OSyncMember *) m->data;
1856 const char *membername = m_priv->osync_member_get_name(member);
1857 if (membername) {
1858 new_member.friendly_name = membername;
1861 new_member.group_name = group_name;
1862 new_member.id = m_priv->osync_member_get_id(member);
1863 new_member.plugin_name = m_priv->osync_member_get_pluginname(member);
1865 // add to member list
1866 members.push_back(new_member);
1869 // cleanup
1870 m_priv->osync_list_free(member_list);
1873 void OpenSync40::AddGroup(const std::string &group_name)
1875 OSyncGroup *group = m_priv->osync_group_new(m_priv->error);
1876 if( !group )
1877 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1879 m_priv->osync_group_set_name(group, group_name.c_str());
1880 if( !m_priv->osync_group_env_add_group(m_priv->group_env.get(), group, m_priv->error) ) {
1881 m_priv->osync_group_unref(group);
1882 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1885 if( !m_priv->osync_group_save(group, m_priv->error) ) {
1886 m_priv->osync_group_unref(group);
1887 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1890 m_priv->osync_group_unref(group);
1893 void OpenSync40::DeleteGroup(const std::string &group_name)
1895 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1896 if( !group )
1897 throw std::runtime_error("DeleteGroup(): Group not found: " + group_name);
1899 if( !m_priv->osync_group_delete(group, m_priv->error) )
1900 throw std::runtime_error("DeleteGroup(): " + m_priv->error.GetErrorMsg());
1902 m_priv->osync_group_env_remove_group(m_priv->group_env.get(), group);
1905 Converter& OpenSync40::GetConverter()
1907 return m_priv->converter;
1910 long OpenSync40::AddMember(const std::string &group_name,
1911 const std::string &plugin_name,
1912 const std::string &member_name)
1914 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1915 if( !group )
1916 throw std::runtime_error("AddMember(): Group not found: " + group_name);
1918 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), plugin_name.c_str());
1919 if( !plugin )
1920 throw std::runtime_error("AddMember(): Plugin not found: " + plugin_name);
1922 vLateSmartPtr<OSyncMember, void(*)(OSyncMember*)> mptr(m_priv->osync_member_unref);
1923 mptr = m_priv->osync_member_new(m_priv->error);
1924 if( !mptr.get() )
1925 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1927 m_priv->osync_group_add_member(group, mptr.get());
1928 m_priv->osync_member_set_pluginname(mptr.get(), plugin_name.c_str());
1930 if( member_name.size() )
1931 m_priv->osync_member_set_name(mptr.get(), member_name.c_str());
1933 if( !m_priv->osync_member_save(mptr.get(), m_priv->error) )
1934 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1936 return m_priv->osync_member_get_id(mptr.get());
1939 void OpenSync40::DeleteMember(const std::string &group_name, long member_id)
1941 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1942 if( !group )
1943 throw std::runtime_error("DeleteMember(): Group not found: " + group_name);
1945 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1946 if( !member ) {
1947 ostringstream oss;
1948 oss << "DeleteMember(): Member " << member_id << " not found.";
1949 throw std::runtime_error(oss.str());
1952 if( !m_priv->osync_member_delete(member, m_priv->error) )
1953 throw std::runtime_error("DeleteMember(): " + m_priv->error.GetErrorMsg());
1955 m_priv->osync_group_remove_member(group, member);
1958 void OpenSync40::DeleteMember(const std::string &group_name,
1959 const std::string &plugin_name)
1961 member_list_type mlist;
1962 GetMembers(group_name, mlist);
1963 Member *member = mlist.Find(plugin_name.c_str());
1964 if( !member )
1965 throw std::runtime_error("DeleteMember(): Member not found: " + plugin_name);
1967 DeleteMember(group_name, member->id);
1970 bool OpenSync40::IsConfigurable(const std::string &group_name,
1971 long member_id)
1973 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1974 if( !group )
1975 throw std::runtime_error("IsConfigurable(): Group not found: " + group_name);
1977 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1978 if( !member ) {
1979 ostringstream oss;
1980 oss << "IsConfigurable(): Member " << member_id << " not found.";
1981 throw std::runtime_error(oss.str());
1984 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
1985 if( !plugin )
1986 throw std::runtime_error(string("IsConfigurable(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
1989 OSyncPluginConfigurationType type = m_priv->osync_plugin_get_config_type(plugin);
1990 return type != OSYNC_PLUGIN_NO_CONFIGURATION;
1993 std::string OpenSync40::GetConfiguration(const std::string &group_name,
1994 long member_id)
1996 if( !IsConfigurable(group_name, member_id) ) {
1997 ostringstream oss;
1998 oss << "GetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
1999 throw std::runtime_error(oss.str());
2002 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2003 if( !group )
2004 throw std::runtime_error("GetConfiguration(): Group not found: " + group_name);
2006 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2007 if( !member ) {
2008 ostringstream oss;
2009 oss << "GetConfiguration(): Member " << member_id << " not found.";
2010 throw std::runtime_error(oss.str());
2013 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2014 if( !plugin )
2015 throw std::runtime_error(string("GetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2018 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2019 if( !config )
2020 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2022 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2023 // functions, and then load that from the file again, and
2024 // return that string as the configuratin.
2026 TempDir tempdir("opensyncapi");
2028 string filename = tempdir.GetNewFilename();
2030 if( !m_priv->osync_plugin_config_file_save(config, filename.c_str(), m_priv->error) )
2031 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2033 ifstream in(filename.c_str());
2034 string config_data;
2035 char buf[4096];
2036 while( in ) {
2037 in.read(buf, sizeof(buf));
2038 config_data.append(buf, in.gcount());
2041 return config_data;
2044 OS40PluginConfig OpenSync40::GetConfigurationObj(const std::string &group_name,
2045 long member_id)
2047 if( !IsConfigurable(group_name, member_id) ) {
2048 ostringstream oss;
2049 oss << "GetConfigurationObj(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2050 throw std::runtime_error(oss.str());
2053 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2054 if( !group )
2055 throw std::runtime_error("GetConfigurationObj(): Group not found: " + group_name);
2057 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2058 if( !member ) {
2059 ostringstream oss;
2060 oss << "GetConfigurationObj(): Member " << member_id << " not found.";
2061 throw std::runtime_error(oss.str());
2064 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2065 if( !plugin )
2066 throw std::runtime_error(string("GetConfigurationObj(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2069 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2070 if( !config )
2071 throw std::runtime_error("GetConfigurationObj(): " + m_priv->error.GetErrorMsg());
2073 return OS40PluginConfig(m_priv, member, config);
2076 void OpenSync40::SetConfiguration(const std::string &group_name,
2077 long member_id,
2078 const std::string &config_data)
2080 if( !IsConfigurable(group_name, member_id) ) {
2081 ostringstream oss;
2082 oss << "SetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2083 throw std::runtime_error(oss.str());
2086 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2087 if( !group )
2088 throw std::runtime_error("SetConfiguration(): Group not found: " + group_name);
2090 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2091 if( !member ) {
2092 ostringstream oss;
2093 oss << "SetConfiguration(): Member " << member_id << " not found.";
2094 throw std::runtime_error(oss.str());
2097 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2098 if( !plugin )
2099 throw std::runtime_error(string("SetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2102 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2103 // functions, and then load that from the file again, and
2104 // return that string as the configuratin.
2106 TempDir tempdir("opensyncapi");
2108 string filename = tempdir.GetNewFilename();
2110 // write config data to file
2112 ofstream out(filename.c_str());
2113 out << config_data;
2116 // load brand new config from file
2117 // if a new config object isn't created here, the loaded config
2118 // will be added to the existing config
2119 OSyncPluginConfig *new_config = m_priv->osync_plugin_config_new(m_priv->error);
2120 if( !m_priv->osync_plugin_config_file_load(new_config, filename.c_str(), m_priv->error) )
2121 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2123 m_priv->osync_member_set_config(member, new_config);
2125 if( !m_priv->osync_member_save(member, m_priv->error))
2126 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2129 void OpenSync40::Discover(const std::string &group_name)
2131 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2132 if( !group )
2133 throw std::runtime_error("Discover(): Group not found: " + group_name);
2135 EngineHandle engine(m_priv->osync_engine_unref);
2136 engine = m_priv->osync_engine_new(group, m_priv->error);
2137 if( !engine.get() )
2138 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2140 SyncListHandle members(m_priv->osync_list_free);
2141 members = m_priv->osync_group_get_members(group);
2142 OSyncList *m = NULL;
2143 for( m = members.get(); m; m = m->next ) {
2144 OSyncMember *member = (OSyncMember *) m->data;
2146 /* Discover the objtypes for the members */
2147 if( !m_priv->osync_engine_discover_and_block(engine.get(), member, m_priv->error))
2148 break;
2150 SyncListHandle objtypes(m_priv->osync_list_free);
2151 objtypes = m_priv->osync_member_get_objtypes(member);
2152 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2153 m_priv->osync_error_set(m_priv->error, OSYNC_ERROR_GENERIC, "discover failed: no objtypes returned");
2154 break;
2157 if( !m_priv->osync_member_save(member, m_priv->error) )
2158 break;
2161 // check for error
2162 if( m ) {
2163 m_priv->osync_engine_finalize(engine.get(), m_priv->error);
2164 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2168 void OpenSync40::Sync(const std::string &group_name,
2169 SyncStatus &status_callback,
2170 Config::pst_type sync_types)
2172 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2173 if( !group )
2174 throw std::runtime_error("Sync(): Group not found: " + group_name);
2176 // enable/disable each objtype, as per sync_types
2177 if( !(sync_types & PST_DO_NOT_SET) ) {
2178 cerr << "enabling objtypes: " << sync_types << endl;
2179 m_priv->osync_group_set_objtype_enabled(group, "contact",
2180 (sync_types & PST_CONTACTS) ? TRUE : FALSE);
2181 m_priv->osync_group_set_objtype_enabled(group, "event",
2182 (sync_types & PST_EVENTS) ? TRUE : FALSE);
2183 m_priv->osync_group_set_objtype_enabled(group, "note",
2184 (sync_types & PST_NOTES) ? TRUE : FALSE);
2185 m_priv->osync_group_set_objtype_enabled(group, "todo",
2186 (sync_types & PST_TODOS) ? TRUE : FALSE);
2189 EngineHandle engine(m_priv->osync_engine_unref);
2190 engine = m_priv->osync_engine_new(group, m_priv->error);
2191 if( !engine.get() )
2192 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2195 CallbackBundle cbdata(m_priv, status_callback);
2197 m_priv->osync_engine_set_conflict_callback(engine.get(), conflict_handler, &cbdata);
2198 m_priv->osync_engine_set_changestatus_callback(engine.get(), entry_status, &cbdata);
2199 m_priv->osync_engine_set_mappingstatus_callback(engine.get(), mapping_status, &cbdata);
2200 m_priv->osync_engine_set_enginestatus_callback(engine.get(), engine_status, &cbdata);
2201 m_priv->osync_engine_set_memberstatus_callback(engine.get(), member_status, &cbdata);
2202 m_priv->osync_engine_set_multiply_callback(engine.get(), multiply_summary, &cbdata);
2205 SyncListHandle members(m_priv->osync_list_free);
2206 members = m_priv->osync_group_get_members(group);
2207 OSyncList *m = NULL;
2208 for( m = members.get(); m; m = m->next ) {
2209 OSyncMember *member = (OSyncMember *) m->data;
2211 SyncListHandle objtypes(m_priv->osync_list_free);
2212 objtypes = m_priv->osync_member_get_objtypes(member);
2213 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2214 cout << "Sync(): Member " << m_priv->osync_member_get_id(member) << " has no objtypes. Has it already been discovered?" << endl;
2218 if( !m_priv->osync_engine_initialize(engine.get(), m_priv->error) )
2219 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2221 if( !m_priv->osync_engine_synchronize_and_block(engine.get(), m_priv->error) ) {
2222 m_priv->osync_engine_finalize(engine.get(), NULL);
2223 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2226 if( !m_priv->osync_engine_finalize(engine.get(), m_priv->error) )
2227 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2231 /////////////////////////////////////////////////////////////////////////////
2232 // TossError public members
2234 /// Returns NULL if no error
2235 std::string TossError::GetErrorMsg()
2237 return std::string(m_priv->osync_error_print(&m_error));
2240 bool TossError::IsSet()
2242 return m_priv->osync_error_is_set(&m_error);
2245 void TossError::Clear()
2247 if( m_error ) {
2248 m_priv->osync_error_unref(&m_error);
2249 m_error = 0;
2253 } // namespace OpenSync