summaryrefslogtreecommitdiffstats
path: root/debian/opensync/opensync-0.22/formats
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2020-09-11 14:38:47 +0900
committerMichele Calgaro <[email protected]>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/opensync/opensync-0.22/formats
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'debian/opensync/opensync-0.22/formats')
-rwxr-xr-xdebian/opensync/opensync-0.22/formats/Makefile.am38
-rw-r--r--debian/opensync/opensync-0.22/formats/Makefile.in697
-rw-r--r--debian/opensync/opensync-0.22/formats/contact.c102
-rw-r--r--debian/opensync/opensync-0.22/formats/data.c77
-rw-r--r--debian/opensync/opensync-0.22/formats/event.c86
-rw-r--r--debian/opensync/opensync-0.22/formats/file.c303
-rw-r--r--debian/opensync/opensync-0.22/formats/file.h43
-rw-r--r--debian/opensync/opensync-0.22/formats/note.c41
-rw-r--r--debian/opensync/opensync-0.22/formats/todo.c76
-rwxr-xr-xdebian/opensync/opensync-0.22/formats/vformats-xml/Makefile.am50
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.in637
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/opensync-xml-contact.h91
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.c472
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.h30
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/vformat.c2005
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/vformat.h155
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-evolution.c522
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-kde.c505
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c406
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.h29
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.c2547
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.h16
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.c1405
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.h11
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.c672
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.h11
-rw-r--r--debian/opensync/opensync-0.22/formats/vformats-xml/xmldoc.c76
27 files changed, 11103 insertions, 0 deletions
diff --git a/debian/opensync/opensync-0.22/formats/Makefile.am b/debian/opensync/opensync-0.22/formats/Makefile.am
new file mode 100755
index 00000000..0dc325e3
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/Makefile.am
@@ -0,0 +1,38 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CFLAGS = -Werror -DOPENSYNC_FORMATSDIR=\"@OPENSYNC_FORMATSDIR@\" -Wall @XML_CFLAGS@ @GCOV_CFLAGS@
+
+formatsdir=@OPENSYNC_FORMATSDIR@
+opensyncheaderdir=@OPENSYNC_HEADERDIR@
+
+opensyncheader_HEADERS = file.h
+
+INCLUDES = @PACKAGE_CFLAGS@ -I$(top_srcdir)
+
+formats_LTLIBRARIES = data.la event.la todo.la contact.la note.la file.la
+
+data_la_SOURCES = data.c
+data_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+data_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+event_la_SOURCES = event.c
+event_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+event_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+note_la_SOURCES = note.c
+note_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+note_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+todo_la_SOURCES = todo.c
+todo_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+todo_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+contact_la_SOURCES = contact.c
+contact_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+contact_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+file_la_SOURCES = file.c
+file_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+file_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+
+SUBDIRS = vformats-xml
diff --git a/debian/opensync/opensync-0.22/formats/Makefile.in b/debian/opensync/opensync-0.22/formats/Makefile.in
new file mode 100644
index 00000000..4882a8c6
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/Makefile.in
@@ -0,0 +1,697 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = formats
+DIST_COMMON = $(opensyncheader_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(formatsdir)" \
+ "$(DESTDIR)$(opensyncheaderdir)"
+formatsLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(formats_LTLIBRARIES)
+contact_la_DEPENDENCIES =
+am_contact_la_OBJECTS = contact.lo
+contact_la_OBJECTS = $(am_contact_la_OBJECTS)
+data_la_DEPENDENCIES =
+am_data_la_OBJECTS = data.lo
+data_la_OBJECTS = $(am_data_la_OBJECTS)
+event_la_DEPENDENCIES =
+am_event_la_OBJECTS = event.lo
+event_la_OBJECTS = $(am_event_la_OBJECTS)
+file_la_DEPENDENCIES =
+am_file_la_OBJECTS = file.lo
+file_la_OBJECTS = $(am_file_la_OBJECTS)
+note_la_DEPENDENCIES =
+am_note_la_OBJECTS = note.lo
+note_la_OBJECTS = $(am_note_la_OBJECTS)
+todo_la_DEPENDENCIES =
+am_todo_la_OBJECTS = todo.lo
+todo_la_OBJECTS = $(am_todo_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(contact_la_SOURCES) $(data_la_SOURCES) $(event_la_SOURCES) \
+ $(file_la_SOURCES) $(note_la_SOURCES) $(todo_la_SOURCES)
+DIST_SOURCES = $(contact_la_SOURCES) $(data_la_SOURCES) \
+ $(event_la_SOURCES) $(file_la_SOURCES) $(note_la_SOURCES) \
+ $(todo_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+opensyncheaderHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(opensyncheader_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_ENGINE = @BUILD_ENGINE@
+BUILD_ENGINE_FALSE = @BUILD_ENGINE_FALSE@
+BUILD_ENGINE_TRUE = @BUILD_ENGINE_TRUE@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_DEBUG = @ENABLE_DEBUG@
+ENABLE_PROF_FALSE = @ENABLE_PROF_FALSE@
+ENABLE_PROF_TRUE = @ENABLE_PROF_TRUE@
+ENABLE_TESTS_FALSE = @ENABLE_TESTS_FALSE@
+ENABLE_TESTS_TRUE = @ENABLE_TESTS_TRUE@
+ENABLE_TOOLS_FALSE = @ENABLE_TOOLS_FALSE@
+ENABLE_TOOLS_TRUE = @ENABLE_TOOLS_TRUE@
+ENABLE_TRACE = @ENABLE_TRACE@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LDFLAGS = @GCOV_LDFLAGS@
+GREP = @GREP@
+HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@
+HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+OPENSYNC_CONFIGDIR = @OPENSYNC_CONFIGDIR@
+OPENSYNC_ENGINEHEADERDIR = @OPENSYNC_ENGINEHEADERDIR@
+OPENSYNC_FORMATSDIR = @OPENSYNC_FORMATSDIR@
+OPENSYNC_HEADERDIR = @OPENSYNC_HEADERDIR@
+OPENSYNC_PLUGINDIR = @OPENSYNC_PLUGINDIR@
+OSPLUGIN = @OSPLUGIN@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_CFLAGS = @PACKAGE_CFLAGS@
+PACKAGE_LIBS = @PACKAGE_LIBS@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+VERSION = @VERSION@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_workaround_abs_builddir = @ac_workaround_abs_builddir@
+ac_workaround_abs_srcdir = @ac_workaround_abs_srcdir@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -Werror -DOPENSYNC_FORMATSDIR=\"@OPENSYNC_FORMATSDIR@\" -Wall @XML_CFLAGS@ @GCOV_CFLAGS@
+formatsdir = @OPENSYNC_FORMATSDIR@
+opensyncheaderdir = @OPENSYNC_HEADERDIR@
+opensyncheader_HEADERS = file.h
+INCLUDES = @PACKAGE_CFLAGS@ -I$(top_srcdir)
+formats_LTLIBRARIES = data.la event.la todo.la contact.la note.la file.la
+data_la_SOURCES = data.c
+data_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+data_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+event_la_SOURCES = event.c
+event_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+event_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+note_la_SOURCES = note.c
+note_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+note_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+todo_la_SOURCES = todo.c
+todo_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+todo_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+contact_la_SOURCES = contact.c
+contact_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+contact_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+file_la_SOURCES = file.c
+file_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+file_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+SUBDIRS = vformats-xml
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign formats/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign formats/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-formatsLTLIBRARIES: $(formats_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(formatsdir)" || $(mkdir_p) "$(DESTDIR)$(formatsdir)"
+ @list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(formatsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(formatsdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(formatsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(formatsdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-formatsLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(formatsdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(formatsdir)/$$p"; \
+ done
+
+clean-formatsLTLIBRARIES:
+ -test -z "$(formats_LTLIBRARIES)" || rm -f $(formats_LTLIBRARIES)
+ @list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+contact.la: $(contact_la_OBJECTS) $(contact_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(contact_la_LDFLAGS) $(contact_la_OBJECTS) $(contact_la_LIBADD) $(LIBS)
+data.la: $(data_la_OBJECTS) $(data_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(data_la_LDFLAGS) $(data_la_OBJECTS) $(data_la_LIBADD) $(LIBS)
+event.la: $(event_la_OBJECTS) $(event_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(event_la_LDFLAGS) $(event_la_OBJECTS) $(event_la_LIBADD) $(LIBS)
+file.la: $(file_la_OBJECTS) $(file_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(file_la_LDFLAGS) $(file_la_OBJECTS) $(file_la_LIBADD) $(LIBS)
+note.la: $(note_la_OBJECTS) $(note_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(note_la_LDFLAGS) $(note_la_OBJECTS) $(note_la_LIBADD) $(LIBS)
+todo.la: $(todo_la_OBJECTS) $(todo_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(todo_la_LDFLAGS) $(todo_la_OBJECTS) $(todo_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/contact.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/note.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/todo.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-opensyncheaderHEADERS: $(opensyncheader_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(opensyncheaderdir)" || $(mkdir_p) "$(DESTDIR)$(opensyncheaderdir)"
+ @list='$(opensyncheader_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(opensyncheaderHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(opensyncheaderdir)/$$f'"; \
+ $(opensyncheaderHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(opensyncheaderdir)/$$f"; \
+ done
+
+uninstall-opensyncheaderHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(opensyncheader_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(opensyncheaderdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(opensyncheaderdir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(formatsdir)" "$(DESTDIR)$(opensyncheaderdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-formatsLTLIBRARIES clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-formatsLTLIBRARIES \
+ install-opensyncheaderHEADERS
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-formatsLTLIBRARIES uninstall-info-am \
+ uninstall-opensyncheaderHEADERS
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
+ clean clean-formatsLTLIBRARIES clean-generic clean-libtool \
+ clean-recursive ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-recursive distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am \
+ install-formatsLTLIBRARIES install-info install-info-am \
+ install-man install-opensyncheaderHEADERS install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-formatsLTLIBRARIES uninstall-info-am \
+ uninstall-opensyncheaderHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/debian/opensync/opensync-0.22/formats/contact.c b/debian/opensync/opensync-0.22/formats/contact.c
new file mode 100644
index 00000000..ee549d20
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/contact.c
@@ -0,0 +1,102 @@
+/*
+ * contact - A plugin for contact objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 <glib.h>
+#include <opensync/opensync_support.h>
+#include <string.h>
+#include <stdio.h>
+
+static OSyncConvCmpResult compare_vcard(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ int leftinpsize = osync_change_get_datasize(leftchange);
+ char *leftinput = osync_change_get_data(leftchange);
+ int rightinpsize = osync_change_get_datasize(rightchange);
+ char *rightinput = osync_change_get_data(rightchange);
+
+ if (leftinpsize == rightinpsize) {
+ if (!memcmp(leftinput, rightinput, leftinpsize))
+ return CONV_DATA_SAME;
+ }
+
+ //Get the name of the contact and compare
+ //If the same, return SIMILAR
+
+ return CONV_DATA_MISMATCH;
+}
+
+static osync_bool detect_plain_as_vcard21(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCARD21", 3, "start: %s", __func__);
+
+ if (!data)
+ return FALSE;
+
+ return osync_pattern_match("*BEGIN:VCARD*VERSION:2.1*", data, size);
+}
+
+static osync_bool detect_plain_as_vcard30(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCARD30", 3, "start: %s", __func__);
+
+ if (!data)
+ return FALSE;
+
+ return osync_pattern_match("*BEGIN:VCARD*VERSION:3.0*", data, size);
+}
+
+static void create_vcard21(OSyncChange *change)
+{
+ char *vcard = g_strdup_printf("BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s;%s;;;\r\nEND:VCARD\r\n", osync_rand_str(10), osync_rand_str(10));
+ osync_change_set_data(change, vcard, strlen(vcard) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+
+static void create_vcard30(OSyncChange *change)
+{
+ char *vcard = g_strdup_printf("BEGIN:VCARD\r\nVERSION:3.0\r\nN:%s;%s;;;\r\nEND:VCARD\r\n", osync_rand_str(10), osync_rand_str(10));
+ osync_change_set_data(change, vcard, strlen(vcard) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+
+static OSyncFilterAction vcard_categories_filter(OSyncChange *change, char *config)
+{
+ //Check what categories are supported here.
+ return OSYNC_FILTER_IGNORE;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "contact");
+
+ osync_env_register_objformat(env, "contact", "vcard21");
+ osync_env_format_set_compare_func(env, "vcard21", compare_vcard);
+ osync_env_format_set_create_func(env, "vcard21", create_vcard21);
+ osync_env_register_detector(env, "plain", "vcard21", detect_plain_as_vcard21);
+ osync_env_register_filter_function(env, "vcard_categories_filter", "contact", "vcard21", vcard_categories_filter);
+
+ osync_env_register_objformat(env, "contact", "vcard30");
+ osync_env_format_set_compare_func(env, "vcard30", compare_vcard);
+ osync_env_format_set_create_func(env, "vcard30", create_vcard30);
+ osync_env_register_detector(env, "plain", "vcard30", detect_plain_as_vcard30);
+ osync_env_register_filter_function(env, "vcard_categories_filter", "contact", "vcard30", vcard_categories_filter);
+}
diff --git a/debian/opensync/opensync-0.22/formats/data.c b/debian/opensync/opensync-0.22/formats/data.c
new file mode 100644
index 00000000..95ef60b0
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/data.c
@@ -0,0 +1,77 @@
+/*
+ * data - A plugin for data objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#include <glib.h>
+
+/** @defgroup data_plain data/plain format
+ *
+ * Definition: pointer to a malloc()ed block of data, or a NULL
+ * pointer.
+ */
+
+/** data/plain comparison function
+ *
+ * The comparison function is a memcpy() on the data.
+ *
+ * @ingroup data_plain
+ */
+static OSyncConvCmpResult compare_plain(OSyncChange *a, OSyncChange *b)
+{
+ const char *d1 = osync_change_get_data(a);
+ const char *d2 = osync_change_get_data(b);
+ size_t s1 = osync_change_get_datasize(a);
+ size_t s2 = osync_change_get_datasize(b);
+
+ /* Consider empty block equal NULL pointers */
+ if (!s1) d1 = NULL;
+ if (!s2) d2 = NULL;
+
+ if (d1 && d2) {
+ int r = memcmp(d1, d2, s1 < s2 ? s1 : s2);
+ if (!r && s1 == s2)
+ return CONV_DATA_SAME;
+ else
+ return CONV_DATA_MISMATCH;
+ } else if (!d1 && !d2)
+ return CONV_DATA_SAME;
+ else
+ return CONV_DATA_MISMATCH;
+}
+
+static osync_bool copy_plain(const char *input, int inpsize, char **output, int *outpsize)
+{
+ char *r = g_malloc0(inpsize);
+
+ memcpy(r, input, inpsize);
+ *output = r;
+ *outpsize = inpsize;
+ return TRUE;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "data");
+ osync_env_register_objformat(env, "data", "plain");
+ osync_env_format_set_compare_func(env, "plain", compare_plain);
+ osync_env_format_set_copy_func(env, "plain", copy_plain);
+}
diff --git a/debian/opensync/opensync-0.22/formats/event.c b/debian/opensync/opensync-0.22/formats/event.c
new file mode 100644
index 00000000..e98db6e0
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/event.c
@@ -0,0 +1,86 @@
+/*
+ * event - A plugin for event objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 <glib.h>
+#include <opensync/opensync_support.h>
+#include <string.h>
+
+/** @defgroup event_vevent event/vevent data format
+ *
+ * The vevent data should be a malloc()ed block of data. See
+ * osync_env_format_set_malloced().
+ *
+ * It can be treated as a plain block of data. See
+ * osync_env_format_set_like().
+ */
+
+static OSyncConvCmpResult compare_vevent(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ /*FIXME: Implement me */
+ return CONV_DATA_MISMATCH;
+}
+
+static osync_bool detect_plain_as_vevent10(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCAL", 3, "start: %s", __func__);
+
+ return osync_pattern_match("*BEGIN:VCALENDAR*VERSION:1.0*BEGIN:VEVENT*", data, size);
+}
+
+static osync_bool detect_plain_as_vevent20(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCAL", 3, "start: %s", __func__);
+
+ return osync_pattern_match("*BEGIN:VCALENDAR*VERSION:2.0*BEGIN:VEVENT*", data, size);
+}
+
+static void create_event10(OSyncChange *change)
+{
+ char *vevent = g_strdup_printf("BEGIN:VCALENDAR\r\nPRODID:-//OpenSync//NONSGML OpenSync TestGenerator//EN\r\nVERSION:1.0\r\nBEGIN:VEVENT\r\nDTSTART:20050307T124500Z\r\nDTEND:20050307T130000Z\r\nSEQUENCE:0\r\nSUMMARY:%s\r\nEND:VEVENT\r\nEND:VCALENDAR", osync_rand_str(20));
+
+ osync_change_set_data(change, vevent, strlen(vevent) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(8));
+}
+
+static void create_event20(OSyncChange *change)
+{
+ char *vevent = g_strdup_printf("BEGIN:VCALENDAR\r\nPRODID:-//OpenSync//NONSGML OpenSync TestGenerator//EN\r\nVERSION:2.0\r\nBEGIN:VEVENT\r\nDTSTART:20050307T124500Z\r\nDTEND:20050307T130000Z\r\nSEQUENCE:0\r\nSUMMARY:%s\r\nEND:VEVENT\r\nEND:VCALENDAR", osync_rand_str(20));
+
+ osync_change_set_data(change, vevent, strlen(vevent) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(8));
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "event");
+
+ osync_env_register_objformat(env, "event", "vevent10");
+ osync_env_format_set_compare_func(env, "vevent10", compare_vevent);
+ osync_env_format_set_create_func(env, "vevent10", create_event10);
+ osync_env_register_detector(env, "plain", "vevent10", detect_plain_as_vevent10);
+
+ osync_env_register_objformat(env, "event", "vevent20");
+ osync_env_format_set_compare_func(env, "vevent20", compare_vevent);
+ osync_env_format_set_create_func(env, "vevent20", create_event20);
+ osync_env_register_detector(env, "plain", "vevent20", detect_plain_as_vevent20);
+}
diff --git a/debian/opensync/opensync-0.22/formats/file.c b/debian/opensync/opensync-0.22/formats/file.c
new file mode 100644
index 00000000..5742eb2d
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/file.c
@@ -0,0 +1,303 @@
+/*
+ * opensync - A plugin for file objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "file.h"
+#include <string.h>
+#include <glib.h>
+
+static OSyncConvCmpResult compare_file(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange);
+
+ fileFormat *leftfile = (fileFormat *)osync_change_get_data(leftchange);
+ fileFormat *rightfile = (fileFormat *)osync_change_get_data(rightchange);
+
+ osync_bool data_same = FALSE;
+ osync_bool path_same = FALSE;
+
+ if (!strcmp(osync_change_get_uid(leftchange), osync_change_get_uid(rightchange)))
+ path_same = TRUE;
+
+ osync_trace(TRACE_INTERNAL, "%i %i", leftfile->size, rightfile->size);
+
+ if (leftfile->size == rightfile->size) {
+ if (leftfile->data == rightfile->data) {
+ data_same = TRUE;
+ } else {
+ if (!memcmp(leftfile->data, rightfile->data, leftfile->size))
+ data_same = TRUE;
+ }
+ }
+
+ if (data_same && path_same) {
+ osync_trace(TRACE_EXIT, "%s: Same", __func__);
+ return CONV_DATA_SAME;
+ }
+ if (path_same) {
+ osync_trace(TRACE_EXIT, "%s: Similar", __func__);
+ return CONV_DATA_SIMILAR;
+ }
+
+ osync_trace(TRACE_EXIT, "%s: Mismatch", __func__);
+ return CONV_DATA_MISMATCH;
+}
+
+#ifdef STRESS_TEST
+static void create_file(OSyncChange *change)
+{
+ osync_debug("FILE", 4, "start: %s", __func__);
+ fileFormat *file_info = g_malloc0(sizeof(fileFormat));
+ int file_size = g_random_int_range(0, 1000);
+ osync_change_set_data(change, (char *)file_info, sizeof(fileFormat), TRUE);
+
+ file_info->data = g_malloc0(file_size * 105 * sizeof(char));
+ file_info->size = file_size * 100 * sizeof(char);
+
+ char *datap = file_info->data;
+ FILE *fd = fopen("/dev/urandom", "r");
+ if (fd) {
+ for (; file_size > 5; file_size--) {
+ fread(datap, 100, 1, fd);
+ datap += 100 * sizeof(char);
+ }
+ }
+ fclose(fd);
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+#endif
+
+static osync_bool conv_file_to_plain(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+ g_assert(inpsize == sizeof(fileFormat));
+ fileFormat *file = (fileFormat *)input;
+
+ *free_input = FALSE;
+ *output = file->data;
+ *outpsize = file->size;
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+}
+
+static osync_bool conv_plain_to_file(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+ fileFormat *file = osync_try_malloc0(sizeof(fileFormat), error);
+ if (!file)
+ goto error;
+
+ file->data = input;
+ file->size = inpsize;
+
+ *free_input = FALSE;
+ *output = (char *)file;
+ *outpsize = sizeof(*file);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+
+error:
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+}
+
+static osync_bool marshall_file(const char *input, int inpsize, char **output, int *outpsize, OSyncError **error)
+{
+ /* The marshall block will be a fileFormat struct, followed by the file data
+ *
+ * the 'data' field on fileFormat will be set to NULL
+ */
+
+ /* Get our input file struct */
+ g_assert(inpsize == sizeof(fileFormat));
+ fileFormat *file = (fileFormat*)input;
+
+ /* Allocate our block */
+ int osize = sizeof(fileFormat) + file->size;
+ char *out = osync_try_malloc0(osize, error);
+ if (!out)
+ goto error;
+
+
+ /* Get the pointers to the output data: */
+ /* fileFormat struct in the beginning */
+ fileFormat *outfile = (fileFormat*)out;
+ /* file data immediately after outfile */
+ char *outdata = ((char*)outfile) + sizeof(fileFormat);
+
+ /* Copy the data: */
+ /* file struct */
+ memcpy(outfile, file, sizeof(fileFormat));
+ outfile->data = NULL;
+
+ /* file data */
+ if (file->size > 0)
+ memcpy(outdata, file->data, file->size);
+
+ *output = out;
+ *outpsize = osize;
+ return TRUE;
+
+error:
+ return FALSE;
+}
+
+static osync_bool demarshall_file(const char *input, int inpsize, char **output, int *outpsize, OSyncError **error)
+{
+ /* Get file struct */
+ g_assert(inpsize >= sizeof(fileFormat));
+ fileFormat *file = (fileFormat*)input;
+
+ /* get file data */
+ g_assert(inpsize == sizeof(fileFormat) + file->size);
+ const char *filedata = input + sizeof(fileFormat);
+
+ fileFormat *newfile = osync_try_malloc0(sizeof(fileFormat), error);
+ if (!newfile)
+ goto error;
+
+ memcpy(newfile, file, sizeof(fileFormat));
+
+ if (file->size > 0) {
+ newfile->data = osync_try_malloc0(file->size, error);
+ if (!newfile->data)
+ goto error_free_file;
+
+ memcpy(newfile->data, filedata, file->size);
+ } else
+ newfile->data = NULL;
+
+ *output = (char*)newfile;
+ *outpsize = sizeof(fileFormat);
+ return TRUE;
+
+error_free_file:
+ g_free(newfile);
+error:
+ return FALSE;
+}
+
+static void destroy_file(char *input, size_t inpsize)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %i)", __func__, input, inpsize);
+ g_assert(inpsize == sizeof(fileFormat));
+ fileFormat *file = (fileFormat *)input;
+
+ g_free(file->data);
+ g_free(file);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void duplicate_file(OSyncChange *change)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, change);
+
+ char *newuid = g_strdup_printf ("%s-dupe", osync_change_get_uid(change));
+ osync_change_set_uid(change, newuid);
+ g_free(newuid);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static osync_bool copy_file(const char *input, int inpsize, char **output, int *outpsize)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %i, %p, %p)", __func__, input, inpsize, output, outpsize);
+
+ fileFormat *oldfile = (fileFormat *)input;
+ fileFormat *newfile = g_malloc0(sizeof(fileFormat));
+
+ newfile->groupid = oldfile->groupid;
+ newfile->mode = oldfile->mode;
+ newfile->userid = oldfile->userid;
+ newfile->size = oldfile->size;
+ newfile->last_mod = oldfile->last_mod;
+
+ if (oldfile->size) {
+ newfile->data = g_malloc0(oldfile->size);
+ memcpy(newfile->data, oldfile->data, oldfile->size);
+ }
+
+ *output = (char *)newfile;
+ *outpsize = inpsize;
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+}
+
+static void create_file(OSyncChange *change)
+{
+ osync_debug("FILE", 4, "start: %s", __func__);
+
+ fileFormat *newfile = g_malloc0(sizeof(fileFormat));
+
+ char *data = osync_rand_str(g_random_int_range(1, 100));
+ newfile->data = data;
+ newfile->size = strlen(data) + 1;
+
+ osync_change_set_data(change, (char *)newfile, sizeof(newfile), TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+
+static time_t revision_file(OSyncChange *change, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error);
+
+ fileFormat *filechange = (fileFormat *)osync_change_get_data(change);
+ time_t lastmod = filechange->last_mod;
+
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, lastmod);
+ return lastmod;
+}
+
+static char *print_file(OSyncChange *change)
+{
+ osync_debug("FILE", 4, "start: %s", __func__);
+ fileFormat *file = (fileFormat *)osync_change_get_data(change);
+
+ char *printable = g_strdup_printf ("File: %s\nSize: %i", osync_change_get_uid(change), file ? file->size : 0);
+ return printable;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "data");
+ osync_env_register_objformat(env, "data", "file");
+ osync_env_format_set_compare_func(env, "file", compare_file);
+ osync_env_format_set_duplicate_func(env, "file", duplicate_file);
+ osync_env_format_set_destroy_func(env, "file", destroy_file);
+ osync_env_format_set_print_func(env, "file", print_file);
+ osync_env_format_set_copy_func(env, "file", copy_file);
+ osync_env_format_set_create_func(env, "file", create_file);
+ osync_env_format_set_revision_func(env, "file", revision_file);
+
+ osync_env_format_set_marshall_func(env, "file", marshall_file);
+ osync_env_format_set_demarshall_func(env, "file", demarshall_file);
+
+#ifdef STRESS_TEST
+ osync_env_format_set_create_func(env, "file", create_file);
+#endif
+ osync_env_register_converter(env, CONVERTER_DECAP, "file", "plain", conv_file_to_plain);
+ osync_env_register_converter(env, CONVERTER_ENCAP, "plain", "file", conv_plain_to_file);
+}
diff --git a/debian/opensync/opensync-0.22/formats/file.h b/debian/opensync/opensync-0.22/formats/file.h
new file mode 100644
index 00000000..7f608fc8
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/file.h
@@ -0,0 +1,43 @@
+/*
+ * opensync - A file format for opensync
+ * Copyright (C) 2005 Armin Bauer <[email protected]>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ *
+ */
+
+#ifndef _FILE_H
+#define _FILE_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+typedef struct fileFormat {
+ /** The mode of this file. See man fstat for explanation */
+ mode_t mode;
+ /** The id of the user (owner) of this file */
+ uid_t userid;
+ /** The id of the owning group of this file */
+ gid_t groupid;
+ /** Time of the last modification */
+ time_t last_mod;
+ /** The file contents */
+ char *data;
+ /** The size of the file contents (without trailing /0) */
+ int size;
+} fileFormat;
+
+#endif //_FILE_H
diff --git a/debian/opensync/opensync-0.22/formats/note.c b/debian/opensync/opensync-0.22/formats/note.c
new file mode 100644
index 00000000..4a164374
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/note.c
@@ -0,0 +1,41 @@
+#include <opensync/opensync.h>
+#include <glib.h>
+#include <opensync/opensync_support.h>
+#include <stdio.h>
+#include <string.h>
+
+static osync_bool detect_plain_as_vnote(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VNOTE11", 3, "start: %s", __func__);
+
+ if (!data)
+ return FALSE;
+
+ return osync_pattern_match("*BEGIN:VNOTE*VERSION:1.1*", data, size);
+}
+
+static OSyncConvCmpResult compare_vnote(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ return CONV_DATA_MISMATCH;
+}
+
+static void create_vnote11(OSyncChange *change)
+{
+ char *vnote = g_strdup_printf("BEGIN:VNOTE\r\nVERSION:1.1\r\nBODY:%s\r\nSUMMARY:%s\r\nEND:VNOTE", osync_rand_str(20), osync_rand_str(6));
+
+ osync_change_set_data(change, vnote, strlen(vnote) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(8));
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "note");
+ osync_env_register_objformat(env, "note", "vnote11");
+ osync_env_register_detector(env, "plain", "vnote11", detect_plain_as_vnote);
+ osync_env_format_set_create_func(env, "vnote11", create_vnote11);
+ osync_env_format_set_compare_func(env, "vnote11", compare_vnote);
+
+ osync_env_register_objtype(env, "note");
+ osync_env_register_objformat(env, "note", "memo");
+}
diff --git a/debian/opensync/opensync-0.22/formats/todo.c b/debian/opensync/opensync-0.22/formats/todo.c
new file mode 100644
index 00000000..f59d84b8
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/todo.c
@@ -0,0 +1,76 @@
+/*
+ * todo - A plugin for todo objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 <glib.h>
+#include <opensync/opensync_support.h>
+#include <string.h>
+
+static OSyncConvCmpResult compare_vtodo(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ return CONV_DATA_MISMATCH;
+}
+
+static osync_bool detect_plain_as_vtodo10(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCAL", 3, "start: %s", __func__);
+
+ return osync_pattern_match("*BEGIN:VCALENDAR*VERSION:1.0*BEGIN:VTODO*", data, size);
+}
+
+static osync_bool detect_plain_as_vtodo20(OSyncFormatEnv *env, const char *data, int size)
+{
+ osync_debug("VCAL", 3, "start: %s", __func__);
+
+ return osync_pattern_match("*BEGIN:VCALENDAR*VERSION:2.0*BEGIN:VTODO*", data, size);
+}
+
+static void create_todo10(OSyncChange *change)
+{
+ char *vtodo = g_strdup_printf("BEGIN:VCALENDAR\r\nPRODID:-//OpenSync//NONSGML OpenSync TestGenerator//EN\r\nVERSION:1.0\r\nBEGIN:VTODO\r\nSUMMARY:%s\r\nEND:VTODO\r\nEND:VCALENDAR", osync_rand_str(20));
+
+ osync_change_set_data(change, vtodo, strlen(vtodo) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+
+static void create_todo20(OSyncChange *change)
+{
+ char *vtodo = g_strdup_printf("BEGIN:VCALENDAR\r\nPRODID:-//OpenSync//NONSGML OpenSync TestGenerator//EN\r\nVERSION:2.0\r\nBEGIN:VTODO\r\nSUMMARY:%s\r\nEND:VTODO\r\nEND:VCALENDAR", osync_rand_str(20));
+
+ osync_change_set_data(change, vtodo, strlen(vtodo) + 1, TRUE);
+ if (!osync_change_get_uid(change))
+ osync_change_set_uid(change, osync_rand_str(6));
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "todo");
+
+ osync_env_register_objformat(env, "todo", "vtodo10");
+ osync_env_format_set_compare_func(env, "vtodo10", compare_vtodo);
+ osync_env_format_set_create_func(env, "vtodo10", create_todo10);
+ osync_env_register_detector(env, "plain", "vtodo10", detect_plain_as_vtodo10);
+
+ osync_env_register_objformat(env, "todo", "vtodo20");
+ osync_env_format_set_compare_func(env, "vtodo20", compare_vtodo);
+ osync_env_format_set_create_func(env, "vtodo20", create_todo20);
+ osync_env_register_detector(env, "plain", "vtodo20", detect_plain_as_vtodo20);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.am b/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.am
new file mode 100755
index 00000000..39dbf385
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CFLAGS = -Werror -DOPENSYNC_FORMATSDIR=\"@OPENSYNC_FORMATSDIR@\" -Wall @XML_CFLAGS@ @GCOV_CFLAGS@
+
+formatsdir=@OPENSYNC_FORMATSDIR@
+opensyncheaderdir=@OPENSYNC_HEADERDIR@
+
+EXTRA_DIST = \
+ vformat.h \
+ xml-support.h \
+ vcalical.h \
+ xml-vcard.h \
+ xml-vcal.h \
+ xml-vnote.h
+
+opensyncheader_HEADERS = xml-support.h opensync-xml-contact.h
+
+INCLUDES = -I$(top_srcdir) @PACKAGE_CFLAGS@
+
+formats_LTLIBRARIES = xml-vcard.la xml-vcal.la xml-evolution.la xml-vnote.la xml-kde.la xmldoc.la
+
+lib_LTLIBRARIES = libopensync-xml.la
+
+xml_vcard_la_SOURCES = xml-vcard.c vformat.c
+xml_vcard_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vcard_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+xml_vcal_la_SOURCES = xml-vcal.c vformat.c vcalical.c
+xml_vcal_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vcal_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+xml_vnote_la_SOURCES = xml-vnote.c vformat.c
+xml_vnote_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vnote_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+xml_evolution_la_SOURCES = xml-evolution.c vformat.c
+xml_evolution_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_evolution_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+xml_kde_la_SOURCES = xml-kde.c vformat.c
+xml_kde_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_kde_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+xmldoc_la_SOURCES = xmldoc.c
+xmldoc_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xmldoc_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+
+libopensync_xml_la_SOURCES = xml-support.c
+libopensync_xml_la_LDFLAGS = @GCOV_LDFLAGS@
+libopensync_xml_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.in b/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.in
new file mode 100644
index 00000000..7ebdba9c
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/Makefile.in
@@ -0,0 +1,637 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = formats/vformats-xml
+DIST_COMMON = $(opensyncheader_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(formatsdir)" "$(DESTDIR)$(libdir)" \
+ "$(DESTDIR)$(opensyncheaderdir)"
+formatsLTLIBRARIES_INSTALL = $(INSTALL)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(formats_LTLIBRARIES) $(lib_LTLIBRARIES)
+libopensync_xml_la_DEPENDENCIES =
+am_libopensync_xml_la_OBJECTS = xml-support.lo
+libopensync_xml_la_OBJECTS = $(am_libopensync_xml_la_OBJECTS)
+xml_evolution_la_DEPENDENCIES = libopensync-xml.la
+am_xml_evolution_la_OBJECTS = xml-evolution.lo vformat.lo
+xml_evolution_la_OBJECTS = $(am_xml_evolution_la_OBJECTS)
+xml_kde_la_DEPENDENCIES = libopensync-xml.la
+am_xml_kde_la_OBJECTS = xml-kde.lo vformat.lo
+xml_kde_la_OBJECTS = $(am_xml_kde_la_OBJECTS)
+xml_vcal_la_DEPENDENCIES = libopensync-xml.la
+am_xml_vcal_la_OBJECTS = xml-vcal.lo vformat.lo vcalical.lo
+xml_vcal_la_OBJECTS = $(am_xml_vcal_la_OBJECTS)
+xml_vcard_la_DEPENDENCIES = libopensync-xml.la
+am_xml_vcard_la_OBJECTS = xml-vcard.lo vformat.lo
+xml_vcard_la_OBJECTS = $(am_xml_vcard_la_OBJECTS)
+xml_vnote_la_DEPENDENCIES = libopensync-xml.la
+am_xml_vnote_la_OBJECTS = xml-vnote.lo vformat.lo
+xml_vnote_la_OBJECTS = $(am_xml_vnote_la_OBJECTS)
+xmldoc_la_DEPENDENCIES = libopensync-xml.la
+am_xmldoc_la_OBJECTS = xmldoc.lo
+xmldoc_la_OBJECTS = $(am_xmldoc_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libopensync_xml_la_SOURCES) $(xml_evolution_la_SOURCES) \
+ $(xml_kde_la_SOURCES) $(xml_vcal_la_SOURCES) \
+ $(xml_vcard_la_SOURCES) $(xml_vnote_la_SOURCES) \
+ $(xmldoc_la_SOURCES)
+DIST_SOURCES = $(libopensync_xml_la_SOURCES) \
+ $(xml_evolution_la_SOURCES) $(xml_kde_la_SOURCES) \
+ $(xml_vcal_la_SOURCES) $(xml_vcard_la_SOURCES) \
+ $(xml_vnote_la_SOURCES) $(xmldoc_la_SOURCES)
+opensyncheaderHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(opensyncheader_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_ENGINE = @BUILD_ENGINE@
+BUILD_ENGINE_FALSE = @BUILD_ENGINE_FALSE@
+BUILD_ENGINE_TRUE = @BUILD_ENGINE_TRUE@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_DEBUG = @ENABLE_DEBUG@
+ENABLE_PROF_FALSE = @ENABLE_PROF_FALSE@
+ENABLE_PROF_TRUE = @ENABLE_PROF_TRUE@
+ENABLE_TESTS_FALSE = @ENABLE_TESTS_FALSE@
+ENABLE_TESTS_TRUE = @ENABLE_TESTS_TRUE@
+ENABLE_TOOLS_FALSE = @ENABLE_TOOLS_FALSE@
+ENABLE_TOOLS_TRUE = @ENABLE_TOOLS_TRUE@
+ENABLE_TRACE = @ENABLE_TRACE@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LDFLAGS = @GCOV_LDFLAGS@
+GREP = @GREP@
+HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@
+HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+OPENSYNC_CONFIGDIR = @OPENSYNC_CONFIGDIR@
+OPENSYNC_ENGINEHEADERDIR = @OPENSYNC_ENGINEHEADERDIR@
+OPENSYNC_FORMATSDIR = @OPENSYNC_FORMATSDIR@
+OPENSYNC_HEADERDIR = @OPENSYNC_HEADERDIR@
+OPENSYNC_PLUGINDIR = @OPENSYNC_PLUGINDIR@
+OSPLUGIN = @OSPLUGIN@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_CFLAGS = @PACKAGE_CFLAGS@
+PACKAGE_LIBS = @PACKAGE_LIBS@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+SWIG_LIB = @SWIG_LIB@
+SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@
+SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
+VERSION = @VERSION@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_workaround_abs_builddir = @ac_workaround_abs_builddir@
+ac_workaround_abs_srcdir = @ac_workaround_abs_srcdir@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -Werror -DOPENSYNC_FORMATSDIR=\"@OPENSYNC_FORMATSDIR@\" -Wall @XML_CFLAGS@ @GCOV_CFLAGS@
+formatsdir = @OPENSYNC_FORMATSDIR@
+opensyncheaderdir = @OPENSYNC_HEADERDIR@
+EXTRA_DIST = \
+ vformat.h \
+ xml-support.h \
+ vcalical.h \
+ xml-vcard.h \
+ xml-vcal.h \
+ xml-vnote.h
+
+opensyncheader_HEADERS = xml-support.h opensync-xml-contact.h
+INCLUDES = -I$(top_srcdir) @PACKAGE_CFLAGS@
+formats_LTLIBRARIES = xml-vcard.la xml-vcal.la xml-evolution.la xml-vnote.la xml-kde.la xmldoc.la
+lib_LTLIBRARIES = libopensync-xml.la
+xml_vcard_la_SOURCES = xml-vcard.c vformat.c
+xml_vcard_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vcard_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+xml_vcal_la_SOURCES = xml-vcal.c vformat.c vcalical.c
+xml_vcal_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vcal_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+xml_vnote_la_SOURCES = xml-vnote.c vformat.c
+xml_vnote_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_vnote_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+xml_evolution_la_SOURCES = xml-evolution.c vformat.c
+xml_evolution_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_evolution_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+xml_kde_la_SOURCES = xml-kde.c vformat.c
+xml_kde_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xml_kde_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+xmldoc_la_SOURCES = xmldoc.c
+xmldoc_la_LDFLAGS = -avoid-version -export-dynamic -module @GCOV_LDFLAGS@
+xmldoc_la_LIBADD = @PACKAGE_LIBS@ @LIBS@ libopensync-xml.la
+libopensync_xml_la_SOURCES = xml-support.c
+libopensync_xml_la_LDFLAGS = @GCOV_LDFLAGS@
+libopensync_xml_la_LIBADD = @PACKAGE_LIBS@ @LIBS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign formats/vformats-xml/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign formats/vformats-xml/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-formatsLTLIBRARIES: $(formats_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(formatsdir)" || $(mkdir_p) "$(DESTDIR)$(formatsdir)"
+ @list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(formatsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(formatsdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(formatsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(formatsdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-formatsLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(formatsdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(formatsdir)/$$p"; \
+ done
+
+clean-formatsLTLIBRARIES:
+ -test -z "$(formats_LTLIBRARIES)" || rm -f $(formats_LTLIBRARIES)
+ @list='$(formats_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libopensync-xml.la: $(libopensync_xml_la_OBJECTS) $(libopensync_xml_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libopensync_xml_la_LDFLAGS) $(libopensync_xml_la_OBJECTS) $(libopensync_xml_la_LIBADD) $(LIBS)
+xml-evolution.la: $(xml_evolution_la_OBJECTS) $(xml_evolution_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xml_evolution_la_LDFLAGS) $(xml_evolution_la_OBJECTS) $(xml_evolution_la_LIBADD) $(LIBS)
+xml-kde.la: $(xml_kde_la_OBJECTS) $(xml_kde_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xml_kde_la_LDFLAGS) $(xml_kde_la_OBJECTS) $(xml_kde_la_LIBADD) $(LIBS)
+xml-vcal.la: $(xml_vcal_la_OBJECTS) $(xml_vcal_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xml_vcal_la_LDFLAGS) $(xml_vcal_la_OBJECTS) $(xml_vcal_la_LIBADD) $(LIBS)
+xml-vcard.la: $(xml_vcard_la_OBJECTS) $(xml_vcard_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xml_vcard_la_LDFLAGS) $(xml_vcard_la_OBJECTS) $(xml_vcard_la_LIBADD) $(LIBS)
+xml-vnote.la: $(xml_vnote_la_OBJECTS) $(xml_vnote_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xml_vnote_la_LDFLAGS) $(xml_vnote_la_OBJECTS) $(xml_vnote_la_LIBADD) $(LIBS)
+xmldoc.la: $(xmldoc_la_OBJECTS) $(xmldoc_la_DEPENDENCIES)
+ $(LINK) -rpath $(formatsdir) $(xmldoc_la_LDFLAGS) $(xmldoc_la_OBJECTS) $(xmldoc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcalical.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vformat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-evolution.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-kde.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-support.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-vcal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-vcard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-vnote.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmldoc.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-opensyncheaderHEADERS: $(opensyncheader_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(opensyncheaderdir)" || $(mkdir_p) "$(DESTDIR)$(opensyncheaderdir)"
+ @list='$(opensyncheader_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(opensyncheaderHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(opensyncheaderdir)/$$f'"; \
+ $(opensyncheaderHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(opensyncheaderdir)/$$f"; \
+ done
+
+uninstall-opensyncheaderHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(opensyncheader_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(opensyncheaderdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(opensyncheaderdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(formatsdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(opensyncheaderdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-formatsLTLIBRARIES clean-generic clean-libLTLIBRARIES \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-formatsLTLIBRARIES \
+ install-opensyncheaderHEADERS
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-formatsLTLIBRARIES uninstall-info-am \
+ uninstall-libLTLIBRARIES uninstall-opensyncheaderHEADERS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean \
+ clean-formatsLTLIBRARIES clean-generic clean-libLTLIBRARIES \
+ clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-formatsLTLIBRARIES install-info install-info-am \
+ install-libLTLIBRARIES install-man \
+ install-opensyncheaderHEADERS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-formatsLTLIBRARIES \
+ uninstall-info-am uninstall-libLTLIBRARIES \
+ uninstall-opensyncheaderHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/opensync-xml-contact.h b/debian/opensync/opensync-0.22/formats/vformats-xml/opensync-xml-contact.h
new file mode 100644
index 00000000..292310a2
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/opensync-xml-contact.h
@@ -0,0 +1,91 @@
+#ifndef HAVE_OPENSYNC_XML_CONTACT_H
+#define HAVE_OPENSYNC_XML_CONTACT_H
+
+/*
+ * Use the constants in this header if you are going to convert
+ * between "xml-contact" and another format.
+ *
+ * See xml-vcard.c for an example.
+ */
+
+
+/* What this is */
+#define XML_CONTACT_ROOT "contact"
+
+/* Parameters */
+#define XML_CONTACT_TYPE "Type"
+
+/* Values for XML_CONTACT_TYPE */
+#define XML_CONTACT_BULLETIN_BOARD "BBS"
+#define XML_CONTACT_CAR "Car"
+#define XML_CONTACT_CELLULAR "Cell"
+#define XML_CONTACT_DOMESTIC "Domestic"
+#define XML_CONTACT_FAX "Fax"
+#define XML_CONTACT_HOME "Home"
+#define XML_CONTACT_INTERNATIONAL "International"
+#define XML_CONTACT_INTERNET "Internet"
+#define XML_CONTACT_ISDN "ISDN"
+#define XML_CONTACT_MESSAGE "Msg"
+#define XML_CONTACT_MODEM "Modem"
+#define XML_CONTACT_PAGER "Pager"
+#define XML_CONTACT_PARCEL "Parcel"
+#define XML_CONTACT_PGP "PGP"
+#define XML_CONTACT_POSTAL "Postal"
+#define XML_CONTACT_PREF "Pref"
+#define XML_CONTACT_VIDEO "Video"
+#define XML_CONTACT_VOICE "Voice"
+#define XML_CONTACT_WORK "Work"
+#define XML_CONTACT_X509 "X509"
+
+/* Lots of properties */
+#define XML_CONTACT_ADDITIONAL "Additional"
+#define XML_CONTACT_ADDRESS "Address"
+#define XML_CONTACT_ADDRESS_LABEL "AddressLabel"
+#define XML_CONTACT_BIRTHDAY "Birthday"
+#define XML_CONTACT_CATEGORIES "Categories"
+#define XML_CONTACT_CITY "City"
+#define XML_CONTACT_CLASS "Class"
+#define XML_CONTACT_COUNTRY "Country"
+#define XML_CONTACT_EMAIL "EMail"
+#define XML_CONTACT_EXTENDED_ADDRESS "ExtendedAddress"
+#define XML_CONTACT_FILE_AS "FileAs"
+#define XML_CONTACT_FIRST_NAME "FirstName"
+#define XML_CONTACT_FULL_NAME "FullName"
+#define XML_CONTACT_KEY "Key"
+#define XML_CONTACT_LAST_NAME "LastName"
+#define XML_CONTACT_LOCATION "Location"
+#define XML_CONTACT_LOGO "Logo"
+#define XML_CONTACT_MAILER "Mailer"
+#define XML_CONTACT_NAME "Name"
+#define XML_CONTACT_NICKNAME "Nickname"
+#define XML_CONTACT_NOTE "Note"
+#define XML_CONTACT_ORGANIZATION "Organization"
+#define XML_CONTACT_PHOTO "Photo"
+#define XML_CONTACT_POSTAL_BOX "PostalBox"
+#define XML_CONTACT_POSTAL_CODE "PostalCode"
+#define XML_CONTACT_PREFIX "Prefix"
+#define XML_CONTACT_REGION "Region"
+#define XML_CONTACT_REVISION "Revision"
+#define XML_CONTACT_ROLE "Role"
+#define XML_CONTACT_SOUND "Sound"
+#define XML_CONTACT_STREET "Street"
+#define XML_CONTACT_SUFFIX "Suffix"
+#define XML_CONTACT_TELEPHONE "Telephone"
+#define XML_CONTACT_TIMEZONE "Timezone"
+#define XML_CONTACT_TITLE "Title"
+#define XML_CONTACT_UID "Uid"
+#define XML_CONTACT_UNIT "Unit"
+#define XML_CONTACT_URL "Url"
+#define XML_CONTACT_WANTS_HTML "WantsHtml"
+
+#define XML_CONTACT_CONTENT "Content"
+
+/* Unknown parameter */
+#define XML_CONTACT_UNKNOWN_PARAM "UnknownParam"
+#define XML_CONTACT_PARAMETER_NAME "ParamName"
+
+/* Unknown node */
+#define XML_CONTACT_UNKNOWN_NODE "UnknownNode"
+#define XML_CONTACT_NODE_NAME "NodeName"
+
+#endif
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.c b/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.c
new file mode 100644
index 00000000..54a05946
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.c
@@ -0,0 +1,472 @@
+/*
+ * vcalical - An vcal/ical converter
+ * Copyright (C) 2006 Daniel Gollub <[email protected]>
+ * Copyright (C) 2006 Christopher Stender <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include "xml-vcal.h"
+#include <glib.h>
+
+
+/* ical 2 vcal */
+#define ATTR_COUNT (sizeof(rrule_attr)/sizeof(rrule_attr[0]))
+#define PARAM_COUNT (sizeof(rrule_param)/sizeof(rrule_param[0]))
+
+enum {
+ FIELD_FREQ,
+ FIELD_INTERVAL,
+ FIELD_FREQMOD,
+ FIELD_FREQMOD2,
+ FIELD_COUNTUNTIL,
+ NUM_OF_FIELDS
+};
+
+enum {
+ TYPE_ATTR,
+ TYPE_PARAM
+};
+
+struct _rrule_attr {
+ const char *ical;
+ const char *vcal;
+ int field;
+} rrule_attr[] = {
+ { "BYDAY", " ", FIELD_FREQMOD },
+ { "BYMONTH", " ", FIELD_FREQMOD },
+ { "BYMONTHDAY", " ", FIELD_FREQMOD },
+ { "BYYEARDAY", " ", FIELD_FREQMOD },
+ { "COUNT", " #", FIELD_COUNTUNTIL },
+ { "FREQ", "", FIELD_FREQ },
+ { "INTERVAL", "", FIELD_INTERVAL },
+ { "UNTIL", " ", FIELD_COUNTUNTIL }
+};
+
+struct _rrule_param {
+ const char *ical;
+ const char *vcal;
+} rrule_param[] = {
+ { "DAILY", "D" },
+ { "MONTHLY", "M" },
+ { "WEEKLY", "W" },
+ { "YEARLY", "YM" }
+};
+
+static int comp_attr(const void *m1, const void *m2) {
+ struct _rrule_attr *mi1 = (struct _rrule_attr *) m1;
+ struct _rrule_attr *mi2 = (struct _rrule_attr *) m2;
+ return strcmp(mi1->ical, mi2->ical);
+}
+static int comp_param(const void *m1, const void *m2) {
+ struct _rrule_param *mi1 = (struct _rrule_param *) m1;
+ struct _rrule_param *mi2 = (struct _rrule_param *) m2;
+ return strcmp(mi1->ical, mi2->ical);
+}
+
+struct _rrule_attr *_parse_rrule_attr(const char *ical) {
+
+ struct _rrule_attr key, *res;
+ key.ical = ical;
+
+ res = bsearch(&key, rrule_attr, ATTR_COUNT, sizeof(struct _rrule_attr), comp_attr);
+
+ if (!res)
+ return NULL;
+
+ return res;
+}
+
+const char *_parse_rrule_param(const char *ical) {
+
+ struct _rrule_param key, *res;
+ const char *ret = NULL;
+
+ key.ical = ical;
+
+ res = bsearch(&key, rrule_param, PARAM_COUNT, sizeof(struct _rrule_param), comp_param);
+
+ if (!res)
+ ret = ical;
+ else
+ ret = res->vcal;
+
+ return ret;
+}
+
+char *_blank_field(char *field) {
+ if (field)
+ g_free(field);
+
+ return g_strdup("");
+}
+
+
+
+char *_adapt_param(const char *param) {
+
+ int i, len;
+ GString *ret = g_string_new("");
+
+ len = strlen(param);
+
+ for (i=0; i < len; i++) {
+ switch(param[i]) {
+ // evil sperators like ','
+ case ',':
+ ret = g_string_append_c(ret, ' ');
+ break;
+ default:
+ ret = g_string_append_c(ret,param[i]);
+ }
+ }
+
+ return g_string_free(ret, FALSE);
+}
+
+void _vcal_hook(char **icalattrs, char **vcalattrs, char **icalparams, char **vcalparams) {
+
+ if (!strcmp(icalparams[FIELD_FREQ], "MONTHLY")) {
+ // Workround for RRULE:MP1 1+ SU 20071003T193000
+ if(!strcmp(icalattrs[FIELD_FREQMOD], "BYDAY")) {
+ char sign = '+';
+ char wday[3];
+ int nthday;
+
+ g_free(vcalparams[FIELD_FREQ]);
+ vcalparams[FIELD_FREQ] = g_strdup("MP");
+
+ g_free(vcalparams[FIELD_FREQMOD]);
+
+ if (strlen(icalparams[FIELD_FREQMOD]) > 3)
+ sscanf(icalparams[FIELD_FREQMOD], "%c%d%c%c", &sign, &nthday, &wday[0], &wday[1]);
+ else
+ sscanf(icalparams[FIELD_FREQMOD], "%d%c%c", &nthday, &wday[0], &wday[1]);
+
+ wday[2] = '\0';
+
+ vcalparams[FIELD_FREQMOD] = g_strdup_printf("%d%c %s", nthday, sign, wday);
+
+ // Workaround for RRULE:MD1 .......
+// } else if (!strcmp(icalattrs[FIELD_FREQMOD], "BYMONTHDAY")) {
+ } else {
+ g_free(vcalparams[FIELD_FREQ]);
+ vcalparams[FIELD_FREQ] = g_strdup("MD");
+ }
+ }
+
+ if (!strcmp(icalparams[FIELD_FREQ], "YEARLY") && icalparams[FIELD_FREQMOD]) {
+ if (!strcmp(icalattrs[FIELD_FREQMOD], "BYYEARDAY")) {
+ g_free(vcalparams[FIELD_FREQ]);
+ vcalparams[FIELD_FREQ] = g_strdup("YD");
+ } else if ((!strcmp(icalattrs[FIELD_FREQMOD], "BYMONTH") && !strcmp(icalattrs[FIELD_FREQMOD2], "BYMONTHDAY"))
+ || (!strcmp(icalattrs[FIELD_FREQMOD2], "BYMONTH") && !strcmp(icalattrs[FIELD_FREQMOD], "BYMONTHDAY"))) {
+
+ g_free(vcalparams[FIELD_FREQ]);
+ vcalparams[FIELD_FREQ] = g_strdup("YM");
+
+ vcalattrs[FIELD_FREQMOD] = _blank_field(vcalattrs[FIELD_FREQMOD]);
+ vcalattrs[FIELD_FREQMOD2] = _blank_field(vcalattrs[FIELD_FREQMOD2]);
+ vcalparams[FIELD_FREQMOD] = _blank_field(vcalparams[FIELD_FREQMOD]);
+ vcalparams[FIELD_FREQMOD2] = _blank_field(vcalparams[FIELD_FREQMOD2]);
+ }
+ }
+
+ // Set INTERVAL to 1 if nothing is set and BYMONTHDAY is not used
+ if (icalparams[FIELD_INTERVAL] == NULL) {
+ vcalparams[FIELD_INTERVAL] = g_strdup("1");
+ }
+}
+
+char *conv_ical2vcal_rrule(const char *ical) {
+
+ osync_trace(TRACE_ENTRY, "%s(%s)", __func__, ical);
+
+ int i;
+ const char *pos, *prev;
+ size_t len;
+ char *icalattrs[NUM_OF_FIELDS] = { NULL };
+ char *vcalattrs[NUM_OF_FIELDS] = { NULL };
+ char *icalparams[NUM_OF_FIELDS] = { NULL };
+ char *vcalparams[NUM_OF_FIELDS] = { NULL };
+ struct _rrule_attr *field_attr;
+ const char *tmp = NULL;
+
+ GString *vcal10 = g_string_new("");
+
+ pos = prev = ical;
+
+ // FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,FR;UNTIL=20060901T182200Z
+ // W1 TU FR 20060901T182200Z
+ // *FREQ**INTERVAL* *FREQ-MOD* *COUNT/UNTIL*
+
+ while ((pos = strstr(pos, "="))) {
+
+ GString *attr = g_string_new("");
+ GString *param = g_string_new("");
+
+ len = pos - prev;
+
+ // not equal is required ... ignoring =
+ for (i=0; i < len; i++)
+ attr = g_string_append_c(attr, prev[i]);
+
+ pos++;
+ prev = pos;
+
+ pos = strstr(pos, ";");
+ if (pos == NULL)
+ pos = ical + strlen(ical);
+
+ len = pos - prev;
+ for (i=0; i < len; i++)
+ param = g_string_append_c(param, prev[i]);
+
+ field_attr = _parse_rrule_attr(attr->str);
+ if (field_attr == NULL)
+ goto next;
+
+ if (icalattrs[field_attr->field] && field_attr->field == FIELD_FREQMOD)
+ field_attr->field += 1;
+
+ vcalattrs[field_attr->field] = g_strdup(field_attr->vcal);
+ icalattrs[field_attr->field] = g_strdup(attr->str);
+
+ tmp = _parse_rrule_param(param->str);
+ if (tmp)
+ vcalparams[field_attr->field] = _adapt_param(tmp);
+ else
+ vcalparams[field_attr->field] = g_strdup("");
+ icalparams[field_attr->field] = g_strdup(param->str);
+
+ g_string_free(attr, TRUE);
+ g_string_free(param, TRUE);
+next:
+
+ prev = pos + 1;
+
+ }
+
+ for (i=0; i < NUM_OF_FIELDS; i++) {
+ if (!vcalparams[i])
+ vcalparams[i] = g_strdup("");
+ if (!vcalattrs[i])
+ vcalattrs[i] = g_strdup("");
+ if (!vcalparams[i])
+ vcalparams[i] = g_strdup("");
+ if (!icalattrs[i])
+ icalattrs[i] = g_strdup("");
+ }
+
+ _vcal_hook(icalattrs, vcalattrs, icalparams, vcalparams);
+
+ for (i=0; i < NUM_OF_FIELDS; i++) {
+ // If no end is set append #0 - recurrence for ever
+ if (i == FIELD_COUNTUNTIL && strlen(vcalparams[i]) == 0)
+ vcalparams[i] = g_strdup(" #0");
+
+ if (vcalattrs[i]) {
+ vcal10 = g_string_append(vcal10, vcalattrs[i]);
+// printf("(%i) \"%s\"\n", i, vcalattrs[i]);
+ g_free(vcalattrs[i]);
+ }
+
+ if (vcalparams[i]) {
+ vcal10 = g_string_append(vcal10, vcalparams[i]);
+// printf("(#%i) \"%s\"\n", i, vcalparams[i]);
+ g_free(vcalparams[i]);
+ }
+
+ if (icalattrs[i])
+ g_free(icalattrs[i]);
+
+ if (icalparams[i])
+ g_free(icalparams[i]);
+
+ }
+
+ osync_trace(TRACE_EXIT, "%s: %s", __func__, vcal10->str);
+ return g_string_free(vcal10, FALSE);
+}
+
+/* vcal 2 ical */
+GList *conv_vcal2ical_rrule(const char *vcal) {
+
+ osync_trace(TRACE_ENTRY, "%s(%s)", __func__, vcal);
+
+ gchar** blocks = g_strsplit(vcal, " ", 256);
+ int offset = 0;
+
+ int frequency_state = 0;
+ char *frequency = NULL;
+ char *frequency_block = NULL;
+
+ int interval;
+
+ int duration_number = -1;
+ char *duration_block;
+
+ char* freq_mod = NULL;
+
+
+ /* count blocks */
+ int counter;
+ for(counter=0; blocks[counter]; counter++);
+
+ frequency_block = blocks[0];
+ duration_block = blocks[counter-1];
+
+
+ /* get frequency: only D(1), W(2), MP(3), MD(4), YD(5) and YM(6) is allowed */
+ switch (*frequency_block++) {
+ case 'D': frequency_state = 1; frequency = "DAILY"; break;
+ case 'W': frequency_state = 2; frequency = "WEEKLY"; break;
+ case 'M': frequency_state = 0;
+ switch (*frequency_block++) {
+ case 'P': frequency_state = 3; frequency = "MONTHLY"; break;
+ case 'D': frequency_state = 4; frequency = "MONTHLY"; break;
+ default:
+ osync_trace(TRACE_INTERNAL, "invalid frequency M<X>");
+ }
+ break;
+ case 'Y': frequency_state = 0;
+ switch (*frequency_block++) {
+ case 'D': frequency_state = 5; frequency = "YEARLY"; break;
+ case 'M': frequency_state = 6; frequency = "YEARLY"; break;
+ default:
+ osync_trace(TRACE_INTERNAL, "invalid frequency Y<X>");
+ }
+ break;
+ default:
+ osync_trace(TRACE_INTERNAL, "invalid or missing frequency");
+ }
+
+
+ /* get interval (integer) */
+ char* e;
+ interval = strtol(frequency_block, &e, 10);
+ if (e == frequency_block) {
+ osync_trace(TRACE_INTERNAL, "interval is missing.");
+ }
+ if (*e != 0) {
+ osync_trace(TRACE_INTERNAL, "interval is to long.");
+ }
+
+
+ /* get frequency modifier if there are more than two blocks */
+ if (counter > 2) {
+
+ GString *fm_buffer = g_string_new("");
+ int i;
+
+ /* for each modifier do... */
+ for(i=1; i < counter-1; i++) {
+
+ int count;
+ char sign;
+
+ if(fm_buffer->len > 0)
+ g_string_append(fm_buffer, ",");
+
+ /* check frequency modifier */
+ if (sscanf(blocks[i], "%d%c" , &count, &sign) == 2) {
+
+ /* we need to convert $COUNT- to -$COUNT -> RFC2445 */
+ if (sign == '-')
+ count = -count;
+
+ g_string_append_printf(fm_buffer, "%d", count);
+
+ if (i < counter-2 && !sscanf(blocks[i+1], "%d", &count)) {
+
+ g_string_append_printf(fm_buffer, " %s", blocks[i+1]);
+ i++;
+
+ }
+
+ } else {
+
+ /* e.g. Day or 'LD' (Last day) */
+ g_string_append(fm_buffer, blocks[i]);
+
+ }
+ }
+
+ freq_mod = fm_buffer->str;
+ g_string_free(fm_buffer, FALSE);
+ }
+
+ char *until = NULL;
+
+ /* get duration (number OR timestamp, but nothing is required) */
+ if (sscanf(duration_block, "#%d", &duration_number) < 1) {
+ if (!osync_time_isdate(duration_block)) {
+
+ /* Check if this duration_block is a localtime timestamp.
+ * If it is not UTC change the offset from 0 to the system UTC offset.
+ * vcal doesn't store any TZ information. This means the device have to be
+ * in the same Timezone as the host.
+ */
+ if (!osync_time_isutc(duration_block)) {
+ struct tm *ttm = osync_time_vtime2tm(duration_block);
+ offset = osync_time_timezone_diff(ttm);
+ g_free(ttm);
+ }
+
+ until = osync_time_vtime2utc(duration_block, offset);
+ } else {
+ until = g_strdup(duration_block);
+ }
+ }
+
+ g_strfreev(blocks);
+
+
+ /* generate new RRULE: D(1), W(2), MP(3), MD(4), YD(5) and YM(6) */
+ GList *new_rrule = NULL;
+
+ new_rrule = g_list_append(new_rrule, g_strdup_printf("FREQ=%s", frequency));
+ new_rrule = g_list_append(new_rrule, g_strdup_printf("INTERVAL=%d", interval));
+
+ if (duration_number > 0)
+ new_rrule = g_list_append(new_rrule, g_strdup_printf("COUNT=%d", duration_number));
+
+ if(freq_mod != NULL) {
+ switch(frequency_state) {
+ case 2: new_rrule = g_list_append(new_rrule, g_strdup_printf("BYDAY=%s", freq_mod)); break;
+ case 3: new_rrule = g_list_append(new_rrule, g_strdup_printf("BYDAY=%s", freq_mod)); break;
+ case 4: new_rrule = g_list_append(new_rrule, g_strdup_printf("BYMONTHDAY=%s", freq_mod)); break;
+ case 5: new_rrule = g_list_append(new_rrule, g_strdup_printf("BYYEARDAY=%s", freq_mod)); break;
+ case 6: new_rrule = g_list_append(new_rrule, g_strdup_printf("BYMONTH=%s", freq_mod)); break;
+ default:
+ break;
+ }
+ }
+
+ if (until != NULL) {
+ new_rrule = g_list_append(new_rrule, g_strdup_printf("UNTIL=%s", until));
+ g_free(until);
+ }
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+
+ return new_rrule;
+}
+
+
+
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.h b/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.h
new file mode 100644
index 00000000..7d87cb48
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/vcalical.h
@@ -0,0 +1,30 @@
+/*
+ * vcalical - An vcal/ical converter
+ * Copyright (C) 2006 Daniel Gollub <[email protected]>
+ * Copyright (C) 2006 Christopher Stender <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include "xml-vcal.h"
+#include <glib.h>
+
+char *conv_ical2vcal_rrule(const char *ical);
+GList *conv_vcal2ical_rrule(const char *vcal);
+GList *conv_vcal2ical_rrule(const char *vcal);
+
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.c b/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.c
new file mode 100644
index 00000000..547eef74
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.c
@@ -0,0 +1,2005 @@
+/*
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * 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
+ *
+ * Author: Chris Toshok ([email protected])
+ * Author: Armin Bauer ([email protected])
+ *
+ */
+
+#include "vformat.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <iconv.h>
+#include <opensync/opensync.h>
+
+static size_t base64_encode_step(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save);
+static size_t base64_decode_step(unsigned char *in, size_t len, unsigned char *out, int *state, unsigned int *save);
+size_t base64_decode_simple (char *data, size_t len);
+char *base64_encode_simple (const char *data, size_t len);
+
+size_t quoted_decode_simple (char *data, size_t len);
+char *quoted_encode_simple (const unsigned char *string, int len);
+
+
+/**
+ * _helper_is_base64 is helper function to check i a string is "b" or "base64"
+ * @param check_string string that should be compared with "b" or "base64"
+ * @return 0 if check_string is not base64 and 1 if it is
+ */
+static int _helper_is_base64(const char *check_string)
+{
+ if(!g_ascii_strcasecmp ((char *) check_string, "BASE64") ||
+ !g_ascii_strcasecmp ((char *) check_string, "b") )
+ return (1);
+ return (0);
+}
+
+time_t vformat_time_to_unix(const char *inptime)
+{
+ char *date = NULL;
+ char *time = NULL;
+ char *ftime = NULL;
+ if ((ftime = g_strrstr(inptime, "T"))) {
+
+ date = g_strndup(inptime, ftime - inptime);
+ if (ftime[3] == ':')
+ time = g_strndup(ftime + 1, 8);
+ else
+ time = g_strndup(ftime + 1, 6);
+ } else {
+ date = g_strdup(inptime);
+ }
+
+ struct tm btime;
+ memset(&btime, 0, sizeof(struct tm));
+
+ if (strlen(date) == 10) {
+ btime.tm_year = date[0] * 1000 + date[1] * 100 + date[2] * 10 + date[3] - '0' * 1111 - 1900;
+ btime.tm_mon = date[5] * 10 + date[6] - '0' * 11 - 1;
+ btime.tm_mday = date[8] * 10 + date[9] - '0' * 11;
+ } else {
+ btime.tm_year = date[0] * 1000 + date[1] * 100 + date[2] * 10 + date[3] - '0' * 1111- 1900;
+ btime.tm_mon = date[4] * 10 + date[5] - '0' * 11 - 1;
+ btime.tm_mday = date[6] * 10 + date[7] - '0' * 11;
+ }
+
+ if (time && strlen(time) == 8) {
+ //Time
+ btime.tm_hour = time[0] * 10 + time[1] - '0' * 11;
+ btime.tm_min = time[3] * 10 + time[4] - '0' * 11;
+ btime.tm_sec = time[6] * 10 + time[7] - '0' * 11;
+ } else if (time && strlen(time) == 6) {
+ btime.tm_hour = time[0] * 10 + time[1] - '0' * 11;
+ btime.tm_min = time[2] * 10 + time[3] - '0' * 11;
+ btime.tm_sec = time[4] * 10 + time[5] - '0' * 11;
+ }
+
+ time_t utime = mktime(&btime);
+ return utime;
+}
+
+static char *_fold_lines (char *buf)
+{
+ GString *str = g_string_new ("");
+ GString *line = g_string_new ("");
+ char *p = buf;
+ char *next, *next2, *q;
+ gboolean newline = TRUE;
+ gboolean quotedprintable = FALSE;
+
+ /*
+ * We're pretty liberal with line folding here. We handle
+ * lines folded with \r\n<WS>, \n\r<WS>, \n<WS>, =\r\n and =\n\r.
+ * We also turn single \r's and \n's not followed by <WS> into \r\n's.
+ */
+
+ while (*p) {
+
+ /* search new lines for quoted printable encoding */
+ if (newline) {
+ for (q=p; *q != '\n' && *q != '\0'; q++)
+ line = g_string_append_unichar (line, g_utf8_get_char (q));
+
+ if (strstr(line->str, "ENCODING=QUOTED-PRINTABLE"))
+ quotedprintable = TRUE;
+
+ g_string_free(line, TRUE);
+ line = g_string_new ("");
+
+ newline = FALSE;
+ }
+
+
+ if ((quotedprintable && *p == '=') || *p == '\r' || *p == '\n') {
+ next = g_utf8_next_char (p);
+ if (*next == '\n' || *next == '\r') {
+ next2 = g_utf8_next_char (next);
+ if (*next2 == '\n' || *next2 == '\r' || *next2 == ' ' || *next2 == '\t') {
+ p = g_utf8_next_char (next2);
+ }
+ else {
+ str = g_string_append (str, CRLF);
+ p = g_utf8_next_char (next);
+ newline = TRUE;
+ quotedprintable = FALSE;
+ }
+ }
+ else if (*p == '=') {
+ str = g_string_append_unichar (str, g_utf8_get_char (p));
+ p = g_utf8_next_char (p);
+ }
+ else if (*next == ' ' || *next == '\t') {
+ p = g_utf8_next_char (next);
+ }
+ else {
+ str = g_string_append (str, CRLF);
+ p = g_utf8_next_char (p);
+ newline = TRUE;
+ quotedprintable = FALSE;
+ }
+ }
+ else {
+ str = g_string_append_unichar (str, g_utf8_get_char (p));
+ p = g_utf8_next_char (p);
+ }
+ }
+
+ g_free (buf);
+ g_string_free(line, TRUE);
+
+ return g_string_free (str, FALSE);
+}
+
+/* skip forward until we hit the CRLF, or \0 */
+static void _skip_to_next_line (char **p)
+{
+ char *lp;
+ lp = *p;
+
+ while (*lp != '\r' && *lp != '\0')
+ lp = g_utf8_next_char (lp);
+
+ if (*lp == '\r') {
+ lp = g_utf8_next_char (lp); /* \n */
+ lp = g_utf8_next_char (lp); /* start of the next line */
+ }
+
+ *p = lp;
+}
+
+/* skip forward until we hit a character in @s, CRLF, or \0. leave *p
+ pointing at the character that causes us to stop */
+static void _skip_until (char **p, char *s)
+{
+ char *lp;
+
+ lp = *p;
+
+ while (*lp != '\r' && *lp != '\0') {
+ gboolean s_matches = FALSE;
+ char *ls;
+ for (ls = s; *ls; ls = g_utf8_next_char (ls)) {
+ if (g_utf8_get_char (ls) == g_utf8_get_char (lp)) {
+ s_matches = TRUE;
+ break;
+ }
+ }
+
+ if (s_matches)
+ break;
+ lp++;
+ }
+
+ *p = lp;
+}
+
+static void _read_attribute_value_add (VFormatAttribute *attr, GString *str, GString *charset)
+{
+ /* don't convert empty strings */
+ if (str->len == 0) {
+ vformat_attribute_add_value(attr, str->str);
+ return;
+ }
+
+ char *inbuf, *outbuf, *p;
+ size_t inbytesleft, outbytesleft;
+
+ inbuf = str->str;
+ p = outbuf = malloc(str->len*2);
+ inbytesleft = str->len;
+ outbytesleft = str->len*2;
+
+ iconv_t cd;
+
+ /* if a CHARSET was given, let's try to convert inbuf to UTF-8 */
+ if (charset) {
+
+ cd = iconv_open("UTF-8", charset->str);
+#ifdef SOLARIS
+ if (iconv(cd, (const char**)&inbuf, &inbytesleft, &p, &outbytesleft) != (size_t)(-1)) {
+#else
+ if (iconv(cd, &inbuf, &inbytesleft, &p, &outbytesleft) != (size_t)(-1)) {
+#endif
+ *p = 0;
+ vformat_attribute_add_value(attr, outbuf);
+
+ } else {
+
+ /* hmm, should not happen */
+ vformat_attribute_add_value(attr, str->str);
+
+ }
+
+ iconv_close(cd);
+
+ } else {
+
+ /* no CHARSET was given, if inbuf is already UTF-8 we add str->str */
+ if (g_utf8_validate (inbuf, -1, NULL)) {
+
+ vformat_attribute_add_value (attr, str->str);
+
+ } else {
+
+ /* because inbuf is not UTF-8, we think it is ISO-8859-1 */
+ cd = iconv_open("UTF-8", "ISO-8859-1");
+#ifdef SOLARIS
+ if (iconv(cd, (const char**)&inbuf, &inbytesleft, &p, &outbytesleft) != (size_t)(-1)) {
+#else
+ if (iconv(cd, &inbuf, &inbytesleft, &p, &outbytesleft) != (size_t)(-1)) {
+#endif
+ *p = 0;
+ vformat_attribute_add_value (attr, outbuf);
+
+ } else {
+
+ vformat_attribute_add_value (attr, str->str);
+
+ }
+
+ iconv_close(cd);
+
+ }
+
+ }
+
+ free(outbuf);
+
+}
+
+static void _read_attribute_value (VFormatAttribute *attr, char **p, int format_encoding, GString *charset)
+{
+ char *lp = *p;
+ GString *str;
+
+ /* read in the value */
+ str = g_string_new ("");
+ while (*lp != '\r' && *lp != '\0') {
+ if (*lp == '=' && format_encoding == VF_ENCODING_QP) {
+ char a, b, x1=0, x2=0;
+
+ if ((a = *(++lp)) == '\0') break;
+ if ((b = *(++lp)) == '\0') break;
+
+ if (isalnum(a)) {
+ if (isalnum(b)) {
+ /* e.g. ...N=C3=BCrnberg\r\n
+ * ^^^
+ */
+ x1=a;
+ x2=b;
+ }
+ else if (b == '=') {
+ /* e.g. ...N=C=\r\n
+ * ^^^
+ * 3=BCrnberg...
+ * ^
+ */
+ char *tmplp = lp;
+ if (*(++tmplp) == '\r' && *(++tmplp) == '\n' && isalnum(*(++tmplp))) {
+ x1 = a;
+ x2 = *tmplp;
+ lp = tmplp;
+ }
+ }
+ else {
+ /* append malformed input, and
+ continue parsing */
+ str = g_string_append_c(str, a);
+ str = g_string_append_c(str, b);
+ }
+ }
+ else if (a == '=') {
+ char *tmplp = lp;
+ char c, d, e;
+ c = *(++tmplp);
+ d = *(++tmplp);
+ e = *(++tmplp);
+ if (b == '\r' && c == '\n' && isalnum(d) && isalnum(e)) {
+ x1 = d;
+ x2 = e;
+ lp = tmplp;
+ }
+ else {
+ /* append malformed input, and
+ continue parsing */
+ str = g_string_append_c(str, a);
+ str = g_string_append_c(str, b);
+ }
+ }
+ else {
+ /* append malformed input, and
+ continue parsing */
+ str = g_string_append_c(str, a);
+ str = g_string_append_c(str, b);
+ }
+ if (x1 && x2) {
+ char c;
+
+ a = tolower (x1);
+ b = tolower (x2);
+
+ c = (((a>='a'?a-'a'+10:a-'0')&0x0f) << 4)
+ | ((b>='a'?b-'a'+10:b-'0')&0x0f);
+
+ str = g_string_append_c (str, c);
+ }
+ lp++;
+ x1 = x2 = 0;
+ }
+ else if (format_encoding == VF_ENCODING_BASE64) {
+ if((*lp != ' ') && (*lp != '\t') )
+ str = g_string_append_unichar (str, g_utf8_get_char (lp));
+ lp = g_utf8_next_char(lp);
+ }
+ else if (*lp == '\\') {
+ /* convert back to the non-escaped version of
+ the characters */
+ lp = g_utf8_next_char(lp);
+ if (*lp == '\0') {
+ str = g_string_append_c (str, '\\');
+ break;
+ }
+ switch (*lp) {
+ case 'n': str = g_string_append_c (str, '\n'); break;
+ case 'r': str = g_string_append_c (str, '\r'); break;
+ case ';': str = g_string_append_c (str, ';'); break;
+ case ',':
+ if (!strcmp (attr->name, "CATEGORIES")) {
+ //We need to handle categories here to work
+ //aroung a bug in evo2
+ _read_attribute_value_add (attr, str, charset);
+ g_string_assign (str, "");
+ } else
+ str = g_string_append_c (str, ',');
+ break;
+ case '\\': str = g_string_append_c (str, '\\'); break;
+ case '"': str = g_string_append_c (str, '"'); break;
+ /* \t is (incorrectly) used by kOrganizer, so handle it here */
+ case 't': str = g_string_append_c (str, '\t'); break;
+ default:
+ osync_trace(TRACE_INTERNAL, "invalid escape, passing it through. escaped char was %i", *lp);
+ str = g_string_append_c (str, '\\');
+ str = g_string_append_unichar (str, g_utf8_get_char(lp));
+ break;
+ }
+ lp = g_utf8_next_char(lp);
+ }
+ else if ((*lp == ';') ||
+ (*lp == ',' && !strcmp (attr->name, "CATEGORIES"))) {
+ _read_attribute_value_add (attr, str, charset);
+ g_string_assign (str, "");
+ lp = g_utf8_next_char(lp);
+ }
+ else {
+ str = g_string_append_unichar (str, g_utf8_get_char (lp));
+ lp = g_utf8_next_char(lp);
+ }
+ }
+ if (str) {
+ _read_attribute_value_add (attr, str, charset);
+ g_string_free (str, TRUE);
+ }
+
+ if (*lp == '\r') {
+ lp = g_utf8_next_char (lp); /* \n */
+ lp = g_utf8_next_char (lp); /* start of the next line */
+ }
+
+ *p = lp;
+}
+
+static void _read_attribute_params(VFormatAttribute *attr, char **p, int *format_encoding, GString **charset)
+{
+ char *lp = *p;
+ GString *str;
+ VFormatParam *param = NULL;
+ gboolean in_quote = FALSE;
+ str = g_string_new ("");
+
+ while (*lp != '\0') {
+ if (*lp == '"') {
+ in_quote = !in_quote;
+ lp = g_utf8_next_char (lp);
+ }
+ else if (in_quote || g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_' || *lp == '/' || *lp == '.' || *lp == ' ') {
+ str = g_string_append_unichar (str, g_utf8_get_char (lp));
+ lp = g_utf8_next_char (lp);
+ }
+ /* accumulate until we hit the '=' or ';'. If we hit
+ * a '=' the string contains the parameter name. if
+ * we hit a ';' the string contains the parameter
+ * value and the name is either ENCODING (if value ==
+ * QUOTED-PRINTABLE) or TYPE (in any other case.)
+ */
+ else if (*lp == '=') {
+ if (str->len > 0) {
+ param = vformat_attribute_param_new (str->str);
+ g_string_assign (str, "");
+ lp = g_utf8_next_char (lp);
+ }
+ else {
+ _skip_until (&lp, ":;");
+ if (*lp == '\r') {
+ lp = g_utf8_next_char (lp); /* \n */
+ lp = g_utf8_next_char (lp); /* start of the next line */
+ break;
+ }
+ else if (*lp == ';')
+ lp = g_utf8_next_char (lp);
+ }
+ }
+ else if (*lp == ';' || *lp == ':' || *lp == ',') {
+ gboolean colon = (*lp == ':');
+ gboolean comma = (*lp == ',');
+
+ if (param) {
+ if (str->len > 0) {
+ vformat_attribute_param_add_value (param, str->str);
+ g_string_assign (str, "");
+ if (!colon)
+ lp = g_utf8_next_char (lp);
+ }
+ else {
+ /* we've got a parameter of the form:
+ * PARAM=(.*,)?[:;]
+ * so what we do depends on if there are already values
+ * for the parameter. If there are, we just finish
+ * this parameter and skip past the offending character
+ * (unless it's the ':'). If there aren't values, we free
+ * the parameter then skip past the character.
+ */
+ if (!param->values) {
+ vformat_attribute_param_free (param);
+ param = NULL;
+ if (!colon)
+ lp = g_utf8_next_char (lp);
+ }
+ }
+
+ if (param
+ && !g_ascii_strcasecmp (param->name, "encoding")) {
+ if (!g_ascii_strcasecmp (param->values->data, "quoted-printable")) {
+ *format_encoding = VF_ENCODING_QP;
+ vformat_attribute_param_free (param);
+ param = NULL;
+ } else if ( _helper_is_base64(param->values->data)) {
+ *format_encoding = VF_ENCODING_BASE64;
+// vformat_attribute_param_free (param);
+// param = NULL;
+ }
+ } else if (param && !g_ascii_strcasecmp(param->name, "charset")) {
+ *charset = g_string_new(param->values->data);
+ vformat_attribute_param_free (param);
+ param = NULL;
+ }
+ }
+ else {
+ if (str->len > 0) {
+ char *param_name;
+ if (!g_ascii_strcasecmp (str->str,
+ "quoted-printable")) {
+ param_name = "ENCODING";
+ *format_encoding = VF_ENCODING_QP;
+ }
+ /* apple's broken addressbook app outputs naked BASE64
+ parameters, which aren't even vcard 3.0 compliant. */
+ else if (!g_ascii_strcasecmp (str->str,
+ "base64")) {
+ param_name = "ENCODING";
+ g_string_assign (str, "b");
+ *format_encoding = VF_ENCODING_BASE64;
+ }
+ else {
+ param_name = "TYPE";
+ }
+
+ if (param_name) {
+ param = vformat_attribute_param_new (param_name);
+ vformat_attribute_param_add_value (param, str->str);
+ }
+ g_string_assign (str, "");
+ if (!colon)
+ lp = g_utf8_next_char (lp);
+ }
+ else {
+ /* we've got an attribute with a truly empty
+ attribute parameter. So it's of the form:
+
+ ATTR;[PARAM=value;]*;[PARAM=value;]*:
+
+ (note the extra ';')
+
+ the only thing to do here is, well.. nothing.
+ we skip over the character if it's not a colon,
+ and the rest is handled for us: We'll either
+ continue through the loop again if we hit a ';',
+ or we'll break out correct below if it was a ':' */
+ if (!colon)
+ lp = g_utf8_next_char (lp);
+ }
+ }
+ if (param && !comma) {
+ vformat_attribute_add_param (attr, param);
+ param = NULL;
+ }
+ if (colon)
+ break;
+ }
+ else {
+ osync_trace(TRACE_INTERNAL, "invalid character found in parameter spec: \"%i\" String so far: %s", lp[0], str->str);
+ g_string_assign (str, "");
+ _skip_until (&lp, ":;");
+ }
+ }
+
+ if (str)
+ g_string_free (str, TRUE);
+
+ *p = lp;
+}
+
+/* reads an entire attribute from the input buffer, leaving p pointing
+ at the start of the next line (past the \r\n) */
+static VFormatAttribute *_read_attribute (char **p)
+{
+ char *attr_group = NULL;
+ char *attr_name = NULL;
+ VFormatAttribute *attr = NULL;
+ GString *str, *charset = NULL;
+ char *lp = *p;
+
+ gboolean is_qp = FALSE;
+
+ /* first read in the group/name */
+ str = g_string_new ("");
+ while (*lp != '\r' && *lp != '\0') {
+ if (*lp == ':' || *lp == ';') {
+ if (str->len != 0) {
+ /* we've got a name, break out to the value/attribute parsing */
+ attr_name = g_string_free (str, FALSE);
+ break;
+ }
+ else {
+ /* a line of the form:
+ * (group.)?[:;]
+ *
+ * since we don't have an attribute
+ * name, skip to the end of the line
+ * and try again.
+ */
+ g_string_free (str, TRUE);
+ *p = lp;
+ _skip_to_next_line(p);
+ goto lose;
+ }
+ }
+ else if (*lp == '.') {
+ if (attr_group) {
+ osync_trace(TRACE_INTERNAL, "extra `.' in attribute specification. ignoring extra group `%s'",
+ str->str);
+ g_string_free (str, TRUE);
+ str = g_string_new ("");
+ }
+ if (str->len != 0) {
+ attr_group = g_string_free (str, FALSE);
+ str = g_string_new ("");
+ }
+ }
+ else if (g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_' || *lp == '/') {
+ str = g_string_append_unichar (str, g_utf8_get_char (lp));
+ }
+ else {
+ osync_trace(TRACE_INTERNAL, "invalid character found in attribute group/name: \"%i\" String so far: %s", lp[0], str->str);
+ g_string_free (str, TRUE);
+ *p = lp;
+ _skip_to_next_line(p);
+ goto lose;
+ }
+
+ lp = g_utf8_next_char(lp);
+ }
+
+ if (!attr_name) {
+ _skip_to_next_line (p);
+ goto lose;
+ }
+
+ attr = vformat_attribute_new (attr_group, attr_name);
+ g_free (attr_group);
+ g_free (attr_name);
+
+ if (*lp == ';') {
+ /* skip past the ';' */
+ lp = g_utf8_next_char(lp);
+ _read_attribute_params (attr, &lp, &is_qp, &charset);
+ }
+ if (*lp == ':') {
+ /* skip past the ':' */
+ lp = g_utf8_next_char(lp);
+ _read_attribute_value (attr, &lp, is_qp, charset);
+ }
+
+ if (charset) g_string_free(charset, TRUE);
+ *p = lp;
+
+ if (!attr->values)
+ goto lose;
+
+ return attr;
+ lose:
+ if (attr)
+ vformat_attribute_free (attr);
+ return NULL;
+}
+
+/* we try to be as forgiving as we possibly can here - this isn't a
+ * validator. Almost nothing is considered a fatal error. We always
+ * try to return *something*.
+ */
+static void _parse(VFormat *evc, const char *str)
+{
+ char *buf = g_strdup (str);
+ char *p, *end;
+ VFormatAttribute *attr;
+
+ /* first validate the string is valid utf8 */
+ if (!g_utf8_validate (buf, -1, (const char **)&end)) {
+ /* if the string isn't valid, we parse as much as we can from it */
+ osync_trace(TRACE_INTERNAL, "invalid utf8 passed to VFormat. Limping along.");
+ *end = '\0';
+ }
+
+ buf = _fold_lines (buf);
+
+ p = buf;
+
+ attr = _read_attribute (&p);
+ if (!attr)
+ attr = _read_attribute (&p);
+
+ if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "begin")) {
+ osync_trace(TRACE_INTERNAL, "vformat began without a BEGIN\n");
+ }
+ if (attr && !g_ascii_strcasecmp (attr->name, "begin"))
+ vformat_attribute_free (attr);
+ else if (attr)
+ vformat_add_attribute (evc, attr);
+
+ while (*p) {
+ VFormatAttribute *next_attr = _read_attribute (&p);
+
+ if (next_attr) {
+ //if (g_ascii_strcasecmp (next_attr->name, "end"))
+ vformat_add_attribute (evc, next_attr);
+ attr = next_attr;
+ }
+ }
+
+ if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "end")) {
+ osync_trace(TRACE_INTERNAL, "vformat ended without END");
+ }
+
+ g_free (buf);
+}
+
+char *vformat_escape_string (const char *s, VFormatType type)
+{
+ GString *str;
+ const char *p;
+
+ str = g_string_new ("");
+
+ /* Escape a string as described in RFC2426, section 5 */
+ for (p = s; p && *p; p++) {
+ switch (*p) {
+ case '\n':
+ str = g_string_append (str, "\\n");
+ break;
+ case '\r':
+ if (*(p+1) == '\n')
+ p++;
+ str = g_string_append (str, "\\n");
+ break;
+ case ';':
+ str = g_string_append (str, "\\;");
+ break;
+ case ',':
+ if (type == VFORMAT_CARD_30 || type == VFORMAT_EVENT_20 || type == VFORMAT_TODO_20)
+ str = g_string_append (str, "\\,");
+ else
+ str = g_string_append_c (str, *p);
+ break;
+ case '\\':
+ /**
+ * We won't escape backslashes
+ * on vcard 2.1, unless it is in the end of a value.
+ * See comments above for a better explanation
+ **/
+ if (*p != '\0' && type == VFORMAT_CARD_21) {
+ osync_trace(TRACE_INTERNAL, "[%s]We won't escape backslashes", __func__);
+ str = g_string_append_c(str, *p);
+ }
+ else {
+ osync_trace(TRACE_INTERNAL, "[%s] escape backslashes!!", __func__);
+ str = g_string_append (str, "\\\\");
+ }
+ break;
+ default:
+ str = g_string_append_c (str, *p);
+ break;
+ }
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+char*
+vformat_unescape_string (const char *s)
+{
+ GString *str;
+ const char *p;
+
+ g_return_val_if_fail (s != NULL, NULL);
+
+ str = g_string_new ("");
+
+ /* Unescape a string as described in RFC2426, section 4 (Formal Grammar) */
+ for (p = s; *p; p++) {
+ if (*p == '\\') {
+ p++;
+ if (*p == '\0') {
+ str = g_string_append_c (str, '\\');
+ break;
+ }
+ switch (*p) {
+ case 'n': str = g_string_append_c (str, '\n'); break;
+ case 'r': str = g_string_append_c (str, '\r'); break;
+ case ';': str = g_string_append_c (str, ';'); break;
+ case ',': str = g_string_append_c (str, ','); break;
+ case '\\': str = g_string_append_c (str, '\\'); break;
+ case '"': str = g_string_append_c (str, '"'); break;
+ /* \t is (incorrectly) used by kOrganizer, so handle it here */
+ case 't': str = g_string_append_c (str, '\t'); break;
+ default:
+ osync_trace(TRACE_INTERNAL, "invalid escape, passing it through. escaped char was %s", *p);
+ str = g_string_append_c (str, '\\');
+ str = g_string_append_unichar (str, g_utf8_get_char(p));
+ break;
+ }
+ }
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+void
+vformat_construct (VFormat *evc, const char *str)
+{
+ g_return_if_fail (str != NULL);
+
+ if (*str)
+ _parse (evc, str);
+}
+
+void vformat_free(VFormat *format)
+{
+ g_list_foreach (format->attributes, (GFunc)vformat_attribute_free, NULL);
+ g_list_free (format->attributes);
+ g_free(format);
+}
+
+VFormat *vformat_new_from_string (const char *str)
+{
+ g_return_val_if_fail (str != NULL, NULL);
+ VFormat *evc = g_malloc0(sizeof(VFormat));
+
+ vformat_construct (evc, str);
+
+ return evc;
+}
+
+VFormat *vformat_new(void)
+{
+ return vformat_new_from_string ("");
+}
+
+VFormatAttribute *vformat_find_attribute(VFormat *vcard, const char *name)
+{
+ GList *attributes = vformat_get_attributes(vcard);
+ GList *a = NULL;
+ for (a = attributes; a; a = a->next) {
+ VFormatAttribute *attr = a->data;
+ if (!strcmp(vformat_attribute_get_name(attr), name)) {
+ return attr;
+ }
+ }
+ return NULL;
+}
+
+char *vformat_to_string (VFormat *evc, VFormatType type)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %i)", __func__, type);
+ GList *l;
+ GList *v;
+
+ GString *str = g_string_new ("");
+
+ switch (type) {
+ case VFORMAT_CARD_21:
+ str = g_string_append (str, "BEGIN:VCARD\r\nVERSION:2.1\r\n");
+ break;
+ case VFORMAT_CARD_30:
+ str = g_string_append (str, "BEGIN:VCARD\r\nVERSION:3.0\r\n");
+ break;
+ case VFORMAT_TODO_10:
+ case VFORMAT_EVENT_10:
+ str = g_string_append (str, "BEGIN:VCALENDAR\r\nVERSION:1.0\r\n");
+ break;
+ case VFORMAT_TODO_20:
+ case VFORMAT_EVENT_20:
+ str = g_string_append (str, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\n");
+ break;
+ case VFORMAT_NOTE:
+ str = g_string_append (str, "BEGIN:VNOTE\r\nVERSION:1.1\r\n");
+ break;
+ }
+
+ for (l = evc->attributes; l; l = l->next) {
+ GList *p;
+ VFormatAttribute *attr = l->data;
+ GString *attr_str;
+ int l;
+ int format_encoding = VF_ENCODING_RAW;
+
+ attr_str = g_string_new ("");
+
+ /* From rfc2425, 5.8.2
+ *
+ * contentline = [group "."] name *(";" param) ":" value CRLF
+ */
+
+ if (attr->group) {
+ attr_str = g_string_append (attr_str, attr->group);
+ attr_str = g_string_append_c (attr_str, '.');
+ }
+ attr_str = g_string_append (attr_str, attr->name);
+ /* handle the parameters */
+ for (p = attr->params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ /* 5.8.2:
+ * param = param-name "=" param-value *("," param-value)
+ */
+ if( type == VFORMAT_CARD_30 || type == VFORMAT_TODO_20
+ || type == VFORMAT_EVENT_20) {
+
+ /**
+ * Character set can only be specified on the CHARSET
+ * parameter on the Content-Type MIME header field.
+ **/
+ if (!g_ascii_strcasecmp (param->name, "CHARSET"))
+ continue;
+ attr_str = g_string_append_c (attr_str, ';');
+ attr_str = g_string_append (attr_str, param->name);
+ if (param->values) {
+ attr_str = g_string_append_c (attr_str, '=');
+ }
+ for (v = param->values; v; v = v->next) {
+ if (_helper_is_base64((const char *) v->data)) {
+ format_encoding = VF_ENCODING_BASE64;
+ /*Only the "B" encoding of [RFC 2047] is an allowed*/
+ v->data="B";
+ }
+ /**
+ * QUOTED-PRINTABLE inline encoding has been
+ * eliminated.
+ **/
+ if (!g_ascii_strcasecmp (param->name, "ENCODING") && !g_ascii_strcasecmp ((char *) v->data, "QUOTED-PRINTABLE")) {
+ osync_trace(TRACE_ERROR, "%s false encoding QUOTED-PRINTABLE is not allowed", __func__);
+ format_encoding = VF_ENCODING_QP;
+ }
+ attr_str = g_string_append (attr_str, v->data);
+
+ if (v->next)
+ attr_str = g_string_append_c (attr_str, ',');
+ }
+ }
+ else {
+ attr_str = g_string_append_c (attr_str, ';');
+ /**
+ * The "TYPE=" is optional skip it.
+ * LOGO, PHOTO and SOUND multimedia formats MUST
+ * have a "TYPE=" parameter
+ **/
+ gboolean must_have_type = FALSE;
+ if (!g_ascii_strcasecmp (attr->name, "PHOTO") || !g_ascii_strcasecmp (attr->name, "LOGO") || !g_ascii_strcasecmp (attr->name, "SOUND") )
+ must_have_type = TRUE;
+ if ( must_have_type || g_ascii_strcasecmp (param->name, "TYPE") )
+ attr_str = g_string_append (attr_str, param->name);
+ if ( param->values && (must_have_type || g_ascii_strcasecmp (param->name, "TYPE")) )
+ attr_str = g_string_append_c (attr_str, '=');
+ for (v = param->values; v; v = v->next) {
+ // check for quoted-printable encoding
+ if (!g_ascii_strcasecmp (param->name, "ENCODING") && !g_ascii_strcasecmp ((char *) v->data, "QUOTED-PRINTABLE"))
+ format_encoding = VF_ENCODING_QP;
+ // check for base64 encoding
+ if (_helper_is_base64((const char *) v->data)) {
+ format_encoding = VF_ENCODING_BASE64;
+ v->data="BASE64";
+ }
+ attr_str = g_string_append (attr_str, v->data);
+ if (v->next)
+ attr_str = g_string_append_c (attr_str, ',');
+ }
+ }
+ }
+
+ attr_str = g_string_append_c (attr_str, ':');
+
+ for (v = attr->values; v; v = v->next) {
+ char *value = v->data;
+ char *escaped_value = NULL;
+
+ if (!strcmp (attr->name, "RRULE") &&
+ strstr (value, "BYDAY") == v->data) {
+ attr_str = g_string_append (attr_str, value);
+ } else {
+ escaped_value = vformat_escape_string (value, type);
+ attr_str = g_string_append (attr_str, escaped_value);
+ }
+
+ if (v->next) {
+
+ /* XXX toshok - i hate you, rfc 2426.
+ why doesn't CATEGORIES use a ; like
+ a normal list attribute? */
+ if (!strcmp (attr->name, "CATEGORIES"))
+ attr_str = g_string_append_c (attr_str, ',');
+ else
+ attr_str = g_string_append_c (attr_str, ';');
+ }
+
+ g_free (escaped_value);
+ }
+
+ /* Folding lines:
+ * ^^^^^^^^^^^^^^
+ *
+ * rfc 2426 (vCard), 2.6 Line Delimiting and Folding:
+ * After generating a content line,
+ * lines longer than 75 characters SHOULD be folded according to the
+ * folding procedure described in [MIME-DIR].
+ *
+ * rfc 2445 (iCalendar), 4.1 Content Lines:
+ * Lines of text SHOULD NOT be longer than 75 octets, excluding the line
+ * break. Long content lines SHOULD be split into a multiple line
+ * representations using a line "folding" technique. That is, a long
+ * line can be split between any two characters by inserting a CRLF
+ * immediately followed by a single linear white space character (i.e.,
+ * SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence
+ * of CRLF followed immediately by a single linear white space character
+ * is ignored (i.e., removed) when processing the content type.
+ *
+ * SUMMARY: When generating a content line, lines longer then 75 characters SHOULD be folded!
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * Differences between encodings:
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *
+ * rfc 2425 [MIME-DIR], 5.8.1:
+ * A logical line MAY be continued on the next physical line anywhere
+ * between two characters by inserting a CRLF immediately followed by a
+ * single <WS> (white space) character.
+ *
+ * rfc 2045, 6.7, chapter 5:
+ * The quoted-printable specs says that softbreaks should be generated by inserting a =\r\n
+ * without follwing <WS>
+ *
+ * UTF-8
+ * ^^^^^
+ *
+ * Note that all the line folding above is described in terms of characters
+ * not bytes. In particular, it would be an error to put a line break
+ * within a UTF-8 character.
+ */
+
+ l = 0;
+ do {
+ if (g_utf8_strlen(attr_str->str, attr_str->len) - l > 75) {
+ l += 75;
+
+ /* If using QP, must be sure that we do not fold within a quote sequence */
+ if (format_encoding == VF_ENCODING_QP) {
+ if (g_utf8_get_char(g_utf8_offset_to_pointer(attr_str->str, l-1)) == '=') l--;
+ else if (g_utf8_get_char(g_utf8_offset_to_pointer(attr_str->str, l-2)) == '=') l -= 2;
+ }
+
+ char *p = g_utf8_offset_to_pointer(attr_str->str, l);
+
+ if (format_encoding == VF_ENCODING_QP)
+ attr_str = g_string_insert_len (attr_str, p - attr_str->str, "=" CRLF "", sizeof ("=" CRLF "") - 1);
+ else
+ attr_str = g_string_insert_len (attr_str, p - attr_str->str, CRLF " ", sizeof (CRLF " ") - 1);
+ }
+ else
+ break;
+ } while (l < g_utf8_strlen(attr_str->str, attr_str->len));
+
+ attr_str = g_string_append (attr_str, CRLF);
+ /**
+ * base64= <MIME RFC 1521 base64 text>
+ * the end of the text is marked with two CRLF sequences
+ * this results in one blank line before the start of the
+ * next property
+ **/
+ if( format_encoding == VF_ENCODING_BASE64
+ && (type == VFORMAT_CARD_21))
+ attr_str = g_string_append (attr_str, CRLF);
+
+ str = g_string_append (str, attr_str->str);
+ g_string_free (attr_str, TRUE);
+ }
+
+ switch (type) {
+ case VFORMAT_CARD_21:
+ str = g_string_append (str, "END:VCARD\r\n");
+ break;
+ case VFORMAT_CARD_30:
+ str = g_string_append (str, "END:VCARD\r\n");
+ break;
+ case VFORMAT_TODO_10:
+ case VFORMAT_EVENT_10:
+ str = g_string_append (str, "END:VCALENDAR\r\n");
+ break;
+ case VFORMAT_TODO_20:
+ case VFORMAT_EVENT_20:
+ str = g_string_append (str, "END:VCALENDAR\r\n");
+ break;
+ case VFORMAT_NOTE:
+ str = g_string_append (str, "END:VNOTE\r\n");
+ break;
+ }
+
+ osync_trace(TRACE_EXIT, "%s(%p, %i)", __func__, type);
+ return g_string_free (str, FALSE);
+}
+
+void vformat_dump_structure (VFormat *evc)
+{
+ GList *a;
+ GList *v;
+ int i;
+
+ printf ("VFormat\n");
+ for (a = evc->attributes; a; a = a->next) {
+ GList *p;
+ VFormatAttribute *attr = a->data;
+ printf ("+-- %s\n", attr->name);
+ if (attr->params) {
+ printf (" +- params=\n");
+
+ for (p = attr->params, i = 0; p; p = p->next, i++) {
+ VFormatParam *param = p->data;
+ printf (" | [%d] = %s", i,param->name);
+ printf ("(");
+ for (v = param->values; v; v = v->next) {
+ char *value = vformat_escape_string ((char*)v->data, VFORMAT_CARD_21);
+ printf ("%s", value);
+ if (v->next)
+ printf (",");
+ g_free (value);
+ }
+
+ printf (")\n");
+ }
+ }
+ printf (" +- values=\n");
+ for (v = attr->values, i = 0; v; v = v->next, i++) {
+ printf (" [%d] = `%s'\n", i, (char*)v->data);
+ }
+ }
+}
+
+VFormatAttribute *vformat_attribute_new (const char *attr_group, const char *attr_name)
+{
+ VFormatAttribute *attr;
+
+ attr = g_new0 (VFormatAttribute, 1);
+
+ attr->group = g_strdup (attr_group);
+ attr->name = g_strdup (attr_name);
+
+ return attr;
+}
+
+void
+vformat_attribute_free (VFormatAttribute *attr)
+{
+ g_return_if_fail (attr != NULL);
+
+ g_free (attr->group);
+ g_free (attr->name);
+
+ vformat_attribute_remove_values (attr);
+
+ vformat_attribute_remove_params (attr);
+
+ g_free (attr);
+}
+
+VFormatAttribute*
+vformat_attribute_copy (VFormatAttribute *attr)
+{
+ VFormatAttribute *a;
+ GList *p;
+
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ a = vformat_attribute_new (vformat_attribute_get_group (attr),
+ vformat_attribute_get_name (attr));
+
+ for (p = attr->values; p; p = p->next)
+ vformat_attribute_add_value (a, p->data);
+
+ for (p = attr->params; p; p = p->next)
+ vformat_attribute_add_param (a, vformat_attribute_param_copy (p->data));
+
+ return a;
+}
+
+void
+vformat_remove_attributes (VFormat *evc, const char *attr_group, const char *attr_name)
+{
+ GList *attr;
+
+ g_return_if_fail (attr_name != NULL);
+
+ attr = evc->attributes;
+ while (attr) {
+ GList *next_attr;
+ VFormatAttribute *a = attr->data;
+
+ next_attr = attr->next;
+
+ if (((!attr_group && !a->group) ||
+ (attr_group && !g_ascii_strcasecmp (attr_group, a->group))) &&
+ ((!attr_name && !a->name) || !g_ascii_strcasecmp (attr_name, a->name))) {
+
+ /* matches, remove/delete the attribute */
+ evc->attributes = g_list_remove_link (evc->attributes, attr);
+
+ vformat_attribute_free (a);
+ }
+
+ attr = next_attr;
+ }
+}
+
+void
+vformat_remove_attribute (VFormat *evc, VFormatAttribute *attr)
+{
+ g_return_if_fail (attr != NULL);
+
+ evc->attributes = g_list_remove (evc->attributes, attr);
+ vformat_attribute_free (attr);
+}
+
+void
+vformat_add_attribute (VFormat *evc, VFormatAttribute *attr)
+{
+ g_return_if_fail (attr != NULL);
+
+ evc->attributes = g_list_append (evc->attributes, attr);
+}
+
+void
+vformat_add_attribute_with_value (VFormat *VFormat,
+ VFormatAttribute *attr, const char *value)
+{
+ g_return_if_fail (attr != NULL);
+
+ vformat_attribute_add_value (attr, value);
+
+ vformat_add_attribute (VFormat, attr);
+}
+
+void
+vformat_add_attribute_with_values (VFormat *VFormat, VFormatAttribute *attr, ...)
+{
+ va_list ap;
+ char *v;
+
+ g_return_if_fail (attr != NULL);
+
+ va_start (ap, attr);
+
+ while ((v = va_arg (ap, char*))) {
+ vformat_attribute_add_value (attr, v);
+ }
+
+ va_end (ap);
+
+ vformat_add_attribute (VFormat, attr);
+}
+
+void
+vformat_attribute_add_value (VFormatAttribute *attr, const char *value)
+{
+ g_return_if_fail (attr != NULL);
+
+ attr->values = g_list_append (attr->values, g_strdup (value));
+}
+
+void
+vformat_attribute_add_value_decoded (VFormatAttribute *attr, const char *value, int len)
+{
+ g_return_if_fail (attr != NULL);
+
+ switch (attr->encoding) {
+ case VF_ENCODING_RAW:
+ osync_trace(TRACE_INTERNAL, "can't add_value_decoded with an attribute using RAW encoding. you must set the ENCODING parameter first");
+ break;
+ case VF_ENCODING_BASE64: {
+ char *b64_data = base64_encode_simple (value, len);
+ GString *decoded = g_string_new_len (value, len);
+
+ /* make sure the decoded list is up to date */
+ vformat_attribute_get_values_decoded (attr);
+
+ attr->values = g_list_append (attr->values, b64_data);
+ attr->decoded_values = g_list_append (attr->decoded_values, decoded);
+ break;
+ }
+ case VF_ENCODING_QP: {
+ char *qp_data = quoted_encode_simple ((unsigned char*)value, len);
+ GString *decoded = g_string_new (value);
+
+ /* make sure the decoded list is up to date */
+ vformat_attribute_get_values_decoded (attr);
+
+ attr->values = g_list_append (attr->values, qp_data);
+ attr->decoded_values = g_list_append (attr->decoded_values, decoded);
+ break;
+ }
+ case VF_ENCODING_8BIT: {
+ char *data = g_strdup(value);
+ GString *decoded = g_string_new (value);
+
+ /* make sure the decoded list is up to date */
+ vformat_attribute_get_values_decoded (attr);
+
+ attr->values = g_list_append (attr->values, data);
+ attr->decoded_values = g_list_append (attr->decoded_values, decoded);
+ break;
+ }
+ }
+}
+
+void
+vformat_attribute_add_values (VFormatAttribute *attr, ...)
+{
+ va_list ap;
+ char *v;
+
+ g_return_if_fail (attr != NULL);
+
+ va_start (ap, attr);
+
+ while ((v = va_arg (ap, char*))) {
+ vformat_attribute_add_value (attr, v);
+ }
+
+ va_end (ap);
+}
+
+static void
+free_gstring (GString *str)
+{
+ g_string_free (str, TRUE);
+}
+
+void
+vformat_attribute_remove_values (VFormatAttribute *attr)
+{
+ g_return_if_fail (attr != NULL);
+
+ g_list_foreach (attr->values, (GFunc)g_free, NULL);
+ g_list_free (attr->values);
+ attr->values = NULL;
+
+ g_list_foreach (attr->decoded_values, (GFunc)free_gstring, NULL);
+ g_list_free (attr->decoded_values);
+ attr->decoded_values = NULL;
+}
+
+void
+vformat_attribute_remove_params (VFormatAttribute *attr)
+{
+ g_return_if_fail (attr != NULL);
+
+ g_list_foreach (attr->params, (GFunc)vformat_attribute_param_free, NULL);
+ g_list_free (attr->params);
+ attr->params = NULL;
+
+ /* also remove the cached encoding on this attribute */
+ attr->encoding_set = FALSE;
+ attr->encoding = VF_ENCODING_RAW;
+}
+
+VFormatParam*
+vformat_attribute_param_new (const char *name)
+{
+ VFormatParam *param = g_new0 (VFormatParam, 1);
+ param->name = g_strdup (name);
+
+ return param;
+}
+
+void
+vformat_attribute_param_free (VFormatParam *param)
+{
+ g_return_if_fail (param != NULL);
+
+ g_free (param->name);
+
+ vformat_attribute_param_remove_values (param);
+
+ g_free (param);
+}
+
+VFormatParam*
+vformat_attribute_param_copy (VFormatParam *param)
+{
+ VFormatParam *p;
+ GList *l;
+
+ g_return_val_if_fail (param != NULL, NULL);
+
+ p = vformat_attribute_param_new (vformat_attribute_param_get_name (param));
+
+ for (l = param->values; l; l = l->next) {
+ vformat_attribute_param_add_value (p, l->data);
+ }
+
+ return p;
+}
+
+void
+vformat_attribute_add_param (VFormatAttribute *attr,
+ VFormatParam *param)
+{
+ g_return_if_fail (attr != NULL);
+ g_return_if_fail (param != NULL);
+
+ attr->params = g_list_append (attr->params, param);
+
+ /* we handle our special encoding stuff here */
+
+ if (!g_ascii_strcasecmp (param->name, "ENCODING")) {
+ if (attr->encoding_set) {
+ osync_trace(TRACE_INTERNAL, "ENCODING specified twice");
+ return;
+ }
+
+ if (param->values && param->values->data) {
+ if (_helper_is_base64((const char*)param->values->data))
+ attr->encoding = VF_ENCODING_BASE64;
+ else if (!g_ascii_strcasecmp ((char*)param->values->data, "QUOTED-PRINTABLE"))
+ attr->encoding = VF_ENCODING_QP;
+ else if (!g_ascii_strcasecmp ((char *)param->values->data, "8BIT"))
+ attr->encoding = VF_ENCODING_8BIT;
+ else {
+ osync_trace(TRACE_INTERNAL, "Unknown value `%s' for ENCODING parameter. values will be treated as raw",
+ (char*)param->values->data);
+ }
+
+ attr->encoding_set = TRUE;
+ }
+ else {
+ osync_trace(TRACE_INTERNAL, "ENCODING parameter added with no value");
+ }
+ }
+}
+
+VFormatParam *vformat_attribute_find_param(VFormatAttribute *attr, const char *name)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+ GList *p = NULL;
+ for (p = attr->params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ if (!g_ascii_strcasecmp (param->name, name))
+ return param;
+ }
+ return NULL;
+}
+
+void
+vformat_attribute_set_value (VFormatAttribute *attr,
+ int nth, const char *value)
+{
+ GList *param = g_list_nth(attr->values, nth);
+ g_free(param->data);
+ param->data = g_strdup(value);
+}
+
+void
+vformat_attribute_param_add_value (VFormatParam *param,
+ const char *value)
+{
+ g_return_if_fail (param != NULL);
+
+ param->values = g_list_append (param->values, g_strdup (value));
+}
+
+void
+vformat_attribute_param_add_values (VFormatParam *param,
+ ...)
+{
+ va_list ap;
+ char *v;
+
+ g_return_if_fail (param != NULL);
+
+ va_start (ap, param);
+
+ while ((v = va_arg (ap, char*))) {
+ vformat_attribute_param_add_value (param, v);
+ }
+
+ va_end (ap);
+}
+
+void
+vformat_attribute_add_param_with_value (VFormatAttribute *attr, const char *name, const char *value)
+{
+ g_return_if_fail (attr != NULL);
+ g_return_if_fail (name != NULL);
+
+ if (!value)
+ return;
+
+ VFormatParam *param = vformat_attribute_param_new(name);
+
+ vformat_attribute_param_add_value (param, value);
+
+ vformat_attribute_add_param (attr, param);
+}
+
+void
+vformat_attribute_add_param_with_values (VFormatAttribute *attr,
+ VFormatParam *param, ...)
+{
+ va_list ap;
+ char *v;
+
+ g_return_if_fail (attr != NULL);
+ g_return_if_fail (param != NULL);
+
+ va_start (ap, param);
+
+ while ((v = va_arg (ap, char*))) {
+ vformat_attribute_param_add_value (param, v);
+ }
+
+ va_end (ap);
+
+ vformat_attribute_add_param (attr, param);
+}
+
+void
+vformat_attribute_param_remove_values (VFormatParam *param)
+{
+ g_return_if_fail (param != NULL);
+
+ g_list_foreach (param->values, (GFunc)g_free, NULL);
+ g_list_free (param->values);
+ param->values = NULL;
+}
+
+GList*
+vformat_get_attributes (VFormat *format)
+{
+ return format->attributes;
+}
+
+const char*
+vformat_attribute_get_group (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ return attr->group;
+}
+
+const char*
+vformat_attribute_get_name (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ return attr->name;
+}
+
+GList*
+vformat_attribute_get_values (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ return attr->values;
+}
+
+GList*
+vformat_attribute_get_values_decoded (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ if (!attr->decoded_values) {
+ GList *l;
+ switch (attr->encoding) {
+ case VF_ENCODING_RAW:
+ case VF_ENCODING_8BIT:
+ for (l = attr->values; l; l = l->next)
+ attr->decoded_values = g_list_append (attr->decoded_values, g_string_new ((char*)l->data));
+ break;
+ case VF_ENCODING_BASE64:
+ for (l = attr->values; l; l = l->next) {
+ char *decoded = g_strdup ((char*)l->data);
+ int len = base64_decode_simple (decoded, strlen (decoded));
+ attr->decoded_values = g_list_append (attr->decoded_values, g_string_new_len (decoded, len));
+ g_free (decoded);
+ }
+ break;
+ case VF_ENCODING_QP:
+ for (l = attr->values; l; l = l->next) {
+ if (!(l->data))
+ continue;
+ char *decoded = g_strdup ((char*)l->data);
+ int len = quoted_decode_simple (decoded, strlen (decoded));
+ attr->decoded_values = g_list_append (attr->decoded_values, g_string_new_len (decoded, len));
+ g_free (decoded);
+ }
+ break;
+ }
+ }
+
+ return attr->decoded_values;
+}
+
+gboolean
+vformat_attribute_is_single_valued (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, FALSE);
+
+ if (attr->values == NULL
+ || attr->values->next != NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+char*
+vformat_attribute_get_value (VFormatAttribute *attr)
+{
+ GList *values;
+
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ values = vformat_attribute_get_values (attr);
+
+ if (!vformat_attribute_is_single_valued (attr))
+ osync_trace(TRACE_INTERNAL, "vformat_attribute_get_value called on multivalued attribute");
+
+ return values ? g_strdup ((char*)values->data) : NULL;
+}
+
+GString*
+vformat_attribute_get_value_decoded (VFormatAttribute *attr)
+{
+ GList *values;
+ GString *str = NULL;
+
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ values = vformat_attribute_get_values_decoded (attr);
+
+ if (!vformat_attribute_is_single_valued (attr))
+ osync_trace(TRACE_INTERNAL, "vformat_attribute_get_value_decoded called on multivalued attribute");
+
+ if (values)
+ str = values->data;
+
+ return str ? g_string_new_len (str->str, str->len) : NULL;
+}
+
+const char *vformat_attribute_get_nth_value(VFormatAttribute *attr, int nth)
+{
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ if (!values)
+ return NULL;
+ GString *retstr = (GString *)g_list_nth_data(values, nth);
+ if (!retstr)
+ return NULL;
+
+ if (!g_utf8_validate(retstr->str, -1, NULL)) {
+ values = vformat_attribute_get_values(attr);
+ if (!values)
+ return NULL;
+ return g_list_nth_data(values, nth);
+ }
+
+ return retstr->str;
+}
+
+gboolean
+vformat_attribute_has_type (VFormatAttribute *attr, const char *typestr)
+{
+ GList *params;
+ GList *p;
+
+ g_return_val_if_fail (attr != NULL, FALSE);
+ g_return_val_if_fail (typestr != NULL, FALSE);
+
+ params = vformat_attribute_get_params (attr);
+
+ for (p = params; p; p = p->next) {
+ VFormatParam *param = p->data;
+
+ if (!strcasecmp (vformat_attribute_param_get_name (param), "TYPE")) {
+ GList *values = vformat_attribute_param_get_values (param);
+ GList *v;
+
+ for (v = values; v; v = v->next) {
+ if (!strcasecmp ((char*)v->data, typestr))
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+gboolean vformat_attribute_has_param(VFormatAttribute *attr, const char *name)
+{
+ g_return_val_if_fail (attr != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ GList *params = vformat_attribute_get_params(attr);
+ GList *p;
+ for (p = params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ if (!strcasecmp(name, vformat_attribute_param_get_name(param)))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+GList*
+vformat_attribute_get_params (VFormatAttribute *attr)
+{
+ g_return_val_if_fail (attr != NULL, NULL);
+
+ return attr->params;
+}
+
+const char*
+vformat_attribute_param_get_name (VFormatParam *param)
+{
+ g_return_val_if_fail (param != NULL, NULL);
+
+ return param->name;
+}
+
+GList*
+vformat_attribute_param_get_values (VFormatParam *param)
+{
+ g_return_val_if_fail (param != NULL, NULL);
+
+ return param->values;
+}
+
+const char *vformat_attribute_param_get_nth_value(VFormatParam *param, int nth)
+{
+ const char *ret = NULL;
+ GList *values = vformat_attribute_param_get_values(param);
+ if (!values)
+ return NULL;
+ ret = g_list_nth_data(values, nth);
+ return ret;
+}
+
+static const char *base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+//static unsigned char _evc_base64_rank[256];
+
+static void base64_init(char *rank)
+{
+ int i;
+
+ memset(rank, 0xff, sizeof(rank));
+ for (i=0;i<64;i++) {
+ rank[(unsigned int)base64_alphabet[i]] = i;
+ }
+ rank['='] = 0;
+}
+
+/* call this when finished encoding everything, to
+ flush off the last little bit */
+static size_t base64_encode_close(unsigned char *in, size_t inlen, gboolean break_lines, unsigned char *out, int *state, int *save)
+{
+ int c1, c2;
+ unsigned char *outptr = out;
+
+ if (inlen>0)
+ outptr += base64_encode_step(in, inlen, break_lines, outptr, state, save);
+
+ c1 = ((unsigned char *)save)[1];
+ c2 = ((unsigned char *)save)[2];
+
+ switch (((char *)save)[0]) {
+ case 2:
+ outptr[2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ];
+ g_assert(outptr[2] != 0);
+ goto skip;
+ case 1:
+ outptr[2] = '=';
+ skip:
+ outptr[0] = base64_alphabet[ c1 >> 2 ];
+ outptr[1] = base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 )];
+ outptr[3] = '=';
+ outptr += 4;
+ break;
+ }
+ if (break_lines)
+ *outptr++ = '\n';
+
+ *save = 0;
+ *state = 0;
+
+ return outptr-out;
+}
+
+/*
+ performs an 'encode step', only encodes blocks of 3 characters to the
+ output at a time, saves left-over state in state and save (initialise to
+ 0 on first invocation).
+*/
+static size_t base64_encode_step(unsigned char *in, size_t len, gboolean break_lines, unsigned char *out, int *state, int *save)
+{
+ register unsigned char *inptr, *outptr;
+
+ if (len<=0)
+ return 0;
+
+ inptr = in;
+ outptr = out;
+
+ if (len + ((char *)save)[0] > 2) {
+ unsigned char *inend = in+len-2;
+ register int c1, c2, c3;
+ register int already;
+
+ already = *state;
+
+ switch (((char *)save)[0]) {
+ case 1: c1 = ((unsigned char *)save)[1]; goto skip1;
+ case 2: c1 = ((unsigned char *)save)[1];
+ c2 = ((unsigned char *)save)[2]; goto skip2;
+ }
+
+ /* yes, we jump into the loop, no i'm not going to change it, it's beautiful! */
+ while (inptr < inend) {
+ c1 = *inptr++;
+ skip1:
+ c2 = *inptr++;
+ skip2:
+ c3 = *inptr++;
+ *outptr++ = base64_alphabet[ c1 >> 2 ];
+ *outptr++ = base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 ) ];
+ *outptr++ = base64_alphabet[ ( (c2 &0x0f) << 2 ) | (c3 >> 6) ];
+ *outptr++ = base64_alphabet[ c3 & 0x3f ];
+ /* this is a bit ugly ... */
+ if (break_lines && (++already)>=19) {
+ *outptr++='\n';
+ already = 0;
+ }
+ }
+
+ ((char *)save)[0] = 0;
+ len = 2-(inptr-inend);
+ *state = already;
+ }
+
+ if (len>0) {
+ register char *saveout;
+
+ /* points to the slot for the next char to save */
+ saveout = & (((char *)save)[1]) + ((char *)save)[0];
+
+ /* len can only be 0 1 or 2 */
+ switch(len) {
+ case 2: *saveout++ = *inptr++;
+ case 1: *saveout++ = *inptr++;
+ }
+ ((char *)save)[0]+=len;
+ }
+
+ return outptr-out;
+}
+
+
+/**
+ * base64_decode_step: decode a chunk of base64 encoded data
+ * @in: input stream
+ * @len: max length of data to decode
+ * @out: output stream
+ * @state: holds the number of bits that are stored in @save
+ * @save: leftover bits that have not yet been decoded
+ *
+ * Decodes a chunk of base64 encoded data
+ **/
+static size_t base64_decode_step(unsigned char *in, size_t len, unsigned char *out, int *state, unsigned int *save)
+{
+ unsigned char base64_rank[256];
+ base64_init((char*)base64_rank);
+
+ register unsigned char *inptr, *outptr;
+ unsigned char *inend, c;
+ register unsigned int v;
+ int i;
+
+ inend = in+len;
+ outptr = out;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
+ v=*save;
+ i=*state;
+ inptr = in;
+ while (inptr<inend) {
+ c = base64_rank[*inptr++];
+ if (c != 0xff) {
+ v = (v<<6) | c;
+ i++;
+ if (i==4) {
+ *outptr++ = v>>16;
+ *outptr++ = v>>8;
+ *outptr++ = v;
+ i=0;
+ }
+ }
+ }
+
+ *save = v;
+ *state = i;
+
+ /* quick scan back for '=' on the end somewhere */
+ /* fortunately we can drop 1 output char for each trailing = (upto 2) */
+ i=2;
+ while (inptr>in && i) {
+ inptr--;
+ if (base64_rank[*inptr] != 0xff) {
+ if (*inptr == '=' && outptr>out)
+ outptr--;
+ i--;
+ }
+ }
+
+ /* if i!= 0 then there is a truncation error! */
+ return outptr-out;
+}
+
+char *base64_encode_simple (const char *data, size_t len)
+{
+ unsigned char *out;
+ int state = 0, outlen;
+ unsigned int save = 0;
+
+ g_return_val_if_fail (data != NULL, NULL);
+
+ out = g_malloc (len * 4 / 3 + 5);
+ outlen = base64_encode_close ((unsigned char *)data, len, FALSE,
+ out, &state, (int*)&save);
+ out[outlen] = '\0';
+ return (char *)out;
+}
+
+size_t base64_decode_simple (char *data, size_t len)
+{
+ int state = 0;
+ unsigned int save = 0;
+
+ g_return_val_if_fail (data != NULL, 0);
+
+ return base64_decode_step ((unsigned char *)data, len,
+ (unsigned char *)data, &state, &save);
+}
+
+char *quoted_encode_simple(const unsigned char *string, int len)
+{
+ GString *tmp = g_string_new("");
+
+ int i = 0;
+ while(string[i] != 0) {
+ if (string[i] > 127 || string[i] == 13 || string[i] == 10 || string[i] == '=') {
+ g_string_append_printf(tmp, "=%02X", string[i]);
+ } else {
+ g_string_append_c(tmp, string[i]);
+ }
+ i++;
+ }
+
+ char *ret = tmp->str;
+ g_string_free(tmp, FALSE);
+ return ret;
+}
+
+
+size_t quoted_decode_simple (char *data, size_t len)
+{
+ g_return_val_if_fail (data != NULL, 0);
+
+ GString *string = g_string_new(data);
+ if (!string)
+ return 0;
+
+ char hex[5];
+ hex[4] = 0;
+
+ while (1) {
+ //Get the index of the next encoded char
+ int i = strcspn(string->str, "=");
+ if (i >= strlen(string->str))
+ break;
+
+ strcpy(hex, "0x");
+ strncat(hex, &string->str[i + 1], 2);
+ char rep = ((int)(strtod(hex, NULL)));
+ g_string_erase(string, i, 2);
+ g_string_insert_c(string, i, rep);
+ }
+
+ memset(data, 0, strlen(data));
+ strcpy(data, string->str);
+ g_string_free(string, 1);
+
+ return strlen(data);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.h b/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.h
new file mode 100644
index 00000000..e754e02b
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/vformat.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2003 Ximian, Inc. 2005 Armin Bauer
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * 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
+ *
+ * Author: Chris Toshok ([email protected])
+ * Author: Armin Bauer ([email protected])
+ *
+ */
+
+#ifndef _VFORMAT_H
+#define _VFORMAT_H
+
+#include <glib.h>
+#include <time.h>
+
+typedef enum {
+ VFORMAT_CARD_21,
+ VFORMAT_CARD_30,
+ VFORMAT_NOTE,
+ VFORMAT_EVENT_10,
+ VFORMAT_EVENT_20,
+ VFORMAT_TODO_10,
+ VFORMAT_TODO_20
+} VFormatType;
+
+typedef struct VFormat {
+ //VFormatType type;
+ GList *attributes;
+} VFormat;
+
+#define CRLF "\r\n"
+
+typedef enum {
+ VF_ENCODING_RAW, /* no encoding */
+ VF_ENCODING_BASE64, /* base64 */
+ VF_ENCODING_QP, /* quoted-printable */
+ VF_ENCODING_8BIT
+} VFormatEncoding;
+
+typedef struct VFormatAttribute {
+ char *group;
+ char *name;
+ GList *params; /* VFormatParam */
+ GList *values;
+ GList *decoded_values;
+ VFormatEncoding encoding;
+ gboolean encoding_set;
+} VFormatAttribute;
+
+typedef struct VFormatParam {
+ char *name;
+ GList *values; /* GList of char*'s*/
+} VFormatParam;
+
+
+/*VFormat *vcard_new(VFormatType type);
+VFormat *vcard_new_from_string (const char *str, VFormatType type);
+//char *vcard_to_string(VFormat *card, VFormatType format);
+
+VFormat *vnote_new(void);
+VFormat *vnote_new_from_string(const char *str);
+//char *vnote_to_string(VFormat *note);
+
+
+VFormat *vevent_new(void);
+VFormat *vevent_new_from_string(const char *str);
+//char *vevent_to_string(VFormat *event);
+
+VFormat *vtodo_new(void);
+VFormat *vtodo_new_from_string(const char *str);*/
+//char *vtodo_to_string(VFormat *todo);
+
+/* mostly for debugging */
+VFormat *vformat_new(void);
+VFormat *vformat_new_from_string(const char *str);
+void vformat_dump_structure(VFormat *format);
+char *vformat_to_string(VFormat *evc, VFormatType type);
+time_t vformat_time_to_unix(const char *inptime);
+
+/* attributes */
+VFormatAttribute *vformat_attribute_new (const char *attr_group, const char *attr_name);
+void vformat_attribute_free (VFormatAttribute *attr);
+VFormatAttribute *vformat_attribute_copy (VFormatAttribute *attr);
+void vformat_remove_attributes (VFormat *vformat, const char *attr_group, const char *attr_name);
+void vformat_remove_attribute (VFormat *vformat, VFormatAttribute *attr);
+void vformat_add_attribute (VFormat *vformat, VFormatAttribute *attr);
+void vformat_add_attribute_with_value (VFormat *vformat, VFormatAttribute *attr, const char *value);
+void vformat_add_attribute_with_values (VFormat *vformat, VFormatAttribute *attr, ...);
+void vformat_attribute_add_value (VFormatAttribute *attr, const char *value);
+void vformat_attribute_set_value (VFormatAttribute *attr, int nth, const char *value);
+void vformat_attribute_add_value_decoded (VFormatAttribute *attr, const char *value, int len);
+void vformat_attribute_add_values (VFormatAttribute *attr, ...);
+void vformat_attribute_remove_values (VFormatAttribute *attr);
+void vformat_attribute_remove_params (VFormatAttribute *attr);
+VFormatAttribute *vformat_find_attribute (VFormat *evc, const char *name);
+
+/* attribute parameters */
+VFormatParam* vformat_attribute_param_new (const char *param_name);
+void vformat_attribute_param_free (VFormatParam *param);
+VFormatParam* vformat_attribute_param_copy (VFormatParam *param);
+void vformat_attribute_add_param (VFormatAttribute *attr, VFormatParam *param);
+VFormatParam *vformat_attribute_find_param(VFormatAttribute *attr, const char *name);
+void vformat_attribute_add_param_with_value (VFormatAttribute *attr, const char *name, const char *value);
+void vformat_attribute_add_param_with_values (VFormatAttribute *attr,
+ VFormatParam *param, ...);
+
+void vformat_attribute_param_add_value (VFormatParam *param,
+ const char *value);
+void vformat_attribute_param_add_values (VFormatParam *param,
+ ...);
+void vformat_attribute_param_remove_values (VFormatParam *param);
+gboolean vformat_attribute_has_param(VFormatAttribute *attr, const char *name);
+
+/* VFormat* accessors. nothing returned from these functions should be
+ freed by the caller. */
+GList* vformat_get_attributes (VFormat *vformat);
+const char* vformat_attribute_get_group (VFormatAttribute *attr);
+const char* vformat_attribute_get_name (VFormatAttribute *attr);
+GList* vformat_attribute_get_values (VFormatAttribute *attr); /* GList elements are of type char* */
+GList* vformat_attribute_get_values_decoded (VFormatAttribute *attr); /* GList elements are of type GString* */
+const char *vformat_attribute_get_nth_value(VFormatAttribute *attr, int nth);
+
+/* special accessors for single valued attributes */
+gboolean vformat_attribute_is_single_valued (VFormatAttribute *attr);
+char* vformat_attribute_get_value (VFormatAttribute *attr);
+GString* vformat_attribute_get_value_decoded (VFormatAttribute *attr);
+
+GList* vformat_attribute_get_params (VFormatAttribute *attr);
+const char* vformat_attribute_param_get_name (VFormatParam *param);
+GList* vformat_attribute_param_get_values (VFormatParam *param);
+const char *vformat_attribute_param_get_nth_value(VFormatParam *param, int nth);
+
+/* special TYPE= parameter predicate (checks for TYPE=@typestr */
+gboolean vformat_attribute_has_type (VFormatAttribute *attr, const char *typestr);
+
+/* Utility functions. */
+char* vformat_escape_string (const char *str, VFormatType type);
+char* vformat_unescape_string (const char *str);
+
+#endif /* _VFORMAT_H */
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-evolution.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-evolution.c
new file mode 100644
index 00000000..648b197a
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-evolution.c
@@ -0,0 +1,522 @@
+/*
+ * x-evo - A plugin for evolution extensions for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include <glib.h>
+
+#include "xml-vcard.h"
+
+static xmlNode *handle_x_aim_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling x-aim attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-AIM", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_file_as_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling file_as attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"FileAs", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_manager_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Manager attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Manager", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_assistant_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Assistant attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Assistant", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_anniversary_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Anniversary attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Anniversary", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_spouse_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Spouse attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Spouse", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_blog_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling BlogUrl attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"BlogUrl", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_calendar_url_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling CalendarUrl attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"CalendarUrl", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_free_busy_url_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling FreeBusyUrl attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"FreeBusyUrl", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_video_chat_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling VideoUrl attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"VideoUrl", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_wants_html_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling WantsHtml attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"WantsHtml", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_yahoo_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling IM-Yahoo attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-Yahoo", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_icq_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling IM-ICQ attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-ICQ", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_groupwise_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling GroupwiseDirectory attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"GroupwiseDirectory", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_jabber_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Jabber attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-Jabber", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_msn_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling MSN attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-MSN", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+//evo2s role is more like a profession so we map it there
+static xmlNode *handle_role_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling role attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Profession", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static void handle_slot_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Slot parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Slot",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_assistant_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Assistant parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type", (xmlChar*)"Assistant");
+}
+
+static void handle_callback_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Callback parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type", (xmlChar*)"Callback");
+}
+
+static void handle_company_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Company parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type", (xmlChar*)"Company");
+}
+
+static void handle_telex_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Telex parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type", (xmlChar*)"Telex");
+}
+
+static void handle_radio_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Radio parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type", (xmlChar*)"Radio");
+}
+
+static osync_bool init_x_evo_to_xml(void *input)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, input);
+
+ GHashTable *table = (GHashTable *)input;
+
+ g_hash_table_insert(table, "X-EVOLUTION-FILE-AS", handle_file_as_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-MANAGER", handle_manager_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-ASSISTANT", handle_assistant_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-ANNIVERSARY", handle_anniversary_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-SPOUSE", handle_spouse_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-BLOG-URL", handle_blog_attribute);
+ g_hash_table_insert(table, "CALURI", handle_calendar_url_attribute);
+ g_hash_table_insert(table, "FBURL", handle_free_busy_url_attribute);
+ g_hash_table_insert(table, "X-EVOLUTION-VIDEO-URL", handle_video_chat_attribute);
+ g_hash_table_insert(table, "X-MOZILLA-HTML", handle_wants_html_attribute);
+ g_hash_table_insert(table, "X-YAHOO", handle_yahoo_attribute);
+ g_hash_table_insert(table, "X-ICQ", handle_icq_attribute);
+ g_hash_table_insert(table, "X-GROUPWISE", handle_groupwise_attribute);
+ g_hash_table_insert(table, "X-AIM", handle_x_aim_attribute);
+ g_hash_table_insert(table, "X-JABBER", handle_jabber_attribute);
+ g_hash_table_insert(table, "X-MSN", handle_msn_attribute);
+
+ g_hash_table_insert(table, "X-EVOLUTION-UI-SLOT", handle_slot_parameter);
+ g_hash_table_insert(table, "TYPE=X-EVOLUTION-ASSISTANT", handle_assistant_parameter);
+ g_hash_table_insert(table, "TYPE=X-EVOLUTION-CALLBACK", handle_callback_parameter);
+ g_hash_table_insert(table, "TYPE=X-EVOLUTION-COMPANY", handle_company_parameter);
+ g_hash_table_insert(table, "TYPE=X-EVOLUTION-TELEX", handle_telex_parameter);
+ g_hash_table_insert(table, "TYPE=X-EVOLUTION-RADIO", handle_radio_parameter);
+
+ //Overwrite Role
+ g_hash_table_insert(table, "ROLE", handle_role_attribute);
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool needs_encoding(const unsigned char *tmp, const char *encoding)
+{
+ int i = 0;
+ if (!strcmp(encoding, "QUOTED-PRINTABLE")) {
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127 || tmp[i] == 10 || tmp[i] == 13)
+ return TRUE;
+ i++;
+ }
+ } else {
+ return !g_utf8_validate((gchar*)tmp, -1, NULL);
+ }
+ return FALSE;
+}
+
+static osync_bool needs_charset(const unsigned char *tmp)
+{
+ int i = 0;
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+static void add_value(VFormatAttribute *attr, xmlNode *parent, const char *name, const char *encoding)
+{
+ char *tmp = osxml_find_node(parent, name);
+ if (!tmp)
+ return;
+
+ if (needs_charset((unsigned char*)tmp))
+ if (!vformat_attribute_has_param (attr, "CHARSET"))
+ vformat_attribute_add_param_with_value(attr, "CHARSET", "UTF-8");
+
+ if (needs_encoding((unsigned char*)tmp, encoding)) {
+ if (!vformat_attribute_has_param (attr, "ENCODING"))
+ vformat_attribute_add_param_with_value(attr, "ENCODING", encoding);
+ vformat_attribute_add_value_decoded(attr, tmp, strlen(tmp) + 1);
+ } else
+ vformat_attribute_add_value(attr, tmp);
+ g_free(tmp);
+}
+
+static VFormatAttribute *handle_xml_file_as_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling file_as xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-FILE-AS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_manager_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling manager xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-MANAGER");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_assistant_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling assistant xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-ASSISTANT");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_anniversary_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling anniversary xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-ANNIVERSARY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_spouse_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling spouse xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-SPOUSE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_blog_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling blog_url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-BLOG-URL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_calendar_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling calendar_url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CALURI");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_free_busy_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling free_busy_url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "FBURL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_video_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling videourl xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-EVOLUTION-VIDEO-URL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_wants_html_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling wants_html xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-MOZILLA-HTML");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_yahoo_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling yahoo xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-YAHOO");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_icq_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling icq xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-ICQ");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_groupwise_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling groupwise xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-GROUPWISE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aim_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling aim xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-AIM");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_jabber_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling jabber xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-JABBER");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_msn_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-MSN");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+//We map the profession to the ROLE
+static VFormatAttribute *handle_xml_profession_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling profession xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ROLE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static void handle_xml_slot_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling slot xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "X-EVOLUTION-UI-SLOT", content);
+ g_free(content);
+}
+
+static void handle_xml_assistant_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling assistant xml parameter");
+ vformat_attribute_add_param_with_value(attr, "TYPE", "X-EVOLUTION-ASSISTANT");
+}
+
+static void handle_xml_callback_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling callback xml parameter");
+ vformat_attribute_add_param_with_value(attr, "TYPE", "X-EVOLUTION-CALLBACK");
+}
+
+static void handle_xml_company_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling company xml parameter");
+ vformat_attribute_add_param_with_value(attr, "TYPE", "X-EVOLUTION-COMPANY");
+}
+
+static void handle_xml_telex_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling telex xml parameter");
+ vformat_attribute_add_param_with_value(attr, "TYPE", "X-EVOLUTION-TELEX");
+}
+
+static void handle_xml_radio_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling radio xml parameter");
+ vformat_attribute_add_param_with_value(attr, "TYPE", "X-EVOLUTION-RADIO");
+}
+
+static osync_bool init_xml_to_x_evo(void *input)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, input);
+
+ OSyncHookTables *hooks = (OSyncHookTables *)input;
+
+ g_hash_table_insert(hooks->attributes, "FileAs", handle_xml_file_as_attribute);
+ g_hash_table_insert(hooks->attributes, "Manager", handle_xml_manager_attribute);
+ g_hash_table_insert(hooks->attributes, "Assistant", handle_xml_assistant_attribute);
+ g_hash_table_insert(hooks->attributes, "Anniversary", handle_xml_anniversary_attribute);
+ g_hash_table_insert(hooks->attributes, "Spouse", handle_xml_spouse_attribute);
+ g_hash_table_insert(hooks->attributes, "BlogUrl", handle_xml_blog_url_attribute);
+ g_hash_table_insert(hooks->attributes, "CalendarUrl", handle_xml_calendar_url_attribute);
+ g_hash_table_insert(hooks->attributes, "FreeBusyUrl", handle_xml_free_busy_url_attribute);
+ g_hash_table_insert(hooks->attributes, "VideoUrl", handle_xml_video_url_attribute);
+ g_hash_table_insert(hooks->attributes, "WantsHtml", handle_xml_wants_html_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-Yahoo", handle_xml_yahoo_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-ICQ", handle_xml_icq_attribute);
+ g_hash_table_insert(hooks->attributes, "GroupwiseDirectory", handle_xml_groupwise_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-AIM", handle_xml_aim_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-Jabber", handle_xml_jabber_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-MSN", handle_xml_msn_attribute);
+ //Overwrite Profession handler
+ g_hash_table_insert(hooks->attributes, "Profession", handle_xml_profession_attribute);
+
+
+ g_hash_table_insert(hooks->parameters, "Slot", handle_xml_slot_parameter);
+ g_hash_table_insert(hooks->parameters, "Type=Assistant", handle_xml_assistant_parameter);
+ g_hash_table_insert(hooks->parameters, "Type=Callback", handle_xml_callback_parameter);
+ g_hash_table_insert(hooks->parameters, "Type=Company", handle_xml_company_parameter);
+ g_hash_table_insert(hooks->parameters, "Type=Telex", handle_xml_telex_parameter);
+ g_hash_table_insert(hooks->parameters, "Type=Radio", handle_xml_radio_parameter);
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "contact");
+ osync_env_register_objformat(env, "contact", "xml-contact");
+
+ osync_env_register_extension(env, "vcard21", "xml-contact", "evolution", init_x_evo_to_xml);
+ osync_env_register_extension(env, "xml-contact", "vcard21", "evolution", init_xml_to_x_evo);
+
+ osync_env_register_extension(env, "vcard30", "xml-contact", "evolution", init_x_evo_to_xml);
+ osync_env_register_extension(env, "xml-contact", "vcard30", "evolution", init_xml_to_x_evo);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-kde.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-kde.c
new file mode 100644
index 00000000..575d61e0
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-kde.c
@@ -0,0 +1,505 @@
+/*
+ * x-kde - A plugin for kde extensions for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include <glib.h>
+
+#include "xml-vcard.h"
+
+static xmlNode *handle_aim_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling x-aim attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-AIM", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_manager_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Manager attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Manager", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_assistant_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Assistant attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Assistant", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_anniversary_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Anniversary attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Anniversary", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_spouse_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Spouse attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Spouse", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_blog_url_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Blog Url attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"BlogUrl", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_yahoo_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling IM-Yahoo attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-Yahoo", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_icq_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling IM-ICQ attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-ICQ", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_jabber_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Jabber attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-Jabber", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_msn_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling MSN attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-MSN", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_department_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling department attribute");
+ xmlNode *current = NULL;
+
+ //We need to check first if the node already exists.
+ if (!(current = osxml_get_node(root, "Organization")))
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"Organization", NULL);
+
+ osxml_node_add(current, "Department", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_office_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling office attribute");
+ xmlNode *current = NULL;
+
+ //We need to check first if the node already exists.
+ if (!(current = osxml_get_node(root, "Organization")))
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"Organization", NULL);
+
+ osxml_node_add(current, "Unit", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_profession_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling profession attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Profession", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_gadu_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling gadu attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IM-GaduGadu", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_irc_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling IRC attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"IRC", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_sms_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling SMS attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"SMS", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_organization_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Organization attribute");
+ xmlNode *current = NULL;
+
+ //We need to check first if the node already exists.
+ if (!(current = osxml_get_node(root, "Organization")))
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"Organization", NULL);
+
+ osxml_node_add(current, "Name", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "Department", vformat_attribute_get_nth_value(attr, 1));
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ values = g_list_nth(values, 2);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Unit", retstr->str);
+ }
+ return current;
+}
+
+static xmlNode *handle_x_kde_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling X-KDE attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"KDE-Extension", NULL);
+ osxml_node_add(current, "ExtName", vformat_attribute_get_name(attr));
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static osync_bool init_kde_to_xml(void *input)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, input);
+
+ GHashTable *table = (GHashTable *)input;
+
+ g_hash_table_insert(table, "X-KADDRESSBOOK-CRYPTOENCRYPTPREF", handle_x_kde_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-CRYPTOPROTOPREF", handle_x_kde_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-CRYPTOSIGNPREF", handle_x_kde_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-OPENPGPFP", handle_x_kde_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-IMAddress", handle_x_kde_attribute);
+
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-ManagersName", handle_manager_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-AssistantsName", handle_assistant_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-Anniversary", handle_anniversary_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-Department", handle_department_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-Office", handle_office_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-Profession", handle_profession_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-X-SpousesName", handle_spouse_attribute);
+ g_hash_table_insert(table, "X-KADDRESSBOOK-BlogFeed", handle_blog_url_attribute);
+ g_hash_table_insert(table, "X-messaging/yahoo-All", handle_yahoo_attribute);
+ g_hash_table_insert(table, "X-messaging/icq-All", handle_icq_attribute);
+ g_hash_table_insert(table, "X-messaging/aim-All", handle_aim_attribute);
+ g_hash_table_insert(table, "X-messaging/xmpp-All", handle_jabber_attribute);
+ g_hash_table_insert(table, "X-messaging/msn-All", handle_msn_attribute);
+ g_hash_table_insert(table, "X-messaging/gadu-All", handle_gadu_attribute);
+ g_hash_table_insert(table, "X-messaging/irc-All", handle_irc_attribute);
+ g_hash_table_insert(table, "X-messaging/sms-All", handle_sms_attribute);
+
+ //Overwrite the organization hook
+ g_hash_table_insert(table, "ORG", handle_organization_attribute);
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool needs_encoding(const unsigned char *tmp, const char *encoding)
+{
+ int i = 0;
+ if (!strcmp(encoding, "QUOTED-PRINTABLE")) {
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127 || tmp[i] == 10 || tmp[i] == 13)
+ return TRUE;
+ i++;
+ }
+ } else {
+ return !g_utf8_validate((gchar*)tmp, -1, NULL);
+ }
+ return FALSE;
+}
+
+static osync_bool needs_charset(const unsigned char *tmp)
+{
+ int i = 0;
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+static void add_value_decoded(VFormatAttribute *attr, const char *value, const char *encoding)
+{
+ if (needs_charset((unsigned char*)value))
+ if (!vformat_attribute_has_param (attr, "CHARSET"))
+ vformat_attribute_add_param_with_value(attr, "CHARSET", "UTF-8");
+
+ if (needs_encoding((unsigned char*)value, encoding)) {
+ if (!vformat_attribute_has_param (attr, "ENCODING"))
+ vformat_attribute_add_param_with_value(attr, "ENCODING", encoding);
+ vformat_attribute_add_value_decoded(attr, value, strlen(value) + 1);
+ } else
+ vformat_attribute_add_value(attr, value);
+}
+
+static void add_value(VFormatAttribute *attr, xmlNode *parent, const char *name, const char *encoding)
+{
+ char *tmp = osxml_find_node(parent, name);
+ if (!tmp)
+ return;
+
+ add_value_decoded(attr, tmp, encoding);
+
+ g_free(tmp);
+}
+
+static VFormatAttribute *handle_xml_manager_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling manager xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-ManagersName");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_assistant_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling assistant xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-AssistantsName");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_anniversary_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling anniversary xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-Anniversary");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_spouse_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling spouse xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-SpousesName");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_blog_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling blog_url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-BlogFeed");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_yahoo_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling yahoo xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/yahoo-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_icq_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling icq xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/icq-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aim_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling aim xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/aim-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_jabber_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling jabber xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/xmpp-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_msn_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/msn-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_organization_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling organization kde xml attribute");
+ VFormatAttribute *org = NULL;
+ VFormatAttribute *attr = NULL;
+
+ root = root->children;
+
+ int i = 0;
+ while (root) {
+ char *content = (char*)xmlNodeGetContent(root);
+ if (!strcmp((char*)root->name, "Name")) {
+ org = vformat_attribute_new(NULL, "ORG");
+ add_value_decoded(org, content, encoding);
+ vformat_add_attribute(vcard, org);
+ }
+
+ if (!strcmp((char*)root->name, "Department")) {
+ attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-Department");
+ vformat_attribute_add_value(attr, content);
+ vformat_add_attribute(vcard, attr);
+ }
+ if (!strcmp((char*)root->name, "Unit")) {
+ switch (i) {
+ case 0:
+ attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-Office");
+ vformat_attribute_add_value(attr, content);
+ vformat_add_attribute(vcard, attr);
+ break;
+ default:
+ vformat_attribute_add_value(org, content);
+ }
+ i++;
+ }
+
+ g_free(content);
+ root = root->next;
+ }
+
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_profession_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling profession xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-KADDRESSBOOK-X-Profession");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_gadu_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/gadu-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_irc_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/irc-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_sms_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-messaging/sms-All");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_x_kde_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling msn xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, osxml_find_node(root, "ExtName"));
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static osync_bool init_xml_to_kde(void *input)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, input);
+
+ OSyncHookTables *hooks = (OSyncHookTables *)input;
+
+ g_hash_table_insert(hooks->attributes, "Manager", handle_xml_manager_attribute);
+ g_hash_table_insert(hooks->attributes, "Assistant", handle_xml_assistant_attribute);
+ g_hash_table_insert(hooks->attributes, "Anniversary", handle_xml_anniversary_attribute);
+ g_hash_table_insert(hooks->attributes, "Organization", handle_xml_organization_attribute);
+ g_hash_table_insert(hooks->attributes, "Profession", handle_xml_profession_attribute);
+ g_hash_table_insert(hooks->attributes, "Spouse", handle_xml_spouse_attribute);
+ g_hash_table_insert(hooks->attributes, "BlogUrl", handle_xml_blog_url_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-Yahoo", handle_xml_yahoo_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-ICQ", handle_xml_icq_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-AIM", handle_xml_aim_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-Jabber", handle_xml_jabber_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-MSN", handle_xml_msn_attribute);
+ g_hash_table_insert(hooks->attributes, "IM-GaduGadu", handle_xml_gadu_attribute);
+ g_hash_table_insert(hooks->attributes, "IRC", handle_xml_irc_attribute);
+ g_hash_table_insert(hooks->attributes, "SMS", handle_xml_sms_attribute);
+
+ g_hash_table_insert(hooks->attributes, "KDE-Extension", handle_xml_x_kde_attribute);
+ //Overwrite the uid and revision handler
+ g_hash_table_insert(hooks->attributes, "Uid", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->attributes, "Revision", HANDLE_IGNORE);
+
+ g_hash_table_insert(hooks->parameters, "Unit", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->parameters, "Name", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->parameters, "Department", HANDLE_IGNORE);
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "contact");
+ osync_env_register_objformat(env, "contact", "xml-contact");
+
+ osync_env_register_extension(env, "vcard21", "xml-contact", "kde", init_kde_to_xml);
+ osync_env_register_extension(env, "xml-contact", "vcard21", "kde", init_xml_to_kde);
+
+ osync_env_register_extension(env, "vcard30", "xml-contact", "kde", init_kde_to_xml);
+ osync_env_register_extension(env, "xml-contact", "vcard30", "kde", init_xml_to_kde);
+}
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 <[email protected]>
+ *
+ * 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;
+}
+
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.h b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.h
new file mode 100644
index 00000000..bf457cb1
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.h
@@ -0,0 +1,29 @@
+#ifndef _XML_SUPPORT_H
+#define _XML_SUPPORT_H
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+
+#include <opensync/opensync.h>
+#include <opensync/opensync_xml.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct OSyncXMLScore {
+ int value;
+ const char *path;
+} OSyncXMLScore;
+
+OSyncConvCmpResult osxml_compare(xmlDoc *leftinpdoc, xmlDoc *rightinpdoc, OSyncXMLScore *scores, int default_score, int treshold);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _XML_SUPPORT_H
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.c
new file mode 100644
index 00000000..5328fee2
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.c
@@ -0,0 +1,2547 @@
+/*
+ * xml-vcard - A plugin for parsing vcard objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include "vcalical.h"
+#include "xml-vcal.h"
+#include <glib.h>
+
+/*TODO: replace all g_hash_table_insert by functions with well-defined-type parameters
+ * (like insert_xml_attr_handler() and insert_attr_handler()) */
+
+/*TODO: Refactor this and other xml-*.c code, to put all common code in the same place */
+
+typedef xmlNode *(* vattr_handler_t)(xmlNode *, VFormatAttribute *);
+typedef VFormatAttribute *(* xml_attr_handler_t)(VFormat *vcard, xmlNode *root, const char *encoding);
+
+static void handle_unknown_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown parameter %s", vformat_attribute_param_get_name(param));
+ xmlNode *property = xmlNewTextChild(current, NULL, (xmlChar*)"UnknownParam",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+ osxml_node_add(property, "ParamName", vformat_attribute_param_get_name(param));
+}
+
+static void handle_tzid_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzid parameter");
+ xmlNewTextChild(current, NULL, (xmlChar*)"TimezoneID",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_value_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Value",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_altrep_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"AlternateRep",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_cn_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"CommonName",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_delegated_from_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"DelegatedFrom",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_delegated_to_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"DelegatedTo",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_dir_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Directory",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_format_type_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"FormaType",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_fb_type_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"FreeBusyType",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_member_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Member",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_partstat_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"PartStat",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_range_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Range",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_related_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Related",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_reltype_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"RelationType",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_role_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Role",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_rsvp_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"RSVP",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_sent_by_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"SentBy",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static void handle_status_parameter(xmlNode *current, VFormatParam *param)
+{
+ xmlNewTextChild(current, NULL, (xmlChar*)"Status",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static xmlNode *handle_unknown_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown attribute %s", vformat_attribute_get_name(attr));
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"UnknownNode", NULL);
+ osxml_node_add(current, "NodeName", vformat_attribute_get_name(attr));
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Content", retstr->str);
+ }
+ return current;
+}
+
+static xmlNode *handle_prodid_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling prodid attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"ProductID", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_method_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling method attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Method", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_dtstamp_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling dtstamp attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateCalendarCreated", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_percent_complete_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling percent complete attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"PercentComplete", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_created_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ const char *tmp;
+ char *timestamp;
+ osync_trace(TRACE_INTERNAL, "Handling created attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateCreated", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ timestamp = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", timestamp);
+ g_free(timestamp);
+ return current;
+}
+
+static xmlNode *handle_dtstart_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ const char *tmp;
+ char *timestamp;
+ osync_trace(TRACE_INTERNAL, "Handling dtstart attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateStarted", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ timestamp = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", timestamp);
+ g_free(timestamp);
+ return current;
+}
+
+static xmlNode *handle_rrule_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling rrule attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RecurrenceRule", NULL);
+
+ GList *values = NULL;
+ osync_bool interval_isset = FALSE;
+ GString *retstr = NULL;
+
+ values = vformat_attribute_get_values_decoded(attr);
+
+ for (; values; values = values->next) {
+ retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Rule", retstr->str);
+ if (strstr(retstr->str, "INTERVAL"))
+ interval_isset = TRUE;
+ }
+
+ if (!interval_isset)
+ osxml_node_add(current, "Rule", "INTERVAL=1");
+
+ return current;
+}
+
+static xmlNode *handle_vcal_rrule_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling rrule attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RecurrenceRule", NULL);
+
+ GList *values = NULL;
+
+ const char *rrule = vformat_attribute_get_nth_value(attr, 0);
+ values = conv_vcal2ical_rrule(rrule);
+
+ for (; values; values = values->next) {
+ osxml_node_add(current, "Rule", (char *) values->data);
+ }
+
+ g_list_free(values);
+
+ return current;
+}
+
+static xmlNode *handle_vcal_transp_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling transp attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Transparency", NULL);
+
+ const char *transp = vformat_attribute_get_nth_value(attr, 0);
+
+ if (atoi(transp) > 0)
+ osxml_node_add(current, "Content", "OPAQUE");
+ else
+ osxml_node_add(current, "Content", "TRANSPARENT");
+
+
+ return current;
+}
+
+static xmlNode *handle_aalarm_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling aalarm attribute");
+
+ time_t started, alarm;
+ char *dtstarted = NULL, *duration = NULL;
+ xmlNode *dtstartNode = NULL, *sub = NULL;
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Alarm", NULL);
+
+ osxml_node_add(current, "AlarmAction", "AUDIO");
+ osxml_node_add(current, "AlarmDescription", vformat_attribute_get_nth_value(attr, 1));
+
+ /*
+ osxml_node_add(current, "AlarmDuration", vformat_attribute_get_nth_value(attr, 1));
+ osxml_node_add(current, "AlarmRepeat", vformat_attribute_get_nth_value(attr, 2));
+ */
+
+ sub = xmlNewTextChild(current, NULL, (xmlChar*) "AlarmTrigger", NULL);
+
+ // get timestamp of DateStarted or DateDue (for todos)
+ if ((dtstartNode = osxml_get_node(root, "DateDue"))) {
+ dtstarted = osxml_find_node(dtstartNode, "Content");
+ } else if (( dtstartNode = osxml_get_node(root, "DateStarted"))) {
+ dtstarted = osxml_find_node(dtstartNode, "Content");
+ }
+
+ /* TODO: This breaks the case if a localtime stamp + tzid
+ get synced to a vcal. This means that the alarm duration
+ _CAN_ be wrong when dtstarted is localtime and alarm is not localtime.
+
+ FIXME */
+
+ if (dtstarted) {
+ started = osync_time_vtime2unix(dtstarted, 0);
+ g_free(dtstarted);
+
+ alarm = osync_time_vtime2unix(vformat_attribute_get_nth_value(attr, 0), 0);
+
+ // convert offset in seconds to alarm duration
+ duration = osync_time_sec2alarmdu(alarm - started);
+ osxml_node_add(sub, "Content", duration);
+ osxml_node_add(sub, "Value", "DURATION");
+ osxml_node_add(sub, "Related", "START");
+ g_free(duration);
+
+
+ /* This happens only if a todo has a AALARM without any DateDue and DateStarted field.
+ (This was found on a old SE mobile phone and is illegal.) */
+ } else {
+ osxml_node_add(sub, "Content", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(sub, "Value", "DATE-TIME");
+ }
+
+ return current;
+}
+
+static xmlNode *handle_dalarm_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling dalarm attribute");
+
+ time_t started, alarm;
+ char *dtstarted = NULL, *duration = NULL;
+ xmlNode *dtstartNode = NULL, *sub = NULL;
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Alarm", NULL);
+
+ osxml_node_add(current, "AlarmDescription", vformat_attribute_get_nth_value(attr, 1));
+ /*
+ osxml_node_add(current, "AlarmDuration", vformat_attribute_get_nth_value(attr, 1));
+ osxml_node_add(current, "AlarmRepeat", vformat_attribute_get_nth_value(attr, 2));
+ */
+
+ osxml_node_add(current, "AlarmAction", "DISPLAY");
+
+ sub = xmlNewTextChild(current, NULL, (xmlChar*) "AlarmTrigger", NULL);
+
+ // get timestamp of DateStarted or DateDue (for todos)
+ if ((dtstartNode = osxml_get_node(root, "DateDue"))) {
+ dtstarted = osxml_find_node(dtstartNode, "Content");
+ } else if (( dtstartNode = osxml_get_node(root, "DateStarted"))) {
+ dtstarted = osxml_find_node(dtstartNode, "Content");
+ }
+
+ /* TODO: This breaks the case if a localtime stamp + tzid
+ get synced to a vcal. This means that the alarm duration
+ _CAN_ be wrong when dtstarted is localtime and alarm is not localtime.
+
+ FIXME */
+
+ if (dtstarted) {
+ started = osync_time_vtime2unix(dtstarted, 0);
+ g_free(dtstarted);
+
+ alarm = osync_time_vtime2unix(vformat_attribute_get_nth_value(attr, 0), 0);
+
+ // convert offset in seconds to alarm duration
+ duration = osync_time_sec2alarmdu(alarm - started);
+ osxml_node_add(sub, "Content", duration);
+ osxml_node_add(sub, "Value", "DURATION");
+ osxml_node_add(sub, "Related", "START");
+ g_free(duration);
+
+
+ /* This happens only if a todo has a AALARM without any DateDue and DateStarted field.
+ (This was found on a old SE mobile phone and is illegal.) */
+ } else {
+ osxml_node_add(sub, "Content", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(sub, "Value", "DATE-TIME");
+ }
+
+
+ return current;
+}
+
+static xmlNode *handle_description_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling description attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Description", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_summary_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling summary attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Summary", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_categories_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Categories attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Categories", NULL);
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Category", retstr->str);
+ }
+
+ return current;
+}
+
+static xmlNode *handle_class_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Class attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Class", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_due_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ const char *tmp;
+ char *timestamp = NULL;
+ osync_trace(TRACE_INTERNAL, "Handling due attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateDue", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ timestamp = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", timestamp);
+ g_free(timestamp);
+ return current;
+}
+
+static xmlNode *handle_url_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Url attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Url", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_priority_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling priority attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Priority", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_sequence_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling sequence attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Sequence", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_last_modified_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"LastModified", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_rdate_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RecurrenceDate", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_location_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Location", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_geo_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling geo attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Geo", NULL);
+ osxml_node_add(current, "Latitude", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "Longitude", vformat_attribute_get_nth_value(attr, 1));
+ return current;
+}
+
+static xmlNode *handle_completed_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Completed", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_organizer_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Organizer", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_recurid_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RecurrenceID", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_status_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Status", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_duration_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Duration", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_attach_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Attach", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_attendee_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Attendee", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_contact_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Contact", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_exdate_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = NULL;
+ char *datestamp = NULL;
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"ExclusionDate", NULL);
+ if (!osync_time_isdate(retstr->str)) {
+ datestamp = osync_time_datestamp(retstr->str);
+ } else {
+ datestamp = g_strdup(retstr->str);
+ }
+ osxml_node_add(current, "Content", datestamp);
+
+ if (!osync_time_isdate(retstr->str))
+ osxml_node_add(current, "Value", "DATE");
+
+ g_free(datestamp);
+ g_string_free(retstr, TRUE);
+ }
+
+ return current;
+}
+
+static xmlNode *handle_exrule_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"ExclusionRule", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_rstatus_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RStatus", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_related_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Related", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_resources_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Resources", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_dtend_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ char *timestamp;
+ const char *tmp;
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateEnd", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ timestamp = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", timestamp);
+ g_free(timestamp);
+ return current;
+}
+
+static xmlNode *handle_transp_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Transparency", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_calscale_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"CalendarScale", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_tzid_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzid attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TimezoneID",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tz_location_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tz location attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"Location",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzoffsetfrom_location_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzoffsetfrom attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TZOffsetFrom",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzoffsetto_location_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzoffsetto attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TZOffsetTo",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzname_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzname attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TimezoneName",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzdtstart_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"DateStarted",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzrrule_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzrrule attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"RecurrenceRule", NULL);
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Rule", retstr->str);
+ }
+
+ return current;
+}
+
+static xmlNode *handle_tz_last_modified_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"LastModified",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzurl_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TimezoneUrl",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_tzrdate_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"TimezoneDate",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_atrigger_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"AlarmTrigger", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_arepeat_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmRepeat",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_aduration_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmDuration",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_aaction_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmAction",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_aattach_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmAttach",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_adescription_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmDescription",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_aattendee_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmAttendee",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static xmlNode *handle_asummary_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling tzdtstart attribute");
+ return xmlNewTextChild(root, NULL, (xmlChar*)"AlarmSummary",
+ (xmlChar*)vformat_attribute_get_nth_value(attr, 0));
+}
+
+static void vcard_handle_parameter(GHashTable *hooks, xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, hooks, current, param);
+
+ //Find the handler for this parameter
+ void (* param_handler)(xmlNode *, VFormatParam *);
+ char *paramname = g_strdup_printf("%s=%s", vformat_attribute_param_get_name(param), vformat_attribute_param_get_nth_value(param, 0));
+ param_handler = g_hash_table_lookup(hooks, paramname);
+ g_free(paramname);
+ if (!param_handler)
+ param_handler = g_hash_table_lookup(hooks, vformat_attribute_param_get_name(param));
+
+ if (param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (param_handler)
+ param_handler(current, param);
+ else
+ handle_unknown_parameter(current, param);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void vcal_handle_attribute(GHashTable *table, GHashTable *paramtable, xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, table, root, attr, attr ? vformat_attribute_get_name(attr) : "None");
+ xmlNode *current = NULL;
+
+ //Dont add empty stuff
+ GList *v;
+ for (v = vformat_attribute_get_values(attr); v; v = v->next) {
+ char *value = v->data;
+ if (strlen(value) != 0)
+ goto has_value;
+ }
+ osync_trace(TRACE_EXIT, "%s: No values", __func__);
+ return;
+
+has_value:;
+
+ //We need to find the handler for this attribute
+ vattr_handler_t attr_handler = g_hash_table_lookup(table, vformat_attribute_get_name(attr));
+ osync_trace(TRACE_INTERNAL, "Hook is: %p", attr_handler);
+ if (attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (attr_handler)
+ current = attr_handler(root, attr);
+ else
+ current = handle_unknown_attribute(root, attr);
+
+ //Handle all parameters of this attribute
+ GList *params = vformat_attribute_get_params(attr);
+ GList *p = NULL;
+ for (p = params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ vcard_handle_parameter(paramtable, current, param);
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void vcal_parse_attributes(OSyncHooksTable *hooks, GHashTable *table, GHashTable *paramtable, GList **attributes, xmlNode *root)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, attributes, root);
+
+ GList *a = NULL;
+ for (a = *attributes; a; a = a->next) {
+ VFormatAttribute *attr = a->data;
+
+ if (!strcmp(vformat_attribute_get_name(attr), "BEGIN")) {
+ //Handling supcomponent
+ a = a->next;
+ if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "VTIMEZONE")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Timezone", NULL);
+ vcal_parse_attributes(hooks, hooks->tztable, hooks->tztable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "DAYLIGHT")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DaylightSavings", NULL);
+ vcal_parse_attributes(hooks, hooks->tztable, hooks->tztable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "STANDARD")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Standard", NULL);
+ vcal_parse_attributes(hooks, hooks->tztable, hooks->tztable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "VTODO")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Todo", NULL);
+ vcal_parse_attributes(hooks, hooks->comptable, hooks->compparamtable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "VEVENT")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Event", NULL);
+ vcal_parse_attributes(hooks, hooks->comptable, hooks->compparamtable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "VJOURNAL")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Journal", NULL);
+ vcal_parse_attributes(hooks, hooks->comptable, hooks->compparamtable, &a, current);
+ } else if (!strcmp(vformat_attribute_get_nth_value(attr, 0), "VALARM")) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Alarm", NULL);
+ vcal_parse_attributes(hooks, hooks->alarmtable, hooks->alarmtable, &a, current);
+ }
+ } else if (!strcmp(vformat_attribute_get_name(attr), "END")) {
+ osync_trace(TRACE_EXIT, "%s: Found END", __func__);
+ *attributes = a;
+ return;
+ } else
+ vcal_handle_attribute(table, paramtable, root, attr);
+ }
+ osync_trace(TRACE_EXIT, "%s: Done", __func__);
+}
+
+static osync_bool conv_vcal_to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, conv_data, input, inpsize, output, outpsize, free_input, error);
+
+ OSyncHooksTable *hooks = (OSyncHooksTable *)conv_data;
+
+ osync_trace(TRACE_SENSITIVE, "Input vcal is:\n%s", input);
+
+ /* The input is not null-terminated, but vformat_new_from_string() expects a null-terminated string */
+ char *input_str = g_malloc(inpsize + 1);
+ memcpy(input_str, input, inpsize);
+ input_str[inpsize] = '\0';
+
+ //Parse the vcard
+ VFormat *vcal = vformat_new_from_string(input_str);
+ g_free(input_str);
+
+ osync_trace(TRACE_INTERNAL, "Creating xml doc");
+
+ //Create a new xml document
+ xmlDoc *doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlNode *root = osxml_node_add_root(doc, "vcal");
+
+ osync_trace(TRACE_INTERNAL, "parsing attributes");
+
+ //For every attribute we have call the handling hook
+ GList *attributes = vformat_get_attributes(vcal);
+ vcal_parse_attributes(hooks, hooks->table, hooks->table, &attributes, root);
+
+ xmlChar *str = osxml_write_to_string(doc);
+ osync_trace(TRACE_SENSITIVE, "Output XML is:\n%s", str);
+ xmlFree(str);
+
+ *free_input = TRUE;
+ *output = (char *)doc;
+ *outpsize = sizeof(doc);
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool needs_encoding(const unsigned char *tmp, const char *encoding)
+{
+ int i = 0;
+ if (!strcmp(encoding, "QUOTED-PRINTABLE")) {
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127 || tmp[i] == 10 || tmp[i] == 13)
+ return TRUE;
+ i++;
+ }
+ } else {
+ return !g_utf8_validate((gchar*)tmp, -1, NULL);
+ }
+ return FALSE;
+}
+
+static osync_bool needs_charset(const unsigned char *tmp)
+{
+ int i = 0;
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+static void add_value(VFormatAttribute *attr, xmlNode *parent, const char *name, const char *encoding)
+{
+ char *tmp = NULL;
+ if (!name)
+ tmp = (char*)xmlNodeGetContent(parent);
+ else
+ tmp = osxml_find_node(parent, name);
+
+ if (!tmp)
+ return;
+
+ if (needs_charset((unsigned char*)tmp))
+ if (!vformat_attribute_has_param (attr, "CHARSET"))
+ vformat_attribute_add_param_with_value(attr, "CHARSET", "UTF-8");
+
+ if (encoding && needs_encoding((unsigned char*)tmp, encoding)) {
+ if (!vformat_attribute_has_param (attr, "ENCODING"))
+ vformat_attribute_add_param_with_value(attr, "ENCODING", encoding);
+ vformat_attribute_add_value_decoded(attr, tmp, strlen(tmp) + 1);
+ } else
+ vformat_attribute_add_value(attr, tmp);
+ g_free(tmp);
+}
+
+static void xml_handle_unknown_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml parameter %s", current->name);
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, (char*)current->name, content);
+ g_free(content);
+}
+
+static void handle_xml_category_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_value(attr, content);
+ g_free(content);
+}
+
+static void handle_xml_rule_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_value(attr, content);
+ g_free(content);
+}
+
+static void handle_xml_value_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "VALUE", content);
+ g_free(content);
+}
+
+static void handle_xml_altrep_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "ALTREP", content);
+ g_free(content);
+}
+
+static void handle_xml_cn_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "CN", content);
+ g_free(content);
+}
+
+static void handle_xml_delegated_from_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "DELEGATED-FROM", content);
+ g_free(content);
+}
+
+static void handle_xml_delegated_to_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "DELEGATED-TO", content);
+ g_free(content);
+}
+
+static void handle_xml_dir_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "DIR", content);
+ g_free(content);
+}
+
+static void handle_xml_format_type_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "FMTTYPE", content);
+ g_free(content);
+}
+
+static void handle_xml_fb_type_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "FBTYPE", content);
+ g_free(content);
+}
+
+static void handle_xml_member_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "MEMBER", content);
+ g_free(content);
+}
+
+static void handle_xml_partstat_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "PARTSTAT", content);
+ g_free(content);
+}
+
+static void handle_xml_range_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "RANGE", content);
+ g_free(content);
+}
+
+static void handle_xml_reltype_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "RELTYPE", content);
+ g_free(content);
+}
+
+static void handle_xml_related_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "RELATED", content);
+ g_free(content);
+}
+
+static void handle_xml_role_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "ROLE", content);
+ g_free(content);
+}
+
+static void handle_xml_rsvp_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "RSVP", content);
+ g_free(content);
+}
+
+static void handle_xml_sent_by_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "SENT-BY", content);
+ g_free(content);
+}
+
+static VFormatAttribute *xml_handle_unknown_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml attribute %s", root->name);
+ char *name = osxml_find_node(root, "NodeName");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, name);
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_prodid_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling prodid xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "PRODID");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_method_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling method xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "METHOD");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_geo_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling location xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "GEO");
+ add_value(attr, root, "Latitude", encoding);
+ add_value(attr, root, "Longitude", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "URL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_uid_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling uid xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "UID");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_class_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling class xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CLASS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_categories_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling categories xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CATEGORIES");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static void xml_vcard_handle_parameter(GHashTable *table, VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, table, attr, current, current ? (char *)current->name : "None");
+
+ //Find the handler for this parameter
+ void (* xml_param_handler)(VFormatAttribute *attr, xmlNode *);
+ char *content = (char*)xmlNodeGetContent(current);
+ char *paramname = g_strdup_printf("%s=%s", current->name, content);
+ g_free(content);
+ xml_param_handler = g_hash_table_lookup(table, paramname);
+ g_free(paramname);
+ if (!xml_param_handler)
+ xml_param_handler = g_hash_table_lookup(table, current->name);
+
+ if (xml_param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (xml_param_handler)
+ xml_param_handler(attr, current);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void xml_vcal_handle_attribute(GHashTable *table, VFormat *vcard, xmlNode *root)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, table, vcard, root, root ? (char *)root->name : "None");
+ VFormatAttribute *attr = NULL;
+
+ //We need to find the handler for this attribute
+ xml_attr_handler_t xml_attr_handler = g_hash_table_lookup(table, root->name);
+ osync_trace(TRACE_INTERNAL, "xml hook is: %p", xml_attr_handler);
+ if (xml_attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (xml_attr_handler)
+ /*FIXME: What the encoding parameter is supposed to be. Is it necessary? */
+ attr = xml_attr_handler(vcard, root, NULL);
+ else {
+ osync_trace(TRACE_EXIT, "%s: Ignored2", __func__);
+ return;
+ }
+
+ //Handle all parameters of this attribute
+ xmlNode *child = root->xmlChildrenNode;
+ while (child) {
+ xml_vcard_handle_parameter(table, attr, child);
+ child = child->next;
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static OSyncConvCmpResult compare_vevent(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange);
+
+ OSyncXMLScore score[] =
+ {
+ {10, "/vcal/Event/StartTime"},
+ {10, "/vcal/Event/EndTime"},
+ {100, "/vcal/Event/Summary"},
+ {0, "/vcal/Event/Uid"},
+ {0, "/vcal/Event/Revision"},
+ {0, "/vcal/Event/DateCalendarCreated"},
+ {0, "/vcal/Event/DateCreated"},
+ {0, "/vcal/Event/LastModified"},
+ {0, "/vcal/Event/Sequence"},
+ {0, "/vcal/Event/Class[Content = \"PUBLIC\"]"},
+ {0, "/vcal/Event/Priority"},
+ {0, "/vcal/Event/Transparency[Content = \"OPAQUE\"]"},
+ {0, "/vcal/Method"},
+// {0, "/vcal/Timezone"},
+ {0, NULL}
+ };
+
+ OSyncConvCmpResult ret = osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 0, 99);
+
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
+ return ret;
+}
+
+static OSyncConvCmpResult compare_vtodo(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange);
+
+ OSyncXMLScore score[] =
+ {
+ {100, "/vcal/Todo/Summary"},
+ {0, "/vcal/Todo/Uid"},
+ {0, "/vcal/Todo/Revision"},
+ {0, "/vcal/Todo/DateCalendarCreated"},
+ {0, "/vcal/Todo/DateCreated"},
+ {0, "/vcal/Todo/LastModified"},
+ {0, "/vcal/Todo/Sequence"},
+ {0, "/vcal/Todo/Class[Content = \"PUBLIC\"]"},
+ {0, "/vcal/Todo/Priority"},
+ // ignore 'PercentComplete', because we aren't able to handle this at the moment
+ {0, "/vcal/Todo/PercentComplete"},
+ {0, "/vcal/Method"},
+// {0, "/vcal/Timezone"},
+ {0, NULL}
+ };
+
+ OSyncConvCmpResult ret = osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 0, 99);
+
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
+ return ret;
+}
+
+static char *print_vcal(OSyncChange *change)
+{
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ return (char *)osxml_write_to_string(doc);
+}
+
+static void destroy_xml(char *data, size_t size)
+{
+ xmlFreeDoc((xmlDoc *)data);
+}
+
+static void insert_attr_handler(GHashTable *table, const char *attrname, vattr_handler_t handler)
+{
+ g_hash_table_insert(table, (gpointer)attrname, handler);
+}
+
+static void *init_ical_to_xml(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+ OSyncHooksTable *hooks = g_malloc0(sizeof(OSyncHooksTable));
+
+ hooks->table = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->tztable = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->comptable = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->compparamtable = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->alarmtable = g_hash_table_new(g_str_hash, g_str_equal);
+
+ //todo attributes
+ insert_attr_handler(hooks->comptable, "BEGIN", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "END", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "UID", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "X-IRMC-LUID", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "X-SONYERICSSON-DST", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "DTSTAMP", handle_dtstamp_attribute);
+ insert_attr_handler(hooks->comptable, "DESCRIPTION", handle_description_attribute);
+ insert_attr_handler(hooks->comptable, "SUMMARY", handle_summary_attribute);
+ insert_attr_handler(hooks->comptable, "DUE", handle_due_attribute);
+ insert_attr_handler(hooks->comptable, "DTSTART", handle_dtstart_attribute);
+ insert_attr_handler(hooks->comptable, "PERCENT-COMPLETE", handle_percent_complete_attribute);
+ insert_attr_handler(hooks->comptable, "CLASS", handle_class_attribute);
+ insert_attr_handler(hooks->comptable, "CATEGORIES", handle_categories_attribute);
+ insert_attr_handler(hooks->comptable, "PRIORITY", handle_priority_attribute);
+ insert_attr_handler(hooks->comptable, "URL", handle_url_attribute);
+ insert_attr_handler(hooks->comptable, "SEQUENCE", handle_sequence_attribute);
+ insert_attr_handler(hooks->comptable, "LAST-MODIFIED", handle_last_modified_attribute);
+ insert_attr_handler(hooks->comptable, "CREATED", handle_created_attribute);
+ insert_attr_handler(hooks->comptable, "DCREATED", handle_created_attribute);
+ insert_attr_handler(hooks->comptable, "RRULE", handle_rrule_attribute);
+
+ insert_attr_handler(hooks->comptable, "RDATE", handle_rdate_attribute);
+ insert_attr_handler(hooks->comptable, "LOCATION", handle_location_attribute);
+ insert_attr_handler(hooks->comptable, "GEO", handle_geo_attribute);
+ insert_attr_handler(hooks->comptable, "COMPLETED", handle_completed_attribute);
+ insert_attr_handler(hooks->comptable, "ORGANIZER", handle_organizer_attribute);
+ insert_attr_handler(hooks->comptable, "ORGANIZER", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "X-ORGANIZER", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "RECURRENCE-ID", handle_recurid_attribute);
+ insert_attr_handler(hooks->comptable, "STATUS", handle_status_attribute);
+ insert_attr_handler(hooks->comptable, "DURATION", handle_duration_attribute);
+ insert_attr_handler(hooks->comptable, "ATTACH", handle_attach_attribute);
+ insert_attr_handler(hooks->comptable, "ATTENDEE", handle_attendee_attribute);
+ insert_attr_handler(hooks->comptable, "COMMENT", HANDLE_IGNORE);
+ insert_attr_handler(hooks->comptable, "CONTACT", handle_contact_attribute);
+ insert_attr_handler(hooks->comptable, "EXDATE", handle_exdate_attribute);
+ insert_attr_handler(hooks->comptable, "EXRULE", handle_exrule_attribute);
+ insert_attr_handler(hooks->comptable, "RSTATUS", handle_rstatus_attribute);
+ insert_attr_handler(hooks->comptable, "RELATED-TO", handle_related_attribute);
+ insert_attr_handler(hooks->comptable, "RESOURCES", handle_resources_attribute);
+ insert_attr_handler(hooks->comptable, "DTEND", handle_dtend_attribute);
+ insert_attr_handler(hooks->comptable, "TRANSP", handle_transp_attribute);
+ insert_attr_handler(hooks->comptable, "X-LIC-ERROR", HANDLE_IGNORE);
+
+ g_hash_table_insert(hooks->compparamtable, "TZID", handle_tzid_parameter);
+ g_hash_table_insert(hooks->compparamtable, "VALUE", handle_value_parameter);
+ g_hash_table_insert(hooks->compparamtable, "ALTREP", handle_altrep_parameter);
+ g_hash_table_insert(hooks->compparamtable, "CN", handle_cn_parameter);
+ g_hash_table_insert(hooks->compparamtable, "DELEGATED-FROM", handle_delegated_from_parameter);
+ g_hash_table_insert(hooks->compparamtable, "DELEGATED-TO", handle_delegated_to_parameter);
+ g_hash_table_insert(hooks->compparamtable, "DIR", handle_dir_parameter);
+ g_hash_table_insert(hooks->compparamtable, "FMTTYPE", handle_format_type_parameter);
+ g_hash_table_insert(hooks->compparamtable, "FBTYPE", handle_fb_type_parameter);
+ g_hash_table_insert(hooks->compparamtable, "MEMBER", handle_member_parameter);
+ g_hash_table_insert(hooks->compparamtable, "PARTSTAT", handle_partstat_parameter);
+ g_hash_table_insert(hooks->compparamtable, "RANGE", handle_range_parameter);
+ g_hash_table_insert(hooks->compparamtable, "RELATED", handle_related_parameter);
+ g_hash_table_insert(hooks->compparamtable, "RELTYPE", handle_reltype_parameter);
+ g_hash_table_insert(hooks->compparamtable, "ROLE", handle_role_parameter);
+ g_hash_table_insert(hooks->compparamtable, "RSVP", handle_rsvp_parameter);
+ g_hash_table_insert(hooks->compparamtable, "SENT-BY", handle_sent_by_parameter);
+ g_hash_table_insert(hooks->compparamtable, "X-LIC-ERROR", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->compparamtable, "CHARSET", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->compparamtable, "STATUS", handle_status_parameter);
+
+ //vcal attributes
+ g_hash_table_insert(hooks->table, "PRODID", handle_prodid_attribute);
+ g_hash_table_insert(hooks->table, "PRODID", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "METHOD", handle_method_attribute);
+ g_hash_table_insert(hooks->table, "VERSION", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "ENCODING", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "CHARSET", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "BEGIN", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "END", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->table, "CALSCALE", handle_calscale_attribute);
+ g_hash_table_insert(hooks->table, "X-LIC-ERROR", HANDLE_IGNORE);
+
+ //Timezone
+ g_hash_table_insert(hooks->tztable, "TZID", handle_tzid_attribute);
+ g_hash_table_insert(hooks->tztable, "X-LIC-LOCATION", handle_tz_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TZOFFSETFROM", handle_tzoffsetfrom_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TZOFFSETTO", handle_tzoffsetto_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TZNAME", handle_tzname_attribute);
+ g_hash_table_insert(hooks->tztable, "DTSTART", handle_tzdtstart_attribute);
+ g_hash_table_insert(hooks->tztable, "RRULE", handle_tzrrule_attribute);
+ g_hash_table_insert(hooks->tztable, "LAST-MODIFIED", handle_tz_last_modified_attribute);
+ g_hash_table_insert(hooks->tztable, "BEGIN", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->tztable, "END", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->tztable, "TZURL", handle_tzurl_attribute);
+ g_hash_table_insert(hooks->tztable, "COMMENT", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->tztable, "RDATE", handle_tzrdate_attribute);
+
+ /*FIXME: The functions below shoudn't be on tztable, but on another hash table */
+ g_hash_table_insert(hooks->tztable, "VALUE", handle_value_parameter);
+ g_hash_table_insert(hooks->tztable, "ALTREP", handle_altrep_parameter);
+ g_hash_table_insert(hooks->tztable, "CN", handle_cn_parameter);
+ g_hash_table_insert(hooks->tztable, "DELEGATED-FROM", handle_delegated_from_parameter);
+ g_hash_table_insert(hooks->tztable, "DELEGATED-TO", handle_delegated_to_parameter);
+ g_hash_table_insert(hooks->tztable, "DIR", handle_dir_parameter);
+ g_hash_table_insert(hooks->tztable, "FMTTYPE", handle_format_type_parameter);
+ g_hash_table_insert(hooks->tztable, "FBTYPE", handle_fb_type_parameter);
+ g_hash_table_insert(hooks->tztable, "MEMBER", handle_member_parameter);
+ g_hash_table_insert(hooks->tztable, "PARTSTAT", handle_partstat_parameter);
+ g_hash_table_insert(hooks->tztable, "RANGE", handle_range_parameter);
+ g_hash_table_insert(hooks->tztable, "RELATED", handle_related_parameter);
+ g_hash_table_insert(hooks->tztable, "RELTYPE", handle_reltype_parameter);
+ g_hash_table_insert(hooks->tztable, "ROLE", handle_role_parameter);
+ g_hash_table_insert(hooks->tztable, "RSVP", handle_rsvp_parameter);
+ g_hash_table_insert(hooks->tztable, "SENT-BY", handle_sent_by_parameter);
+ g_hash_table_insert(hooks->tztable, "X-LIC-ERROR", HANDLE_IGNORE);
+
+ //VAlarm component
+ g_hash_table_insert(hooks->alarmtable, "TRIGGER", handle_atrigger_attribute);
+ g_hash_table_insert(hooks->alarmtable, "REPEAT", handle_arepeat_attribute);
+ g_hash_table_insert(hooks->alarmtable, "DURATION", handle_aduration_attribute);
+ g_hash_table_insert(hooks->alarmtable, "ACTION", handle_aaction_attribute);
+ g_hash_table_insert(hooks->alarmtable, "ATTACH", handle_aattach_attribute);
+ g_hash_table_insert(hooks->alarmtable, "DESCRIPTION", handle_adescription_attribute);
+ g_hash_table_insert(hooks->alarmtable, "ATTENDEE", handle_aattendee_attribute);
+ g_hash_table_insert(hooks->alarmtable, "SUMMARY", handle_asummary_attribute);
+
+ /*FIXME: The functions below shoudn't be on alarmtable, but on another hash table */
+ g_hash_table_insert(hooks->alarmtable, "TZID", handle_tzid_parameter);
+ g_hash_table_insert(hooks->alarmtable, "VALUE", handle_value_parameter);
+ g_hash_table_insert(hooks->alarmtable, "ALTREP", handle_altrep_parameter);
+ g_hash_table_insert(hooks->alarmtable, "CN", handle_cn_parameter);
+ g_hash_table_insert(hooks->alarmtable, "DELEGATED-FROM", handle_delegated_from_parameter);
+ g_hash_table_insert(hooks->alarmtable, "DELEGATED-TO", handle_delegated_to_parameter);
+ g_hash_table_insert(hooks->alarmtable, "DIR", handle_dir_parameter);
+ g_hash_table_insert(hooks->alarmtable, "FMTTYPE", handle_format_type_parameter);
+ g_hash_table_insert(hooks->alarmtable, "FBTYPE", handle_fb_type_parameter);
+ g_hash_table_insert(hooks->alarmtable, "MEMBER", handle_member_parameter);
+ g_hash_table_insert(hooks->alarmtable, "PARTSTAT", handle_partstat_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RANGE", handle_range_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RELATED", handle_related_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RELTYPE", handle_reltype_parameter);
+ g_hash_table_insert(hooks->alarmtable, "ROLE", handle_role_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RSVP", handle_rsvp_parameter);
+ g_hash_table_insert(hooks->alarmtable, "SENT-BY", handle_sent_by_parameter);
+ g_hash_table_insert(hooks->alarmtable, "X-LIC-ERROR", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->alarmtable, "X-EVOLUTION-ALARM-UID", HANDLE_IGNORE);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks);
+ return (void *)hooks;
+}
+
+static void *init_vcal_to_xml(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+ OSyncHooksTable *hooks = (OSyncHooksTable *)init_ical_to_xml();
+
+ //vcal (event10) only
+ insert_attr_handler(hooks->comptable, "RRULE", handle_vcal_rrule_attribute);
+ insert_attr_handler(hooks->comptable, "TRANSP", handle_vcal_transp_attribute);
+ insert_attr_handler(hooks->comptable, "AALARM", handle_aalarm_attribute);
+ insert_attr_handler(hooks->comptable, "DALARM", handle_dalarm_attribute);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks);
+ return (void *)hooks;
+}
+
+static void fin_vcal_to_xml(void *data)
+{
+ OSyncHooksTable *hooks = (OSyncHooksTable *)data;
+ g_hash_table_destroy(hooks->table);
+ g_free(hooks);
+}
+
+
+
+/* xml to vcal */
+static VFormatAttribute *handle_xml_dtstamp_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTSTAMP");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_description_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DESCRIPTION");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_summary_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "SUMMARY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+/* ical only */
+static VFormatAttribute *handle_xml_due_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DUE");
+ add_value(attr, root, "Content", encoding);
+ vformat_attribute_add_param_with_value(attr, "TZID", osxml_find_node(root, "TimezoneID"));
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_dtstart_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTSTART");
+ add_value(attr, root, "Content", encoding);
+ vformat_attribute_add_param_with_value(attr, "TZID", osxml_find_node(root, "TimezoneID"));
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+/* end ical only */
+
+/* vcal only */
+static VFormatAttribute *handle_vcal_xml_due_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DUE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_vcal_xml_dtstart_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTSTART");
+
+ char *content = NULL;
+ GString *newdate = g_string_new("");
+
+ content = osxml_find_node(root, "Content");
+ newdate = g_string_append(newdate, content);
+
+ if (osync_time_isdate(content)) {
+ newdate = g_string_append(newdate, "T000000");
+ }
+
+ g_free(content);
+
+ vformat_attribute_add_value(attr, newdate->str);
+ vformat_add_attribute(vcard, attr);
+
+ g_string_free(newdate, TRUE);
+
+ return attr;
+}
+/* end vcal only */
+
+static VFormatAttribute *handle_xml_percent_complete_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "PERCENT-COMPLETE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_priority_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "PRIORITY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_sequence_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "SEQUENCE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_last_modified_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LAST-MODIFIED");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_created_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CREATED");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_rrule_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RRULE");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+/* vcal only */
+static VFormatAttribute *handle_vcal_xml_rrule_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RRULE");
+
+ char *vcalrrule = NULL;
+ GString *icalrrule = g_string_new("");
+ xmlNode *child = root->xmlChildrenNode;
+ while (child) {
+ icalrrule = g_string_append(icalrrule, (char*)xmlNodeGetContent(child));
+ if (child->next)
+ icalrrule = g_string_append(icalrrule, ";");
+
+ child = child->next;
+ }
+
+ vcalrrule = conv_ical2vcal_rrule(icalrrule->str);
+
+ g_string_free(icalrrule, TRUE);
+
+ vformat_attribute_add_value(attr, vcalrrule);
+
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+/* end of vcal only */
+
+static VFormatAttribute *handle_xml_rdate_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RDATE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_location_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LOCATION");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_completed_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "COMPLETED");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_organizer_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ORGANIZER");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_recurid_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RECURRENCE-ID");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_status_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "STATUS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_duration_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DURATION");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_attach_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ATTACH");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_attendee_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ATTENDEE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_contact_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CONTACT");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_exdate_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "EXDATE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+/* vcal only */
+static VFormatAttribute *handle_vcal_xml_exdate_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+
+ xmlNode *dtstartNode = NULL;
+ char *dtstart = NULL, *timestamp = NULL, *origex = NULL;
+ GString *exdate = g_string_new("");
+ VFormatAttribute *attr = NULL;
+
+ if (!(attr = vformat_find_attribute(vcard, "EXDATE")))
+ attr = vformat_attribute_new(NULL, "EXDATE");
+
+ origex = (char *) xmlNodeGetContent(root);
+
+ exdate = g_string_append(exdate, origex);
+
+ if (!strstr(origex, "T")) {
+ dtstartNode = osxml_get_node(root->parent->parent, "DateStarted");
+ osync_trace(TRACE_INTERNAL, "dtstartNode pointer: %p", dtstartNode);
+ dtstart = osxml_find_node(dtstartNode, "Content");
+ timestamp = strstr(dtstart, "T");
+ osync_trace(TRACE_INTERNAL, "append timestamp: %s", timestamp);
+ exdate = g_string_append(exdate, timestamp);
+ g_free(dtstart);
+ }
+
+ vformat_attribute_add_value(attr, exdate->str);
+
+ g_string_free(exdate, TRUE);
+
+ if (!vformat_find_attribute(vcard, "EXDATE"))
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+/* end of vcal only */
+
+static VFormatAttribute *handle_xml_exrule_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "EXRULE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_rstatus_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RSTATUS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_related_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RELATED-TO");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_resources_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RESOURCES");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+/* ical only */
+static VFormatAttribute *handle_xml_dtend_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTEND");
+ add_value(attr, root, "Content", encoding);
+ vformat_attribute_add_param_with_value(attr, "TZID", osxml_find_node(root, "TimezoneID"));
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+/* end ical only */
+
+/* vcal only */
+static VFormatAttribute *handle_vcal_xml_dtend_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTEND");
+
+ char *content_dtend = NULL;
+ GString *new_dtend = g_string_new("");
+
+ content_dtend = osxml_find_node(root, "Content");
+ new_dtend = g_string_append(new_dtend, content_dtend);
+
+
+ /*
+ * if (DTEND->VALUE == DATE) ==> DTEND = DTEND-60sec + "T000000"
+ *
+ * e.g. (SE W880i): 20070313T000000Z -> 20070313T235900Z
+ *
+ * this works also for SE K750i, SE D750i
+ *
+ */
+ if (osync_time_isdate(content_dtend)) {
+
+ osync_trace(TRACE_INTERNAL, "DTEND (old): %s", content_dtend);
+
+ char *tmp1 = NULL, *tmp2 = NULL;
+
+ /* append "T000000" */
+ new_dtend = g_string_append(new_dtend, "T000000");
+
+ time_t dtend_unixtime = osync_time_vtime2unix(content_dtend, 0);
+
+ /* DTEND = DTEND - 60 sec */
+ dtend_unixtime -= 60;
+
+ tmp1 = osync_time_unix2vtime(&dtend_unixtime);
+ tmp2 = osync_time_vtime2localtime(tmp1, 0);
+
+ g_string_erase(new_dtend, 0, -1);
+ g_string_append(new_dtend, tmp2);
+
+ osync_trace(TRACE_INTERNAL, "DTEND (new): %s", tmp2);
+
+ g_free(tmp1);
+ g_free(tmp2);
+
+ }
+
+ g_free(content_dtend);
+
+ vformat_attribute_add_value(attr, new_dtend->str);
+ vformat_add_attribute(vcard, attr);
+
+ g_string_free(new_dtend, TRUE);
+
+ return attr;
+}
+
+static VFormatAttribute *handle_vcal_xml_transp_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TRANSP");
+
+ char *val = osxml_find_node(root, "Content");
+
+ // Default: TRANSPARENT
+ int block = 0;
+
+ if (!strcmp("OPAQUE", val))
+ block = 1;
+
+ g_free(val);
+
+ char *transp = g_strdup_printf("%i", block);
+ vformat_attribute_add_value(attr, transp);
+ vformat_add_attribute(vcard, attr);
+ g_free(transp);
+
+ return attr;
+}
+/* end vcal only */
+
+static VFormatAttribute *handle_xml_transp_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TRANSP");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_calscale_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CALSCALE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzid_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZID");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tz_location_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "X-LIC-LOCATION");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzoffsetfrom_location_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZOFFSETFROM");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzoffsetto_location_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZOFFSETTO");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzname_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZNAME");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzdtstart_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DTSTART");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzrrule_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RRULE");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tz_last_modified_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LAST-MODIFIED");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzurl_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZURL");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_tzrdate_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "RDATE");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+/* vcal only */
+static VFormatAttribute *handle_vcal_xml_alarm_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling reminder xml attribute");
+
+ xmlNode *dtstart = NULL;
+ xmlNode *trigger = osxml_get_node(root, "AlarmTrigger");
+ char *action = NULL, *tmp = NULL, *value = NULL, *runtime = NULL;
+ char *startvtime = NULL;
+ time_t dtstarted;
+ int duration;
+ osync_bool isruntime = FALSE;
+
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DALARM");
+
+ dtstart = osxml_get_node(root->parent, "DateStarted");
+ value = osxml_find_node(dtstart, "Value");
+
+ if (value) {
+ if (strstr(value, "DATE-TIME")) {
+ isruntime = TRUE;
+ }
+ }
+
+ startvtime = osxml_find_node(dtstart, "Content");
+
+ /* Runtime */
+ if (isruntime) {
+ runtime = startvtime;
+ /* Duration */
+ } else {
+ tmp = osxml_find_node(trigger, "Content");
+ duration = osync_time_alarmdu2sec(tmp);
+ g_free(tmp);
+
+ tmp = osxml_find_node(dtstart, "Content");
+ /* AlarmTrigger MUST be UTC (see rfc2445).
+ So there is an offset to UTC of 0 seconds. */
+ if (osync_time_isutc(tmp))
+ osync_trace(TRACE_INTERNAL, "WARNNING: timestamp is not UTC: %s", tmp);
+
+ dtstarted = osync_time_vtime2unix(tmp, 0);
+
+ g_free(tmp);
+
+ dtstarted += duration;
+
+ runtime = osync_time_unix2vtime(&dtstarted);
+ }
+
+ g_free(value);
+
+ vformat_attribute_add_value(attr, runtime);
+
+ add_value(attr, root, "AlarmDuration", encoding);
+ add_value(attr, root, "AlarmRepeat", encoding);
+ add_value(attr, root, "AlarmDescription", encoding);
+
+ action = osxml_find_node(root, "AlarmAction");
+ if (action) {
+ if (!strcmp(action, "AUDIO")) {
+ osync_trace(TRACE_INTERNAL, "Handling audo reminder xml attribute");
+
+ attr = vformat_attribute_new(NULL, "AALARM");
+ vformat_attribute_add_value(attr, runtime);
+ add_value(attr, root, "AlarmDuration", encoding);
+ add_value(attr, root, "AlarmRepeat", encoding);
+ add_value(attr, root, "AlarmDescription", encoding);
+ }
+ }
+
+ vformat_add_attribute(vcard, attr);
+ g_free(action);
+ g_free(runtime);
+
+ return attr;
+}
+/* end of vcal only */
+
+/* ical only */
+static VFormatAttribute *handle_xml_atrigger_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TRIGGER");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_arepeat_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "REPEAT");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aduration_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DURATION");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aaction_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ACTION");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aattach_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ATTACH");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_adescription_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DESCRIPTION");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_aattendee_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ATTENDEE");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_asummary_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "SUMMARY");
+ add_value(attr, root, NULL, encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+/* end of ical only */
+
+void xml_parse_attribute(OSyncHooksTable *hooks, GHashTable *table, xmlNode **current, VFormat *vcal, VFormatType target)
+{
+ osync_trace(TRACE_INTERNAL, "parsing xml attributes");
+ void *xml_param_handler = NULL;
+ VFormatAttribute *attr = NULL;
+ xmlNode *root = *current;
+ while (root) {
+ if (!strcmp((char*)root->name, "Todo")) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "VTODO");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->comptable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "VTODO");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "Timezone") && target != VFORMAT_EVENT_10) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "VTIMEZONE");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->tztable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "VTIMEZONE");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "Event")) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "VEVENT");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->comptable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "VEVENT");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "Journal")) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "VJOURNAL");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->tztable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "VJOURNAL");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "DaylightSavings")) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "DAYLIGHT");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->tztable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "DAYLIGHT");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "Standard")) {
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "STANDARD");
+ vformat_add_attribute(vcal, attr);
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->tztable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "STANDARD");
+ vformat_add_attribute(vcal, attr);
+ } else if (!strcmp((char*)root->name, "Alarm") && target != VFORMAT_EVENT_10) {
+
+ xmlNode *child = root->children;
+ attr = vformat_attribute_new(NULL, "BEGIN");
+ vformat_attribute_add_value(attr, "VALARM");
+ vformat_add_attribute(vcal, attr);
+ xml_parse_attribute(hooks, hooks->alarmtable, &child, vcal, target);
+ attr = vformat_attribute_new(NULL, "END");
+ vformat_attribute_add_value(attr, "VALARM");
+ vformat_add_attribute(vcal, attr);
+
+ /* list of parameters which should NOT handle for vcal (event10) */
+ } else if (!strcmp((char*)root->name, "ExclusionDate") && target == VFORMAT_EVENT_10) {
+ xml_param_handler = g_hash_table_lookup(hooks->comptable, "Value");
+ g_hash_table_insert(hooks->comptable, "Value", HANDLE_IGNORE);
+ g_hash_table_insert(hooks->comptable, "Content", handle_vcal_xml_exdate_attribute);
+
+ xmlNode *child = root->children;
+ xml_parse_attribute(hooks, hooks->comptable, &child, vcal, target);
+
+ g_hash_table_insert(hooks->comptable, "Value", xml_param_handler);
+ g_hash_table_remove(hooks->comptable, "Content");
+
+ } else {
+ xml_vcal_handle_attribute(table, vcal, root);
+ }
+ root = root->next;
+ }
+}
+
+
+static void insert_xml_attr_handler(GHashTable *table, const char *name, xml_attr_handler_t handler)
+{
+ g_hash_table_insert(table, (gpointer)name, handler);
+}
+
+static osync_bool conv_xml_to_vcal(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error, VFormatType target)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+
+ xmlChar *str = osxml_write_to_string((xmlDoc *)input);
+ osync_trace(TRACE_SENSITIVE, "Input XML is:\n%s", str);
+ xmlFree(str);
+
+ //Get the root node of the input document
+ xmlNode *root = osxml_node_get_root((xmlDoc *)input, "vcal", error);
+ if (!root) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get root element of xml-contact");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+ }
+
+ //Make the new vcard
+ VFormat *vcal = vformat_new();
+
+ OSyncHooksTable *hooks = (OSyncHooksTable *)user_data;
+ /* vevent10 / vevent20 */
+ if (target == VFORMAT_EVENT_10) {
+ /* RRULE */
+ insert_xml_attr_handler(hooks->comptable, "RecurrenceRule", handle_vcal_xml_rrule_attribute);
+ insert_xml_attr_handler(hooks->comptable, "ExclusionDate", handle_vcal_xml_exdate_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Alarm", handle_vcal_xml_alarm_attribute);
+ g_hash_table_insert(hooks->comptable, "Rule", HANDLE_IGNORE);
+
+ /* TRANSP */
+ insert_xml_attr_handler(hooks->comptable, "Transparency", handle_vcal_xml_transp_attribute);
+
+ /* vcal attributes */
+ insert_xml_attr_handler(hooks->comptable, "DateEnd", handle_vcal_xml_dtend_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateDue", handle_vcal_xml_due_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateStarted", handle_vcal_xml_dtstart_attribute);
+
+ /* vcal parameter */
+ g_hash_table_insert(hooks->comptable, "Value", HANDLE_IGNORE);
+
+
+ } else {
+ /* RRULE */
+ insert_xml_attr_handler(hooks->comptable, "RecurrenceRule", handle_xml_rrule_attribute);
+ insert_xml_attr_handler(hooks->comptable, "ExclusionDate", handle_xml_exdate_attribute);
+ g_hash_table_insert(hooks->comptable, "Rule", handle_xml_rule_parameter);
+
+ /* TRANSP */
+ insert_xml_attr_handler(hooks->comptable, "Transparency", handle_xml_transp_attribute);
+
+ /* ical attributes */
+ g_hash_table_insert(hooks->table, "Method", handle_xml_method_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateEnd", handle_xml_dtend_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateDue", handle_xml_due_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateStarted", handle_xml_dtstart_attribute);
+
+ /* Timezone */
+ g_hash_table_insert(hooks->tztable, "TimezoneID", handle_xml_tzid_attribute);
+ g_hash_table_insert(hooks->tztable, "Location", handle_xml_tz_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TZOffsetFrom", handle_xml_tzoffsetfrom_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TZOffsetTo", handle_xml_tzoffsetto_location_attribute);
+ g_hash_table_insert(hooks->tztable, "TimezoneName", handle_xml_tzname_attribute);
+ g_hash_table_insert(hooks->tztable, "DateStarted", handle_xml_tzdtstart_attribute);
+ g_hash_table_insert(hooks->tztable, "RecurrenceRule", handle_xml_tzrrule_attribute);
+ g_hash_table_insert(hooks->tztable, "LastModified", handle_xml_tz_last_modified_attribute);
+ g_hash_table_insert(hooks->tztable, "TimezoneUrl", handle_xml_tzurl_attribute);
+ g_hash_table_insert(hooks->tztable, "RecurrenceDate", handle_xml_tzrdate_attribute);
+
+ /* VAlarm component */
+ g_hash_table_insert(hooks->alarmtable, "AlarmTrigger", handle_xml_atrigger_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmRepeat", handle_xml_arepeat_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmDuration", handle_xml_aduration_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmAction", handle_xml_aaction_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmAttach", handle_xml_aattach_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmDescription", handle_xml_adescription_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmAttendee", handle_xml_aattendee_attribute);
+ g_hash_table_insert(hooks->alarmtable, "AlarmSummary", handle_xml_asummary_attribute);
+
+ }
+
+ xml_parse_attribute(hooks, hooks->table, &root, vcal, target);
+
+ *free_input = TRUE;
+ *output = vformat_to_string(vcal, target);
+ osync_trace(TRACE_SENSITIVE, "vevent output is: \n%s", *output);
+ *outpsize = strlen(*output);
+ osync_trace(TRACE_EXIT, "%s", __func__);
+
+ return TRUE;
+}
+
+static osync_bool conv_xml_to_vevent10(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcal(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_EVENT_10);
+}
+
+static osync_bool conv_xml_to_vevent20(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcal(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_EVENT_20);
+}
+
+static osync_bool conv_xml_to_vtodo10(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcal(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_TODO_10);
+}
+
+static osync_bool conv_xml_to_vtodo20(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcal(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_TODO_20);
+}
+
+static void *init_xml_to_vcal(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+
+ OSyncHooksTable *hooks = g_malloc0(sizeof(OSyncHooksTable));
+
+ hooks->table = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->tztable = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->comptable = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->alarmtable = g_hash_table_new(g_str_hash, g_str_equal);
+
+ //todo attributes
+ insert_xml_attr_handler(hooks->comptable, "Uid", handle_xml_uid_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateCalendarCreated", handle_xml_dtstamp_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Description", handle_xml_description_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Summary", handle_xml_summary_attribute);
+ insert_xml_attr_handler(hooks->comptable, "PercentComplete", handle_xml_percent_complete_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Class", handle_xml_class_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Categories", handle_xml_categories_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Priority", handle_xml_priority_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Url", handle_xml_url_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Sequence", handle_xml_sequence_attribute);
+ insert_xml_attr_handler(hooks->comptable, "LastModified", handle_xml_last_modified_attribute);
+ insert_xml_attr_handler(hooks->comptable, "DateCreated", handle_xml_created_attribute);
+ insert_xml_attr_handler(hooks->comptable, "RecurrenceDate", handle_xml_rdate_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Location", handle_xml_location_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Geo", handle_xml_geo_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Completed", handle_xml_completed_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Organizer", handle_xml_organizer_attribute);
+ insert_xml_attr_handler(hooks->comptable, "RecurrenceID", handle_xml_recurid_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Status", handle_xml_status_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Duration", handle_xml_duration_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Attach", handle_xml_attach_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Attendee", handle_xml_attendee_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Contact", handle_xml_contact_attribute);
+ insert_xml_attr_handler(hooks->comptable, "ExclusionRule", handle_xml_exrule_attribute);
+ insert_xml_attr_handler(hooks->comptable, "RStatus", handle_xml_rstatus_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Related", handle_xml_related_attribute);
+ insert_xml_attr_handler(hooks->comptable, "Resources", handle_xml_resources_attribute);
+
+
+ /*FIXME: The functions below shouldn't be on comptable, but on other hash table */
+ g_hash_table_insert(hooks->comptable, "Category", handle_xml_category_parameter);
+ g_hash_table_insert(hooks->comptable, "Value", handle_xml_value_parameter);
+ g_hash_table_insert(hooks->comptable, "AlternateRep", handle_xml_altrep_parameter);
+ g_hash_table_insert(hooks->comptable, "CommonName", handle_xml_cn_parameter);
+ g_hash_table_insert(hooks->comptable, "DelegatedFrom", handle_xml_delegated_from_parameter);
+ g_hash_table_insert(hooks->comptable, "DelegatedTo", handle_xml_delegated_to_parameter);
+ g_hash_table_insert(hooks->comptable, "Directory", handle_xml_dir_parameter);
+ g_hash_table_insert(hooks->comptable, "FormaType", handle_xml_format_type_parameter);
+ g_hash_table_insert(hooks->comptable, "FreeBusyType", handle_xml_fb_type_parameter);
+ g_hash_table_insert(hooks->comptable, "Member", handle_xml_member_parameter);
+ g_hash_table_insert(hooks->comptable, "PartStat", handle_xml_partstat_parameter);
+ g_hash_table_insert(hooks->comptable, "Range", handle_xml_range_parameter);
+ g_hash_table_insert(hooks->comptable, "Related", handle_xml_related_parameter);
+ g_hash_table_insert(hooks->comptable, "RelationType", handle_xml_reltype_parameter);
+ g_hash_table_insert(hooks->comptable, "Role", handle_xml_role_parameter);
+ g_hash_table_insert(hooks->comptable, "RSVP", handle_xml_rsvp_parameter);
+ g_hash_table_insert(hooks->comptable, "SentBy", handle_xml_sent_by_parameter);
+
+ //vcal attributes
+ g_hash_table_insert(hooks->table, "CalendarScale", handle_xml_calscale_attribute);
+ g_hash_table_insert(hooks->table, "ProductID", handle_xml_prodid_attribute);
+ g_hash_table_insert(hooks->table, "UnknownNode", xml_handle_unknown_attribute);
+ g_hash_table_insert(hooks->table, "UnknownParameter", xml_handle_unknown_parameter);
+
+ /*FIXME: The functions below shouldn't be on tztable, but on other hash table */
+ g_hash_table_insert(hooks->tztable, "Category", handle_xml_category_parameter);
+ g_hash_table_insert(hooks->tztable, "Rule", handle_xml_rule_parameter);
+ g_hash_table_insert(hooks->tztable, "Value", handle_xml_value_parameter);
+ g_hash_table_insert(hooks->tztable, "AlternateRep", handle_xml_altrep_parameter);
+ g_hash_table_insert(hooks->tztable, "CommonName", handle_xml_cn_parameter);
+ g_hash_table_insert(hooks->tztable, "DelegatedFrom", handle_xml_delegated_from_parameter);
+ g_hash_table_insert(hooks->tztable, "DelegatedTo", handle_xml_delegated_to_parameter);
+ g_hash_table_insert(hooks->tztable, "Directory", handle_xml_dir_parameter);
+ g_hash_table_insert(hooks->tztable, "FormaType", handle_xml_format_type_parameter);
+ g_hash_table_insert(hooks->tztable, "FreeBusyType", handle_xml_fb_type_parameter);
+ g_hash_table_insert(hooks->tztable, "Member", handle_xml_member_parameter);
+ g_hash_table_insert(hooks->tztable, "PartStat", handle_xml_partstat_parameter);
+ g_hash_table_insert(hooks->tztable, "Range", handle_xml_range_parameter);
+ g_hash_table_insert(hooks->tztable, "Related", handle_xml_related_parameter);
+ g_hash_table_insert(hooks->tztable, "RelationType", handle_xml_reltype_parameter);
+ g_hash_table_insert(hooks->tztable, "Role", handle_xml_role_parameter);
+ g_hash_table_insert(hooks->tztable, "RSVP", handle_xml_rsvp_parameter);
+ g_hash_table_insert(hooks->tztable, "SentBy", handle_xml_sent_by_parameter);
+
+
+ /*FIXME: The functions below shouldn't be on alarmtable, but on other hash table */
+ g_hash_table_insert(hooks->alarmtable, "Category", handle_xml_category_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Rule", handle_xml_rule_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Value", handle_xml_value_parameter);
+ g_hash_table_insert(hooks->alarmtable, "AlternateRep", handle_xml_altrep_parameter);
+ g_hash_table_insert(hooks->alarmtable, "CommonName", handle_xml_cn_parameter);
+ g_hash_table_insert(hooks->alarmtable, "DelegatedFrom", handle_xml_delegated_from_parameter);
+ g_hash_table_insert(hooks->alarmtable, "DelegatedTo", handle_xml_delegated_to_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Directory", handle_xml_dir_parameter);
+ g_hash_table_insert(hooks->alarmtable, "FormaType", handle_xml_format_type_parameter);
+ g_hash_table_insert(hooks->alarmtable, "FreeBusyType", handle_xml_fb_type_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Member", handle_xml_member_parameter);
+ g_hash_table_insert(hooks->alarmtable, "PartStat", handle_xml_partstat_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Range", handle_xml_range_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Related", handle_xml_related_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RelationType", handle_xml_reltype_parameter);
+ g_hash_table_insert(hooks->alarmtable, "Role", handle_xml_role_parameter);
+ g_hash_table_insert(hooks->alarmtable, "RSVP", handle_xml_rsvp_parameter);
+ g_hash_table_insert(hooks->alarmtable, "SentBy", handle_xml_sent_by_parameter);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks);
+ return (void *)hooks;
+}
+
+static void fin_xml_to_vcal(void *data)
+{
+ OSyncHooksTable *hooks = (OSyncHooksTable *)data;
+ g_hash_table_destroy(hooks->table);
+ g_free(hooks);
+}
+
+static time_t get_revision(OSyncChange *change, const char *path, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error);
+
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ xmlXPathObject *xobj = osxml_get_nodeset(doc, path);
+
+ xmlNodeSet *nodes = xobj->nodesetval;
+
+ int size = (nodes) ? nodes->nodeNr : 0;
+ if (size != 1) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find the revision");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return -1;
+ }
+
+ char *revision = (char*)xmlNodeGetContent(nodes->nodeTab[0]);
+
+ time_t time = vformat_time_to_unix(revision);
+ g_free(revision);
+ xmlXPathFreeObject(xobj);
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, time);
+ return time;
+}
+
+static time_t get_todo_revision(OSyncChange *change, OSyncError **error)
+{
+ return get_revision(change, "/vcal/Todo/LastModified", error);
+}
+
+static time_t get_event_revision(OSyncChange *change, OSyncError **error)
+{
+ return get_revision(change, "/vcal/Event/LastModified", error);
+}
+
+void get_info(OSyncEnv *env)
+{
+ //Calendar
+ osync_env_register_objtype(env, "event");
+ osync_env_register_objformat(env, "event", "xml-event");
+ osync_env_format_set_compare_func(env, "xml-event", compare_vevent);
+ osync_env_format_set_destroy_func(env, "xml-event", destroy_xml);
+ osync_env_format_set_print_func(env, "xml-event", print_vcal);
+ osync_env_format_set_copy_func(env, "xml-event", osxml_copy);
+ osync_env_format_set_revision_func(env, "xml-event", get_event_revision);
+ osync_env_format_set_marshall_func(env, "xml-event", osxml_marshall);
+ osync_env_format_set_demarshall_func(env, "xml-event", osxml_demarshall);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vevent10", "xml-event", conv_vcal_to_xml);
+ osync_env_converter_set_init(env, "vevent10", "xml-event", init_vcal_to_xml, fin_vcal_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-event", "vevent10", conv_xml_to_vevent10);
+ osync_env_converter_set_init(env, "xml-event", "vevent10", init_xml_to_vcal, fin_xml_to_vcal);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vevent20", "xml-event", conv_vcal_to_xml);
+ osync_env_converter_set_init(env, "vevent20", "xml-event", init_ical_to_xml, fin_vcal_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-event", "vevent20", conv_xml_to_vevent20);
+ osync_env_converter_set_init(env, "xml-event", "vevent20", init_xml_to_vcal, fin_xml_to_vcal);
+
+ //Todo
+ osync_env_register_objtype(env, "todo");
+ osync_env_register_objformat(env, "todo", "xml-todo");
+ osync_env_format_set_compare_func(env, "xml-todo", compare_vtodo);
+ osync_env_format_set_destroy_func(env, "xml-todo", destroy_xml);
+ osync_env_format_set_print_func(env, "xml-todo", print_vcal);
+ osync_env_format_set_copy_func(env, "xml-todo", osxml_copy);
+ osync_env_format_set_revision_func(env, "xml-todo", get_todo_revision);
+ osync_env_format_set_marshall_func(env, "xml-todo", osxml_marshall);
+ osync_env_format_set_demarshall_func(env, "xml-todo", osxml_demarshall);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vtodo10", "xml-todo", conv_vcal_to_xml);
+ osync_env_converter_set_init(env, "vtodo10", "xml-todo", init_vcal_to_xml, fin_vcal_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-todo", "vtodo10", conv_xml_to_vtodo10);
+ osync_env_converter_set_init(env, "xml-todo", "vtodo10", init_xml_to_vcal, fin_xml_to_vcal);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vtodo20", "xml-todo", conv_vcal_to_xml);
+ osync_env_converter_set_init(env, "vtodo20", "xml-todo", init_ical_to_xml, fin_vcal_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-todo", "vtodo20", conv_xml_to_vtodo20);
+ osync_env_converter_set_init(env, "xml-todo", "vtodo20", init_xml_to_vcal, fin_xml_to_vcal);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.h b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.h
new file mode 100644
index 00000000..dcc4a02e
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcal.h
@@ -0,0 +1,16 @@
+#ifndef _XMLVCARD_H_
+#define _XMLVCARD_H_
+
+typedef struct OSyncHooksTable OSyncHooksTable;
+
+struct OSyncHooksTable {
+ GHashTable *table;
+ GHashTable *tztable;
+ GHashTable *comptable;
+ GHashTable *compparamtable;
+ GHashTable *alarmtable;
+};
+
+#define HANDLE_IGNORE (void *)1
+
+#endif //_XMLVCARD_H_
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.c
new file mode 100644
index 00000000..a577ed86
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.c
@@ -0,0 +1,1405 @@
+/*
+ * xml-vcard - A plugin for parsing vcard objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include "xml-vcard.h"
+#include <opensync/opensync_xml.h>
+#include <glib.h>
+
+static const char * rewrite_mime_type(const char * source_format, int use_iana);
+static int _helper_is_base64(const char *);
+
+static void handle_unknown_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown parameter %s", vformat_attribute_param_get_name(param));
+ xmlNode *property = xmlNewTextChild(current, NULL, (xmlChar*)"UnknownParam",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+ osxml_node_add(property, "ParamName", vformat_attribute_param_get_name(param));
+}
+
+static void handle_encoding_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "%s: xmlNodeName=%s, param=%s", __func__,
+ (char *)current->name,
+ vformat_attribute_param_get_name(param));
+ GList *v = vformat_attribute_param_get_values(param);
+ for (; v; v = v->next) {
+ char * content = g_strdup(v->data);
+ if (_helper_is_base64((const char *)content))
+ {
+ g_free(content);
+ content=g_strdup("B");
+ }
+ xmlNewTextChild(current, NULL, (xmlChar*)"Encoding", (xmlChar*)content);
+ g_free(content);
+ }
+}
+
+static void handle_type_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "%s: xmlNodeName=%s, param=%s", __func__,
+ (char *)current->name,
+ vformat_attribute_param_get_name(param));
+ GList *v = vformat_attribute_param_get_values(param);
+ /**
+ * PHOTO and LOGO TYPE parameter should be rewritten
+ * PHOTO;TYPE=JPEG -> PHOTO;TYPE=image/jpeg
+ **/
+ if ( xmlStrcmp(current->name, (const xmlChar *)"Photo") && xmlStrcmp(current->name, (const xmlChar *)"Logo")) {
+ for (; v; v = v->next) {
+ xmlNewTextChild(current, NULL,
+ (xmlChar*)"Type", (xmlChar*)v->data);
+ }
+ } else {
+ for (; v; v = v->next) {
+ const char * tmp = rewrite_mime_type(v->data, 1);
+ if (tmp)
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type",
+ (xmlChar*)tmp);
+ }
+ }
+
+}
+
+static void handle_value_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling value parameter %s", vformat_attribute_param_get_name(param));
+
+ GList *v = vformat_attribute_param_get_values(param);
+ for (; v; v = v->next) {
+ xmlNewTextChild(current, NULL, (xmlChar*)"Value", (xmlChar*)v->data);
+ }
+}
+
+static xmlNode *handle_formatted_name_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling formatted name attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"FormattedName", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_name_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling name attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Name", NULL);
+ osxml_node_add(current, "LastName", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "FirstName", vformat_attribute_get_nth_value(attr, 1));
+ osxml_node_add(current, "Additional", vformat_attribute_get_nth_value(attr, 2));
+ osxml_node_add(current, "Prefix", vformat_attribute_get_nth_value(attr, 3));
+ osxml_node_add(current, "Suffix", vformat_attribute_get_nth_value(attr, 4));
+ return current;
+}
+
+static xmlNode *handle_agent_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling agent attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Agent", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_photo_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "%s:Handling photo attribute", __func__);
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Photo", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_birthday_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ char *datestamp;
+ const char *tmp;
+
+ osync_trace(TRACE_INTERNAL, "Handling birthday attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Birthday", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ datestamp = osync_time_datestamp(tmp);
+ osxml_node_add(current, "Content", datestamp);
+ free(datestamp);
+
+ return current;
+}
+
+static xmlNode *handle_address_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling address attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Address", NULL);
+ osxml_node_add(current, "PostalBox", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "ExtendedAddress", vformat_attribute_get_nth_value(attr, 1));
+ osxml_node_add(current, "Street", vformat_attribute_get_nth_value(attr, 2));
+ osxml_node_add(current, "City", vformat_attribute_get_nth_value(attr, 3));
+ osxml_node_add(current, "Region", vformat_attribute_get_nth_value(attr, 4));
+ osxml_node_add(current, "PostalCode", vformat_attribute_get_nth_value(attr, 5));
+ osxml_node_add(current, "Country", vformat_attribute_get_nth_value(attr, 6));
+ return current;
+}
+
+static xmlNode *handle_label_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling AddressLabel attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"AddressLabel", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_telephone_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Telephone attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Telephone", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_email_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling EMail attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"EMail", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_mailer_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Mailer attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Mailer", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_timezone_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Timezone attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Timezone", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_location_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Location attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Location", NULL);
+ osxml_node_add(current, "Latitude", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "Longitude", vformat_attribute_get_nth_value(attr, 1));
+ return current;
+}
+
+static xmlNode *handle_title_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Title attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Title", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_role_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Role attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Role", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_logo_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Logo attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Logo", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_organization_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Organization attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Organization", NULL);
+ osxml_node_add(current, "Name", vformat_attribute_get_nth_value(attr, 0));
+ osxml_node_add(current, "Department", vformat_attribute_get_nth_value(attr, 1));
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ values = g_list_nth(values, 2);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Unit", retstr->str);
+ }
+ return current;
+}
+
+static xmlNode *handle_note_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Note attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Note", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_revision_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ const char *tmp;
+ char *revision;
+
+ osync_trace(TRACE_INTERNAL, "Handling Revision attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Revision", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ revision = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", revision);
+ free(revision);
+ return current;
+}
+
+static xmlNode *handle_sound_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Sound attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Sound", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_url_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Url attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Url", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_uid_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Uid attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Uid", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_key_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Key attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Key", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_nickname_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Nickname attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Nickname", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_class_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Class attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Class", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_categories_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Categories attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Categories", NULL);
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Category", retstr->str);
+ }
+
+ return current;
+}
+
+static xmlNode *handle_unknown_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown attribute %s", vformat_attribute_get_name(attr));
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"UnknownNode", NULL);
+ osxml_node_add(current, "NodeName", vformat_attribute_get_name(attr));
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Content", retstr->str);
+ }
+ return current;
+}
+
+static void vcard_handle_parameter(GHashTable *hooks, xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, hooks, current, param);
+
+ //Find the handler for this parameter
+ void (* param_handler)(xmlNode *, VFormatParam *);
+ char *paramname = g_strdup_printf("%s=%s", vformat_attribute_param_get_name(param), vformat_attribute_param_get_nth_value(param, 0));
+ param_handler = g_hash_table_lookup(hooks, paramname);
+ g_free(paramname);
+ if (!param_handler)
+ param_handler = g_hash_table_lookup(hooks, vformat_attribute_param_get_name(param));
+
+ if (param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (param_handler)
+ param_handler(current, param);
+ else
+ handle_unknown_parameter(current, param);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void vcard_handle_attribute(GHashTable *hooks, xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, root, attr, attr ? vformat_attribute_get_name(attr) : "None");
+ xmlNode *current = NULL;
+
+ //Dont add empty stuff
+ GList *v;
+ for (v = vformat_attribute_get_values(attr); v; v = v->next) {
+ char *value = v->data;
+ if (strlen(value) != 0)
+ goto has_value;
+ }
+ osync_trace(TRACE_EXIT, "%s: No values", __func__);
+ return;
+
+has_value:;
+
+ //We need to find the handler for this attribute
+ xmlNode *(* attr_handler)(xmlNode *, VFormatAttribute *) = g_hash_table_lookup(hooks, vformat_attribute_get_name(attr));
+ osync_trace(TRACE_INTERNAL, "Hook is: %p", attr_handler);
+ if (attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (attr_handler)
+ current = attr_handler(root, attr);
+ else
+ current = handle_unknown_attribute(root, attr);
+
+ //Handle all parameters of this attribute
+ GList *params = vformat_attribute_get_params(attr);
+ GList *p = NULL;
+ for (p = params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ vcard_handle_parameter(hooks, current, param);
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void _generate_formatted_name(VFormat *vcard, xmlNode *root)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, root);
+ VFormatAttribute *n = vformat_find_attribute(vcard, "N");
+ GList *v = vformat_attribute_get_values(n);
+ GString *fnentry;
+ fnentry = g_string_new("");
+
+ // NAME:LAST;FIRST;ADDITIONAL;PREFIX;SUFFIX
+ // FN:PREFIX FIRST ADDITIONAL LAST SUFFIX
+
+ int order[5] = {3, 1, 2, 0, 4};
+ int i = 0;
+ char *str = NULL;
+ for (i = 0; i < 5; i++) {
+ if ((str = g_list_nth_data(v, order[i])) && str[0]) {
+ if (fnentry->len != 0)
+ g_string_append(fnentry, " ");
+ g_string_append(fnentry, str);
+ }
+ }
+
+ osync_trace(TRACE_INTERNAL, "Handling formattedname attribute");
+
+ if (fnentry->len != 0) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"FormattedName", NULL);
+ osxml_node_add(current, "Content", fnentry->str);
+ } else {
+ osync_trace(TRACE_INTERNAL, "FN is empty!");
+ }
+
+ g_string_free(fnentry,TRUE);
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return;
+}
+
+static void _generate_name_from_fn(VFormat *vcard, xmlNode *root)
+{
+ /*
+ * We copy FN to N:LASTNAME because we don't now how FN was build.
+ * e.g. we don't know if FN is "PREFIX FIRST LAST" or "FIRST ADDITIONAL LAST"
+ * With copying FN to N we prevent the vcard from being invalid.
+ */
+
+ osync_trace(TRACE_ENTRY, "%s(%p)", __func__, root);
+ VFormatAttribute *n = vformat_find_attribute(vcard, "FN");
+ char *fn = vformat_attribute_get_value(n);
+
+ osync_trace(TRACE_INTERNAL, "Handling name attribute");
+ if (strlen(fn) != 0) {
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Name", NULL);
+ osxml_node_add(current, "LastName", fn);
+ } else {
+ osync_trace(TRACE_INTERNAL, "Name is empty");
+ }
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return;
+}
+
+static osync_bool conv_vcard_to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, conv_data, input, inpsize, output, outpsize, free_input, error);
+
+ GHashTable *hooks = (GHashTable *)conv_data;
+
+ osync_trace(TRACE_SENSITIVE, "Input Vcard is:\n%s", input);
+
+ /* The input is not null-terminated, but vformat_new_from_string() expects a null-terminated string */
+ char *input_str = g_malloc(inpsize + 1);
+ memcpy(input_str, input, inpsize);
+ input_str[inpsize] = '\0';
+
+ //Parse the vcard
+ VFormat *vcard = vformat_new_from_string(input_str);
+
+ g_free(input_str);
+
+ osync_trace(TRACE_INTERNAL, "Creating xml doc");
+
+ //Create a new xml document
+ xmlDoc *doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlNode *root = osxml_node_add_root(doc, "contact");
+
+ osync_trace(TRACE_INTERNAL, "parsing attributes");
+
+ //For every attribute we have call the handling hook
+ GList *attributes = vformat_get_attributes(vcard);
+ GList *a = NULL;
+ for (a = attributes; a; a = a->next) {
+ VFormatAttribute *attr = a->data;
+ vcard_handle_attribute(hooks, root, attr);
+ }
+
+ //Generate FormattedName from Name if it doesn't exist
+ if (!vformat_find_attribute(vcard, "FN") && vformat_find_attribute(vcard, "N")) {
+ _generate_formatted_name(vcard,root);
+ }
+
+ //Generate Name from FormattedName if it doesn't exist
+ if (!vformat_find_attribute(vcard, "N") && vformat_find_attribute(vcard, "FN")) {
+ _generate_name_from_fn(vcard,root);
+ }
+
+ xmlChar *str = osxml_write_to_string(doc);
+ osync_trace(TRACE_SENSITIVE, "Output XML is:\n%s", str);
+ xmlFree(str);
+
+ *free_input = TRUE;
+ *output = (char *)doc;
+ *outpsize = sizeof(doc);
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool needs_encoding(const unsigned char *tmp, const char *encoding)
+{
+ int i = 0;
+ if (!strcmp(encoding, "QUOTED-PRINTABLE")) {
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127 || tmp[i] == 10 || tmp[i] == 13)
+ return TRUE;
+ i++;
+ }
+ } else {
+ return !g_utf8_validate((gchar*)tmp, -1, NULL);
+ }
+ return FALSE;
+}
+
+static osync_bool needs_charset(const unsigned char *tmp)
+{
+ int i = 0;
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+static void add_value(VFormatAttribute *attr, xmlNode *parent, const char *name, const char *encoding)
+{
+ char *tmp = osxml_find_node(parent, name);
+
+ if (!tmp) {
+ /* If there is no node with the given name, add an empty value to the list.
+ * This is necessary because some fields (N and ADR, for example) need
+ * a specific order of the values
+ */
+ tmp = g_strdup("");
+ }
+
+ if (needs_charset((unsigned char*)tmp))
+ if (!vformat_attribute_has_param (attr, "CHARSET"))
+ vformat_attribute_add_param_with_value(attr, "CHARSET", "UTF-8");
+
+ if (needs_encoding((unsigned char*)tmp, encoding)) {
+ if (!vformat_attribute_has_param (attr, "ENCODING"))
+ vformat_attribute_add_param_with_value(attr, "ENCODING", encoding);
+ vformat_attribute_add_value_decoded(attr, tmp, strlen(tmp) + 1);
+ } else
+ vformat_attribute_add_value(attr, tmp);
+ g_free(tmp);
+}
+
+/**
+ * handle_xml_type_parameter:
+ * Photo or Logo Type will be IANA Mime type or not set
+ * @param attr
+ * @param current
+ */
+static void handle_xml_type_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "%s: nodename=%s",
+ __func__, (char *)current->parent->name);
+ char *content = (char*)xmlNodeGetContent(current);
+ if(!xmlStrcmp(current->parent->name, (const xmlChar *)"Photo") || !xmlStrcmp(current->parent->name, (const xmlChar *)"Logo")) {
+ content = (char *)rewrite_mime_type((const char *)content, 1);
+ if(!content)
+ return;
+ }
+ VFormatParam *param = vformat_attribute_param_new("TYPE");
+ vformat_attribute_param_add_value(param, content);
+ vformat_attribute_add_param (attr, param);
+}
+
+/**
+ * handle_xml_type_parameter:
+ * Photo or Logo Type will be not IANA Mime type or not set
+ * @param attr
+ * @param current
+ */
+static void handle_xml_type_no_iana_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "%s: nodename=%s",
+ __func__, (char *)current->parent->name);
+ char *content = (char*)xmlNodeGetContent(current);
+ if(!xmlStrcmp(current->parent->name, (const xmlChar *)"Photo") || !xmlStrcmp(current->parent->name, (const xmlChar *)"Logo")) {
+ content = (char *)rewrite_mime_type((const char *)content, 0);
+ if(!content)
+ return;
+ }
+ VFormatParam *param = vformat_attribute_param_new("TYPE");
+ vformat_attribute_param_add_value(param, content);
+ vformat_attribute_add_param (attr, param);
+}
+
+static void handle_xml_encoding_21_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "%s()",__func__);
+ char *content = (char*)xmlNodeGetContent(current);
+ if (_helper_is_base64((const char *)content))
+ {
+ g_free(content);
+ content=g_strdup("BASE64");
+ }
+ VFormatParam *param = vformat_attribute_param_new("ENCODING");
+ vformat_attribute_param_add_value(param, content);
+ vformat_attribute_add_param (attr, param);
+ g_free(content);
+}
+
+static void handle_xml_encoding_30_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "%s()",__func__);
+ char *content = (char*)xmlNodeGetContent(current);
+ VFormatParam *param = vformat_attribute_param_new("ENCODING");
+ if (_helper_is_base64((const char *)content))
+ {
+ g_free(content);
+ content=g_strdup("B");
+ }
+ vformat_attribute_param_add_value(param, content);
+ vformat_attribute_add_param (attr, param);
+ g_free(content);
+}
+
+static void handle_xml_value_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling value xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ VFormatParam *param = vformat_attribute_param_new("VALUE");
+ vformat_attribute_param_add_value(param, content);
+ vformat_attribute_add_param (attr, param);
+ g_free(content);
+}
+
+static void handle_xml_category_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling category xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_value(attr, content);
+ g_free(content);
+}
+
+static void handle_xml_unit_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unit xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_value(attr, content);
+ g_free(content);
+}
+
+static void xml_handle_unknown_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml parameter %s", current->name);
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, (char*)current->name, content);
+ g_free(content);
+}
+
+static void xml_vcard_handle_parameter(OSyncHookTables *hooks, VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, attr, current, current ? (char *)current->name : "None");
+
+ //Find the handler for this parameter
+ void (* xml_param_handler)(VFormatAttribute *attr, xmlNode *);
+ char *content = (char*)xmlNodeGetContent(current);
+ char *paramname = g_strdup_printf("%s=%s", current->name, content);
+ g_free(content);
+ xml_param_handler = g_hash_table_lookup(hooks->parameters, paramname);
+ g_free(paramname);
+ if (!xml_param_handler)
+ xml_param_handler = g_hash_table_lookup(hooks->parameters, current->name);
+
+ if (xml_param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (xml_param_handler)
+ xml_param_handler(attr, current);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static VFormatAttribute *xml_handle_unknown_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml attribute %s", root->name);
+ char *name = osxml_find_node(root, "NodeName");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, name);
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_formatted_name_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling formatted name xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "FN");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_name_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling name xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "N");
+ add_value(attr, root, "LastName", encoding);
+ add_value(attr, root, "FirstName", encoding);
+ add_value(attr, root, "Additional", encoding);
+ add_value(attr, root, "Prefix", encoding);
+ add_value(attr, root, "Suffix", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_agent_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling agent xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "AGENT");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static void xml_vcard_handle_attribute(OSyncHookTables *hooks, VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, vcard, root, root ? (char *)root->name : "None");
+ VFormatAttribute *attr = NULL;
+
+ //We need to find the handler for this attribute
+ VFormatAttribute *(* xml_attr_handler)(VFormat *vcard, xmlNode *root, const char *) = g_hash_table_lookup(hooks->attributes, root->name);
+ osync_trace(TRACE_INTERNAL, "xml hook is: %p", xml_attr_handler);
+ if (xml_attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (xml_attr_handler)
+ attr = xml_attr_handler(vcard, root, encoding);
+ else {
+ osync_trace(TRACE_EXIT, "%s: Ignored2", __func__);
+ return;
+ }
+
+ //Handle all parameters of this attribute
+ xmlNode *child = root->xmlChildrenNode;
+ while (child) {
+ xml_vcard_handle_parameter(hooks, attr, child);
+ child = child->next;
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static VFormatAttribute *handle_xml_photo_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "%s:Handling photo xml attribute", __func__);
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "PHOTO");
+ add_value(attr, root, "Content", encoding);
+// vformat_attribute_add_param_with_value(attr, "ENCODING", "b");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_photo_base64_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "%s:Handling photo xml attribute", __func__);
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "PHOTO");
+ add_value(attr, root, "Content", encoding);
+// vformat_attribute_add_param_with_value(attr, "ENCODING", "BASE64");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_birthday_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling birthday xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "BDAY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_address_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling address xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ADR");
+ add_value(attr, root, "PostalBox", encoding);
+ add_value(attr, root, "ExtendedAddress", encoding);
+ add_value(attr, root, "Street", encoding);
+ add_value(attr, root, "City", encoding);
+ add_value(attr, root, "Region", encoding);
+ add_value(attr, root, "PostalCode", encoding);
+ add_value(attr, root, "Country", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_label_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling label xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LABEL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_telephone_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling telephone xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TEL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_email_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling email xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "EMAIL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_mailer_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling mailer xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "MAILER");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_timezone_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling timezone xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TZ");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_location_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling location xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "GEO");
+ add_value(attr, root, "Latitude", encoding);
+ add_value(attr, root, "Longitude", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_title_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling title xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "TITLE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_role_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling role xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ROLE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_logo_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling logo xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LOGO");
+ add_value(attr, root, "Content", encoding);
+ //vformat_attribute_add_param_with_value(attr, "ENCODING", "b");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_organization_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling organization xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "ORG");
+ add_value(attr, root, "Name", encoding);
+ add_value(attr, root, "Department", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_note_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling note xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "NOTE");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_revision_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling revision xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "REV");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_sound_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling sound xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "SOUND");
+ add_value(attr, root, "Content", encoding);
+ //vformat_attribute_add_param_with_value(attr, "ENCODING", "b");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_url_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling url xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "URL");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_uid_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling uid xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "UID");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_key_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling key xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "KEY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_nickname_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling nickname xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "NICKNAME");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_class_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling class xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CLASS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_categories_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling categories xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CATEGORIES");
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static osync_bool conv_xml_to_vcard(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error, int target)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+
+ xmlChar *str = osxml_write_to_string((xmlDoc *)input);
+ osync_trace(TRACE_SENSITIVE, "Input XML is:\n%s", str);
+ xmlFree(str);
+
+ //Get the root node of the input document
+ xmlNode *root = xmlDocGetRootElement((xmlDoc *)input);
+ if (!root) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get xml root element");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+ }
+
+ if (xmlStrcmp(root->name, (const xmlChar *)"contact")) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Wrong xml root element");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+ }
+
+ //Make the new vcard
+ VFormat *vcard = vformat_new();
+
+ osync_trace(TRACE_INTERNAL, "parsing cml attributes");
+ const char *std_encoding = NULL;
+ if (target == VFORMAT_CARD_21)
+ std_encoding = "QUOTED-PRINTABLE";
+ else
+ std_encoding = "B";
+
+ OSyncHookTables *hooks = (OSyncHookTables *)user_data;
+ /* vcard21 / vcard30 */
+ if (target == VFORMAT_CARD_21) {
+ g_hash_table_insert(hooks->attributes, "Photo", handle_xml_photo_base64_attribute);
+ g_hash_table_insert(hooks->parameters, "Type", handle_xml_type_no_iana_parameter);
+ g_hash_table_insert(hooks->parameters, "Encoding", handle_xml_encoding_21_parameter);
+ } else {
+ g_hash_table_insert(hooks->attributes, "Photo", handle_xml_photo_attribute);
+ g_hash_table_insert(hooks->parameters, "Type", handle_xml_type_parameter);
+ g_hash_table_insert(hooks->parameters, "Encoding", handle_xml_encoding_30_parameter);
+ }
+
+ if (root)
+ root = root->children;
+ while (root) {
+ xml_vcard_handle_attribute(hooks, vcard, root, std_encoding);
+ root = root->next;
+ }
+
+ *free_input = TRUE;
+ *output = vformat_to_string(vcard, target);
+ osync_trace(TRACE_SENSITIVE, "vcard output is: \n%s", *output);
+ *outpsize = strlen(*output);
+ osync_trace(TRACE_EXIT, "%s", __func__);
+
+ return TRUE;
+}
+
+static osync_bool conv_xml_to_vcard30(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcard(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_CARD_30);
+}
+
+static osync_bool conv_xml_to_vcard21(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ return conv_xml_to_vcard(user_data, input, inpsize, output, outpsize, free_input, error, VFORMAT_CARD_21);
+}
+
+static OSyncConvCmpResult compare_contact(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange);
+
+ OSyncXMLScore score[] =
+ {
+ //{30, "/contact/FullName"},
+ {100, "/contact/Name"},
+ //{20, "/contact/Telephone"},
+ //{20, "/contact/Address"},
+ {0, "/contact/UnknownNode"},
+ {0, "/contact/*/Slot"},
+ {0, "/contact/*/Type"},
+ {0, "/contact/WantsHtml"},
+ {0, "/contact/Class"},
+ {0, "/contact/FileAs"},
+ {0, "/contact/IM-ICQ"},
+ {0, "/contact/AddressLabel"},
+ {0, "/contact/Uid"},
+ {0, "/contact/Revision"},
+ {0, NULL}
+ };
+
+ OSyncConvCmpResult ret = osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 0, 99);
+
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
+ return ret;
+}
+
+static char *print_contact(OSyncChange *change)
+{
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ return (char *)osxml_write_to_string(doc);
+}
+
+static void destroy_xml(char *data, size_t size)
+{
+ xmlFreeDoc((xmlDoc *)data);
+}
+
+static void *init_vcard_to_xml(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+ GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert(table, "FN", handle_formatted_name_attribute);
+ g_hash_table_insert(table, "N", handle_name_attribute);
+ g_hash_table_insert(table, "AGENT", handle_agent_attribute);
+ g_hash_table_insert(table, "PHOTO", handle_photo_attribute);
+ g_hash_table_insert(table, "BDAY", handle_birthday_attribute);
+ g_hash_table_insert(table, "ADR", handle_address_attribute);
+ g_hash_table_insert(table, "LABEL", handle_label_attribute);
+ g_hash_table_insert(table, "TEL", handle_telephone_attribute);
+ g_hash_table_insert(table, "EMAIL", handle_email_attribute);
+ g_hash_table_insert(table, "MAILER", handle_mailer_attribute);
+ g_hash_table_insert(table, "TZ", handle_timezone_attribute);
+ g_hash_table_insert(table, "GEO", handle_location_attribute);
+ g_hash_table_insert(table, "TITLE", handle_title_attribute);
+ g_hash_table_insert(table, "ROLE", handle_role_attribute);
+ g_hash_table_insert(table, "LOGO", handle_logo_attribute);
+ g_hash_table_insert(table, "ORG", handle_organization_attribute);
+ g_hash_table_insert(table, "NOTE", handle_note_attribute);
+ g_hash_table_insert(table, "REV", handle_revision_attribute);
+ g_hash_table_insert(table, "SOUND", handle_sound_attribute);
+ g_hash_table_insert(table, "URL", handle_url_attribute);
+ g_hash_table_insert(table, "UID", handle_uid_attribute);
+ g_hash_table_insert(table, "KEY", handle_key_attribute);
+ g_hash_table_insert(table, "NICKNAME", handle_nickname_attribute);
+ g_hash_table_insert(table, "CLASS", handle_class_attribute);
+ g_hash_table_insert(table, "CATEGORIES", handle_categories_attribute);
+
+ g_hash_table_insert(table, "VERSION", HANDLE_IGNORE);
+ g_hash_table_insert(table, "BEGIN", HANDLE_IGNORE);
+ g_hash_table_insert(table, "END", HANDLE_IGNORE);
+
+ g_hash_table_insert(table, "ENCODING", handle_encoding_parameter);
+ g_hash_table_insert(table, "CHARSET", HANDLE_IGNORE);
+
+ g_hash_table_insert(table, "TYPE", handle_type_parameter);
+ g_hash_table_insert(table, "VALUE", handle_value_parameter);
+
+ g_hash_table_insert(table, "X-IRMC-LUID", HANDLE_IGNORE);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, table);
+ return (void *)table;
+}
+
+static void fin_vcard_to_xml(void *data)
+{
+ g_hash_table_destroy((GHashTable *)data);
+}
+
+static void *init_xml_to_vcard(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+
+ OSyncHookTables *hooks = g_malloc0(sizeof(OSyncHookTables));
+
+ hooks->attributes = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->parameters = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert(hooks->attributes, "FormattedName", handle_xml_formatted_name_attribute);
+ g_hash_table_insert(hooks->attributes, "Name", handle_xml_name_attribute);
+ g_hash_table_insert(hooks->attributes, "Agent", handle_xml_agent_attribute);
+ g_hash_table_insert(hooks->attributes, "Birthday", handle_xml_birthday_attribute);
+ g_hash_table_insert(hooks->attributes, "Address", handle_xml_address_attribute);
+ g_hash_table_insert(hooks->attributes, "AddressLabel", handle_xml_label_attribute);
+ g_hash_table_insert(hooks->attributes, "Telephone", handle_xml_telephone_attribute);
+ g_hash_table_insert(hooks->attributes, "EMail", handle_xml_email_attribute);
+ g_hash_table_insert(hooks->attributes, "Mailer", handle_xml_mailer_attribute);
+ g_hash_table_insert(hooks->attributes, "Timezone", handle_xml_timezone_attribute);
+ g_hash_table_insert(hooks->attributes, "Location", handle_xml_location_attribute);
+ g_hash_table_insert(hooks->attributes, "Title", handle_xml_title_attribute);
+ g_hash_table_insert(hooks->attributes, "Role", handle_xml_role_attribute);
+ g_hash_table_insert(hooks->attributes, "Logo", handle_xml_logo_attribute);
+ g_hash_table_insert(hooks->attributes, "Organization", handle_xml_organization_attribute);
+ g_hash_table_insert(hooks->attributes, "Note", handle_xml_note_attribute);
+ g_hash_table_insert(hooks->attributes, "Revision", handle_xml_revision_attribute);
+ g_hash_table_insert(hooks->attributes, "Sound", handle_xml_sound_attribute);
+ g_hash_table_insert(hooks->attributes, "Url", handle_xml_url_attribute);
+ g_hash_table_insert(hooks->attributes, "Uid", handle_xml_uid_attribute);
+ g_hash_table_insert(hooks->attributes, "Key", handle_xml_key_attribute);
+ g_hash_table_insert(hooks->attributes, "Nickname", handle_xml_nickname_attribute);
+ g_hash_table_insert(hooks->attributes, "Class", handle_xml_class_attribute);
+ g_hash_table_insert(hooks->attributes, "Categories", handle_xml_categories_attribute);
+ g_hash_table_insert(hooks->attributes, "UnknownNode", xml_handle_unknown_attribute);
+
+ /* disable general Type handling .... because Photo type needs to be handled
+ seperatly
+ g_hash_table_insert(hooks->parameters, "Type", handle_xml_type_parameter);*/
+ g_hash_table_insert(hooks->parameters, "Value", handle_xml_value_parameter);
+ g_hash_table_insert(hooks->parameters, "Category", handle_xml_category_parameter);
+ g_hash_table_insert(hooks->parameters, "Unit", handle_xml_unit_parameter);
+
+ g_hash_table_insert(hooks->parameters, "UnknownParam", xml_handle_unknown_parameter);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks);
+ return (void *)hooks;
+}
+
+static void fin_xml_to_vcard(void *data)
+{
+ OSyncHookTables *hooks = (OSyncHookTables *)data;
+ g_hash_table_destroy(hooks->attributes);
+ g_hash_table_destroy(hooks->parameters);
+ g_free(hooks);
+}
+
+static time_t get_revision(OSyncChange *change, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error);
+
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ xmlXPathObject *xobj = osxml_get_nodeset(doc, "/contact/Revision");
+
+ xmlNodeSet *nodes = xobj->nodesetval;
+
+ int size = (nodes) ? nodes->nodeNr : 0;
+ if (size != 1) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find the revision");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return -1;
+ }
+
+ char *revision = (char*)osxml_find_node(nodes->nodeTab[0], "Content");
+
+ osync_trace(TRACE_INTERNAL, "About to convert string %s", revision);
+ time_t time = vformat_time_to_unix(revision);
+ g_free(revision);
+ xmlXPathFreeObject(xobj);
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, time);
+ return time;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "contact");
+ osync_env_register_objformat(env, "contact", "xml-contact");
+ osync_env_format_set_compare_func(env, "xml-contact", compare_contact);
+ osync_env_format_set_destroy_func(env, "xml-contact", destroy_xml);
+ osync_env_format_set_print_func(env, "xml-contact", print_contact);
+ osync_env_format_set_copy_func(env, "xml-contact", osxml_copy);
+ osync_env_format_set_revision_func(env, "xml-contact", get_revision);
+ osync_env_format_set_marshall_func(env, "xml-contact", osxml_marshall);
+ osync_env_format_set_demarshall_func(env, "xml-contact", osxml_demarshall);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vcard21", "xml-contact", conv_vcard_to_xml);
+ osync_env_converter_set_init(env, "vcard21", "xml-contact", init_vcard_to_xml, fin_vcard_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-contact", "vcard21", conv_xml_to_vcard21);
+ osync_env_converter_set_init(env, "xml-contact", "vcard21", init_xml_to_vcard, fin_xml_to_vcard);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vcard30", "xml-contact", conv_vcard_to_xml);
+ osync_env_converter_set_init(env, "vcard30", "xml-contact", init_vcard_to_xml, fin_vcard_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-contact", "vcard30", conv_xml_to_vcard30);
+ osync_env_converter_set_init(env, "xml-contact", "vcard30", init_xml_to_vcard, fin_xml_to_vcard);
+}
+
+/**
+ * rewrite_mime_type: rewrites a IANA or not IANA mime type
+ * Internet Assigned Numbers Authority mime types are only supported in
+ * VCARD:3.0.
+ * VCARD:2.1 only supports the following mime types: GIF, CGM, WMF, BMP,
+ * MET, PMB, DIB, PICT, TIFF, PS, PDF, JPEG, MPEG, MPEG2, AVI, QTIME, WAVE,
+ * PCM, AIFF
+ *
+ * @param source_format: could be a IANA ("image/jpeg") or not IANA ("JPEG")
+ * @param use_iana: 0 rewrite to not IANA, 1 rewrite to IANA
+ * @returns IANA / not IANA mime type or NULL if not found
+ **/
+static const char * rewrite_mime_type(const char * source_format, int use_iana)
+{
+ osync_trace(TRACE_INTERNAL, "%s: source_format = %s", __func__, source_format);
+ char * iana_format = NULL;
+ char * not_iana_format = NULL;
+
+ if ( (!g_ascii_strcasecmp (source_format, "JPEG")) ||
+ (!g_ascii_strcasecmp (source_format, "image/jpeg")) ) {
+ iana_format = "image/jpeg";
+ not_iana_format = "JPEG";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "TIFF")) ||
+ (!g_ascii_strcasecmp (source_format, "image/tiff")) ) {
+ iana_format = "image/tiff";
+ not_iana_format = "TIFF";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "GIF")) ||
+ (!g_ascii_strcasecmp (source_format, "image/gif")) ) {
+ iana_format = "image/gif";
+ not_iana_format = "GIF";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "CGM")) ||
+ (!g_ascii_strcasecmp (source_format, "image/cgm")) ) {
+ iana_format = "image/cgm";
+ not_iana_format = "CGM";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "BMP")) ||
+ (!g_ascii_strcasecmp (source_format, "image/x-ms-bmp")) ) {
+ iana_format = "image/x-ms-bmp";
+ not_iana_format = "BMP";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "PS")) ||
+ (!g_ascii_strcasecmp (source_format, "application/postscript")) ) {
+ iana_format = "application/postscript";
+ not_iana_format = "PS";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "PDF")) ||
+ (!g_ascii_strcasecmp (source_format, "application/pdf")) ) {
+ iana_format = "application/pdf";
+ not_iana_format = "PDF";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "MPEG")) ||
+ (!g_ascii_strcasecmp (source_format, "video/mpeg")) ) {
+ iana_format = "video/mpeg";
+ not_iana_format = "MPEG";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "MPEG2")) ||
+ (!g_ascii_strcasecmp (source_format, "video/mpeg")) ) {
+ iana_format = "video/mpeg";
+ not_iana_format = "MPEG2";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "AVI")) ||
+ (!g_ascii_strcasecmp (source_format, "video/x-msvideo")) ) {
+ iana_format = "video/x-msvideo";
+ not_iana_format = "AVI";
+ goto NORMAL_EXIT;
+ }
+ if ( (!g_ascii_strcasecmp (source_format, "QTIME")) ||
+ (!g_ascii_strcasecmp (source_format, "video/quicktime")) ) {
+ iana_format = "video/quicktime";
+ not_iana_format = "QTIME";
+ goto NORMAL_EXIT;
+ }
+
+ /*FIXME:vcard 2.1 only no iana typ found*/
+ if ( !g_ascii_strcasecmp (source_format, "WMF") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "MET") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "PMB") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "DIB") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "PICT") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "WAVE") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "PCM") ) {
+ goto NO_IANA;
+ }
+ if ( !g_ascii_strcasecmp (source_format, "AIFF") ) {
+ goto NO_IANA;
+ }
+
+/*NO_MATCH:*/
+ osync_trace(TRACE_INTERNAL, "%s:[NO_MATCH] output = NULL ", __func__);
+ return(NULL);
+
+NO_IANA:
+ osync_trace(TRACE_INTERNAL, "%s:[NO_IANA] output = %s ", __func__, source_format);
+ if (!use_iana)
+ return(source_format);
+ return(NULL);
+
+NORMAL_EXIT:
+ if (use_iana)
+ {
+ osync_trace(TRACE_INTERNAL, "%s:[NORMAL_EXIT] output = %s ", __func__, iana_format);
+ return (iana_format);
+ }
+ osync_trace(TRACE_INTERNAL, "%s:[NORMAL_EXIT] output = %s ", __func__, not_iana_format);
+ return(not_iana_format);
+}
+
+/**
+ * _helper_is_base64 is helper function to check i a string is "b" or "base64"
+ * @param check_string string that should be compared with "b" or "base64"
+ * @return 0 if check_string is not base64 and 1 if it is
+ */
+static int _helper_is_base64(const char *check_string)
+{
+ if(!g_ascii_strcasecmp ((char *) check_string, "BASE64") ||
+ !g_ascii_strcasecmp ((char *) check_string, "b") )
+ return (1);
+ return (0);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.h b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.h
new file mode 100644
index 00000000..e84bfa3d
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vcard.h
@@ -0,0 +1,11 @@
+#ifndef _XMLVCARD_H_
+#define _XMLVCARD_H_
+
+typedef struct OSyncHookTables {
+ GHashTable *attributes;
+ GHashTable *parameters;
+} OSyncHookTables;
+
+#define HANDLE_IGNORE (void *)1
+
+#endif //_XMLVCARD_H_
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.c
new file mode 100644
index 00000000..ce8580c4
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.c
@@ -0,0 +1,672 @@
+/*
+ * xml-vnote - A plugin for parsing vnote objects for the opensync framework
+ * Copyright (C) 2004-2005 Armin Bauer <[email protected]>
+ *
+ * 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 "xml-support.h"
+#include "vformat.h"
+#include "xml-vnote.h"
+#include <glib.h>
+
+static void handle_unknown_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown parameter %s", vformat_attribute_param_get_name(param));
+ xmlNode *property = xmlNewTextChild(current, NULL, (xmlChar*)"UnknownParam",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+ osxml_node_add(property, "ParamName", vformat_attribute_param_get_name(param));
+}
+
+static xmlNode *handle_created_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ char *timestamp;
+ const char *tmp;
+
+ osync_trace(TRACE_INTERNAL, "Handling created attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"DateCreated", NULL);
+ tmp = vformat_attribute_get_nth_value(attr, 0);
+ timestamp = osync_time_timestamp(tmp);
+ osxml_node_add(current, "Content", timestamp);
+ g_free(timestamp);
+ return current;
+}
+
+static xmlNode *handle_last_modified_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling last_modified attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"LastModified", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_summary_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling summary attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Summary", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_categories_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Categories attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Categories", NULL);
+
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Category", retstr->str);
+ }
+
+ return current;
+}
+
+static xmlNode *handle_body_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling body attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Body", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static xmlNode *handle_class_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling Class attribute");
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"Class", NULL);
+ osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0));
+ return current;
+}
+
+static void handle_type_parameter(xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_INTERNAL, "Handling type parameter %s", vformat_attribute_param_get_name(param));
+ xmlNewTextChild(current, NULL, (xmlChar*)"Type",
+ (xmlChar*)vformat_attribute_param_get_nth_value(param, 0));
+}
+
+static xmlNode *handle_unknown_attribute(xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown attribute %s", vformat_attribute_get_name(attr));
+ xmlNode *current = xmlNewTextChild(root, NULL, (xmlChar*)"UnknownNode", NULL);
+ osxml_node_add(current, "NodeName", vformat_attribute_get_name(attr));
+ GList *values = vformat_attribute_get_values_decoded(attr);
+ for (; values; values = values->next) {
+ GString *retstr = (GString *)values->data;
+ g_assert(retstr);
+ osxml_node_add(current, "Content", retstr->str);
+ }
+ return current;
+}
+
+static void vnote_handle_parameter(GHashTable *hooks, xmlNode *current, VFormatParam *param)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, hooks, current, param);
+
+ //Find the handler for this parameter
+ void (* param_handler)(xmlNode *, VFormatParam *);
+ char *paramname = g_strdup_printf("%s=%s", vformat_attribute_param_get_name(param), vformat_attribute_param_get_nth_value(param, 0));
+ param_handler = g_hash_table_lookup(hooks, paramname);
+ g_free(paramname);
+ if (!param_handler)
+ param_handler = g_hash_table_lookup(hooks, vformat_attribute_param_get_name(param));
+
+ if (param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (param_handler)
+ param_handler(current, param);
+ else
+ handle_unknown_parameter(current, param);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static void vnote_handle_attribute(GHashTable *hooks, xmlNode *root, VFormatAttribute *attr)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, root, attr, attr ? vformat_attribute_get_name(attr) : "None");
+ xmlNode *current = NULL;
+
+ //Dont add empty stuff
+ GList *v;
+ for (v = vformat_attribute_get_values(attr); v; v = v->next) {
+ char *value = v->data;
+ if (strlen(value) != 0)
+ goto has_value;
+ }
+ osync_trace(TRACE_EXIT, "%s: No values", __func__);
+ return;
+
+has_value:;
+
+ //We need to find the handler for this attribute
+ xmlNode *(* attr_handler)(xmlNode *, VFormatAttribute *) = g_hash_table_lookup(hooks, vformat_attribute_get_name(attr));
+ osync_trace(TRACE_INTERNAL, "Hook is: %p", attr_handler);
+ if (attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (attr_handler)
+ current = attr_handler(root, attr);
+ else
+ current = handle_unknown_attribute(root, attr);
+
+ //Handle all parameters of this attribute
+ GList *params = vformat_attribute_get_params(attr);
+ GList *p = NULL;
+ for (p = params; p; p = p->next) {
+ VFormatParam *param = p->data;
+ vnote_handle_parameter(hooks, current, param);
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static osync_bool conv_vnote_to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, conv_data, input, inpsize, output, outpsize, free_input, error);
+
+ GHashTable *hooks = (GHashTable *)conv_data;
+
+ osync_trace(TRACE_SENSITIVE, "Input vnote is:\n%s", input);
+
+ /* The input is not null-terminated, but vformat_new_from_string() expects a null-terminated string */
+ char *input_str = g_malloc(inpsize + 1);
+ memcpy(input_str, input, inpsize);
+ input_str[inpsize] = '\0';
+
+ //Parse the vnote
+ VFormat *vnote = vformat_new_from_string(input_str);
+
+ g_free(input_str);
+
+ osync_trace(TRACE_INTERNAL, "Creating xml doc");
+
+ //Create a new xml document
+ xmlDoc *doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlNode *root = osxml_node_add_root(doc, "Note");
+
+ osync_trace(TRACE_INTERNAL, "parsing attributes");
+
+ //For every attribute we have call the handling hook
+ GList *attributes = vformat_get_attributes(vnote);
+ GList *a = NULL;
+ for (a = attributes; a; a = a->next) {
+ VFormatAttribute *attr = a->data;
+ vnote_handle_attribute(hooks, root, attr);
+ }
+
+ xmlChar *str = osxml_write_to_string(doc);
+ osync_trace(TRACE_SENSITIVE, "Output XML is:\n%s", str);
+ xmlFree(str);
+
+ *free_input = TRUE;
+ *output = (char *)doc;
+ *outpsize = sizeof(doc);
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool conv_memo_to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, conv_data, input, inpsize, output, outpsize, free_input, error);
+
+ osync_trace(TRACE_SENSITIVE, "Input memo is:\n%s", input);
+
+ xmlNode *current = NULL;
+
+ //Create a new xml document
+ xmlDoc *doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlNode *root = osxml_node_add_root(doc, "Note");
+
+ // Summary & Body
+ if (input) {
+ gchar **splitMemo = g_strsplit(input, "\n", 2);
+
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"Summary", NULL);
+ xmlNewTextChild(current, NULL, (xmlChar*)"Content", (xmlChar*)splitMemo[0]);
+
+ current = xmlNewTextChild(root, NULL, (xmlChar*)"Body", NULL);
+ xmlNewTextChild(current, NULL, (xmlChar*)"Content", (xmlChar*)splitMemo[1]);
+
+ g_strfreev(splitMemo);
+ }
+
+ xmlChar *str = osxml_write_to_string(doc);
+ osync_trace(TRACE_SENSITIVE, "Output XML is:\n%s", str);
+ xmlFree(str);
+
+ *free_input = TRUE;
+ *output = (char *)doc;
+ *outpsize = sizeof(doc);
+
+ osync_trace(TRACE_EXIT, "%s: TRUE", __func__);
+ return TRUE;
+}
+
+static osync_bool needs_encoding(const unsigned char *tmp, const char *encoding)
+{
+ int i = 0;
+ if (!strcmp(encoding, "QUOTED-PRINTABLE")) {
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127 || tmp[i] == 10 || tmp[i] == 13)
+ return TRUE;
+ i++;
+ }
+ } else {
+ return !g_utf8_validate((gchar*)tmp, -1, NULL);
+ }
+ return FALSE;
+}
+
+static osync_bool needs_charset(const unsigned char *tmp)
+{
+ int i = 0;
+ while (tmp[i] != 0) {
+ if (tmp[i] > 127)
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+static void add_value(VFormatAttribute *attr, xmlNode *parent, const char *name, const char *encoding)
+{
+ char *tmp = osxml_find_node(parent, name);
+ if (!tmp)
+ return;
+
+ if (needs_charset((unsigned char*)tmp))
+ if (!vformat_attribute_has_param (attr, "CHARSET"))
+ vformat_attribute_add_param_with_value(attr, "CHARSET", "UTF-8");
+
+ if (needs_encoding((unsigned char*)tmp, encoding)) {
+ if (!vformat_attribute_has_param (attr, "ENCODING"))
+ vformat_attribute_add_param_with_value(attr, "ENCODING", encoding);
+ vformat_attribute_add_value_decoded(attr, tmp, strlen(tmp) + 1);
+ } else
+ vformat_attribute_add_value(attr, tmp);
+ g_free(tmp);
+}
+
+static void handle_xml_type_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling type xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, "TYPE", content);
+ g_free(content);
+}
+
+static void handle_xml_category_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling category xml parameter");
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_value(attr, content);
+ g_free(content);
+}
+
+static void xml_handle_unknown_parameter(VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml parameter %s", current->name);
+ char *content = (char*)xmlNodeGetContent(current);
+ vformat_attribute_add_param_with_value(attr, (char*)current->name, content);
+ g_free(content);
+}
+
+static VFormatAttribute *handle_xml_categories_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling categories xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CATEGORIES");
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_class_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling class xml attribute");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "CLASS");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_summary_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "SUMMARY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_body_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "BODY");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_created_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "DCREATED");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static VFormatAttribute *handle_xml_last_modified_attribute(VFormat *vcard, xmlNode *root, const char *encoding)
+{
+ VFormatAttribute *attr = vformat_attribute_new(NULL, "LAST-MODIFIED");
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vcard, attr);
+ return attr;
+}
+
+static void xml_vnote_handle_parameter(OSyncHookTables *hooks, VFormatAttribute *attr, xmlNode *current)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, attr, current, current ? (char *)current->name : "None");
+
+ //Find the handler for this parameter
+ void (* xml_param_handler)(VFormatAttribute *attr, xmlNode *);
+ char *content = (char*)xmlNodeGetContent(current);
+ char *paramname = g_strdup_printf("%s=%s", current->name, content);
+ g_free(content);
+ xml_param_handler = g_hash_table_lookup(hooks->parameters, paramname);
+ g_free(paramname);
+ if (!xml_param_handler)
+ xml_param_handler = g_hash_table_lookup(hooks->parameters, current->name);
+
+ if (xml_param_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+
+ if (xml_param_handler)
+ xml_param_handler(attr, current);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static VFormatAttribute *xml_handle_unknown_attribute(VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_INTERNAL, "Handling unknown xml attribute %s", root->name);
+ char *name = osxml_find_node(root, "NodeName");
+ VFormatAttribute *attr = vformat_attribute_new(NULL, name);
+ add_value(attr, root, "Content", encoding);
+ vformat_add_attribute(vnote, attr);
+ return attr;
+}
+
+static void xml_vnote_handle_attribute(OSyncHookTables *hooks, VFormat *vnote, xmlNode *root, const char *encoding)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, vnote, root, root ? (char *)root->name : "None");
+ VFormatAttribute *attr = NULL;
+
+ //We need to find the handler for this attribute
+ VFormatAttribute *(* xml_attr_handler)(VFormat *vnote, xmlNode *root, const char *) = g_hash_table_lookup(hooks->attributes, root->name);
+ osync_trace(TRACE_INTERNAL, "xml hook is: %p", xml_attr_handler);
+ if (xml_attr_handler == HANDLE_IGNORE) {
+ osync_trace(TRACE_EXIT, "%s: Ignored", __func__);
+ return;
+ }
+ if (xml_attr_handler)
+ attr = xml_attr_handler(vnote, root, encoding);
+ else {
+ osync_trace(TRACE_EXIT, "%s: Ignored2", __func__);
+ return;
+ }
+
+ //Handle all parameters of this attribute
+ xmlNode *child = root->xmlChildrenNode;
+ while (child) {
+ xml_vnote_handle_parameter(hooks, attr, child);
+ child = child->next;
+ }
+ osync_trace(TRACE_EXIT, "%s", __func__);
+}
+
+static osync_bool conv_xml_to_vnote(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+
+ xmlChar *str = osxml_write_to_string((xmlDoc *)input);
+ osync_trace(TRACE_SENSITIVE, "Input XML is:\n%s", str);
+ xmlFree(str);
+
+ //Get the root node of the input document
+ xmlNode *root = osxml_node_get_root((xmlDoc *)input, "Note", error);
+ if (!root) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get root element of xml-note");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+ }
+
+ //Make the new vnote
+ VFormat *vnote = vformat_new();
+
+ osync_trace(TRACE_INTERNAL, "parsing xml attributes");
+ while (root) {
+ xml_vnote_handle_attribute((OSyncHookTables *)user_data, vnote, root, "QUOTED-PRINTABLE");
+ root = root->next;
+ }
+
+ *free_input = TRUE;
+ *output = vformat_to_string(vnote, VFORMAT_NOTE);
+ osync_trace(TRACE_SENSITIVE, "vnote output is: \n%s", *output);
+ *outpsize = strlen(*output);
+ osync_trace(TRACE_EXIT, "%s", __func__);
+
+ return TRUE;
+}
+
+static osync_bool conv_xml_to_memo(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error);
+
+ xmlChar *str = osxml_write_to_string((xmlDoc *)input);
+ osync_trace(TRACE_SENSITIVE, "Input XML is:\n%s", str);
+ xmlFree(str);
+
+ //Get the root node of the input document
+ xmlNode *root = xmlDocGetRootElement((xmlDoc *)input);
+
+ if (!root) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get xml root element");
+ goto error;
+ }
+
+ if (xmlStrcmp(root->name, (const xmlChar *)"Note")) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Wrong xml root element");
+ goto error;
+ }
+
+ GString *memo = g_string_new("");
+
+ // Summary
+ xmlNode *cur = osxml_get_node(root, "Summary");
+
+ if (cur)
+ memo = g_string_append(memo, osxml_find_node(cur, "Content"));
+
+ // Body
+ cur = osxml_get_node(root, "Body");
+ if (cur) {
+ if (memo->len > 0)
+ memo = g_string_append(memo, "\n");
+
+ memo = g_string_append(memo, osxml_find_node(cur, "Content"));
+ }
+
+ *free_input = TRUE;
+ *output = g_string_free(memo, FALSE);
+ osync_trace(TRACE_SENSITIVE, "memo output is: \n%s", *output);
+ *outpsize = strlen(*output);
+
+ osync_trace(TRACE_EXIT, "%s", __func__);
+ return TRUE;
+
+error:
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return FALSE;
+}
+
+static OSyncConvCmpResult compare_notes(OSyncChange *leftchange, OSyncChange *rightchange)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange);
+
+ OSyncXMLScore score[] =
+ {
+ {100, "/Note/Summary"},
+ {100, "/Note/Body"},
+ {0, "/Note/*/Type"},
+ {0, "/Note/Uid"},
+ {0, "/Note/LastModified"},
+ {0, "/Note/DateCreated"},
+ {0, NULL}
+ };
+
+ OSyncConvCmpResult ret = osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 0, 199);
+
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, ret);
+ return ret;
+}
+
+static char *print_note(OSyncChange *change)
+{
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ return (char *)osxml_write_to_string(doc);
+}
+
+static void destroy_xml(char *data, size_t size)
+{
+ xmlFreeDoc((xmlDoc *)data);
+}
+
+static void *init_vnote_to_xml(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+ GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert(table, "X-IRMC-LUID", HANDLE_IGNORE);
+ g_hash_table_insert(table, "DCREATED", handle_created_attribute);
+ g_hash_table_insert(table, "LAST-MODIFIED", handle_last_modified_attribute);
+ g_hash_table_insert(table, "SUMMARY", handle_summary_attribute);
+ g_hash_table_insert(table, "BODY", handle_body_attribute);
+ g_hash_table_insert(table, "CLASS", handle_class_attribute);
+ g_hash_table_insert(table, "CATEGORIES", handle_categories_attribute);
+
+ g_hash_table_insert(table, "VERSION", HANDLE_IGNORE);
+ g_hash_table_insert(table, "BEGIN", HANDLE_IGNORE);
+ g_hash_table_insert(table, "END", HANDLE_IGNORE);
+
+ g_hash_table_insert(table, "ENCODING", HANDLE_IGNORE);
+ g_hash_table_insert(table, "CHARSET", HANDLE_IGNORE);
+
+ g_hash_table_insert(table, "TYPE", handle_type_parameter);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, table);
+ return (void *)table;
+}
+
+static void fin_vnote_to_xml(void *data)
+{
+ g_hash_table_destroy((GHashTable *)data);
+}
+
+static void *init_xml_to_vnote(void)
+{
+ osync_trace(TRACE_ENTRY, "%s", __func__);
+
+ OSyncHookTables *hooks = g_malloc0(sizeof(OSyncHookTables));
+
+ hooks->attributes = g_hash_table_new(g_str_hash, g_str_equal);
+ hooks->parameters = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert(hooks->attributes, "Summary", handle_xml_summary_attribute);
+ g_hash_table_insert(hooks->attributes, "Body", handle_xml_body_attribute);
+ g_hash_table_insert(hooks->attributes, "Class", handle_xml_class_attribute);
+ g_hash_table_insert(hooks->attributes, "Categories", handle_xml_categories_attribute);
+ g_hash_table_insert(hooks->attributes, "UnknownNode", xml_handle_unknown_attribute);
+ g_hash_table_insert(hooks->attributes, "DateCreated", handle_xml_created_attribute);
+ g_hash_table_insert(hooks->attributes, "LastModified", handle_xml_last_modified_attribute);
+
+ g_hash_table_insert(hooks->parameters, "Type", handle_xml_type_parameter);
+ g_hash_table_insert(hooks->parameters, "Category", handle_xml_category_parameter);
+
+ g_hash_table_insert(hooks->parameters, "UnknownParameter", xml_handle_unknown_parameter);
+
+ osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks);
+ return (void *)hooks;
+}
+
+static void fin_xml_to_vnote(void *data)
+{
+ OSyncHookTables *hooks = (OSyncHookTables *)data;
+ g_hash_table_destroy(hooks->attributes);
+ g_hash_table_destroy(hooks->parameters);
+ g_free(hooks);
+}
+
+static time_t get_revision(OSyncChange *change, OSyncError **error)
+{
+ osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error);
+
+ xmlDoc *doc = (xmlDoc *)osync_change_get_data(change);
+
+ xmlXPathObject *xobj = osxml_get_nodeset(doc, "/Note/LastModified");
+
+ xmlNodeSet *nodes = xobj->nodesetval;
+
+ int size = (nodes) ? nodes->nodeNr : 0;
+ if (size != 1) {
+ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find the revision");
+ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
+ return -1;
+ }
+
+ char *revision = (char*)osxml_find_node(nodes->nodeTab[0], "Content");
+
+ osync_trace(TRACE_INTERNAL, "About to convert string %s", revision);
+ time_t time = vformat_time_to_unix(revision);
+ g_free(revision);
+ xmlXPathFreeObject(xobj);
+ osync_trace(TRACE_EXIT, "%s: %i", __func__, time);
+ return time;
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "note");
+ osync_env_register_objformat(env, "note", "xml-note");
+ osync_env_format_set_compare_func(env, "xml-note", compare_notes);
+ osync_env_format_set_destroy_func(env, "xml-note", destroy_xml);
+ osync_env_format_set_print_func(env, "xml-note", print_note);
+ osync_env_format_set_copy_func(env, "xml-note", osxml_copy);
+ osync_env_format_set_revision_func(env, "xml-note", get_revision);
+ osync_env_format_set_marshall_func(env, "xml-note", osxml_marshall);
+ osync_env_format_set_demarshall_func(env, "xml-note", osxml_demarshall);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "vnote11", "xml-note", conv_vnote_to_xml);
+ osync_env_converter_set_init(env, "vnote11", "xml-note", init_vnote_to_xml, fin_vnote_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-note", "vnote11", conv_xml_to_vnote);
+ osync_env_converter_set_init(env, "xml-note", "vnote11", init_xml_to_vnote, fin_xml_to_vnote);
+
+ osync_env_register_converter(env, CONVERTER_CONV, "memo", "xml-note", conv_memo_to_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-note", "memo", conv_xml_to_memo);
+}
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.h b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.h
new file mode 100644
index 00000000..1b76878c
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-vnote.h
@@ -0,0 +1,11 @@
+#ifndef _XMLVNOTE_H_
+#define _XMLVNOTE_H_
+
+typedef struct OSyncHookTables {
+ GHashTable *attributes;
+ GHashTable *parameters;
+} OSyncHookTables;
+
+#define HANDLE_IGNORE (void *)1
+
+#endif //_XMLVNOTE_H_
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xmldoc.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xmldoc.c
new file mode 100644
index 00000000..3bf998df
--- /dev/null
+++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xmldoc.c
@@ -0,0 +1,76 @@
+/*
+ * xmldoc - serialised textual versions of the XML event formats, for external plugins
+ * Copyright (C) 2006 Andrew Baumann <[email protected]>
+ *
+ * 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 "xml-support.h"
+
+static osync_bool from_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ *free_input = TRUE;
+ return osxml_marshall(input, inpsize, output, outpsize, error);
+}
+
+static osync_bool to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error)
+{
+ *free_input = TRUE;
+ return osxml_demarshall(input, inpsize, output, outpsize, error);
+}
+
+static osync_bool copy_string(const char *input, int inpsize, char **output, int *outpsize)
+{
+ *output = strdup(input);
+ *outpsize = inpsize;
+ return TRUE;
+}
+
+static void destroy(char *input, size_t inpsize)
+{
+ free(input);
+}
+
+void get_info(OSyncEnv *env)
+{
+ osync_env_register_objtype(env, "event");
+ osync_env_register_objformat(env, "event", "xml-event-doc");
+ osync_env_format_set_destroy_func(env, "xml-event-doc", destroy);
+ osync_env_format_set_copy_func(env, "xml-event-doc", copy_string);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-event", "xml-event-doc", from_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-event-doc", "xml-event", to_xml);
+
+ osync_env_register_objtype(env, "todo");
+ osync_env_register_objformat(env, "todo", "xml-todo-doc");
+ osync_env_format_set_destroy_func(env, "xml-todo-doc", destroy);
+ osync_env_format_set_copy_func(env, "xml-todo-doc", copy_string);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-todo", "xml-todo-doc", from_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-todo-doc", "xml-todo", to_xml);
+
+ osync_env_register_objtype(env, "contact");
+ osync_env_register_objformat(env, "contact", "xml-contact-doc");
+ osync_env_format_set_destroy_func(env, "xml-contact-doc", destroy);
+ osync_env_format_set_copy_func(env, "xml-contact-doc", copy_string);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-contact", "xml-contact-doc", from_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-contact-doc", "xml-contact", to_xml);
+
+ osync_env_register_objtype(env, "note");
+ osync_env_register_objformat(env, "note", "xml-note-doc");
+ osync_env_format_set_destroy_func(env, "xml-note-doc", destroy);
+ osync_env_format_set_copy_func(env, "xml-note-doc", copy_string);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-note", "xml-note-doc", from_xml);
+ osync_env_register_converter(env, CONVERTER_CONV, "xml-note-doc", "xml-note", to_xml);
+}