Bumped copyright dates for 2013
[barry.git] / desktop / src / os40.cc
blob89eb3332f2248de31abcc3981027d3634e6fed5f
1 ///
2 /// \file os40.cc
3 /// Wrapper class for opensync 0.22 syncing behaviour
4 ///
6 /*
7 Copyright (C) 2009-2013, 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 <barry/common.h>
37 #include <iostream>
38 #include <sstream>
39 #include <fstream>
40 #include <errno.h>
41 #include <glib.h>
42 #include "i18n.h"
44 // use relative paths to backtrack enough to specify only 0.4x includes
45 #include <../libopensync1/opensync/opensync.h>
46 #include <../libopensync1/opensync/opensync-group.h>
47 #include <../libopensync1/opensync/opensync-format.h>
48 #include <../libopensync1/opensync/opensync-plugin.h>
49 #include <../libopensync1/opensync/opensync-engine.h>
50 #include <../libopensync1/opensync/opensync-data.h>
51 #include <../libopensync1/opensync/opensync-capabilities.h>
53 using namespace std;
54 using namespace Barry;
56 namespace OpenSync {
59 typedef Barry::vLateSmartPtr<OSyncEngine, void(*)(OSyncEngine*)> EngineHandle;
60 typedef Barry::vLateSmartPtr<OSyncList, void(*)(OSyncList*)> SyncListHandle;
64 // Private class declarations
68 class TossError
70 OSyncError *m_error;
71 OpenSync40Private *m_priv;
73 public:
74 // simple wrapper... unref's the error on destruction
75 TossError(OpenSync40Private *priv)
76 : m_error(0)
77 , m_priv(priv)
81 ~TossError()
83 Clear();
86 /// Returns NULL if no error
87 std::string GetErrorMsg();
88 bool IsSet();
89 void Clear();
91 operator OSyncError**()
93 return &m_error;
97 class OpenSync40Private
99 public:
100 // function pointers
101 const char* (*osync_get_version)();
102 const char* (*osync_error_print)(OSyncError **error);
103 char* (*osync_error_print_stack)(OSyncError **error);
104 osync_bool (*osync_error_is_set)(OSyncError **error);
105 void (*osync_error_unref)(OSyncError **error);
106 OSyncGroupEnv* (*osync_group_env_new)(OSyncError **error);
107 OSyncFormatEnv* (*osync_format_env_new)(OSyncError **error);
108 OSyncPluginEnv* (*osync_plugin_env_new)(OSyncError **error);
109 void (*osync_group_env_unref)(OSyncGroupEnv *env);
110 void (*osync_format_env_unref)(OSyncFormatEnv *env);
111 void (*osync_plugin_env_unref)(OSyncPluginEnv *env);
112 osync_bool (*osync_plugin_env_load)(OSyncPluginEnv *env,
113 const char *path, OSyncError **error);
114 OSyncList* (*osync_plugin_env_get_plugins)(
115 OSyncPluginEnv *env);
116 const char* (*osync_plugin_get_name)(OSyncPlugin *plugin);
117 void (*osync_list_free)(OSyncList *list);
118 osync_bool (*osync_group_env_load_groups)(
119 OSyncGroupEnv *env, const char *path,
120 OSyncError **error);
121 osync_bool (*osync_format_env_load_plugins)(
122 OSyncFormatEnv *env, const char *path,
123 OSyncError **error);
124 OSyncList* (*osync_group_env_get_groups)(
125 OSyncGroupEnv *env);
126 const char* (*osync_group_get_name)(OSyncGroup *group);
127 OSyncGroup* (*osync_group_env_find_group)(
128 OSyncGroupEnv *env, const char *name);
129 OSyncList* (*osync_group_get_members)(OSyncGroup *group);
130 const char* (*osync_member_get_name)(OSyncMember *member);
131 osync_memberid (*osync_member_get_id)(OSyncMember *member);
132 const char* (*osync_member_get_pluginname)(
133 OSyncMember *member);
134 OSyncList* (*osync_format_env_get_objformats)(
135 OSyncFormatEnv *env);
136 const char* (*osync_objformat_get_name)(
137 OSyncObjFormat *format);
138 const char* (*osync_objformat_get_objtype)(
139 OSyncObjFormat *format);
140 OSyncGroup* (*osync_group_new)(OSyncError **error);
141 void (*osync_group_unref)(OSyncGroup *group);
142 void (*osync_group_set_name)(OSyncGroup *group,
143 const char *name);
144 osync_bool (*osync_group_env_add_group)(OSyncGroupEnv *env,
145 OSyncGroup *group,
146 OSyncError **error);
147 osync_bool (*osync_group_save)(OSyncGroup *group,
148 OSyncError **error);
149 osync_bool (*osync_group_delete)(OSyncGroup *group,
150 OSyncError **error);
151 void (*osync_group_env_remove_group)(
152 OSyncGroupEnv *env, OSyncGroup *group);
153 OSyncPlugin* (*osync_plugin_env_find_plugin)(
154 OSyncPluginEnv *env, const char *name);
155 void (*osync_member_unref)(OSyncMember *member);
156 OSyncMember* (*osync_member_new)(OSyncError **error);
157 void (*osync_group_add_member)(OSyncGroup *group,
158 OSyncMember *member);
159 void (*osync_member_set_pluginname)(
160 OSyncMember *member,
161 const char *pluginname);
162 void (*osync_member_set_name)(OSyncMember *member,
163 const char *name);
164 osync_bool (*osync_member_save)(OSyncMember *member,
165 OSyncError **error);
166 OSyncMember* (*osync_group_find_member)(OSyncGroup *group,
167 osync_memberid id);
168 osync_bool (*osync_member_delete)(OSyncMember *member,
169 OSyncError **error);
170 void (*osync_group_remove_member)(OSyncGroup *group,
171 OSyncMember *member);
172 OSyncPluginConfig* (*osync_plugin_config_new)(OSyncError **error);
173 osync_bool (*osync_plugin_config_file_load)(
174 OSyncPluginConfig *config,
175 const char *path,
176 OSyncError **error);
177 void (*osync_member_set_config)(OSyncMember *member,
178 OSyncPluginConfig *config);
179 OSyncPluginConfig* (*osync_member_get_config_or_default)(
180 OSyncMember *member,
181 OSyncError **error);
182 osync_bool (*osync_plugin_config_file_save)(
183 OSyncPluginConfig *config,
184 const char *path, OSyncError **error);
185 OSyncPluginConfigurationType (*osync_plugin_get_config_type)(
186 OSyncPlugin *plugin);
187 OSyncEngine* (*osync_engine_new)(OSyncGroup *group,
188 OSyncError **error);
189 void (*osync_engine_unref)(OSyncEngine *engine);
190 osync_bool (*osync_engine_discover_and_block)(
191 OSyncEngine *engine,
192 OSyncMember *member,
193 OSyncError **error);
194 OSyncList* (*osync_member_get_objtypes)(
195 OSyncMember *member);
196 unsigned int (*osync_list_length)(const OSyncList *list);
197 void (*osync_error_set)(OSyncError **error,
198 OSyncErrorType type,
199 const char *format, ...);
200 osync_bool (*osync_engine_finalize)(OSyncEngine *engine,
201 OSyncError **error);
202 OSyncList* (*osync_mapping_engine_get_changes)(
203 OSyncMappingEngine *engine);
204 osync_bool (*osync_mapping_engine_supports_ignore)(
205 OSyncMappingEngine *engine);
206 osync_bool (*osync_mapping_engine_supports_use_latest)(
207 OSyncMappingEngine *engine);
208 OSyncList* (*osync_list_nth)(OSyncList *list,
209 unsigned int n);
210 osync_bool (*osync_engine_mapping_solve)(
211 OSyncEngine *engine,
212 OSyncMappingEngine *mapping_engine,
213 OSyncChange *change,
214 OSyncError **error);
215 osync_bool (*osync_engine_abort)(OSyncEngine *engine,
216 OSyncError **error);
217 osync_bool (*osync_engine_mapping_duplicate)(
218 OSyncEngine *engine,
219 OSyncMappingEngine *mapping_engine,
220 OSyncError **error);
221 osync_bool (*osync_engine_mapping_ignore_conflict)(
222 OSyncEngine *engine,
223 OSyncMappingEngine *mapping_engine,
224 OSyncError **error);
225 osync_bool (*osync_engine_mapping_use_latest)(
226 OSyncEngine *engine,
227 OSyncMappingEngine *mapping_engine,
228 OSyncError **error);
229 OSyncChangeType (*osync_change_get_changetype)(
230 OSyncChange *change);
231 OSyncMember* (*osync_mapping_engine_change_find_member)(
232 OSyncMappingEngine *engine,
233 OSyncChange *change);
234 OSyncData* (*osync_change_get_data)(OSyncChange *change);
235 char* (*osync_data_get_printable)(OSyncData *data,
236 OSyncError **error);
237 void (*osync_free)(void *ptr);
238 const char* (*osync_change_get_uid)(OSyncChange *change);
239 osync_bool (*osync_engine_continue)(OSyncEngine *engine,
240 OSyncError **error);
241 OSyncList* (*osync_engine_get_objengines)(
242 OSyncEngine *engine);
243 OSyncList* (*osync_obj_engine_get_members)(
244 OSyncObjEngine* engine);
245 const char* (*osync_obj_engine_get_objtype)(
246 OSyncObjEngine *engine);
247 const OSyncList* (*osync_obj_engine_get_mapping_entry_engines_of_member)(
248 OSyncObjEngine *engine,
249 OSyncMember *member);
250 osync_bool (*osync_entry_engine_is_dirty)(
251 OSyncMappingEntryEngine *engine);
252 OSyncChangeType (*osync_entry_engine_get_changetype)(
253 OSyncMappingEntryEngine *engine);
254 OSyncChange* (*osync_engine_change_update_get_change)(
255 OSyncEngineChangeUpdate *update);
256 OSyncMember* (*osync_engine_change_update_get_member)(
257 OSyncEngineChangeUpdate *update);
258 OSyncError* (*osync_engine_change_update_get_error)(
259 OSyncEngineChangeUpdate *update);
260 OSyncEngineChangeEvent (*osync_engine_change_update_get_event)(
261 OSyncEngineChangeUpdate *update);
262 OSyncObjFormat* (*osync_change_get_objformat)(
263 OSyncChange *change);
264 OSyncError* (*osync_engine_mapping_update_get_error)(
265 OSyncEngineMappingUpdate *update);
266 OSyncError* (*osync_engine_update_get_error)(
267 OSyncEngineUpdate *update);
268 OSyncEngineEvent (*osync_engine_update_get_event)(
269 OSyncEngineUpdate *update);
270 const char* (*osync_engine_member_update_get_objtype)(
271 OSyncEngineMemberUpdate *update);
272 OSyncMember* (*osync_engine_member_update_get_member)(
273 OSyncEngineMemberUpdate *update);
274 OSyncError* (*osync_engine_member_update_get_error)(
275 OSyncEngineMemberUpdate *update);
276 OSyncEngineMemberEvent (*osync_engine_member_update_get_event)(
277 OSyncEngineMemberUpdate *update);
278 void (*osync_engine_set_conflict_callback)(
279 OSyncEngine *engine,
280 osync_conflict_cb callback,
281 void *user_data);
282 void (*osync_engine_set_changestatus_callback)(
283 OSyncEngine *engine,
284 osync_status_change_cb callback,
285 void *user_data);
286 void (*osync_engine_set_mappingstatus_callback)(
287 OSyncEngine *engine,
288 osync_status_mapping_cb callback,
289 void *user_data);
290 void (*osync_engine_set_enginestatus_callback)(
291 OSyncEngine *engine,
292 osync_status_engine_cb callback,
293 void *user_data);
294 void (*osync_engine_set_memberstatus_callback)(
295 OSyncEngine *engine,
296 osync_status_member_cb callback,
297 void *user_data);
298 void (*osync_engine_set_multiply_callback)(
299 OSyncEngine *engine,
300 osync_multiply_cb callback,
301 void *user_data);
302 osync_bool (*osync_engine_initialize)(OSyncEngine *engine,
303 OSyncError **error);
304 osync_bool (*osync_engine_synchronize_and_block)(
305 OSyncEngine *engine,OSyncError **error);
306 OSyncEngineMappingEvent (*osync_engine_mapping_update_get_event)(
307 OSyncEngineMappingUpdate *update);
308 void (*osync_plugin_resource_unref)(
309 OSyncPluginResource *resource);
310 void (*osync_plugin_config_add_resource)(
311 OSyncPluginConfig *config,
312 OSyncPluginResource *resource);
313 osync_bool (*osync_plugin_resource_is_enabled)(
314 OSyncPluginResource *resource);
315 void (*osync_plugin_resource_enable)(
316 OSyncPluginResource *resource,
317 osync_bool enable);
318 OSyncList* (*osync_plugin_resource_get_objformat_sinks)(
319 OSyncPluginResource *resource);
320 const char* (*osync_objformat_sink_get_objformat)(
321 OSyncObjFormatSink *sink);
322 const char* (*osync_objformat_sink_get_config)(
323 OSyncObjFormatSink *sink);
324 void (*osync_objformat_sink_set_config)(
325 OSyncObjFormatSink *sink,
326 const char *config);
327 OSyncObjFormatSink* (*osync_objformat_sink_new)(
328 const char *objformat,
329 OSyncError **error);
330 void (*osync_plugin_resource_add_objformat_sink)(
331 OSyncPluginResource *resource,
332 OSyncObjFormatSink *formatsink);
333 void (*osync_objformat_sink_unref)(
334 OSyncObjFormatSink *sink);
335 const char* (*osync_plugin_resource_get_preferred_format)(
336 OSyncPluginResource *resource);
337 void (*osync_plugin_resource_set_preferred_format)(
338 OSyncPluginResource *resource,
339 const char *preferred_format);
340 const char* (*osync_plugin_resource_get_mime)(
341 OSyncPluginResource *resource);
342 void (*osync_plugin_resource_set_mime)(
343 OSyncPluginResource *resource,
344 const char *mime);
345 const char* (*osync_plugin_resource_get_objtype)(
346 OSyncPluginResource *resource);
347 void (*osync_plugin_resource_set_objtype)(
348 OSyncPluginResource *resource,
349 const char *objtype);
350 const char* (*osync_plugin_resource_get_path)(
351 OSyncPluginResource *resource);
352 void (*osync_plugin_resource_set_path)(
353 OSyncPluginResource *resource,
354 const char *path);
355 const char* (*osync_plugin_resource_get_url)(
356 OSyncPluginResource *resource);
357 void (*osync_plugin_resource_set_url)(
358 OSyncPluginResource *resource,
359 const char *url);
360 const char* (*osync_plugin_config_get_advancedoption_value_by_name)(
361 OSyncPluginConfig *config,
362 const char *name);
363 OSyncList* (*osync_plugin_config_get_advancedoptions)(
364 OSyncPluginConfig *config);
365 void (*osync_plugin_config_add_advancedoption)(
366 OSyncPluginConfig *config,
367 OSyncPluginAdvancedOption *option);
368 OSyncPluginAdvancedOption* (*osync_plugin_advancedoption_new)(
369 OSyncError **error);
370 void (*osync_plugin_advancedoption_unref)(
371 OSyncPluginAdvancedOption *option);
372 const char* (*osync_plugin_advancedoption_get_name)(
373 OSyncPluginAdvancedOption *option);
374 void (*osync_plugin_advancedoption_set_name)(
375 OSyncPluginAdvancedOption *option,
376 const char *name);
377 void (*osync_plugin_advancedoption_set_displayname)(
378 OSyncPluginAdvancedOption *option,
379 const char *displayname);
380 void (*osync_plugin_advancedoption_set_type)(
381 OSyncPluginAdvancedOption *option,
382 OSyncPluginAdvancedOptionType type);
383 void (*osync_plugin_advancedoption_set_value)(
384 OSyncPluginAdvancedOption *option,
385 const char *value);
386 OSyncList* (*osync_plugin_config_get_resources)(
387 OSyncPluginConfig *config);
388 OSyncPluginResource* (*osync_plugin_resource_ref)(
389 OSyncPluginResource *resource);
390 OSyncPluginResource* (*osync_plugin_resource_new)(
391 OSyncError **error);
392 const char* (*osync_plugin_resource_get_name)(
393 OSyncPluginResource *resource);
394 void (*osync_plugin_resource_set_name)(
395 OSyncPluginResource *resource,
396 const char *name);
397 OSyncPluginAuthentication* (*osync_plugin_config_get_authentication)(
398 OSyncPluginConfig *config);
399 const char* (*osync_plugin_authentication_get_password)(
400 OSyncPluginAuthentication *auth);
401 OSyncPluginAuthentication* (*osync_plugin_authentication_new)(
402 OSyncError **error);
403 osync_bool (*osync_plugin_authentication_option_is_supported)(
404 OSyncPluginAuthentication *auth,
405 OSyncPluginAuthenticationOptionSupportedFlag flag);
406 void (*osync_plugin_authentication_unref)(
407 OSyncPluginAuthentication *auth);
408 void (*osync_plugin_config_set_authentication)(
409 OSyncPluginConfig *config,
410 OSyncPluginAuthentication *auth);
411 void (*osync_plugin_authentication_set_password)(
412 OSyncPluginAuthentication *auth,
413 const char *password);
414 const char* (*osync_plugin_authentication_get_username)(
415 OSyncPluginAuthentication *auth);
416 void (*osync_plugin_authentication_set_username)(
417 OSyncPluginAuthentication *auth,
418 const char *password);
419 void (*osync_group_set_objtype_enabled)(
420 OSyncGroup *group, const char *objtype,
421 osync_bool enabled);
423 // data pointers
424 vLateSmartPtr<OSyncGroupEnv, void(*)(OSyncGroupEnv*)> group_env;
425 vLateSmartPtr<OSyncFormatEnv, void(*)(OSyncFormatEnv*)> format_env;
426 vLateSmartPtr<OSyncPluginEnv, void(*)(OSyncPluginEnv*)> plugin_env;
428 TossError error;
429 Converter40 converter;
431 OpenSync40Private(OpenSync40 &api)
432 : error(this)
433 , converter(api)
437 // helper functions
438 std::string osync_error_print_stack_wrapper(OSyncError **error)
440 std::string rmsg;
441 char *msg = osync_error_print_stack(error);
442 if( msg ) {
443 rmsg = msg;
444 osync_free(msg);
446 else {
447 rmsg = _C("(NULL error msg)");
449 return rmsg;
453 class SyncConflict40Private : public SyncConflictPrivateBase
455 OpenSync40Private *m_priv;
456 OSyncEngine *m_engine;
457 OSyncMappingEngine *m_mapping;
458 OSyncList *m_changes;
460 public:
461 SyncConflict40Private(OpenSync40Private *priv,
462 OSyncEngine *engine, OSyncMappingEngine *mapping);
463 ~SyncConflict40Private();
465 virtual bool IsAbortSupported() const;
466 virtual bool IsIgnoreSupported() const;
467 virtual bool IsKeepNewerSupported() const;
469 virtual void Select(int change_id); // takes the id of SyncChange
470 virtual void Abort();
471 virtual void Duplicate();
472 virtual void Ignore();
473 virtual void KeepNewer();
475 void AppendChanges(std::vector<SyncChange> &list);
478 class SyncSummary40Private : public SyncSummaryPrivateBase
480 OpenSync40Private *m_priv;
481 OSyncEngine *m_engine;
483 public:
484 SyncSummary40Private(OpenSync40Private *priv, OSyncEngine *engine);
485 ~SyncSummary40Private();
487 virtual void Abort();
488 virtual void Continue();
490 // returns true if any member is dirty
491 bool AppendMembers(std::vector<SyncMemberSummary> &list);
494 class OS40PluginConfigPrivate
496 public:
497 OSyncMember *m_member;
498 OSyncPluginConfig *m_config;
500 OS40PluginConfigPrivate()
501 : m_member(0)
502 , m_config(0)
507 class OS40ConfigResourcePrivate
509 public:
510 OpenSync40Private *m_privapi;
511 OS40PluginConfigPrivate *m_parentpriv;
512 OSyncPluginResource *m_resource;
514 OS40ConfigResourcePrivate()
515 : m_privapi(0)
516 , m_parentpriv(0)
517 , m_resource(0)
522 struct CallbackBundle
524 OpenSync40Private *m_priv;
525 SyncStatus *m_status;
527 CallbackBundle(OpenSync40Private *priv, SyncStatus &status)
528 : m_priv(priv)
529 , m_status(&status)
534 void conflict_handler(OSyncEngine *, OSyncMappingEngine *, void *);
535 void entry_status(OSyncEngineChangeUpdate *, void *);
536 void mapping_status(OSyncEngineMappingUpdate *, void *);
537 void engine_status(OSyncEngineUpdate *, void *);
538 void member_status(OSyncEngineMemberUpdate *, void *);
539 void multiply_summary(OSyncEngine *, void *);
542 /////////////////////////////////////////////////////////////////////////////
543 // Static helper functions
545 static const char *OSyncChangeType2String(OSyncChangeType type)
547 switch (type) {
548 case OSYNC_CHANGE_TYPE_ADDED: return _C("ADDED");
549 case OSYNC_CHANGE_TYPE_UNMODIFIED: return _C("UNMODIFIED");
550 case OSYNC_CHANGE_TYPE_DELETED: return _C("DELETED");
551 case OSYNC_CHANGE_TYPE_MODIFIED: return _C("MODIFIED");
552 default:
553 case OSYNC_CHANGE_TYPE_UNKNOWN: return "?";
558 /////////////////////////////////////////////////////////////////////////////
559 // SyncConflict40Private member functions
561 SyncConflict40Private::SyncConflict40Private(OpenSync40Private *priv,
562 OSyncEngine *engine, OSyncMappingEngine *mapping)
563 : m_priv(priv)
564 , m_engine(engine)
565 , m_mapping(mapping)
566 , m_changes(0)
568 m_changes = m_priv->osync_mapping_engine_get_changes(m_mapping);
571 SyncConflict40Private::~SyncConflict40Private()
573 m_priv->osync_list_free(m_changes);
576 bool SyncConflict40Private::IsAbortSupported() const
578 return true;
581 bool SyncConflict40Private::IsIgnoreSupported() const
583 return m_priv->osync_mapping_engine_supports_ignore(m_mapping);
586 bool SyncConflict40Private::IsKeepNewerSupported() const
588 return m_priv->osync_mapping_engine_supports_use_latest(m_mapping);
591 void SyncConflict40Private::Select(int change_id)
593 OSyncList *c = m_priv->osync_list_nth(m_changes, change_id);
594 if( !c )
595 throw std::logic_error("Bad change_id");
597 OSyncChange *change = (OSyncChange *) c->data;
599 if( !m_priv->osync_engine_mapping_solve(m_engine, m_mapping,
600 change, m_priv->error) )
602 throw std::runtime_error(m_priv->error.GetErrorMsg());
606 void SyncConflict40Private::Abort()
608 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) ) {
609 ostringstream oss;
610 oss << _C("Problems while aborting: ")
611 << m_priv->error.GetErrorMsg();
612 throw std::runtime_error(oss.str());
616 void SyncConflict40Private::Duplicate()
618 if( !m_priv->osync_engine_mapping_duplicate(m_engine, m_mapping, m_priv->error) )
619 throw std::runtime_error(m_priv->error.GetErrorMsg());
622 void SyncConflict40Private::Ignore()
624 if( !IsIgnoreSupported() )
625 throw std::logic_error("Ignore not supported, yet Ignore() called.");
627 if( !m_priv->osync_engine_mapping_ignore_conflict(m_engine, m_mapping,
628 m_priv->error) )
630 throw std::runtime_error(m_priv->error.GetErrorMsg());
634 void SyncConflict40Private::KeepNewer()
636 if( !IsKeepNewerSupported() )
637 throw std::logic_error("Keep Newer not supported, yet KeepNewer() called.");
639 if( !m_priv->osync_engine_mapping_use_latest(m_engine, m_mapping, m_priv->error) )
640 throw std::runtime_error(m_priv->error.GetErrorMsg());
643 void SyncConflict40Private::AppendChanges(std::vector<SyncChange> &list)
645 int i = 0;
646 for( OSyncList *c = m_changes; c; c = c->next, i++ ) {
647 OSyncChange *change = (OSyncChange *) c->data;
649 if( m_priv->osync_change_get_changetype(change) != OSYNC_CHANGE_TYPE_UNKNOWN ) {
650 OSyncMember *member = m_priv->osync_mapping_engine_change_find_member(m_mapping, change);
652 OSyncData *data = m_priv->osync_change_get_data(change);
654 SyncChange entry;
656 char *printable = m_priv->osync_data_get_printable(data, m_priv->error);
657 if( printable )
658 entry.printable_data = printable;
659 m_priv->osync_free(printable);
661 if( m_priv->error.IsSet() )
662 throw std::runtime_error(m_priv->error.GetErrorMsg());
664 entry.id = i;
665 entry.member_id = m_priv->osync_member_get_id(member);
666 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
667 entry.uid = m_priv->osync_change_get_uid(change);
669 // add to list
670 list.push_back(entry);
676 /////////////////////////////////////////////////////////////////////////////
677 // SyncSummary40Private member functions
679 SyncSummary40Private::SyncSummary40Private(OpenSync40Private *priv,
680 OSyncEngine *engine)
681 : m_priv(priv)
682 , m_engine(engine)
686 SyncSummary40Private::~SyncSummary40Private()
690 void SyncSummary40Private::Abort()
692 if( !m_priv->osync_engine_abort(m_engine, m_priv->error) )
693 throw std::runtime_error(m_priv->error.GetErrorMsg());
696 void SyncSummary40Private::Continue()
698 if( !m_priv->osync_engine_continue(m_engine, m_priv->error) )
699 throw std::runtime_error(m_priv->error.GetErrorMsg());
702 bool SyncSummary40Private::AppendMembers(std::vector<SyncMemberSummary> &list)
704 SyncListHandle objengines(m_priv->osync_list_free);
705 objengines = m_priv->osync_engine_get_objengines(m_engine);
707 int i = 0;
708 bool dirty = false;
710 for( OSyncList *o = objengines.get(); o; o = o->next ) {
711 OSyncObjEngine *objengine = (OSyncObjEngine *) o->data;
717 SyncListHandle members(m_priv->osync_list_free);
718 members = m_priv->osync_obj_engine_get_members(objengine);
719 for( OSyncList *m = members.get(); m; m = m->next ) {
720 OSyncMember *member = (OSyncMember *) m->data;
722 // Fill in common summary data
723 SyncMemberSummary entry;
724 entry.id = i;
725 entry.objtype_name = m_priv->osync_obj_engine_get_objtype(objengine);
726 entry.member_id = m_priv->osync_member_get_id(member);
727 entry.plugin_name = m_priv->osync_member_get_pluginname(member);
729 const OSyncList *mapping_entry_engines = m_priv->osync_obj_engine_get_mapping_entry_engines_of_member(objengine, member);
731 // Calculate summary counts
732 for( const OSyncList *e = mapping_entry_engines; e; e = e->next ) {
733 OSyncMappingEntryEngine *entry_engine = (OSyncMappingEntryEngine*) e->data;
735 if( !m_priv->osync_entry_engine_is_dirty(entry_engine) )
736 continue;
738 dirty = true;
740 OSyncChangeType type = m_priv->osync_entry_engine_get_changetype(entry_engine);
741 switch (type)
743 case OSYNC_CHANGE_TYPE_ADDED:
744 entry.added++;
745 break;
746 case OSYNC_CHANGE_TYPE_MODIFIED:
747 entry.modified++;
748 break;
749 case OSYNC_CHANGE_TYPE_DELETED:
750 entry.deleted++;
751 break;
752 default:
753 break;
757 // Add entry to list
758 list.push_back(entry);
763 return dirty;
767 /////////////////////////////////////////////////////////////////////////////
768 // Callback functions
770 void conflict_handler(OSyncEngine *engine, OSyncMappingEngine *mapping,
771 void *cbdata)
773 CallbackBundle *cb = (CallbackBundle*) cbdata;
775 try {
776 // build the SyncConflict object
777 SyncConflict40Private scp(cb->m_priv, engine, mapping);
778 SyncConflict conflict(scp);
780 // append all conflicting changes as vector objects in the same
781 // order as the opensync library mapping
782 scp.AppendChanges(conflict);
784 // call the status handler
785 cb->m_status->HandleConflict(conflict);
787 catch( std::exception &e ) {
788 cb->m_status->ReportError(
789 string(_C("Conflict not resolved. ")) + e.what());
791 catch( ... ) {
792 cb->m_status->ReportError(
793 _C("Unknown exception caught in conflict_handler()"));
797 void entry_status(OSyncEngineChangeUpdate *status, void *cbdata)
799 CallbackBundle *cb = (CallbackBundle*) cbdata;
801 try {
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 string fmt, msg;
807 bool error_event = false;
809 switch( cb->m_priv->osync_engine_change_update_get_event(status) )
811 case OSYNC_ENGINE_CHANGE_EVENT_READ:
812 fmt = _C("Received an entry %s (%s) from member %d (%s): %s");
813 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
814 break;
816 case OSYNC_ENGINE_CHANGE_EVENT_WRITTEN:
817 fmt = _C("Sent an entry %s (%s) to member %d (%s): %s");
818 msg = OSyncChangeType2String(cb->m_priv->osync_change_get_changetype(change));
819 break;
821 case OSYNC_ENGINE_CHANGE_EVENT_ERROR:
822 error_event = true;
823 fmt = _C("Error for entry %s (%s) and member %d (%s): %s");
824 msg = cb->m_priv->osync_error_print_stack_wrapper(&(error));
825 break;
828 if( fmt.size() ) {
829 string status_msg = string_vprintf(fmt.c_str(),
830 cb->m_priv->osync_change_get_uid(change),
831 cb->m_priv->osync_objformat_get_name( cb->m_priv->osync_change_get_objformat(change)),
832 cb->m_priv->osync_member_get_id(member),
833 cb->m_priv->osync_member_get_pluginname(member),
834 msg.c_str());
836 // call the status handler
837 cb->m_status->EntryStatus(status_msg, error_event);
840 catch( std::exception &e ) {
841 cb->m_status->ReportError(
842 string(_C("entry_status error: ")) + e.what());
844 catch( ... ) {
845 cb->m_status->ReportError(
846 _C("Unknown exception caught in entry_status()"));
850 void mapping_status(OSyncEngineMappingUpdate *status, void *cbdata)
852 CallbackBundle *cb = (CallbackBundle*) cbdata;
854 try {
855 OSyncError *error = cb->m_priv->osync_engine_mapping_update_get_error(status);
857 ostringstream oss;
858 bool error_event = false;
860 switch( cb->m_priv->osync_engine_mapping_update_get_event(status) )
862 case OSYNC_ENGINE_MAPPING_EVENT_SOLVED:
863 oss << _C("Mapping solved");
864 break;
866 case OSYNC_ENGINE_MAPPING_EVENT_ERROR:
867 error_event = true;
868 oss << _C("Mapping error: ")
869 << cb->m_priv->osync_error_print_stack_wrapper(&(error));
870 break;
873 // call the status handler
874 if( oss.str().size() )
875 cb->m_status->MappingStatus(oss.str(), error_event);
877 catch( std::exception &e ) {
878 cb->m_status->ReportError(
879 string(_C("mapping_status error: ")) + e.what());
881 catch( ... ) {
882 cb->m_status->ReportError(
883 _C("Unknown exception caught in mapping_status()"));
887 void engine_status(OSyncEngineUpdate *status, void *cbdata)
889 CallbackBundle *cb = (CallbackBundle*) cbdata;
891 try {
892 OSyncError *error = cb->m_priv->osync_engine_update_get_error(status);
894 ostringstream oss;
895 bool error_event = false;
896 bool slow_sync = false;
898 switch( cb->m_priv->osync_engine_update_get_event(status) )
900 case OSYNC_ENGINE_EVENT_CONNECTED:
901 oss << _C("All clients connected or error");
902 break;
903 case OSYNC_ENGINE_EVENT_CONNECT_DONE:
904 /* Not of interest for regular user. */
905 break;
906 case OSYNC_ENGINE_EVENT_READ:
907 oss << _C("All clients sent changes or error");
908 break;
909 case OSYNC_ENGINE_EVENT_MAPPED:
910 oss << _C("All changes got mapped");
911 break;
912 case OSYNC_ENGINE_EVENT_MULTIPLIED:
913 oss << _C("All changes got multiplied");
914 break;
915 case OSYNC_ENGINE_EVENT_PREPARED_WRITE:
916 oss << _C("All changes got prepared for write");
917 break;
918 case OSYNC_ENGINE_EVENT_PREPARED_MAP:
919 /* Not of interest for regular user. */
920 break;
921 case OSYNC_ENGINE_EVENT_WRITTEN:
922 oss << _C("All clients have written");
923 break;
924 case OSYNC_ENGINE_EVENT_DISCONNECTED:
925 oss << _C("All clients have disconnected");
926 break;
927 case OSYNC_ENGINE_EVENT_ERROR:
928 error_event = true;
929 oss << _C("The sync failed: ") << cb->m_priv->osync_error_print_stack_wrapper(&(error));
930 break;
931 case OSYNC_ENGINE_EVENT_SUCCESSFUL:
932 oss << _C("The sync was successful");
933 break;
934 case OSYNC_ENGINE_EVENT_PREV_UNCLEAN:
935 oss << _C("The previous synchronization was unclean. Slow-syncing");
936 slow_sync = true;
937 break;
938 case OSYNC_ENGINE_EVENT_END_CONFLICTS:
939 oss << _C("All conflicts have been reported");
940 break;
941 case OSYNC_ENGINE_EVENT_SYNC_DONE:
942 oss << _C("All clients reported sync done");
943 break;
946 // call the status handler
947 if( oss.str().size() )
948 cb->m_status->EngineStatus(oss.str(),
949 error_event,
950 slow_sync);
952 catch( std::exception &e ) {
953 cb->m_status->ReportError(
954 string(_C("engine_status error: ")) + e.what());
956 catch( ... ) {
957 cb->m_status->ReportError(
958 _C("Unknown exception caught in engine_status()"));
962 void member_status(OSyncEngineMemberUpdate *status, void *cbdata)
964 CallbackBundle *cb = (CallbackBundle*) cbdata;
966 try {
967 bool error_event = false;
968 bool valid = true;
970 string fmt, sinkmsg, errmsg;
972 const char *objtype = cb->m_priv->osync_engine_member_update_get_objtype(status);
973 if( objtype == NULL )
974 sinkmsg = _C("Main sink");
975 else
976 sinkmsg = string_vprintf(_C("%s sink"), objtype);
979 OSyncMember *member = cb->m_priv->osync_engine_member_update_get_member(status);
981 OSyncError *error = cb->m_priv->osync_engine_member_update_get_error(status);
983 switch( cb->m_priv->osync_engine_member_update_get_event(status) )
985 case OSYNC_ENGINE_MEMBER_EVENT_CONNECTED:
986 // TRANSLATORS: resulting message may look like this:
987 // "Main sink of member 5 (barry-sync) just connected"
988 // The "Main sink" part is based on the "Main sink"
989 // string or the "%s sink" string.
990 fmt = _C("%s of member %d (%s) just connected");
991 break;
992 case OSYNC_ENGINE_MEMBER_EVENT_CONNECT_DONE:
993 // Special event - but not interesting for
994 // the normal user.
995 break;
996 case OSYNC_ENGINE_MEMBER_EVENT_DISCONNECTED:
997 fmt = _C("%s of member %d (%s) just disconnected");
998 break;
999 case OSYNC_ENGINE_MEMBER_EVENT_READ:
1000 fmt = _C("%s of member %d (%s) just sent all changes");
1001 break;
1002 case OSYNC_ENGINE_MEMBER_EVENT_WRITTEN:
1003 fmt = _C("%s of member %d (%s) committed all changes");
1004 break;
1005 case OSYNC_ENGINE_MEMBER_EVENT_SYNC_DONE:
1006 fmt = _C("%s of member %d (%s) reported sync done");
1007 break;
1008 case OSYNC_ENGINE_MEMBER_EVENT_DISCOVERED:
1009 fmt = _C("%s of member %d (%s) discovered its objtypes");
1010 break;
1011 case OSYNC_ENGINE_MEMBER_EVENT_ERROR:
1012 fmt = _C("%s of member %d (%s) had an error: %s");
1013 errmsg = cb->m_priv->osync_error_print_stack_wrapper(&error);
1014 error_event = true;
1015 break;
1016 default:
1017 valid = false;
1018 break;
1021 // construct the msg
1022 string msg = string_vprintf(fmt.c_str(),
1023 sinkmsg.c_str(),
1024 cb->m_priv->osync_member_get_id(member),
1025 cb->m_priv->osync_member_get_pluginname(member),
1026 errmsg.c_str());
1028 // call the status handler
1029 if( msg.size() && valid ) {
1030 cb->m_status->MemberStatus(
1031 cb->m_priv->osync_member_get_id(member),
1032 cb->m_priv->osync_member_get_pluginname(member),
1033 msg, error_event);
1036 catch( std::exception &e ) {
1037 cb->m_status->ReportError(
1038 string(_C("member_status error: ")) + e.what());
1040 catch( ... ) {
1041 cb->m_status->ReportError(
1042 _C("Unknown exception caught in member_status()"));
1046 void multiply_summary(OSyncEngine *engine, void *cbdata)
1048 CallbackBundle *cb = (CallbackBundle*) cbdata;
1050 try {
1051 // build the SyncSummary object
1052 SyncSummary40Private ssp(cb->m_priv, engine);
1053 SyncSummary summary(ssp);
1055 // append a summary for each objtype member
1056 if( ssp.AppendMembers(summary) ) {
1057 // call the status handler only if dirty
1058 cb->m_status->CheckSummary(summary);
1060 else {
1061 // nothing dirty, just continue
1062 summary.Continue();
1065 catch( std::exception &e ) {
1066 cb->m_status->ReportError(
1067 string(_C("Error handling summary item. ")) + e.what());
1069 catch( ... ) {
1070 cb->m_status->ReportError(
1071 _C("Unknown exception caught in multiply_summary()"));
1076 /////////////////////////////////////////////////////////////////////////////
1077 // OS40ConfigResource - public members
1079 OS40ConfigResource::OS40ConfigResource(const OS40PluginConfig &parent,
1080 void *resource,
1081 bool existing_resource)
1082 : m_priv( new OS40ConfigResourcePrivate )
1083 , m_exists(existing_resource)
1085 m_priv->m_privapi = parent.m_privapi;
1086 m_priv->m_parentpriv = parent.m_priv.get();
1087 m_priv->m_resource = (OSyncPluginResource*) resource;
1090 OS40ConfigResource::~OS40ConfigResource()
1092 // unref the resource, since we hold a copy
1093 m_priv->m_privapi->
1094 osync_plugin_resource_unref(m_priv->m_resource);
1095 delete m_priv;
1098 bool OS40ConfigResource::IsExistingResource() const
1100 return m_exists;
1103 // safe to call multiple times
1104 void OS40ConfigResource::AddResource()
1106 if( !IsExistingResource() ) {
1107 m_priv->m_privapi->
1108 osync_plugin_config_add_resource(
1109 m_priv->m_parentpriv->m_config,
1110 m_priv->m_resource);
1114 bool OS40ConfigResource::IsEnabled() const
1116 return m_priv->m_privapi->
1117 osync_plugin_resource_is_enabled(m_priv->m_resource);
1120 OS40ConfigResource& OS40ConfigResource::Enable(bool enabled)
1122 m_priv->m_privapi->osync_plugin_resource_enable(m_priv->m_resource,
1123 enabled);
1124 return *this;
1127 bool OS40ConfigResource::FindObjFormat(const std::string &objformat,
1128 std::string &config)
1130 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1131 sinks = m_priv->m_privapi->
1132 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1133 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1134 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1135 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1136 const char *cfg = m_priv->m_privapi->osync_objformat_sink_get_config(sink);
1137 if( cfg )
1138 config = cfg;
1139 else
1140 config.clear();
1141 return true;
1144 return false;
1147 OS40ConfigResource& OS40ConfigResource::SetObjFormat(const std::string &objformat,
1148 const std::string &config)
1150 // if it already exists, just set the config value
1151 SyncListHandle sinks(m_priv->m_privapi->osync_list_free);
1152 sinks = m_priv->m_privapi->
1153 osync_plugin_resource_get_objformat_sinks(m_priv->m_resource);
1154 for( OSyncList *o = sinks.get(); o; o = o->next ) {
1155 OSyncObjFormatSink *sink = (OSyncObjFormatSink*) o->data;
1156 if( objformat == m_priv->m_privapi->osync_objformat_sink_get_objformat(sink) ) {
1157 m_priv->m_privapi->osync_objformat_sink_set_config(sink, config.c_str());
1158 return *this;
1162 // if we get here, it doesn't exist, and we need to add it
1163 OSyncObjFormatSink *sink = m_priv->m_privapi->
1164 osync_objformat_sink_new(objformat.c_str(),
1165 m_priv->m_privapi->error);
1166 if( !sink )
1167 throw std::runtime_error(m_priv->m_privapi->error.GetErrorMsg());
1169 if( config.size() )
1170 m_priv->m_privapi->osync_objformat_sink_set_config(sink,
1171 config.c_str());
1172 m_priv->m_privapi->osync_plugin_resource_add_objformat_sink(
1173 m_priv->m_resource, sink);
1174 m_priv->m_privapi->osync_objformat_sink_unref(sink);
1175 return *this;
1178 std::string OS40ConfigResource::GetName() const
1180 string value;
1181 const char *pv = m_priv->m_privapi->
1182 osync_plugin_resource_get_name(m_priv->m_resource);
1183 if( pv )
1184 value = pv;
1185 return value;
1188 OS40ConfigResource& OS40ConfigResource::SetName(const std::string &name)
1190 m_priv->m_privapi->
1191 osync_plugin_resource_set_name(m_priv->m_resource, name.c_str());
1192 return *this;
1195 std::string OS40ConfigResource::GetPreferredFormat() const
1197 string value;
1198 const char *pv = m_priv->m_privapi->
1199 osync_plugin_resource_get_preferred_format(m_priv->m_resource);
1200 if( pv )
1201 value = pv;
1202 return value;
1205 OS40ConfigResource& OS40ConfigResource::SetPreferredFormat(const std::string &format)
1207 m_priv->m_privapi->
1208 osync_plugin_resource_set_preferred_format(m_priv->m_resource,
1209 format.c_str());
1210 return *this;
1213 std::string OS40ConfigResource::GetMime() const
1215 string value;
1216 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_mime(
1217 m_priv->m_resource);
1218 if( pv )
1219 value = pv;
1220 return value;
1223 OS40ConfigResource& OS40ConfigResource::SetMime(const std::string &mime)
1225 m_priv->m_privapi->osync_plugin_resource_set_mime(m_priv->m_resource,
1226 mime.c_str());
1227 return *this;
1230 std::string OS40ConfigResource::GetObjType() const
1232 string value;
1233 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_objtype(
1234 m_priv->m_resource);
1235 if( pv )
1236 value = pv;
1237 return value;
1240 OS40ConfigResource& OS40ConfigResource::SetObjType(const std::string &objtype)
1242 m_priv->m_privapi->osync_plugin_resource_set_objtype(m_priv->m_resource,
1243 objtype.c_str());
1244 return *this;
1247 std::string OS40ConfigResource::GetPath() const
1249 string value;
1250 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_path(
1251 m_priv->m_resource);
1252 if( pv )
1253 value = pv;
1254 return value;
1257 OS40ConfigResource& OS40ConfigResource::SetPath(const std::string &path)
1259 m_priv->m_privapi->osync_plugin_resource_set_path(m_priv->m_resource,
1260 path.c_str());
1261 return *this;
1264 std::string OS40ConfigResource::GetUrl() const
1266 string value;
1267 const char *pv = m_priv->m_privapi->osync_plugin_resource_get_url(
1268 m_priv->m_resource);
1269 if( pv )
1270 value = pv;
1271 return value;
1274 OS40ConfigResource& OS40ConfigResource::SetUrl(const std::string &url)
1276 m_priv->m_privapi->osync_plugin_resource_set_url(m_priv->m_resource,
1277 url.c_str());
1278 return *this;
1282 /////////////////////////////////////////////////////////////////////////////
1283 // OS40PluginConfig - public members
1285 OS40PluginConfig::OS40PluginConfig(OpenSync40Private *privapi,
1286 void *member,
1287 void *config)
1288 : m_privapi(privapi)
1290 m_priv.reset( new OS40PluginConfigPrivate );
1291 m_priv->m_member = (OSyncMember*) member;
1292 m_priv->m_config = (OSyncPluginConfig*) config;
1295 std::string OS40PluginConfig::GetAdvanced(const std::string &name)
1297 const char *value = m_privapi->osync_plugin_config_get_advancedoption_value_by_name(m_priv->m_config, name.c_str());
1298 string val;
1299 if( value )
1300 val = value;
1301 return val;
1304 void OS40PluginConfig::SetAdvanced(const std::string &name,
1305 const std::string &display_name,
1306 const std::string &val)
1308 SetAdvanced(name, display_name, STRING_TYPE, val);
1311 void OS40PluginConfig::SetAdvanced(const std::string &name,
1312 const std::string &display_name,
1313 int val_type,
1314 const std::string &val)
1316 // find the first advanced option with this name
1317 SyncListHandle aos(m_privapi->osync_list_free);
1318 aos = m_privapi->osync_plugin_config_get_advancedoptions(m_priv->m_config);
1319 OSyncPluginAdvancedOption *option = 0;
1320 for( OSyncList *o = aos.get(); o; o = o->next ) {
1321 option = (OSyncPluginAdvancedOption*) o->data;
1323 if( name == m_privapi->osync_plugin_advancedoption_get_name(option) )
1324 break;
1327 if( option ) {
1328 // found existing option, set it with val
1329 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1331 else {
1332 // option with that name does not exist, so create it
1333 option = m_privapi->osync_plugin_advancedoption_new(m_privapi->error);
1334 if( !option )
1335 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1337 m_privapi->osync_plugin_advancedoption_set_name(option, name.c_str());
1338 m_privapi->osync_plugin_advancedoption_set_displayname(option, display_name.c_str());
1339 OSyncPluginAdvancedOptionType type;
1340 switch( val_type )
1342 case NONE_TYPE:
1343 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_NONE;
1344 break;
1345 case BOOL_TYPE:
1346 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_BOOL;
1347 break;
1348 case CHAR_TYPE:
1349 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_CHAR;
1350 break;
1351 case DOUBLE_TYPE:
1352 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_DOUBLE;
1353 break;
1354 case INT_TYPE:
1355 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_INT;
1356 break;
1357 case LONG_TYPE:
1358 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONG;
1359 break;
1360 case LONGLONG_TYPE:
1361 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_LONGLONG;
1362 break;
1363 case UINT_TYPE:
1364 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_UINT;
1365 break;
1366 case ULONG_TYPE:
1367 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONG;
1368 break;
1369 case ULONGLONG_TYPE:
1370 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_ULONGLONG;
1371 break;
1372 case STRING_TYPE:
1373 type = OSYNC_PLUGIN_ADVANCEDOPTION_TYPE_STRING;
1374 break;
1375 default:
1376 throw std::logic_error("Bad type in SetAdvanced()");
1378 m_privapi->osync_plugin_advancedoption_set_type(option, type);
1379 m_privapi->osync_plugin_advancedoption_set_value(option, val.c_str());
1380 m_privapi->osync_plugin_config_add_advancedoption(m_priv->m_config, option);
1381 m_privapi->osync_plugin_advancedoption_unref(option);
1385 OS40PluginConfig::OS40ConfigResourcePtr
1386 OS40PluginConfig::GetResource(const std::string &objtype)
1388 OS40ConfigResourcePtr ptr;
1390 // FIXME - get_resources() does not give us a copy, so don't use
1391 // the SyncListHandle here
1392 OSyncList *rs = m_privapi->osync_plugin_config_get_resources(m_priv->m_config);
1393 for( OSyncList *o = rs; o; o = o->next ) {
1394 OSyncPluginResource *res = (OSyncPluginResource*) o->data;
1395 if( objtype == m_privapi->osync_plugin_resource_get_objtype(res) ) {
1396 // bump the resource count, since OS40ConfigResource
1397 // will unref it in the destructor
1398 m_privapi->osync_plugin_resource_ref(res);
1399 ptr.reset( new OS40ConfigResource(*this, res, true) );
1400 return ptr;
1404 // this res has a ref bump already, no ref() needed like it is above
1405 OSyncPluginResource *res = m_privapi->osync_plugin_resource_new(m_privapi->error);
1406 if( !res )
1407 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1408 ptr.reset( new OS40ConfigResource(*this, res, false) );
1409 // we search by objtype name, so make sure this is set in
1410 // the new object
1411 ptr->SetObjType(objtype);
1412 return ptr;
1415 std::string OS40PluginConfig::GetUsername() const
1417 string username;
1419 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1420 if( !auth )
1421 return username;
1423 const char *un = m_privapi->osync_plugin_authentication_get_username(auth);
1424 if( !un )
1425 return username;
1427 username = un;
1428 return username;
1431 void OS40PluginConfig::SetUsername(const std::string &username)
1433 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1434 if( !auth ) {
1435 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1436 if( !auth )
1437 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1438 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_USERNAME) ) {
1439 m_privapi->osync_plugin_authentication_unref(auth);
1440 throw std::runtime_error(_C("Username (authentication parameter) is not supported in plugin!"));
1443 // all looks ok, add it to the config
1444 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1445 // unref our copy, since the config now has it...
1446 // our auth pointer will still be valid since config holds it
1447 m_privapi->osync_plugin_authentication_unref(auth);
1450 m_privapi->osync_plugin_authentication_set_username(auth, username.c_str());
1453 std::string OS40PluginConfig::GetPassword() const
1455 string password;
1457 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1458 if( !auth )
1459 return password;
1461 const char *pass = m_privapi->osync_plugin_authentication_get_password(auth);
1462 if( !pass )
1463 return password;
1465 password = pass;
1466 return password;
1469 void OS40PluginConfig::SetPassword(const std::string &password)
1471 OSyncPluginAuthentication *auth = m_privapi->osync_plugin_config_get_authentication(m_priv->m_config);
1472 if( !auth ) {
1473 auth = m_privapi->osync_plugin_authentication_new(m_privapi->error);
1474 if( !auth )
1475 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1476 if( !m_privapi->osync_plugin_authentication_option_is_supported(auth, OSYNC_PLUGIN_AUTHENTICATION_PASSWORD) ) {
1477 m_privapi->osync_plugin_authentication_unref(auth);
1478 throw std::runtime_error(_C("Password authentication is not supported in plugin!"));
1481 // all looks ok, add it to the config
1482 m_privapi->osync_plugin_config_set_authentication(m_priv->m_config, auth);
1483 // unref our copy, since the config now has it...
1484 // our auth pointer will still be valid since config holds it
1485 m_privapi->osync_plugin_authentication_unref(auth);
1488 m_privapi->osync_plugin_authentication_set_password(auth, password.c_str());
1491 void OS40PluginConfig::Save()
1493 if( !m_privapi->osync_member_save(m_priv->m_member, m_privapi->error) )
1494 throw std::runtime_error(m_privapi->error.GetErrorMsg());
1498 /////////////////////////////////////////////////////////////////////////////
1499 // OpenSync40 (API override class) - public members
1501 OpenSync40::OpenSync40()
1503 // due to bugs in the way opensync 0.22 loads its modules,
1504 // (i.e. it doesn't load the plugins using RTLD_LOCAL, and
1505 // so libopensync.so.0 is loaded and pollutes the symbol table,
1506 // causing symbol clashes) we need to make sure that
1507 // OpenSync40 is only loaded first... if OpenSync22 was
1508 // loaded first, we will fail, so error out
1509 if( OpenSync22::SymbolsLoaded() )
1510 throw std::logic_error("Always load OpenSync40 before OpenSync22, to avoid symbol table conflicts.");
1512 if( !Open("libopensync.so.1") )
1513 throw DlError("Can't dlopen libopensync.so.1");
1515 // store locally in case of constructor exception in LoadSym
1516 std::auto_ptr<OpenSync40Private> p(new OpenSync40Private(*this));
1518 // load all required symbols...
1519 // we don't need to use try/catch here, since the base
1520 // class destructor will clean up for us if LoadSym() throws
1521 LoadSym(p->osync_get_version, "osync_get_version");
1522 LoadSym(p->osync_error_print, "osync_error_print");
1523 LoadSym(p->osync_error_print_stack, "osync_error_print_stack");
1524 LoadSym(p->osync_error_is_set, "osync_error_is_set");
1525 LoadSym(p->osync_error_unref, "osync_error_unref");
1526 LoadSym(p->osync_group_env_new, "osync_group_env_new");
1527 LoadSym(p->osync_format_env_new, "osync_format_env_new");
1528 LoadSym(p->osync_plugin_env_new, "osync_plugin_env_new");
1529 LoadSym(p->osync_group_env_unref, "osync_group_env_unref");
1530 LoadSym(p->osync_format_env_unref, "osync_format_env_unref");
1531 LoadSym(p->osync_plugin_env_unref, "osync_plugin_env_unref");
1532 LoadSym(p->osync_plugin_env_load, "osync_plugin_env_load");
1533 LoadSym(p->osync_plugin_env_get_plugins,"osync_plugin_env_get_plugins");
1534 LoadSym(p->osync_plugin_get_name, "osync_plugin_get_name");
1535 LoadSym(p->osync_list_free, "osync_list_free");
1536 LoadSym(p->osync_group_env_load_groups, "osync_group_env_load_groups");
1537 LoadSym(p->osync_format_env_load_plugins,
1538 "osync_format_env_load_plugins");
1539 LoadSym(p->osync_group_env_get_groups, "osync_group_env_get_groups");
1540 LoadSym(p->osync_group_get_name, "osync_group_get_name");
1541 LoadSym(p->osync_group_env_find_group, "osync_group_env_find_group");
1542 LoadSym(p->osync_group_get_members, "osync_group_get_members");
1543 LoadSym(p->osync_member_get_name, "osync_member_get_name");
1544 LoadSym(p->osync_member_get_id, "osync_member_get_id");
1545 LoadSym(p->osync_member_get_pluginname, "osync_member_get_pluginname");
1546 LoadSym(p->osync_format_env_get_objformats,
1547 "osync_format_env_get_objformats");
1548 LoadSym(p->osync_objformat_get_name, "osync_objformat_get_name");
1549 LoadSym(p->osync_objformat_get_objtype, "osync_objformat_get_objtype");
1550 LoadSym(p->osync_group_new, "osync_group_new");
1551 LoadSym(p->osync_group_unref, "osync_group_unref");
1552 LoadSym(p->osync_group_set_name, "osync_group_set_name");
1553 LoadSym(p->osync_group_env_add_group, "osync_group_env_add_group");
1554 LoadSym(p->osync_group_save, "osync_group_save");
1555 LoadSym(p->osync_group_delete, "osync_group_delete");
1556 LoadSym(p->osync_group_env_remove_group,"osync_group_env_remove_group");
1557 LoadSym(p->osync_plugin_env_find_plugin,"osync_plugin_env_find_plugin");
1558 LoadSym(p->osync_member_unref, "osync_member_unref");
1559 LoadSym(p->osync_member_new, "osync_member_new");
1560 LoadSym(p->osync_group_add_member, "osync_group_add_member");
1561 LoadSym(p->osync_member_set_pluginname, "osync_member_set_pluginname");
1562 LoadSym(p->osync_member_set_name, "osync_member_set_name");
1563 LoadSym(p->osync_member_save, "osync_member_save");
1564 LoadSym(p->osync_group_find_member, "osync_group_find_member");
1565 LoadSym(p->osync_member_delete, "osync_member_delete");
1566 LoadSym(p->osync_group_remove_member, "osync_group_remove_member");
1567 LoadSym(p->osync_plugin_config_new, "osync_plugin_config_new");
1568 LoadSym(p->osync_plugin_config_file_load,
1569 "osync_plugin_config_file_load");
1570 LoadSym(p->osync_member_set_config, "osync_member_set_config");
1571 LoadSym(p->osync_member_get_config_or_default,
1572 "osync_member_get_config_or_default");
1573 LoadSym(p->osync_plugin_config_file_save,
1574 "osync_plugin_config_file_save");
1575 LoadSym(p->osync_plugin_get_config_type,"osync_plugin_get_config_type");
1576 LoadSym(p->osync_engine_new, "osync_engine_new");
1577 LoadSym(p->osync_engine_unref, "osync_engine_unref");
1578 LoadSym(p->osync_engine_discover_and_block,
1579 "osync_engine_discover_and_block");
1580 LoadSym(p->osync_member_get_objtypes, "osync_member_get_objtypes");
1581 LoadSym(p->osync_list_length, "osync_list_length");
1582 LoadSym(p->osync_error_set, "osync_error_set");
1583 LoadSym(p->osync_engine_finalize, "osync_engine_finalize");
1584 LoadSym(p->osync_mapping_engine_get_changes,
1585 "osync_mapping_engine_get_changes");
1586 LoadSym(p->osync_mapping_engine_supports_ignore,
1587 "osync_mapping_engine_supports_ignore");
1588 LoadSym(p->osync_mapping_engine_supports_use_latest,
1589 "osync_mapping_engine_supports_use_latest");
1590 LoadSym(p->osync_list_nth, "osync_list_nth");
1591 LoadSym(p->osync_engine_mapping_solve, "osync_engine_mapping_solve");
1592 LoadSym(p->osync_engine_abort, "osync_engine_abort");
1593 LoadSym(p->osync_engine_mapping_duplicate,
1594 "osync_engine_mapping_duplicate");
1595 LoadSym(p->osync_engine_mapping_ignore_conflict,
1596 "osync_engine_mapping_ignore_conflict");
1597 LoadSym(p->osync_engine_mapping_use_latest,
1598 "osync_engine_mapping_use_latest");
1599 LoadSym(p->osync_change_get_changetype, "osync_change_get_changetype");
1600 LoadSym(p->osync_mapping_engine_change_find_member,
1601 "osync_mapping_engine_change_find_member");
1602 LoadSym(p->osync_change_get_data, "osync_change_get_data");
1603 LoadSym(p->osync_data_get_printable, "osync_data_get_printable");
1604 LoadSym(p->osync_free, "osync_free");
1605 LoadSym(p->osync_change_get_uid, "osync_change_get_uid");
1606 LoadSym(p->osync_engine_continue, "osync_engine_continue");
1607 LoadSym(p->osync_engine_get_objengines, "osync_engine_get_objengines");
1608 LoadSym(p->osync_obj_engine_get_members,
1609 "osync_obj_engine_get_members");
1610 LoadSym(p->osync_obj_engine_get_objtype,
1611 "osync_obj_engine_get_objtype");
1612 LoadSym(p->osync_obj_engine_get_mapping_entry_engines_of_member,
1613 "osync_obj_engine_get_mapping_entry_engines_of_member");
1614 LoadSym(p->osync_entry_engine_is_dirty,"osync_entry_engine_is_dirty");
1615 LoadSym(p->osync_entry_engine_get_changetype,
1616 "osync_entry_engine_get_changetype");
1617 LoadSym(p->osync_engine_change_update_get_change,
1618 "osync_engine_change_update_get_change");
1619 LoadSym(p->osync_engine_change_update_get_member,
1620 "osync_engine_change_update_get_member");
1621 LoadSym(p->osync_engine_change_update_get_error,
1622 "osync_engine_change_update_get_error");
1623 LoadSym(p->osync_engine_change_update_get_event,
1624 "osync_engine_change_update_get_event");
1625 LoadSym(p->osync_change_get_objformat, "osync_change_get_objformat");
1626 LoadSym(p->osync_engine_mapping_update_get_error,
1627 "osync_engine_mapping_update_get_error");
1628 LoadSym(p->osync_engine_update_get_error,
1629 "osync_engine_update_get_error");
1630 LoadSym(p->osync_engine_update_get_event,
1631 "osync_engine_update_get_event");
1632 LoadSym(p->osync_engine_member_update_get_objtype,
1633 "osync_engine_member_update_get_objtype");
1634 LoadSym(p->osync_engine_member_update_get_member,
1635 "osync_engine_member_update_get_member");
1636 LoadSym(p->osync_engine_member_update_get_error,
1637 "osync_engine_member_update_get_error");
1638 LoadSym(p->osync_engine_member_update_get_event,
1639 "osync_engine_member_update_get_event");
1640 LoadSym(p->osync_engine_set_conflict_callback,
1641 "osync_engine_set_conflict_callback");
1642 LoadSym(p->osync_engine_set_changestatus_callback,
1643 "osync_engine_set_changestatus_callback");
1644 LoadSym(p->osync_engine_set_mappingstatus_callback,
1645 "osync_engine_set_mappingstatus_callback");
1646 LoadSym(p->osync_engine_set_enginestatus_callback,
1647 "osync_engine_set_enginestatus_callback");
1648 LoadSym(p->osync_engine_set_memberstatus_callback,
1649 "osync_engine_set_memberstatus_callback");
1650 LoadSym(p->osync_engine_set_multiply_callback,
1651 "osync_engine_set_multiply_callback");
1652 LoadSym(p->osync_engine_initialize, "osync_engine_initialize");
1653 LoadSym(p->osync_engine_synchronize_and_block,
1654 "osync_engine_synchronize_and_block");
1655 LoadSym(p->osync_engine_mapping_update_get_event,
1656 "osync_engine_mapping_update_get_event");
1657 LoadSym(p->osync_plugin_resource_unref,
1658 "osync_plugin_resource_unref");
1659 LoadSym(p->osync_plugin_config_add_resource,
1660 "osync_plugin_config_add_resource");
1661 LoadSym(p->osync_plugin_resource_is_enabled,
1662 "osync_plugin_resource_is_enabled");
1663 LoadSym(p->osync_plugin_resource_enable,
1664 "osync_plugin_resource_enable");
1665 LoadSym(p->osync_plugin_resource_get_objformat_sinks,
1666 "osync_plugin_resource_get_objformat_sinks");
1667 LoadSym(p->osync_objformat_sink_get_objformat,
1668 "osync_objformat_sink_get_objformat");
1669 LoadSym(p->osync_objformat_sink_get_config,
1670 "osync_objformat_sink_get_config");
1671 LoadSym(p->osync_objformat_sink_set_config,
1672 "osync_objformat_sink_set_config");
1673 LoadSym(p->osync_objformat_sink_new,
1674 "osync_objformat_sink_new");
1675 LoadSym(p->osync_plugin_resource_add_objformat_sink,
1676 "osync_plugin_resource_add_objformat_sink");
1677 LoadSym(p->osync_objformat_sink_unref,
1678 "osync_objformat_sink_unref");
1679 LoadSym(p->osync_plugin_resource_get_preferred_format,
1680 "osync_plugin_resource_get_preferred_format");
1681 LoadSym(p->osync_plugin_resource_set_preferred_format,
1682 "osync_plugin_resource_set_preferred_format");
1683 LoadSym(p->osync_plugin_resource_get_mime,
1684 "osync_plugin_resource_get_mime");
1685 LoadSym(p->osync_plugin_resource_set_mime,
1686 "osync_plugin_resource_set_mime");
1687 LoadSym(p->osync_plugin_resource_get_objtype,
1688 "osync_plugin_resource_get_objtype");
1689 LoadSym(p->osync_plugin_resource_set_objtype,
1690 "osync_plugin_resource_set_objtype");
1691 LoadSym(p->osync_plugin_resource_get_path,
1692 "osync_plugin_resource_get_path");
1693 LoadSym(p->osync_plugin_resource_set_path,
1694 "osync_plugin_resource_set_path");
1695 LoadSym(p->osync_plugin_resource_get_url,
1696 "osync_plugin_resource_get_url");
1697 LoadSym(p->osync_plugin_resource_set_url,
1698 "osync_plugin_resource_set_url");
1699 LoadSym(p->osync_plugin_config_get_advancedoption_value_by_name,
1700 "osync_plugin_config_get_advancedoption_value_by_name");
1701 LoadSym(p->osync_plugin_config_get_advancedoptions,
1702 "osync_plugin_config_get_advancedoptions");
1703 LoadSym(p->osync_plugin_config_add_advancedoption,
1704 "osync_plugin_config_add_advancedoption");
1705 LoadSym(p->osync_plugin_advancedoption_new,
1706 "osync_plugin_advancedoption_new");
1707 LoadSym(p->osync_plugin_advancedoption_unref,
1708 "osync_plugin_advancedoption_unref");
1709 LoadSym(p->osync_plugin_advancedoption_get_name,
1710 "osync_plugin_advancedoption_get_name");
1711 LoadSym(p->osync_plugin_advancedoption_set_name,
1712 "osync_plugin_advancedoption_set_name");
1713 LoadSym(p->osync_plugin_advancedoption_set_displayname,
1714 "osync_plugin_advancedoption_set_displayname");
1715 LoadSym(p->osync_plugin_advancedoption_set_type,
1716 "osync_plugin_advancedoption_set_type");
1717 LoadSym(p->osync_plugin_advancedoption_set_value,
1718 "osync_plugin_advancedoption_set_value");
1719 LoadSym(p->osync_plugin_config_get_resources,
1720 "osync_plugin_config_get_resources");
1721 LoadSym(p->osync_plugin_resource_ref,
1722 "osync_plugin_resource_ref");
1723 LoadSym(p->osync_plugin_resource_new,
1724 "osync_plugin_resource_new");
1725 LoadSym(p->osync_plugin_resource_get_name,
1726 "osync_plugin_resource_get_name");
1727 LoadSym(p->osync_plugin_resource_set_name,
1728 "osync_plugin_resource_set_name");
1729 LoadSym(p->osync_plugin_config_get_authentication,
1730 "osync_plugin_config_get_authentication");
1731 LoadSym(p->osync_plugin_authentication_get_password,
1732 "osync_plugin_authentication_get_password");
1733 LoadSym(p->osync_plugin_authentication_new,
1734 "osync_plugin_authentication_new");
1735 LoadSym(p->osync_plugin_authentication_option_is_supported,
1736 "osync_plugin_authentication_option_is_supported");
1737 LoadSym(p->osync_plugin_authentication_unref,
1738 "osync_plugin_authentication_unref");
1739 LoadSym(p->osync_plugin_config_set_authentication,
1740 "osync_plugin_config_set_authentication");
1741 LoadSym(p->osync_plugin_authentication_set_password,
1742 "osync_plugin_authentication_set_password");
1743 LoadSym(p->osync_plugin_authentication_get_username,
1744 "osync_plugin_authentication_get_username");
1745 LoadSym(p->osync_plugin_authentication_set_username,
1746 "osync_plugin_authentication_set_username");
1747 LoadSym(p->osync_group_set_objtype_enabled,
1748 "osync_group_set_objtype_enabled");
1750 // fixup free pointers
1751 p->group_env.SetFreeFunc(p->osync_group_env_unref);
1752 p->format_env.SetFreeFunc(p->osync_format_env_unref);
1753 p->plugin_env.SetFreeFunc(p->osync_plugin_env_unref);
1755 // setup opensync support environment
1756 SetupEnvironment(p.get());
1758 // this pointer is ours now
1759 m_priv = p.release();
1762 OpenSync40::~OpenSync40()
1764 delete m_priv;
1765 m_priv = 0;
1768 void OpenSync40::SetupEnvironment(OpenSync40Private *p)
1770 // allocate group, format, and env
1771 p->group_env = p->osync_group_env_new(p->error);
1772 if( !p->group_env.get() )
1773 throw std::runtime_error(p->error.GetErrorMsg());
1775 p->format_env = p->osync_format_env_new(p->error);
1776 if( !p->format_env.get() )
1777 throw std::runtime_error(p->error.GetErrorMsg());
1779 p->plugin_env = p->osync_plugin_env_new(p->error);
1780 if( !p->plugin_env.get() )
1781 throw std::runtime_error(p->error.GetErrorMsg());
1783 // load group, format, and env
1784 if( !p->osync_group_env_load_groups(p->group_env.get(), NULL, p->error) ||
1785 !p->osync_format_env_load_plugins(p->format_env.get(), NULL, p->error) ||
1786 !p->osync_plugin_env_load(p->plugin_env.get(), NULL, p->error) )
1787 throw std::runtime_error(p->error.GetErrorMsg());
1790 const char* OpenSync40::GetVersion() const
1792 return m_priv->osync_get_version();
1795 const char* OpenSync40::GetEngineName() const
1797 return "0.40";
1800 void OpenSync40::GetPluginNames(string_list_type &plugins)
1802 // start fresh
1803 plugins.clear();
1805 OSyncPlugin *plugin;
1806 OSyncList *plugin_list, *p;
1808 plugin_list = m_priv->osync_plugin_env_get_plugins(m_priv->plugin_env.get());
1809 for( p = plugin_list; p; p = p->next ) {
1810 plugin = (OSyncPlugin *) p->data;
1811 plugins.push_back(m_priv->osync_plugin_get_name(plugin));
1814 m_priv->osync_list_free(plugin_list);
1817 void OpenSync40::GetFormats(format_list_type &formats)
1819 // start fresh
1820 formats.clear();
1822 OSyncList *o, *list = m_priv->osync_format_env_get_objformats(m_priv->format_env.get());
1824 for( o = list; o; o = o->next ) {
1825 OSyncObjFormat *format = (OSyncObjFormat *) o->data;
1827 Format new_format;
1828 new_format.name = m_priv->osync_objformat_get_name(format);
1829 new_format.object_type = m_priv->osync_objformat_get_objtype(format);
1831 formats.push_back(new_format);
1834 m_priv->osync_list_free(list);
1837 void OpenSync40::GetGroupNames(string_list_type &groups)
1839 // start fresh
1840 groups.clear();
1842 OSyncGroup *group;
1843 OSyncList *g, *group_list = m_priv->osync_group_env_get_groups(m_priv->group_env.get());
1845 for( g = group_list; g; g = g->next ) {
1846 group = (OSyncGroup *) g->data;
1847 groups.push_back(m_priv->osync_group_get_name(group));
1850 m_priv->osync_list_free(group_list);
1853 void OpenSync40::GetMembers(const std::string &group_name,
1854 member_list_type &members)
1856 // start fresh
1857 members.clear();
1859 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1860 if( !group ) {
1861 ostringstream oss;
1862 oss << "GetMembers(): " << _C("Unable to find group with name: ") << group_name;
1863 throw std::runtime_error(oss.str());
1866 OSyncList *member_list = m_priv->osync_group_get_members(group);
1867 for( OSyncList *m = member_list; m; m = m->next ) {
1868 Member new_member;
1869 OSyncMember *member = (OSyncMember *) m->data;
1870 const char *membername = m_priv->osync_member_get_name(member);
1871 if (membername) {
1872 new_member.friendly_name = membername;
1875 new_member.group_name = group_name;
1876 new_member.id = m_priv->osync_member_get_id(member);
1877 new_member.plugin_name = m_priv->osync_member_get_pluginname(member);
1879 // add to member list
1880 members.push_back(new_member);
1883 // cleanup
1884 m_priv->osync_list_free(member_list);
1887 void OpenSync40::AddGroup(const std::string &group_name)
1889 OSyncGroup *group = m_priv->osync_group_new(m_priv->error);
1890 if( !group )
1891 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1893 m_priv->osync_group_set_name(group, group_name.c_str());
1894 if( !m_priv->osync_group_env_add_group(m_priv->group_env.get(), group, m_priv->error) ) {
1895 m_priv->osync_group_unref(group);
1896 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1899 if( !m_priv->osync_group_save(group, m_priv->error) ) {
1900 m_priv->osync_group_unref(group);
1901 throw std::runtime_error("AddGroup(): " + m_priv->error.GetErrorMsg());
1904 m_priv->osync_group_unref(group);
1907 void OpenSync40::DeleteGroup(const std::string &group_name)
1909 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1910 if( !group )
1911 throw std::runtime_error(string("DeleteGroup(): ") + _C("Group not found: ") + group_name);
1913 if( !m_priv->osync_group_delete(group, m_priv->error) )
1914 throw std::runtime_error("DeleteGroup(): " + m_priv->error.GetErrorMsg());
1916 m_priv->osync_group_env_remove_group(m_priv->group_env.get(), group);
1919 Converter& OpenSync40::GetConverter()
1921 return m_priv->converter;
1924 long OpenSync40::AddMember(const std::string &group_name,
1925 const std::string &plugin_name,
1926 const std::string &member_name)
1928 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1929 if( !group )
1930 throw std::runtime_error(string("AddMember(): ") + _C("Group not found: ") + group_name);
1932 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), plugin_name.c_str());
1933 if( !plugin )
1934 throw std::runtime_error(string("AddMember(): ") + _C("Plugin not found: ") + plugin_name);
1936 vLateSmartPtr<OSyncMember, void(*)(OSyncMember*)> mptr(m_priv->osync_member_unref);
1937 mptr = m_priv->osync_member_new(m_priv->error);
1938 if( !mptr.get() )
1939 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1941 m_priv->osync_group_add_member(group, mptr.get());
1942 m_priv->osync_member_set_pluginname(mptr.get(), plugin_name.c_str());
1944 if( member_name.size() )
1945 m_priv->osync_member_set_name(mptr.get(), member_name.c_str());
1947 if( !m_priv->osync_member_save(mptr.get(), m_priv->error) )
1948 throw std::runtime_error("AddMember(): " + m_priv->error.GetErrorMsg());
1950 return m_priv->osync_member_get_id(mptr.get());
1953 void OpenSync40::DeleteMember(const std::string &group_name, long member_id)
1955 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1956 if( !group )
1957 throw std::runtime_error(string("DeleteMember(): ") + _C("Group not found: ") + group_name);
1959 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1960 if( !member ) {
1961 ostringstream oss;
1962 oss << "DeleteMember(): " << _C("Member not found: ") << member_id;
1963 throw std::runtime_error(oss.str());
1966 if( !m_priv->osync_member_delete(member, m_priv->error) )
1967 throw std::runtime_error("DeleteMember(): " + m_priv->error.GetErrorMsg());
1969 m_priv->osync_group_remove_member(group, member);
1972 void OpenSync40::DeleteMember(const std::string &group_name,
1973 const std::string &plugin_name)
1975 member_list_type mlist;
1976 GetMembers(group_name, mlist);
1977 Member *member = mlist.Find(plugin_name.c_str());
1978 if( !member )
1979 throw std::runtime_error(string("DeleteMember(): ") + _C("Member not found: ") + plugin_name);
1981 DeleteMember(group_name, member->id);
1984 bool OpenSync40::IsConfigurable(const std::string &group_name,
1985 long member_id)
1987 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
1988 if( !group )
1989 throw std::runtime_error(string("IsConfigurable(): ") + _C("Group not found: ") + group_name);
1991 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
1992 if( !member ) {
1993 ostringstream oss;
1994 oss << "IsConfigurable(): " << _C("Member not found: ") << member_id;
1995 throw std::runtime_error(oss.str());
1998 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
1999 if( !plugin )
2000 throw std::runtime_error(string("IsConfigurable(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2003 OSyncPluginConfigurationType type = m_priv->osync_plugin_get_config_type(plugin);
2004 return type != OSYNC_PLUGIN_NO_CONFIGURATION;
2007 std::string OpenSync40::GetConfiguration(const std::string &group_name,
2008 long member_id)
2010 if( !IsConfigurable(group_name, member_id) ) {
2011 throw std::runtime_error(string("GetConfiguration(): ") + string_vprintf(_C("Member %ld of group '%s' does not accept configuration."),
2012 member_id,
2013 group_name.c_str()));
2016 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2017 if( !group )
2018 throw std::runtime_error(string("GetConfiguration(): ") + _C("Group not found: ") + group_name);
2020 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2021 if( !member ) {
2022 ostringstream oss;
2023 oss << "GetConfiguration(): " << _C("Member not found: ") << member_id;
2024 throw std::runtime_error(oss.str());
2027 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2028 if( !plugin )
2029 throw std::runtime_error(string("GetConfiguration(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2032 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2033 if( !config )
2034 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2036 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2037 // functions, and then load that from the file again, and
2038 // return that string as the configuratin.
2040 TempDir tempdir("opensyncapi");
2042 string filename = tempdir.GetNewFilename();
2044 if( !m_priv->osync_plugin_config_file_save(config, filename.c_str(), m_priv->error) )
2045 throw std::runtime_error("GetConfiguration(): " + m_priv->error.GetErrorMsg());
2047 ifstream in(filename.c_str());
2048 string config_data;
2049 char buf[4096];
2050 while( in ) {
2051 in.read(buf, sizeof(buf));
2052 config_data.append(buf, in.gcount());
2055 return config_data;
2058 OS40PluginConfig OpenSync40::GetConfigurationObj(const std::string &group_name,
2059 long member_id)
2061 if( !IsConfigurable(group_name, member_id) ) {
2062 throw std::runtime_error(string("GetConfigurationObj(): ") + string_vprintf(_C("Member %ld of group '%s' does not accept configuration."),
2063 member_id,
2064 group_name.c_str()));
2067 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2068 if( !group )
2069 throw std::runtime_error(string("GetConfigurationObj(): ") + _C("Group not found: ") + group_name);
2071 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2072 if( !member ) {
2073 ostringstream oss;
2074 oss << "GetConfigurationObj(): " << _C("Member not found: ") << member_id;
2075 throw std::runtime_error(oss.str());
2078 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2079 if( !plugin )
2080 throw std::runtime_error(string("GetConfigurationObj(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2083 OSyncPluginConfig *config = m_priv->osync_member_get_config_or_default(member, m_priv->error);
2084 if( !config )
2085 throw std::runtime_error("GetConfigurationObj(): " + m_priv->error.GetErrorMsg());
2087 return OS40PluginConfig(m_priv, member, config);
2090 void OpenSync40::SetConfiguration(const std::string &group_name,
2091 long member_id,
2092 const std::string &config_data)
2094 if( !IsConfigurable(group_name, member_id) ) {
2095 throw std::runtime_error(string("SetConfiguration(): ") + string_vprintf(_C("Member %ld of group '%s' does not accept configuration."),
2096 member_id,
2097 group_name.c_str()));
2100 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2101 if( !group )
2102 throw std::runtime_error(string("SetConfiguration(): ") + _C("Group not found: ") + group_name);
2104 OSyncMember *member = m_priv->osync_group_find_member(group, member_id);
2105 if( !member ) {
2106 ostringstream oss;
2107 oss << "SetConfiguration(): " << _C("Member not found: ") << member_id;
2108 throw std::runtime_error(oss.str());
2111 OSyncPlugin *plugin = m_priv->osync_plugin_env_find_plugin(m_priv->plugin_env.get(), m_priv->osync_member_get_pluginname(member));
2112 if( !plugin )
2113 throw std::runtime_error(string("SetConfiguration(): ") + _C("Unable to find plugin with name: ") + m_priv->osync_member_get_pluginname(member));
2116 // To emulate 0.22 behaviour, we need to use 0.4x save-to-file
2117 // functions, and then load that from the file again, and
2118 // return that string as the configuratin.
2120 TempDir tempdir("opensyncapi");
2122 string filename = tempdir.GetNewFilename();
2124 // write config data to file
2126 ofstream out(filename.c_str());
2127 out << config_data;
2130 // load brand new config from file
2131 // if a new config object isn't created here, the loaded config
2132 // will be added to the existing config
2133 OSyncPluginConfig *new_config = m_priv->osync_plugin_config_new(m_priv->error);
2134 if( !m_priv->osync_plugin_config_file_load(new_config, filename.c_str(), m_priv->error) )
2135 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2137 m_priv->osync_member_set_config(member, new_config);
2139 if( !m_priv->osync_member_save(member, m_priv->error))
2140 throw std::runtime_error("SetConfiguration(): " + m_priv->error.GetErrorMsg());
2143 void OpenSync40::Discover(const std::string &group_name)
2145 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2146 if( !group )
2147 throw std::runtime_error(string("Discover(): ") + _C("Group not found: ") + group_name);
2149 EngineHandle engine(m_priv->osync_engine_unref);
2150 engine = m_priv->osync_engine_new(group, m_priv->error);
2151 if( !engine.get() )
2152 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2154 SyncListHandle members(m_priv->osync_list_free);
2155 members = m_priv->osync_group_get_members(group);
2156 OSyncList *m = NULL;
2157 for( m = members.get(); m; m = m->next ) {
2158 OSyncMember *member = (OSyncMember *) m->data;
2160 /* Discover the objtypes for the members */
2161 if( !m_priv->osync_engine_discover_and_block(engine.get(), member, m_priv->error))
2162 break;
2164 SyncListHandle objtypes(m_priv->osync_list_free);
2165 objtypes = m_priv->osync_member_get_objtypes(member);
2166 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2167 m_priv->osync_error_set(m_priv->error, OSYNC_ERROR_GENERIC, _C("discover failed: no objtypes returned"));
2168 break;
2171 if( !m_priv->osync_member_save(member, m_priv->error) )
2172 break;
2175 // check for error
2176 if( m ) {
2177 m_priv->osync_engine_finalize(engine.get(), m_priv->error);
2178 throw std::runtime_error("Discover(): " + m_priv->error.GetErrorMsg());
2182 void OpenSync40::Sync(const std::string &group_name,
2183 SyncStatus &status_callback,
2184 Config::pst_type sync_types)
2186 OSyncGroup *group = m_priv->osync_group_env_find_group(m_priv->group_env.get(), group_name.c_str());
2187 if( !group )
2188 throw std::runtime_error(string("Sync(): ") + _C("Group not found: ") + group_name);
2190 // enable/disable each objtype, as per sync_types
2191 if( !(sync_types & PST_DO_NOT_SET) ) {
2192 cerr << "enabling objtypes: " << sync_types << endl;
2193 m_priv->osync_group_set_objtype_enabled(group, "contact",
2194 (sync_types & PST_CONTACTS) ? TRUE : FALSE);
2195 m_priv->osync_group_set_objtype_enabled(group, "event",
2196 (sync_types & PST_EVENTS) ? TRUE : FALSE);
2197 m_priv->osync_group_set_objtype_enabled(group, "note",
2198 (sync_types & PST_NOTES) ? TRUE : FALSE);
2199 m_priv->osync_group_set_objtype_enabled(group, "todo",
2200 (sync_types & PST_TODOS) ? TRUE : FALSE);
2203 EngineHandle engine(m_priv->osync_engine_unref);
2204 engine = m_priv->osync_engine_new(group, m_priv->error);
2205 if( !engine.get() )
2206 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2209 CallbackBundle cbdata(m_priv, status_callback);
2211 m_priv->osync_engine_set_conflict_callback(engine.get(), conflict_handler, &cbdata);
2212 m_priv->osync_engine_set_changestatus_callback(engine.get(), entry_status, &cbdata);
2213 m_priv->osync_engine_set_mappingstatus_callback(engine.get(), mapping_status, &cbdata);
2214 m_priv->osync_engine_set_enginestatus_callback(engine.get(), engine_status, &cbdata);
2215 m_priv->osync_engine_set_memberstatus_callback(engine.get(), member_status, &cbdata);
2216 m_priv->osync_engine_set_multiply_callback(engine.get(), multiply_summary, &cbdata);
2219 SyncListHandle members(m_priv->osync_list_free);
2220 members = m_priv->osync_group_get_members(group);
2221 OSyncList *m = NULL;
2222 for( m = members.get(); m; m = m->next ) {
2223 OSyncMember *member = (OSyncMember *) m->data;
2225 SyncListHandle objtypes(m_priv->osync_list_free);
2226 objtypes = m_priv->osync_member_get_objtypes(member);
2227 if( m_priv->osync_list_length(objtypes.get()) == 0 ) {
2228 cout << "Sync(): " << "Member " << m_priv->osync_member_get_id(member) << " has no objtypes. Has it already been discovered?" << endl;
2232 if( !m_priv->osync_engine_initialize(engine.get(), m_priv->error) )
2233 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2235 if( !m_priv->osync_engine_synchronize_and_block(engine.get(), m_priv->error) ) {
2236 m_priv->osync_engine_finalize(engine.get(), NULL);
2237 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2240 if( !m_priv->osync_engine_finalize(engine.get(), m_priv->error) )
2241 throw std::runtime_error("Sync(): " + m_priv->error.GetErrorMsg());
2245 /////////////////////////////////////////////////////////////////////////////
2246 // TossError public members
2248 /// Returns NULL if no error
2249 std::string TossError::GetErrorMsg()
2251 return std::string(m_priv->osync_error_print_stack_wrapper(&m_error));
2254 bool TossError::IsSet()
2256 return m_priv->osync_error_is_set(&m_error);
2259 void TossError::Clear()
2261 if( m_error ) {
2262 m_priv->osync_error_unref(&m_error);
2263 m_error = 0;
2267 } // namespace OpenSync