/*Load the state from a xml file and return it in the conn struct*/ osync_bool synce_parse_settings(SyncePluginPtr *env, char *data, int size, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %i)", __func__, env, data, size); xmlDocPtr doc; xmlNodePtr cur; int i; /* set defaults */ for (i = 0; i < TYPE_INDEX_MAX; i++) env->config_types[i] = FALSE; env->config_file = NULL; doc = xmlParseMemory(data, size); if (!doc) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to parse settings"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; } cur = xmlDocGetRootElement(doc); if (!cur) { xmlFreeDoc(doc); osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get root element of the settings"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; } if (xmlStrcmp(cur->name, (xmlChar*)"config")) { xmlFreeDoc(doc); osync_error_set(error, OSYNC_ERROR_GENERIC, "Config valid is not valid"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; } cur = cur->xmlChildrenNode; while (cur != NULL) { char *str = (char*)xmlNodeGetContent(cur); if (str) { if (!xmlStrcmp(cur->name, (const xmlChar *)"contact")) { /* Disable by mentioning NO or FALSE, otherwise enable. */ env->config_types[TYPE_INDEX_CONTACT] = TRUE; if (g_ascii_strcasecmp(str, "FALSE") == 0) env->config_types[TYPE_INDEX_CONTACT] = FALSE; if (g_ascii_strcasecmp(str, "NO") == 0) env->config_types[TYPE_INDEX_CONTACT] = FALSE; } if (!xmlStrcmp(cur->name, (const xmlChar *)"file")) { env->config_file = g_strdup(str); } if (!xmlStrcmp(cur->name, (const xmlChar *)"calendar")) { /* Disable by mentioning NO or FALSE, otherwise enable. */ env->config_types[TYPE_INDEX_CALENDAR] = TRUE; if (g_ascii_strcasecmp(str, "FALSE") == 0) env->config_types[TYPE_INDEX_CALENDAR] = FALSE; if (g_ascii_strcasecmp(str, "NO") == 0) env->config_types[TYPE_INDEX_CALENDAR] = FALSE; } if (!xmlStrcmp(cur->name, (const xmlChar *)"todos")) { /* Disable by mentioning NO or FALSE, otherwise enable. */ env->config_types[TYPE_INDEX_TODO] = TRUE; if (g_ascii_strcasecmp(str, "FALSE") == 0) env->config_types[TYPE_INDEX_CALENDAR] = FALSE; if (g_ascii_strcasecmp(str, "NO") == 0) env->config_types[TYPE_INDEX_CALENDAR] = FALSE; } xmlFree(str); } cur = cur->next; } xmlFreeDoc(doc); /* This belongs in XXX_connect() * if (!osync_member_objtype_enabled(env->member, "contact")) * env->config_contacts = FALSE; * if (!osync_member_objtype_enabled(env->member, "todos")) * env->config_todos = FALSE; * if (!osync_member_objtype_enabled(env->member, "calendar")) * env->config_calendar = FALSE; */ if (env->config_types[0] == 0 && env->config_types[1] == 0 && env->config_types[2] == 0 && env->config_file == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Nothing was configured"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; } osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; }
osync_bool synchronize_once(OSyncEngine *engine, OSyncError **error) { reset_counters(); fail_unless(osync_engine_repair(engine, error), "Repair of engine failed: %s", osync_error_print(error)); return osync_engine_synchronize_and_block(engine, error); }
OSyncList *osync_version_load_from_descriptions(OSyncError **error, const char *descriptiondir, const char *schemadir) { GDir *dir = NULL; GError *gerror = NULL; const char *descpath = descriptiondir ? descriptiondir : OPENSYNC_DESCRIPTIONSDIR; const char *schemapath = schemadir ? schemadir : OPENSYNC_SCHEMASDIR; char *filename = NULL; const gchar *de = NULL; OSyncList *versions = NULL; OSyncVersion *version = NULL; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr cur; xmlNodePtr child; osync_trace(TRACE_ENTRY, "%s(%p)", __func__, error); dir = g_dir_open(descpath, 0, &gerror); if (!dir) { /* If description directory doesn't exist (e.g. unittests), just ignore this. */ osync_trace(TRACE_EXIT, "Unable to open directory %s: %s", descpath, gerror->message); g_error_free(gerror); return NULL; } while ((de = g_dir_read_name(dir))) { char *schemafilepath = NULL; osync_bool res; filename = osync_strdup_printf ("%s%c%s", descpath, G_DIR_SEPARATOR, de); if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR) || !g_pattern_match_simple("*.xml", filename)) { osync_free(filename); continue; } doc = xmlReadFile(filename, NULL, XML_PARSE_NOBLANKS); if(!doc) { osync_free(filename); continue; } osync_free(filename); root = xmlDocGetRootElement(doc); if(!root || !xmlStrEqual(root->name, BAD_CAST "versions")) { osync_xml_free_doc(doc); continue; } schemafilepath = osync_strdup_printf("%s%c%s", schemapath, G_DIR_SEPARATOR, "descriptions.xsd"); res = osync_xml_validate_document(doc, schemafilepath); osync_free(schemafilepath); if(res == FALSE) { osync_xml_free_doc(doc); continue; } cur = root->children; for(; cur != NULL; cur = cur->next) { version = osync_version_new(error); if(!version) { OSyncList *cur = NULL; osync_xml_free_doc(doc); cur = osync_list_first(versions); while(cur) { osync_version_unref(cur->data); cur = cur->next; } goto error; } child = cur->children; osync_version_set_plugin(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_priority(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_vendor(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_modelversion(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_firmwareversion(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_softwareversion(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_hardwareversion(version, (const char *)osync_xml_node_get_content(child)); child = child->next; osync_version_set_identifier(version, (const char *)osync_xml_node_get_content(child)); versions = osync_list_append(versions, version); } osync_xml_free_doc(doc); } g_dir_close(dir); osync_trace(TRACE_EXIT, "%s: %p", __func__, versions); return versions; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; }
osync_bool osync_queue_connect(OSyncQueue *queue, OSyncQueueType type, OSyncError **error) { #ifdef _WIN32 return FALSE; #else //_WIN32 OSyncQueue **queueptr = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, queue, type, error); osync_assert(queue); osync_assert(queue->connected == FALSE); queue->type = type; if (queue->fd == -1) { /* First, open the queue with the flags provided by the user */ int fd = open(queue->name, type == OSYNC_QUEUE_SENDER ? O_WRONLY : O_RDONLY); if (fd == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open fifo"); goto error; } queue->fd = fd; } int oldflags = fcntl(queue->fd, F_GETFD); if (oldflags == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get fifo flags"); goto error_close; } if (fcntl(queue->fd, F_SETFD, oldflags|FD_CLOEXEC) == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to set fifo flags"); goto error_close; } queue->connected = TRUE; signal(SIGPIPE, SIG_IGN); /* now we start a thread which handles reading/writing of the queue */ queue->thread = osync_thread_new(queue->context, error); if (!queue->thread) goto error; queue->write_functions = g_malloc0(sizeof(GSourceFuncs)); queue->write_functions->prepare = _queue_prepare; queue->write_functions->check = _queue_check; queue->write_functions->dispatch = _queue_dispatch; queue->write_functions->finalize = NULL; queue->write_source = g_source_new(queue->write_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->write_source + 1); *queueptr = queue; g_source_set_callback(queue->write_source, NULL, queue, NULL); g_source_attach(queue->write_source, queue->context); if (queue->context) g_main_context_ref(queue->context); queue->read_functions = g_malloc0(sizeof(GSourceFuncs)); queue->read_functions->prepare = _source_prepare; queue->read_functions->check = _source_check; queue->read_functions->dispatch = _source_dispatch; queue->read_functions->finalize = NULL; queue->read_source = g_source_new(queue->read_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->read_source + 1); *queueptr = queue; g_source_set_callback(queue->read_source, NULL, queue, NULL); g_source_attach(queue->read_source, queue->context); if (queue->context) g_main_context_ref(queue->context); queue->timeout_functions = g_malloc0(sizeof(GSourceFuncs)); queue->timeout_functions->prepare = _timeout_prepare; queue->timeout_functions->check = _timeout_check; queue->timeout_functions->dispatch = _timeout_dispatch; queue->timeout_functions->finalize = NULL; queue->timeout_source = g_source_new(queue->timeout_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->timeout_source + 1); *queueptr = queue; g_source_set_callback(queue->timeout_source, NULL, queue, NULL); g_source_attach(queue->timeout_source, queue->context); if (queue->context) g_main_context_ref(queue->context); osync_thread_start(queue->thread); osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; error_close: close(queue->fd); error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; #endif //_WIN32 }
int main (int argc, char *argv[]) { int i; char *groupname = NULL; char *membername = NULL; ToolAction action = DUMPMAPS; char *configdir = NULL; char *objtype = NULL; OSyncError *error = NULL; OSyncGroupEnv *env = NULL; if (argc == 1) usage (argv[0], 1); groupname = argv[1]; for (i = 2; i < argc; i++) { char *arg = argv[i]; if (!strcmp (arg, "--mappings")) { action = DUMPMAPS; objtype = argv[i + 1]; i++; if (!objtype) usage (argv[0], 1); } else if (!strcmp (arg, "--hash")) { action = DUMPHASH; objtype = argv[i + 1]; membername = argv[i + 2]; i += 2; if (!objtype || !membername) usage (argv[0], 1); } else if (!strcmp (arg, "--reset")) { action = RESET; } else if (!strcmp (arg, "--help")) { usage (argv[0], 0); } else if (!strcmp (arg, "--configdir")) { configdir = argv[i + 1]; i++; if (!configdir) usage (argv[0], 1); } else if (!strcmp (arg, "--")) { break; } else if (arg[0] == '-') { usage (argv[0], 1); } else { usage (argv[0], 1); } } env = osync_group_env_new(&error); if (!env) goto error; if (!osync_group_env_load_groups(env, configdir, &error)) goto error; switch (action) { case DUMPMAPS: if (objtype) dump_map_objtype(env, objtype, groupname); else dump_map(env, groupname); break; case DUMPHASH: dump_hash(env, objtype, groupname, membername); break; case RESET: reset(env, groupname); break; } osync_group_env_unref(env); return 0; error: if (env) osync_group_env_unref(env); printf("ERROR: %s", osync_error_print(&error)); osync_error_unref(&error); return 1; }
OSyncCapabilities *osync_version_find_capabilities(OSyncVersion *version, OSyncError **error) { int priority = -1; OSyncVersion *winner = NULL; OSyncCapabilities *capabilities = NULL; OSyncList *versions = NULL; OSyncList *cur = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, version, error); osync_assert(version); versions = osync_version_load_from_default_descriptions(error); if (*error) /* versions can be null */ goto error; cur = osync_list_first(versions); while(cur) { int curpriority = osync_version_matches(cur->data, version, error); if (curpriority == -1) { if (versions) osync_list_free(versions); if (winner) osync_version_unref(winner); goto error; } if( curpriority > 0 && curpriority > priority) { if(winner) osync_version_unref(winner); winner = cur->data; osync_version_ref(winner); priority = curpriority; } osync_version_unref(cur->data); cur = cur->next; } osync_list_free(versions); /* we found or own capabilities */ if(priority > 0) { osync_trace(TRACE_INTERNAL, "Found capabilities file by version: %s ", (const char*)osync_version_get_identifier(winner)); capabilities = osync_capabilities_load_identifier((const char*)osync_version_get_identifier(winner), error); osync_version_unref(winner); if (!capabilities) goto error; } osync_trace(TRACE_EXIT, "%s: %p", __func__, capabilities); return capabilities; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; }
void on_editgroupdiscoverbutton_clicked(GtkButton* button, gpointer user_data) { g_assert(user_data); MSyncEnv* env = (MSyncEnv*)user_data; OSyncError* error = NULL; //TODO: dont block gui thread! //g_thread_create((GThreadFunc)msync_group_syncronize2, group, FALSE, NULL); OSyncEngine *engine = osync_engine_new(env->curgroup->group, &error); if (!engine) { goto error; } /* Discover the objtypes for the members */ if(!osync_engine_discover_and_block(engine,env->curmember, &error)) goto error_free_engine; osync_engine_unref(engine); return; error_free_engine: osync_engine_unref(engine); error: msync_error_message(GTK_WINDOW(env->mainwindow), TRUE, "Error while discovering: %s\n", osync_error_print(&error)); osync_error_unref(&error); }
/* In initialize, we get the config for the plugin. Here we also must register * all _possible_ objtype sinks. */ static void *mock_initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error); if (mock_get_error(info->memberid, "INIT_NULL_NOERROR")) { osync_trace(TRACE_EXIT, "%s: %s", __func__, "Everything is fine. I don't need plugin userdata."); return NULL; } if (mock_get_error(info->memberid, "INIT_NULL")) { osync_error_set(error, OSYNC_ERROR_EXPECTED, "Triggering INIT_NULL error"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } mock_env *env = osync_try_malloc0(sizeof(mock_env), error); osync_assert(env); OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); osync_assert(formatenv); OSyncPluginConfig *config = osync_plugin_info_get_config(info); osync_assert(config); if (mock_get_error(info->memberid, "MAINSINK_CONNECT")) { env->mainsink = osync_objtype_main_sink_new(error); osync_objtype_sink_set_connect_func(env->mainsink, mock_connect); osync_objtype_sink_set_disconnect_func(env->mainsink, mock_mainsink_disconnect); osync_objtype_sink_set_userdata(env->mainsink, env); osync_plugin_info_set_main_sink(info, env->mainsink); } /* Now we register the objtypes that we can sync. This plugin is special. It can * synchronize any objtype we configure it to sync and where a conversion * path to the file format can be found */ OSyncList *objtypesinks = osync_plugin_info_get_objtype_sinks(info); OSyncList *list = NULL; for (list = objtypesinks;list; list = list->next) { MockDir *dir = osync_try_malloc0(sizeof(MockDir), error); osync_assert(dir); dir->committed_all = TRUE; OSyncObjTypeSink *sink = (OSyncObjTypeSink*)list->data; osync_assert(sink); const char *objtype = osync_objtype_sink_get_name(sink); dir->res = osync_plugin_config_find_active_resource(config, objtype); osync_plugin_resource_ref(dir->res); dir->path = osync_plugin_resource_get_path(dir->res); osync_assert(dir->path); OSyncList *format_sinks = osync_plugin_resource_get_objformat_sinks(dir->res); osync_assert(osync_list_length(format_sinks) == 1); OSyncObjFormatSink *format_sink = osync_list_nth_data(format_sinks, 0); const char *objformat_str = osync_objformat_sink_get_objformat(format_sink); osync_assert(objformat_str); dir->objformat = osync_format_env_find_objformat(formatenv, objformat_str); osync_assert(dir->objformat); osync_objformat_ref(dir->objformat); osync_list_free(format_sinks); /* const char *objformat = osync_objformat_get_name(dir->objformat); OSyncObjFormatSink *format_sink = osync_objformat_sink_new(objformat, error); if (!format_sink) return NULL; osync_objtype_sink_add_objformat_sink(sink, format_sink); */ /* Sanity check for connect_done */ dir->connect_done = TRUE; if (!mock_get_error(info->memberid, "MAINSINK_CONNECT")) { osync_objtype_sink_set_connect_func(sink, mock_connect); osync_objtype_sink_set_connect_done_func(sink, mock_connect_done); osync_objtype_sink_set_disconnect_func(sink, mock_disconnect); } osync_objtype_sink_set_get_changes_func(sink, mock_get_changes); osync_objtype_sink_set_committed_all_func(sink, mock_committed_all); osync_objtype_sink_set_commit_func(sink, mock_commit_change); osync_objtype_sink_set_read_func(sink, mock_read); osync_objtype_sink_set_sync_done_func(sink, mock_sync_done); /* We pass the MockDir object to the sink, so we dont have to look it up * again once the functions are called */ osync_objtype_sink_set_userdata(sink, dir); /* Request an Anchor */ osync_objtype_sink_enable_state_db(sink, TRUE); /* Request an Hashtable */ osync_objtype_sink_enable_hashtable(sink, TRUE); //Lets reduce the timeouts a bit so the checks work faster osync_objtype_sink_set_connect_timeout(sink, 2); osync_objtype_sink_set_getchanges_timeout(sink, 2); osync_objtype_sink_set_commit_timeout(sink, 4); osync_objtype_sink_set_committedall_timeout(sink, 4); osync_objtype_sink_set_syncdone_timeout(sink, 2); osync_objtype_sink_set_disconnect_timeout(sink, 2); osync_objtype_sink_set_read_timeout(sink, 2); /* XXX No testcase is currently using this at all! */ #if 0 if (g_getenv("NO_TIMEOUTS")) { /* XXX Timeout value of wouldn't work out, since the Sink object would fallback to the default timeout value: sink->timeout.connect ? sink->timeout.connect : OSYNC_SINK_TIMEOUT_CONNECT; Really needed?! */ osync_objtype_sink_set_connect_timeout(sink, 0); osync_objtype_sink_set_getchanges_timeout(sink, 0); osync_objtype_sink_set_commit_timeout(sink, 0); osync_objtype_sink_set_committedall_timeout(sink, 0); osync_objtype_sink_set_syncdone_timeout(sink, 0); osync_objtype_sink_set_disconnect_timeout(sink, 0); osync_objtype_sink_set_read_timeout(sink, 0); } /* What is meant by this?! Maybe OSyncPlugin.useable?! Not used at all... if (g_getenv("IS_AVAILABLE")) info->functions.is_available = mock_is_available; */ #endif env->directories = g_list_append(env->directories, dir); } osync_list_free(objtypesinks); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; }
static OSyncFormatConverterPath *osync_format_env_find_path_fn(OSyncFormatEnv *env, OSyncData *sourcedata, OSyncPathTargetFn target_fn, OSyncTargetLastConverterFn last_converter_fn, const void *fndata, const char * preferred_format, OSyncError **error) { OSyncFormatConverterPath *path = NULL; OSyncFormatConverterTree *tree = NULL; OSyncFormatConverterPathVertice *begin = NULL; OSyncFormatConverterPathVertice *result = NULL; OSyncFormatConverterPathVertice *neighbour = NULL; GList *e, *v; guint vertice_id = 0; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, env, sourcedata, target_fn, fndata, error); osync_assert(env); osync_assert(sourcedata); osync_assert(target_fn); //Vertice = Spitze = Format //edge = Kante = Converter /* Optimization: check if the format is already valid */ if (target_fn(fndata, osync_data_get_objformat(sourcedata))) { path = osync_converter_path_new(error); if (!path) goto error; osync_trace(TRACE_EXIT, "%s: Target already valid", __func__); return path; } /* Make a new search tree */ tree = osync_try_malloc0(sizeof(OSyncFormatConverterTree), error); if (!tree) goto error; tree->unused = g_list_copy(env->converters); /* We make our starting point (which is the current format of the * change of course */ begin = osync_format_converter_path_vertice_new(error); if (!begin) goto error_free_tree; begin->format = osync_data_get_objformat(sourcedata); begin->path = NULL; begin->id = vertice_id; begin->neighbour_id = 0; tree->search = g_list_append(NULL, begin); /* While there are still vertices in our * search queue */ while (g_list_length(tree->search)) { /* log current tree search list */ GString *string = g_string_new(""); guint size = g_list_length(tree->search); guint count = 0; guint neighbour_id = 0; OSyncFormatConverterPathVertice *current = NULL; OSyncFormatConverterPath *path_tmp = NULL; for (v = tree->search; v; v = v->next) { OSyncFormatConverterPathVertice *vertice = v->data; GString *string2 = g_string_new(""); guint size2 = g_list_length(vertice->path); guint count2 = 0; count ++; for (e = vertice->path; e; e = e->next) { OSyncFormatConverter *edge = e->data; count2 ++; if (count2 == 1) { g_string_append(string2, osync_objformat_get_name(osync_converter_get_sourceformat(edge))); g_string_append(string2, " -> "); } g_string_append(string2, osync_objformat_get_name(osync_converter_get_targetformat(edge))); if (size2 > 1 && count2 < size2) g_string_append(string2, " -> "); } g_string_append(string, osync_objformat_get_name(vertice->format)); g_string_append(string, " ( "); g_string_append(string, string2->str); g_string_append(string, " ) "); g_string_free(string2, TRUE); if (size > 1 && count < size) g_string_append(string, " -> "); } osync_trace(TRACE_INTERNAL, "Tree : %s", string->str); g_string_free(string, TRUE); /* Get the first OSyncFormatConverterPathVertice from the search queue * and remove it from the queue */ current = tree->search->data; tree->search = g_list_remove(tree->search, current); /* log current OSyncFormatConverterPathVertice */ string = g_string_new(""); size = g_list_length(current->path); count = 0; for (e = current->path; e; e = e->next) { OSyncFormatConverter *edge = e->data; count ++; if (count == 1) { g_string_append(string, osync_objformat_get_name(osync_converter_get_sourceformat(edge))); g_string_append(string, " -> "); } g_string_append(string, osync_objformat_get_name(osync_converter_get_targetformat(edge))); if (size > 1 && count < size) g_string_append(string, " -> "); } osync_trace(TRACE_INTERNAL, "Next vertice : %s (%s).", osync_objformat_get_name(current->format), string->str); g_string_free(string, TRUE); current->neighbour_id = 0; vertice_id++; // current OSyncFormatConverterPathVertice id for its neighbours /* Check if we have reached a target format */ if (target_fn(fndata, current->format)) { osync_trace(TRACE_INTERNAL, "Target %s found", osync_objformat_get_name(current->format)); /* Done. return the result */ result = current; break; } /* * Optimizations : */ if (last_converter_fn(fndata, tree)) { osync_trace(TRACE_INTERNAL, "Last converter for target format reached: %s.", (result)?osync_objformat_get_name(result->format):"null"); osync_format_converter_path_vertice_unref(current); break; } /* Check if saved result is equal to current regarding losses, objtype_changes * and conversions. If yes, we can skip further searches and break here */ if (result) { if (result->losses <= current->losses && result->objtype_changes <= current->objtype_changes && result->conversions <= current->conversions) { osync_trace(TRACE_INTERNAL, "Target %s found in queue", osync_objformat_get_name(result->format)); tree->search = g_list_remove(tree->search, result); break; } else { result = NULL; } } /* * If we dont have reached a target, we look at our neighbours */ osync_trace(TRACE_INTERNAL, "Looking at %s's neighbours.", osync_objformat_get_name(current->format)); /* Convert the "current" data to the last edge found in the "current" conversion path */ current->data = osync_data_clone(sourcedata, error); path_tmp = osync_converter_path_new(error); if (!path_tmp) goto error; for (e = current->path; e; e = e->next) { OSyncFormatConverter *edge = e->data; osync_converter_path_add_edge(path_tmp, edge); } if (!(osync_format_env_convert(env, path_tmp, current->data, error))) { osync_trace(TRACE_INTERNAL, "osync format env convert on this path failed - skipping the conversion"); continue; } osync_converter_path_unref(path_tmp); /* Find all the neighboors or "current" at its current conversion point */ while ((neighbour = osync_format_converter_path_vertice_get_next_vertice_neighbour(env, tree, current, error))) { GString *string = g_string_new(""); guint size = g_list_length(neighbour->path); guint count = 0; neighbour->id = vertice_id; neighbour_id++; neighbour->neighbour_id = neighbour_id; neighbour->preferred = FALSE; if (current->preferred) /* preferred is inherited by the neighbours */ neighbour->preferred = TRUE; if(preferred_format && !strcmp(preferred_format, osync_objformat_get_name(neighbour->format))) neighbour->preferred = TRUE; /* log neighbour to be added to the tree search list */ for (e = neighbour->path; e; e = e->next) { OSyncFormatConverter *edge = e->data; count ++; if (count == 1) { g_string_append(string, osync_objformat_get_name(osync_converter_get_sourceformat(edge))); g_string_append(string, " -> "); } g_string_append(string, osync_objformat_get_name(osync_converter_get_targetformat(edge))); if (size > 1 && count < size) g_string_append(string, " -> "); } osync_trace(TRACE_INTERNAL, "%s's neighbour : %s (%s)", osync_objformat_get_name(current->format), osync_objformat_get_name(neighbour->format), string->str); g_string_free(string, TRUE); /* We found a neighbour and insert it sorted in our search queue If vertices are equals in losses, objtypes and conversions, first registered is inserted before the others in the same OSyncFormatConverterPathVertice group (vertice_id) */ tree->search = g_list_insert_sorted(tree->search, neighbour, osync_format_converter_path_vertice_compare_distance); /* Optimization: * We found a possible target. Save it. */ if (target_fn(fndata, neighbour->format)) { osync_trace(TRACE_INTERNAL, "Possible target found."); result = neighbour; osync_format_converter_path_vertice_ref(result); } } if (osync_error_is_set(error)) goto error_free_tree; /* Done, drop the reference to the OSyncFormatConverterPathVertice */ osync_format_converter_path_vertice_unref(current); } if (!result) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find conversion path"); goto error_free_tree; } /* Found it. Create a path object */ path = osync_converter_path_new(error); if (!path) goto error; for (e = result->path; e; e = e->next) { OSyncFormatConverter *edge = e->data; osync_converter_path_add_edge(path, edge); } /* Drop the reference to the result OSyncFormatConverterPathVertice */ osync_format_converter_path_vertice_unref(result); /* Free the tree */ osync_converter_tree_free(tree); osync_trace(TRACE_EXIT, "%s: %p", __func__, path); return path; error_free_tree: osync_converter_tree_free(tree); error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; }
static osync_bool osync_format_env_load_modules(OSyncFormatEnv *env, const char *path, osync_bool must_exist, OSyncError **error) { GDir *dir = NULL; GError *gerror = NULL; char *filename = NULL; OSyncModule *module = NULL; const gchar *de = NULL; GList *m = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %s, %i, %p)", __func__, env, path, must_exist, error); osync_assert(env); osync_assert(path); //Load all available shared libraries (plugins) if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { if (must_exist) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Path is not loadable"); goto error; } else { osync_trace(TRACE_EXIT, "%s: Directory does not exist (non-fatal)", __func__); return TRUE; } } dir = g_dir_open(path, 0, &gerror); if (!dir) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Unable to open directory %s: %s", path, gerror->message); g_error_free(gerror); goto error; } while ((de = g_dir_read_name(dir))) { filename = g_strdup_printf ("%s%c%s", path, G_DIR_SEPARATOR, de); if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR) || !g_pattern_match_simple("*."G_MODULE_SUFFIX, filename)) { g_free(filename); continue; } module = osync_module_new(error); if (!module) goto error_free_filename; if (!osync_module_load(module, filename, error)) { osync_trace(TRACE_INTERNAL, "Unable to load module %s: %s", filename, osync_error_print(error)); osync_module_free(module); g_free(filename); continue; } if (!osync_module_check(module, error)) { if (osync_error_is_set(error)) { osync_trace(TRACE_INTERNAL, "Module check error for %s: %s", filename, osync_error_print(error)); } osync_module_free(module); g_free(filename); continue; } if (!osync_module_get_format_info(module, env, error) && !osync_module_get_function(module, "get_conversion_info", NULL)) { if (osync_error_is_set(error)) { osync_trace(TRACE_ERROR, "Module load format plugin error for %s: %s", filename, osync_error_print(error)); } osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to load format plugin %s. Neither a converter nor a format could be initialized.", __NULLSTR(filename)); osync_trace(TRACE_ERROR, "%s", osync_error_print(error)); osync_module_free(module); g_free(filename); continue; } env->modules = g_list_append(env->modules, module); g_free(filename); } g_dir_close(dir); /* Load the converters, filters, etc */ for (m = env->modules; m; m = m->next) { module = m->data; if (!osync_module_get_conversion_info(module, env, error)) { osync_trace(TRACE_INTERNAL, "Module get conversion error %s", osync_error_print(error)); osync_error_unref(error); } } osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; error_free_filename: g_free(filename); g_dir_close(dir); error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; }
static OSyncFormatConverterPathVertice *osync_format_converter_path_vertice_get_next_vertice_neighbour(OSyncFormatEnv *env, OSyncFormatConverterTree *tree, OSyncFormatConverterPathVertice *ve, OSyncError **error) { GList *c = NULL; OSyncFormatConverter *converter = NULL; OSyncObjFormat *fmt_target = NULL; OSyncFormatConverterPathVertice *neigh = NULL; const char *source_objtype = NULL; const char *target_objtype = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, env, tree, ve); /* Ok. we need to get the next valid neighbour to our input OSyncFormatConverterPathVertice. * Valid neighbours are the once that are reachable by a conversion. So * we now go through all converters and check if they are valid */ for (c = tree->unused; c; c = c->next) { OSyncObjFormat *sourceformat = NULL, *targetformat = NULL; converter = c->data; fmt_target = osync_converter_get_targetformat(converter); /* Check only valid converters, from the right format */ if (!osync_objformat_is_equal(osync_converter_get_sourceformat(converter), ve->format)) continue; /* Only validate with the help of detectors, if data is available to run a detector on it. Check if a detector validate this path */ if (osync_data_has_data(ve->data) && !osync_format_converter_path_vertice_validate_path_with_detector(ve, env, converter)) continue; /* Remove the converter from the unused list */ tree->unused = g_list_remove(tree->unused, converter); /* Allocate the new neighbour */ neigh = osync_format_converter_path_vertice_new(error); if (!neigh) goto error; neigh->format = fmt_target; neigh->path = g_list_copy(ve->path); neigh->path = g_list_append(neigh->path, converter); /* Distance calculation */ neigh->conversions = ve->conversions + 1; neigh->losses = ve->losses; if (osync_converter_get_type(converter) == OSYNC_CONVERTER_DECAP) neigh->losses++; neigh->objtype_changes = ve->objtype_changes; sourceformat = osync_converter_get_sourceformat(converter); targetformat = osync_converter_get_targetformat(converter); source_objtype = osync_objformat_get_objtype(sourceformat); target_objtype = osync_objformat_get_objtype(targetformat); if (strcmp(source_objtype, target_objtype)) neigh->objtype_changes++; osync_trace(TRACE_EXIT, "%s: %p (converter from %s to %s) objtype changes : %i losses : %i, conversions : %i", __func__, neigh, osync_objformat_get_name(sourceformat), osync_objformat_get_name(targetformat), neigh->objtype_changes, neigh->losses, neigh->conversions); return neigh; } osync_trace(TRACE_EXIT, "%s: None found", __func__); return NULL; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; }
static osync_bool init(OSyncError **error) { OSyncPluginConfig *config; assert(!plugin); assert(!plugin_env); if (!(plugin_env = osync_plugin_env_new(error))) goto error; if (!(format_env = osync_format_env_new(error))) goto error_free_pluginenv; if (!osync_format_env_load_plugins(format_env, formatpath, error)) goto error_free_formatenv; if (osync_error_is_set(error)) { fprintf(stderr, "WARNING! Some plugins couldn't get loaded in " "format plugin environment: %s\n", osync_error_print(error)); osync_error_unref(error); } if (!osync_plugin_env_load(plugin_env, pluginpath, error)) goto error_free_pluginenv; if (osync_error_is_set(error)) { fprintf(stderr, "WARNING! Some plugins couldn't get loaded in " "plugin environment: %s\n", osync_error_print(error)); osync_error_unref(error); } if (!(plugin = osync_plugin_env_find_plugin(plugin_env, pluginname))) { osync_error_set(error, OSYNC_ERROR_PLUGIN_NOT_FOUND, "Plugin not found: \"%s\"", pluginname); goto error_free_pluginenv; } if (!(plugin_info = osync_plugin_info_new(error))) goto error_free_pluginenv; config = osync_plugin_config_new(error); if (!config) goto error_free_plugininfo; if (osync_plugin_get_config_type(plugin) != OSYNC_PLUGIN_NO_CONFIGURATION && configfile) { OSyncList *r = NULL; if (!osync_plugin_config_file_load(config, configfile, error)) goto error_free_pluginconfig; osync_plugin_info_set_config(plugin_info, config); /** Redudant(aka. stolen) code from opensync/client/opensync_client.c */ /* Enable active sinks */ if (config) r = osync_plugin_config_get_resources(config); for (; r; r = r->next) { OSyncPluginResource *res = r->data; OSyncObjTypeSink *sink; const char *objtype = osync_plugin_resource_get_objtype(res); OSyncList *o = NULL; /* Check for ObjType sink */ if (!(sink = osync_plugin_info_find_objtype(plugin_info, objtype))) { sink = osync_objtype_sink_new(objtype, error); if (!sink) goto error_free_pluginconfig; osync_plugin_info_add_objtype(plugin_info, sink); } OSyncList *objformats = osync_plugin_resource_get_objformat_sinks(res); for ( o = objformats; o; o = o->next) { OSyncObjFormatSink *format_sink = (OSyncObjFormatSink *) o->data; osync_objtype_sink_add_objformat_sink(sink, format_sink); } osync_list_free(objformats); } osync_plugin_config_unref(config); } if (!configfile && osync_plugin_get_config_type(plugin) == OSYNC_PLUGIN_NEEDS_CONFIGURATION) { osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "Plugin \"%s\" requires configuration!", pluginname); goto error_free_pluginconfig; } assert(!ctx); ctx = g_main_context_new(); osync_plugin_info_set_configdir(plugin_info, configdir); osync_plugin_info_set_loop(plugin_info, ctx); osync_plugin_info_set_format_env(plugin_info, format_env); osync_plugin_info_set_groupname(plugin_info, syncgroup); return TRUE; /* error_free_loop: g_main_context_unref(ctx); */ error_free_pluginconfig: osync_plugin_config_unref(config); error_free_plugininfo: osync_plugin_info_unref(plugin_info); error_free_formatenv: osync_format_env_unref(format_env); format_env = NULL; error_free_pluginenv: osync_plugin_env_unref(plugin_env); plugin_env = NULL; error: return FALSE; }
int main (int argc, char *argv[]) { int i; char *pluginname = NULL; char *plugindir = NULL; char *configfile = NULL; char *objtype = NULL; OSyncError *error = NULL; if (argc < 2) usage (argv[0], 1); pluginname = argv[1]; for (i = 2; i < argc; i++) { char *arg = argv[i]; if (!strcmp (arg, "--config")) { configfile = argv[i + 1]; i++; if (!configfile) usage (argv[0], 1); } else if (!strcmp (arg, "--type")) { objtype = argv[i + 1]; i++; if (!objtype) usage (argv[0], 1); } else if (!strcmp (arg, "--plugindir")) { printf("plugindir %s\n", argv[i + 1]); plugindir = argv[i + 1]; i++; if (!plugindir) usage (argv[0], 1); } else if (!strcmp (arg, "--random")) { only_random = TRUE; } else if (!strcmp (arg, "--help")) { usage (argv[0], 0); } else { usage (argv[0], 1); } } OSyncEnv *env = osync_env_new(NULL); osync_env_set_option(env, "LOAD_GROUPS", "FALSE"); if (plugindir) osync_env_set_option(env, "PLUGINS_DIRECTORY", plugindir); if (!osync_env_initialize(env, &error)) { printf("Unable to initialize environment: %s\n", osync_error_print(&error)); osync_error_unref(&error); return 1; } char *testdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir()); char *result = mkdtemp(testdir); if (result == NULL) { osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno)); return 1; } OSyncGroup *group = osync_group_new(env); osync_group_set_name(group, osync_rand_str(8)); osync_group_set_configdir(group, testdir); OSyncMember *member = osync_member_new(group); char *config = NULL; int size = 0; if (configfile) { if (!osync_file_read(configfile, &config, &size, &error)) { fprintf(stderr, "Unable to read config: %s\n", osync_error_print(&error)); osync_error_unref(&error); return 1; } osync_member_set_config(member, config, size); } osync_member_set_pluginname(member, pluginname); OSyncMember *file = osync_member_new(group); localdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir()); result = mkdtemp(localdir); if (result == NULL) { osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno)); return 1; } config = g_strdup_printf("<config><path>%s</path><recursive>0</recursive></config>", localdir); osync_member_set_config(file, config, strlen(config) + 1); osync_member_set_pluginname(file, "file-sync"); if (!osync_group_save(group, &error)) { printf("Error while creating syncengine: %s\n", osync_error_print(&error)); osync_error_unref(&error); goto error_free_env; } if (!g_thread_supported ()) g_thread_init (NULL); OSyncEngine *engine = osengine_new(group, &error); if (!engine) { printf("Error while creating syncengine: %s\n", osync_error_print(&error)); osync_error_unref(&error); goto error_free_env; } if (!osengine_init(engine, &error)) { printf("Error while initializing syncengine: %s\n", osync_error_print(&error)); osync_error_unref(&error); goto error_free_engine; } int count = 0; if (only_random) { do { count++; printf("++++++++++++++++++++++++++++++\n"); printf("Initializing new round #%i!\n", count); if (g_random_int_range(0, 5) == 0) { int i; OSyncFormatEnv *env = osync_group_get_format_env(group); for (i = 0; i < osync_conv_num_objtypes(env); i++) { if (g_random_int_range(0, 5) == 0) { OSyncObjType *type = osync_conv_nth_objtype(env, i); osync_group_set_slow_sync(group, osync_objtype_get_name(type), TRUE); printf("Requesting slow-sync for: %s\n", osync_objtype_get_name(type)); } } osync_conv_env_free(env); } change_content(); check_sync(engine, "Random", 1); } while (g_random_int_range(0, 3) != 0); printf("Finalizing engine\n"); osengine_finalize(engine); osengine_free(engine); engine = osengine_new(group, &error); if (!engine) { printf("Error while creating syncengine: %s\n", osync_error_print(&error)); osync_error_unref(&error); goto error_free_env; } if (!osengine_init(engine, &error)) { printf("Error while initializing syncengine: %s\n", osync_error_print(&error)); osync_error_unref(&error); goto error_free_engine; } } else { register_tests(); run_all_tests(engine, file, member, objtype); } printf("\nCompleted successfully\n"); return 0; error_free_engine: osengine_free(engine); error_free_env: osync_group_free(group); osync_env_free(env); return 1; }