changed indentation to tabs
[opensync.git] / tools / osyncplugin.c
blob51aa95b16c0de5cb553a1d149c72716917421d33
1 /*
2 * osyncplugin - swiss-knife for testing OpenSync synchronization plugins
3 * Copyright (C) 2008 Daniel Gollub <dgollub@suse.de>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #ifndef _WIN32
27 #include <unistd.h>
28 #endif
30 #include <glib.h>
32 #include <opensync/opensync.h>
33 #include <opensync/opensync-ipc.h>
34 #include <opensync/opensync-data.h>
35 #include <opensync/opensync-plugin.h>
36 #include <opensync/opensync-format.h>
39 #include <opensync/opensync-context.h>
41 char *pluginpath = NULL;
42 char *formatpath = NULL;
43 char *pluginname = NULL;
44 char *configfile = NULL;
45 char *configdir = NULL;
46 char *syncgroup = NULL;
47 osync_bool pluginlist= FALSE;
48 GList *sinks = NULL;
49 GList *cmdlist = NULL;
50 GList *changesList = NULL;
51 GMainContext *ctx = NULL;
52 OSyncPlugin *plugin = NULL;
53 OSyncPluginEnv *plugin_env = NULL;
54 OSyncFormatEnv *format_env = NULL;
55 OSyncPluginInfo *plugin_info = NULL;
57 typedef enum {
58 CMD_EMPTY,
59 CMD_INITIALIZE,
60 CMD_FINALIZE,
61 CMD_CONNECT,
62 CMD_DISCONNECT,
63 CMD_SYNC,
64 CMD_SLOWSYNC,
65 CMD_FASTSYNC,
66 CMD_COMMIT,
67 CMD_BATCHCOMMIT,
68 CMD_COMMITTEDALL,
69 CMD_READ,
70 CMD_WRITE,
71 CMD_SYNCDONE,
72 CMD_DISCOVER
73 } Cmd;
75 typedef struct _Command {
76 Cmd cmd;
77 char *arg;
78 GCond *cond;
79 GMutex *mutex;
80 OSyncObjTypeSink *sink;
81 osync_bool done;
82 } Command;
84 typedef enum {
85 /* regular sync - plugin decides for slow or fast sync */
86 SYNCTYPE_NORMAL,
87 /* force fast sync */
88 SYNCTYPE_FORCE_FASTSYNC,
89 /* foce slow sync */
90 SYNCTYPE_FORCE_SLOWSYNC
91 } SyncType;
94 * Argument handling
96 static Command *new_command(Cmd cmd, const char *arg) {
98 Command *newcommand = malloc(sizeof(Command));
99 if (!newcommand) {
100 perror("Can't allocate new command");
101 exit(errno);
104 memset(newcommand, 0, sizeof(Command));
106 newcommand->cmd = cmd;
107 if (arg)
108 newcommand->arg = strdup(arg);
110 newcommand->mutex = g_mutex_new();
111 newcommand->cond = g_cond_new();
113 cmdlist = g_list_append(cmdlist, newcommand);
115 return newcommand;
118 static void free_command(Command **cmd) {
119 assert(*cmd);
121 if ((*cmd)->arg)
122 free((*cmd)->arg);
124 free(*cmd);
125 *cmd = NULL;
128 static void usage(const char *name)
130 /* TODO: improve usage output */
131 fprintf(stderr, "Usage: %s\n", name);
133 fprintf (stderr, "Configuration options:\n");
134 fprintf (stderr, "[--config] \tSet config file\n");
135 fprintf (stderr, "[--configdir] \tSet different config directory. Default: ~./opensync\n");
136 fprintf (stderr, "[--syncgroup] \tSet the name of the sync group. Default: osyncplugin\n");
138 fprintf (stderr, "Plugin options:\n");
139 fprintf (stderr, "[--plugin] \tSet plugin\n");
140 fprintf (stderr, "[--pluginpath] \t\n");
141 fprintf (stderr, "[--pluginlist] \tShow list of plugins\n");
143 fprintf (stderr, "Format options:\n");
144 fprintf (stderr, "[--formatpath] \t\n");
146 fprintf (stderr, "Command options:\n");
147 fprintf (stderr, "[--initialize] \t\n");
148 fprintf (stderr, "[--connect] \t\n");
149 fprintf (stderr, "[--disconnect] \t\n");
150 fprintf (stderr, "[--finalize] \t\n");
151 fprintf (stderr, "[--slowsync] \t\n");
152 fprintf (stderr, "[--sync] \t\n");
153 fprintf (stderr, "[--fastsync] \t\n");
154 fprintf (stderr, "[--syncdone] \t\n");
155 fprintf (stderr, "[--committedall] \t\n");
156 fprintf (stderr, "[--commit] \t\n");
157 fprintf (stderr, "[--batchcommit] \t\n");
158 fprintf (stderr, "[--write] \t\n");
159 fprintf (stderr, "[--read] \t\n");
160 fprintf (stderr, "[--empty] \t\n");
162 exit(1);
165 static void parse_args(int argc, char **argv) {
167 int i;
168 char *arg;
170 for (i=1; i < argc; i++) {
172 arg = argv[i];
174 if (!strcmp(arg, "--config") || !strcmp(arg, "-c")) {
175 if (!configfile)
176 configfile = strdup(argv[i+1]);
178 i++;
179 continue;
180 } else if (!strcmp(arg, "--configdir") || !strcmp(arg, "-C")) {
181 if (!configdir)
182 configdir = strdup(argv[i+1]);
184 i++;
185 continue;
186 } else if (!strcmp(arg, "--syncgroup")) {
187 if (!syncgroup)
188 syncgroup = strdup(argv[i+1]);
189 i++;
190 continue;
191 } else if (!strcmp(arg, "--plugin") || !strcmp(arg, "-p")) {
192 if (!pluginname)
193 pluginname = strdup(argv[i+1]);
195 i++;
196 continue;
197 } else if (!strcmp(arg, "--pluginpath") || !strcmp(arg, "-P")) {
198 if (!pluginpath)
199 pluginpath = strdup(argv[i+1]);
201 i++;
202 continue;
203 } else if (!strcmp(arg, "--pluginlist") || !strcmp(arg, "-L")) {
204 pluginlist= TRUE;
206 i++;
207 continue;
208 } else if (!strcmp(arg, "--formatpath") || !strcmp(arg, "-F")) {
209 if (!formatpath)
210 formatpath = strdup(argv[i+1]);
212 i++;
213 continue;
214 } else if (!strcmp(arg, "--initialize")) {
215 new_command(CMD_INITIALIZE, NULL);
216 continue;
217 } else if (!strcmp(arg, "--connect")) {
218 if (!argv[i+1] || *argv[i+1] == '-')
219 new_command(CMD_CONNECT, NULL);
220 else
221 new_command(CMD_CONNECT, argv[++i]);
223 continue;
224 } else if (!strcmp(arg, "--disconnect")) {
225 if (!argv[i+1] || *argv[i+1] == '-')
226 new_command(CMD_DISCONNECT, NULL);
227 else
228 new_command(CMD_DISCONNECT, argv[++i]);
230 continue;
231 } else if (!strcmp(arg, "--finalize")) {
232 new_command(CMD_FINALIZE, NULL);
233 continue;
234 } else if (!strcmp(arg, "--slowsync")) {
235 if (!argv[i+1] || *argv[i+1] == '-')
236 new_command(CMD_SLOWSYNC, NULL);
237 else
238 new_command(CMD_SLOWSYNC, argv[++i]);
240 continue;
241 } else if (!strcmp(arg, "--sync")) {
242 if (!argv[i+1] || *argv[i+1] == '-')
243 new_command(CMD_SYNC, NULL);
244 else
245 new_command(CMD_SYNC, argv[++i]);
247 continue;
248 } else if (!strcmp(arg, "--fastsync")) {
249 if (!argv[i+1] || *argv[i+1] == '-')
250 new_command(CMD_FASTSYNC, NULL);
251 else
252 new_command(CMD_FASTSYNC, argv[++i]);
254 continue;
255 } else if (!strcmp(arg, "--syncdone")) {
256 if (!argv[i+1] || *argv[i+1] == '-')
257 new_command(CMD_SYNCDONE, NULL);
258 else
259 new_command(CMD_SYNCDONE, argv[++i]);
261 continue;
262 } else if (!strcmp(arg, "--committedall")) {
263 if (!argv[i+1] || *argv[i+1] == '-')
264 new_command(CMD_COMMITTEDALL, NULL);
265 else
266 new_command(CMD_COMMITTEDALL, argv[++i]);
268 continue;
269 } else if (!strcmp(arg, "--commit")) {
270 if (!argv[i+1] || *argv[i+1] == '-')
271 new_command(CMD_COMMIT, NULL);
272 else
273 new_command(CMD_COMMIT, argv[++i]);
275 continue;
276 } else if (!strcmp(arg, "--batchcommit")) {
277 if (!argv[i+1] || *argv[i+1] == '-')
278 new_command(CMD_BATCHCOMMIT, NULL);
279 else
280 new_command(CMD_BATCHCOMMIT, argv[++i]);
282 continue;
283 } else if (!strcmp(arg, "--write")) {
284 if (!argv[i+1] || *argv[i+1] == '-')
285 new_command(CMD_WRITE, NULL);
286 else
287 new_command(CMD_WRITE, argv[++i]);
289 continue;
290 } else if (!strcmp(arg, "--read")) {
291 if (!argv[i+1] || *argv[i+1] == '-')
292 new_command(CMD_READ, NULL);
293 else
294 new_command(CMD_READ, argv[++i]);
296 continue;
297 } else if (!strcmp(arg, "--discover")) {
298 if (!argv[i+1] || *argv[i+1] == '-')
299 new_command(CMD_DISCOVER, NULL);
300 else
301 new_command(CMD_DISCOVER, argv[++i]);
303 continue;
304 } else if (!strcmp(arg, "--empty")) {
305 if (!argv[i+1] || *argv[i+1] == '-')
306 new_command(CMD_EMPTY, NULL);
307 else
308 new_command(CMD_EMPTY, argv[++i]);
310 continue;
311 } else {
312 fprintf(stderr, "Unknown argument: %s\n", argv[i]);
313 usage(argv[0]);
317 if (pluginlist)
318 return;
320 if (!cmdlist)
321 fprintf(stderr, "No command set.\n");
323 if (!pluginname)
324 fprintf(stderr, "No plugin set.\n");
326 if (!configdir)
327 fprintf(stderr, "No working/configuraiton directory set.\n");
329 if (!pluginname || !cmdlist || !configdir)
330 usage(argv[0]);
334 * Plugin Commands
337 static osync_bool init(OSyncError **error) {
338 OSyncPluginConfig *config;
339 assert(!plugin);
340 assert(!plugin_env);
342 if (!(plugin_env = osync_plugin_env_new(error)))
343 goto error;
345 if (!(format_env = osync_format_env_new(error)))
346 goto error_free_pluginenv;
348 if (!osync_format_env_load_plugins(format_env, formatpath, error))
349 goto error_free_formatenv;
351 if (osync_error_is_set(error)) {
352 fprintf(stderr, "WARNING! Some plugins couldn't get loaded in "
353 "format plugin environment: %s\n", osync_error_print(error));
354 osync_error_unref(error);
357 if (!osync_plugin_env_load(plugin_env, pluginpath, error))
358 goto error_free_pluginenv;
360 if (osync_error_is_set(error)) {
361 fprintf(stderr, "WARNING! Some plugins couldn't get loaded in "
362 "plugin environment: %s\n", osync_error_print(error));
363 osync_error_unref(error);
366 if (!(plugin = osync_plugin_env_find_plugin(plugin_env, pluginname))) {
367 osync_error_set(error, OSYNC_ERROR_PLUGIN_NOT_FOUND, "Plugin not found: \"%s\"", pluginname);
368 goto error_free_pluginenv;
371 if (!(plugin_info = osync_plugin_info_new(error)))
372 goto error_free_pluginenv;
374 config = osync_plugin_config_new(error);
375 if (!config)
376 goto error_free_plugininfo;
378 if (osync_plugin_get_config_type(plugin) != OSYNC_PLUGIN_NO_CONFIGURATION && configfile) {
379 OSyncList *r = NULL;
380 if (!osync_plugin_config_file_load(config, configfile, NULL, error))
381 goto error_free_pluginconfig;
383 osync_plugin_info_set_config(plugin_info, config);
385 /** Redudant(aka. stolen) code from opensync/client/opensync_client.c */
386 /* Enable active sinks */
388 if (config)
389 r = osync_plugin_config_get_resources(config);
391 for (; r; r = r->next) {
392 OSyncPluginResource *res = r->data;
393 OSyncObjTypeSink *sink;
395 const char *objtype = osync_plugin_resource_get_objtype(res);
396 OSyncList *o = NULL;
397 /* Check for ObjType sink */
398 if (!(sink = osync_plugin_info_find_objtype(plugin_info, objtype))) {
399 sink = osync_objtype_sink_new(objtype, error);
400 if (!sink)
401 goto error_free_pluginconfig;
403 osync_plugin_info_add_objtype(plugin_info, sink);
406 o = osync_plugin_resource_get_objformat_sinks(res);
407 for (; o; o = o->next) {
408 OSyncObjFormatSink *format_sink = (OSyncObjFormatSink *) o->data;
409 osync_objtype_sink_add_objformat_sink(sink, format_sink);
413 osync_plugin_config_unref(config);
417 if (!configfile && osync_plugin_get_config_type(plugin) == OSYNC_PLUGIN_NEEDS_CONFIGURATION) {
418 osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "Plugin \"%s\" requires configuration!", pluginname);
419 goto error_free_pluginconfig;
422 assert(!ctx);
423 ctx = g_main_context_new();
425 osync_plugin_info_set_configdir(plugin_info, configdir);
426 osync_plugin_info_set_loop(plugin_info, ctx);
427 osync_plugin_info_set_format_env(plugin_info, format_env);
428 osync_plugin_info_set_groupname(plugin_info, syncgroup);
430 return TRUE;
433 error_free_loop:
434 g_main_context_unref(ctx);
436 error_free_pluginconfig:
437 osync_plugin_config_unref(config);
438 error_free_plugininfo:
439 osync_plugin_info_unref(plugin_info);
440 error_free_formatenv:
441 osync_format_env_unref(format_env);
442 format_env = NULL;
443 error_free_pluginenv:
444 osync_plugin_env_unref(plugin_env);
445 plugin_env = NULL;
446 error:
447 return FALSE;
450 static void *plugin_initialize(OSyncError **error)
452 unsigned int n, num_sinks = osync_plugin_info_num_objtypes(plugin_info);
453 void *plugin_data;
454 osync_bool couldinit;
455 couldinit = osync_plugin_initialize(plugin, &(plugin_data), plugin_info, error);
458 for (n = 0; n < num_sinks; n++) {
459 OSyncObjTypeSink *sink = osync_plugin_info_nth_objtype(plugin_info, n);
461 if (!osync_objtype_sink_load_anchor(sink, plugin_info, error))
462 return NULL;
465 return plugin_data;
468 static void finalize_plugin(void **plugin_data)
471 if (!*plugin_data)
472 return;
474 osync_plugin_finalize(plugin, *plugin_data);
475 *plugin_data = NULL;
479 static OSyncObjTypeSink *find_sink(const char *objtype, OSyncError **error)
481 OSyncObjTypeSink *sink = NULL;
482 assert(objtype);
484 sink = osync_plugin_info_find_objtype(plugin_info, objtype);
485 if (!sink) {
486 osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find sink for %s", objtype);
487 return NULL;
490 return sink;
493 static OSyncObjTypeSink *get_main_sink()
495 return osync_plugin_info_get_main_sink(plugin_info);
498 static const char *_osyncplugin_changetype_str(OSyncChange *change)
500 const char *type;
501 assert(change);
503 switch (osync_change_get_changetype(change)) {
504 case OSYNC_CHANGE_TYPE_ADDED:
505 type = "ADDED";
506 break;
507 case OSYNC_CHANGE_TYPE_UNMODIFIED:
508 type = "UNMODIFIED";
509 break;
510 case OSYNC_CHANGE_TYPE_DELETED:
511 type = "DELETED";
512 break;
513 case OSYNC_CHANGE_TYPE_MODIFIED:
514 type = "MODIFIED";
515 break;
516 case OSYNC_CHANGE_TYPE_UNKNOWN:
517 default:
518 type = "UNKNOWN";
519 break;
522 return type;
525 //typedef void (* OSyncContextChangeFn) (OSyncChange *, void *);
526 static void _osyncplugin_ctx_change_callback(OSyncChange *change, void *user_data)
528 Command *cmd = (Command *) user_data;
529 OSyncObjTypeSink *sink = cmd->sink;
531 printf("GETCHANGES:\t%s\t%s\t%s",
532 _osyncplugin_changetype_str(change),
533 osync_objtype_sink_get_name(sink),
534 osync_change_get_uid(change));
536 if (osync_change_get_objformat(change))
537 printf("\t%s", osync_objformat_get_name(osync_change_get_objformat(change)));
539 printf("\n");
541 osync_change_ref(change);
542 changesList = g_list_append(changesList, change);
545 //typedef void (* OSyncContextCallbackFn)(void *, OSyncError *);
546 static void _osyncplugin_ctx_callback_getchanges(void *user_data, OSyncError *error)
548 Command *cmd = (Command *) user_data;
549 OSyncObjTypeSink *sink = cmd->sink;
551 if (error)
552 fprintf(stderr, "Sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&error));
554 g_mutex_lock(cmd->mutex);
555 g_cond_signal(cmd->cond);
556 cmd->done = TRUE;
557 g_mutex_unlock(cmd->mutex);
561 static osync_bool get_changes_sink(Command *cmd, OSyncObjTypeSink *sink, SyncType type, void *plugin_data, OSyncError **error)
563 OSyncContext *context = NULL;
564 assert(sink);
566 switch (type) {
567 case SYNCTYPE_NORMAL:
568 break;
569 case SYNCTYPE_FORCE_FASTSYNC:
570 osync_objtype_sink_set_slowsync(sink, FALSE);
571 break;
572 case SYNCTYPE_FORCE_SLOWSYNC:
573 osync_objtype_sink_set_slowsync(sink, TRUE);
574 break;
577 context = osync_context_new(error);
578 if (!context)
579 goto error;
581 osync_context_set_changes_callback(context, _osyncplugin_ctx_change_callback);
582 osync_context_set_callback(context, _osyncplugin_ctx_callback_getchanges, cmd);
584 osync_plugin_info_set_sink(plugin_info, sink);
586 osync_objtype_sink_get_changes(sink, plugin_data, plugin_info, context);
588 osync_context_unref(context);
591 return TRUE;
593 error:
594 return FALSE;
597 static osync_bool get_changes(Command *cmd, SyncType type, void *plugin_data, OSyncError **error)
599 int num, i;
600 OSyncObjTypeSink *sink = NULL;
601 const char *objtype = cmd->arg;
603 if (objtype) {
604 sink = find_sink(objtype, error);
605 if (!sink)
606 goto error;
608 cmd->sink = sink;
609 if (!get_changes_sink(cmd, sink, type, plugin_data, error))
610 goto error;
612 } else {
613 /* all available objtypes */
614 num = osync_plugin_info_num_objtypes(plugin_info);
615 for (i=0; i < num; i++) {
616 sink = osync_plugin_info_nth_objtype(plugin_info, i);
618 cmd->sink = sink;
619 if (!get_changes_sink(cmd, sink, type, plugin_data, error))
620 goto error;
623 /* last but not least - the main sink */
624 if (get_main_sink())
626 if (!get_changes_sink(cmd, get_main_sink(), type, plugin_data, error))
627 goto error;
630 return TRUE;
632 error:
633 return FALSE;
636 static void _osyncplugin_ctx_callback_connect(void *user_data, OSyncError *error)
638 OSyncError *locerror = NULL;
639 Command *cmd = NULL;
640 OSyncObjTypeSink *sink = NULL;
642 assert(user_data);
644 cmd = (Command *) user_data;
645 sink = cmd->sink;
647 if (error) {
648 osync_error_set_from_error(&locerror, &error);
649 goto error;
652 if (osync_objtype_sink_get_slowsync(sink)) {
653 printf("SlowSync got requested by CONNECT function");
654 if (osync_objtype_sink_get_name(sink))
655 printf(" for ObjType: \"%s\"", osync_objtype_sink_get_name(sink));
657 printf(".\n");
660 g_mutex_lock(cmd->mutex);
661 g_cond_signal(cmd->cond);
662 cmd->done = TRUE;
663 g_mutex_unlock(cmd->mutex);
665 return;
666 error:
667 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
668 return;
671 static osync_bool connect_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
672 OSyncContext *context = NULL;
673 assert(sink);
674 assert(cmd);
676 context = osync_context_new(error);
677 if (!context)
678 goto error;
680 cmd->sink = sink;
682 osync_context_set_callback(context, _osyncplugin_ctx_callback_connect, cmd);
684 osync_plugin_info_set_sink(plugin_info, sink);
686 osync_objtype_sink_connect(sink, plugin_data, plugin_info, context);
688 osync_context_unref(context);
690 return TRUE;
692 error:
693 return FALSE;
696 static osync_bool connect_plugin(Command *cmd, void *plugin_data, OSyncError **error)
698 unsigned int i, num;
699 OSyncObjTypeSink *sink = NULL;
700 const char *objtype = cmd->arg;
702 if (objtype) {
703 sink = find_sink(objtype, error);
704 if (!sink)
705 goto error;
707 if (!connect_sink(cmd, sink, plugin_data, error))
708 goto error;
709 } else {
710 num = osync_plugin_info_num_objtypes(plugin_info);
711 for (i=0; i < num; i++) {
712 sink = osync_plugin_info_nth_objtype(plugin_info, i);
714 if (!connect_sink(cmd, sink, plugin_data, error))
715 goto error;
718 /* last but not least - the main sink */
719 if (get_main_sink())
720 if (!connect_sink(cmd, get_main_sink(), plugin_data, error))
721 goto error;
724 return TRUE;
725 error:
726 return FALSE;
729 static void _osyncplugin_ctx_callback_disconnect(void *user_data, OSyncError *error)
731 OSyncError *locerror = NULL;
732 Command *cmd = NULL;
733 OSyncObjTypeSink *sink = NULL;
735 assert(user_data);
737 cmd = (Command *) user_data;
738 sink = cmd->sink;
740 if (error) {
741 osync_error_set_from_error(&locerror, &error);
742 goto error;
745 if (osync_objtype_sink_get_name(sink))
746 printf("Sink \"%s\"", osync_objtype_sink_get_name(sink));
747 else
748 printf("Main Sink");
750 printf(" disconnected.\n");
752 g_mutex_lock(cmd->mutex);
753 g_cond_signal(cmd->cond);
754 cmd->done = TRUE;
755 g_mutex_unlock(cmd->mutex);
757 return;
758 error:
759 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
760 return;
763 static osync_bool disconnect_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
764 OSyncContext *context = osync_context_new(error);
765 assert(sink);
766 assert(cmd);
768 if (!context)
769 goto error;
771 cmd->sink = sink;
773 osync_context_set_callback(context, _osyncplugin_ctx_callback_disconnect, cmd);
775 osync_plugin_info_set_sink(plugin_info, sink);
777 osync_objtype_sink_disconnect(sink, plugin_data, plugin_info, context);
779 osync_context_unref(context);
781 return TRUE;
783 error:
784 return FALSE;
787 static osync_bool disconnect(Command *cmd, void *plugin_data, OSyncError **error)
790 int i, num;
791 OSyncObjTypeSink *sink = NULL;
792 const char *objtype = cmd->arg;
794 if (objtype) {
795 sink = find_sink(objtype, error);
796 if (!sink)
797 goto error;
799 if (!disconnect_sink(cmd, sink, plugin_data, error))
800 goto error;
801 } else {
802 num = osync_plugin_info_num_objtypes(plugin_info);
803 for (i=0; i < num; i++) {
804 sink = osync_plugin_info_nth_objtype(plugin_info, i);
806 if (!disconnect_sink(cmd, sink, plugin_data, error))
807 goto error;
810 /* last but not least - the main sink */
811 if (get_main_sink())
812 if (!disconnect_sink(cmd, get_main_sink(), plugin_data, error))
813 goto error;
816 return TRUE;
817 error:
818 return FALSE;
821 static void _osyncplugin_ctx_callback_commit_change(void *user_data, OSyncError *error)
823 OSyncError *locerror = NULL;
824 Command *cmd = NULL;
825 OSyncObjTypeSink *sink = NULL;
827 assert(user_data);
829 cmd = (Command *) user_data;
830 sink = cmd->sink;
832 if (error) {
833 osync_error_set_from_error(&locerror, &error);
834 goto error;
837 g_mutex_lock(cmd->mutex);
838 g_cond_signal(cmd->cond);
839 cmd->done = TRUE;
840 g_mutex_unlock(cmd->mutex);
842 return;
843 error:
844 fprintf(stderr, "ERROR for sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&locerror));
845 return;
849 static osync_bool commit_sink(Command *cmd, OSyncObjTypeSink *sink, OSyncChange *change, void *plugin_data, OSyncError **error) {
850 OSyncContext *context = NULL;
851 assert(sink);
852 assert(change);
854 context = osync_context_new(error);
855 if (!context)
856 goto error;
858 cmd->sink = sink;
860 osync_context_set_callback(context, _osyncplugin_ctx_callback_commit_change, cmd);
862 osync_plugin_info_set_sink(plugin_info, sink);
864 printf("COMMIT:\t%s\t%s\t%s\n",
865 _osyncplugin_changetype_str(change),
866 osync_data_get_objtype(osync_change_get_data(change)),
867 osync_change_get_uid(change));
869 osync_objtype_sink_commit_change(sink, plugin_data, plugin_info, change, context);
871 osync_context_unref(context);
873 return TRUE;
875 error:
876 return FALSE;
879 static osync_bool commit(Command *cmd, OSyncChange *change, void *plugin_data, OSyncError **error)
881 int i, num;
882 OSyncObjTypeSink *sink = NULL;
883 const char *objtype = cmd->arg;
885 assert(change);
887 if (objtype) {
888 sink = find_sink(objtype, error);
889 if (!sink)
890 goto error;
892 if (!commit_sink(cmd, sink, change, plugin_data, error))
893 goto error;
894 } else {
895 num = osync_plugin_info_num_objtypes(plugin_info);
896 for (i=0; i < num; i++) {
897 sink = osync_plugin_info_nth_objtype(plugin_info, i);
899 if (!commit_sink(cmd, sink, change, plugin_data, error))
900 goto error;
903 /* last but not least - the main sink */
904 if (get_main_sink())
905 if (!commit_sink(cmd, get_main_sink(), change, plugin_data, error))
906 goto error;
909 return TRUE;
910 error:
911 return FALSE;
914 static osync_bool empty(Command *cmd, void *plugin_data, OSyncError **error)
916 int i;
917 GList *c;
918 //const char *objtype = cmd->arg;
920 /* Perform slowync - if objtype is set for this objtype, otherwise slowsync for ALL */
921 if (!get_changes(cmd, SYNCTYPE_FORCE_SLOWSYNC, plugin_data, error))
922 goto error;
925 for (i=0, c = changesList; c; c = c->next, i++) {
926 OSyncChange *change = c->data;
927 osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED);
929 if (!commit(cmd, change, plugin_data, error))
930 goto error;
934 return TRUE;
936 error:
937 return FALSE;
940 static void _osyncplugin_ctx_callback_syncdone(void *user_data, OSyncError *error)
942 OSyncError *locerror = NULL;
943 Command *cmd = (Command *) user_data;
944 OSyncObjTypeSink *sink = NULL;
946 assert(user_data);
948 sink = cmd->sink;
950 if (error) {
951 osync_error_set_from_error(&locerror, &error);
952 goto error;
955 g_mutex_lock(cmd->mutex);
956 g_cond_signal(cmd->cond);
957 cmd->done = TRUE;
958 g_mutex_unlock(cmd->mutex);
960 return;
961 error:
962 fprintf(stderr, "ERROR for sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&locerror));
963 return;
966 static osync_bool syncdone_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
967 OSyncContext *context = NULL;
968 assert(sink);
969 assert(cmd);
971 context = osync_context_new(error);
972 if (!context)
973 goto error;
975 cmd->sink = sink;
977 osync_context_set_callback(context, _osyncplugin_ctx_callback_syncdone, cmd);
979 osync_plugin_info_set_sink(plugin_info, sink);
981 osync_objtype_sink_sync_done(sink, plugin_data, plugin_info, context);
983 osync_context_unref(context);
985 return TRUE;
987 error:
988 return FALSE;
991 static osync_bool syncdone(Command *cmd, void *plugin_data, OSyncError **error)
994 int i, num;
995 OSyncObjTypeSink *sink = NULL;
996 const char *objtype = cmd->arg;
998 if (objtype) {
999 sink = find_sink(objtype, error);
1000 if (!sink)
1001 goto error;
1003 if (!syncdone_sink(cmd, sink, plugin_data, error))
1004 goto error;
1005 } else {
1006 num = osync_plugin_info_num_objtypes(plugin_info);
1007 for (i=0; i < num; i++) {
1008 sink = osync_plugin_info_nth_objtype(plugin_info, i);
1010 if (!syncdone_sink(cmd, sink, plugin_data, error))
1011 goto error;
1014 /* last but not least - the main sink */
1015 if (get_main_sink())
1016 if (!syncdone_sink(cmd, get_main_sink(), plugin_data, error))
1017 goto error;
1020 return TRUE;
1021 error:
1022 return FALSE;
1025 static void _osyncplugin_ctx_callback_committedall(void *user_data, OSyncError *error)
1027 OSyncError *locerror = NULL;
1028 Command *cmd = (Command *) user_data;
1030 assert(user_data);
1032 //OSyncObjTypeSink *sink = cmd->sink;
1034 if (error) {
1035 osync_error_set_from_error(&locerror, &error);
1036 goto error;
1039 g_mutex_lock(cmd->mutex);
1040 g_cond_signal(cmd->cond);
1041 cmd->done = TRUE;
1042 g_mutex_unlock(cmd->mutex);
1044 return;
1045 error:
1046 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
1047 return;
1050 static osync_bool committedall_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
1051 OSyncContext *context = NULL;
1052 assert(sink);
1053 assert(cmd);
1055 context = osync_context_new(error);
1056 if (!context)
1057 goto error;
1059 cmd->sink = sink;
1061 osync_context_set_callback(context, _osyncplugin_ctx_callback_committedall, cmd);
1063 osync_plugin_info_set_sink(plugin_info, sink);
1065 osync_objtype_sink_committed_all(sink, plugin_data, plugin_info, context);
1067 osync_context_unref(context);
1069 return TRUE;
1071 error:
1072 return FALSE;
1075 static osync_bool committedall(Command *cmd, void *plugin_data, OSyncError **error)
1077 int i, num;
1078 OSyncObjTypeSink *sink = NULL;
1079 const char *objtype = cmd->arg;
1081 if (objtype) {
1082 sink = find_sink(objtype, error);
1083 if (!sink)
1084 goto error;
1086 if (!committedall_sink(cmd, sink, plugin_data, error))
1087 goto error;
1088 } else {
1089 num = osync_plugin_info_num_objtypes(plugin_info);
1090 for (i=0; i < num; i++) {
1091 sink = osync_plugin_info_nth_objtype(plugin_info, i);
1093 if (!committedall_sink(cmd, sink, plugin_data, error))
1094 goto error;
1097 /* last but not least - the main sink */
1098 if (get_main_sink())
1099 if (!committedall_sink(cmd, get_main_sink(), plugin_data, error))
1100 goto error;
1103 return TRUE;
1104 error:
1105 return FALSE;
1109 * Sync Flow
1111 static osync_bool run_command(Command *cmd, void **plugin_data, OSyncError **error) {
1113 assert(cmd);
1115 if (cmd->cmd != CMD_INITIALIZE && *plugin_data == NULL) {
1116 fprintf(stderr, "WARNING: Got Plugin initialized? plugin_data is NULL.\n");
1117 goto error;
1121 switch (cmd->cmd) {
1122 case CMD_EMPTY:
1123 if (!empty(cmd, *plugin_data, error))
1124 goto error;
1125 break;
1126 case CMD_INITIALIZE:
1127 if (!(*plugin_data = plugin_initialize(error)))
1128 goto error;
1129 break;
1130 case CMD_FINALIZE:
1131 finalize_plugin(plugin_data);
1132 break;
1133 case CMD_CONNECT:
1134 if (!connect_plugin(cmd, *plugin_data, error))
1135 goto error;
1136 break;
1137 case CMD_DISCONNECT:
1138 if (!disconnect(cmd, *plugin_data, error))
1139 goto error;
1140 break;
1141 case CMD_SLOWSYNC:
1142 if (!get_changes(cmd, SYNCTYPE_FORCE_SLOWSYNC, *plugin_data, error))
1143 goto error;
1144 break;
1145 case CMD_FASTSYNC:
1146 if (!get_changes(cmd, SYNCTYPE_FORCE_FASTSYNC, *plugin_data, error))
1147 goto error;
1148 break;
1149 case CMD_SYNC:
1150 if (!get_changes(cmd, SYNCTYPE_NORMAL, *plugin_data, error))
1151 goto error;
1152 break;
1153 case CMD_COMMIT:
1154 fprintf(stderr, "COMMIT not yet implemented\n");
1155 break;
1156 case CMD_BATCHCOMMIT:
1157 fprintf(stderr, "BATCHCOMMIT not yet implemented\n");
1158 break;
1159 case CMD_COMMITTEDALL:
1160 if (!committedall(cmd, *plugin_data, error))
1161 goto error;
1162 break;
1163 case CMD_READ:
1164 fprintf(stderr, "READ not yet implemented\n");
1165 break;
1166 case CMD_WRITE:
1167 fprintf(stderr, "WRITE not yet implemented\n");
1168 break;
1169 case CMD_SYNCDONE:
1170 if (!syncdone(cmd, *plugin_data, error))
1171 goto error;
1172 break;
1173 case CMD_DISCOVER:
1174 fprintf(stderr, "DISCOVER not yet implemented\n");
1175 break;
1179 printf("%s: %u - sink: %p\n", __func__, cmd->cmd, cmd->sink);
1180 switch (cmd->cmd) {
1181 case CMD_INITIALIZE:
1182 case CMD_FINALIZE:
1183 case CMD_DISCOVER:
1184 break;
1186 case CMD_EMPTY:
1187 case CMD_CONNECT:
1188 case CMD_DISCONNECT:
1189 case CMD_SLOWSYNC:
1190 case CMD_FASTSYNC:
1191 case CMD_SYNC:
1192 case CMD_COMMIT:
1193 case CMD_BATCHCOMMIT:
1194 case CMD_COMMITTEDALL:
1195 case CMD_READ:
1196 case CMD_WRITE:
1197 case CMD_SYNCDONE:
1198 printf("waiting .....\n");
1199 if (!cmd->done)
1200 g_cond_wait(cmd->cond, cmd->mutex);
1201 printf("DONE\n");
1202 break;
1205 return TRUE;
1207 error:
1208 return FALSE;
1211 static osync_bool plugin_list(OSyncError **error) {
1212 int num;
1213 int i;
1215 assert(!plugin_env);
1217 if (!(plugin_env = osync_plugin_env_new(error)))
1218 goto error;
1220 if (!(format_env = osync_format_env_new(error)))
1221 goto error_free_pluginenv;
1223 if (!osync_format_env_load_plugins(format_env, formatpath, error))
1224 goto error_free_formatenv;
1226 if (!osync_plugin_env_load(plugin_env, pluginpath, error))
1227 goto error_free_formatenv;
1229 num= osync_plugin_env_num_plugins(plugin_env);
1230 for(i= 0; i < num; i++) {
1231 OSyncPlugin* plugin= osync_plugin_env_nth_plugin(plugin_env, i);
1232 fprintf (stdout, "Name: %s\n", osync_plugin_get_name(plugin));
1233 fprintf (stdout, "Description: %s\n", osync_plugin_get_description(plugin));
1235 return TRUE;
1237 error_free_formatenv:
1238 osync_format_env_unref(format_env);
1239 format_env = NULL;
1240 error_free_pluginenv:
1241 osync_plugin_env_unref(plugin_env);
1242 plugin_env = NULL;
1243 error:
1244 return FALSE;
1247 int main(int argc, char **argv) {
1249 GList *o;
1250 void *plugin_data = NULL;
1251 OSyncError *error = NULL;
1253 if (!g_thread_supported())
1254 g_thread_init(NULL);
1256 parse_args(argc, argv);
1257 /* Set defaults if not set on the command line */
1258 if (!syncgroup)
1259 syncgroup = strdup("osyncplugin");
1261 if (pluginlist) {
1262 if (!plugin_list(&error))
1263 goto error;
1265 goto success;
1268 if (!init(&error))
1269 goto error;
1271 for (o=cmdlist; o; o = o->next)
1272 if (!run_command((Command *) o->data, &plugin_data, &error))
1273 goto error_disconnect_and_finalize;
1276 success:
1277 if (plugin_env)
1278 osync_plugin_env_unref(plugin_env);
1280 for (o=cmdlist; o; o = o->next) {
1281 Command *cmd = o->data;
1282 free_command(&cmd);
1286 return EXIT_SUCCESS;
1288 error_disconnect_and_finalize:
1289 if (plugin_data)
1290 disconnect(NULL, plugin_data, NULL);
1291 //error_finalize:
1292 finalize_plugin(&plugin_data);
1293 //error_free_plugin_env:
1294 if (plugin_env)
1295 osync_plugin_env_unref(plugin_env);
1297 for (o=cmdlist; o; o = o->next) {
1298 Command *cmd = o->data;
1299 free_command(&cmd);
1302 error:
1303 fprintf(stderr, "Error: %s\n", osync_error_print(&error));
1304 osync_error_unref(&error);
1305 return EXIT_FAILURE;