diff options
author | Michele Calgaro <[email protected]> | 2020-09-11 14:38:47 +0900 |
---|---|---|
committer | Michele Calgaro <[email protected]> | 2020-09-11 14:38:47 +0900 |
commit | 884c8093d63402a1ad0b502244b791e3c6782be3 (patch) | |
tree | a600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/opensync/opensync-0.22/formats | |
parent | 14e1aa2006796f147f3f4811fb908a6b01e79253 (diff) | |
download | extra-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')
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); +} |