desktop: fixed bug in GroupCfgDlg that gave mistaken "not configured" error
[barry/progweb.git] / desktop / src / os40.cc
blob3375cbe0d42c50961be92800d50480ea7d2af050
1 ///
2 /// \file os40.cc
3 /// Wrapper class for opensync 0.22 syncing behaviour
4 ///
6 /*
7 Copyright (C) 2009-2010, 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 #include <../libopensync1/opensync/opensync.h>
43 #include <../libopensync1/opensync/opensync-group.h>
44 #include <../libopensync1/opensync/opensync-format.h>
45 #include <../libopensync1/opensync/opensync-plugin.h>
46 #include <../libopensync1/opensync/opensync-engine.h>
47 #include <../libopensync1/opensync/opensync-data.h>
48 #include <../libopensync1/opensync/opensync-capabilities.h>
50 using namespace std;
51 using namespace Barry;
53 namespace OpenSync {
56 typedef Barry::vLateSmartPtr<OSyncEngine, void(*)(OSyncEngine*)> EngineHandle;
57 typedef Barry::vLateSmartPtr<OSyncList, void(*)(OSyncList*)> SyncListHandle;
61 // Private class declarations
65 class TossError
67 OSyncError *m_error;
68 OpenSync40Private *m_priv;
70 public:
71 // simple wrapper... unref's the error on destruction
72 TossError(OpenSync40Private *priv)
73 : m_error(0)
74 , m_priv(priv)
78 ~TossError()
80 Clear();
83 /// Returns NULL if no error
84 std::string GetErrorMsg();
85 bool IsSet();
86 void Clear();
88 operator OSyncError**()
90 return &m_error;
94 class OpenSync40Private
96 public:
97 // function pointers
98 const char* (*osync_get_version)();
99 const char* (*osync_error_print)(OSyncError **error);
100 osync_bool (*osync_error_is_set)(OSyncError **error);
101 void (*osync_error_unref)(OSyncError **error);
102 OSyncGroupEnv* (*osync_group_env_new)(OSyncError **error);
103 OSyncFormatEnv* (*osync_format_env_new)(OSyncError **error);
104 OSyncPluginEnv* (*osync_plugin_env_new)(OSyncError **error);
105 void (*osync_group_env_unref)(OSyncGroupEnv *env);
106 void (*osync_format_env_unref)(OSyncFormatEnv *env);
107 void (*osync_plugin_env_unref)(OSyncPluginEnv *env);
108 osync_bool (*osync_plugin_env_load)(OSyncPluginEnv *env,
109 const char *path, OSyncError **error);
110 OSyncList* (*osync_plugin_env_get_plugins)(
111 OSyncPluginEnv *env);
112 const char* (*osync_plugin_get_name)(OSyncPlugin *plugin);
113 void (*osync_list_free)(OSyncList *list);
114 osync_bool (*osync_group_env_load_groups)(
115 OSyncGroupEnv *env, const char *path,
116 OSyncError **error);
117 osync_bool (*osync_format_env_load_plugins)(
118 OSyncFormatEnv *env, const char *path,
119 OSyncError **error);
120 OSyncList* (*osync_group_env_get_groups)(
121 OSyncGroupEnv *env);
122 const char* (*osync_group_get_name)(OSyncGroup *group);
123 OSyncGroup* (*osync_group_env_find_group)(
124 OSyncGroupEnv *env, const char *name);
125 OSyncList* (*osync_group_get_members)(OSyncGroup *group);
126 const char* (*osync_member_get_name)(OSyncMember *member);
127 osync_memberid (*osync_member_get_id)(OSyncMember *member);
128 const char* (*osync_member_get_pluginname)(
129 OSyncMember *member);
130 OSyncList* (*osync_format_env_get_objformats)(
131 OSyncFormatEnv *env);
132 const char* (*osync_objformat_get_name)(
133 OSyncObjFormat *format);
134 const char* (*osync_objformat_get_objtype)(
135 OSyncObjFormat *format);
136 OSyncGroup* (*osync_group_new)(OSyncError **error);
137 void (*osync_group_unref)(OSyncGroup *group);
138 void (*osync_group_set_name)(OSyncGroup *group,
139 const char *name);
140 osync_bool (*osync_group_env_add_group)(OSyncGroupEnv *env,
141 OSyncGroup *group,
142 OSyncError **error);
143 osync_bool (*osync_group_save)(OSyncGroup *group,
144 OSyncError **error);
145 osync_bool (*osync_group_delete)(OSyncGroup *group,
146 OSyncError **error);
147 void (*osync_group_env_remove_group)(
148 OSyncGroupEnv *env, OSyncGroup *group);
149 OSyncPlugin* (*osync_plugin_env_find_plugin)(
150 OSyncPluginEnv *env, const char *name);
151 void (*osync_member_unref)(OSyncMember *member);
152 OSyncMember* (*osync_member_new)(OSyncError **error);
153 void (*osync_group_add_member)(OSyncGroup *group,
154 OSyncMember *member);
155 void (*osync_member_set_pluginname)(
156 OSyncMember *member,
157 const char *pluginname);
158 void (*osync_member_set_name)(OSyncMember *member,
159 const char *name);
160 osync_bool (*osync_member_save)(OSyncMember *member,
161 OSyncError **error);
162 OSyncMember* (*osync_group_find_member)(OSyncGroup *group,
163 osync_memberid id);
164 osync_bool (*osync_member_delete)(OSyncMember *member,
165 OSyncError **error);
166 void (*osync_group_remove_member)(OSyncGroup *group,
167 OSyncMember *member);
168 OSyncPluginConfig* (*osync_plugin_config_new)(OSyncError **error);
169 osync_bool (*osync_plugin_config_file_load)(
170 OSyncPluginConfig *config,
171 const char *path,
172 OSyncError **error);
173 void (*osync_member_set_config)(OSyncMember *member,
174 OSyncPluginConfig *config);
175 OSyncPluginConfig* (*osync_member_get_config_or_default)(
176 OSyncMember *member,
177 OSyncError **error);
178 osync_bool (*osync_plugin_config_file_save)(
179 OSyncPluginConfig *config,
180 const char *path, OSyncError **error);
181 OSyncPluginConfigurationType (*osync_plugin_get_config_type)(
182 OSyncPlugin *plugin);
183 OSyncEngine* (*osync_engine_new)(OSyncGroup *group,
184 OSyncError **error);
185 void (*osync_engine_unref)(OSyncEngine *engine);
186 osync_bool (*osync_engine_discover_and_block)(
187 OSyncEngine *engine,
188 OSyncMember *member,
189 OSyncError **error);
190 OSyncList* (*osync_member_get_objtypes)(
191 OSyncMember *member);
192 unsigned int (*osync_list_length)(const OSyncList *list);
193 void (*osync_error_set)(OSyncError **error,
194 OSyncErrorType type,
195 const char *format, ...);
196 osync_bool (*osync_engine_finalize)(OSyncEngine *engine,
197 OSyncError **error);
198 OSyncList* (*osync_mapping_engine_get_changes)(
199 OSyncMappingEngine *engine);
200 osync_bool (*osync_mapping_engine_supports_ignore)(
201 OSyncMappingEngine *engine);
202 osync_bool (*osync_mapping_engine_supports_use_latest)(
203 OSyncMappingEngine *engine);
204 OSyncList* (*osync_list_nth)(OSyncList *list,
205 unsigned int n);
206 osync_bool (*osync_engine_mapping_solve)(
207 OSyncEngine *engine,
208 OSyncMappingEngine *mapping_engine,
209 OSyncChange *change,
210 OSyncError **error);
211 osync_bool (*osync_engine_abort)(OSyncEngine *engine,
212 OSyncError **error);
213 osync_bool (*osync_engine_mapping_duplicate)(
214 OSyncEngine *engine,
215 OSyncMappingEngine *mapping_engine,
216 OSyncError **error);
217 osync_bool (*osync_engine_mapping_ignore_conflict)(
218 OSyncEngine *engine,
219 OSyncMappingEngine *mapping_engine,
220 OSyncError **error);
221 osync_bool (*osync_engine_mapping_use_latest)(
222 OSyncEngine *engine,
223 OSyncMappingEngine *mapping_engine,
224 OSyncError **error);
225 OSyncChangeType (*osync_change_get_changetype)(
226 OSyncChange *change);
227 OSyncMember* (*osync_mapping_engine_change_find_member)(
228 OSyncMappingEngine *engine,
229 OSyncChange *change);
230 OSyncData* (*osync_change_get_data)(OSyncChange *change);
231 char* (*osync_data_get_printable)(OSyncData *data,
232 OSyncError **error);
233 void (*osync_free)(void *ptr);
234 const char* (*osync_change_get_uid)(OSyncChange *change);
235 osync_bool (*osync_engine_continue)(OSyncEngine *engine,
236 OSyncError **error);
237 OSyncList* (*osync_engine_get_objengines)(
238 OSyncEngine *engine);
239 OSyncList* (*osync_obj_engine_get_members)(
240 OSyncObjEngine* engine);
241 const char* (*osync_obj_engine_get_objtype)(
242 OSyncObjEngine *engine);
243 const OSyncList* (*osync_obj_engine_get_mapping_entry_engines_of_member)(
244 OSyncObjEngine *engine,
245 OSyncMember *member);
246 osync_bool (*osync_entry_engine_is_dirty)(
247 OSyncMappingEntryEngine *engine);
248 OSyncChangeType (*osync_entry_engine_get_changetype)(
249 OSyncMappingEntryEngine *engine);
250 OSyncChange* (*osync_engine_change_update_get_change)(
251 OSyncEngineChangeUpdate *update);
252 OSyncMember* (*osync_engine_change_update_get_member)(
253 OSyncEngineChangeUpdate *update);
254 OSyncError* (*osync_engine_change_update_get_error)(
255 OSyncEngineChangeUpdate *update);
256 OSyncEngineChangeEvent (*osync_engine_change_update_get_event)(
257 OSyncEngineChangeUpdate *update);
258 OSyncObjFormat* (*osync_change_get_objformat)(
259 OSyncChange *change);
260 OSyncError* (*osync_engine_mapping_update_get_error)(
261 OSyncEngineMappingUpdate *update);
262 OSyncError* (*osync_engine_update_get_error)(
263 OSyncEngineUpdate *update);
264 OSyncEngineEvent (*osync_engine_update_get_event)(
265 OSyncEngineUpdate *update);
266 const char* (*osync_engine_member_update_get_objtype)(
267 OSyncEngineMemberUpdate *update);
268 OSyncMember* (*osync_engine_member_update_get_member)(
269 OSyncEngineMemberUpdate *update);
270 OSyncError* (*osync_engine_member_update_get_error)(
271 OSyncEngineMemberUpdate *update);
272 OSyncEngineMemberEvent (*osync_engine_member_update_get_event)(
273 OSyncEngineMemberUpdate *update);
274 void (*osync_engine_set_conflict_callback)(
275 OSyncEngine *engine,
276 osync_conflict_cb callback,
277 void *user_data);
278 void (*osync_engine_set_changestatus_callback)(
279 OSyncEngine *engine,
280 osync_status_change_cb callback,
281 void *user_data);
282 void (*osync_engine_set_mappingstatus_callback)(
283 OSyncEngine *engine,
284 osync_status_mapping_cb callback,
285 void *user_data);
286 void (*osync_engine_set_enginestatus_callback)(
287 OSyncEngine *engine,
288 osync_status_engine_cb callback,
289 void *user_data);
290 void (*osync_engine_set_memberstatus_callback)(
291 OSyncEngine *engine,
292 osync_status_member_cb callback,
293 void *user_data);
294 void (*osync_engine_set_multiply_callback)(
295 OSyncEngine *engine,
296 osync_multiply_cb callback,
297 void *user_data);
298 osync_bool (*osync_engine_initialize)(OSyncEngine *engine,
299 OSyncError **error);
300 osync_bool (*osync_engine_synchronize_and_block)(
301 OSyncEngine *engine,OSyncError **error);
302 OSyncEngineMappingEvent (*osync_engine_mapping_update_get_event)(
303 OSyncEngineMappingUpdate *update);
304 void (*osync_plugin_resource_unref)(
305 OSyncPluginResource *resource);
306 void (*osync_plugin_config_add_resource)(
307 OSyncPluginConfig *config,
308 OSyncPluginResource *resource);
309 osync_bool (*osync_plugin_resource_is_enabled)(
310 OSyncPluginResource *resource);
311 void (*osync_plugin_resource_enable)(
312 OSyncPluginResource *resource,
313 osync_bool enable);
314 OSyncList* (*osync_plugin_resource_get_objformat_sinks)(
315 OSyncPluginResource *resource);
316 const char* (*osync_objformat_sink_get_objformat)(
317 OSyncObjFormatSink *sink);
318 const char* (*osync_objformat_sink_get_config)(
319 OSyncObjFormatSink *sink);
320 void (*osync_objformat_sink_set_config)(
321 OSyncObjFormatSink *sink,
322 const char *config);
323 OSyncObjFormatSink* (*osync_objformat_sink_new)(
324 const char *objformat,
325 OSyncError **error);
326 void (*osync_plugin_resource_add_objformat_sink)(
327 OSyncPluginResource *resource,
328 OSyncObjFormatSink *formatsink);
329 void (*osync_objformat_sink_unref)(
330 OSyncObjFormatSink *sink);
331 const char* (*osync_plugin_resource_get_preferred_format)(
332 OSyncPluginResource *resource);
333 void (*osync_plugin_resource_set_preferred_format)(
334 OSyncPluginResource *resource,
335 const char *preferred_format);
336 const char* (*osync_plugin_resource_get_mime)(
337 OSyncPluginResource *resource);
338 void (*osync_plugin_resource_set_mime)(
339 OSyncPluginResource *resource,
340 const char *mime);
341 const char* (*osync_plugin_resource_get_objtype)(
342 OSyncPluginResource *resource);
343 void (*osync_plugin_resource_set_objtype)(
344 OSyncPluginResource *resource,
345 const char *objtype);
346 const char* (*osync_plugin_resource_get_path)(
347 OSyncPluginResource *resource);
348 void (*osync_plugin_resource_set_path)(
349 OSyncPluginResource *resource,
350 const char *path);
351 const char* (*osync_plugin_resource_get_url)(
352 OSyncPluginResource *resource);
353 void (*osync_plugin_resource_set_url)(
354 OSyncPluginResource *resource,
355 const char *url);
356 const char* (*osync_plugin_config_get_advancedoption_value_by_name)(
357 OSyncPluginConfig *config,
358 const char *name);
359 OSyncList* (*osync_plugin_config_get_advancedoptions)(
360 OSyncPluginConfig *config);
361 void (*osync_plugin_config_add_advancedoption)(
362 OSyncPluginConfig *config,
363 OSyncPluginAdvancedOption *option);
364 OSyncPluginAdvancedOption* (*osync_plugin_advancedoption_new)(
365 OSyncError **error);
366 void (*osync_plugin_advancedoption_unref)(
367 OSyncPluginAdvancedOption *option);
368 const char* (*osync_plugin_advancedoption_get_name)(
369 OSyncPluginAdvancedOption *option);
370 void (*osync_plugin_advancedoption_set_name)(
371 OSyncPluginAdvancedOption *option,
372 const char *name);
373 void (*osync_plugin_advancedoption_set_displayname)(
374 OSyncPluginAdvancedOption *option,
375 const char *displayname);
376 void (*osync_plugin_advancedoption_set_type)(
377 OSyncPluginAdvancedOption *option,
378 OSyncPluginAdvancedOptionType type);
379 void (*osync_plugin_advancedoption_set_value)(
380 OSyncPluginAdvancedOption *option,
381 const char *value);
382 OSyncList* (*osync_plugin_config_get_resources)(
383 OSyncPluginConfig *config);
384 OSyncPluginResource* (*osync_plugin_resource_ref)(
385 OSyncPluginResource *resource);
386 OSyncPluginResource* (*osync_plugin_resource_new)(
387 OSyncError **error);
388 const char* (*osync_plugin_resource_get_name)(
389 OSyncPluginResource *resource);
390 void (*osync_plugin_resource_set_name)(
391 OSyncPluginResource *resource,
392 const char *name);
393 OSyncPluginAuthentication* (*osync_plugin_config_get_authentication)(
394 OSyncPluginConfig *config);
395 const char* (*osync_plugin_authentication_get_password)(
396 OSyncPluginAuthentication *auth);
397 OSyncPluginAuthentication* (*osync_plugin_authentication_new)(
398 OSyncError **error);
399 osync_bool (*osync_plugin_authentication_option_is_supported)(
400 OSyncPluginAuthentication *auth,
401 OSyncPluginAuthenticationOptionSupportedFlag flag);
402 void (*osync_plugin_authentication_unref)(
403 OSyncPluginAuthentication *auth);
404 void (*osync_plugin_config_set_authentication)(
405 OSyncPluginConfig *config,
406 OSyncPluginAuthentication *auth);
407 void (*osync_plugin_authentication_set_password)(
408 OSyncPluginAuthentication *auth,
409 const char *password);
411 // data pointers
412 vLateSmartPtr<OSyncGroupEnv, void(*)(OSyncGroupEnv*)> group_env;
413 vLateSmartPtr<OSyncFormatEnv, void(*)(OSyncFormatEnv*)> format_env;
414 vLateSmartPtr<OSyncPluginEnv, void(*)(OSyncPluginEnv*)> plugin_env;
416 TossError error;
417 Converter40 converter;
419 OpenSync40Private(OpenSync40 &api)
420 : error(this)
421 , converter(api)
426 class SyncConflict40Private : public SyncConflictPrivateBase
428 OpenSync40Private *m_priv;
429 OSyncEngine *m_engine;
430 OSyncMappingEngine *m_mapping;
431 OSyncList *m_changes;
433 public:
434 SyncConflict40Private(OpenSync40Private *priv,
435 OSyncEngine *engine, OSyncMappingEngine *mapping);
436 ~SyncConflict40Private();
438 virtual bool IsAbortSupported() const;
439 virtual bool IsIgnoreSupported() const;
440 virtual bool IsKeepNewerSupported() const;
442 virtual void Select(int change_id); // takes the id of SyncChange
443 virtual void Abort();
444 virtual void Duplicate();
445 virtual void Ignore();
446 virtual void KeepNewer();
448 void AppendChanges(std::vector<SyncChange> &list);
451 class SyncSummary40Private : public SyncSummaryPrivateBase
453 OpenSync40Private *m_priv;
454 OSyncEngine *m_engine;
456 public:
457 SyncSummary40Private(OpenSync40Private *priv, OSyncEngine *engine);
458 ~SyncSummary40Private();
460 virtual void Abort();
461 virtual void Continue();
463 // returns true if any member is dirty
464 bool AppendMembers(std::vector<SyncMemberSummary> &list);
467 class OS40PluginConfigPrivate
469 public:
470 OSyncMember *m_member;
471 OSyncPluginConfig *m_config;
473 OS40PluginConfigPrivate()
474 : m_member(0)
475 , m_config(0)
480 class OS40ConfigResourcePrivate
482 public:
483 OpenSync40Private *m_privapi;
484 OS40PluginConfigPrivate *m_parentpriv;
485 OSyncPluginResource *m_resource;
487 OS40ConfigResourcePrivate()
488 : m_privapi(0)
489 , m_parentpriv(0)
490 , m_resource(0)
495 struct CallbackBundle
497 OpenSync40Private *m_priv;
498 SyncStatus *m_status;
500 CallbackBundle(OpenSync40Private *priv, SyncStatus &status)
501 : m_priv(priv)
502 , m_status(&status)
507 void conflict_handler(OSyncEngine *, OSyncMappingEngine *, void *);
508 void entry_status(OSyncEngineChangeUpdate *, void *);
509 void mapping_status(OSyncEngineMappingUpdate *, void *);
510 void engine_status(OSyncEngineUpdate *, void *);
511 void member_status(OSyncEngineMemberUpdate *, void *);
512 void multiply_summary(OSyncEngine *, void *);
515 /////////////////////////////////////////////////////////////////////////////
516 // Static helper functions
518 static const char *OSyncChangeType2String(OSyncChangeType type)
520 switch (type) {
521 case OSYNC_CHANGE_TYPE_ADDED: return "ADDED";
522 case OSYNC_CHANGE_TYPE_UNMODIFIED: return "UNMODIFIED";
523 case OSYNC_CHANGE_TYPE_DELETED: return "DELETED";
524 case OSYNC_CHANGE_TYPE_MODIFIED: return "MODIFIED";
525 default:
526 case OSYNC_CHANGE_TYPE_UNKNOWN: return "?";
531 /////////////////////////////////////////////////////////////////////////////
532 // SyncConflict40Private member functions
534 SyncConflict40Private::SyncConflict40Private(OpenSync40Private *priv,
535 OSyncEngine *engine, OSyncMappingEngine *mapping)
536 : m_priv(priv)
537 , m_engine(engine)
538 , m_mapping(mapping)
539 , m_changes(0)
541 m_changes = m_priv->osync_mapping_engine_get_changes(m_mapping);
544 SyncConflict40Private::~SyncConflict40Private()
546 m_priv->osync_list_free(m_changes);
549 bool SyncConflict40Private::IsAbortSupported() const
551 return true;
554 bool SyncConflict40Private::IsIgnoreSupported() const
556 return m_priv->osync_mapping_engine_supports_ignore(m_mapping);
559 bool SyncConflict40Private::IsKeepNewerSupported() const
561 return m_priv->osync_mapping_engine_supports_use_latest(m_mapping);
564 void SyncConflict40Private::Select(int change_id)
566 OSyncList *c = m_priv->osync_list_nth(m_changes, change_id);
567 if( !c )
568 throw std::logic_error("Bad change_id");
570 OSyncChange *change = (OSyncChange *) c->data;
572 if( !m_priv->osync_engine_mapping_solve(m_engine, m_mapping,
573 change, m_priv->error) )
575 throw std::runtime_error(m_priv->error.GetErrorMsg());
579 void SyncConflict40Private::Abort()
581 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) ) {
582 ostringstream oss;
583 oss << "Problems while aborting: "
584 << m_priv->error.GetErrorMsg();
585 throw std::runtime_error(oss.str());
589 void SyncConflict40Private::Duplicate()
591 if( !m_priv->osync_engine_mapping_duplicate(m_engine, m_mapping, m_priv->error) )
592 throw std::runtime_error(m_priv->error.GetErrorMsg());
595 void SyncConflict40Private::Ignore()
597 if( !IsIgnoreSupported() )
598 throw std::logic_error("Ignore not supported, yet Ignore() called.");
600 if( !m_priv->osync_engine_mapping_ignore_conflict(m_engine, m_mapping,
601 m_priv->error) )
603 throw std::runtime_error(m_priv->error.GetErrorMsg());
607 void SyncConflict40Private::KeepNewer()
609 if( !IsKeepNewerSupported() )
610 throw std::logic_error("Keep Newer not supported, yet KeepNewer() called.");
612 if( !m_priv->osync_engine_mapping_use_latest(m_engine, m_mapping, m_priv->error) )
613 throw std::runtime_error(m_priv->error.GetErrorMsg());
616 void SyncConflict40Private::AppendChanges(std::vector<SyncChange> &list)
618 int i = 0;
619 for( OSyncList *c = m_changes; c; c = c->next, i++ ) {
620 OSyncChange *change = (OSyncChange *) c->data;
622 if( m_priv->osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_UNKNOWN ) {
623 OSyncMember *member = m_priv->osync_mapping_engine_change_find_member(m_mapping, change);
625 OSyncData *data = m_priv->osync_change_get_data(change);
627 SyncChange entry;
629 char *printable = m_priv->osync_data_get_printable(data, m_priv->error);
630 if( printable )
631 entry.printable_data = printable;
632 m_priv->osync_free(printable);
634 if( m_priv->error.IsSet() )
635 throw std::runtime_error(m_priv->error.GetErrorMsg());
637 entry.id = i;
638 entry.member_id = m_priv->osync_member_get_id(member);
639 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
640 entry.uid = m_priv->osync_change_get_uid(change);
642 // add to list
643 list.push_back(entry);
649 /////////////////////////////////////////////////////////////////////////////
650 // SyncSummary40Private member functions
652 SyncSummary40Private::SyncSummary40Private(OpenSync40Private *priv,
653 OSyncEngine *engine)
654 : m_priv(priv)
655 , m_engine(engine)
659 SyncSummary40Private::~SyncSummary40Private()
663 void SyncSummary40Private::Abort()
665 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) )
666 throw std::runtime_error(m_priv->error.GetErrorMsg());
669 void SyncSummary40Private::Continue()
671 if( !m_priv->osync_engine_continue(m_engine, m_priv->error) )
672 throw std::runtime_error(m_priv->error.GetErrorMsg());
675 bool SyncSummary40Private::AppendMembers(std::vector<SyncMemberSummary> &list)
677 SyncListHandle objengines(m_priv->osync_list_free);
678 objengines = m_priv->osync_engine_get_objengines(m_engine);
680 int i = 0;
681 bool dirty = false;
683 for( OSyncList *o = objengines.get(); o; o = o->next ) {
684 OSyncObjEngine *objengine = (OSyncObjEngine *) o->data;
690 SyncListHandle members(m_priv->osync_list_free);
691 members = m_priv->osync_obj_engine_get_members(objengine);
692 for( OSyncList *m = members.get(); m; m = m->next ) {
693 OSyncMember *member = (OSyncMember *) m->data;
695 // Fill in common summary data
696 SyncMemberSummary entry;
697 entry.id = i;
698 entry.objtype_name = m_priv->osync_obj_engine_get_objtype(objengine);
699 entry.member_id = m_priv->osync_member_get_id(member);
700 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
702 const OSyncList *mapping_entry_engines = m_priv->osync_obj_engine_get_mapping_entry_engines_of_member(objengine, member);
704 // Calculate summary counts
705 for( const OSyncList *e = mapping_entry_engines; e; e = e->next ) {
706 OSyncMappingEntryEngine *entry_engine = (OSyncMappingEntryEngine*) e->data;
708 if( !m_priv->osync_entry_engine_is_dirty(entry_engine) )
709 continue;
711 dirty = true;
713 OSyncChangeType type = m_priv->osync_entry_engine_get_changetype(entry_engine);
714 switch (type)
716 case OSYNC_CHANGE_TYPE_ADDED:
717 entry.added++;
718 break;
719 case OSYNC_CHANGE_TYPE_MODIFIED:
720 entry.modified++;
721 break;
722 case OSYNC_CHANGE_TYPE_DELETED:
723 entry.deleted++;
724 break;
725 default:
726 break;
730 // Add entry to list
731 list.push_back(entry);
736 return dirty;
740 /////////////////////////////////////////////////////////////////////////////
741 // Callback functions
743 void conflict_handler(OSyncEngine *engine, OSyncMappingEngine *mapping,
744 void *cbdata)
746 CallbackBundle *cb = (CallbackBundle*) cbdata;
748 try {
749 // build the SyncConflict object
750 SyncConflict40Private scp(cb->m_priv, engine, mapping);
751 SyncConflict conflict(scp);
753 // append all conflicting changes as vector objects in the same
754 // order as the opensync library mapping
755 scp.AppendChanges(conflict);
757 // call the status handler
758 cb->m_status->HandleConflict(conflict);
760 catch( std::exception &e ) {
761 cb->m_status->ReportError(
762 string("Conflict not resolved. ") + e.what());
764 catch( ... ) {
765 cb->m_status->ReportError(
766 "Unknown exception caught in conflict_handler()");
770 void entry_status(OSyncEngineChangeUpdate *status, void *cbdata)
772 CallbackBundle *cb = (CallbackBundle*) cbdata;
774 try {
775 ostringstream oss;
777 OSyncChange *change = cb->m_priv->osync_engine_change_update_get_change(status);
778 OSyncMember *member = cb->m_priv->osync_engine_change_update_get_member(status);
779 OSyncError *error = cb->m_priv->osync_engine_change_update_get_error(status);
781 const char *action = NULL;
782 const char *direction = NULL;
783 const char *msg = NULL;
784 bool error_event = false;
786 switch( cb->m_priv->osync_engine_change_update_get_event(status) )
788 case OSYNC_ENGINE_CHANGE_EVENT_READ:
789 action = "Received an entry";
790 direction = "from";
791 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
792 break;
794 case OSYNC_ENGINE_CHANGE_EVENT_WRITTEN:
795 action = "Sent an entry";
796 direction = "to";
797 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
798 break;
800 case OSYNC_ENGINE_CHANGE_EVENT_ERROR:
801 error_event = true;
802 action = "Error for entry";
803 direction = "and";
804 msg = cb->m_priv->osync_error_print(&(error));
805 break;
808 if( action ) {
809 oss << action << " "
810 << cb->m_priv->osync_change_get_uid(change)
811 << "("
812 << cb->m_priv->osync_objformat_get_name( cb->m_priv->osync_change_get_objformat(change))
813 << ") " << direction << " member "
814 << cb->m_priv->osync_member_get_id(member)
815 << " ("
816 << cb->m_priv->osync_member_get_pluginname(member)
817 << "): "
818 << msg;
820 // call the status handler
821 cb->m_status->EntryStatus(oss.str(), error_event);
824 catch( std::exception &e ) {
825 cb->m_status->ReportError(
826 string("entry_status error:") + e.what());
828 catch( ... ) {
829 cb->m_status->ReportError(
830 "Unknown exception caught in entry_status()");
834 void mapping_status(OSyncEngineMappingUpdate *status, void *cbdata)
836 CallbackBundle *cb = (CallbackBundle*) cbdata;
838 try {
839 OSyncError *error = cb->m_priv->osync_engine_mapping_update_get_error(status);
841 ostringstream oss;
842 bool error_event = false;
844 switch( cb->m_priv->osync_engine_mapping_update_get_event(status) )
846 case OSYNC_ENGINE_MAPPING_EVENT_SOLVED:
847 oss << "Mapping solved";
848 break;
850 case OSYNC_ENGINE_MAPPING_EVENT_ERROR:
851 error_event = true;
852 oss << "Mapping error: "
853 << cb->m_priv->osync_error_print(&(error));
854 break;
857 // call the status handler
858 if( oss.str().size() )
859 cb->m_status->MappingStatus(oss.str(), error_event);
861 catch( std::exception &e ) {
862 cb->m_status->ReportError(
863 string("mapping_status error: ") + e.what());
865 catch( ... ) {
866 cb->m_status->ReportError(
867 "Unknown exception caught in mapping_status()");
871 void engine_status(OSyncEngineUpdate *status, void *cbdata)
873 CallbackBundle *cb = (CallbackBundle*) cbdata;
875 try {
876 OSyncError *error = cb->m_priv->osync_engine_update_get_error(status);
878 ostringstream oss;
879 bool error_event = false;
880 bool slow_sync = false;
882 switch( cb->m_priv->osync_engine_update_get_event(status) )
884 case OSYNC_ENGINE_EVENT_CONNECTED:
885 oss << "All clients connected or error";
886 break;
887 case OSYNC_ENGINE_EVENT_CONNECT_DONE:
888 /* Not of interest for regular user. */
889 break;
890 case OSYNC_ENGINE_EVENT_READ:
891 oss << "All clients sent changes or error";
892 break;
893 case OSYNC_ENGINE_EVENT_MAPPED:
894 oss << "All changes got mapped";
895 break;
896 case OSYNC_ENGINE_EVENT_MULTIPLIED:
897 oss << "All changes got multiplied";
898 break;
899 case OSYNC_ENGINE_EVENT_PREPARED_WRITE:
900 oss << "All changes got prepared for write";
901 break;
902 case OSYNC_ENGINE_EVENT_PREPARED_MAP:
903 /* Not of interest for regular user. */
904 break;
905 case OSYNC_ENGINE_EVENT_WRITTEN:
906 oss << "All clients have written";
907 break;
908 case OSYNC_ENGINE_EVENT_DISCONNECTED:
909 oss << "All clients have disconnected";
910 break;
911 case OSYNC_ENGINE_EVENT_ERROR:
912 error_event = true;
913 oss << "The sync failed: " << cb->m_priv->osync_error_print(&(error));
914 break;
915 case OSYNC_ENGINE_EVENT_SUCCESSFUL:
916 oss << "The sync was successful";
917 break;
918 case OSYNC_ENGINE_EVENT_PREV_UNCLEAN:
919 oss << "The previous synchronization was unclean. Slow-syncing";
920 slow_sync = true;
921 break;
922 case OSYNC_ENGINE_EVENT_END_CONFLICTS:
923 oss << "All conflicts have been reported";
924 break;
925 case OSYNC_ENGINE_EVENT_SYNC_DONE:
926 oss << "All clients reported sync done";
927 break;
930 // call the status handler
931 if( oss.str().size() )
932 cb->m_status->EngineStatus(oss.str(),
933 error_event,
934 slow_sync);
936 catch( std::exception &e ) {
937 cb->m_status->ReportError(
938 string("engine_status error: ") + e.what());
940 catch( ... ) {
941 cb->m_status->ReportError(
942 "Unknown exception caught in engine_status()");
946 void member_status(OSyncEngineMemberUpdate *status, void *cbdata)
948 CallbackBundle *cb = (CallbackBundle*) cbdata;
950 try {
951 ostringstream oss;
952 bool error_event = false;
953 bool valid = true;
955 const char *objtype = cb->m_priv->osync_engine_member_update_get_objtype(status);
956 if( objtype == NULL )
957 oss << "Main sink";
958 else
959 oss << objtype << " sink";
962 OSyncMember *member = cb->m_priv->osync_engine_member_update_get_member(status);
964 oss << " of member "
965 << cb->m_priv->osync_member_get_id(member)
966 << " ("
967 << cb->m_priv->osync_member_get_pluginname(member)
968 << ")";
970 OSyncError *error = cb->m_priv->osync_engine_member_update_get_error(status);
972 switch( cb->m_priv->osync_engine_member_update_get_event(status) )
974 case OSYNC_ENGINE_MEMBER_EVENT_CONNECTED:
975 oss << " just connected";
976 break;
977 case OSYNC_ENGINE_MEMBER_EVENT_CONNECT_DONE:
978 // Special event - but not interesting for
979 // the normal user.
980 break;
981 case OSYNC_ENGINE_MEMBER_EVENT_DISCONNECTED:
982 oss << " just disconnected";
983 break;
984 case OSYNC_ENGINE_MEMBER_EVENT_READ:
985 oss << " just sent all changes";
986 break;
987 case OSYNC_ENGINE_MEMBER_EVENT_WRITTEN:
988 oss << " committed all changes";
989 break;
990 case OSYNC_ENGINE_MEMBER_EVENT_SYNC_DONE:
991 oss << " reported sync done";
992 break;
993 case OSYNC_ENGINE_MEMBER_EVENT_DISCOVERED:
994 oss << " discovered its objtypes";
995 break;
996 case OSYNC_ENGINE_MEMBER_EVENT_ERROR:
997 oss << " had an error: "
998 << cb->m_priv->osync_error_print(&error);
999 error_event = true;
1000 break;
1001 default:
1002 valid = false;
1003 break;
1006 // call the status handler
1007 if( oss.str().size() && valid ) {
1008 cb->m_status->MemberStatus(
1009 cb->m_priv->osync_member_get_id(member),
1010 cb->m_priv->osync_member_get_pluginname(member),
1011 oss.str(), error_event);
1014 catch( std::exception &e ) {
1015 cb->m_status->ReportError(
1016 string("member_status error: ") + e.what());
1018 catch( ... ) {
1019 cb->m_status->ReportError(
1020 "Unknown exception caught in member_status()");
1024 void multiply_summary(OSyncEngine *engine, void *cbdata)
1026 CallbackBundle *cb = (CallbackBundle*) cbdata;
1028 try {
1029 // build the SyncSummary object
1030 SyncSummary40Private ssp(cb->m_priv, engine);
1031 SyncSummary summary(ssp);
1033 // append a summary for each objtype member
1034 if( ssp.AppendMembers(summary) ) {
1035 // call the status handler only if dirty
1036 cb->m_status->CheckSummary(summary);
1038 else {
1039 // nothing dirty, just continue
1040 summary.Continue();
1043 catch( std::exception &e ) {
1044 cb->m_status->ReportError(
1045 string("Error handling summary. ") + e.what());
1047 catch( ... ) {
1048 cb->m_status->ReportError(
1049 "Unknown exception caught in multiply_summary()");
1054 /////////////////////////////////////////////////////////////////////////////
1055 // OS40ConfigResource - public members
1057 OS40ConfigResource::OS40ConfigResource(const OS40PluginConfig &parent,
1058 void *resource,
1059 bool existing_resource)
1060 : m_priv( new OS40ConfigResourcePrivate )
1061 , m_exists(existing_resource)
1063 m_priv->m_privapi = parent.m_privapi;
1064 m_priv->m_parentpriv = parent.m_priv.get();
1065 m_priv->m_resource = (OSyncPluginResource*) resource;
1068 OS40ConfigResource::~OS40ConfigResource()
1070 // unref the resource, since we hold a copy
1071 m_priv->m_privapi->
1072 osync_plugin_resource_unref(m_priv->m_resource);
1073 delete m_priv;
1076 bool OS40ConfigResource::IsExistingResource() const
1078 return m_exists;
1081 // safe to call multiple times
1082 void OS40ConfigResource::AddResource()
1084 if( !IsExistingResource() ) {
1085 m_priv->m_privapi->
1086 osync_plugin_config_add_resource(
1087 m_priv->m_parentpriv->m_config,
1088 m_priv->m_resource);
1092 bool OS40ConfigResource::IsEnabled() const
1094 return m_priv->m_privapi->
1095 osync_plugin_resource_is_enabled(m_priv->m_resource);
1098 OS40ConfigResource& OS40ConfigResource::Enable(bool enabled)
1100 m_priv->m_privapi->osync_plugin_resource_enable(m_priv->m_resource,
1101 enabled);
1102 return *this;
1105 bool OS40ConfigResource::FindObjFormat(const std::string &objformat,
1106 std::string &config)
1108 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1109 sinks = m_priv->m_privapi->
1110 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1111 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1112 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1113 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1114 const char *cfg = m_priv->m_privapi->osync_objformat_sink_get_config(sink);
1115 if( cfg )
1116 config = cfg;
1117 else
1118 config.clear();
1119 return true;
1122 return false;
1125 OS40ConfigResource& OS40ConfigResource::SetObjFormat(const std::string &objformat,
1126 const std::string &config)
1128 // if it already exists, just set the config value
1129 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1130 sinks = m_priv->m_privapi->
1131 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1132 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1133 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1134 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1135 m_priv->m_privapi->osync_objformat_sink_set_config(sink, config.c_str());
1136 return *this;
1140 // if we get here, it doesn't exist, and we need to add it
1141 OSyncObjFormatSink *sink = m_priv->m_privapi->
1142 osync_objformat_sink_new(objformat.c_str(),
1143 m_priv->m_privapi->error);
1144 if( !sink )
1145 throw std::runtime_error(m_priv->m_privapi->error.GetErrorMsg());
1147 if( config.size() )
1148 m_priv->m_privapi->osync_objformat_sink_set_config(sink,
1149 config.c_str());
1150 m_priv->m_privapi->osync_plugin_resource_add_objformat_sink(
1151 m_priv->m_resource, sink);
1152 m_priv->m_privapi->osync_objformat_sink_unref(sink);
1153 return *this;
1156 std::string OS40ConfigResource::GetName() const
1158 string value;
1159 const char *pv = m_priv->m_privapi->
1160 osync_plugin_resource_get_name(m_priv->m_resource);
1161 if( pv )
1162 value = pv;
1163 return value;
1166 OS40ConfigResource& OS40ConfigResource::SetName(const std::string &name)
1168 m_priv->m_privapi->
1169 osync_plugin_resource_set_name(m_priv->m_resource, name.c_str());
1170 return *this;
1173 std::string OS40ConfigResource::GetPreferredFormat() const
1175 string value;
1176 const char *pv = m_priv->m_privapi->
1177 osync_plugin_resource_get_preferred_format(m_priv->m_resource);
1178 if( pv )
1179 value = pv;
1180 return value;
1183 OS40ConfigResource& OS40ConfigResource::SetPreferredFormat(const std::string &format)
1185 m_priv->m_privapi->
1186 osync_plugin_resource_set_preferred_format(m_priv->m_resource,
1187 format.c_str());
1188 return *this;
1191 std::string OS40ConfigResource::GetMime() const
1193 string value;
1194 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_mime(
1195 m_priv->m_resource);
1196 if( pv )
1197 value = pv;
1198 return value;
1201 OS40ConfigResource& OS40ConfigResource::SetMime(const std::string &mime)
1203 m_priv->m_privapi->osync_plugin_resource_set_mime(m_priv->m_resource,
1204 mime.c_str());
1205 return *this;
1208 std::string OS40ConfigResource::GetObjType() const
1210 string value;
1211 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_objtype(
1212 m_priv->m_resource);
1213 if( pv )
1214 value = pv;
1215 return value;
1218 OS40ConfigResource& OS40ConfigResource::SetObjType(const std::string &objtype)
1220 m_priv->m_privapi->osync_plugin_resource_set_objtype(m_priv->m_resource,
1221 objtype.c_str());
1222 return *this;
1225 std::string OS40ConfigResource::GetPath() const
1227 string value;
1228 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_path(
1229 m_priv->m_resource);
1230 if( pv )
1231 value = pv;
1232 return value;
1235 OS40ConfigResource& OS40ConfigResource::SetPath(const std::string &path)
1237 m_priv->m_privapi->osync_plugin_resource_set_path(m_priv->m_resource,
1238 path.c_str());
1239 return *this;
1242 std::string OS40ConfigResource::GetUrl() const
1244 string value;
1245 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_url(
1246 m_priv->m_resource);
1247 if( pv )
1248 value = pv;
1249 return value;
1252 OS40ConfigResource& OS40ConfigResource::SetUrl(const std::string &url)
1254 m_priv->m_privapi->osync_plugin_resource_set_url(m_priv->m_resource,
1255 url.c_str());
1256 return *this;
1260 /////////////////////////////////////////////////////////////////////////////
1261 // OS40PluginConfig - public members
1263 OS40PluginConfig::OS40PluginConfig(OpenSync40Private *privapi,
1264 void *member,
1265 void *config)
1266 : m_privapi(privapi)
1268 m_priv.reset( new OS40PluginConfigPrivate );
1269 m_priv->m_member = (OSyncMember*) member;
1270 m_priv->m_config = (OSyncPluginConfig*) config;
1273 std::string OS40PluginConfig::GetAdvanced(const std::string &name)
1275 const char *value = m_privapi->osync_plugin_config_get_advancedoption_value_by_name(m_priv->m_config, name.c_str());
1276 string val;
1277 if( value )
1278 val = value;
1279 return val;
1282 void OS40PluginConfig::SetAdvanced(const std::string &name,
1283 const std::string &display_name,
1284 const std::string &val)
1286 SetAdvanced(name, display_name, STRING_TYPE, val);
1289 void OS40PluginConfig::SetAdvanced(const std::string &name,
1290 const std::string &display_name,
1291 int val_type,
1292 const std::string &val)
1294 // find the first advanced option with this name
1295 SyncListHandle aos(m_privapi->osync_list_free);
1296 aos = m_privapi->osync_plugin_config_get_advancedoptions(m_priv->m_config);
1297 OSyncPluginAdvancedOption *option = 0;
1298 for( OSyncList *o = aos.get(); o; o = o->next ) {
1299 option = (OSyncPluginAdvancedOption*) o->data;
1301 if( name == m_privapi->osync_plugin_advancedoption_get_name(option) )
1302 break;
1305 if( option ) {
1306 // found existing option, set it with val
1307 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1309 else {
1310 // option with that name does not exist, so create it
1311 option = m_privapi->osync_plugin_advancedoption_new(m_privapi->error);
1312 if( !option )
1313 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1315 m_privapi->osync_plugin_advancedoption_set_name(option, name.c_str());
1316 m_privapi->osync_plugin_advancedoption_set_displayname(option, display_name.c_str());
1317 OSyncPluginAdvancedOptionType type;
1318 switch( val_type )
1320 case NONE_TYPE:
1321 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_NONE;
1322 break;
1323 case BOOL_TYPE:
1324 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_BOOL;
1325 break;
1326 case CHAR_TYPE:
1327 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_CHAR;
1328 break;
1329 case DOUBLE_TYPE:
1330 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_DOUBLE;
1331 break;
1332 case INT_TYPE:
1333 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_INT;
1334 break;
1335 case LONG_TYPE:
1336 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONG;
1337 break;
1338 case LONGLONG_TYPE:
1339 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONGLONG;
1340 break;
1341 case UINT_TYPE:
1342 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_UINT;
1343 break;
1344 case ULONG_TYPE:
1345 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONG;
1346 break;
1347 case ULONGLONG_TYPE:
1348 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONGLONG;
1349 break;
1350 case STRING_TYPE:
1351 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_STRING;
1352 break;
1353 default:
1354 throw std::logic_error("Bad type in SetAdvanced()");
1356 m_privapi->osync_plugin_advancedoption_set_type(option, type);
1357 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1358 m_privapi->osync_plugin_config_add_advancedoption(m_priv->m_config, option);
1359 m_privapi->osync_plugin_advancedoption_unref(option);
1363 OS40PluginConfig::OS40ConfigResourcePtr
1364 OS40PluginConfig::GetResource(const std::string &objtype)
1366 OS40ConfigResourcePtr ptr;
1368 // FIXME - get_resources() does not give us a copy, so don't use
1369 // the SyncListHandle here
1370 OSyncList *rs = m_privapi->osync_plugin_config_get_resources(m_priv->m_config);
1371 for( OSyncList *o = rs; o; o = o->next ) {
1372 OSyncPluginResource *res = (OSyncPluginResource*) o->data;
1373 if( objtype == m_privapi->osync_plugin_resource_get_objtype(res) ) {
1374 // bump the resource count, since OS40ConfigResource
1375 // will unref it in the destructor
1376 m_privapi->osync_plugin_resource_ref(res);
1377 ptr.reset( new OS40ConfigResource(*this, res, true) );
1378 return ptr;
1382 // this res has a ref bump already, no ref() needed like it is above
1383 OSyncPluginResource *res = m_privapi->osync_plugin_resource_new(m_privapi->error);
1384 if( !res )
1385 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1386 ptr.reset( new OS40ConfigResource(*this, res, false) );
1387 // we search by objtype name, so make sure this is set in
1388 // the new object
1389 ptr->SetObjType(objtype);
1390 return ptr;
1393 std::string OS40PluginConfig::GetPassword() const
1395 string password;
1397 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1398 if( !auth )
1399 return password;
1401 const char *pass = m_privapi->osync_plugin_authentication_get_password(auth);
1402 if( !pass )
1403 return password;
1405 password = pass;
1406 return password;
1409 void OS40PluginConfig::SetPassword(const std::string &password)
1411 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1412 if( !auth ) {
1413 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1414 if( !auth )
1415 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1416 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_PASSWORD) ) {
1417 m_privapi->osync_plugin_authentication_unref(auth);
1418 throw std::runtime_error("Password authentication is not supported in plugin!");
1421 // all looks ok, add it to the config
1422 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1423 // unref our copy, since the config now has it...
1424 // our auth pointer will still be valid since config holds it
1425 m_privapi->osync_plugin_authentication_unref(auth);
1428 m_privapi->osync_plugin_authentication_set_password(auth, password.c_str());
1431 void OS40PluginConfig::Save()
1433 if( !m_privapi->osync_member_save(m_priv->m_member, m_privapi->error) )
1434 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1438 /////////////////////////////////////////////////////////////////////////////
1439 // OpenSync40 (API override class) - public members
1441 OpenSync40::OpenSync40()
1443 // due to bugs in the way opensync 0.22 loads its modules,
1444 // (i.e. it doesn't load the plugins using RTLD_LOCAL, and
1445 // so libopensync.so.0 is loaded and pollutes the symbol table,
1446 // causing symbol clashes) we need to make sure that
1447 // OpenSync40 is only loaded first... if OpenSync22 was
1448 // loaded first, we will fail, so error out
1449 if( OpenSync22::SymbolsLoaded() )
1450 throw std::logic_error("Always load OpenSync40 before OpenSync22, to avoid symbol table conflicts.");
1452 if( !Open("libopensync.so.1") )
1453 throw DlError("Can't dlopen libopensync.so.1");
1455 // store locally in case of constructor exception in LoadSym
1456 std::auto_ptr<OpenSync40Private> p(new OpenSync40Private(*this));
1458 // load all required symbols...
1459 // we don't need to use try/catch here, since the base
1460 // class destructor will clean up for us if LoadSym() throws
1461 LoadSym(p->osync_get_version, "osync_get_version");
1462 LoadSym(p->osync_error_print, "osync_error_print");
1463 LoadSym(p->osync_error_is_set, "osync_error_is_set");
1464 LoadSym(p->osync_error_unref, "osync_error_unref");
1465 LoadSym(p->osync_group_env_new, "osync_group_env_new");
1466 LoadSym(p->osync_format_env_new, "osync_format_env_new");
1467 LoadSym(p->osync_plugin_env_new, "osync_plugin_env_new");
1468 LoadSym(p->osync_group_env_unref, "osync_group_env_unref");
1469 LoadSym(p->osync_format_env_unref, "osync_format_env_unref");
1470 LoadSym(p->osync_plugin_env_unref, "osync_plugin_env_unref");
1471 LoadSym(p->osync_plugin_env_load, "osync_plugin_env_load");
1472 LoadSym(p->osync_plugin_env_get_plugins,"osync_plugin_env_get_plugins");
1473 LoadSym(p->osync_plugin_get_name, "osync_plugin_get_name");
1474 LoadSym(p->osync_list_free, "osync_list_free");
1475 LoadSym(p->osync_group_env_load_groups, "osync_group_env_load_groups");
1476 LoadSym(p->osync_format_env_load_plugins,
1477 "osync_format_env_load_plugins");
1478 LoadSym(p->osync_group_env_get_groups, "osync_group_env_get_groups");
1479 LoadSym(p->osync_group_get_name, "osync_group_get_name");
1480 LoadSym(p->osync_group_env_find_group, "osync_group_env_find_group");
1481 LoadSym(p->osync_group_get_members, "osync_group_get_members");
1482 LoadSym(p->osync_member_get_name, "osync_member_get_name");
1483 LoadSym(p->osync_member_get_id, "osync_member_get_id");
1484 LoadSym(p->osync_member_get_pluginname, "osync_member_get_pluginname");
1485 LoadSym(p->osync_format_env_get_objformats,
1486 "osync_format_env_get_objformats");
1487 LoadSym(p->osync_objformat_get_name, "osync_objformat_get_name");
1488 LoadSym(p->osync_objformat_get_objtype, "osync_objformat_get_objtype");
1489 LoadSym(p->osync_group_new, "osync_group_new");
1490 LoadSym(p->osync_group_unref, "osync_group_unref");
1491 LoadSym(p->osync_group_set_name, "osync_group_set_name");
1492 LoadSym(p->osync_group_env_add_group, "osync_group_env_add_group");
1493 LoadSym(p->osync_group_save, "osync_group_save");
1494 LoadSym(p->osync_group_delete, "osync_group_delete");
1495 LoadSym(p->osync_group_env_remove_group,"osync_group_env_remove_group");
1496 LoadSym(p->osync_plugin_env_find_plugin,"osync_plugin_env_find_plugin");
1497 LoadSym(p->osync_member_unref, "osync_member_unref");
1498 LoadSym(p->osync_member_new, "osync_member_new");
1499 LoadSym(p->osync_group_add_member, "osync_group_add_member");
1500 LoadSym(p->osync_member_set_pluginname, "osync_member_set_pluginname");
1501 LoadSym(p->osync_member_set_name, "osync_member_set_name");
1502 LoadSym(p->osync_member_save, "osync_member_save");
1503 LoadSym(p->osync_group_find_member, "osync_group_find_member");
1504 LoadSym(p->osync_member_delete, "osync_member_delete");
1505 LoadSym(p->osync_group_remove_member, "osync_group_remove_member");
1506 LoadSym(p->osync_plugin_config_new, "osync_plugin_config_new");
1507 LoadSym(p->osync_plugin_config_file_load,
1508 "osync_plugin_config_file_load");
1509 LoadSym(p->osync_member_set_config, "osync_member_set_config");
1510 LoadSym(p->osync_member_get_config_or_default,
1511 "osync_member_get_config_or_default");
1512 LoadSym(p->osync_plugin_config_file_save,
1513 "osync_plugin_config_file_save");
1514 LoadSym(p->osync_plugin_get_config_type,"osync_plugin_get_config_type");
1515 LoadSym(p->osync_engine_new, "osync_engine_new");
1516 LoadSym(p->osync_engine_unref, "osync_engine_unref");
1517 LoadSym(p->osync_engine_discover_and_block,
1518 "osync_engine_discover_and_block");
1519 LoadSym(p->osync_member_get_objtypes, "osync_member_get_objtypes");
1520 LoadSym(p->osync_list_length, "osync_list_length");
1521 LoadSym(p->osync_error_set, "osync_error_set");
1522 LoadSym(p->osync_engine_finalize, "osync_engine_finalize");
1523 LoadSym(p->osync_mapping_engine_get_changes,
1524 "osync_mapping_engine_get_changes");
1525 LoadSym(p->osync_mapping_engine_supports_ignore,
1526 "osync_mapping_engine_supports_ignore");
1527 LoadSym(p->osync_mapping_engine_supports_use_latest,
1528 "osync_mapping_engine_supports_use_latest");
1529 LoadSym(p->osync_list_nth, "osync_list_nth");
1530 LoadSym(p->osync_engine_mapping_solve, "osync_engine_mapping_solve");
1531 LoadSym(p->osync_engine_abort, "osync_engine_abort");
1532 LoadSym(p->osync_engine_mapping_duplicate,
1533 "osync_engine_mapping_duplicate");
1534 LoadSym(p->osync_engine_mapping_ignore_conflict,
1535 "osync_engine_mapping_ignore_conflict");
1536 LoadSym(p->osync_engine_mapping_use_latest,
1537 "osync_engine_mapping_use_latest");
1538 LoadSym(p->osync_change_get_changetype, "osync_change_get_changetype");
1539 LoadSym(p->osync_mapping_engine_change_find_member,
1540 "osync_mapping_engine_change_find_member");
1541 LoadSym(p->osync_change_get_data, "osync_change_get_data");
1542 LoadSym(p->osync_data_get_printable, "osync_data_get_printable");
1543 LoadSym(p->osync_free, "osync_free");
1544 LoadSym(p->osync_change_get_uid, "osync_change_get_uid");
1545 LoadSym(p->osync_engine_continue, "osync_engine_continue");
1546 LoadSym(p->osync_engine_get_objengines, "osync_engine_get_objengines");
1547 LoadSym(p->osync_obj_engine_get_members,
1548 "osync_obj_engine_get_members");
1549 LoadSym(p->osync_obj_engine_get_objtype,
1550 "osync_obj_engine_get_objtype");
1551 LoadSym(p->osync_obj_engine_get_mapping_entry_engines_of_member,
1552 "osync_obj_engine_get_mapping_entry_engines_of_member");
1553 LoadSym(p->osync_entry_engine_is_dirty,"osync_entry_engine_is_dirty");
1554 LoadSym(p->osync_entry_engine_get_changetype,
1555 "osync_entry_engine_get_changetype");
1556 LoadSym(p->osync_engine_change_update_get_change,
1557 "osync_engine_change_update_get_change");
1558 LoadSym(p->osync_engine_change_update_get_member,
1559 "osync_engine_change_update_get_member");
1560 LoadSym(p->osync_engine_change_update_get_error,
1561 "osync_engine_change_update_get_error");
1562 LoadSym(p->osync_engine_change_update_get_event,
1563 "osync_engine_change_update_get_event");
1564 LoadSym(p->osync_change_get_objformat, "osync_change_get_objformat");
1565 LoadSym(p->osync_engine_mapping_update_get_error,
1566 "osync_engine_mapping_update_get_error");
1567 LoadSym(p->osync_engine_update_get_error,
1568 "osync_engine_update_get_error");
1569 LoadSym(p->osync_engine_update_get_event,
1570 "osync_engine_update_get_event");
1571 LoadSym(p->osync_engine_member_update_get_objtype,
1572 "osync_engine_member_update_get_objtype");
1573 LoadSym(p->osync_engine_member_update_get_member,
1574 "osync_engine_member_update_get_member");
1575 LoadSym(p->osync_engine_member_update_get_error,
1576 "osync_engine_member_update_get_error");
1577 LoadSym(p->osync_engine_member_update_get_event,
1578 "osync_engine_member_update_get_event");
1579 LoadSym(p->osync_engine_set_conflict_callback,
1580 "osync_engine_set_conflict_callback");
1581 LoadSym(p->osync_engine_set_changestatus_callback,
1582 "osync_engine_set_changestatus_callback");
1583 LoadSym(p->osync_engine_set_mappingstatus_callback,
1584 "osync_engine_set_mappingstatus_callback");
1585 LoadSym(p->osync_engine_set_enginestatus_callback,
1586 "osync_engine_set_enginestatus_callback");
1587 LoadSym(p->osync_engine_set_memberstatus_callback,
1588 "osync_engine_set_memberstatus_callback");
1589 LoadSym(p->osync_engine_set_multiply_callback,
1590 "osync_engine_set_multiply_callback");
1591 LoadSym(p->osync_engine_initialize, "osync_engine_initialize");
1592 LoadSym(p->osync_engine_synchronize_and_block,
1593 "osync_engine_synchronize_and_block");
1594 LoadSym(p->osync_engine_mapping_update_get_event,
1595 "osync_engine_mapping_update_get_event");
1596 LoadSym(p->osync_plugin_resource_unref,
1597 "osync_plugin_resource_unref");
1598 LoadSym(p->osync_plugin_config_add_resource,
1599 "osync_plugin_config_add_resource");
1600 LoadSym(p->osync_plugin_resource_is_enabled,
1601 "osync_plugin_resource_is_enabled");
1602 LoadSym(p->osync_plugin_resource_enable,
1603 "osync_plugin_resource_enable");
1604 LoadSym(p->osync_plugin_resource_get_objformat_sinks,
1605 "osync_plugin_resource_get_objformat_sinks");
1606 LoadSym(p->osync_objformat_sink_get_objformat,
1607 "osync_objformat_sink_get_objformat");
1608 LoadSym(p->osync_objformat_sink_get_config,
1609 "osync_objformat_sink_get_config");
1610 LoadSym(p->osync_objformat_sink_set_config,
1611 "osync_objformat_sink_set_config");
1612 LoadSym(p->osync_objformat_sink_new,
1613 "osync_objformat_sink_new");
1614 LoadSym(p->osync_plugin_resource_add_objformat_sink,
1615 "osync_plugin_resource_add_objformat_sink");
1616 LoadSym(p->osync_objformat_sink_unref,
1617 "osync_objformat_sink_unref");
1618 LoadSym(p->osync_plugin_resource_get_preferred_format,
1619 "osync_plugin_resource_get_preferred_format");
1620 LoadSym(p->osync_plugin_resource_set_preferred_format,
1621 "osync_plugin_resource_set_preferred_format");
1622 LoadSym(p->osync_plugin_resource_get_mime,
1623 "osync_plugin_resource_get_mime");
1624 LoadSym(p->osync_plugin_resource_set_mime,
1625 "osync_plugin_resource_set_mime");
1626 LoadSym(p->osync_plugin_resource_get_objtype,
1627 "osync_plugin_resource_get_objtype");
1628 LoadSym(p->osync_plugin_resource_set_objtype,
1629 "osync_plugin_resource_set_objtype");
1630 LoadSym(p->osync_plugin_resource_get_path,
1631 "osync_plugin_resource_get_path");
1632 LoadSym(p->osync_plugin_resource_set_path,
1633 "osync_plugin_resource_set_path");
1634 LoadSym(p->osync_plugin_resource_get_url,
1635 "osync_plugin_resource_get_url");
1636 LoadSym(p->osync_plugin_resource_set_url,
1637 "osync_plugin_resource_set_url");
1638 LoadSym(p->osync_plugin_config_get_advancedoption_value_by_name,
1639 "osync_plugin_config_get_advancedoption_value_by_name");
1640 LoadSym(p->osync_plugin_config_get_advancedoptions,
1641 "osync_plugin_config_get_advancedoptions");
1642 LoadSym(p->osync_plugin_config_add_advancedoption,
1643 "osync_plugin_config_add_advancedoption");
1644 LoadSym(p->osync_plugin_advancedoption_new,
1645 "osync_plugin_advancedoption_new");
1646 LoadSym(p->osync_plugin_advancedoption_unref,
1647 "osync_plugin_advancedoption_unref");
1648 LoadSym(p->osync_plugin_advancedoption_get_name,
1649 "osync_plugin_advancedoption_get_name");
1650 LoadSym(p->osync_plugin_advancedoption_set_name,
1651 "osync_plugin_advancedoption_set_name");
1652 LoadSym(p->osync_plugin_advancedoption_set_displayname,
1653 "osync_plugin_advancedoption_set_displayname");
1654 LoadSym(p->osync_plugin_advancedoption_set_type,
1655 "osync_plugin_advancedoption_set_type");
1656 LoadSym(p->osync_plugin_advancedoption_set_value,
1657 "osync_plugin_advancedoption_set_value");
1658 LoadSym(p->osync_plugin_config_get_resources,
1659 "osync_plugin_config_get_resources");
1660 LoadSym(p->osync_plugin_resource_ref,
1661 "osync_plugin_resource_ref");
1662 LoadSym(p->osync_plugin_resource_new,
1663 "osync_plugin_resource_new");
1664 LoadSym(p->osync_plugin_resource_get_name,
1665 "osync_plugin_resource_get_name");
1666 LoadSym(p->osync_plugin_resource_set_name,
1667 "osync_plugin_resource_set_name");
1668 LoadSym(p->osync_plugin_config_get_authentication,
1669 "osync_plugin_config_get_authentication");
1670 LoadSym(p->osync_plugin_authentication_get_password,
1671 "osync_plugin_authentication_get_password");
1672 LoadSym(p->osync_plugin_authentication_new,
1673 "osync_plugin_authentication_new");
1674 LoadSym(p->osync_plugin_authentication_option_is_supported,
1675 "osync_plugin_authentication_option_is_supported");
1676 LoadSym(p->osync_plugin_authentication_unref,
1677 "osync_plugin_authentication_unref");
1678 LoadSym(p->osync_plugin_config_set_authentication,
1679 "osync_plugin_config_set_authentication");
1680 LoadSym(p->osync_plugin_authentication_set_password,
1681 "osync_plugin_authentication_set_password");
1683 // fixup free pointers
1684 p->group_env.SetFreeFunc(p->osync_group_env_unref);
1685 p->format_env.SetFreeFunc(p->osync_format_env_unref);
1686 p->plugin_env.SetFreeFunc(p->osync_plugin_env_unref);
1688 // setup opensync support environment
1689 SetupEnvironment(p.get());
1691 // this pointer is ours now
1692 m_priv = p.release();
1695 OpenSync40::~OpenSync40()
1697 delete m_priv;
1698 m_priv = 0;
1701 void OpenSync40::SetupEnvironment(OpenSync40Private *p)
1703 // allocate group, format, and env
1704 p->group_env = p->osync_group_env_new(p->error);
1705 if( !p->group_env.get() )
1706 throw std::runtime_error(p->error.GetErrorMsg());
1708 p->format_env = p->osync_format_env_new(p->error);
1709 if( !p->format_env.get() )
1710 throw std::runtime_error(p->error.GetErrorMsg());
1712 p->plugin_env = p->osync_plugin_env_new(p->error);
1713 if( !p->plugin_env.get() )
1714 throw std::runtime_error(p->error.GetErrorMsg());
1716 // load group, format, and env
1717 if( !p->osync_group_env_load_groups(p->group_env.get(), NULL, p->error) ||
1718 !p->osync_format_env_load_plugins(p->format_env.get(), NULL, p->error) ||
1719 !p->osync_plugin_env_load(p->plugin_env.get(), NULL, p->error) )
1720 throw std::runtime_error(p->error.GetErrorMsg());
1723 const char* OpenSync40::GetVersion() const
1725 return m_priv->osync_get_version();
1728 const char* OpenSync40::GetEngineName() const
1730 return "0.40";
1733 void OpenSync40::GetPluginNames(string_list_type &plugins)
1735 // start fresh
1736 plugins.clear();
1738 OSyncPlugin *plugin;
1739 OSyncList *plugin_list, *p;
1741 plugin_list = m_priv->osync_plugin_env_get_plugins(m_priv->plugin_env.get());
1742 for( p = plugin_list; p; p = p->next ) {
1743 plugin = (OSyncPlugin *) p->data;
1744 plugins.push_back(m_priv->osync_plugin_get_name(plugin));
1747 m_priv->osync_list_free(plugin_list);
1750 void OpenSync40::GetFormats(format_list_type &formats)
1752 // start fresh
1753 formats.clear();
1755 OSyncList *o, *list = m_priv->osync_format_env_get_objformats(m_priv->format_env.get());
1757 for( o = list; o; o = o->next ) {
1758 OSyncObjFormat *format = (OSyncObjFormat *) o->data;
1760 Format new_format;
1761 new_format.name = m_priv->osync_objformat_get_name(format);
1762 new_format.object_type = m_priv->osync_objformat_get_objtype(format);
1764 formats.push_back(new_format);
1767 m_priv->osync_list_free(list);
1770 void OpenSync40::GetGroupNames(string_list_type &groups)
1772 // start fresh
1773 groups.clear();
1775 OSyncGroup *group;
1776 OSyncList *g, *group_list = m_priv->osync_group_env_get_groups(m_priv->group_env.get());
1778 for( g = group_list; g; g = g->next ) {
1779 group = (OSyncGroup *) g->data;
1780 groups.push_back(m_priv->osync_group_get_name(group));
1783 m_priv->osync_list_free(group_list);
1786 void OpenSync40::GetMembers(const std::string &group_name,
1787 member_list_type &members)
1789 // start fresh
1790 members.clear();
1792 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1793 if( !group ) {
1794 ostringstream oss;
1795 oss << "GetMembers: Unable to find group with name: " << group_name;
1796 throw std::runtime_error(oss.str());
1799 OSyncList *member_list = m_priv->osync_group_get_members(group);
1800 for( OSyncList *m = member_list; m; m = m->next ) {
1801 Member new_member;
1802 OSyncMember *member = (OSyncMember *) m->data;
1803 const char *membername = m_priv->osync_member_get_name(member);
1804 if (membername) {
1805 new_member.friendly_name = membername;
1808 new_member.group_name = group_name;
1809 new_member.id = m_priv->osync_member_get_id(member);
1810 new_member.plugin_name = m_priv->osync_member_get_pluginname(member);
1812 // add to member list
1813 members.push_back(new_member);
1816 // cleanup
1817 m_priv->osync_list_free(member_list);
1820 void OpenSync40::AddGroup(const std::string &group_name)
1822 OSyncGroup *group = m_priv->osync_group_new(m_priv->error);
1823 if( !group )
1824 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1826 m_priv->osync_group_set_name(group, group_name.c_str());
1827 if( !m_priv->osync_group_env_add_group(m_priv->group_env.get(), group, m_priv->error) ) {
1828 m_priv->osync_group_unref(group);
1829 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1832 if( !m_priv->osync_group_save(group, m_priv->error) ) {
1833 m_priv->osync_group_unref(group);
1834 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1837 m_priv->osync_group_unref(group);
1840 void OpenSync40::DeleteGroup(const std::string &group_name)
1842 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1843 if( !group )
1844 throw std::runtime_error("DeleteGroup(): Group not found: " + group_name);
1846 if( !m_priv->osync_group_delete(group, m_priv->error) )
1847 throw std::runtime_error("DeleteGroup(): " + m_priv->error.GetErrorMsg());
1849 m_priv->osync_group_env_remove_group(m_priv->group_env.get(), group);
1852 Converter& OpenSync40::GetConverter()
1854 return m_priv->converter;
1857 long OpenSync40::AddMember(const std::string &group_name,
1858 const std::string &plugin_name,
1859 const std::string &member_name)
1861 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1862 if( !group )
1863 throw std::runtime_error("AddMember(): Group not found: " + group_name);
1865 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), plugin_name.c_str());
1866 if( !plugin )
1867 throw std::runtime_error("AddMember(): Plugin not found: " + plugin_name);
1869 vLateSmartPtr<OSyncMember, void(*)(OSyncMember*)> mptr(m_priv->osync_member_unref);
1870 mptr = m_priv->osync_member_new(m_priv->error);
1871 if( !mptr.get() )
1872 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1874 m_priv->osync_group_add_member(group, mptr.get());
1875 m_priv->osync_member_set_pluginname(mptr.get(), plugin_name.c_str());
1877 if( member_name.size() )
1878 m_priv->osync_member_set_name(mptr.get(), member_name.c_str());
1880 if( !m_priv->osync_member_save(mptr.get(), m_priv->error) )
1881 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1883 return m_priv->osync_member_get_id(mptr.get());
1886 void OpenSync40::DeleteMember(const std::string &group_name, long member_id)
1888 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1889 if( !group )
1890 throw std::runtime_error("DeleteMember(): Group not found: " + group_name);
1892 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1893 if( !member ) {
1894 ostringstream oss;
1895 oss << "DeleteMember(): Member " << member_id << " not found.";
1896 throw std::runtime_error(oss.str());
1899 if( !m_priv->osync_member_delete(member, m_priv->error) )
1900 throw std::runtime_error("DeleteMember(): " + m_priv->error.GetErrorMsg());
1902 m_priv->osync_group_remove_member(group, member);
1905 void OpenSync40::DeleteMember(const std::string &group_name,
1906 const std::string &plugin_name)
1908 member_list_type mlist;
1909 GetMembers(group_name, mlist);
1910 Member *member = mlist.Find(plugin_name.c_str());
1911 if( !member )
1912 throw std::runtime_error("DeleteMember(): Member not found: " + plugin_name);
1914 DeleteMember(group_name, member->id);
1917 bool OpenSync40::IsConfigurable(const std::string &group_name,
1918 long member_id)
1920 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1921 if( !group )
1922 throw std::runtime_error("IsConfigurable(): Group not found: " + group_name);
1924 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1925 if( !member ) {
1926 ostringstream oss;
1927 oss << "IsConfigurable(): Member " << member_id << " not found.";
1928 throw std::runtime_error(oss.str());
1931 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
1932 if( !plugin )
1933 throw std::runtime_error(string("IsConfigurable(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
1936 OSyncPluginConfigurationType type = m_priv->osync_plugin_get_config_type(plugin);
1937 return type != OSYNC_PLUGIN_NO_CONFIGURATION;
1940 std::string OpenSync40::GetConfiguration(const std::string &group_name,
1941 long member_id)
1943 if( !IsConfigurable(group_name, member_id) ) {
1944 ostringstream oss;
1945 oss << "GetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
1946 throw std::runtime_error(oss.str());
1949 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1950 if( !group )
1951 throw std::runtime_error("GetConfiguration(): Group not found: " + group_name);
1953 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1954 if( !member ) {
1955 ostringstream oss;
1956 oss << "GetConfiguration(): Member " << member_id << " not found.";
1957 throw std::runtime_error(oss.str());
1960 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
1961 if( !plugin )
1962 throw std::runtime_error(string("GetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
1965 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
1966 if( !config )
1967 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
1969 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
1970 // functions, and then load that from the file again, and
1971 // return that string as the configuratin.
1973 TempDir tempdir("opensyncapi");
1975 string filename = tempdir.GetNewFilename();
1977 if( !m_priv->osync_plugin_config_file_save(config, filename.c_str(), m_priv->error) )
1978 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
1980 ifstream in(filename.c_str());
1981 string config_data;
1982 char buf[4096];
1983 while( in ) {
1984 in.read(buf, sizeof(buf));
1985 config_data.append(buf, in.gcount());
1988 return config_data;
1991 OS40PluginConfig OpenSync40::GetConfigurationObj(const std::string &group_name,
1992 long member_id)
1994 if( !IsConfigurable(group_name, member_id) ) {
1995 ostringstream oss;
1996 oss << "GetConfigurationObj(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
1997 throw std::runtime_error(oss.str());
2000 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2001 if( !group )
2002 throw std::runtime_error("GetConfigurationObj(): Group not found: " + group_name);
2004 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2005 if( !member ) {
2006 ostringstream oss;
2007 oss << "GetConfigurationObj(): Member " << member_id << " not found.";
2008 throw std::runtime_error(oss.str());
2011 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2012 if( !plugin )
2013 throw std::runtime_error(string("GetConfigurationObj(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2016 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2017 if( !config )
2018 throw std::runtime_error("GetConfigurationObj(): " + m_priv->error.GetErrorMsg());
2020 return OS40PluginConfig(m_priv, member, config);
2023 void OpenSync40::SetConfiguration(const std::string &group_name,
2024 long member_id,
2025 const std::string &config_data)
2027 if( !IsConfigurable(group_name, member_id) ) {
2028 ostringstream oss;
2029 oss << "SetConfiguration(): Member " << member_id << " of group '" << group_name << "' does not accept configuration.";
2030 throw std::runtime_error(oss.str());
2033 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2034 if( !group )
2035 throw std::runtime_error("SetConfiguration(): Group not found: " + group_name);
2037 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2038 if( !member ) {
2039 ostringstream oss;
2040 oss << "SetConfiguration(): Member " << member_id << " not found.";
2041 throw std::runtime_error(oss.str());
2044 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2045 if( !plugin )
2046 throw std::runtime_error(string("SetConfiguration(): Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2049 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2050 // functions, and then load that from the file again, and
2051 // return that string as the configuratin.
2053 TempDir tempdir("opensyncapi");
2055 string filename = tempdir.GetNewFilename();
2057 // write config data to file
2059 ofstream out(filename.c_str());
2060 out << config_data;
2063 // load brand new config from file
2064 // if a new config object isn't created here, the loaded config
2065 // will be added to the existing config
2066 OSyncPluginConfig *new_config = m_priv->osync_plugin_config_new(m_priv->error);
2067 if( !m_priv->osync_plugin_config_file_load(new_config, filename.c_str(), m_priv->error) )
2068 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2070 m_priv->osync_member_set_config(member, new_config);
2072 if( !m_priv->osync_member_save(member, m_priv->error))
2073 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2076 void OpenSync40::Discover(const std::string &group_name)
2078 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2079 if( !group )
2080 throw std::runtime_error("Discover(): Group not found: " + group_name);
2082 EngineHandle engine(m_priv->osync_engine_unref);
2083 engine = m_priv->osync_engine_new(group, m_priv->error);
2084 if( !engine.get() )
2085 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2087 SyncListHandle members(m_priv->osync_list_free);
2088 members = m_priv->osync_group_get_members(group);
2089 OSyncList *m = NULL;
2090 for( m = members.get(); m; m = m->next ) {
2091 OSyncMember *member = (OSyncMember *) m->data;
2093 /* Discover the objtypes for the members */
2094 if( !m_priv->osync_engine_discover_and_block(engine.get(), member, m_priv->error))
2095 break;
2097 SyncListHandle objtypes(m_priv->osync_list_free);
2098 objtypes = m_priv->osync_member_get_objtypes(member);
2099 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2100 m_priv->osync_error_set(m_priv->error, OSYNC_ERROR_GENERIC, "discover failed: no objtypes returned");
2101 break;
2104 if( !m_priv->osync_member_save(member, m_priv->error) )
2105 break;
2108 // check for error
2109 if( m ) {
2110 m_priv->osync_engine_finalize(engine.get(), m_priv->error);
2111 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2115 void OpenSync40::Sync(const std::string &group_name,
2116 SyncStatus &status_callback)
2118 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2119 if( !group )
2120 throw std::runtime_error("Sync(): Group not found: " + group_name);
2122 EngineHandle engine(m_priv->osync_engine_unref);
2123 engine = m_priv->osync_engine_new(group, m_priv->error);
2124 if( !engine.get() )
2125 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2128 CallbackBundle cbdata(m_priv, status_callback);
2130 m_priv->osync_engine_set_conflict_callback(engine.get(), conflict_handler, &cbdata);
2131 m_priv->osync_engine_set_changestatus_callback(engine.get(), entry_status, &cbdata);
2132 m_priv->osync_engine_set_mappingstatus_callback(engine.get(), mapping_status, &cbdata);
2133 m_priv->osync_engine_set_enginestatus_callback(engine.get(), engine_status, &cbdata);
2134 m_priv->osync_engine_set_memberstatus_callback(engine.get(), member_status, &cbdata);
2135 m_priv->osync_engine_set_multiply_callback(engine.get(), multiply_summary, &cbdata);
2138 SyncListHandle members(m_priv->osync_list_free);
2139 members = m_priv->osync_group_get_members(group);
2140 OSyncList *m = NULL;
2141 for( m = members.get(); m; m = m->next ) {
2142 OSyncMember *member = (OSyncMember *) m->data;
2144 SyncListHandle objtypes(m_priv->osync_list_free);
2145 objtypes = m_priv->osync_member_get_objtypes(member);
2146 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2147 cout << "Sync(): Member " << m_priv->osync_member_get_id(member) << " has no objtypes. Has it already been discovered?" << endl;
2151 if( !m_priv->osync_engine_initialize(engine.get(), m_priv->error) )
2152 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2154 if( !m_priv->osync_engine_synchronize_and_block(engine.get(), m_priv->error) ) {
2155 m_priv->osync_engine_finalize(engine.get(), NULL);
2156 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2159 if( !m_priv->osync_engine_finalize(engine.get(), m_priv->error) )
2160 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2164 /////////////////////////////////////////////////////////////////////////////
2165 // TossError public members
2167 /// Returns NULL if no error
2168 std::string TossError::GetErrorMsg()
2170 return std::string(m_priv->osync_error_print(&m_error));
2173 bool TossError::IsSet()
2175 return m_priv->osync_error_is_set(&m_error);
2178 void TossError::Clear()
2180 if( m_error ) {
2181 m_priv->osync_error_unref(&m_error);
2182 m_error = 0;
2186 } // namespace OpenSync