summaryrefslogtreecommitdiffstats
path: root/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c')
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c
new file mode 100644
index 00000000..f1583bb8
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c
@@ -0,0 +1,406 @@
+/*
+ * xml - A plugin for xml objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "opensync/opensync.h"
+#include "opensync/opensync_time_internals.h"
+#include "xml-support.h"
+#include <glib.h>
+
+static char *osxml_prepare_time(const char *content, xmlNode *node) {
+
+ osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, content, node);
+
+ int tzoffset = 0;
+ char *time = NULL;
+ struct tm *ttm = NULL;
+
+
+ if (!osync_time_isutc(content)) {
+ time = osync_time_tzlocal2utc(node, (char *) node->name);
+ if (!time) {
+ ttm = osync_time_vtime2tm(content);
+ tzoffset = osync_time_timezone_diff(ttm);
+ time = osync_time_vtime2utc(content, tzoffset);
+ g_free(ttm);
+ }
+ }
+
+ if (!time)
+ time = g_strdup(content);
+
+ osync_trace(TRACE_EXIT, "%s: %s", __func__, time);
+ return time;
+}
+
+static osync_bool osxml_compare_time(xmlNode *leftnode, xmlNode *rightnode) {
+
+ osync_trace(TRACE_ENTRY, "%s(%s(%p), %s(%p))", __func__, leftnode->name, leftnode, rightnode->name, rightnode);
+ int ret = 0;
+ char *left = NULL, *right = NULL;
+ char *leftcontent = osxml_find_node(leftnode, "Content");
+ char *rightcontent = osxml_find_node(rightnode, "Content");
+
+ osync_trace(TRACE_SENSITIVE, "time compare - left: %s right: %s", leftcontent, rightcontent);
+
+ if (osync_time_isutc(leftcontent) != osync_time_isutc(rightcontent)) {
+ left = osxml_prepare_time(leftcontent, leftnode);
+ right = osxml_prepare_time(rightcontent, rightnode);
+
+ g_free(leftcontent);
+ g_free(rightcontent);
+
+ osync_trace(TRACE_SENSITIVE, "AFTER convert - left: %s right: %s", left, right);
+ } else {
+ left = leftcontent;
+ right = rightcontent;
+ }
+
+ ret = strcmp(left, right);
+
+ g_free(left);
+ g_free(right);
+
+ if (ret) {
+ osync_trace(TRACE_EXIT, "%s: FALSE", __func__);
+ return FALSE;
+ }
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+
+}
+
+static osync_bool osxml_compare_node(xmlNode *leftnode, xmlNode *rightnode)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p:%s, %p:%s)", __func__, leftnode, leftnode->name, rightnode, rightnode->name);
+
+ if (strcmp((char*)leftnode->name, (char*)rightnode->name)) {
+ osync_trace(TRACE_EXIT, "%s: FALSE: Different Name", __func__);
+ return FALSE;
+ }
+
+ leftnode = leftnode->children;
+ rightnode = rightnode->children;
+ xmlNode *rightstartnode = rightnode;
+
+ if (!leftnode && !rightnode) {
+ osync_trace(TRACE_EXIT, "%s: TRUE. Both 0", __func__);
+ return TRUE;
+ }
+
+ if (!leftnode || !rightnode) {
+ osync_trace(TRACE_EXIT, "%s: FALSE. One 0", __func__);
+ return FALSE;
+ }
+
+ do {
+ if (!strcmp("UnknownParam", (char*)leftnode->name))
+ continue;
+ if (!strcmp("Order", (char*)leftnode->name))
+ continue;
+ rightnode = rightstartnode;
+ char *leftcontent = (char*)xmlNodeGetContent(leftnode);
+
+ do {
+ if (!strcmp("UnknownParam", (char*)rightnode->name))
+ continue;
+
+ osync_trace(TRACE_INTERNAL, "leftnode %s, rightnode %s", leftnode->name, rightnode->name);
+
+ /* Compare only nodes with same name. Skip if
+ * the names are different
+ */
+ if (xmlStrcmp(leftnode->name, rightnode->name))
+ continue;
+
+ char *rightcontent = (char*)xmlNodeGetContent(rightnode);
+
+ osync_trace(TRACE_SENSITIVE, "leftcontent %s, rightcontent %s\n", leftcontent, rightcontent);
+
+ if (leftcontent == rightcontent) {
+ g_free(rightcontent);
+ goto next;
+ }
+
+ /* We compare the striped content to work around bugs in
+ * applications like evo2 which always strip the content
+ * and would therefore cause conflicts. This change should not break
+ * anything since it does not touch the actual content */
+ char *strip_right = g_strstrip(g_strdup(rightcontent));
+ char *strip_left = g_strstrip(g_strdup(leftcontent));
+ if (!strcmp(strip_left, strip_right)) {
+ g_free(strip_right);
+ g_free(strip_left);
+ g_free(rightcontent);
+ goto next;
+ }
+ g_free(strip_right);
+ g_free(strip_left);
+
+ if (!leftcontent || !rightcontent) {
+ osync_trace(TRACE_EXIT, "%s: One is empty", __func__);
+ return FALSE;
+ }
+
+ /* Workaround for palm-sync. palm-sync is not able to set a correct Completed date-timestamp so ignore value (objtype: todo) */
+ if (!strcmp("Completed", (char*)rightnode->name) && !strcmp("Completed",(char*)leftnode->name)) {
+ if ((leftcontent && rightcontent) || (!leftcontent && !rightcontent)) {
+ osync_trace(TRACE_INTERNAL, "PALM-SYNC workaround active!");
+ g_free(rightcontent);
+ goto next;
+ }
+ }
+
+
+ g_free(rightcontent);
+
+ if ((!strcmp("DateStarted", (char*)rightnode->name) && !strcmp("DateStarted", (char*)leftnode->name))
+ || (!strcmp("DateEnd", (char*)rightnode->name) && !strcmp("DateEnd", (char*)leftnode->name))) {
+
+ if (osxml_compare_time(leftnode, rightnode))
+ goto next;
+ }
+
+ /* compare child nodes again .... */
+ if (rightnode->type == XML_ELEMENT_NODE && osxml_compare_node(rightnode, leftnode))
+ goto next;
+
+
+ } while ((rightnode = rightnode->next));
+ osync_trace(TRACE_EXIT, "%s: Could not match one", __func__);
+ g_free(leftcontent);
+ return FALSE;
+ next:;
+ g_free(leftcontent);
+ } while ((leftnode = leftnode->next));
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+OSyncConvCmpResult osxml_compare(xmlDoc *leftinpdoc, xmlDoc *rightinpdoc, OSyncXMLScore *scores, int default_score, int treshold)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, leftinpdoc, rightinpdoc, scores);
+ int z = 0, i = 0, n = 0;
+ int res_score = 0;
+
+ xmlDoc *leftdoc = xmlCopyDoc(leftinpdoc, TRUE);
+ xmlDoc *rightdoc = xmlCopyDoc(rightinpdoc, TRUE);
+
+ osync_trace(TRACE_INTERNAL, "Comparing given score list");
+ while (scores && scores[z].path) {
+ OSyncXMLScore *score = &scores[z];
+ z++;
+ xmlXPathObject *leftxobj = osxml_get_nodeset(leftdoc, score->path);
+ xmlXPathObject *rightxobj = osxml_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;
+ 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++) {
+ if (!rnodes->nodeTab[n])
+ continue;
+ osync_trace(TRACE_INTERNAL, "cmp %i:%s (leftcontent), %i:%s (rightcontent)", i, lnodes->nodeTab[i]->name,
+ n, rnodes->nodeTab[n]->name);
+ osync_trace(TRACE_SENSITIVE, "cmp %i:%s (%s), %i:%s (%s)\n", i, lnodes->nodeTab[i]->name, osxml_find_node(lnodes->nodeTab[i],
+ "Content"), n, rnodes->nodeTab[n]->name, osxml_find_node(rnodes->nodeTab[n], "Content"));
+
+ /*
+ if ((!strcmp("DateStarted", lnodes->nodeTab[i]->name) && !strcmp("DateStarted", rnodes->nodeTab[n]->name))
+ || (!strcmp("DateEnd", lnodes->nodeTab[i]->name) && !strcmp("DateEnd", rnodes->nodeTab[n]->name))) {
+ */
+
+ if (osxml_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);
+ }
+
+ xmlXPathObject *leftxobj = osxml_get_nodeset(leftdoc, "/*/*");
+ xmlXPathObject *rightxobj = osxml_get_nodeset(rightdoc, "/*/*");
+
+ xmlNodeSet *lnodes = leftxobj->nodesetval;
+ xmlNodeSet *rnodes = rightxobj->nodesetval;
+
+ // Check if nodeTab actually exists (for example vnote stuff would crash otherwise...)
+ if (lnodes->nodeTab && rnodes->nodeTab) {
+ // WORKAROUND - FIXME
+ // if nodeTab[0] is an Event or Todo we need a new node structure (/*/*/*)
+
+ if ((!strcmp((char*)lnodes->nodeTab[0]->name, "Event") && \
+ !strcmp((char*)rnodes->nodeTab[0]->name, "Event")) || \
+ (!strcmp((char*)lnodes->nodeTab[0]->name, "Todo") && \
+ !strcmp((char*)rnodes->nodeTab[0]->name, "Todo"))) {
+
+ xmlXPathFreeObject(leftxobj);
+ xmlXPathFreeObject(rightxobj);
+
+ leftxobj = osxml_get_nodeset(leftdoc, "/*/*/*");
+ rightxobj = osxml_get_nodeset(rightdoc, "/*/*/*");
+
+ lnodes = leftxobj->nodesetval;
+ rnodes = rightxobj->nodesetval;
+
+ }
+ }
+
+ int lsize = (lnodes) ? lnodes->nodeNr : 0;
+ int rsize = (rnodes) ? rnodes->nodeNr : 0;
+
+ osync_trace(TRACE_INTERNAL, "Comparing remaining list");
+ osync_bool same = TRUE;
+ for(i = 0; i < lsize; i++) {
+ for (n = 0; n < rsize; n++) {
+ if (!rnodes->nodeTab[n])
+ continue;
+ osync_trace(TRACE_INTERNAL, "cmp %i:%s (leftcontent), %i:%s (rightcontent)", i, lnodes->nodeTab[i]->name,
+ n, rnodes->nodeTab[n]->name);
+ osync_trace(TRACE_SENSITIVE, "cmp %i:%s (%s), %i:%s (%s)\n", i, lnodes->nodeTab[i]->name, osxml_find_node(lnodes->nodeTab[i],
+ "Content"), n, rnodes->nodeTab[n]->name, osxml_find_node(rnodes->nodeTab[n], "Content"));
+
+ if ((!strcmp("DateStarted", (char *) lnodes->nodeTab[i]->name) && !strcmp("DateStarted", (char *) rnodes->nodeTab[n]->name))
+ || (!strcmp("DateEnd", (char *) lnodes->nodeTab[i]->name) && !strcmp("DateEnd", (char *) rnodes->nodeTab[n]->name))) {
+
+ if (osxml_compare_time(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;
+ }
+ }
+
+ if (osxml_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;
+
+ // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes.
+ if (!strcmp("Timezone", (char *) lnodes->nodeTab[i]->name))
+ osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML");
+ else
+ 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);
+
+ // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes.
+ if (!strcmp("Timezone", (char *) lnodes->nodeTab[i]->name))
+ osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML");
+ else
+ 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);
+
+ // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes.
+ if (!strcmp("Timezone", (char *) rnodes->nodeTab[i]->name))
+ osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML");
+ else
+ same = FALSE;
+
+ goto out;
+ }
+ out:
+ xmlXPathFreeObject(leftxobj);
+ xmlXPathFreeObject(rightxobj);
+
+ xmlFreeDoc(leftdoc);
+ xmlFreeDoc(rightdoc);
+
+ osync_trace(TRACE_INTERNAL, "Result is: %i, Treshold is: %i", res_score, treshold);
+ if (same) {
+ osync_trace(TRACE_EXIT, "%s: SAME", __func__);
+ return CONV_DATA_SAME;
+ }
+ if (res_score >= treshold) {
+ osync_trace(TRACE_EXIT, "%s: SIMILAR", __func__);
+ return CONV_DATA_SIMILAR;
+ }
+ osync_trace(TRACE_EXIT, "%s: MISMATCH", __func__);
+ return CONV_DATA_MISMATCH;
+}
+