windows port - replaced sleep with g_usleep
[opensync.git] / tools / osyncplugin.c
blob8c6a81a91ae8a80a80ef55de632312e01701170c
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_plugin_env_load(plugin_env, pluginpath, error))
352 goto error_free_pluginenv;
354 if (!(plugin = osync_plugin_env_find_plugin(plugin_env, pluginname))) {
355 osync_error_set(error, OSYNC_ERROR_PLUGIN_NOT_FOUND, "Plugin not found: \"%s\"", pluginname);
356 goto error_free_pluginenv;
359 if (!(plugin_info = osync_plugin_info_new(error)))
360 goto error_free_pluginenv;
362 config = osync_plugin_config_new(error);
363 if (!config)
364 goto error_free_plugininfo;
366 if (osync_plugin_get_config_type(plugin) != OSYNC_PLUGIN_NO_CONFIGURATION && configfile) {
367 OSyncList *r = NULL;
368 if (!osync_plugin_config_file_load(config, configfile, NULL, error))
369 goto error_free_pluginconfig;
371 osync_plugin_info_set_config(plugin_info, config);
373 /** Redudant(aka. stolen) code from opensync/client/opensync_client.c */
374 /* Enable active sinks */
376 if (config)
377 r = osync_plugin_config_get_resources(config);
379 for (; r; r = r->next) {
380 OSyncPluginResource *res = r->data;
381 OSyncObjTypeSink *sink;
383 const char *objtype = osync_plugin_resource_get_objtype(res);
384 OSyncList *o = NULL;
385 /* Check for ObjType sink */
386 if (!(sink = osync_plugin_info_find_objtype(plugin_info, objtype))) {
387 sink = osync_objtype_sink_new(objtype, error);
388 if (!sink)
389 goto error_free_pluginconfig;
391 osync_plugin_info_add_objtype(plugin_info, sink);
394 o = osync_plugin_resource_get_objformat_sinks(res);
395 for (; o; o = o->next) {
396 OSyncObjFormatSink *format_sink = (OSyncObjFormatSink *) o->data;
397 osync_objtype_sink_add_objformat_sink(sink, format_sink);
401 osync_plugin_config_unref(config);
405 if (!configfile && osync_plugin_get_config_type(plugin) == OSYNC_PLUGIN_NEEDS_CONFIGURATION) {
406 osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "Plugin \"%s\" requires configuration!", pluginname);
407 goto error_free_pluginconfig;
410 assert(!ctx);
411 ctx = g_main_context_new();
413 osync_plugin_info_set_configdir(plugin_info, configdir);
414 osync_plugin_info_set_loop(plugin_info, ctx);
415 osync_plugin_info_set_format_env(plugin_info, format_env);
416 osync_plugin_info_set_groupname(plugin_info, syncgroup);
418 return TRUE;
421 error_free_loop:
422 g_main_context_unref(ctx);
424 error_free_pluginconfig:
425 osync_plugin_config_unref(config);
426 error_free_plugininfo:
427 osync_plugin_info_unref(plugin_info);
428 error_free_formatenv:
429 osync_format_env_unref(format_env);
430 format_env = NULL;
431 error_free_pluginenv:
432 osync_plugin_env_unref(plugin_env);
433 plugin_env = NULL;
434 error:
435 return FALSE;
438 static void *plugin_initialize(OSyncError **error)
440 void *plugin_data = osync_plugin_initialize(plugin, plugin_info, error);
442 if (!plugin_data)
443 return NULL;
445 return plugin_data;
448 static void finalize_plugin(void **plugin_data)
451 if (!*plugin_data)
452 return;
454 osync_plugin_finalize(plugin, *plugin_data);
455 *plugin_data = NULL;
459 static OSyncObjTypeSink *find_sink(const char *objtype, OSyncError **error)
461 OSyncObjTypeSink *sink = NULL;
462 assert(objtype);
464 sink = osync_plugin_info_find_objtype(plugin_info, objtype);
465 if (!sink) {
466 osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find sink for %s", objtype);
467 return NULL;
470 return sink;
473 static OSyncObjTypeSink *get_main_sink()
475 return osync_plugin_info_get_main_sink(plugin_info);
478 static const char *_osyncplugin_changetype_str(OSyncChange *change)
480 const char *type;
481 assert(change);
483 switch (osync_change_get_changetype(change)) {
484 case OSYNC_CHANGE_TYPE_ADDED:
485 type = "ADDED";
486 break;
487 case OSYNC_CHANGE_TYPE_UNMODIFIED:
488 type = "UNMODIFIED";
489 break;
490 case OSYNC_CHANGE_TYPE_DELETED:
491 type = "DELETED";
492 break;
493 case OSYNC_CHANGE_TYPE_MODIFIED:
494 type = "MODIFIED";
495 break;
496 case OSYNC_CHANGE_TYPE_UNKNOWN:
497 default:
498 type = "UNKNOWN";
499 break;
502 return type;
505 //typedef void (* OSyncContextChangeFn) (OSyncChange *, void *);
506 static void _osyncplugin_ctx_change_callback(OSyncChange *change, void *user_data)
508 Command *cmd = (Command *) user_data;
509 OSyncObjTypeSink *sink = cmd->sink;
511 printf("GETCHANGES:\t%s\t%s\t%s",
512 _osyncplugin_changetype_str(change),
513 osync_objtype_sink_get_name(sink),
514 osync_change_get_uid(change));
516 if (osync_change_get_objformat(change))
517 printf("\t%s", osync_objformat_get_name(osync_change_get_objformat(change)));
519 printf("\n");
521 osync_change_ref(change);
522 changesList = g_list_append(changesList, change);
525 //typedef void (* OSyncContextCallbackFn)(void *, OSyncError *);
526 static void _osyncplugin_ctx_callback_getchanges(void *user_data, OSyncError *error)
528 Command *cmd = (Command *) user_data;
529 OSyncObjTypeSink *sink = cmd->sink;
531 if (error)
532 fprintf(stderr, "Sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&error));
534 g_mutex_lock(cmd->mutex);
535 g_cond_signal(cmd->cond);
536 cmd->done = TRUE;
537 g_mutex_unlock(cmd->mutex);
541 static osync_bool get_changes_sink(Command *cmd, OSyncObjTypeSink *sink, SyncType type, void *plugin_data, OSyncError **error)
543 OSyncContext *context = NULL;
544 assert(sink);
546 switch (type) {
547 case SYNCTYPE_NORMAL:
548 break;
549 case SYNCTYPE_FORCE_FASTSYNC:
550 osync_objtype_sink_set_slowsync(sink, FALSE);
551 break;
552 case SYNCTYPE_FORCE_SLOWSYNC:
553 osync_objtype_sink_set_slowsync(sink, TRUE);
554 break;
557 context = osync_context_new(error);
558 if (!context)
559 goto error;
561 osync_context_set_changes_callback(context, _osyncplugin_ctx_change_callback);
562 osync_context_set_callback(context, _osyncplugin_ctx_callback_getchanges, cmd);
564 osync_plugin_info_set_sink(plugin_info, sink);
566 osync_objtype_sink_get_changes(sink, plugin_data, plugin_info, context);
568 osync_context_unref(context);
571 return TRUE;
573 error:
574 return FALSE;
577 static osync_bool get_changes(Command *cmd, SyncType type, void *plugin_data, OSyncError **error)
579 int num, i;
580 OSyncObjTypeSink *sink = NULL;
581 const char *objtype = cmd->arg;
583 if (objtype) {
584 sink = find_sink(objtype, error);
585 if (!sink)
586 goto error;
588 cmd->sink = sink;
589 if (!get_changes_sink(cmd, sink, type, plugin_data, error))
590 goto error;
592 } else {
593 /* all available objtypes */
594 num = osync_plugin_info_num_objtypes(plugin_info);
595 for (i=0; i < num; i++) {
596 sink = osync_plugin_info_nth_objtype(plugin_info, i);
598 cmd->sink = sink;
599 if (!get_changes_sink(cmd, sink, type, plugin_data, error))
600 goto error;
603 /* last but not least - the main sink */
604 if (get_main_sink())
606 if (!get_changes_sink(cmd, get_main_sink(), type, plugin_data, error))
607 goto error;
610 return TRUE;
612 error:
613 return FALSE;
616 static void _osyncplugin_ctx_callback_connect(void *user_data, OSyncError *error)
618 OSyncError *locerror = NULL;
619 Command *cmd = NULL;
620 OSyncObjTypeSink *sink = NULL;
622 assert(user_data);
624 cmd = (Command *) user_data;
625 sink = cmd->sink;
627 if (error) {
628 osync_error_set_from_error(&locerror, &error);
629 goto error;
632 if (osync_objtype_sink_get_slowsync(sink)) {
633 printf("SlowSync got requested by CONNECT function");
634 if (osync_objtype_sink_get_name(sink))
635 printf(" for ObjType: \"%s\"", osync_objtype_sink_get_name(sink));
637 printf(".\n");
640 g_mutex_lock(cmd->mutex);
641 g_cond_signal(cmd->cond);
642 cmd->done = TRUE;
643 g_mutex_unlock(cmd->mutex);
645 return;
646 error:
647 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
648 return;
651 static osync_bool connect_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
652 OSyncContext *context = NULL;
653 assert(sink);
654 assert(cmd);
656 context = osync_context_new(error);
657 if (!context)
658 goto error;
660 cmd->sink = sink;
662 osync_context_set_callback(context, _osyncplugin_ctx_callback_connect, cmd);
664 osync_plugin_info_set_sink(plugin_info, sink);
666 osync_objtype_sink_connect(sink, plugin_data, plugin_info, context);
668 osync_context_unref(context);
670 return TRUE;
672 error:
673 return FALSE;
676 static osync_bool connect_plugin(Command *cmd, void *plugin_data, OSyncError **error)
678 unsigned int i, num;
679 OSyncObjTypeSink *sink = NULL;
680 const char *objtype = cmd->arg;
682 if (objtype) {
683 sink = find_sink(objtype, error);
684 if (!sink)
685 goto error;
687 if (!connect_sink(cmd, sink, plugin_data, error))
688 goto error;
689 } else {
690 num = osync_plugin_info_num_objtypes(plugin_info);
691 for (i=0; i < num; i++) {
692 sink = osync_plugin_info_nth_objtype(plugin_info, i);
694 if (!connect_sink(cmd, sink, plugin_data, error))
695 goto error;
698 /* last but not least - the main sink */
699 if (get_main_sink())
700 if (!connect_sink(cmd, get_main_sink(), plugin_data, error))
701 goto error;
704 return TRUE;
705 error:
706 return FALSE;
709 static void _osyncplugin_ctx_callback_disconnect(void *user_data, OSyncError *error)
711 OSyncError *locerror = NULL;
712 Command *cmd = NULL;
713 OSyncObjTypeSink *sink = NULL;
715 assert(user_data);
717 cmd = (Command *) user_data;
718 sink = cmd->sink;
720 if (error) {
721 osync_error_set_from_error(&locerror, &error);
722 goto error;
725 if (osync_objtype_sink_get_name(sink))
726 printf("Sink \"%s\"", osync_objtype_sink_get_name(sink));
727 else
728 printf("Main Sink");
730 printf(" disconnected.\n");
732 g_mutex_lock(cmd->mutex);
733 g_cond_signal(cmd->cond);
734 cmd->done = TRUE;
735 g_mutex_unlock(cmd->mutex);
737 return;
738 error:
739 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
740 return;
743 static osync_bool disconnect_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
744 OSyncContext *context = osync_context_new(error);
745 assert(sink);
746 assert(cmd);
748 if (!context)
749 goto error;
751 cmd->sink = sink;
753 osync_context_set_callback(context, _osyncplugin_ctx_callback_disconnect, cmd);
755 osync_plugin_info_set_sink(plugin_info, sink);
757 osync_objtype_sink_disconnect(sink, plugin_data, plugin_info, context);
759 osync_context_unref(context);
761 return TRUE;
763 error:
764 return FALSE;
767 static osync_bool disconnect(Command *cmd, void *plugin_data, OSyncError **error)
770 int i, num;
771 OSyncObjTypeSink *sink = NULL;
772 const char *objtype = cmd->arg;
774 if (objtype) {
775 sink = find_sink(objtype, error);
776 if (!sink)
777 goto error;
779 if (!disconnect_sink(cmd, sink, plugin_data, error))
780 goto error;
781 } else {
782 num = osync_plugin_info_num_objtypes(plugin_info);
783 for (i=0; i < num; i++) {
784 sink = osync_plugin_info_nth_objtype(plugin_info, i);
786 if (!disconnect_sink(cmd, sink, plugin_data, error))
787 goto error;
790 /* last but not least - the main sink */
791 if (get_main_sink())
792 if (!disconnect_sink(cmd, get_main_sink(), plugin_data, error))
793 goto error;
796 return TRUE;
797 error:
798 return FALSE;
801 static void _osyncplugin_ctx_callback_commit_change(void *user_data, OSyncError *error)
803 OSyncError *locerror = NULL;
804 Command *cmd = NULL;
805 OSyncObjTypeSink *sink = NULL;
807 assert(user_data);
809 cmd = (Command *) user_data;
810 sink = cmd->sink;
812 if (error) {
813 osync_error_set_from_error(&locerror, &error);
814 goto error;
817 g_mutex_lock(cmd->mutex);
818 g_cond_signal(cmd->cond);
819 cmd->done = TRUE;
820 g_mutex_unlock(cmd->mutex);
822 return;
823 error:
824 fprintf(stderr, "ERROR for sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&locerror));
825 return;
829 static osync_bool commit_sink(Command *cmd, OSyncObjTypeSink *sink, OSyncChange *change, void *plugin_data, OSyncError **error) {
830 OSyncContext *context = NULL;
831 assert(sink);
832 assert(change);
834 context = osync_context_new(error);
835 if (!context)
836 goto error;
838 cmd->sink = sink;
840 osync_context_set_callback(context, _osyncplugin_ctx_callback_commit_change, cmd);
842 osync_plugin_info_set_sink(plugin_info, sink);
844 printf("COMMIT:\t%s\t%s\t%s\n",
845 _osyncplugin_changetype_str(change),
846 osync_data_get_objtype(osync_change_get_data(change)),
847 osync_change_get_uid(change));
849 osync_objtype_sink_commit_change(sink, plugin_data, plugin_info, change, context);
851 osync_context_unref(context);
853 return TRUE;
855 error:
856 return FALSE;
859 static osync_bool commit(Command *cmd, OSyncChange *change, void *plugin_data, OSyncError **error)
861 int i, num;
862 OSyncObjTypeSink *sink = NULL;
863 const char *objtype = cmd->arg;
865 assert(change);
867 if (objtype) {
868 sink = find_sink(objtype, error);
869 if (!sink)
870 goto error;
872 if (!commit_sink(cmd, sink, change, plugin_data, error))
873 goto error;
874 } else {
875 num = osync_plugin_info_num_objtypes(plugin_info);
876 for (i=0; i < num; i++) {
877 sink = osync_plugin_info_nth_objtype(plugin_info, i);
879 if (!commit_sink(cmd, sink, change, plugin_data, error))
880 goto error;
883 /* last but not least - the main sink */
884 if (get_main_sink())
885 if (!commit_sink(cmd, get_main_sink(), change, plugin_data, error))
886 goto error;
889 return TRUE;
890 error:
891 return FALSE;
894 static osync_bool empty(Command *cmd, void *plugin_data, OSyncError **error)
896 int i;
897 GList *c;
898 //const char *objtype = cmd->arg;
900 /* Perform slowync - if objtype is set for this objtype, otherwise slowsync for ALL */
901 if (!get_changes(cmd, SYNCTYPE_FORCE_SLOWSYNC, plugin_data, error))
902 goto error;
905 for (i=0, c = changesList; c; c = c->next, i++) {
906 OSyncChange *change = c->data;
907 osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED);
909 if (!commit(cmd, change, plugin_data, error))
910 goto error;
914 return TRUE;
916 error:
917 return FALSE;
920 static void _osyncplugin_ctx_callback_syncdone(void *user_data, OSyncError *error)
922 OSyncError *locerror = NULL;
923 Command *cmd = (Command *) user_data;
924 OSyncObjTypeSink *sink = NULL;
926 assert(user_data);
928 sink = cmd->sink;
930 if (error) {
931 osync_error_set_from_error(&locerror, &error);
932 goto error;
935 g_mutex_lock(cmd->mutex);
936 g_cond_signal(cmd->cond);
937 cmd->done = TRUE;
938 g_mutex_unlock(cmd->mutex);
940 return;
941 error:
942 fprintf(stderr, "ERROR for sink \"%s\": %s\n", osync_objtype_sink_get_name(sink), osync_error_print(&locerror));
943 return;
946 static osync_bool syncdone_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
947 OSyncContext *context = NULL;
948 assert(sink);
949 assert(cmd);
951 context = osync_context_new(error);
952 if (!context)
953 goto error;
955 cmd->sink = sink;
957 osync_context_set_callback(context, _osyncplugin_ctx_callback_syncdone, cmd);
959 osync_plugin_info_set_sink(plugin_info, sink);
961 osync_objtype_sink_sync_done(sink, plugin_data, plugin_info, context);
963 osync_context_unref(context);
965 return TRUE;
967 error:
968 return FALSE;
971 static osync_bool syncdone(Command *cmd, void *plugin_data, OSyncError **error)
974 int i, num;
975 OSyncObjTypeSink *sink = NULL;
976 const char *objtype = cmd->arg;
978 if (objtype) {
979 sink = find_sink(objtype, error);
980 if (!sink)
981 goto error;
983 if (!syncdone_sink(cmd, sink, plugin_data, error))
984 goto error;
985 } else {
986 num = osync_plugin_info_num_objtypes(plugin_info);
987 for (i=0; i < num; i++) {
988 sink = osync_plugin_info_nth_objtype(plugin_info, i);
990 if (!syncdone_sink(cmd, sink, plugin_data, error))
991 goto error;
994 /* last but not least - the main sink */
995 if (get_main_sink())
996 if (!syncdone_sink(cmd, get_main_sink(), plugin_data, error))
997 goto error;
1000 return TRUE;
1001 error:
1002 return FALSE;
1005 static void _osyncplugin_ctx_callback_committedall(void *user_data, OSyncError *error)
1007 OSyncError *locerror = NULL;
1008 Command *cmd = (Command *) user_data;
1010 assert(user_data);
1012 //OSyncObjTypeSink *sink = cmd->sink;
1014 if (error) {
1015 osync_error_set_from_error(&locerror, &error);
1016 goto error;
1019 g_mutex_lock(cmd->mutex);
1020 g_cond_signal(cmd->cond);
1021 cmd->done = TRUE;
1022 g_mutex_unlock(cmd->mutex);
1024 return;
1025 error:
1026 fprintf(stderr, "ERROR: %s\n", osync_error_print(&locerror));
1027 return;
1030 static osync_bool committedall_sink(Command *cmd, OSyncObjTypeSink *sink, void *plugin_data, OSyncError **error) {
1031 OSyncContext *context = NULL;
1032 assert(sink);
1033 assert(cmd);
1035 context = osync_context_new(error);
1036 if (!context)
1037 goto error;
1039 cmd->sink = sink;
1041 osync_context_set_callback(context, _osyncplugin_ctx_callback_committedall, cmd);
1043 osync_plugin_info_set_sink(plugin_info, sink);
1045 osync_objtype_sink_committed_all(sink, plugin_data, plugin_info, context);
1047 osync_context_unref(context);
1049 return TRUE;
1051 error:
1052 return FALSE;
1055 static osync_bool committedall(Command *cmd, void *plugin_data, OSyncError **error)
1057 int i, num;
1058 OSyncObjTypeSink *sink = NULL;
1059 const char *objtype = cmd->arg;
1061 if (objtype) {
1062 sink = find_sink(objtype, error);
1063 if (!sink)
1064 goto error;
1066 if (!committedall_sink(cmd, sink, plugin_data, error))
1067 goto error;
1068 } else {
1069 num = osync_plugin_info_num_objtypes(plugin_info);
1070 for (i=0; i < num; i++) {
1071 sink = osync_plugin_info_nth_objtype(plugin_info, i);
1073 if (!committedall_sink(cmd, sink, plugin_data, error))
1074 goto error;
1077 /* last but not least - the main sink */
1078 if (get_main_sink())
1079 if (!committedall_sink(cmd, get_main_sink(), plugin_data, error))
1080 goto error;
1083 return TRUE;
1084 error:
1085 return FALSE;
1089 * Sync Flow
1091 static osync_bool run_command(Command *cmd, void **plugin_data, OSyncError **error) {
1093 assert(cmd);
1095 if (cmd->cmd != CMD_INITIALIZE && *plugin_data == NULL) {
1096 fprintf(stderr, "WARNING: Got Plugin initialized? plugin_data is NULL.\n");
1097 goto error;
1101 switch (cmd->cmd) {
1102 case CMD_EMPTY:
1103 if (!empty(cmd, *plugin_data, error))
1104 goto error;
1105 break;
1106 case CMD_INITIALIZE:
1107 if (!(*plugin_data = plugin_initialize(error)))
1108 goto error;
1109 break;
1110 case CMD_FINALIZE:
1111 finalize_plugin(plugin_data);
1112 break;
1113 case CMD_CONNECT:
1114 if (!connect_plugin(cmd, *plugin_data, error))
1115 goto error;
1116 break;
1117 case CMD_DISCONNECT:
1118 if (!disconnect(cmd, *plugin_data, error))
1119 goto error;
1120 break;
1121 case CMD_SLOWSYNC:
1122 if (!get_changes(cmd, SYNCTYPE_FORCE_SLOWSYNC, *plugin_data, error))
1123 goto error;
1124 break;
1125 case CMD_FASTSYNC:
1126 if (!get_changes(cmd, SYNCTYPE_FORCE_FASTSYNC, *plugin_data, error))
1127 goto error;
1128 break;
1129 case CMD_SYNC:
1130 if (!get_changes(cmd, SYNCTYPE_NORMAL, *plugin_data, error))
1131 goto error;
1132 break;
1133 case CMD_COMMIT:
1134 fprintf(stderr, "COMMIT not yet implemented\n");
1135 break;
1136 case CMD_BATCHCOMMIT:
1137 fprintf(stderr, "BATCHCOMMIT not yet implemented\n");
1138 break;
1139 case CMD_COMMITTEDALL:
1140 if (!committedall(cmd, *plugin_data, error))
1141 goto error;
1142 break;
1143 case CMD_READ:
1144 fprintf(stderr, "READ not yet implemented\n");
1145 break;
1146 case CMD_WRITE:
1147 fprintf(stderr, "WRITE not yet implemented\n");
1148 break;
1149 case CMD_SYNCDONE:
1150 if (!syncdone(cmd, *plugin_data, error))
1151 goto error;
1152 break;
1153 case CMD_DISCOVER:
1154 fprintf(stderr, "DISCOVER not yet implemented\n");
1155 break;
1159 printf("%s: %u - sink: %p\n", __func__, cmd->cmd, cmd->sink);
1160 switch (cmd->cmd) {
1161 case CMD_INITIALIZE:
1162 case CMD_FINALIZE:
1163 case CMD_DISCOVER:
1164 break;
1166 case CMD_EMPTY:
1167 case CMD_CONNECT:
1168 case CMD_DISCONNECT:
1169 case CMD_SLOWSYNC:
1170 case CMD_FASTSYNC:
1171 case CMD_SYNC:
1172 case CMD_COMMIT:
1173 case CMD_BATCHCOMMIT:
1174 case CMD_COMMITTEDALL:
1175 case CMD_READ:
1176 case CMD_WRITE:
1177 case CMD_SYNCDONE:
1178 printf("waiting .....\n");
1179 if (!cmd->done)
1180 g_cond_wait(cmd->cond, cmd->mutex);
1181 printf("DONE\n");
1182 break;
1185 return TRUE;
1187 error:
1188 return FALSE;
1191 static osync_bool plugin_list(OSyncError **error) {
1192 int num;
1193 int i;
1195 assert(!plugin_env);
1197 if (!(plugin_env = osync_plugin_env_new(error)))
1198 goto error;
1200 if (!(format_env = osync_format_env_new(error)))
1201 goto error_free_pluginenv;
1203 if (!osync_format_env_load_plugins(format_env, formatpath, error))
1204 goto error_free_formatenv;
1206 if (!osync_plugin_env_load(plugin_env, pluginpath, error))
1207 goto error_free_formatenv;
1209 num= osync_plugin_env_num_plugins(plugin_env);
1210 for(i= 0; i < num; i++) {
1211 OSyncPlugin* plugin= osync_plugin_env_nth_plugin(plugin_env, i);
1212 fprintf (stdout, "Name: %s\n", osync_plugin_get_name(plugin));
1213 fprintf (stdout, "Description: %s\n", osync_plugin_get_description(plugin));
1215 return TRUE;
1217 error_free_formatenv:
1218 osync_format_env_unref(format_env);
1219 format_env = NULL;
1220 error_free_pluginenv:
1221 osync_plugin_env_unref(plugin_env);
1222 plugin_env = NULL;
1223 error:
1224 return FALSE;
1227 int main(int argc, char **argv) {
1229 GList *o;
1230 void *plugin_data = NULL;
1231 OSyncError *error = NULL;
1233 if (!g_thread_supported())
1234 g_thread_init(NULL);
1236 parse_args(argc, argv);
1237 /* Set defaults if not set on the command line */
1238 if (!syncgroup)
1239 syncgroup = strdup("osyncplugin");
1241 if (pluginlist) {
1242 if (!plugin_list(&error))
1243 goto error;
1245 goto success;
1248 if (!init(&error))
1249 goto error;
1251 for (o=cmdlist; o; o = o->next)
1252 if (!run_command((Command *) o->data, &plugin_data, &error))
1253 goto error_disconnect_and_finalize;
1256 success:
1257 if (plugin_env)
1258 osync_plugin_env_unref(plugin_env);
1260 for (o=cmdlist; o; o = o->next) {
1261 Command *cmd = o->data;
1262 free_command(&cmd);
1266 return EXIT_SUCCESS;
1268 error_disconnect_and_finalize:
1269 if (plugin_data)
1270 disconnect(NULL, plugin_data, NULL);
1271 //error_finalize:
1272 finalize_plugin(&plugin_data);
1273 //error_free_plugin_env:
1274 if (plugin_env)
1275 osync_plugin_env_unref(plugin_env);
1277 for (o=cmdlist; o; o = o->next) {
1278 Command *cmd = o->data;
1279 free_command(&cmd);
1282 error:
1283 fprintf(stderr, "Error: %s\n", osync_error_print(&error));
1284 osync_error_unref(&error);
1285 return EXIT_FAILURE;