osync_bool osync_xml_open_file(xmlDocPtr *doc, xmlNodePtr *cur, const char *path, const char *topentry, OSyncError **error) { if (!g_file_test(path, G_FILE_TEST_EXISTS)) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "File %s does not exist", path); return FALSE; } *doc = xmlParseFile(path); if (!*doc) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Could not open: %s", path); goto error; } *cur = xmlDocGetRootElement(*doc); if (!*cur) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "%s seems to be empty", path); goto error_free_doc; } if (xmlStrcmp((*cur)->name, (const xmlChar *) topentry)) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "%s seems not to be a valid configfile.\n", path); goto error_free_doc; } *cur = (*cur)->xmlChildrenNode; return TRUE; error_free_doc: osync_xml_free_doc(*doc); error: osync_trace(TRACE_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; }
/*! @brief Check if group configuration is up to date. * * @param group The group * @returns TRUE if the group configuration is up to date, FALSE otherwise. */ osync_bool osync_group_is_uptodate(OSyncGroup *group) { xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; OSyncError *error = NULL; unsigned int version_major; unsigned int version_minor; xmlChar *version_str = NULL; osync_bool uptodate = FALSE; char *config = NULL; const char *configdir = NULL; osync_assert(group); osync_trace(TRACE_ENTRY, "%s(%p)", __func__, group); configdir = osync_group_get_configdir(group); if (!configdir){ osync_trace(TRACE_EXIT, "%s(%p) - No configdir set", __func__, group); return FALSE; } config = g_strdup_printf("%s%c%s", configdir, G_DIR_SEPARATOR, "syncgroup.conf"); /* If syncgroup isn't present, we assume that update is required. */ if (!osync_xml_open_file(&doc, &cur, config, "syncgroup", &error)) { osync_trace(TRACE_ERROR, "%s: %s", __func__, osync_error_print(&error)); osync_error_unref(&error); goto end; } version_str = xmlGetProp(cur->parent, (const xmlChar *)"version"); /* No version node, means very outdated version. */ if (!version_str) goto end; sscanf((const char *) version_str, "%u.%u", &version_major, &version_minor); osync_trace(TRACE_INTERNAL, "Version: %s (current %u.%u required %u.%u)", version_str, version_major, version_minor, OSYNC_GROUP_MAJOR_VERSION, OSYNC_GROUP_MINOR_VERSION ); if (OSYNC_GROUP_MAJOR_VERSION == version_major && OSYNC_GROUP_MINOR_VERSION == version_minor) uptodate = TRUE; osync_xml_free(version_str); end: g_free(config); if (doc) osync_xml_free_doc(doc); osync_trace(TRACE_EXIT, "%s(%p)", __func__, group); return uptodate; }
osync_bool osync_capabilities_assemble(OSyncCapabilities *capabilities, char **buffer, unsigned int *size, OSyncError **error) { xmlDocPtr doc = NULL; xmlNodePtr root; char *version_str; const char *capsformat; OSyncList *l; osync_assert(capabilities); capsformat = osync_capabilities_get_format(capabilities); if (!capsformat) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Can't assamble capabilities: Capabilities Format not set."); goto error; } if (capabilities->doc) osync_xml_free_doc(capabilities->doc); capabilities->doc = doc = xmlNewDoc(BAD_CAST "1.0"); capabilities->doc->children = xmlNewDocNode(capabilities->doc, NULL, (xmlChar *)"Caps", NULL); capabilities->doc->_private = capabilities; /* Set version for capabilities configuration */ version_str = osync_strdup_printf("%u.%u", OSYNC_CAPS_MAJOR_VERSION, OSYNC_CAPS_MINOR_VERSION); xmlSetProp(doc->children, (const xmlChar*)"Version", (const xmlChar *)version_str); osync_free(version_str); /* Set CapsFormat Name */ xmlSetProp(doc->children, (const xmlChar*)"CapsFormat", (const xmlChar *)capsformat); root = doc->children; for (l = capabilities->objtypes; l; l = l->next) { OSyncCapabilitiesObjType *capobjtype; capobjtype = (OSyncCapabilitiesObjType *) l->data; if (!osync_capabilities_objtype_assemble(capobjtype, root, error)) goto error; } /* XXX Ugly cast, but we try to fit here the opensync API pattern of unsigned size/length types */ xmlDocDumpFormatMemoryEnc(doc, (xmlChar **) buffer, (int *) size, NULL, 1); return TRUE; /* error_oom: osync_error_set(error, OSYNC_ERROR_GENERIC, "Couldn't allocate memory to assemble capabilities file."); */ error: osync_trace(TRACE_EXIT_ERROR, "%s: %s" , __func__, osync_error_print(error)); return FALSE; }
void osync_capabilities_unref(OSyncCapabilities *caps) { osync_assert(caps); if (g_atomic_int_dec_and_test(&(caps->ref_count))) { while (caps->objtypes) { osync_capabilities_objtype_unref(caps->objtypes->data); caps->objtypes = osync_list_remove(caps->objtypes, caps->objtypes->data); } osync_free(caps->format); osync_xml_free_doc(caps->doc); osync_free(caps); } }
void osync_xmlformat_unref(OSyncXMLFormat *xmlformat) { osync_assert(xmlformat); if (g_atomic_int_dec_and_test(&(xmlformat->ref_count))) { OSyncXMLField *cur, *tmp; cur = xmlformat->first_child; while(cur != NULL) { tmp = osync_xmlfield_get_next(cur); osync_xmlfield_delete(cur); cur = tmp; } osync_xml_free_doc(xmlformat->doc); g_free(xmlformat); } }
/*! @brief Loads a group from a directory * * Loads a group from a directory * * @param group The group object to load into * @param path The path to the config directory of the group * @param error Pointer to an error struct * @returns TRUE on success, FALSE otherwise * */ osync_bool osync_group_load(OSyncGroup *group, const char *path, OSyncError **error) { char *filename = NULL; char *real_path = NULL; xmlDocPtr doc; xmlNodePtr cur; //xmlNodePtr filternode; osync_assert(group); osync_assert(path); osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, group, path, error); if (!g_path_is_absolute(path)) { char *curdir = g_get_current_dir(); real_path = g_strdup_printf("%s%c%s", curdir, G_DIR_SEPARATOR, path); g_free(curdir); } else { real_path = g_strdup(path); } osync_group_set_configdir(group, real_path); filename = g_strdup_printf("%s%csyncgroup.conf", real_path, G_DIR_SEPARATOR); g_free(real_path); if (!osync_xml_open_file(&doc, &cur, filename, "syncgroup", error)) { g_free(filename); goto error; } g_free(filename); while (cur != NULL) { char *str = (char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (str) { if (!xmlStrcmp(cur->name, (const xmlChar *)"groupname")) osync_group_set_name(group, str); if (!xmlStrcmp(cur->name, (const xmlChar *)"last_sync")) group->last_sync = (time_t)atoi(str); //TODO: remove the next 2 lines later if (!xmlStrcmp(cur->name, (const xmlChar *)"enable_merger")) group->merger_enabled = (!g_ascii_strcasecmp("true", str)) ? TRUE : FALSE; //TODO: remove the next 2 lines later if (!xmlStrcmp(cur->name, (const xmlChar *)"enable_converter")) group->converter_enabled = (!g_ascii_strcasecmp("true", str)) ? TRUE : FALSE; if (!xmlStrcmp(cur->name, (const xmlChar *)"merger_enabled")) group->merger_enabled = (!g_ascii_strcasecmp("true", str)) ? TRUE : FALSE; if (!xmlStrcmp(cur->name, (const xmlChar *)"converter_enabled")) group->converter_enabled = (!g_ascii_strcasecmp("true", str)) ? TRUE : FALSE; // TODO: reimplement the filter! /*if (!xmlStrcmp(cur->name, (const xmlChar *)"filter")) { filternode = cur->xmlChildrenNode; OSyncFilter *filter = osync_filter_new(); filter->group = group; while (filternode != NULL) { if (!xmlStrcmp(filternode->name, (const xmlChar *)"sourceobjtype")) filter->sourceobjtype = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!xmlStrcmp(filternode->name, (const xmlChar *)"destobjtype")) filter->destobjtype = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!xmlStrcmp(filternode->name, (const xmlChar *)"detectobjtype")) filter->detectobjtype = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!xmlStrcmp(filternode->name, (const xmlChar *)"config")) filter->config = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!xmlStrcmp(filternode->name, (const xmlChar *)"function_name")) { char *str = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!str) { filternode = filternode->next; continue; } osync_filter_update_hook(filter, group, str); osync_xml_free(str); } if (!xmlStrcmp(filternode->name, (const xmlChar *)"sourcemember")) { char *str = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!str) { filternode = filternode->next; continue; } filter->sourcememberid = atoll(str); osync_xml_free(str); } if (!xmlStrcmp(filternode->name, (const xmlChar *)"destmember")) { char *str = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!str) { filternode = filternode->next; continue; } filter->destmemberid = atoll(str); osync_xml_free(str); } if (!xmlStrcmp(filternode->name, (const xmlChar *)"action")) { char *str = (char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1); if (!str) { filternode = filternode->next; continue; } filter->action = atoi(str); osync_xml_free(str); } filternode = filternode->next; } osync_filter_register(group, filter); }*/ osync_xml_free(str); } cur = cur->next; } osync_xml_free_doc(doc); /* Check for sanity */ if (!group->name) { osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION, "Loaded a group without a name"); goto error; } if (!_osync_group_load_members(group, group->configdir, error)) goto error; osync_trace(TRACE_EXIT, "%s: %p", __func__, group); return TRUE; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; }
/*! @brief Saves the group to disc * * Saves the group to disc possibly creating the configdirectory * * @param group The group * @param error Pointer to an error struct * @returns TRUE on success, FALSE otherwise * */ osync_bool osync_group_save(OSyncGroup *group, OSyncError **error) { char *filename = NULL; int i; xmlDocPtr doc; char *tmstr = NULL; char *version_str = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, group, error); osync_assert(group); osync_assert(group->configdir); osync_trace(TRACE_INTERNAL, "Trying to open configdirectory %s to save group %s", group->configdir, group->name); if (!g_file_test(group->configdir, G_FILE_TEST_IS_DIR)) { osync_trace(TRACE_INTERNAL, "Creating group configdirectory %s", group->configdir); if (g_mkdir(group->configdir, 0700)) { osync_error_set(error, OSYNC_ERROR_IO_ERROR, "Unable to create directory for group %s\n", group->name); goto error; } } filename = g_strdup_printf ("%s%csyncgroup.conf", group->configdir, G_DIR_SEPARATOR); osync_trace(TRACE_INTERNAL, "Saving group to file %s", filename); doc = xmlNewDoc((xmlChar*)"1.0"); doc->children = xmlNewDocNode(doc, NULL, (xmlChar*)"syncgroup", NULL); version_str = g_strdup_printf("%u.%u", OSYNC_GROUP_MAJOR_VERSION, OSYNC_GROUP_MINOR_VERSION); xmlSetProp(doc->children, (const xmlChar*)"version", (const xmlChar *)version_str); g_free(version_str); // TODO: reimplement the filter! //The filters /*GList *f; for (f = group->filters; f; f = f->next) { OSyncFilter *filter = f->data; xmlNodePtr child = xmlNewChild(doc->children, NULL, (xmlChar*)"filter", NULL); if (filter->sourcememberid) { char *sourcememberid = g_strdup_printf("%lli", filter->sourcememberid); xmlNewChild(child, NULL, (xmlChar*)"sourcemember", (xmlChar*)sourcememberid); g_free(sourcememberid); } if (filter->destmemberid) { char *destmemberid = g_strdup_printf("%lli", filter->destmemberid); xmlNewChild(child, NULL, (xmlChar*)"destmember", (xmlChar*)destmemberid); g_free(destmemberid); } if (filter->sourceobjtype) xmlNewChild(child, NULL, (xmlChar*)"sourceobjtype", (xmlChar*)filter->sourceobjtype); if (filter->destobjtype) xmlNewChild(child, NULL, (xmlChar*)"destobjtype", (xmlChar*)filter->destobjtype); if (filter->detectobjtype) xmlNewChild(child, NULL, (xmlChar*)"detectobjtype", (xmlChar*)filter->detectobjtype); if (filter->action) { char *action = g_strdup_printf("%i", filter->action); xmlNewChild(child, NULL, (xmlChar*)"action", (xmlChar*)action); g_free(action); } if (filter->function_name) xmlNewChild(child, NULL, (xmlChar*)"function_name", (xmlChar*)filter->function_name); if (filter->config) xmlNewChild(child, NULL, (xmlChar*)"config", (xmlChar*)filter->config); }*/ xmlNewChild(doc->children, NULL, (xmlChar*)"groupname", (xmlChar*)group->name); tmstr = g_strdup_printf("%i", (int)group->last_sync); xmlNewChild(doc->children, NULL, (xmlChar*)"last_sync", (xmlChar*)tmstr); g_free(tmstr); xmlNewChild(doc->children, NULL, (xmlChar*)"merger_enabled", (xmlChar*) (group->merger_enabled ? "true" : "false")); xmlNewChild(doc->children, NULL, (xmlChar*)"converter_enabled", (xmlChar*) (group->converter_enabled ? "true" : "false")); xmlSaveFormatFile(filename, doc, 1); osync_xml_free_doc(doc); g_free(filename); for (i = 0; i < osync_group_num_members(group); i++) { OSyncMember *member = osync_group_nth_member(group, i); if (!osync_member_save(member, error)) goto error; } osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; }
OSyncConvCmpResult osync_xml_compare(xmlDoc *leftinpdoc, xmlDoc *rightinpdoc, OSyncXMLScore *scores, int default_score, int treshold) { int z = 0, i = 0, n = 0; int res_score = 0; xmlDoc *leftdoc = NULL; xmlDoc *rightdoc = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, leftinpdoc, rightinpdoc, scores); leftdoc = xmlCopyDoc(leftinpdoc, TRUE); rightdoc = xmlCopyDoc(rightinpdoc, TRUE); osync_trace(TRACE_INTERNAL, "Comparing given score list"); while (scores && scores[z].path) { OSyncXMLScore *score = &scores[z]; xmlXPathObject *leftxobj = osync_xml_get_nodeset(leftdoc, score->path); xmlXPathObject *rightxobj = osync_xml_get_nodeset(rightdoc, score->path); xmlNodeSet *lnodes = leftxobj->nodesetval; xmlNodeSet *rnodes = rightxobj->nodesetval; int lsize = (lnodes) ? lnodes->nodeNr : 0; int rsize = (rnodes) ? rnodes->nodeNr : 0; z++; osync_trace(TRACE_INTERNAL, "parsing next path %s", score->path); if (!score->value) { for (i = 0; i < lsize; i++) { xmlUnlinkNode(lnodes->nodeTab[i]); xmlFreeNode(lnodes->nodeTab[i]); lnodes->nodeTab[i] = NULL; } for (n = 0; n < rsize; n++) { xmlUnlinkNode(rnodes->nodeTab[n]); xmlFreeNode(rnodes->nodeTab[n]); rnodes->nodeTab[n] = NULL; } } else { for (i = 0; i < lsize; i++) { if (!lnodes->nodeTab[i]) continue; for (n = 0; n < rsize; n++) { xmlChar *lcontent = NULL; xmlChar *rcontent = NULL; if (!rnodes->nodeTab[n]) continue; lcontent = osync_xml_find_node(lnodes->nodeTab[i], "Content"); rcontent = osync_xml_find_node(rnodes->nodeTab[n], "Content"); osync_trace(TRACE_INTERNAL, "cmp %i:%s (%s), %i:%s (%s)", i, lnodes->nodeTab[i]->name, lcontent, n, rnodes->nodeTab[n]->name, rcontent); xmlFree(lcontent); xmlFree(rcontent); if (osync_xml_compare_node(lnodes->nodeTab[i], rnodes->nodeTab[n])) { osync_trace(TRACE_INTERNAL, "Adding %i for %s", score->value, score->path); res_score += score->value; xmlUnlinkNode(lnodes->nodeTab[i]); xmlFreeNode(lnodes->nodeTab[i]); lnodes->nodeTab[i] = NULL; xmlUnlinkNode(rnodes->nodeTab[n]); xmlFreeNode(rnodes->nodeTab[n]); rnodes->nodeTab[n] = NULL; goto next; } } osync_trace(TRACE_INTERNAL, "Subtracting %i for %s", score->value, score->path); res_score -= score->value; next:; } for(i = 0; i < rsize; i++) { if (!rnodes->nodeTab[i]) continue; res_score -= score->value; } } xmlXPathFreeObject(leftxobj); xmlXPathFreeObject(rightxobj); } { /* Block for new variables */ xmlXPathObject *leftxobj = osync_xml_get_nodeset(leftdoc, "/*/*"); xmlXPathObject *rightxobj = osync_xml_get_nodeset(rightdoc, "/*/*"); xmlNodeSet *lnodes = leftxobj->nodesetval; xmlNodeSet *rnodes = rightxobj->nodesetval; int lsize = (lnodes) ? lnodes->nodeNr : 0; int rsize = (rnodes) ? rnodes->nodeNr : 0; osync_bool same = TRUE; osync_trace(TRACE_INTERNAL, "Comparing remaining list"); for(i = 0; i < lsize; i++) { for (n = 0; n < rsize; n++) { xmlChar *lcontent = NULL; xmlChar *rcontent = NULL; if (!rnodes->nodeTab[n]) continue; lcontent = osync_xml_find_node(lnodes->nodeTab[i], "Content"); rcontent = osync_xml_find_node(rnodes->nodeTab[n], "Content"); osync_trace(TRACE_INTERNAL, "cmp %i:%s (%s), %i:%s (%s)", i, lnodes->nodeTab[i]->name, lcontent, n, rnodes->nodeTab[n]->name, rcontent); xmlFree(lcontent); xmlFree(rcontent); if (osync_xml_compare_node(lnodes->nodeTab[i], rnodes->nodeTab[n])) { xmlUnlinkNode(lnodes->nodeTab[i]); xmlFreeNode(lnodes->nodeTab[i]); lnodes->nodeTab[i] = NULL; xmlUnlinkNode(rnodes->nodeTab[n]); xmlFreeNode(rnodes->nodeTab[n]); rnodes->nodeTab[n] = NULL; osync_trace(TRACE_INTERNAL, "Adding %i", default_score); res_score += default_score; goto next2; } } osync_trace(TRACE_INTERNAL, "Subtracting %i", default_score); res_score -= default_score; same = FALSE; //goto out; next2:; } for(i = 0; i < lsize; i++) { if (!lnodes->nodeTab[i]) continue; osync_trace(TRACE_INTERNAL, "left remaining: %s", lnodes->nodeTab[i]->name); same = FALSE; goto out; } for(i = 0; i < rsize; i++) { if (!rnodes->nodeTab[i]) continue; osync_trace(TRACE_INTERNAL, "right remaining: %s", rnodes->nodeTab[i]->name); same = FALSE; goto out; } out: xmlXPathFreeObject(leftxobj); xmlXPathFreeObject(rightxobj); osync_xml_free_doc(leftdoc); osync_xml_free_doc(rightdoc); osync_trace(TRACE_INTERNAL, "Result is: %i, Treshold is: %i", res_score, treshold); if (same) { osync_trace(TRACE_EXIT, "%s: SAME", __func__); return OSYNC_CONV_DATA_SAME; } } /* Block for new variables */ if (res_score >= treshold) { osync_trace(TRACE_EXIT, "%s: SIMILAR", __func__); return OSYNC_CONV_DATA_SIMILAR; } osync_trace(TRACE_EXIT, "%s: MISMATCH", __func__); return OSYNC_CONV_DATA_MISMATCH; }
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; }