OpenSync  0.22
opensync_env.c
1 /*
2  * libopensync - A synchronization framework
3  * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
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.
14  *
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
18  *
19  */
20 
21 #include "opensync.h"
22 #include "opensync_internals.h"
23 
46 
47 /* Get the value of a an OSyncEnv option
48  *
49  * Search order:
50  * - options set using osync_env_set_option()
51  * - OSYNC_* environment variables
52  */
53 static const char *osync_env_query_option(OSyncEnv *env, const char *name)
54 {
55  const char *value;
56  value = g_hash_table_lookup(env->options, name);
57  if (value)
58  return value;
59 
60  gchar *env_name = g_strdup_printf("OSYNC_%s", name);
61  value = getenv(env_name);
62  g_free(env_name);
63 
64  if (value)
65  return value;
66 
67  return NULL;
68 }
69 
70 static osync_bool osync_env_query_option_bool(OSyncEnv *env, const char *name)
71 {
72  const char *get_value;
73  if (!(get_value = osync_env_query_option(env, name)))
74  return FALSE;
75  if (!strcmp(get_value, "TRUE"))
76  return TRUE;
77  return FALSE;
78 }
79 
84 {
85  int num_modules = g_list_length(env->modules);
86 
87  /* build an array for g_strjoinv() */
88  gchar **path_array = g_malloc0(sizeof(gchar*)*(num_modules + 1));
89  int i;
90  for (i = 0; i < num_modules; i++) {
91  GModule *module = g_list_nth_data(env->modules, i);
92  const gchar *path = g_module_name(module);
93  /*XXX: casting to non-const, here. Ugly.
94  *
95  * We know the elements pointed by path_array won't
96  * be touched. But isn't g_strjoinv() supposed to get a
97  * 'const gchar **' instead of a 'gchar **'?
98  */
99  path_array[i] = (gchar*)path;
100  }
101 
102  /* Build a ':'-separated list */
103  gchar *list_str = g_strjoinv(":", path_array);
104  setenv("OSYNC_FORMAT_LIST", list_str, 1);
105  g_free(list_str);
106 }
107 
108 static void export_option_to_env(gpointer key, gpointer data, gpointer user_data)
109 {
110  const char *name = (const char*)key;
111  const char *value = (const char*)data;
112  gchar *env_name = g_strdup_printf("OSYNC_%s", name);
113  setenv(env_name, value, 1);
114  g_free(env_name);
115 }
116 
120 void osync_env_export_all_options(OSyncEnv *env)
121 {
122  g_hash_table_foreach(env->options, export_option_to_env, NULL);
123 }
124 
125 static void free_hash(char *key, char *value, void *data)
126 {
127  g_free(key);
128  g_free(value);
129 }
130 
139 long long int _osync_env_create_group_id(OSyncEnv *env)
140 {
141  char *filename = NULL;
142  long long int i = 0;
143  do {
144  i++;
145  if (filename)
146  g_free(filename);
147  filename = g_strdup_printf("%s/group%lli", env->groupsdir, i);
148  } while (g_file_test(filename, G_FILE_TEST_EXISTS));
149  g_free(filename);
150  return i;
151 }
152 
177 
178 
186 OSyncEnv *osync_env_new(void)
187 {
188  OSyncEnv *env = g_malloc0(sizeof(OSyncEnv));
189  env->is_initialized = FALSE;
190  env->options = g_hash_table_new(g_str_hash, g_str_equal);
191 
192  //Set some defaults
193  osync_env_set_option(env, "LOAD_GROUPS", "TRUE");
194  osync_env_set_option(env, "LOAD_FORMATS", "TRUE");
195  osync_env_set_option(env, "LOAD_PLUGINS", "TRUE");
196 
197  return env;
198 }
199 
207 void osync_env_free(OSyncEnv *env)
208 {
209  g_assert(env);
210  g_hash_table_foreach(env->options, (GHFunc)free_hash, NULL);
211  g_hash_table_destroy(env->options);
212  g_free(env);
213 }
214 
222 void osync_env_set_option(OSyncEnv *env, const char *name, const char *value)
223 {
224  if (value)
225  g_hash_table_insert(env->options, g_strdup(name), g_strdup(value));
226  else
227  g_hash_table_remove(env->options, name);
228 }
229 
240 osync_bool osync_env_initialize(OSyncEnv *env, OSyncError **error)
241 {
242  osync_trace(TRACE_ENTRY, "osync_env_initialize(%p, %p)", env, error);
243  g_assert(env);
244 
245  if (env->is_initialized) {
246  osync_error_set(error, OSYNC_ERROR_INITIALIZATION, "Cannot initialize the same environment twice");
247  osync_trace(TRACE_EXIT_ERROR, "osync_env_initialize: %s", osync_error_print(error));
248  return FALSE;
249  }
250 
251  //Load the normal plugins
252  if (osync_env_query_option_bool(env, "LOAD_PLUGINS")) {
253  if (!osync_env_load_plugins(env, osync_env_query_option(env, "PLUGINS_DIRECTORY"), error)) {
254  osync_trace(TRACE_EXIT_ERROR, "osync_env_initialize: %s", osync_error_print(error));
255  return FALSE;
256  }
257  }
258 
259  //Load the format plugins
260  if (osync_env_query_option_bool(env, "LOAD_FORMATS")) {
261  if (!osync_env_load_formats(env, osync_env_query_option(env, "FORMATS_DIRECTORY"), error)) {
262  osync_trace(TRACE_EXIT_ERROR, "osync_env_initialize: %s", osync_error_print(error));
263  return FALSE;
264  }
265  }
266 
267  //Load groups
268  if (osync_env_query_option_bool(env, "LOAD_GROUPS")) {
269  if (!osync_env_load_groups(env, osync_env_query_option(env, "GROUPS_DIRECTORY"), error)) {
270  osync_trace(TRACE_EXIT_ERROR, "osync_env_initialize: %s", osync_error_print(error));
271  return FALSE;
272  }
273  }
274 
275  env->is_initialized = TRUE;
276  osync_trace(TRACE_EXIT, "osync_env_initialize");
277  return TRUE;
278 }
279 
289 osync_bool osync_env_finalize(OSyncEnv *env, OSyncError **error)
290 {
291  osync_trace(TRACE_ENTRY, "osync_env_finalize(%p, %p)", env, error);
292  g_assert(env);
293 
294  if (!env->is_initialized) {
295  osync_error_set(error, OSYNC_ERROR_INITIALIZATION, "Environment has to be initialized before");
296  return FALSE;
297  }
298 
299  while (osync_env_nth_group(env, 0))
301 
302  GList *plugins = g_list_copy(env->plugins);
303  GList *p;
304  for (p = plugins; p; p = p->next) {
305  OSyncPlugin *plugin = p->data;
306  osync_plugin_free(plugin);
307  }
308  g_list_free(plugins);
309 
310  //Unload all loaded modules
311  GList *modules = g_list_copy(env->modules);
312  for (p = modules; p; p = p->next) {
313  GModule *module = p->data;
314  osync_module_unload(env, module);
315  }
316  g_list_free(modules);
317 
318  osync_trace(TRACE_EXIT, "osync_env_finalize");
319  return TRUE;
320 }
321 
334 osync_bool osync_env_load_formats(OSyncEnv *env, const char *path, OSyncError **error)
335 {
336  osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, path, error);
337  osync_bool must_exist = TRUE;
338 
339  if (!path) {
340  path = OPENSYNC_FORMATSDIR;
341  must_exist = FALSE;
342  }
343 
344  if (!osync_module_load_dir(env, path, must_exist, error)) {
345  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
346  return FALSE;
347  }
348 
349  osync_trace(TRACE_EXIT, "%s", __func__);
350  return TRUE;
351 }
352 
363 osync_bool osync_env_load_plugins(OSyncEnv *env, const char *path, OSyncError **error)
364 {
365  osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, path, error);
366  osync_bool must_exist = TRUE;
367 
368  if (!path) {
369  path = OPENSYNC_PLUGINDIR;
370  must_exist = FALSE;
371  }
372 
373  if (!osync_module_load_dir(env, path, must_exist, error)) {
374  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
375  return FALSE;
376  }
377 
378  osync_trace(TRACE_EXIT, "%s", __func__);
379  return TRUE;
380 }
381 
391 OSyncPlugin *osync_env_find_plugin(OSyncEnv *env, const char *name)
392 {
393  g_assert(env);
394  OSyncPlugin *plugin;
395  int i;
396  for (i = 0; i < osync_env_num_plugins(env); i++) {
397  plugin = osync_env_nth_plugin(env, i);
398  if (g_ascii_strcasecmp(plugin->info.name, name) == 0) {
399  return plugin;
400  }
401  }
402  return NULL;
403 }
404 
413 int osync_env_num_plugins(OSyncEnv *env)
414 {
415  return g_list_length(env->plugins);
416 }
417 
427 OSyncPlugin *osync_env_nth_plugin(OSyncEnv *env, int nth)
428 {
429  return (OSyncPlugin *)g_list_nth_data(env->plugins, nth);
430 }
431 
440 osync_bool osync_env_plugin_is_usable(OSyncEnv *env, const char *pluginname, OSyncError **error)
441 {
442  osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, pluginname, error);
443 
444  OSyncPlugin *plugin = osync_env_find_plugin(env, pluginname);
445  if (!plugin) {
446  osync_error_set(error, OSYNC_ERROR_PLUGIN_NOT_FOUND, "Unable to find plugin \"%s\". This can be caused by unresolved symbols", pluginname);
447  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
448  return FALSE;
449  }
450 
451  if (plugin->info.functions.is_available) {
452  osync_bool ret = plugin->info.functions.is_available(error);
453  osync_trace(ret ? TRACE_EXIT : TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
454  return ret;
455  }
456 
457  osync_trace(TRACE_EXIT, "%s: TRUE: No is_available function", __func__);
458  return TRUE;
459 }
460 
472 osync_bool osync_env_load_groups(OSyncEnv *env, const char *p, OSyncError **error)
473 {
474  GDir *dir;
475  GError *gerror = NULL;
476  char *filename = NULL;
477  char *real_path = NULL;
478  char *path = g_strdup(p);
479 
480  if (!path) {
481  OSyncUserInfo *user = osync_user_new(error);
482  if (!user)
483  return FALSE;
484  path = g_strdup(osync_user_get_confdir(user));
485 
486  if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
487  if (mkdir(path, 0700) == -1) {
488  osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to create group directory at %s: %s", path, strerror(errno));
489  g_free(path);
490  return FALSE;
491  }
492  char *enginepath = g_strdup_printf("%s/engines", path);
493  if (mkdir(enginepath, 0700) == -1) {
494  osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to create engine group directory at %s: %s", enginepath, strerror(errno));
495  g_free(path);
496  g_free(enginepath);
497  return FALSE;
498  }
499  g_free(enginepath);
500  osync_debug("OSGRP", 3, "Created groups configdir %s\n", path);
501  }
502  osync_user_free(user);
503  }
504 
505  if (!g_path_is_absolute(path)) {
506  real_path = g_strdup_printf("%s/%s", g_get_current_dir(), path);
507  } else {
508  real_path = g_strdup(path);
509  }
510 
511  if (!g_file_test(real_path, G_FILE_TEST_IS_DIR)) {
512  osync_debug("OSGRP", 0, "%s exists, but is no dir", real_path);
513  osync_error_set(error, OSYNC_ERROR_INITIALIZATION, "%s exists, but is no dir", real_path);
514  g_free(real_path);
515  g_free(path);
516  return FALSE;
517  }
518 
519  dir = g_dir_open(real_path, 0, &gerror);
520  if (!dir) {
521  osync_debug("OSGRP", 0, "Unable to open main configdir %s: %s", real_path, gerror->message);
522  osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Unable to open main configdir %s: %s", real_path, gerror->message);
523  g_error_free (gerror);
524  g_free(real_path);
525  g_free(path);
526  return FALSE;
527  }
528 
529  const gchar *de = NULL;
530  while ((de = g_dir_read_name(dir))) {
531  filename = g_strdup_printf ("%s/%s", real_path, de);
532 
533  if (!g_file_test(filename, G_FILE_TEST_IS_DIR) || g_file_test(filename, G_FILE_TEST_IS_SYMLINK) || !g_pattern_match_simple("group*", de)) {
534  g_free(filename);
535  continue;
536  }
537 
538  /* Try to open the confdir*/
539  OSyncError *error = NULL;
540  if (!osync_group_load(env, filename, &error)) {
541  osync_debug("OSGRP", 0, "Unable to load group from %s: %s", filename, error->message);
542  osync_error_free(&error);
543  }
544 
545  g_free(filename);
546  }
547  g_free(real_path);
548  g_dir_close(dir);
549 
550  env->groupsdir = path;
551  return TRUE;
552 }
553 
563 OSyncGroup *osync_env_find_group(OSyncEnv *env, const char *name)
564 {
565  OSyncGroup *group;
566  int i;
567  for (i = 0; i < osync_env_num_groups(env); i++) {
568  group = osync_env_nth_group(env, i);
569  if (g_ascii_strcasecmp(group->name, name) == 0) {
570  return group;
571  }
572  }
573  osync_debug("OSPLG", 0, "Couldnt find the group with the name %s", name);
574  return NULL;
575 }
576 
585 void osync_env_append_group(OSyncEnv *env, OSyncGroup *group)
586 {
587  env->groups = g_list_append(env->groups, group);
588 }
589 
598 void osync_env_remove_group(OSyncEnv *env, OSyncGroup *group)
599 {
600  env->groups = g_list_remove(env->groups, group);
601 }
602 
611 int osync_env_num_groups(OSyncEnv *env)
612 {
613  return g_list_length(env->groups);
614 }
615 
625 OSyncGroup *osync_env_nth_group(OSyncEnv *env, int nth)
626 {
627  return (OSyncGroup *)g_list_nth_data(env->groups, nth);;
628 }
629 
639 
652 osync_bool _osync_open_xml_file(xmlDocPtr *doc, xmlNodePtr *cur, const char *path, const char *topentry, OSyncError **error)
653 {
654  if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
655  osync_debug("OSXML", 1, "File %s does not exist", path);
656  osync_error_set(error, OSYNC_ERROR_IO_ERROR, "File %s does not exist", path);
657  return FALSE;
658  }
659 
660  *doc = xmlParseFile(path);
661 
662  if (!*doc) {
663  osync_debug("OSXML", 1, "Could not open: %s", path);
664  osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Could not open: %s", path);
665  return FALSE;
666  }
667 
668  *cur = xmlDocGetRootElement(*doc);
669 
670  if (!*cur) {
671  osync_debug("OSXML", 0, "%s seems to be empty", path);
672  osync_error_set(error, OSYNC_ERROR_IO_ERROR, "%s seems to be empty", path);
673  xmlFreeDoc(*doc);
674  return FALSE;
675  }
676 
677  if (xmlStrcmp((*cur)->name, (const xmlChar *) topentry)) {
678  osync_debug("OSXML", 0, "%s seems not to be a valid configfile.\n", path);
679  osync_error_set(error, OSYNC_ERROR_IO_ERROR, "%s seems not to be a valid configfile.\n", path);
680  xmlFreeDoc(*doc);
681  return FALSE;
682  }
683 
684  *cur = (*cur)->xmlChildrenNode;
685  return TRUE;
686 }
687 
700 osync_bool osync_file_write(const char *filename, const char *data, int size, int mode, OSyncError **oserror)
701 {
702  osync_bool ret = FALSE;
703  GError *error = NULL;
704  GIOChannel *chan = g_io_channel_new_file(filename, "w", &error);
705  if (!chan) {
706  osync_debug("OSYNC", 3, "Unable to open file %s for writing: %s", filename, error->message);
707  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "Unable to open file %s for writing: %s", filename, error->message);
708  return FALSE;
709  }
710  if (mode) {
711  int fd = g_io_channel_unix_get_fd(chan);
712  if (fchmod(fd, mode)) {
713  osync_debug("OSYNC", 3, "Unable to set file permissions %i for file %s", mode, filename);
714  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "Unable to set file permissions %i for file %s", mode, filename);
715  return FALSE;
716  }
717  }
718  gsize writen;
719  g_io_channel_set_encoding(chan, NULL, NULL);
720  if (g_io_channel_write_chars(chan, data, size, &writen, &error) != G_IO_STATUS_NORMAL) {
721  osync_debug("OSYNC", 3, "Unable to write contents of file %s: %s", filename, error->message);
722  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "Unable to write contents of file %s: %s", filename, error->message);
723  } else {
724  g_io_channel_flush(chan, NULL);
725  ret = TRUE;
726  }
727  g_io_channel_shutdown(chan, FALSE, NULL);
728  g_io_channel_unref(chan);
729  return ret;
730 }
731 
743 osync_bool osync_file_read(const char *filename, char **data, int *size, OSyncError **oserror)
744 {
745  osync_bool ret = FALSE;
746  GError *error = NULL;
747  gsize sz = 0;
748 
749  if (!filename) {
750  osync_debug("OSYNC", 3, "No file open specified");
751  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "No file to open specified");
752  return FALSE;
753  }
754  GIOChannel *chan = g_io_channel_new_file(filename, "r", &error);
755  if (!chan) {
756  osync_debug("OSYNC", 3, "Unable to read file %s: %s", filename, error->message);
757  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "Unable to open file %s for reading: %s", filename, error->message);
758  return FALSE;
759  }
760  g_io_channel_set_encoding(chan, NULL, NULL);
761  if (g_io_channel_read_to_end(chan, data, &sz, &error) != G_IO_STATUS_NORMAL) {
762  osync_debug("OSYNC", 3, "Unable to read contents of file %s: %s", filename, error->message);
763  osync_error_set(oserror, OSYNC_ERROR_IO_ERROR, "Unable to read contents of file %s: %s", filename, error->message);
764  } else {
765  ret = TRUE;
766  *size = (int)sz;
767  }
768  g_io_channel_shutdown(chan, FALSE, NULL);
769  g_io_channel_unref(chan);
770  return ret;
771 }
772 
781 const char *osync_get_version(void)
782 {
783  return VERSION;
784 }
785 
796 void *osync_try_malloc0(unsigned int size, OSyncError **error)
797 {
798  void *result = g_try_malloc(size);
799  if (!result) {
800  osync_error_set(error, OSYNC_ERROR_GENERIC, "No memory left");
801  return NULL;
802  }
803  memset(result, 0, size);
804  return result;
805 }
806 
807 char *osync_strreplace(const char *input, const char *delimiter, const char *replacement)
808 {
809  osync_return_val_if_fail(input != NULL, NULL);
810  osync_return_val_if_fail(delimiter != NULL, NULL);
811  osync_return_val_if_fail(replacement != NULL, NULL);
812 
813  gchar **array = g_strsplit(input, delimiter, 0);
814  gchar *ret = g_strjoinv(replacement, array);
815  g_strfreev(array);
816 
817  return ret;
818 }
819 
822 OSyncThread *osync_thread_new(GMainContext *context, OSyncError **error)
823 {
824  osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, context, error);
825 
826  OSyncThread *thread = osync_try_malloc0(sizeof(OSyncThread), error);
827  if (!thread)
828  goto error;
829 
830  if (!g_thread_supported ()) g_thread_init (NULL);
831 
832  thread->started_mutex = g_mutex_new();
833  thread->started = g_cond_new();
834  thread->context = context;
835  if (thread->context)
836  g_main_context_ref(thread->context);
837  thread->loop = g_main_loop_new(thread->context, FALSE);
838 
839  osync_trace(TRACE_EXIT, "%s: %p", __func__, thread);
840  return thread;
841 
842 error:
843  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
844  return NULL;
845 }
846 
847 void osync_thread_free(OSyncThread *thread)
848 {
849  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, thread);
850  osync_assert(thread);
851 
852  if (thread->started_mutex)
853  g_mutex_free(thread->started_mutex);
854 
855  if (thread->started)
856  g_cond_free(thread->started);
857 
858  if (thread->loop)
859  g_main_loop_unref(thread->loop);
860 
861  if (thread->context)
862  g_main_context_unref(thread->context);
863 
864  g_free(thread);
865  osync_trace(TRACE_EXIT, "%s", __func__);
866 }
867 
868 /*static gpointer osyncThreadStartCallback(gpointer data)
869 {
870  OSyncThread *thread = data;
871 
872  g_mutex_lock(thread->started_mutex);
873  g_cond_signal(thread->started);
874  g_mutex_unlock(thread->started_mutex);
875 
876  g_main_loop_run(thread->loop);
877 
878  return NULL;
879 }*/
880 
881 static gboolean osyncThreadStopCallback(gpointer data)
882 {
883  OSyncThread *thread = data;
884 
885  g_main_loop_quit(thread->loop);
886 
887  return FALSE;
888 }
889 
890 /*void osync_thread_start(OSyncThread *thread)
891 {
892  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, thread);
893  osync_assert(thread);
894 
895  //Start the thread
896  g_mutex_lock(thread->started_mutex);
897  thread->thread = g_thread_create (osyncThreadStartCallback, thread, TRUE, NULL);
898  g_cond_wait(thread->started, thread->started_mutex);
899  g_mutex_unlock(thread->started_mutex);
900 
901  osync_trace(TRACE_EXIT, "%s", __func__);
902 }*/
903 
904 static gboolean osyncThreadStartCallback(gpointer data)
905 {
906  OSyncThread *thread = data;
907 
908  g_mutex_lock(thread->started_mutex);
909  g_cond_signal(thread->started);
910  g_mutex_unlock(thread->started_mutex);
911  return FALSE;
912 }
913 
914 void osync_thread_start(OSyncThread *thread)
915 {
916  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, thread);
917 
918  g_mutex_lock(thread->started_mutex);
919  GSource *idle = g_idle_source_new();
920  g_source_set_callback(idle, osyncThreadStartCallback, thread, NULL);
921  g_source_attach(idle, thread->context);
922  thread->thread = g_thread_create ((GThreadFunc)g_main_loop_run, thread->loop, TRUE, NULL);
923  g_cond_wait(thread->started, thread->started_mutex);
924  g_mutex_unlock(thread->started_mutex);
925 
926  osync_trace(TRACE_EXIT, "%s", __func__);
927 }
928 
929 void osync_thread_stop(OSyncThread *thread)
930 {
931  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, thread);
932  osync_assert(thread);
933 
934  GSource *source = g_idle_source_new();
935  g_source_set_callback(source, osyncThreadStopCallback, thread, NULL);
936  g_source_attach(source, thread->context);
937 
938  g_thread_join(thread->thread);
939  thread->thread = NULL;
940 
941  g_source_unref(source);
942 
943  osync_trace(TRACE_EXIT, "%s", __func__);
944 }
945 
946 osync_bool osync_pattern_match(const char *pattern, const char *data, int size)
947 {
948  GPatternSpec *spec = g_pattern_spec_new(pattern);
949  osync_bool result = g_pattern_match(spec, size, data, NULL);
950  g_pattern_spec_free(spec);
951  return result;
952 }
void osync_env_remove_group(OSyncEnv *env, OSyncGroup *group)
Removes the given group from the enviroment.
Definition: opensync_env.c:598
void osync_plugin_free(OSyncPlugin *plugin)
Used to free a plugin.
osync_bool osync_env_finalize(OSyncEnv *env, OSyncError **error)
Finalizes the environment.
Definition: opensync_env.c:289
OSyncGroup * osync_group_load(OSyncEnv *env, const char *path, OSyncError **error)
Loads a group from a directory.
osync_bool osync_env_initialize(OSyncEnv *env, OSyncError **error)
Initializes the environment (loads plugins)
Definition: opensync_env.c:240
void osync_env_export_loaded_modules(OSyncEnv *env)
Definition: opensync_env.c:83
Represent a user.
void osync_env_export_all_options(OSyncEnv *env)
Definition: opensync_env.c:120
void osync_module_unload(OSyncEnv *env, GModule *module)
Closes a module.
Represent an error.
osync_bool _osync_open_xml_file(xmlDocPtr *doc, xmlNodePtr *cur, const char *path, const char *topentry, OSyncError **error)
Opens a xml document.
Definition: opensync_env.c:652
int osync_env_num_groups(OSyncEnv *env)
Counts the groups in the environment.
Definition: opensync_env.c:611
OSyncGroup * osync_env_find_group(OSyncEnv *env, const char *name)
Finds the group with the given name.
Definition: opensync_env.c:563
void osync_env_set_option(OSyncEnv *env, const char *name, const char *value)
Sets a options on the environment.
Definition: opensync_env.c:222
Represent a synchronzation plugin.
void osync_env_append_group(OSyncEnv *env, OSyncGroup *group)
Adds the given group to the environment.
Definition: opensync_env.c:585
Represent a group of members that should be synchronized.
OSyncUserInfo * osync_user_new(OSyncError **error)
This will create a new user.
Definition: opensync_user.c:40
osync_bool osync_file_write(const char *filename, const char *data, int size, int mode, OSyncError **oserror)
Writes data to a file.
Definition: opensync_env.c:700
void osync_env_free(OSyncEnv *env)
Frees a osync environment.
Definition: opensync_env.c:207
osync_bool osync_env_load_plugins(OSyncEnv *env, const char *path, OSyncError **error)
Loads the sync modules from a given directory.
Definition: opensync_env.c:363
osync_bool osync_env_plugin_is_usable(OSyncEnv *env, const char *pluginname, OSyncError **error)
Checks if a plugin is available and usable.
Definition: opensync_env.c:440
void osync_error_free(OSyncError **error)
Frees the error so it can be reused.
void osync_group_free(OSyncGroup *group)
Frees the given group.
osync_bool osync_module_load_dir(OSyncEnv *env, const char *path, osync_bool must_exist, OSyncError **error)
Loads the modules from a given directory.
void * osync_try_malloc0(unsigned int size, OSyncError **error)
Safely tries to malloc memory.
Definition: opensync_env.c:796
const char * osync_user_get_confdir(OSyncUserInfo *user)
This will get the configdir for the given user.
Definition: opensync_user.c:93
void osync_debug(const char *subpart, int level, const char *message,...)
Used for debugging.
int osync_env_num_plugins(OSyncEnv *env)
Returns the number of loaded plugins.
Definition: opensync_env.c:413
osync_bool osync_file_read(const char *filename, char **data, int *size, OSyncError **oserror)
Reads a file.
Definition: opensync_env.c:743
long long int _osync_env_create_group_id(OSyncEnv *env)
Returns the next free number for a group in the environments configdir.
Definition: opensync_env.c:139
OSyncGroup * osync_env_nth_group(OSyncEnv *env, int nth)
Returns the nth group.
Definition: opensync_env.c:625
void osync_error_set(OSyncError **error, OSyncErrorType type, const char *format,...)
Sets the error.
const char * osync_error_print(OSyncError **error)
Returns the message of the error.
void osync_trace(OSyncTraceType type, const char *message,...)
Used for tracing the application.
const char * osync_get_version(void)
Returns the version of opensync.
Definition: opensync_env.c:781
OSyncPlugin * osync_env_find_plugin(OSyncEnv *env, const char *name)
Finds the plugin with the given name.
Definition: opensync_env.c:391
osync_bool osync_env_load_formats(OSyncEnv *env, const char *path, OSyncError **error)
Loads all format and conversion plugins.
Definition: opensync_env.c:334
osync_bool osync_env_load_groups(OSyncEnv *env, const char *p, OSyncError **error)
Loads the plugins from a given directory.
Definition: opensync_env.c:472
OSyncEnv * osync_env_new(void)
This will create a new opensync environment.
Definition: opensync_env.c:186
OSyncPlugin * osync_env_nth_plugin(OSyncEnv *env, int nth)
Returns pointer to nth plugin.
Definition: opensync_env.c:427