desktop: use os4x's osync_error_print_stack() for more detailed error msgs
[barry/progweb.git] / desktop / src / os40.cc
blob59e11da1fd24318fd424d716762761420eb51942
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 char* (*osync_error_print_stack)(OSyncError **error);
102 osync_bool (*osync_error_is_set)(OSyncError **error);
103 void (*osync_error_unref)(OSyncError **error);
104 OSyncGroupEnv* (*osync_group_env_new)(OSyncError **error);
105 OSyncFormatEnv* (*osync_format_env_new)(OSyncError **error);
106 OSyncPluginEnv* (*osync_plugin_env_new)(OSyncError **error);
107 void (*osync_group_env_unref)(OSyncGroupEnv *env);
108 void (*osync_format_env_unref)(OSyncFormatEnv *env);
109 void (*osync_plugin_env_unref)(OSyncPluginEnv *env);
110 osync_bool (*osync_plugin_env_load)(OSyncPluginEnv *env,
111 const char *path, OSyncError **error);
112 OSyncList* (*osync_plugin_env_get_plugins)(
113 OSyncPluginEnv *env);
114 const char* (*osync_plugin_get_name)(OSyncPlugin *plugin);
115 void (*osync_list_free)(OSyncList *list);
116 osync_bool (*osync_group_env_load_groups)(
117 OSyncGroupEnv *env, const char *path,
118 OSyncError **error);
119 osync_bool (*osync_format_env_load_plugins)(
120 OSyncFormatEnv *env, const char *path,
121 OSyncError **error);
122 OSyncList* (*osync_group_env_get_groups)(
123 OSyncGroupEnv *env);
124 const char* (*osync_group_get_name)(OSyncGroup *group);
125 OSyncGroup* (*osync_group_env_find_group)(
126 OSyncGroupEnv *env, const char *name);
127 OSyncList* (*osync_group_get_members)(OSyncGroup *group);
128 const char* (*osync_member_get_name)(OSyncMember *member);
129 osync_memberid (*osync_member_get_id)(OSyncMember *member);
130 const char* (*osync_member_get_pluginname)(
131 OSyncMember *member);
132 OSyncList* (*osync_format_env_get_objformats)(
133 OSyncFormatEnv *env);
134 const char* (*osync_objformat_get_name)(
135 OSyncObjFormat *format);
136 const char* (*osync_objformat_get_objtype)(
137 OSyncObjFormat *format);
138 OSyncGroup* (*osync_group_new)(OSyncError **error);
139 void (*osync_group_unref)(OSyncGroup *group);
140 void (*osync_group_set_name)(OSyncGroup *group,
141 const char *name);
142 osync_bool (*osync_group_env_add_group)(OSyncGroupEnv *env,
143 OSyncGroup *group,
144 OSyncError **error);
145 osync_bool (*osync_group_save)(OSyncGroup *group,
146 OSyncError **error);
147 osync_bool (*osync_group_delete)(OSyncGroup *group,
148 OSyncError **error);
149 void (*osync_group_env_remove_group)(
150 OSyncGroupEnv *env, OSyncGroup *group);
151 OSyncPlugin* (*osync_plugin_env_find_plugin)(
152 OSyncPluginEnv *env, const char *name);
153 void (*osync_member_unref)(OSyncMember *member);
154 OSyncMember* (*osync_member_new)(OSyncError **error);
155 void (*osync_group_add_member)(OSyncGroup *group,
156 OSyncMember *member);
157 void (*osync_member_set_pluginname)(
158 OSyncMember *member,
159 const char *pluginname);
160 void (*osync_member_set_name)(OSyncMember *member,
161 const char *name);
162 osync_bool (*osync_member_save)(OSyncMember *member,
163 OSyncError **error);
164 OSyncMember* (*osync_group_find_member)(OSyncGroup *group,
165 osync_memberid id);
166 osync_bool (*osync_member_delete)(OSyncMember *member,
167 OSyncError **error);
168 void (*osync_group_remove_member)(OSyncGroup *group,
169 OSyncMember *member);
170 OSyncPluginConfig* (*osync_plugin_config_new)(OSyncError **error);
171 osync_bool (*osync_plugin_config_file_load)(
172 OSyncPluginConfig *config,
173 const char *path,
174 OSyncError **error);
175 void (*osync_member_set_config)(OSyncMember *member,
176 OSyncPluginConfig *config);
177 OSyncPluginConfig* (*osync_member_get_config_or_default)(
178 OSyncMember *member,
179 OSyncError **error);
180 osync_bool (*osync_plugin_config_file_save)(
181 OSyncPluginConfig *config,
182 const char *path, OSyncError **error);
183 OSyncPluginConfigurationType (*osync_plugin_get_config_type)(
184 OSyncPlugin *plugin);
185 OSyncEngine* (*osync_engine_new)(OSyncGroup *group,
186 OSyncError **error);
187 void (*osync_engine_unref)(OSyncEngine *engine);
188 osync_bool (*osync_engine_discover_and_block)(
189 OSyncEngine *engine,
190 OSyncMember *member,
191 OSyncError **error);
192 OSyncList* (*osync_member_get_objtypes)(
193 OSyncMember *member);
194 unsigned int (*osync_list_length)(const OSyncList *list);
195 void (*osync_error_set)(OSyncError **error,
196 OSyncErrorType type,
197 const char *format, ...);
198 osync_bool (*osync_engine_finalize)(OSyncEngine *engine,
199 OSyncError **error);
200 OSyncList* (*osync_mapping_engine_get_changes)(
201 OSyncMappingEngine *engine);
202 osync_bool (*osync_mapping_engine_supports_ignore)(
203 OSyncMappingEngine *engine);
204 osync_bool (*osync_mapping_engine_supports_use_latest)(
205 OSyncMappingEngine *engine);
206 OSyncList* (*osync_list_nth)(OSyncList *list,
207 unsigned int n);
208 osync_bool (*osync_engine_mapping_solve)(
209 OSyncEngine *engine,
210 OSyncMappingEngine *mapping_engine,
211 OSyncChange *change,
212 OSyncError **error);
213 osync_bool (*osync_engine_abort)(OSyncEngine *engine,
214 OSyncError **error);
215 osync_bool (*osync_engine_mapping_duplicate)(
216 OSyncEngine *engine,
217 OSyncMappingEngine *mapping_engine,
218 OSyncError **error);
219 osync_bool (*osync_engine_mapping_ignore_conflict)(
220 OSyncEngine *engine,
221 OSyncMappingEngine *mapping_engine,
222 OSyncError **error);
223 osync_bool (*osync_engine_mapping_use_latest)(
224 OSyncEngine *engine,
225 OSyncMappingEngine *mapping_engine,
226 OSyncError **error);
227 OSyncChangeType (*osync_change_get_changetype)(
228 OSyncChange *change);
229 OSyncMember* (*osync_mapping_engine_change_find_member)(
230 OSyncMappingEngine *engine,
231 OSyncChange *change);
232 OSyncData* (*osync_change_get_data)(OSyncChange *change);
233 char* (*osync_data_get_printable)(OSyncData *data,
234 OSyncError **error);
235 void (*osync_free)(void *ptr);
236 const char* (*osync_change_get_uid)(OSyncChange *change);
237 osync_bool (*osync_engine_continue)(OSyncEngine *engine,
238 OSyncError **error);
239 OSyncList* (*osync_engine_get_objengines)(
240 OSyncEngine *engine);
241 OSyncList* (*osync_obj_engine_get_members)(
242 OSyncObjEngine* engine);
243 const char* (*osync_obj_engine_get_objtype)(
244 OSyncObjEngine *engine);
245 const OSyncList* (*osync_obj_engine_get_mapping_entry_engines_of_member)(
246 OSyncObjEngine *engine,
247 OSyncMember *member);
248 osync_bool (*osync_entry_engine_is_dirty)(
249 OSyncMappingEntryEngine *engine);
250 OSyncChangeType (*osync_entry_engine_get_changetype)(
251 OSyncMappingEntryEngine *engine);
252 OSyncChange* (*osync_engine_change_update_get_change)(
253 OSyncEngineChangeUpdate *update);
254 OSyncMember* (*osync_engine_change_update_get_member)(
255 OSyncEngineChangeUpdate *update);
256 OSyncError* (*osync_engine_change_update_get_error)(
257 OSyncEngineChangeUpdate *update);
258 OSyncEngineChangeEvent (*osync_engine_change_update_get_event)(
259 OSyncEngineChangeUpdate *update);
260 OSyncObjFormat* (*osync_change_get_objformat)(
261 OSyncChange *change);
262 OSyncError* (*osync_engine_mapping_update_get_error)(
263 OSyncEngineMappingUpdate *update);
264 OSyncError* (*osync_engine_update_get_error)(
265 OSyncEngineUpdate *update);
266 OSyncEngineEvent (*osync_engine_update_get_event)(
267 OSyncEngineUpdate *update);
268 const char* (*osync_engine_member_update_get_objtype)(
269 OSyncEngineMemberUpdate *update);
270 OSyncMember* (*osync_engine_member_update_get_member)(
271 OSyncEngineMemberUpdate *update);
272 OSyncError* (*osync_engine_member_update_get_error)(
273 OSyncEngineMemberUpdate *update);
274 OSyncEngineMemberEvent (*osync_engine_member_update_get_event)(
275 OSyncEngineMemberUpdate *update);
276 void (*osync_engine_set_conflict_callback)(
277 OSyncEngine *engine,
278 osync_conflict_cb callback,
279 void *user_data);
280 void (*osync_engine_set_changestatus_callback)(
281 OSyncEngine *engine,
282 osync_status_change_cb callback,
283 void *user_data);
284 void (*osync_engine_set_mappingstatus_callback)(
285 OSyncEngine *engine,
286 osync_status_mapping_cb callback,
287 void *user_data);
288 void (*osync_engine_set_enginestatus_callback)(
289 OSyncEngine *engine,
290 osync_status_engine_cb callback,
291 void *user_data);
292 void (*osync_engine_set_memberstatus_callback)(
293 OSyncEngine *engine,
294 osync_status_member_cb callback,
295 void *user_data);
296 void (*osync_engine_set_multiply_callback)(
297 OSyncEngine *engine,
298 osync_multiply_cb callback,
299 void *user_data);
300 osync_bool (*osync_engine_initialize)(OSyncEngine *engine,
301 OSyncError **error);
302 osync_bool (*osync_engine_synchronize_and_block)(
303 OSyncEngine *engine,OSyncError **error);
304 OSyncEngineMappingEvent (*osync_engine_mapping_update_get_event)(
305 OSyncEngineMappingUpdate *update);
306 void (*osync_plugin_resource_unref)(
307 OSyncPluginResource *resource);
308 void (*osync_plugin_config_add_resource)(
309 OSyncPluginConfig *config,
310 OSyncPluginResource *resource);
311 osync_bool (*osync_plugin_resource_is_enabled)(
312 OSyncPluginResource *resource);
313 void (*osync_plugin_resource_enable)(
314 OSyncPluginResource *resource,
315 osync_bool enable);
316 OSyncList* (*osync_plugin_resource_get_objformat_sinks)(
317 OSyncPluginResource *resource);
318 const char* (*osync_objformat_sink_get_objformat)(
319 OSyncObjFormatSink *sink);
320 const char* (*osync_objformat_sink_get_config)(
321 OSyncObjFormatSink *sink);
322 void (*osync_objformat_sink_set_config)(
323 OSyncObjFormatSink *sink,
324 const char *config);
325 OSyncObjFormatSink* (*osync_objformat_sink_new)(
326 const char *objformat,
327 OSyncError **error);
328 void (*osync_plugin_resource_add_objformat_sink)(
329 OSyncPluginResource *resource,
330 OSyncObjFormatSink *formatsink);
331 void (*osync_objformat_sink_unref)(
332 OSyncObjFormatSink *sink);
333 const char* (*osync_plugin_resource_get_preferred_format)(
334 OSyncPluginResource *resource);
335 void (*osync_plugin_resource_set_preferred_format)(
336 OSyncPluginResource *resource,
337 const char *preferred_format);
338 const char* (*osync_plugin_resource_get_mime)(
339 OSyncPluginResource *resource);
340 void (*osync_plugin_resource_set_mime)(
341 OSyncPluginResource *resource,
342 const char *mime);
343 const char* (*osync_plugin_resource_get_objtype)(
344 OSyncPluginResource *resource);
345 void (*osync_plugin_resource_set_objtype)(
346 OSyncPluginResource *resource,
347 const char *objtype);
348 const char* (*osync_plugin_resource_get_path)(
349 OSyncPluginResource *resource);
350 void (*osync_plugin_resource_set_path)(
351 OSyncPluginResource *resource,
352 const char *path);
353 const char* (*osync_plugin_resource_get_url)(
354 OSyncPluginResource *resource);
355 void (*osync_plugin_resource_set_url)(
356 OSyncPluginResource *resource,
357 const char *url);
358 const char* (*osync_plugin_config_get_advancedoption_value_by_name)(
359 OSyncPluginConfig *config,
360 const char *name);
361 OSyncList* (*osync_plugin_config_get_advancedoptions)(
362 OSyncPluginConfig *config);
363 void (*osync_plugin_config_add_advancedoption)(
364 OSyncPluginConfig *config,
365 OSyncPluginAdvancedOption *option);
366 OSyncPluginAdvancedOption* (*osync_plugin_advancedoption_new)(
367 OSyncError **error);
368 void (*osync_plugin_advancedoption_unref)(
369 OSyncPluginAdvancedOption *option);
370 const char* (*osync_plugin_advancedoption_get_name)(
371 OSyncPluginAdvancedOption *option);
372 void (*osync_plugin_advancedoption_set_name)(
373 OSyncPluginAdvancedOption *option,
374 const char *name);
375 void (*osync_plugin_advancedoption_set_displayname)(
376 OSyncPluginAdvancedOption *option,
377 const char *displayname);
378 void (*osync_plugin_advancedoption_set_type)(
379 OSyncPluginAdvancedOption *option,
380 OSyncPluginAdvancedOptionType type);
381 void (*osync_plugin_advancedoption_set_value)(
382 OSyncPluginAdvancedOption *option,
383 const char *value);
384 OSyncList* (*osync_plugin_config_get_resources)(
385 OSyncPluginConfig *config);
386 OSyncPluginResource* (*osync_plugin_resource_ref)(
387 OSyncPluginResource *resource);
388 OSyncPluginResource* (*osync_plugin_resource_new)(
389 OSyncError **error);
390 const char* (*osync_plugin_resource_get_name)(
391 OSyncPluginResource *resource);
392 void (*osync_plugin_resource_set_name)(
393 OSyncPluginResource *resource,
394 const char *name);
395 OSyncPluginAuthentication* (*osync_plugin_config_get_authentication)(
396 OSyncPluginConfig *config);
397 const char* (*osync_plugin_authentication_get_password)(
398 OSyncPluginAuthentication *auth);
399 OSyncPluginAuthentication* (*osync_plugin_authentication_new)(
400 OSyncError **error);
401 osync_bool (*osync_plugin_authentication_option_is_supported)(
402 OSyncPluginAuthentication *auth,
403 OSyncPluginAuthenticationOptionSupportedFlag flag);
404 void (*osync_plugin_authentication_unref)(
405 OSyncPluginAuthentication *auth);
406 void (*osync_plugin_config_set_authentication)(
407 OSyncPluginConfig *config,
408 OSyncPluginAuthentication *auth);
409 void (*osync_plugin_authentication_set_password)(
410 OSyncPluginAuthentication *auth,
411 const char *password);
412 const char* (*osync_plugin_authentication_get_username)(
413 OSyncPluginAuthentication *auth);
414 void (*osync_plugin_authentication_set_username)(
415 OSyncPluginAuthentication *auth,
416 const char *password);
417 void (*osync_group_set_objtype_enabled)(
418 OSyncGroup *group, const char *objtype,
419 osync_bool enabled);
421 // data pointers
422 vLateSmartPtr<OSyncGroupEnv, void(*)(OSyncGroupEnv*)> group_env;
423 vLateSmartPtr<OSyncFormatEnv, void(*)(OSyncFormatEnv*)> format_env;
424 vLateSmartPtr<OSyncPluginEnv, void(*)(OSyncPluginEnv*)> plugin_env;
426 TossError error;
427 Converter40 converter;
429 OpenSync40Private(OpenSync40 &api)
430 : error(this)
431 , converter(api)
435 // helper functions
436 std::string osync_error_print_stack_wrapper(OSyncError **error)
438 std::string rmsg;
439 char *msg = osync_error_print_stack(error);
440 if( msg ) {
441 rmsg = msg;
442 osync_free(msg);
444 else {
445 rmsg = "(NULL error msg)";
447 return rmsg;
451 class SyncConflict40Private : public SyncConflictPrivateBase
453 OpenSync40Private *m_priv;
454 OSyncEngine *m_engine;
455 OSyncMappingEngine *m_mapping;
456 OSyncList *m_changes;
458 public:
459 SyncConflict40Private(OpenSync40Private *priv,
460 OSyncEngine *engine, OSyncMappingEngine *mapping);
461 ~SyncConflict40Private();
463 virtual bool IsAbortSupported() const;
464 virtual bool IsIgnoreSupported() const;
465 virtual bool IsKeepNewerSupported() const;
467 virtual void Select(int change_id); // takes the id of SyncChange
468 virtual void Abort();
469 virtual void Duplicate();
470 virtual void Ignore();
471 virtual void KeepNewer();
473 void AppendChanges(std::vector<SyncChange> &list);
476 class SyncSummary40Private : public SyncSummaryPrivateBase
478 OpenSync40Private *m_priv;
479 OSyncEngine *m_engine;
481 public:
482 SyncSummary40Private(OpenSync40Private *priv, OSyncEngine *engine);
483 ~SyncSummary40Private();
485 virtual void Abort();
486 virtual void Continue();
488 // returns true if any member is dirty
489 bool AppendMembers(std::vector<SyncMemberSummary> &list);
492 class OS40PluginConfigPrivate
494 public:
495 OSyncMember *m_member;
496 OSyncPluginConfig *m_config;
498 OS40PluginConfigPrivate()
499 : m_member(0)
500 , m_config(0)
505 class OS40ConfigResourcePrivate
507 public:
508 OpenSync40Private *m_privapi;
509 OS40PluginConfigPrivate *m_parentpriv;
510 OSyncPluginResource *m_resource;
512 OS40ConfigResourcePrivate()
513 : m_privapi(0)
514 , m_parentpriv(0)
515 , m_resource(0)
520 struct CallbackBundle
522 OpenSync40Private *m_priv;
523 SyncStatus *m_status;
525 CallbackBundle(OpenSync40Private *priv, SyncStatus &status)
526 : m_priv(priv)
527 , m_status(&status)
532 void conflict_handler(OSyncEngine *, OSyncMappingEngine *, void *);
533 void entry_status(OSyncEngineChangeUpdate *, void *);
534 void mapping_status(OSyncEngineMappingUpdate *, void *);
535 void engine_status(OSyncEngineUpdate *, void *);
536 void member_status(OSyncEngineMemberUpdate *, void *);
537 void multiply_summary(OSyncEngine *, void *);
540 /////////////////////////////////////////////////////////////////////////////
541 // Static helper functions
543 static const char *OSyncChangeType2String(OSyncChangeType type)
545 switch (type) {
546 case OSYNC_CHANGE_TYPE_ADDED: return "ADDED";
547 case OSYNC_CHANGE_TYPE_UNMODIFIED: return "UNMODIFIED";
548 case OSYNC_CHANGE_TYPE_DELETED: return "DELETED";
549 case OSYNC_CHANGE_TYPE_MODIFIED: return "MODIFIED";
550 default:
551 case OSYNC_CHANGE_TYPE_UNKNOWN: return "?";
556 /////////////////////////////////////////////////////////////////////////////
557 // SyncConflict40Private member functions
559 SyncConflict40Private::SyncConflict40Private(OpenSync40Private *priv,
560 OSyncEngine *engine, OSyncMappingEngine *mapping)
561 : m_priv(priv)
562 , m_engine(engine)
563 , m_mapping(mapping)
564 , m_changes(0)
566 m_changes = m_priv->osync_mapping_engine_get_changes(m_mapping);
569 SyncConflict40Private::~SyncConflict40Private()
571 m_priv->osync_list_free(m_changes);
574 bool SyncConflict40Private::IsAbortSupported() const
576 return true;
579 bool SyncConflict40Private::IsIgnoreSupported() const
581 return m_priv->osync_mapping_engine_supports_ignore(m_mapping);
584 bool SyncConflict40Private::IsKeepNewerSupported() const
586 return m_priv->osync_mapping_engine_supports_use_latest(m_mapping);
589 void SyncConflict40Private::Select(int change_id)
591 OSyncList *c = m_priv->osync_list_nth(m_changes, change_id);
592 if( !c )
593 throw std::logic_error("Bad change_id");
595 OSyncChange *change = (OSyncChange *) c->data;
597 if( !m_priv->osync_engine_mapping_solve(m_engine, m_mapping,
598 change, m_priv->error) )
600 throw std::runtime_error(m_priv->error.GetErrorMsg());
604 void SyncConflict40Private::Abort()
606 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) ) {
607 ostringstream oss;
608 oss << "Problems while aborting: "
609 << m_priv->error.GetErrorMsg();
610 throw std::runtime_error(oss.str());
614 void SyncConflict40Private::Duplicate()
616 if( !m_priv->osync_engine_mapping_duplicate(m_engine, m_mapping, m_priv->error) )
617 throw std::runtime_error(m_priv->error.GetErrorMsg());
620 void SyncConflict40Private::Ignore()
622 if( !IsIgnoreSupported() )
623 throw std::logic_error("Ignore not supported, yet Ignore() called.");
625 if( !m_priv->osync_engine_mapping_ignore_conflict(m_engine, m_mapping,
626 m_priv->error) )
628 throw std::runtime_error(m_priv->error.GetErrorMsg());
632 void SyncConflict40Private::KeepNewer()
634 if( !IsKeepNewerSupported() )
635 throw std::logic_error("Keep Newer not supported, yet KeepNewer() called.");
637 if( !m_priv->osync_engine_mapping_use_latest(m_engine, m_mapping, m_priv->error) )
638 throw std::runtime_error(m_priv->error.GetErrorMsg());
641 void SyncConflict40Private::AppendChanges(std::vector<SyncChange> &list)
643 int i = 0;
644 for( OSyncList *c = m_changes; c; c = c->next, i++ ) {
645 OSyncChange *change = (OSyncChange *) c->data;
647 if( m_priv->osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_UNKNOWN ) {
648 OSyncMember *member = m_priv->osync_mapping_engine_change_find_member(m_mapping, change);
650 OSyncData *data = m_priv->osync_change_get_data(change);
652 SyncChange entry;
654 char *printable = m_priv->osync_data_get_printable(data, m_priv->error);
655 if( printable )
656 entry.printable_data = printable;
657 m_priv->osync_free(printable);
659 if( m_priv->error.IsSet() )
660 throw std::runtime_error(m_priv->error.GetErrorMsg());
662 entry.id = i;
663 entry.member_id = m_priv->osync_member_get_id(member);
664 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
665 entry.uid = m_priv->osync_change_get_uid(change);
667 // add to list
668 list.push_back(entry);
674 /////////////////////////////////////////////////////////////////////////////
675 // SyncSummary40Private member functions
677 SyncSummary40Private::SyncSummary40Private(OpenSync40Private *priv,
678 OSyncEngine *engine)
679 : m_priv(priv)
680 , m_engine(engine)
684 SyncSummary40Private::~SyncSummary40Private()
688 void SyncSummary40Private::Abort()
690 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) )
691 throw std::runtime_error(m_priv->error.GetErrorMsg());
694 void SyncSummary40Private::Continue()
696 if( !m_priv->osync_engine_continue(m_engine, m_priv->error) )
697 throw std::runtime_error(m_priv->error.GetErrorMsg());
700 bool SyncSummary40Private::AppendMembers(std::vector<SyncMemberSummary> &list)
702 SyncListHandle objengines(m_priv->osync_list_free);
703 objengines = m_priv->osync_engine_get_objengines(m_engine);
705 int i = 0;
706 bool dirty = false;
708 for( OSyncList *o = objengines.get(); o; o = o->next ) {
709 OSyncObjEngine *objengine = (OSyncObjEngine *) o->data;
715 SyncListHandle members(m_priv->osync_list_free);
716 members = m_priv->osync_obj_engine_get_members(objengine);
717 for( OSyncList *m = members.get(); m; m = m->next ) {
718 OSyncMember *member = (OSyncMember *) m->data;
720 // Fill in common summary data
721 SyncMemberSummary entry;
722 entry.id = i;
723 entry.objtype_name = m_priv->osync_obj_engine_get_objtype(objengine);
724 entry.member_id = m_priv->osync_member_get_id(member);
725 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
727 const OSyncList *mapping_entry_engines = m_priv->osync_obj_engine_get_mapping_entry_engines_of_member(objengine, member);
729 // Calculate summary counts
730 for( const OSyncList *e = mapping_entry_engines; e; e = e->next ) {
731 OSyncMappingEntryEngine *entry_engine = (OSyncMappingEntryEngine*) e->data;
733 if( !m_priv->osync_entry_engine_is_dirty(entry_engine) )
734 continue;
736 dirty = true;
738 OSyncChangeType type = m_priv->osync_entry_engine_get_changetype(entry_engine);
739 switch (type)
741 case OSYNC_CHANGE_TYPE_ADDED:
742 entry.added++;
743 break;
744 case OSYNC_CHANGE_TYPE_MODIFIED:
745 entry.modified++;
746 break;
747 case OSYNC_CHANGE_TYPE_DELETED:
748 entry.deleted++;
749 break;
750 default:
751 break;
755 // Add entry to list
756 list.push_back(entry);
761 return dirty;
765 /////////////////////////////////////////////////////////////////////////////
766 // Callback functions
768 void conflict_handler(OSyncEngine *engine, OSyncMappingEngine *mapping,
769 void *cbdata)
771 CallbackBundle *cb = (CallbackBundle*) cbdata;
773 try {
774 // build the SyncConflict object
775 SyncConflict40Private scp(cb->m_priv, engine, mapping);
776 SyncConflict conflict(scp);
778 // append all conflicting changes as vector objects in the same
779 // order as the opensync library mapping
780 scp.AppendChanges(conflict);
782 // call the status handler
783 cb->m_status->HandleConflict(conflict);
785 catch( std::exception &e ) {
786 cb->m_status->ReportError(
787 string("Conflict not resolved. ") + e.what());
789 catch( ... ) {
790 cb->m_status->ReportError(
791 "Unknown exception caught in conflict_handler()");
795 void entry_status(OSyncEngineChangeUpdate *status, void *cbdata)
797 CallbackBundle *cb = (CallbackBundle*) cbdata;
799 try {
800 ostringstream oss;
802 OSyncChange *change = cb->m_priv->osync_engine_change_update_get_change(status);
803 OSyncMember *member = cb->m_priv->osync_engine_change_update_get_member(status);
804 OSyncError *error = cb->m_priv->osync_engine_change_update_get_error(status);
806 const char *action = NULL;
807 const char *direction = NULL;
808 string msg;
809 bool error_event = false;
811 switch( cb->m_priv->osync_engine_change_update_get_event(status) )
813 case OSYNC_ENGINE_CHANGE_EVENT_READ:
814 action = "Received an entry";
815 direction = "from";
816 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
817 break;
819 case OSYNC_ENGINE_CHANGE_EVENT_WRITTEN:
820 action = "Sent an entry";
821 direction = "to";
822 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
823 break;
825 case OSYNC_ENGINE_CHANGE_EVENT_ERROR:
826 error_event = true;
827 action = "Error for entry";
828 direction = "and";
829 msg = cb->m_priv->osync_error_print_stack_wrapper(&(error));
830 break;
833 if( action ) {
834 oss << action << " "
835 << cb->m_priv->osync_change_get_uid(change)
836 << "("
837 << cb->m_priv->osync_objformat_get_name( cb->m_priv->osync_change_get_objformat(change))
838 << ") " << direction << " member "
839 << cb->m_priv->osync_member_get_id(member)
840 << " ("
841 << cb->m_priv->osync_member_get_pluginname(member)
842 << "): "
843 << msg;
845 // call the status handler
846 cb->m_status->EntryStatus(oss.str(), error_event);
849 catch( std::exception &e ) {
850 cb->m_status->ReportError(
851 string("entry_status error:") + e.what());
853 catch( ... ) {
854 cb->m_status->ReportError(
855 "Unknown exception caught in entry_status()");
859 void mapping_status(OSyncEngineMappingUpdate *status, void *cbdata)
861 CallbackBundle *cb = (CallbackBundle*) cbdata;
863 try {
864 OSyncError *error = cb->m_priv->osync_engine_mapping_update_get_error(status);
866 ostringstream oss;
867 bool error_event = false;
869 switch( cb->m_priv->osync_engine_mapping_update_get_event(status) )
871 case OSYNC_ENGINE_MAPPING_EVENT_SOLVED:
872 oss << "Mapping solved";
873 break;
875 case OSYNC_ENGINE_MAPPING_EVENT_ERROR:
876 error_event = true;
877 oss << "Mapping error: "
878 << cb->m_priv->osync_error_print_stack_wrapper(&(error));
879 break;
882 // call the status handler
883 if( oss.str().size() )
884 cb->m_status->MappingStatus(oss.str(), error_event);
886 catch( std::exception &e ) {
887 cb->m_status->ReportError(
888 string("mapping_status error: ") + e.what());
890 catch( ... ) {
891 cb->m_status->ReportError(
892 "Unknown exception caught in mapping_status()");
896 void engine_status(OSyncEngineUpdate *status, void *cbdata)
898 CallbackBundle *cb = (CallbackBundle*) cbdata;
900 try {
901 OSyncError *error = cb->m_priv->osync_engine_update_get_error(status);
903 ostringstream oss;
904 bool error_event = false;
905 bool slow_sync = false;
907 switch( cb->m_priv->osync_engine_update_get_event(status) )
909 case OSYNC_ENGINE_EVENT_CONNECTED:
910 oss << "All clients connected or error";
911 break;
912 case OSYNC_ENGINE_EVENT_CONNECT_DONE:
913 /* Not of interest for regular user. */
914 break;
915 case OSYNC_ENGINE_EVENT_READ:
916 oss << "All clients sent changes or error";
917 break;
918 case OSYNC_ENGINE_EVENT_MAPPED:
919 oss << "All changes got mapped";
920 break;
921 case OSYNC_ENGINE_EVENT_MULTIPLIED:
922 oss << "All changes got multiplied";
923 break;
924 case OSYNC_ENGINE_EVENT_PREPARED_WRITE:
925 oss << "All changes got prepared for write";
926 break;
927 case OSYNC_ENGINE_EVENT_PREPARED_MAP:
928 /* Not of interest for regular user. */
929 break;
930 case OSYNC_ENGINE_EVENT_WRITTEN:
931 oss << "All clients have written";
932 break;
933 case OSYNC_ENGINE_EVENT_DISCONNECTED:
934 oss << "All clients have disconnected";
935 break;
936 case OSYNC_ENGINE_EVENT_ERROR:
937 error_event = true;
938 oss << "The sync failed: " << cb->m_priv->osync_error_print_stack_wrapper(&(error));
939 break;
940 case OSYNC_ENGINE_EVENT_SUCCESSFUL:
941 oss << "The sync was successful";
942 break;
943 case OSYNC_ENGINE_EVENT_PREV_UNCLEAN:
944 oss << "The previous synchronization was unclean. Slow-syncing";
945 slow_sync = true;
946 break;
947 case OSYNC_ENGINE_EVENT_END_CONFLICTS:
948 oss << "All conflicts have been reported";
949 break;
950 case OSYNC_ENGINE_EVENT_SYNC_DONE:
951 oss << "All clients reported sync done";
952 break;
955 // call the status handler
956 if( oss.str().size() )
957 cb->m_status->EngineStatus(oss.str(),
958 error_event,
959 slow_sync);
961 catch( std::exception &e ) {
962 cb->m_status->ReportError(
963 string("engine_status error: ") + e.what());
965 catch( ... ) {
966 cb->m_status->ReportError(
967 "Unknown exception caught in engine_status()");
971 void member_status(OSyncEngineMemberUpdate *status, void *cbdata)
973 CallbackBundle *cb = (CallbackBundle*) cbdata;
975 try {
976 ostringstream oss;
977 bool error_event = false;
978 bool valid = true;
980 const char *objtype = cb->m_priv->osync_engine_member_update_get_objtype(status);
981 if( objtype == NULL )
982 oss << "Main sink";
983 else
984 oss << objtype << " sink";
987 OSyncMember *member = cb->m_priv->osync_engine_member_update_get_member(status);
989 oss << " of member "
990 << cb->m_priv->osync_member_get_id(member)
991 << " ("
992 << cb->m_priv->osync_member_get_pluginname(member)
993 << ")";
995 OSyncError *error = cb->m_priv->osync_engine_member_update_get_error(status);
997 switch( cb->m_priv->osync_engine_member_update_get_event(status) )
999 case OSYNC_ENGINE_MEMBER_EVENT_CONNECTED:
1000 oss << " just connected";
1001 break;
1002 case OSYNC_ENGINE_MEMBER_EVENT_CONNECT_DONE:
1003 // Special event - but not interesting for
1004 // the normal user.
1005 break;
1006 case OSYNC_ENGINE_MEMBER_EVENT_DISCONNECTED:
1007 oss << " just disconnected";
1008 break;
1009 case OSYNC_ENGINE_MEMBER_EVENT_READ:
1010 oss << " just sent all changes";
1011 break;
1012 case OSYNC_ENGINE_MEMBER_EVENT_WRITTEN:
1013 oss << " committed all changes";
1014 break;
1015 case OSYNC_ENGINE_MEMBER_EVENT_SYNC_DONE:
1016 oss << " reported sync done";
1017 break;
1018 case OSYNC_ENGINE_MEMBER_EVENT_DISCOVERED:
1019 oss << " discovered its objtypes";
1020 break;
1021 case OSYNC_ENGINE_MEMBER_EVENT_ERROR:
1022 oss << " had an error: "
1023 << cb->m_priv->osync_error_print_stack_wrapper(&error);
1024 error_event = true;
1025 break;
1026 default:
1027 valid = false;
1028 break;
1031 // call the status handler
1032 if( oss.str().size() && valid ) {
1033 cb->m_status->MemberStatus(
1034 cb->m_priv->osync_member_get_id(member),
1035 cb->m_priv->osync_member_get_pluginname(member),
1036 oss.str(), error_event);
1039 catch( std::exception &e ) {
1040 cb->m_status->ReportError(
1041 string("member_status error: ") + e.what());
1043 catch( ... ) {
1044 cb->m_status->ReportError(
1045 "Unknown exception caught in member_status()");
1049 void multiply_summary(OSyncEngine *engine, void *cbdata)
1051 CallbackBundle *cb = (CallbackBundle*) cbdata;
1053 try {
1054 // build the SyncSummary object
1055 SyncSummary40Private ssp(cb->m_priv, engine);
1056 SyncSummary summary(ssp);
1058 // append a summary for each objtype member
1059 if( ssp.AppendMembers(summary) ) {
1060 // call the status handler only if dirty
1061 cb->m_status->CheckSummary(summary);
1063 else {
1064 // nothing dirty, just continue
1065 summary.Continue();
1068 catch( std::exception &e ) {
1069 cb->m_status->ReportError(
1070 string("Error handling summary. ") + e.what());
1072 catch( ... ) {
1073 cb->m_status->ReportError(
1074 "Unknown exception caught in multiply_summary()");
1079 /////////////////////////////////////////////////////////////////////////////
1080 // OS40ConfigResource - public members
1082 OS40ConfigResource::OS40ConfigResource(const OS40PluginConfig &parent,
1083 void *resource,
1084 bool existing_resource)
1085 : m_priv( new OS40ConfigResourcePrivate )
1086 , m_exists(existing_resource)
1088 m_priv->m_privapi = parent.m_privapi;
1089 m_priv->m_parentpriv = parent.m_priv.get();
1090 m_priv->m_resource = (OSyncPluginResource*) resource;
1093 OS40ConfigResource::~OS40ConfigResource()
1095 // unref the resource, since we hold a copy
1096 m_priv->m_privapi->
1097 osync_plugin_resource_unref(m_priv->m_resource);
1098 delete m_priv;
1101 bool OS40ConfigResource::IsExistingResource() const
1103 return m_exists;
1106 // safe to call multiple times
1107 void OS40ConfigResource::AddResource()
1109 if( !IsExistingResource() ) {
1110 m_priv->m_privapi->
1111 osync_plugin_config_add_resource(
1112 m_priv->m_parentpriv->m_config,
1113 m_priv->m_resource);
1117 bool OS40ConfigResource::IsEnabled() const
1119 return m_priv->m_privapi->
1120 osync_plugin_resource_is_enabled(m_priv->m_resource);
1123 OS40ConfigResource& OS40ConfigResource::Enable(bool enabled)
1125 m_priv->m_privapi->osync_plugin_resource_enable(m_priv->m_resource,
1126 enabled);
1127 return *this;
1130 bool OS40ConfigResource::FindObjFormat(const std::string &objformat,
1131 std::string &config)
1133 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1134 sinks = m_priv->m_privapi->
1135 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1136 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1137 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1138 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1139 const char *cfg = m_priv->m_privapi->osync_objformat_sink_get_config(sink);
1140 if( cfg )
1141 config = cfg;
1142 else
1143 config.clear();
1144 return true;
1147 return false;
1150 OS40ConfigResource& OS40ConfigResource::SetObjFormat(const std::string &objformat,
1151 const std::string &config)
1153 // if it already exists, just set the config value
1154 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1155 sinks = m_priv->m_privapi->
1156 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1157 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1158 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1159 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1160 m_priv->m_privapi->osync_objformat_sink_set_config(sink, config.c_str());
1161 return *this;
1165 // if we get here, it doesn't exist, and we need to add it
1166 OSyncObjFormatSink *sink = m_priv->m_privapi->
1167 osync_objformat_sink_new(objformat.c_str(),
1168 m_priv->m_privapi->error);
1169 if( !sink )
1170 throw std::runtime_error(m_priv->m_privapi->error.GetErrorMsg());
1172 if( config.size() )
1173 m_priv->m_privapi->osync_objformat_sink_set_config(sink,
1174 config.c_str());
1175 m_priv->m_privapi->osync_plugin_resource_add_objformat_sink(
1176 m_priv->m_resource, sink);
1177 m_priv->m_privapi->osync_objformat_sink_unref(sink);
1178 return *this;
1181 std::string OS40ConfigResource::GetName() const
1183 string value;
1184 const char *pv = m_priv->m_privapi->
1185 osync_plugin_resource_get_name(m_priv->m_resource);
1186 if( pv )
1187 value = pv;
1188 return value;
1191 OS40ConfigResource& OS40ConfigResource::SetName(const std::string &name)
1193 m_priv->m_privapi->
1194 osync_plugin_resource_set_name(m_priv->m_resource, name.c_str());
1195 return *this;
1198 std::string OS40ConfigResource::GetPreferredFormat() const
1200 string value;
1201 const char *pv = m_priv->m_privapi->
1202 osync_plugin_resource_get_preferred_format(m_priv->m_resource);
1203 if( pv )
1204 value = pv;
1205 return value;
1208 OS40ConfigResource& OS40ConfigResource::SetPreferredFormat(const std::string &format)
1210 m_priv->m_privapi->
1211 osync_plugin_resource_set_preferred_format(m_priv->m_resource,
1212 format.c_str());
1213 return *this;
1216 std::string OS40ConfigResource::GetMime() const
1218 string value;
1219 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_mime(
1220 m_priv->m_resource);
1221 if( pv )
1222 value = pv;
1223 return value;
1226 OS40ConfigResource& OS40ConfigResource::SetMime(const std::string &mime)
1228 m_priv->m_privapi->osync_plugin_resource_set_mime(m_priv->m_resource,
1229 mime.c_str());
1230 return *this;
1233 std::string OS40ConfigResource::GetObjType() const
1235 string value;
1236 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_objtype(
1237 m_priv->m_resource);
1238 if( pv )
1239 value = pv;
1240 return value;
1243 OS40ConfigResource& OS40ConfigResource::SetObjType(const std::string &objtype)
1245 m_priv->m_privapi->osync_plugin_resource_set_objtype(m_priv->m_resource,
1246 objtype.c_str());
1247 return *this;
1250 std::string OS40ConfigResource::GetPath() const
1252 string value;
1253 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_path(
1254 m_priv->m_resource);
1255 if( pv )
1256 value = pv;
1257 return value;
1260 OS40ConfigResource& OS40ConfigResource::SetPath(const std::string &path)
1262 m_priv->m_privapi->osync_plugin_resource_set_path(m_priv->m_resource,
1263 path.c_str());
1264 return *this;
1267 std::string OS40ConfigResource::GetUrl() const
1269 string value;
1270 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_url(
1271 m_priv->m_resource);
1272 if( pv )
1273 value = pv;
1274 return value;
1277 OS40ConfigResource& OS40ConfigResource::SetUrl(const std::string &url)
1279 m_priv->m_privapi->osync_plugin_resource_set_url(m_priv->m_resource,
1280 url.c_str());
1281 return *this;
1285 /////////////////////////////////////////////////////////////////////////////
1286 // OS40PluginConfig - public members
1288 OS40PluginConfig::OS40PluginConfig(OpenSync40Private *privapi,
1289 void *member,
1290 void *config)
1291 : m_privapi(privapi)
1293 m_priv.reset( new OS40PluginConfigPrivate );
1294 m_priv->m_member = (OSyncMember*) member;
1295 m_priv->m_config = (OSyncPluginConfig*) config;
1298 std::string OS40PluginConfig::GetAdvanced(const std::string &name)
1300 const char *value = m_privapi->osync_plugin_config_get_advancedoption_value_by_name(m_priv->m_config, name.c_str());
1301 string val;
1302 if( value )
1303 val = value;
1304 return val;
1307 void OS40PluginConfig::SetAdvanced(const std::string &name,
1308 const std::string &display_name,
1309 const std::string &val)
1311 SetAdvanced(name, display_name, STRING_TYPE, val);
1314 void OS40PluginConfig::SetAdvanced(const std::string &name,
1315 const std::string &display_name,
1316 int val_type,
1317 const std::string &val)
1319 // find the first advanced option with this name
1320 SyncListHandle aos(m_privapi->osync_list_free);
1321 aos = m_privapi->osync_plugin_config_get_advancedoptions(m_priv->m_config);
1322 OSyncPluginAdvancedOption *option = 0;
1323 for( OSyncList *o = aos.get(); o; o = o->next ) {
1324 option = (OSyncPluginAdvancedOption*) o->data;
1326 if( name == m_privapi->osync_plugin_advancedoption_get_name(option) )
1327 break;
1330 if( option ) {
1331 // found existing option, set it with val
1332 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1334 else {
1335 // option with that name does not exist, so create it
1336 option = m_privapi->osync_plugin_advancedoption_new(m_privapi->error);
1337 if( !option )
1338 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1340 m_privapi->osync_plugin_advancedoption_set_name(option, name.c_str());
1341 m_privapi->osync_plugin_advancedoption_set_displayname(option, display_name.c_str());
1342 OSyncPluginAdvancedOptionType type;
1343 switch( val_type )
1345 case NONE_TYPE:
1346 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_NONE;
1347 break;
1348 case BOOL_TYPE:
1349 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_BOOL;
1350 break;
1351 case CHAR_TYPE:
1352 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_CHAR;
1353 break;
1354 case DOUBLE_TYPE:
1355 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_DOUBLE;
1356 break;
1357 case INT_TYPE:
1358 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_INT;
1359 break;
1360 case LONG_TYPE:
1361 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONG;
1362 break;
1363 case LONGLONG_TYPE:
1364 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONGLONG;
1365 break;
1366 case UINT_TYPE:
1367 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_UINT;
1368 break;
1369 case ULONG_TYPE:
1370 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONG;
1371 break;
1372 case ULONGLONG_TYPE:
1373 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONGLONG;
1374 break;
1375 case STRING_TYPE:
1376 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_STRING;
1377 break;
1378 default:
1379 throw std::logic_error("Bad type in SetAdvanced()");
1381 m_privapi->osync_plugin_advancedoption_set_type(option, type);
1382 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1383 m_privapi->osync_plugin_config_add_advancedoption(m_priv->m_config, option);
1384 m_privapi->osync_plugin_advancedoption_unref(option);
1388 OS40PluginConfig::OS40ConfigResourcePtr
1389 OS40PluginConfig::GetResource(const std::string &objtype)
1391 OS40ConfigResourcePtr ptr;
1393 // FIXME - get_resources() does not give us a copy, so don't use
1394 // the SyncListHandle here
1395 OSyncList *rs = m_privapi->osync_plugin_config_get_resources(m_priv->m_config);
1396 for( OSyncList *o = rs; o; o = o->next ) {
1397 OSyncPluginResource *res = (OSyncPluginResource*) o->data;
1398 if( objtype == m_privapi->osync_plugin_resource_get_objtype(res) ) {
1399 // bump the resource count, since OS40ConfigResource
1400 // will unref it in the destructor
1401 m_privapi->osync_plugin_resource_ref(res);
1402 ptr.reset( new OS40ConfigResource(*this, res, true) );
1403 return ptr;
1407 // this res has a ref bump already, no ref() needed like it is above
1408 OSyncPluginResource *res = m_privapi->osync_plugin_resource_new(m_privapi->error);
1409 if( !res )
1410 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1411 ptr.reset( new OS40ConfigResource(*this, res, false) );
1412 // we search by objtype name, so make sure this is set in
1413 // the new object
1414 ptr->SetObjType(objtype);
1415 return ptr;
1418 std::string OS40PluginConfig::GetUsername() const
1420 string username;
1422 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1423 if( !auth )
1424 return username;
1426 const char *un = m_privapi->osync_plugin_authentication_get_username(auth);
1427 if( !un )
1428 return username;
1430 username = un;
1431 return username;
1434 void OS40PluginConfig::SetUsername(const std::string &username)
1436 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1437 if( !auth ) {
1438 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1439 if( !auth )
1440 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1441 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_USERNAME) ) {
1442 m_privapi->osync_plugin_authentication_unref(auth);
1443 throw std::runtime_error("Username (authentication parameter) is not supported in plugin!");
1446 // all looks ok, add it to the config
1447 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1448 // unref our copy, since the config now has it...
1449 // our auth pointer will still be valid since config holds it
1450 m_privapi->osync_plugin_authentication_unref(auth);
1453 m_privapi->osync_plugin_authentication_set_username(auth, username.c_str());
1456 std::string OS40PluginConfig::GetPassword() const
1458 string password;
1460 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1461 if( !auth )
1462 return password;
1464 const char *pass = m_privapi->osync_plugin_authentication_get_password(auth);
1465 if( !pass )
1466 return password;
1468 password = pass;
1469 return password;
1472 void OS40PluginConfig::SetPassword(const std::string &password)
1474 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1475 if( !auth ) {
1476 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1477 if( !auth )
1478 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1479 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_PASSWORD) ) {
1480 m_privapi->osync_plugin_authentication_unref(auth);
1481 throw std::runtime_error("Password authentication is not supported in plugin!");
1484 // all looks ok, add it to the config
1485 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1486 // unref our copy, since the config now has it...
1487 // our auth pointer will still be valid since config holds it
1488 m_privapi->osync_plugin_authentication_unref(auth);
1491 m_privapi->osync_plugin_authentication_set_password(auth, password.c_str());
1494 void OS40PluginConfig::Save()
1496 if( !m_privapi->osync_member_save(m_priv->m_member, m_privapi->error) )
1497 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1501 /////////////////////////////////////////////////////////////////////////////
1502 // OpenSync40 (API override class) - public members
1504 OpenSync40::OpenSync40()
1506 // due to bugs in the way opensync 0.22 loads its modules,
1507 // (i.e. it doesn't load the plugins using RTLD_LOCAL, and
1508 // so libopensync.so.0 is loaded and pollutes the symbol table,
1509 // causing symbol clashes) we need to make sure that
1510 // OpenSync40 is only loaded first... if OpenSync22 was
1511 // loaded first, we will fail, so error out
1512 if( OpenSync22::SymbolsLoaded() )
1513 throw std::logic_error("Always load OpenSync40 before OpenSync22, to avoid symbol table conflicts.");
1515 if( !Open("libopensync.so.1") )
1516 throw DlError("Can't dlopen libopensync.so.1");
1518 // store locally in case of constructor exception in LoadSym
1519 std::auto_ptr<OpenSync40Private> p(new OpenSync40Private(*this));
1521 // load all required symbols...
1522 // we don't need to use try/catch here, since the base
1523 // class destructor will clean up for us if LoadSym() throws
1524 LoadSym(p->osync_get_version, "osync_get_version");
1525 LoadSym(p->osync_error_print, "osync_error_print");
1526 LoadSym(p->osync_error_print_stack, "osync_error_print_stack");
1527 LoadSym(p->osync_error_is_set, "osync_error_is_set");
1528 LoadSym(p->osync_error_unref, "osync_error_unref");
1529 LoadSym(p->osync_group_env_new, "osync_group_env_new");
1530 LoadSym(p->osync_format_env_new, "osync_format_env_new");
1531 LoadSym(p->osync_plugin_env_new, "osync_plugin_env_new");
1532 LoadSym(p->osync_group_env_unref, "osync_group_env_unref");
1533 LoadSym(p->osync_format_env_unref, "osync_format_env_unref");
1534 LoadSym(p->osync_plugin_env_unref, "osync_plugin_env_unref");
1535 LoadSym(p->osync_plugin_env_load, "osync_plugin_env_load");
1536 LoadSym(p->osync_plugin_env_get_plugins,"osync_plugin_env_get_plugins");
1537 LoadSym(p->osync_plugin_get_name, "osync_plugin_get_name");
1538 LoadSym(p->osync_list_free, "osync_list_free");
1539 LoadSym(p->osync_group_env_load_groups, "osync_group_env_load_groups");
1540 LoadSym(p->osync_format_env_load_plugins,
1541 "osync_format_env_load_plugins");
1542 LoadSym(p->osync_group_env_get_groups, "osync_group_env_get_groups");
1543 LoadSym(p->osync_group_get_name, "osync_group_get_name");
1544 LoadSym(p->osync_group_env_find_group, "osync_group_env_find_group");
1545 LoadSym(p->osync_group_get_members, "osync_group_get_members");
1546 LoadSym(p->osync_member_get_name, "osync_member_get_name");
1547 LoadSym(p->osync_member_get_id, "osync_member_get_id");
1548 LoadSym(p->osync_member_get_pluginname, "osync_member_get_pluginname");
1549 LoadSym(p->osync_format_env_get_objformats,
1550 "osync_format_env_get_objformats");
1551 LoadSym(p->osync_objformat_get_name, "osync_objformat_get_name");
1552 LoadSym(p->osync_objformat_get_objtype, "osync_objformat_get_objtype");
1553 LoadSym(p->osync_group_new, "osync_group_new");
1554 LoadSym(p->osync_group_unref, "osync_group_unref");
1555 LoadSym(p->osync_group_set_name, "osync_group_set_name");
1556 LoadSym(p->osync_group_env_add_group, "osync_group_env_add_group");
1557 LoadSym(p->osync_group_save, "osync_group_save");
1558 LoadSym(p->osync_group_delete, "osync_group_delete");
1559 LoadSym(p->osync_group_env_remove_group,"osync_group_env_remove_group");
1560 LoadSym(p->osync_plugin_env_find_plugin,"osync_plugin_env_find_plugin");
1561 LoadSym(p->osync_member_unref, "osync_member_unref");
1562 LoadSym(p->osync_member_new, "osync_member_new");
1563 LoadSym(p->osync_group_add_member, "osync_group_add_member");
1564 LoadSym(p->osync_member_set_pluginname, "osync_member_set_pluginname");
1565 LoadSym(p->osync_member_set_name, "osync_member_set_name");
1566 LoadSym(p->osync_member_save, "osync_member_save");
1567 LoadSym(p->osync_group_find_member, "osync_group_find_member");
1568 LoadSym(p->osync_member_delete, "osync_member_delete");
1569 LoadSym(p->osync_group_remove_member, "osync_group_remove_member");
1570 LoadSym(p->osync_plugin_config_new, "osync_plugin_config_new");
1571 LoadSym(p->osync_plugin_config_file_load,
1572 "osync_plugin_config_file_load");
1573 LoadSym(p->osync_member_set_config, "osync_member_set_config");
1574 LoadSym(p->osync_member_get_config_or_default,
1575 "osync_member_get_config_or_default");
1576 LoadSym(p->osync_plugin_config_file_save,
1577 "osync_plugin_config_file_save");
1578 LoadSym(p->osync_plugin_get_config_type,"osync_plugin_get_config_type");
1579 LoadSym(p->osync_engine_new, "osync_engine_new");
1580 LoadSym(p->osync_engine_unref, "osync_engine_unref");
1581 LoadSym(p->osync_engine_discover_and_block,
1582 "osync_engine_discover_and_block");
1583 LoadSym(p->osync_member_get_objtypes, "osync_member_get_objtypes");
1584 LoadSym(p->osync_list_length, "osync_list_length");
1585 LoadSym(p->osync_error_set, "osync_error_set");
1586 LoadSym(p->osync_engine_finalize, "osync_engine_finalize");
1587 LoadSym(p->osync_mapping_engine_get_changes,
1588 "osync_mapping_engine_get_changes");
1589 LoadSym(p->osync_mapping_engine_supports_ignore,
1590 "osync_mapping_engine_supports_ignore");
1591 LoadSym(p->osync_mapping_engine_supports_use_latest,
1592 "osync_mapping_engine_supports_use_latest");
1593 LoadSym(p->osync_list_nth, "osync_list_nth");
1594 LoadSym(p->osync_engine_mapping_solve, "osync_engine_mapping_solve");
1595 LoadSym(p->osync_engine_abort, "osync_engine_abort");
1596 LoadSym(p->osync_engine_mapping_duplicate,
1597 "osync_engine_mapping_duplicate");
1598 LoadSym(p->osync_engine_mapping_ignore_conflict,
1599 "osync_engine_mapping_ignore_conflict");
1600 LoadSym(p->osync_engine_mapping_use_latest,
1601 "osync_engine_mapping_use_latest");
1602 LoadSym(p->osync_change_get_changetype, "osync_change_get_changetype");
1603 LoadSym(p->osync_mapping_engine_change_find_member,
1604 "osync_mapping_engine_change_find_member");
1605 LoadSym(p->osync_change_get_data, "osync_change_get_data");
1606 LoadSym(p->osync_data_get_printable, "osync_data_get_printable");
1607 LoadSym(p->osync_free, "osync_free");
1608 LoadSym(p->osync_change_get_uid, "osync_change_get_uid");
1609 LoadSym(p->osync_engine_continue, "osync_engine_continue");
1610 LoadSym(p->osync_engine_get_objengines, "osync_engine_get_objengines");
1611 LoadSym(p->osync_obj_engine_get_members,
1612 "osync_obj_engine_get_members");
1613 LoadSym(p->osync_obj_engine_get_objtype,
1614 "osync_obj_engine_get_objtype");
1615 LoadSym(p->osync_obj_engine_get_mapping_entry_engines_of_member,
1616 "osync_obj_engine_get_mapping_entry_engines_of_member");
1617 LoadSym(p->osync_entry_engine_is_dirty,"osync_entry_engine_is_dirty");
1618 LoadSym(p->osync_entry_engine_get_changetype,
1619 "osync_entry_engine_get_changetype");
1620 LoadSym(p->osync_engine_change_update_get_change,
1621 "osync_engine_change_update_get_change");
1622 LoadSym(p->osync_engine_change_update_get_member,
1623 "osync_engine_change_update_get_member");
1624 LoadSym(p->osync_engine_change_update_get_error,
1625 "osync_engine_change_update_get_error");
1626 LoadSym(p->osync_engine_change_update_get_event,
1627 "osync_engine_change_update_get_event");
1628 LoadSym(p->osync_change_get_objformat, "osync_change_get_objformat");
1629 LoadSym(p->osync_engine_mapping_update_get_error,
1630 "osync_engine_mapping_update_get_error");
1631 LoadSym(p->osync_engine_update_get_error,
1632 "osync_engine_update_get_error");
1633 LoadSym(p->osync_engine_update_get_event,
1634 "osync_engine_update_get_event");
1635 LoadSym(p->osync_engine_member_update_get_objtype,
1636 "osync_engine_member_update_get_objtype");
1637 LoadSym(p->osync_engine_member_update_get_member,
1638 "osync_engine_member_update_get_member");
1639 LoadSym(p->osync_engine_member_update_get_error,
1640 "osync_engine_member_update_get_error");
1641 LoadSym(p->osync_engine_member_update_get_event,
1642 "osync_engine_member_update_get_event");
1643 LoadSym(p->osync_engine_set_conflict_callback,
1644 "osync_engine_set_conflict_callback");
1645 LoadSym(p->osync_engine_set_changestatus_callback,
1646 "osync_engine_set_changestatus_callback");
1647 LoadSym(p->osync_engine_set_mappingstatus_callback,
1648 "osync_engine_set_mappingstatus_callback");
1649 LoadSym(p->osync_engine_set_enginestatus_callback,
1650 "osync_engine_set_enginestatus_callback");
1651 LoadSym(p->osync_engine_set_memberstatus_callback,
1652 "osync_engine_set_memberstatus_callback");
1653 LoadSym(p->osync_engine_set_multiply_callback,
1654 "osync_engine_set_multiply_callback");
1655 LoadSym(p->osync_engine_initialize, "osync_engine_initialize");
1656 LoadSym(p->osync_engine_synchronize_and_block,
1657 "osync_engine_synchronize_and_block");
1658 LoadSym(p->osync_engine_mapping_update_get_event,
1659 "osync_engine_mapping_update_get_event");
1660 LoadSym(p->osync_plugin_resource_unref,
1661 "osync_plugin_resource_unref");
1662 LoadSym(p->osync_plugin_config_add_resource,
1663 "osync_plugin_config_add_resource");
1664 LoadSym(p->osync_plugin_resource_is_enabled,
1665 "osync_plugin_resource_is_enabled");
1666 LoadSym(p->osync_plugin_resource_enable,
1667 "osync_plugin_resource_enable");
1668 LoadSym(p->osync_plugin_resource_get_objformat_sinks,
1669 "osync_plugin_resource_get_objformat_sinks");
1670 LoadSym(p->osync_objformat_sink_get_objformat,
1671 "osync_objformat_sink_get_objformat");
1672 LoadSym(p->osync_objformat_sink_get_config,
1673 "osync_objformat_sink_get_config");
1674 LoadSym(p->osync_objformat_sink_set_config,
1675 "osync_objformat_sink_set_config");
1676 LoadSym(p->osync_objformat_sink_new,
1677 "osync_objformat_sink_new");
1678 LoadSym(p->osync_plugin_resource_add_objformat_sink,
1679 "osync_plugin_resource_add_objformat_sink");
1680 LoadSym(p->osync_objformat_sink_unref,
1681 "osync_objformat_sink_unref");
1682 LoadSym(p->osync_plugin_resource_get_preferred_format,
1683 "osync_plugin_resource_get_preferred_format");
1684 LoadSym(p->osync_plugin_resource_set_preferred_format,
1685 "osync_plugin_resource_set_preferred_format");
1686 LoadSym(p->osync_plugin_resource_get_mime,
1687 "osync_plugin_resource_get_mime");
1688 LoadSym(p->osync_plugin_resource_set_mime,
1689 "osync_plugin_resource_set_mime");
1690 LoadSym(p->osync_plugin_resource_get_objtype,
1691 "osync_plugin_resource_get_objtype");
1692 LoadSym(p->osync_plugin_resource_set_objtype,
1693 "osync_plugin_resource_set_objtype");
1694 LoadSym(p->osync_plugin_resource_get_path,
1695 "osync_plugin_resource_get_path");
1696 LoadSym(p->osync_plugin_resource_set_path,
1697 "osync_plugin_resource_set_path");
1698 LoadSym(p->osync_plugin_resource_get_url,
1699 "osync_plugin_resource_get_url");
1700 LoadSym(p->osync_plugin_resource_set_url,
1701 "osync_plugin_resource_set_url");
1702 LoadSym(p->osync_plugin_config_get_advancedoption_value_by_name,
1703 "osync_plugin_config_get_advancedoption_value_by_name");
1704 LoadSym(p->osync_plugin_config_get_advancedoptions,
1705 "osync_plugin_config_get_advancedoptions");
1706 LoadSym(p->osync_plugin_config_add_advancedoption,
1707 "osync_plugin_config_add_advancedoption");
1708 LoadSym(p->osync_plugin_advancedoption_new,
1709 "osync_plugin_advancedoption_new");
1710 LoadSym(p->osync_plugin_advancedoption_unref,
1711 "osync_plugin_advancedoption_unref");
1712 LoadSym(p->osync_plugin_advancedoption_get_name,
1713 "osync_plugin_advancedoption_get_name");
1714 LoadSym(p->osync_plugin_advancedoption_set_name,
1715 "osync_plugin_advancedoption_set_name");
1716 LoadSym(p->osync_plugin_advancedoption_set_displayname,
1717 "osync_plugin_advancedoption_set_displayname");
1718 LoadSym(p->osync_plugin_advancedoption_set_type,
1719 "osync_plugin_advancedoption_set_type");
1720 LoadSym(p->osync_plugin_advancedoption_set_value,
1721 "osync_plugin_advancedoption_set_value");
1722 LoadSym(p->osync_plugin_config_get_resources,
1723 "osync_plugin_config_get_resources");
1724 LoadSym(p->osync_plugin_resource_ref,
1725 "osync_plugin_resource_ref");
1726 LoadSym(p->osync_plugin_resource_new,
1727 "osync_plugin_resource_new");
1728 LoadSym(p->osync_plugin_resource_get_name,
1729 "osync_plugin_resource_get_name");
1730 LoadSym(p->osync_plugin_resource_set_name,
1731 "osync_plugin_resource_set_name");
1732 LoadSym(p->osync_plugin_config_get_authentication,
1733 "osync_plugin_config_get_authentication");
1734 LoadSym(p->osync_plugin_authentication_get_password,
1735 "osync_plugin_authentication_get_password");
1736 LoadSym(p->osync_plugin_authentication_new,
1737 "osync_plugin_authentication_new");
1738 LoadSym(p->osync_plugin_authentication_option_is_supported,
1739 "osync_plugin_authentication_option_is_supported");
1740 LoadSym(p->osync_plugin_authentication_unref,
1741 "osync_plugin_authentication_unref");
1742 LoadSym(p->osync_plugin_config_set_authentication,
1743 "osync_plugin_config_set_authentication");
1744 LoadSym(p->osync_plugin_authentication_set_password,
1745 "osync_plugin_authentication_set_password");
1746 LoadSym(p->osync_plugin_authentication_get_username,
1747 "osync_plugin_authentication_get_username");
1748 LoadSym(p->osync_plugin_authentication_set_username,
1749 "osync_plugin_authentication_set_username");
1750 LoadSym(p->osync_group_set_objtype_enabled,
1751 "osync_group_set_objtype_enabled");
1753 // fixup free pointers
1754 p->group_env.SetFreeFunc(p->osync_group_env_unref);
1755 p->format_env.SetFreeFunc(p->osync_format_env_unref);
1756 p->plugin_env.SetFreeFunc(p->osync_plugin_env_unref);
1758 // setup opensync support environment
1759 SetupEnvironment(p.get());
1761 // this pointer is ours now
1762 m_priv = p.release();
1765 OpenSync40::~OpenSync40()
1767 delete m_priv;
1768 m_priv = 0;
1771 void OpenSync40::SetupEnvironment(OpenSync40Private *p)
1773 // allocate group, format, and env
1774 p->group_env = p->osync_group_env_new(p->error);
1775 if( !p->group_env.get() )
1776 throw std::runtime_error(p->error.GetErrorMsg());
1778 p->format_env = p->osync_format_env_new(p->error);
1779 if( !p->format_env.get() )
1780 throw std::runtime_error(p->error.GetErrorMsg());
1782 p->plugin_env = p->osync_plugin_env_new(p->error);
1783 if( !p->plugin_env.get() )
1784 throw std::runtime_error(p->error.GetErrorMsg());
1786 // load group, format, and env
1787 if( !p->osync_group_env_load_groups(p->group_env.get(), NULL, p->error) ||
1788 !p->osync_format_env_load_plugins(p->format_env.get(), NULL, p->error) ||
1789 !p->osync_plugin_env_load(p->plugin_env.get(), NULL, p->error) )
1790 throw std::runtime_error(p->error.GetErrorMsg());
1793 const char* OpenSync40::GetVersion() const
1795 return m_priv->osync_get_version();
1798 const char* OpenSync40::GetEngineName() const
1800 return "0.40";
1803 void OpenSync40::GetPluginNames(string_list_type &plugins)
1805 // start fresh
1806 plugins.clear();
1808 OSyncPlugin *plugin;
1809 OSyncList *plugin_list, *p;
1811 plugin_list = m_priv->osync_plugin_env_get_plugins(m_priv->plugin_env.get());
1812 for( p = plugin_list; p; p = p->next ) {
1813 plugin = (OSyncPlugin *) p->data;
1814 plugins.push_back(m_priv->osync_plugin_get_name(plugin));
1817 m_priv->osync_list_free(plugin_list);
1820 void OpenSync40::GetFormats(format_list_type &formats)
1822 // start fresh
1823 formats.clear();
1825 OSyncList *o, *list = m_priv->osync_format_env_get_objformats(m_priv->format_env.get());
1827 for( o = list; o; o = o->next ) {
1828 OSyncObjFormat *format = (OSyncObjFormat *) o->data;
1830 Format new_format;
1831 new_format.name = m_priv->osync_objformat_get_name(format);
1832 new_format.object_type = m_priv->osync_objformat_get_objtype(format);
1834 formats.push_back(new_format);
1837 m_priv->osync_list_free(list);
1840 void OpenSync40::GetGroupNames(string_list_type &groups)
1842 // start fresh
1843 groups.clear();
1845 OSyncGroup *group;
1846 OSyncList *g, *group_list = m_priv->osync_group_env_get_groups(m_priv->group_env.get());
1848 for( g = group_list; g; g = g->next ) {
1849 group = (OSyncGroup *) g->data;
1850 groups.push_back(m_priv->osync_group_get_name(group));
1853 m_priv->osync_list_free(group_list);
1856 void OpenSync40::GetMembers(const std::string &group_name,
1857 member_list_type &members)
1859 // start fresh
1860 members.clear();
1862 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1863 if( !group ) {
1864 ostringstream oss;
1865 oss << "GetMembers: Unable to find group with name: " << group_name;
1866 throw std::runtime_error(oss.str());
1869 OSyncList *member_list = m_priv->osync_group_get_members(group);
1870 for( OSyncList *m = member_list; m; m = m->next ) {
1871 Member new_member;
1872 OSyncMember *member = (OSyncMember *) m->data;
1873 const char *membername = m_priv->osync_member_get_name(member);
1874 if (membername) {
1875 new_member.friendly_name = membername;
1878 new_member.group_name = group_name;
1879 new_member.id = m_priv->osync_member_get_id(member);
1880 new_member.plugin_name = m_priv->osync_member_get_pluginname(member);
1882 // add to member list
1883 members.push_back(new_member);
1886 // cleanup
1887 m_priv->osync_list_free(member_list);
1890 void OpenSync40::AddGroup(const std::string &group_name)
1892 OSyncGroup *group = m_priv->osync_group_new(m_priv->error);
1893 if( !group )
1894 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1896 m_priv->osync_group_set_name(group, group_name.c_str());
1897 if( !m_priv->osync_group_env_add_group(m_priv->group_env.get(), group, m_priv->error) ) {
1898 m_priv->osync_group_unref(group);
1899 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1902 if( !m_priv->osync_group_save(group, m_priv->error) ) {
1903 m_priv->osync_group_unref(group);
1904 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1907 m_priv->osync_group_unref(group);
1910 void OpenSync40::DeleteGroup(const std::string &group_name)
1912 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1913 if( !group )
1914 throw std::runtime_error("DeleteGroup(): Group not found: " + group_name);
1916 if( !m_priv->osync_group_delete(group, m_priv->error) )
1917 throw std::runtime_error("DeleteGroup(): " + m_priv->error.GetErrorMsg());
1919 m_priv->osync_group_env_remove_group(m_priv->group_env.get(), group);
1922 Converter& OpenSync40::GetConverter()
1924 return m_priv->converter;
1927 long OpenSync40::AddMember(const std::string &group_name,
1928 const std::string &plugin_name,
1929 const std::string &member_name)
1931 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1932 if( !group )
1933 throw std::runtime_error("AddMember(): Group not found: " + group_name);
1935 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), plugin_name.c_str());
1936 if( !plugin )
1937 throw std::runtime_error("AddMember(): Plugin not found: " + plugin_name);
1939 vLateSmartPtr<OSyncMember, void(*)(OSyncMember*)> mptr(m_priv->osync_member_unref);
1940 mptr = m_priv->osync_member_new(m_priv->error);
1941 if( !mptr.get() )
1942 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1944 m_priv->osync_group_add_member(group, mptr.get());
1945 m_priv->osync_member_set_pluginname(mptr.get(), plugin_name.c_str());
1947 if( member_name.size() )
1948 m_priv->osync_member_set_name(mptr.get(), member_name.c_str());
1950 if( !m_priv->osync_member_save(mptr.get(), m_priv->error) )
1951 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1953 return m_priv->osync_member_get_id(mptr.get());
1956 void OpenSync40::DeleteMember(const std::string &group_name, long member_id)
1958 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1959 if( !group )
1960 throw std::runtime_error("DeleteMember(): Group not found: " + group_name);
1962 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1963 if( !member ) {
1964 ostringstream oss;
1965 oss << "DeleteMember(): Member " << member_id << " not found.";
1966 throw std::runtime_error(oss.str());
1969 if( !m_priv->osync_member_delete(member, m_priv->error) )
1970 throw std::runtime_error("DeleteMember(): " + m_priv->error.GetErrorMsg());
1972 m_priv->osync_group_remove_member(group, member);
1975 void OpenSync40::DeleteMember(const std::string &group_name,
1976 const std::string &plugin_name)
1978 member_list_type mlist;
1979 GetMembers(group_name, mlist);
1980 Member *member = mlist.Find(plugin_name.c_str());
1981 if( !member )
1982 throw std::runtime_error("DeleteMember(): Member not found: " + plugin_name);
1984 DeleteMember(group_name, member->id);
1987 bool OpenSync40::IsConfigurable(const std::string &group_name,
1988 long member_id)
1990 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1991 if( !group )
1992 throw std::runtime_error("IsConfigurable(): Group not found: " + group_name);
1994 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1995 if( !member ) {
1996 ostringstream oss;
1997 oss << "IsConfigurable(): Member " << member_id << " not found.";
1998 throw std::runtime_error(oss.str());
2001 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2002 if( !plugin )
2003 throw std::runtime_error(string("IsConfigurable(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2006 OSyncPluginConfigurationType type = m_priv->osync_plugin_get_config_type(plugin);
2007 return type != OSYNC_PLUGIN_NO_CONFIGURATION;
2010 std::string OpenSync40::GetConfiguration(const std::string &group_name,
2011 long member_id)
2013 if( !IsConfigurable(group_name, member_id) ) {
2014 ostringstream oss;
2015 oss << "GetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2016 throw std::runtime_error(oss.str());
2019 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2020 if( !group )
2021 throw std::runtime_error("GetConfiguration(): Group not found: " + group_name);
2023 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2024 if( !member ) {
2025 ostringstream oss;
2026 oss << "GetConfiguration(): Member " << member_id << " not found.";
2027 throw std::runtime_error(oss.str());
2030 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2031 if( !plugin )
2032 throw std::runtime_error(string("GetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2035 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2036 if( !config )
2037 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2039 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2040 // functions, and then load that from the file again, and
2041 // return that string as the configuratin.
2043 TempDir tempdir("opensyncapi");
2045 string filename = tempdir.GetNewFilename();
2047 if( !m_priv->osync_plugin_config_file_save(config, filename.c_str(), m_priv->error) )
2048 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2050 ifstream in(filename.c_str());
2051 string config_data;
2052 char buf[4096];
2053 while( in ) {
2054 in.read(buf, sizeof(buf));
2055 config_data.append(buf, in.gcount());
2058 return config_data;
2061 OS40PluginConfig OpenSync40::GetConfigurationObj(const std::string &group_name,
2062 long member_id)
2064 if( !IsConfigurable(group_name, member_id) ) {
2065 ostringstream oss;
2066 oss << "GetConfigurationObj(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2067 throw std::runtime_error(oss.str());
2070 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2071 if( !group )
2072 throw std::runtime_error("GetConfigurationObj(): Group not found: " + group_name);
2074 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2075 if( !member ) {
2076 ostringstream oss;
2077 oss << "GetConfigurationObj(): Member " << member_id << " not found.";
2078 throw std::runtime_error(oss.str());
2081 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2082 if( !plugin )
2083 throw std::runtime_error(string("GetConfigurationObj(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2086 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2087 if( !config )
2088 throw std::runtime_error("GetConfigurationObj(): " + m_priv->error.GetErrorMsg());
2090 return OS40PluginConfig(m_priv, member, config);
2093 void OpenSync40::SetConfiguration(const std::string &group_name,
2094 long member_id,
2095 const std::string &config_data)
2097 if( !IsConfigurable(group_name, member_id) ) {
2098 ostringstream oss;
2099 oss << "SetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2100 throw std::runtime_error(oss.str());
2103 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2104 if( !group )
2105 throw std::runtime_error("SetConfiguration(): Group not found: " + group_name);
2107 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2108 if( !member ) {
2109 ostringstream oss;
2110 oss << "SetConfiguration(): Member " << member_id << " not found.";
2111 throw std::runtime_error(oss.str());
2114 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2115 if( !plugin )
2116 throw std::runtime_error(string("SetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2119 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2120 // functions, and then load that from the file again, and
2121 // return that string as the configuratin.
2123 TempDir tempdir("opensyncapi");
2125 string filename = tempdir.GetNewFilename();
2127 // write config data to file
2129 ofstream out(filename.c_str());
2130 out << config_data;
2133 // load brand new config from file
2134 // if a new config object isn't created here, the loaded config
2135 // will be added to the existing config
2136 OSyncPluginConfig *new_config = m_priv->osync_plugin_config_new(m_priv->error);
2137 if( !m_priv->osync_plugin_config_file_load(new_config, filename.c_str(), m_priv->error) )
2138 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2140 m_priv->osync_member_set_config(member, new_config);
2142 if( !m_priv->osync_member_save(member, m_priv->error))
2143 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2146 void OpenSync40::Discover(const std::string &group_name)
2148 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2149 if( !group )
2150 throw std::runtime_error("Discover(): Group not found: " + group_name);
2152 EngineHandle engine(m_priv->osync_engine_unref);
2153 engine = m_priv->osync_engine_new(group, m_priv->error);
2154 if( !engine.get() )
2155 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2157 SyncListHandle members(m_priv->osync_list_free);
2158 members = m_priv->osync_group_get_members(group);
2159 OSyncList *m = NULL;
2160 for( m = members.get(); m; m = m->next ) {
2161 OSyncMember *member = (OSyncMember *) m->data;
2163 /* Discover the objtypes for the members */
2164 if( !m_priv->osync_engine_discover_and_block(engine.get(), member, m_priv->error))
2165 break;
2167 SyncListHandle objtypes(m_priv->osync_list_free);
2168 objtypes = m_priv->osync_member_get_objtypes(member);
2169 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2170 m_priv->osync_error_set(m_priv->error, OSYNC_ERROR_GENERIC, "discover failed: no objtypes returned");
2171 break;
2174 if( !m_priv->osync_member_save(member, m_priv->error) )
2175 break;
2178 // check for error
2179 if( m ) {
2180 m_priv->osync_engine_finalize(engine.get(), m_priv->error);
2181 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2185 void OpenSync40::Sync(const std::string &group_name,
2186 SyncStatus &status_callback,
2187 Config::pst_type sync_types)
2189 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2190 if( !group )
2191 throw std::runtime_error("Sync(): Group not found: " + group_name);
2193 // enable/disable each objtype, as per sync_types
2194 if( !(sync_types & PST_DO_NOT_SET) ) {
2195 cerr << "enabling objtypes: " << sync_types << endl;
2196 m_priv->osync_group_set_objtype_enabled(group, "contact",
2197 (sync_types & PST_CONTACTS) ? TRUE : FALSE);
2198 m_priv->osync_group_set_objtype_enabled(group, "event",
2199 (sync_types & PST_EVENTS) ? TRUE : FALSE);
2200 m_priv->osync_group_set_objtype_enabled(group, "note",
2201 (sync_types & PST_NOTES) ? TRUE : FALSE);
2202 m_priv->osync_group_set_objtype_enabled(group, "todo",
2203 (sync_types & PST_TODOS) ? TRUE : FALSE);
2206 EngineHandle engine(m_priv->osync_engine_unref);
2207 engine = m_priv->osync_engine_new(group, m_priv->error);
2208 if( !engine.get() )
2209 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2212 CallbackBundle cbdata(m_priv, status_callback);
2214 m_priv->osync_engine_set_conflict_callback(engine.get(), conflict_handler, &cbdata);
2215 m_priv->osync_engine_set_changestatus_callback(engine.get(), entry_status, &cbdata);
2216 m_priv->osync_engine_set_mappingstatus_callback(engine.get(), mapping_status, &cbdata);
2217 m_priv->osync_engine_set_enginestatus_callback(engine.get(), engine_status, &cbdata);
2218 m_priv->osync_engine_set_memberstatus_callback(engine.get(), member_status, &cbdata);
2219 m_priv->osync_engine_set_multiply_callback(engine.get(), multiply_summary, &cbdata);
2222 SyncListHandle members(m_priv->osync_list_free);
2223 members = m_priv->osync_group_get_members(group);
2224 OSyncList *m = NULL;
2225 for( m = members.get(); m; m = m->next ) {
2226 OSyncMember *member = (OSyncMember *) m->data;
2228 SyncListHandle objtypes(m_priv->osync_list_free);
2229 objtypes = m_priv->osync_member_get_objtypes(member);
2230 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2231 cout << "Sync(): Member " << m_priv->osync_member_get_id(member) << " has no objtypes. Has it already been discovered?" << endl;
2235 if( !m_priv->osync_engine_initialize(engine.get(), m_priv->error) )
2236 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2238 if( !m_priv->osync_engine_synchronize_and_block(engine.get(), m_priv->error) ) {
2239 m_priv->osync_engine_finalize(engine.get(), NULL);
2240 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2243 if( !m_priv->osync_engine_finalize(engine.get(), m_priv->error) )
2244 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2248 /////////////////////////////////////////////////////////////////////////////
2249 // TossError public members
2251 /// Returns NULL if no error
2252 std::string TossError::GetErrorMsg()
2254 return std::string(m_priv->osync_error_print_stack_wrapper(&m_error));
2257 bool TossError::IsSet()
2259 return m_priv->osync_error_is_set(&m_error);
2262 void TossError::Clear()
2264 if( m_error ) {
2265 m_priv->osync_error_unref(&m_error);
2266 m_error = 0;
2270 } // namespace OpenSync