00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "opensync.h"
00022 #include "opensync_internals.h"
00023
00024
00032
00033 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00034 OSyncObjTypeSink *osync_objtype_sink_from_template(OSyncGroup *group, OSyncObjTypeTemplate *template)
00035 {
00036 g_assert(group);
00037 g_assert(template);
00038 OSyncObjTypeSink *sink = g_malloc0(sizeof(OSyncObjTypeSink));
00039 OSyncObjType *type = osync_conv_find_objtype(group->conv_env, template->name);
00040 if (!type) {
00041 osync_debug("OSYNC", 0, "Unable to find objtype named %s to create objtype sink", template->name);
00042 return NULL;
00043 }
00044 sink->objtype = type;
00045 sink->enabled = TRUE;
00046 sink->write = TRUE;
00047 sink->read = TRUE;
00048 return sink;
00049 }
00050
00051 OSyncObjFormatSink *osync_objformat_sink_from_template(OSyncGroup *group, OSyncObjFormatTemplate *template)
00052 {
00053 OSyncObjFormatSink *sink = g_malloc0(sizeof(OSyncObjFormatSink));
00054 OSyncObjFormat *format = osync_conv_find_objformat(group->conv_env, template->name);
00055 if (!format)
00056 return NULL;
00057 sink->format = format;
00058 sink->functions.commit_change = template->commit_change;
00059 sink->functions.access = template->access;
00060 sink->functions.read = template->read;
00061 sink->functions.committed_all = template->committed_all;
00062 sink->functions.batch_commit = template->batch_commit;
00063 sink->extension_name = g_strdup(template->extension_name);
00064 return sink;
00065 }
00066
00067 OSyncObjTypeTemplate *osync_plugin_find_objtype_template(OSyncPlugin *plugin, const char *objtypestr)
00068 {
00069 GList *o;
00070 for (o = plugin->accepted_objtypes; o; o = o->next) {
00071 OSyncObjTypeTemplate *template = o->data;
00072 if (!strcmp(template->name, objtypestr))
00073 return template;
00074 }
00075 return NULL;
00076 }
00077
00078 OSyncObjFormatTemplate *osync_plugin_find_objformat_template(OSyncObjTypeTemplate *type_template, const char *objformatstr)
00079 {
00080 GList *f;
00081 for (f = type_template->formats; f; f = f->next) {
00082 OSyncObjFormatTemplate *template = f->data;
00083 if (!strcmp(template->name, objformatstr))
00084 return template;
00085 }
00086 return NULL;
00087 }
00088
00089 OSyncObjFormatSink *osync_objtype_find_format_sink(OSyncObjTypeSink *sink, const char *formatstr)
00090 {
00091 GList *f;
00092 for (f = sink->formatsinks; f; f = f->next) {
00093 OSyncObjFormatSink *sink = f->data;
00094 if (!strcmp(sink->format->name, formatstr))
00095 return sink;
00096 }
00097 return NULL;
00098 }
00099
00100 void _osync_format_set_commit(OSyncObjTypeTemplate *template, const char *formatstr, OSyncFormatCommitFn commit_change)
00101 {
00102 OSyncObjFormatTemplate *format_template = NULL;
00103 if (formatstr) {
00104 OSyncObjFormatTemplate *format_template = osync_plugin_find_objformat_template(template, formatstr);
00105 osync_assert_msg(format_template, "Unable to set commit function. Did you forget to add the objformat?");
00106 format_template->commit_change = commit_change;
00107 } else {
00108 GList *f = NULL;
00109 for (f = template->formats; f; f = f->next) {
00110 format_template = f->data;
00111 format_template->commit_change = commit_change;
00112 }
00113 }
00114 }
00115
00116 void _osync_format_set_access(OSyncObjTypeTemplate *template, const char *formatstr, OSyncFormatAccessFn access)
00117 {
00118 OSyncObjFormatTemplate *format_template = NULL;
00119 if (formatstr) {
00120 format_template = osync_plugin_find_objformat_template(template, formatstr);
00121 osync_assert_msg(format_template, "Unable to set commit function. Did you forget to add the objformat?");
00122 format_template->access = access;
00123 } else {
00124 GList *f = NULL;
00125 for (f = template->formats; f; f = f->next) {
00126 format_template = f->data;
00127 format_template->access = access;
00128 }
00129 }
00130 }
00131
00132 void _osync_format_set_batch(OSyncObjTypeTemplate *template, const char *formatstr, OSyncFormatBatchCommitFn batch)
00133 {
00134 OSyncObjFormatTemplate *format_template = NULL;
00135 if (formatstr) {
00136 format_template = osync_plugin_find_objformat_template(template, formatstr);
00137 osync_assert_msg(format_template, "Unable to set batch commit function. Did you forget to add the objformat?");
00138 format_template->batch_commit = batch;
00139 } else {
00140 GList *f = NULL;
00141 for (f = template->formats; f; f = f->next) {
00142 format_template = f->data;
00143 format_template->batch_commit = batch;
00144 }
00145 }
00146 }
00147 #endif
00148
00158
00167 OSyncPlugin *osync_plugin_new(OSyncEnv *env)
00168 {
00169 OSyncPlugin *plugin = g_malloc0(sizeof(OSyncPlugin));
00170 g_assert(plugin);
00171 memset(&(plugin->info), 0, sizeof(plugin->info));
00172 memset(&(plugin->info.functions), 0, sizeof(plugin->info.functions));
00173 memset(&(plugin->info.timeouts), 0, sizeof(plugin->info.timeouts));
00174
00175
00176 plugin->info.timeouts.connect_timeout = 60;
00177 plugin->info.timeouts.sync_done_timeout = 60;
00178 plugin->info.timeouts.disconnect_timeout = 60;
00179 plugin->info.timeouts.get_changeinfo_timeout = 60;
00180 plugin->info.timeouts.get_data_timeout = 60;
00181 plugin->info.timeouts.commit_timeout = 60;
00182 plugin->info.timeouts.read_change_timeout = 60;
00183
00184 plugin->info.plugin = plugin;
00185 plugin->info.config_type = NEEDS_CONFIGURATION;
00186
00187 if (env) {
00188 env->plugins = g_list_append(env->plugins, plugin);
00189 plugin->env = env;
00190 plugin->real_plugin = env->current_module;
00191 }
00192
00193 return plugin;
00194 }
00195
00196
00205 OSyncPluginInfo *osync_plugin_new_info(OSyncEnv *env)
00206 {
00207 OSyncPlugin *plg = osync_plugin_new(env);
00208 osync_trace(TRACE_INTERNAL, "%s(%p): %p", __func__, env, plg);
00209 if (!plg)
00210 return NULL;
00211
00212 return &plg->info;
00213 }
00214
00222 void osync_plugin_free(OSyncPlugin *plugin)
00223 {
00224 osync_trace(TRACE_INTERNAL, "osync_plugin_free(%p)", plugin);
00225 g_assert(plugin);
00226 if (plugin->env)
00227 plugin->env->plugins = g_list_remove(plugin->env->plugins, plugin);
00228
00229
00230 g_free(plugin);
00231 }
00232
00243 void *osync_plugin_get_function(OSyncPlugin *plugin, const char *name, OSyncError **error)
00244 {
00245 void *function;
00246 if (!plugin->real_plugin) {
00247 osync_debug("OSPLG", 1, "You need to load a plugin before getting a function");
00248 osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "You need to load a plugin before getting a function");
00249 return NULL;
00250 }
00251
00252 if (!g_module_symbol (plugin->real_plugin, name, &function)) {
00253 osync_debug("OSPLG", 0, "Unable to locate symbol %s on plugin", name);
00254 osync_error_set(error, OSYNC_ERROR_PARAMETER, "Unable to locate symbol %s: %s", name, g_module_error());
00255 return NULL;
00256 }
00257 return function;
00258 }
00259
00270 osync_bool osync_module_load(OSyncEnv *env, const char *path, OSyncError **error)
00271 {
00272 osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, path, error);
00273
00274
00275
00276 if (!g_module_supported()) {
00277 osync_error_set(error, OSYNC_ERROR_GENERIC, "This platform does not support loading of modules");
00278 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00279 return FALSE;
00280 }
00281
00282
00283 GModule *module = g_module_open(path, 0);
00284 if (!module) {
00285 osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open module %s: %s", path, g_module_error());
00286 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00287 return FALSE;
00288 }
00289
00290
00291 void (* fct_info)(OSyncEnv *env) = NULL;
00292 void (** fct_infop)(OSyncEnv *env) = &fct_info;
00293 if (!g_module_symbol(module, "get_info", (void **)fct_infop)) {
00294
00295
00296
00297 osync_trace(TRACE_EXIT, "%s: Not loading implementation library", __func__);
00298 return TRUE;
00299 }
00300 env->modules = g_list_append(env->modules, module);
00301
00302
00303 env->current_module = module;
00304 fct_info(env);
00305 env->current_module = NULL;
00306
00307 osync_trace(TRACE_EXIT, "%s: %p", __func__, module);
00308 return TRUE;
00309 }
00310
00317 void osync_module_unload(OSyncEnv *env, GModule *module)
00318 {
00319 osync_trace(TRACE_INTERNAL, "%s(%p, %p)", __func__, env, module);
00320
00321
00322 env->modules = g_list_remove(env->modules, module);
00323 }
00324
00336 osync_bool osync_module_load_dir(OSyncEnv *env, const char *path, osync_bool must_exist, OSyncError **error)
00337 {
00338 osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, path, error);
00339 GDir *dir;
00340 GError *gerror = NULL;
00341 char *filename = NULL;
00342
00343 if (!path) {
00344 osync_error_set(error, OSYNC_ERROR_GENERIC, "Not path given to load the modules from");
00345 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00346 return FALSE;
00347 }
00348
00349
00350 if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
00351 if (must_exist) {
00352 osync_error_set(error, OSYNC_ERROR_GENERIC, "Path is not loadable");
00353 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00354 return FALSE;
00355 } else {
00356 osync_trace(TRACE_EXIT, "%s: Directory does not exist (non-fatal)", __func__);
00357 return TRUE;
00358 }
00359 }
00360
00361 dir = g_dir_open(path, 0, &gerror);
00362 if (!dir) {
00363 osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Unable to open directory %s: %s", path, gerror->message);
00364 g_error_free(gerror);
00365 osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
00366 return FALSE;
00367 }
00368
00369 const gchar *de = NULL;
00370 while ((de = g_dir_read_name(dir))) {
00371 filename = g_strdup_printf ("%s/%s", path, de);
00372
00373 if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR) || g_file_test(filename, G_FILE_TEST_IS_SYMLINK) || !g_pattern_match_simple("*.so", filename)) {
00374 g_free(filename);
00375 continue;
00376 }
00377
00378 OSyncError *error = NULL;
00379 if (!osync_module_load(env, filename, &error)) {
00380 osync_debug("OSPLG", 0, "Unable to load plugin %s: %s", filename, error->message);
00381 osync_error_free(&error);
00382 }
00383 g_free(filename);
00384 }
00385 g_dir_close(dir);
00386
00387 osync_trace(TRACE_EXIT, "%s", __func__);
00388 return TRUE;
00389 }
00390
00397 const char *osync_plugin_get_name(OSyncPlugin *plugin)
00398 {
00399 g_assert(plugin);
00400 return plugin->info.name;
00401 }
00402
00409 const char *osync_plugin_get_longname(OSyncPlugin *plugin)
00410 {
00411 g_assert(plugin);
00412 return plugin->info.longname;
00413 }
00414
00421 const char *osync_plugin_get_description(OSyncPlugin *plugin)
00422 {
00423 g_assert(plugin);
00424 return plugin->info.description;
00425 }
00426
00433 OSyncPluginTimeouts osync_plugin_get_timeouts(OSyncPlugin *plugin)
00434 {
00435 g_assert(plugin);
00436 return plugin->info.timeouts;
00437 }
00438
00444 void *osync_plugin_get_plugin_data(OSyncPlugin *plugin)
00445 {
00446 g_assert(plugin);
00447 return plugin->info.plugin_data;
00448 }
00449
00455 const char *osync_plugin_get_path(OSyncPlugin *plugin)
00456 {
00457 g_assert(plugin);
00458 return g_module_name(plugin->real_plugin);
00459 }
00460
00469 void osync_plugin_set_commit_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, OSyncFormatCommitFn commit_change)
00470 {
00471 OSyncObjTypeTemplate *template = NULL;
00472
00473 if (objtypestr) {
00474 OSyncObjTypeTemplate *template = osync_plugin_find_objtype_template(info->plugin, objtypestr);
00475 osync_assert_msg(template, "Unable to accept objformat. Did you forget to add the objtype?");
00476 _osync_format_set_commit(template, formatstr, commit_change);
00477 } else {
00478 GList *o = NULL;
00479 for (o = info->plugin->accepted_objtypes; o; o = o->next) {
00480 template = o->data;
00481 _osync_format_set_commit(template, formatstr, commit_change);
00482 }
00483 }
00484 }
00485
00494 void osync_plugin_set_access_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, OSyncFormatAccessFn access)
00495 {
00496 OSyncObjTypeTemplate *template = NULL;
00497
00498 if (objtypestr) {
00499
00500
00501
00502 } else {
00503 GList *o = NULL;
00504 for (o = info->plugin->accepted_objtypes; o; o = o->next) {
00505 template = o->data;
00506 _osync_format_set_access(template, formatstr, access);
00507 }
00508 }
00509 }
00510
00519 void osync_plugin_set_read_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, OSyncFormatReadFn read)
00520 {
00521 OSyncObjTypeTemplate *template = osync_plugin_find_objtype_template(info->plugin, objtypestr);
00522 osync_assert_msg(template, "Unable to accept objformat. Did you forget to add the objtype?");
00523 OSyncObjFormatTemplate *format_template = osync_plugin_find_objformat_template(template, formatstr);
00524 osync_assert_msg(format_template, "Unable to set commit function. Did you forget to add the objformat?");
00525 format_template->read = read;
00526 }
00527
00536 void osync_plugin_set_batch_commit_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, OSyncFormatBatchCommitFn batch)
00537 {
00538 OSyncObjTypeTemplate *template = NULL;
00539
00540 if (objtypestr) {
00541 template = osync_plugin_find_objtype_template(info->plugin, objtypestr);
00542 osync_assert_msg(template, "Unable to accept objformat. Did you forget to add the objtype?");
00543 _osync_format_set_batch(template, formatstr, batch);
00544 } else {
00545 GList *o = NULL;
00546 for (o = info->plugin->accepted_objtypes; o; o = o->next) {
00547 template = o->data;
00548 _osync_format_set_batch(template, formatstr, batch);
00549 }
00550 }
00551 }
00552
00561 void osync_plugin_set_committed_all_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, OSyncFormatCommittedAllFn committed_all)
00562 {
00563 OSyncObjTypeTemplate *template = osync_plugin_find_objtype_template(info->plugin, objtypestr);
00564 osync_assert_msg(template, "Unable to accept objformat. Did you forget to add the objtype?");
00565 OSyncObjFormatTemplate *format_template = osync_plugin_find_objformat_template(template, formatstr);
00566 osync_assert_msg(format_template, "Unable to set committed_all function. Did you forget to add the objformat?");
00567 format_template->committed_all = committed_all;
00568 }
00569
00579 void osync_plugin_accept_objtype(OSyncPluginInfo *info, const char *objtypestr)
00580 {
00581 OSyncObjTypeTemplate *template = g_malloc0(sizeof(OSyncObjTypeTemplate));
00582 template->name = g_strdup(objtypestr);
00583 info->plugin->accepted_objtypes = g_list_append(info->plugin->accepted_objtypes, template);
00584 }
00585
00597 void osync_plugin_accept_objformat(OSyncPluginInfo *info, const char *objtypestr, const char *formatstr, const char *extension)
00598 {
00599 OSyncObjTypeTemplate *template = osync_plugin_find_objtype_template(info->plugin, objtypestr);
00600 osync_assert_msg(template, "Unable to accept objformat. Did you forget to add the objtype?");
00601 OSyncObjFormatTemplate *format_template = g_malloc0(sizeof(OSyncObjFormatTemplate));
00602 format_template->name = g_strdup(formatstr);
00603 if (extension)
00604 format_template->extension_name = g_strdup(extension);
00605 template->formats = g_list_append(template->formats, format_template);
00606 }
00607