# Generated by configure. Do not edit.
+2014-10-31 Patrick Ohly <patrick.ohly@intel.com>
+
+ * NEWS:
+ * configure.ac:
+
+ autotools, NEWS: SyncEvolution 1.5
+
+2014-10-31 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/backends/signon/signon.cpp:
+ * src/syncevo/GVariantSupport.cpp:
+
+ signon: fix HashTable2Variant() ref counting (TC-1667)
+
+2014-10-30 Patrick Ohly <patrick.ohly@intel.com>
+
+ * configure.ac:
+
+ autotools: bump libsynthesis requirement
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/syncevo/SyncContext.cpp:
+
+ sync: ignore unnecessary username property
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/logger.py:
+ * test/wrappercheck.sh:
+
+ wrappercheck: augment output of daemon with time stamps
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/wrappercheck.sh:
+
+ wrappercheck: fix repeated daemon startup
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/wrappercheck.sh:
+
+ wrappercheck: augment output
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/wrappercheck.sh:
+
+ wrappercheck: configurable sleep after daemon launch
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/dbus/server/main.cpp:
+ * src/dbus/server/server.cpp:
+ * src/dbus/server/server.h:
+
+ D-Bus server: fix unreliable shutdown handling
+
+2014-10-24 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/syncevo/GLibSupport.h:
+
+ glib: add GIOChannelCXX
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/test-dbus.py:
+
+ testing: include stack backtrace when killing stuck process
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/sys.supp:
+
+ testing: ignore some minor leaks
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateLocalWins/local-synced:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateLocalWins/modify-local:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateLocalWins/modify-remote:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateLocalWins/remote-synced:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateRemoteWins/local-synced:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateRemoteWins/modify-local:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateRemoteWins/modify-remote:
+ * test/testcases/synctests/googlecontacts/eds_contact/testUpdateRemoteWins/remote-synced:
+
+ testing: Google testcases must work with and without
+ libphonenumber support in EDS
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/synccompare.pl:
+
+ testing: ignore valid Akonadi vCard changes
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/testcases/eds_contact.vcf.filekde.tem.patch:
+
+ testing: ignore Akonadi encodig issues
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/runtests.py:
+
+ testing: ignore Akonadi
+ Client::Sync::file_event::testAddBothSides failures
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/ClientTest.cpp:
+ * test/runtests.py:
+
+ testing: ignore Memotoo eds_memo update failures
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/ClientTest.cpp:
+
+ testing: give valgrind more time in SyncTests::testTimeout()
+
+2014-10-10 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/dbus/server/pim/testpim.py:
+
+ PIM testing: allow testSync to run longer udner valgrind
+
+2014-09-25 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/syncevo/configs/scripting/00looptimeout.xml:
+ * src/syncevo/configs/scripting/client/00timeout.xml:
+
+ scripting: prevent premature loop timeouts
+
+2014-09-18 Patrick Ohly <patrick.ohly@intel.com>
+
+ * test/client-test-main.cpp:
+
+ testing: run one test per client-test instance
+
+2014-05-27 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/dbus/server/server.am:
+
+ PIM: always install examples
+
+2014-05-27 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/dbus/server/pim/examples/search.py:
+ * src/dbus/server/pim/examples/sync.py:
+
+ PIM: make examples work with recent Python GNOME
+
+2014-05-27 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/backends/signon/signonRegister.cpp:
+
+ signon: fix providersignon.so
+
+2014-10-09 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/dbus/server/pim/manager.cpp:
+
+ PIM testing: use file source similar to PBAP (part of FDO #84710)
+
+2014-10-09 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/syncevo/configs/scripting/05vcard-merge.xml:
+
+ vcard: fix caching of PBAP contacts (FDO #84710)
+
+2014-10-09 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/syncevo/configs/scripting/05vcard-merge.xml:
+
+ vcard: remove duplicate loops
+
+2014-09-22 Mateusz Polrola <mateusz.polrola@gmail.com>
+
+ * src/backends/pbap/PbapSyncSource.cpp:
+
+ PBAP: Wrong behaviour when SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME
+ is <= 0.
+
2014-09-10 Patrick Ohly <patrick.ohly@intel.com>
* NEWS:
INSTALL NEWS compile config.guess config.sub depcomp \
install-sh ltmain.sh missing mkinstalldirs
test_PROGRAMS = $(am__EXEEXT_9)
-bin_PROGRAMS = $(am__EXEEXT_4) $(am__append_84) $(am__append_88)
+bin_PROGRAMS = $(am__EXEEXT_4) $(am__append_85) $(am__append_89)
libexec_PROGRAMS = src/syncevo-local-sync$(EXEEXT) $(am__EXEEXT_5)
noinst_PROGRAMS = $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8)
EXTRA_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_79 = \
@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@ src/dbus/server/pim/org._01.pim.contacts.service.in
-@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@@ENABLE_TESTING_TRUE@am__append_80 = \
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@am__append_80 = \
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@ src/dbus/server/pim/examples/search.py \
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@ src/dbus/server/pim/examples/sync.py \
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@ $(NOP)
+
+@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@@ENABLE_TESTING_TRUE@am__append_81 = \
@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@@ENABLE_TESTING_TRUE@ src/dbus/server/pim/testpim.py \
@COND_DBUS_PIM_TRUE@@COND_DBUS_TRUE@@ENABLE_TESTING_TRUE@ $(NOP)
-@COND_DBUS_TRUE@am__append_81 = \
+@COND_DBUS_TRUE@am__append_82 = \
@COND_DBUS_TRUE@ $(src_dbus_server_service_files_in) \
@COND_DBUS_TRUE@ $(src_dbus_server_script_in) \
@COND_DBUS_TRUE@ $(src_dbus_server_desktop_in)
-@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_82 = src/gtk-ui/README \
+@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_83 = src/gtk-ui/README \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ $(src_gtk_ui_applications_in_files)
# sync-ui: default GUI, could be plain GTK or Moblin UX
# sync-ui-moblin: Moblin UX
#
# The later two are built when --enable-gui=all was used.
-@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_83 = \
+@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_84 = \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ src/gtk-ui/sync-ui \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ src/gtk-ui/sync-ui-gtk \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ src/gtk-ui/sync-ui-moblin
-@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_84 = @GUI_PROGRAMS@
-@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_85 = \
+@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_85 = @GUI_PROGRAMS@
+@COND_GTK2_TRUE@@COND_GUI_TRUE@am__append_86 = \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ src/gtk-ui/sync-moblin.desktop \
@COND_GTK2_TRUE@@COND_GUI_TRUE@ $(src_gtk_ui_applications_generated)
-@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_86 = src/gtk3-ui/README \
+@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_87 = src/gtk3-ui/README \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ $(src_gtk3_ui_applications_in_files)
# sync-ui: default GUI, could be plain GTK or Moblin UX
# sync-ui-moblin: Moblin UX
#
# The later two are built when --enable-gui=all was used.
-@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_87 = \
+@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_88 = \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ src/gtk3-ui/sync-ui \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ src/gtk3-ui/sync-ui-gtk \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ src/gtk3-ui/sync-ui-moblin
-@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_88 = @GUI_PROGRAMS@
-@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_89 = \
+@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_89 = @GUI_PROGRAMS@
+@COND_GTK2_FALSE@@COND_GUI_TRUE@am__append_90 = \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ src/gtk3-ui/sync-moblin.desktop \
@COND_GTK2_FALSE@@COND_GUI_TRUE@ $(src_gtk3_ui_applications_generated)
-@COND_DBUS_TRUE@am__append_90 = src/syncevo-http-server
+@COND_DBUS_TRUE@am__append_91 = src/syncevo-http-server
# SYNCEVOLUTION_LDADD is defined in configure script.
-@ENABLE_MODULES_FALSE@am__append_91 = @SYNCSOURCES@
@ENABLE_MODULES_FALSE@am__append_92 = @SYNCSOURCES@
+@ENABLE_MODULES_FALSE@am__append_93 = @SYNCSOURCES@
# The files which register backends have to be compiled into
# "client-test" and "syncevolution" in order to pull in the
# When using modules the registration is done inside the
# module and the register file is unnecessary. However, they
# still need to be included in "make dist".
-@ENABLE_MODULES_TRUE@am__append_93 = $(BACKEND_REGISTRIES)
-@ENABLE_MODULES_FALSE@am__append_94 = $(BACKEND_REGISTRIES)
+@ENABLE_MODULES_TRUE@am__append_94 = $(BACKEND_REGISTRIES)
+@ENABLE_MODULES_FALSE@am__append_95 = $(BACKEND_REGISTRIES)
# Force inclusion of our own icaltz-util.o into binaries even though
# we do not call the icaltzutil_fetch_timezone directly ourself.
# That way it is there if or when libical needs it.
-@ENABLE_ICALTZ_UTIL_TRUE@am__append_95 = -Wl,-usyncevo_fetch_timezone
-@COND_DBUS_TRUE@am__append_96 = $(gdbus_build_dir)/libgdbussyncevo.la
+@ENABLE_ICALTZ_UTIL_TRUE@am__append_96 = -Wl,-usyncevo_fetch_timezone
@COND_DBUS_TRUE@am__append_97 = $(gdbus_build_dir)/libgdbussyncevo.la
+@COND_DBUS_TRUE@am__append_98 = $(gdbus_build_dir)/libgdbussyncevo.la
# Do the linking here, as with all SyncEvolution executables.
# Sources are compiled in dbus/server.
# DBus Server
# syncevo-dbus-server's helper binary
-@COND_DBUS_TRUE@am__append_98 = src/syncevo-dbus-server \
+@COND_DBUS_TRUE@am__append_99 = src/syncevo-dbus-server \
@COND_DBUS_TRUE@ src/syncevo-dbus-helper
-@COND_DBUS_TRUE@am__append_99 = src/dbus/server/libsyncevodbushelper.la src/dbus/server/libsyncevodbusserver.la
-@ENABLE_EVOLUTION_COMPATIBILITY_FALSE@am__append_100 = $(LIBICAL_LIBS)
+@COND_DBUS_TRUE@am__append_100 = src/dbus/server/libsyncevodbushelper.la src/dbus/server/libsyncevodbusserver.la
+@ENABLE_EVOLUTION_COMPATIBILITY_FALSE@am__append_101 = $(LIBICAL_LIBS)
# distribute test system?
# yes: install client-test and test files in testdir
-@ENABLE_TESTING_TRUE@am__append_101 = src/client-test
+@ENABLE_TESTING_TRUE@am__append_102 = src/client-test
# The "all" dependency causes a rebuild even if the actual input files
# haven't changed. If client-test is part of the regular targets built
# by "all", then it must not depend on all!
-@ENABLE_TESTING_FALSE@am__append_102 = src/client-test
-@ENABLE_TESTING_FALSE@am__append_103 = $(CLIENT_LIB_TEST_FILES)
-@ENABLE_TESTING_FALSE@am__append_104 = all
-@COND_CORE_TRUE@am__append_105 = test/abort-redirect.cpp \
+@ENABLE_TESTING_FALSE@am__append_103 = src/client-test
+@ENABLE_TESTING_FALSE@am__append_104 = $(CLIENT_LIB_TEST_FILES)
+@ENABLE_TESTING_FALSE@am__append_105 = all
+@COND_CORE_TRUE@am__append_106 = test/abort-redirect.cpp \
@COND_CORE_TRUE@ test/ClientTest.h test/ClientTestAssert.h \
@COND_CORE_TRUE@ test/ClientTest.cpp test/client-test-main.cpp \
@COND_CORE_TRUE@ test/test.h test/test.cpp $(test_testcases) \
@COND_CORE_TRUE@ $(wildcard test/testcases/*.patch)
# generic D-Bus client/server tests
-@COND_CORE_TRUE@@COND_DBUS_TRUE@am__append_106 = test/dbus-client-server
-@COND_CORE_TRUE@@COND_DBUS_TRUE@@ENABLE_UNIT_TESTS_TRUE@am__append_107 = test/test.cpp
-@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_108 = \
+@COND_CORE_TRUE@@COND_DBUS_TRUE@am__append_107 = test/dbus-client-server
+@COND_CORE_TRUE@@COND_DBUS_TRUE@@ENABLE_UNIT_TESTS_TRUE@am__append_108 = test/test.cpp
+@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_109 = \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/__init__.py \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/test-dbus.py \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/testdbus.py \
# uses the right SyncEvolution without depending on the PATH.
# client-test should have been installed in testdir already as
# normal executable, see src.am.
-@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_109 = install-test-files
-@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_110 = uninstall-test-files
-@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_111 = \
+@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_110 = install-test-files
+@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_111 = uninstall-test-files
+@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_112 = \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/Makefile \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ $(NOP)
-@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_112 = \
+@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@am__append_113 = \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ $(test_testcases) \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/test-dbus/templates/templates/clients/phone/nokia/S40/7210c.ini \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/test-dbus/templates/templates/clients/SyncEvolution.ini \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ test/test-dbus/reports/cache/syncevolution/dummy__test-2009-11-18-12-56/status.ini \
@COND_CORE_TRUE@@ENABLE_TESTING_TRUE@ $(NOP)
-@COND_CORE_TRUE@am__append_113 = po
-@COND_CORE_TRUE@am__append_114 = README NEWS COPYING $(TEST_README_FILES) test/syncevo-http-server-logging.conf
-@COND_CORE_TRUE@am__append_115 = $(disted_docs)
+@COND_CORE_TRUE@am__append_114 = po
+@COND_CORE_TRUE@am__append_115 = README NEWS COPYING $(TEST_README_FILES) test/syncevo-http-server-logging.conf
@COND_CORE_TRUE@am__append_116 = $(disted_docs)
-@COND_CORE_TRUE@@COND_HTML_README_TRUE@am__append_117 = README.html
-# do not distribute in tarball.
+@COND_CORE_TRUE@am__append_117 = $(disted_docs)
@COND_CORE_TRUE@@COND_HTML_README_TRUE@am__append_118 = README.html
-@COND_CORE_TRUE@@COND_MAN_PAGES_TRUE@am__append_119 = syncevolution.1
+# do not distribute in tarball.
+@COND_CORE_TRUE@@COND_HTML_README_TRUE@am__append_119 = README.html
+@COND_CORE_TRUE@@COND_MAN_PAGES_TRUE@am__append_120 = syncevolution.1
# check .so (relevant for modular builds) and main syncevolution binary
# (relevant in that case and for static builds) for dependencies on
# Exclude *-[0-9].so, these are EXTRA_BACKENDS for which other rules apply.
#
# ical_strdup is an exception because it is in SyncEvolution.
-@ENABLE_EVOLUTION_COMPATIBILITY_TRUE@am__append_120 = toplevel_so_check
+@ENABLE_EVOLUTION_COMPATIBILITY_TRUE@am__append_121 = toplevel_so_check
# libneon is intentionally not linked against, to choose between
# GNUTLS and OpenSSL at runtime.
# Allow undefined references to libstdcxx. This happens when
# adding backends compiled on more recent Linux distros into
# the release archive.
-@NEON_COMPATIBILITY_TRUE@am__append_121 = -e 'symbol ne_.*syncdav.so' \
+@NEON_COMPATIBILITY_TRUE@am__append_122 = -e 'symbol ne_.*syncdav.so' \
@NEON_COMPATIBILITY_TRUE@ -e '@GLIBCXX_[^ ]* used by'
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
STRIP = @STRIP@
SYNCEVOLUTION_CFLAGS = @SYNCEVOLUTION_CFLAGS@
SYNCEVOLUTION_CXXFLAGS = @SYNCEVOLUTION_CXXFLAGS@
-SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@ $(am__append_91)
+SYNCEVOLUTION_LDADD = @SYNCEVOLUTION_LDADD@ $(am__append_92)
SYNCEVOLUTION_LIBS = @SYNCEVOLUTION_LIBS@
SYNCEVOLUTION_LOCALEDIR = @SYNCEVOLUTION_LOCALEDIR@
SYNCEVO_DBUS_SERVER_ARGS = @SYNCEVO_DBUS_SERVER_ARGS@
# clean variables
CLEANFILES = $(am__append_28) $(src_dbus_interfaces_built_sources) \
src/dbus/interfaces/.stamp $(NONE) $(am__append_59) \
- $(am__append_64) $(am__append_77) $(am__append_85) \
- $(am__append_89) src/libstdc++.a src/client-test \
+ $(am__append_64) $(am__append_77) $(am__append_86) \
+ $(am__append_90) src/libstdc++.a src/client-test \
$(CLIENT_LIB_TEST_FILES) src/syncevo-http-server \
src/syncevo-phone-config src/synclog2html \
src/ClientTest.cpp.html src/abort-redirect.log \
testparentdir = $(libdir)/syncevolution
# Must end in "/test" so that we can use nobase_testparent_DATA=test/...
testdir = $(testparentdir)/test
-test_DATA = $(am__append_111)
+test_DATA = $(am__append_112)
nobase_test_DATA =
-test_SCRIPTS = $(am__append_80) $(am__append_108)
-nobase_testparent_DATA = $(am__append_112)
+test_SCRIPTS = $(am__append_80) $(am__append_81) $(am__append_109)
+nobase_testparent_DATA = $(am__append_113)
# standard variables with standard prefixes
-dist_doc_DATA = $(am__append_116)
+dist_doc_DATA = $(am__append_117)
dist_noinst_DATA = $(am__append_8) $(am__append_13) \
src/dbus/interfaces/spec-strip-docs.xsl \
src/dbus/interfaces/spec-to-docbook.xsl \
src/dbus/interfaces/syncevo-server-full.xml \
src/dbus/interfaces/syncevo-session-full.xml \
src/dbus/interfaces/README $(am__append_55) $(am__append_66) \
- $(am__append_81) $(am__append_82) $(am__append_86) \
+ $(am__append_82) $(am__append_83) $(am__append_87) \
src/shlibs.local src/synthesis-includes/Makefile.am \
- src/synthesis-includes/Makefile.in $(am__append_93) \
- $(am__append_105) HACKING LICENSE.txt LICENSE.LGPL-21 \
+ src/synthesis-includes/Makefile.in $(am__append_94) \
+ $(am__append_106) HACKING LICENSE.txt LICENSE.LGPL-21 \
README.rst description autogen.sh Doxyfile po/LINGUAS.README
dist_pkgdata_DATA = $(am__append_69)
-doc_DATA = $(am__append_52) $(am__append_118)
+doc_DATA = $(am__append_52) $(am__append_119)
# generate syntax-highlighted version of ClientTest.cpp for HTML
# version of .log test results
dist_noinst_SCRIPTS = build/gen-git-version.sh build/source2html.py \
$(am__append_32)
libexec_SCRIPTS = $(am__append_78)
-nodist_bin_SCRIPTS = $(am__append_90) src/syncevo-phone-config
+nodist_bin_SCRIPTS = $(am__append_91) src/syncevo-phone-config
# other
# found in a parent directory. However, these files are needed
# later on during the recursive libsynthesis configure+make.
all_dist_hooks = src_dist_hook dot_dist_hook
-all_install_exec_hooks = $(am__append_109)
-all_uninstall_hooks = $(am__append_110)
+all_install_exec_hooks = $(am__append_110)
+all_uninstall_hooks = $(am__append_111)
# Check that no executable or shared object depends on symbols in
# libraries that it does not link against. Unnecessarily linking
# -Wl,--as-needed. Depends on dpkg-shlibdeps, skipped if that is
# not available.
all_local_installchecks = $(am__append_33) $(am__append_48) \
- $(am__append_120) toplevel_link_check
+ $(am__append_121) toplevel_link_check
# These dependencies are intentionally a bit too broad:
# they ensure that all files are in place to *run* client-test.
src/dbus/server/pim/test-dbus/simple-sort/config/syncevolution/pim-manager.ini \
src/dbus/server/pim/test-dbus/first-last-sort/config/syncevolution/pim-manager.ini \
$(am__append_76) src/gtk-ui/ui.xml src/gtk3-ui/ui.xml
-SUBDIRS = $(am__append_1) $(am__append_2) . $(am__append_113)
+SUBDIRS = $(am__append_1) $(am__append_2) . $(am__append_114)
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = -I m4 -I m4-repo ${ACLOCAL_FLAGS}
@COND_GIO_GDBUS_FALSE@gdbus_dir = $(top_srcdir)/src/gdbus
@COND_GIO_GDBUS_TRUE@gdbus_dir = $(top_srcdir)/src/gdbusxx
@COND_GIO_GDBUS_FALSE@gdbus_build_dir = src/gdbus
@COND_GIO_GDBUS_TRUE@gdbus_build_dir = src/gdbusxx
-disted_docs = $(am__append_114)
-distbin_docs = $(am__append_115) $(am__append_117)
-man_MANS = $(am__append_119)
+disted_docs = $(am__append_115)
+distbin_docs = $(am__append_116) $(am__append_118)
+man_MANS = $(am__append_120)
src_cppflags = -I$(top_srcdir)/src $(am__append_3) $(am__append_7) \
$(am__append_12) $(am__append_34) $(am__append_51) \
-I$(top_srcdir)/src/dbus -I$(top_srcdir)/test -I$(top_srcdir) \
@COND_GTK2_FALSE@@COND_GUI_TRUE@src_gtk3_ui_sync_ui_moblin_LDADD = $(src_gtk3_ui_sync_ui_LDADD)
@COND_GTK2_FALSE@@COND_GUI_TRUE@src_gtk3_ui_sync_ui_moblin_CFLAGS = $(src_gtk3_ui_sync_ui_CFLAGS)
@COND_GTK2_FALSE@@COND_GUI_TRUE@src_gtk3_ui_sync_ui_moblin_CPPFLAGS = $(src_gtk3_ui_sync_ui_CPPFLAGS) -DUSE_MOBLIN_UX
-SYNCEVOLUTION_DEP = $(am__append_92)
-CORE_SOURCES = $(am__append_94)
+SYNCEVOLUTION_DEP = $(am__append_93)
+CORE_SOURCES = $(am__append_95)
CORE_CXXFLAGS = $(SYNTHESIS_CFLAGS) $(CPPUNIT_CXXFLAGS)
CORE_LDADD = $(SYNCEVOLUTION_LDADD) src/syncevo/libsyncevolution.la $(GLIB_LIBS) $(GTHREAD_LIBS) $(GOBJECT_LIBS) $(LIBS)
CORE_DEP = $(SYNCEVOLUTION_DEP) src/syncevo/libsyncevolution.la $(SYNTHESIS_DEP)
CORE_LD_FLAGS = -Wl,-uSyncEvolution_Module_Version \
-Wl,--export-dynamic $(CPPUNIT_LDFLAGS) $(ADDITIONAL_LDFLAGS) \
- $(am__append_95)
+ $(am__append_96)
src_syncevolution_SOURCES = \
src/syncevolution.cpp \
$(CORE_SOURCES)
# SYNCEVOLUTION_LDADD will be replaced with libsyncebook.la/libsyncecal.la/libsyncsqlite.la
# if linking statically against them, empty otherwise;
# either way this does not lead to a dependency on those libs - done explicitly
-src_syncevolution_LDADD = $(CORE_LDADD) $(am__append_96)
+src_syncevolution_LDADD = $(CORE_LDADD) $(am__append_97)
src_syncevolution_DEPENDENCIES = $(EXTRA_LTLIBRARIES) $(CORE_DEP) \
- $(am__append_97)
+ $(am__append_98)
src_syncevolution_LDFLAGS = $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(DBUS_LIBS)
src_syncevolution_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(DBUS_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevolution_CPPFLAGS = $(src_cppflags) -I$(gdbus_dir)
test/client-test-main.cpp \
$(CORE_SOURCES)
-nodist_src_client_test_SOURCES = test/test.cpp $(am__append_103)
+nodist_src_client_test_SOURCES = test/test.cpp $(am__append_104)
# List of test files which get copied verbatim from
# $(top_srcdir)/test/testcases/ to src/testcases below. test/test.am
# To pull in those object files, LDFLAGS must contain undef statements
# for the C symbols exported by the macro.
src_client_test_libs = src/syncevo/libsyncevolution.la \
- $(am__append_99)
+ $(am__append_100)
# src/syncevo/libsyncevolution.la -> src/syncevo/.libs/libsyncevolution.a -> -Wl,-u...
src_client_test_undef = $(shell nm $(patsubst %.la,%.a,$(subst /lib,/.libs/lib,$(src_client_test_libs))) | grep funambolAutoRegisterRegistry | sed -e 's/.* /-Wl,-u/' )
src_client_test_LDFLAGS = @CPPUNIT_LDFLAGS@ $(src_client_test_undef) $(CORE_LD_FLAGS) $(QT_LDFLAGS)
src_client_test_LDADD = $(src_client_test_libs) $(CORE_LDADD) \
$(PCRECPP_LIBS) $(SYNTHESIS_ENGINE) $(QT_LIBS) \
- $(am__append_100)
+ $(am__append_101)
# The binary does not really depend on the test cases, only running it does.
# Listing the dependencies here is done to ensure that one doesn't accidentally
src_client_test_DEPENDENCIES = $(EXTRA_LTLIBRARIES) \
$(src_client_test_libs) $(CORE_DEP) $(CLIENT_LIB_TEST_FILES) \
testcase2patch src/synccompare src/synclog2html src/templates \
- $(am__append_104)
+ $(am__append_105)
@ENABLE_TESTING_TRUE@src_testcasesdir = $(testdir)/testcases
@ENABLE_TESTING_TRUE@dist_src_testcases_DATA = $(TEST_FILES_GENERATED)
@ENABLE_TESTING_TRUE@src_testcases_lcsdir = $(testdir)/testcases/lcs
@COND_CORE_TRUE@@COND_DBUS_TRUE@test_dbus_client_server_SOURCES = \
@COND_CORE_TRUE@@COND_DBUS_TRUE@ test/dbus-client-server.cpp \
-@COND_CORE_TRUE@@COND_DBUS_TRUE@ $(am__append_107)
+@COND_CORE_TRUE@@COND_DBUS_TRUE@ $(am__append_108)
@COND_CORE_TRUE@@COND_DBUS_TRUE@test_dbus_client_server_CPPFLAGS = -I$(gdbus_dir) -I$(top_srcdir)/src
@COND_CORE_TRUE@@COND_DBUS_TRUE@test_dbus_client_server_CXXFLAGS = $(CPPUNIT_CXXFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(BACKEND_CPPFLAGS) $(DBUS_CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(PCRECPP_CFLAGS)
@COND_CORE_TRUE@@COND_DBUS_TRUE@test_dbus_client_server_LDFLAGS = $(CPPUNIT_LDFLAGS)
# Some exceptions for the link check above (= symbol may be used without linking).
# SySync_ConsolePrintf is expected by libsmltk and has to be provided by caller.
LINK_CHECK_ALLOWED = -e xxxxxxxx -e \
- 'SySync_ConsolePrintf.*libsmltk.so' $(am__append_121)
+ 'SySync_ConsolePrintf.*libsmltk.so' $(am__append_122)
@COND_CROSS_COMPILING_FALSE@RUN_SYNCEVOLUTION_CHECK = die if $$?; return $$buffer;
# Be strict about running 'syncevolution' only when not doing
+SyncEvolution 1.4.1 -> 1.5, 31.10.2014
+======================================
+
+Based on community feedback and discussions, the terminology used in
+SyncEvolution for configuration, local sync and database access was
+revised. Some usability issues with setting up access to databases
+were addressed.
+
+Interoperability with WebDAV servers and in particular Google Contacts
+was enhanced considerably. Access to iCloud contacts was reported as
+working when using username=foobar@icloud.com and password, but is not
+formally tested. Syncing with iCloud calendars ran into a server
+limitation (reported as 17001498 "CalDAV REPORT drops calendar data")
+and needs further work (FDO #72133).
+
+Contact data gets converted to and from the format typically used by
+CardDAV servers, so now anniversary, spouse, manager, assistant and
+instant message information are exchanged properly. Custom labels get
+stored in EDS as extensions and no longer get lost when updating some
+other aspects of a contact. However, Evolution does not show custom
+labels and removes them when editing a property which has a custom
+label (BGO #730636).
+
+Scanning for CardDAV/CalDAV resources was enhanced. It now finds
+additional calendars with Google CalDAV. For Google, the obsolete
+SyncML config template was removed and CalDAV/CardDAV were merged into
+a single "Google" template.
+
+Using Google Calendar/Contacts with OAuth2 authentication on a
+headless server becomes a bit easier: it is possible to set up access
+on one system with a GUI using either gSSO or GNOME Online Accounts,
+then take the OAuth2 refresh token and use it in SyncEvolution on a
+different system. See
+http://cgit.freedesktop.org/SyncEvolution/syncevolution/tree/src/backends/oauth2/README
+
+The PIM Manager API also supports Google Contact syncing. Some
+problems with suspending a PBAP sync were fixed. Suspend/abort can
+be tested with the sync.py example.
+
+Performance is better for local syncs and PBAP caching. The most
+common case, a two-way sync with no changes on either side, no longer
+rewrites any meta data files. CPU consumption during local sync was
+reduced to one third by exchanging messages via shared memory instead
+of internal D-Bus. Redundant vCard decode/encode on the sending side
+of PBAP and too agressive flushing of meta data during a normal sync
+were removed.
+
+The EDS memo backend is able to switch between syncing in plain
+text and iCalendar 2.0 VJOURNAL automatically.
+
+
+Details:
+
+* source -> datastore rename, improved terminology
+
+ The word "source" implies reading, while in fact access is read/write.
+ "datastore" avoids that misconception. Writing it in one word emphasizes
+ that it is single entity.
+
+ While renaming, also remove references to explicit --*-property
+ parameters. The only necessary use today is "--sync-property ?"
+ and "--datastore-property ?".
+
+ --datastore-property was used instead of the short --store-property
+ because "store" might be mistaken for the verb. It doesn't matter
+ that it is longer because it doesn't get typed often.
+
+ --source-property must remain valid for backward compatility.
+
+ As many user-visible instances of "source" as possible got replaced in
+ text strings by the newer term "datastore". Debug messages were left
+ unchanged unless some regex happened to match it.
+
+ The source code will continue to use the old variable and class names
+ based on "source".
+
+ Various documentation enhancements:
+ Better explain what local sync is and how it involves two sync
+ configs. "originating config" gets introduces instead of just
+ "sync config".
+
+ Better explain the relationship between contexts, sync configs,
+ and source configs ("a sync config can use the datastore configs in
+ the same context").
+
+ An entire section on config properties in the terminology
+ section. "item" added (Todd Wilson correctly pointed out that it was
+ missing).
+
+ Less focus on conflict resolution, as suggested by Graham Cobb.
+
+ Fix examples that became invalid when fixing the password
+ storage/lookup mechanism for GNOME keyring in 1.4.
+
+ The "command line conventions", "Synchronization beyond SyncML" and
+ "CalDAV and CardDAV" sections were updated. It's possible that the
+ other sections also contain slightly incorrect usage of the
+ terminology or are simply out-dated.
+
+* local sync: allow config name in syncURL=local://
+
+ Previously, only syncURL=local://@<context name> was allowed and used
+ the "target-config@context name" config as target side in the local
+ sync.
+
+ Now "local://config-name@context-name" or simply "local://config-name"
+ are also allowed. "target-config" is still the fallback if only a
+ context is give.
+
+ It also has one more special meaning: "--configure
+ target-config@google" will pick the "Google" template automatically
+ because it knows that the intention is to configure the target side
+ of a local sync. It does not know that when using some other name
+ for the config, in which case the template (if needed) must be
+ specified explicitly.
+
+ The process name in output from the target side now also includes the
+ configuration name if it is not the default "target-config".
+
+* command line: revise usability checking of datastores
+
+ When configuring a new sync config, the command line checks whether a
+ datastore is usable before enabling it. If no datastores were listed
+ explicitly, only the usable ones get enabled. If unusable datastores
+ were explicitly listed, the entire configure operation fails.
+
+ This check was based on listing databases, which turned out to be too
+ unspecific for the WebDAV backend: when "database" was set to some URL
+ which is good enough to list databases, but not a database URL itself,
+ the sources where configured with that bad URL.
+
+ Now a new SyncSource::isUsable() operation is used, which by default
+ just falls back to calling the existing Operations::m_isEmpty. In
+ practice, all sources either check their config in open() or the
+ m_isEmpty operation, so the source is usable if no error is
+ enountered.
+
+ For WebDAV, the usability check is skipped because it would require
+ contacting a remote server, which is both confusing (why does a local
+ configure operation need the server?) and could fail even for valid
+ configs (server temporarily down). The check was incomplete anyway
+ because listing databases gave a fixed help text response when no
+ credentials were given. For usability checking that should have
+ resulted in "not usable" and didn't.
+
+ The output during the check was confusing: it always said "listing
+ databases" without giving a reason why that was done. The intention
+ was to give some feedback while a potentially expensive operation
+ ran. Now the isUsable() method itself prints "checking usability" if
+ (and only if!) such a check is really done.
+
+ Sometimes datastores were checked even when they were about to be
+ configure as "disabled" already. Now checking such datastores is
+ skipped.
+
+* command line: fix --update from directory
+
+ The "--update <dir name>" operation was supposed to take the
+ item luids from the file names inside the directory. That part
+ had not been implemented, turning the operation accidentally
+ into an "--import".
+
+ Also missing was the escaping/unescaping of luids. Now the
+ same escaping is done as in command line output and command
+ line parsing to make the luids safe for use as file name.
+
+* sync output: hide "<source>: started" INFO messages
+
+ These messages get printed at the start of processing each
+ SyncML message. This is not particularly useful and just
+ adds noise to the output.
+
+* config: allow storing credentials for email address
+
+ When configuring a WebDAV server with username = email address and no
+ URL (which is possible if the server supports service discovery via
+ the domain in the email address), then storing the credentials in the
+ GNOME keyring used to fail with "cannot store password in GNOME
+ keyring, not enough attributes".
+
+ That is because GNOME keyring seemed to get confused when a network
+ login has no server name and some extra safeguards were added to
+ SyncEvolution to avoid this.
+
+ To store the credentials in the case above, the email address now gets
+ split into user and domain part and together get used to look up the
+ password.
+
+* config: ignore unnecessary username property
+
+ A local sync or Bluetooth sync do not need the 'username' property.
+ When it is set despite that, issue a warning.
+
+ Previously, the value was checked even when not needed, which
+ caused such syncs to fail when set to something other than a plain
+ username.
+
+* config templates: Funambol URLs
+
+ Funambol turned of the URL redirect from my.funambol.com to
+ onemedia.com. The Funambol template now uses the current URL. Users
+ with existing Funambol configs must updated the syncURL property
+ manually to https://onemediahub.com/sync
+
+ Kudos to Daniel Clement for reporting the change.
+
+* EDS: memo syncing as iCalendar 2.0 (FDO #52714)
+
+ When syncing memos with a peer which also supports iCalendar 2.0 as
+ data format, the engine will now pick iCalendar 2.0 instead of
+ converting to/from plain text. The advantage is that some additional
+ properties like start date and categories can also be synchronized.
+
+ The code is a lot simpler, too, because the EDS specific iCalendar 2.0
+ <-> text conversion code can be removed.
+
+* SoupTransport: drop CA file check
+
+ It used to be necessary to specify a CA file for libsoup to enable SSL
+ certificate checking. Nowadays libsoup uses the default CA store
+ unless told otherwise, so the check in SyncEvolution became
+ obsolete. However, now there is a certain risk that no SSL checking is
+ done although the user asked for it (when libsoup is not recent enough
+ or compiled correctly).
+
+* CardDAV: use Apple/Google/CardDAV vCard flavor
+
+ In principle, CardDAV servers support arbitrary vCard 3.0
+ data. Extensions can be different and need to be preserved. However,
+ when multiple different clients or the server's Web UI interpret the
+ vCards, they need to agree on the semantic of these vCard extensions.
+
+ In practice, CardDAV was pushed by Apple and Apple clients are
+ probably the most common clients of CardDAV services. When the Google
+ Contacts Web UI creates or edits a contact, Google CardDAV will
+ send that data using the vCard flavor used by Apple.
+
+ Therefore it makes sense to exchange contacts with *all* CardDAV
+ servers using that format. This format could be made configurable in
+ SyncEvolution on a case-by-case basis; at the moment, it is
+ hard-coded.
+
+ During syncing, SyncEvolution takes care to translate between the
+ vCard flavor used internally (based on Evolution) and the CardDAV
+ vCard flavor. This mapping includes:
+
+ X-AIM/JABBER/... <-> IMPP + X-SERVICE-TYPE
+
+ Any IMPP property declared as X-SERVICE-TYPE=AIM will get
+ mapped to X-AIM. Same for others. Some IMPP service types
+ have no known X- property extension; they are stored in
+ EDS as IMPP. X- property extensions without a known X-SERVICE-TYPE
+ (for example, GaduGadu and Groupwise) are stored with
+ X-SERVICE-TYPE values chosen by SyncEvolution so that
+ Google CardDAV preserves them (GroupWise with mixed case
+ got translated by Google into Groupwise, so the latter is used).
+
+ Google always sends an X-ABLabel:Other for IMPP. This is ignored
+ because the service type overrides it.
+
+ The value itself also gets transformed during the mapping. IMPP uses
+ an URI as value, with a chat protocol (like "aim" or "xmpp") and
+ some protocol specific identifier. For each X- extension the
+ protocol is determined by the property name and the value is the
+ protocol specific identifier without URL encoding.
+
+ X-SPOUSE/MANAGER/ASSISTANT <-> X-ABRELATEDNAMES + X-ABLabel
+
+ The mapping is based on the X-ABLabel property attached to
+ the X-ABRELATEDNAMES property. This depends on the English
+ words "Spouse", "Manager", "Assistant" that Google CardDAV
+ and Apple devices seem to use regardless of the configured
+ language.
+
+ As with IMPP, only the subset of related names which have
+ a corresponding X- property extension get mapped. The rest
+ is stored in EDS using the X-ABRELATEDNAMES property.
+
+ X-ANNIVERSARY <-> X-ABDATE
+
+ Same here, with X-ABLabel:Anniversary as the special case
+ which gets mapped.
+
+ X-ABLabel parameter <-> property
+
+ CardDAV vCards have labels attached to arbitrary other properties
+ (TEL, ADR, X-ABDATE, X-ABRELATEDNAMES, ...) via vCard group tags:
+ item1.X-ABDATE:2010-01-01
+ item1.X-ABLabel:Anniversary
+
+ The advantage is that property values can contain arbitrary
+ characters, including line breaks and double quotation marks,
+ which is not possible in property parameters.
+
+ Neither EDS nor KDE (judging from the lack of responses on the
+ KDE-PIM mailing list) support custom labels. SyncEvolution could
+ have used grouping as it is done in CardDAV, but grouping is not
+ used much (not at all?) by the UIs working with the vCards in EDS
+ and KDE. It seemed easier to use a new X-ABLabel parameter.
+
+ Characters which cannot be stored in a parameter get converted
+ (double space to single space, line break to space, etc.) during
+ syncing. In practice, these characters don't appear in X-ABLabel
+ properties anyway because neither Apple nor Google UIs allow entering
+ them for custom labels.
+
+ The "Other" label is used by Google even in case where it adds no
+ information. For example, all XMPP properties have an associated
+ X-ABLabel=Other although the Web UI does not provide a means to edit
+ or show such a label. Editing the text before the value in the UI
+ changes the X-SERVICE-TYPE parameter value, not the X-ABLabel as for
+ other fields.
+
+ Therefore the "Other" label is ignored by removing it during syncing.
+
+ X-EVOLUTION-UI-SLOT (the parameter used in Evolution to determine the
+ order of properties in the UI) gets stored in CardDAV. The only exception
+ is Google CardDAV which got confused when an IMPP property had both
+ X-SERVICE-TYPE and X-EVOLUTION-UI-SLOT parameters set. For Google,
+ X-EVOLUTION-UI-SLOT is only sent on other properties and thus ordering
+ of chat information can get lost when syncing with Google.
+
+* synccompare: support grouping and quoted parameter strings
+
+ Grouped properties are sorted first according to the actual property
+ name, then related properties are moved to the place where their group
+ tag appears first. The first grouped property gets a "- " prefix, all
+ following ones are just indended with " ". The actual group tag is not
+ part of the normalized output, because its value is irrelevant:
+
+ BDAY:19701230
+ - EMAIL:john@custom.com
+ X-ABLabel:custom-label2
+ ...
+ FN:Mr. John 1 Doe Sr.
+ - IMPP;X-SERVICE-TYPE=AIM:aim:aim
+ X-ABLabel:Other
+ ...
+ - X-ABDATE:19710101
+ X-ABLabel:Anniversary
+
+ Redundant tags (those set for only a single property, X-ABLabel:Other)
+ get removed as part of normalizing an item.
+
+* WebDAV: use server's order when listing collections
+
+ When doing a recursive scan of the home set, preserve the order of
+ entries as reported by the server and check the first one first. The
+ server knows better which entries are more relevant for the user (and
+ thus should be the default) or may have some other relevant
+ order. Previously, SyncEvolution replaced that order with sorting by
+ URL, which led to a predictable, but rather meaningless order.
+
+ For example, Google lists the users own calendar first, followed by
+ the shared calendars sorted alphabetical by their name. Now
+ SyncEvolution picks the main calendar as default correctly when
+ scanning from https://www.google.com/calendar/dav/.
+
+* WebDAV: improved database search (Google, Zimbra)
+
+ Zimbra has a principal URL that also serves as home set. When using it
+ as start URL, SyncEvolution only looked the URL once, without listing
+ its content, and thus did not find the databases.
+
+ When following the Zimbra principal URL indirectly, SyncEvolution did
+ check all of the collections there recursively. Unfortunately that
+ also includes many mail folders, causing the scan to abort after
+ checking 1000 collections (an internal safe guard).
+
+ The solution for both includes tracking what to do with a URL. For the
+ initial URL, only meta data about the URL itself gets
+ checked. Recursive scanning is only done for the home set. If that
+ home set contains many collections, scanning is still slow and may run
+ into the internal safe guard limit. This cannot be avoided because the
+ CalDAV spec explicitly states that the home set may contain normal
+ collections which contain other collections, so a client has to do the
+ recursive scan.
+
+ When looking at a specific calendar, Google CalDAV does not report
+ what the current principal or the home set is and therefore
+ SyncEvolution stopped after finding just the initial calendar. Now it
+ detects the lack of meta information and adds all parents also as
+ candidates that need to be looked at. The downside of this is that it
+ doesn't know anything about which parents are relevant, so it ends up
+ checking https://www.google.com/calendar/ and
+ https://www.google.com/.
+
+ In both cases Basic Auth gets rejected with a temporary redirect to
+ the Google login page, which is something that SyncEvolution must
+ ignore immediately during scanning without applying the resend
+ workaround for "temporary rejection of valid credentials" that can
+ happen for valid Google CalDAV URLs.
+
+* WebDAV: enhanced database search (Google Calendar)
+
+ Additional databases where not found for several
+ reasons. SyncEvolution ignored all shared calendars
+ (http://calendarserver.org/ns/shared) and Google marks the additional
+ calendars that way. The other problem was that the check for leaf
+ collections (= collections which cannot contain other desired
+ collections) incorrectly excluded those collections instead of only
+ preventing listing of their content.
+
+ With this change,
+ https://www.google.com/calendar/dav/?SyncEvolution=Google can be used
+ as starting point for Google Calendar.
+
+* WebDAV: fix database scan on iCloud
+
+ The calendar home set URL on iCloud (the one ending in /calendars/) is
+ declared as containing calendar data. That was enough for
+ SyncEvolution to accept it incorrectly as calendar. However, the home
+ set only contains calendar data indirectly.
+
+* WebDAV: support redirects between hosts and DNS SRV lookup based on URL
+
+ When finding a new URL, we must be prepared to reinitialize the Neon
+ session with the new host settings.
+
+ iCloud does not have .well-known support on its www.icloud.com
+ server. To support lookup with a non-icloudd.com email address, we
+ must do DNS SRV lookup when access to .well-known URLs fails. We do
+ this without a www prefix on the host first, because that is what happens
+ to work for icloud.com.
+
+ With these changes it becomes possible to do database scans on Apple
+ iCloud, using syncURL=https://www.icloud.com or
+ syncURL=https://icloud.com. Giving the syncURL like this is only
+ necessary for a username that does not end in @icloud.com. When
+ the syncURL is not set, the domain for DNS SRV lookup is taken
+ from the username.
+
+* WebDAV: more efficient item creation
+
+ PUT has the disadvantage that a client needs to choose a name and then
+ figure out what the real name on the server is. With Google CardDAV that
+ requires sending another request and only works because the server happens
+ to remember the original name (which is not guaranteed!).
+
+ POST works for new items without a name and happens to be implemented
+ by Google such that the response already includes all required
+ information (new name and revision string).
+
+ POST is checked for as described in RFC 5995 once before creating a new
+ item. Servers which don't support it continue to get a PUT.
+
+* WebDAV: send "User-Agent: SyncEvolution"
+
+ Apple iCloud servers reject requests unless they contain a User-Agent
+ header. The exact value doesn't seem to matter. Making the string
+ configurable might be better, but can still be done later when it
+ is more certain whether and for what it is needed.
+
+* WebDAV: refactor and fix DNS SRV lookup
+
+ The syncevo-webdav-lookup script was not packaged. It did not report
+ "not found" DNS results correctly and the caller did not check for
+ this either, so when looking up the information for a domain which
+ does not have DNS SRV entries, SyncEvolution ended up retrying for
+ while as if there had been a temporary lookup problem.
+
+* Google: remove SyncML template, combine CalDAV/CardDAV
+
+ Google has turned off their SyncML server, so the corresponding
+ "Google Contacts" template became useless and needs to be removed. It
+ gets replaced by a "Google" template which combines the three
+ different URLs currently used by Google for CalDAV/CardDAV.
+
+ This new template can be used to configure a "target-config@google"
+ with default calendar and address book database already enabled. The
+ actual URL of these databases will be determined during the first
+ sync using them.
+
+ The template relies on the WebDAV backend's new capability to search
+ multiple different entries in the syncURL property for databases. To
+ avoid listing each calendar twice (once for the legacy URL, once with
+ the new one) when using basic username/password authentication, the
+ backend needs a special case for Google and detect that the legacy URL
+ does not need to be checked.
+
+* Google Calendar: remove child hack, improve alarm hack (FDO #63881)
+
+ Google recently enhanced support for RECURRENCE-ID, so SyncEvolution
+ no longer needs to replace the property when uploading a single
+ detached event with RECURRENCE-ID. However, several things are still
+ broken in the server, with no workaround in SyncEvolution:
+ - Removing individual events gets ignored by the server;
+ a full "wipe out server data" might work (untested).
+ - When updating the parent event, all child events also get
+ updated even though they were included unchanged in the data
+ sent by SyncEvolution.
+ - The RECURRENCE-ID of a child event of an all-day recurring event
+ does not get stored properly.
+ - The update hack seems to fail for complex meetings: uploading them
+ once and then deleting them seems to make uploading them again
+ impossible.
+
+ All of these issues were reported to Google and are worked on there,
+ so perhaps the situation will improve. In the meantime, syncing with
+ Google CalDAV should better be limited to:
+ - Downloading a Google calendar in one-way mode.
+ - Two-way syncing of simple calendars without complex meeting
+ serieses.
+
+ While updating the Google workarounds, the alarm hack (sending a
+ new event without alarms twice to avoid the automatic server side
+ alarm) was simplified. Now the new event gets sent only once with a
+ pseudo-alarm.
+
+* CardDAV: implement read-ahead
+
+ Instead of downloading contacts one-by-one with GET, SyncEvolution now
+ looks at contacts that are most likely going to be needed soon and
+ gets all of them at once with addressbook-multiget REPORT.
+
+ The number of contacts per REPORT is 50 by default, configurable by
+ setting the SYNCEVOLUTION_CARDDAV_BATCH_SIZE env variable.
+
+ This has two advantages:
+ - It avoids round-trips to the server and thus speeds up a large
+ download (100 small contacts with individual GETs took 28s on
+ a fast connection, 3s with two REPORTs).
+ - It reduces the overall number of requests. Google CardDAV is known
+ to start issuing intermittent 401 authentication errors when the
+ number of contacts retrieved via GET is too large. Perhaps this
+ can be avoided with addressbook-multiget.
+
+* oauth2: new backend using libsoup/libcurl
+
+ New backend implements identity provider for obtaining OAuth2 access
+ token for systems without HMI support.
+ Access token is obtained by making direct HTTP request to OAuth2 server
+ and using refresh token obtained by user in some other way.
+ New provider automatically updates stored refresh token when OAuth2
+ server is issuing new one.
+
+* signon: make Accounts optional
+
+ The new "signon" provider only depends on lib[g]signon-glib. It uses
+ gSSO if found, else UOA. Instead of pulling parameters and the
+ identity via libaccounts-glib, the user of SyncEvolution now has to
+ ensure that the identity exists and pass all relevant parameters
+ in the "signon:" username.
+
+* gSSO: adapt to gSSO >= 2.0
+
+* signon: fix build
+
+ Static build was broken for gSSO and UOA (wrong path name to .la file)
+ and gSSO was not enabled properly (wrong condition check).
+
+* datatypes: raw text items with minimal conversion (FDO #52791)
+
+ When using "raw/text/calendar" or "raw/text/vcard" as SyncEvolution
+ "databaseFormat", all parsing and conversion is skipped. The backend's
+ data is identical to the item data in the engine. Finding duplicates
+ in a slow sync is very limited when using these types because the entire
+ item data must match exactly.
+
+ This is useful for the file backend when the goal is to store an exact copy
+ of what a peer has or for limited, read-only backends (PBAP). The downside
+ of using the raw types is that the peer is not given accurate information
+ about which vCard or iCalendar properties are supported, which may cause
+ some peers to not send all data.
+
+* datatypes: text/calendar+plain revised heuristic
+
+ When sending a VEVENT, DESCRIPTION was set to the SUMMARY if empty. This may
+ have been necessary for some peers, but for notes (= VJOURNAL) we don't know
+ that (hasn't been used in the past) and don't want to alter the item
+ unnecessarily, so skip that part and allow empty DESCRIPTION.
+
+ When receiving a plain text note, the "text/calendar+plain" type
+ used to store the first line as summary and the rest as description.
+ This may be correct in some cases and wrong in others.
+
+ The EDS backend implemented a different heuristic: there the first
+ line is copied into the summary and stays in the description. This
+ makes a bit more sense (the description alone is always enough to
+ understand the note). Therefore and to avoid behavioral changes
+ for EDS users when switching the EDS backend to use text/calendar+plain,
+ the engine now uses the same approach.
+
+* datatypes: avoid PHOTO corruption during merge (FDO #77065)
+
+ When handling an update/update conflict (both sides of the sync have an
+ updated contact) and photo data was moved into a local file by EDS, the engine
+ merged the file path and the photo data together and thus corrupted the photo.
+
+ The engine does not know about the special role of the photo property.
+ This needs to be handled by the merge script, and that script did not
+ cover this particular situation. Now the loosing side is cleared,
+ causing the engine to then copy the winning side over into the loosing
+ one.
+
+ Found by Renato Filho/Canonical when testing SyncEvolution for Ubuntu 14.04.
+
+* vcard profile: avoid data loss during merging
+
+ When resolving a merge conflict, repeating properties were taken
+ wholesale from the winning side (for example, all email addresses). If
+ a new email address had been added on the loosing side, it got lost.
+
+ Arguably it is better to preserve as much data as possible during a
+ conflict. SyncEvolution now does that in a merge script by checking
+ which properties in the loosing side do not exist in the winning side
+ and copying those entries.
+
+ Typically only the main value (email address, phone number) is checked
+ and not the additional meta data (like the type). Otherwise minor
+ differences (for example, both sides have same email address, but with
+ different types) would lead to duplicates.
+
+ Only addresses are treated differently: for them all attributes
+ (street, country, city, etc.) are compared, because there is no single
+ main value.
+
+* engine: UID support in contact data
+
+ Before, the UID property in a vCard was ignored by the engine.
+ Backends were responsible for ensuring that the property is
+ set if required by the underlying storage. This turned out to be
+ handled incompletely in the WebDAV backend.
+
+ This change moves this into the engine:
+ - UID is now field. It does not get used for matching
+ because the engine cannot rely on it being stored
+ by both sides.
+ - It gets parsed if present, but only generated if
+ explicitly enabled (because that is the traditional
+ behavior).
+ - It is never shown in the DevInf's CtCap
+ because the Synthesis engine would always show it
+ regardless whether a rule enabled the property.
+ That's because rules normally only get triggered
+ after exchanging DevInf and thus DevInf has to
+ be rule-independent. We don't want it shown because
+ then merging the incoming item during a local sync
+ would use the incoming UID, even if it is empty.
+ - Before writing, ensure that UID is set.
+
+ When updating an existing item, the Synthesis engine reads
+ the existing item, preserves the existing UID unless the peer
+ claims to support UID, and then updates with the existing UID.
+
+ This works for local sync (where SyncEvolution never claims
+ to support UID when talking to the other side). It will break
+ with peers which have UID in their CtCap although they
+ rewrite the UID and backends whose underlying storage cannot
+ handle UID changes during an update (for example, CardDAV).
+
+* engine: flush map items less frequently
+
+ The Synthesis API does not say explicitly, but in practice all map
+ items get updated in a tight loop. Rewriting the m_mappingNode (case
+ insensitive string comparisons) and serialization to disk
+ (std::ostrstream) consume a significant amount of CPU cycles and cause
+ extra disk writes that can be avoided by making some assumptions about
+ the sequence of API calls and flushing only once.
+
+* local sync: exchange SyncML messages via shared memory
+
+ Encoding/decoding of the uint8_t array in D-Bus took a surprisingly
+ large amount of CPU cycles relative to the rest of the SyncML message
+ processing. Now the actual data resides in memory-mapped temporary
+ files and the D-Bus messages only contain offset and size inside these
+ files. Both sides use memory mapping to read and write directly.
+
+ For caching 1000 contacts with photos on a fast laptop, total sync
+ time roughly drops from 6s to 3s.
+
+ To eliminate memory copies, memory handling in libsynthesis or rather,
+ libsmltk is tweaked such that it allocates the buffer used for SyncML
+ message data in the shared memory buffer directly. This relies on
+ knowledge of libsmltk internals, but those shouldn't change and if they
+ do, SyncEvolution will notice ("unexpected send buffer").
+
+* local sync: avoid updating meta data when nothing changed
+
+ The sync meta data (sync anchors, client change log) get updated after
+ a sync even if nothing changed and the existing meta data could be
+ used again. This can be skipped for local sync, because then
+ SyncEvolution can ensure that both sides skip updating the meta
+ data. With a remote SyncML server that is not possible and thus
+ SyncEvolution has to update its data.
+
+ It is based on the observation that when the server side calls
+ SaveAdminData, the client has sent its last message and the sync is
+ complete. At that point, SyncEvolution can check whether anything has
+ changed and if not, skip saving the server's admin data and stop the
+ sync without sending the real reply to the client.
+
+ Instead the client gets an empty message with "quitsync" as content
+ type. Then it takes shortcuts to close down without finalizing the
+ sync engine, because that would trigger writing of meta data
+ changes. The server continues its shutdown normally.
+
+ This optimization is limited to syncs with a single source, because
+ the assumption about when aborting is possible is harder to verify
+ when multiple sources are involved.
+
+* PBAP: support SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME <= 0
+
+ When set to 0 or less, the chunk size is not getting adapted at all
+ while still using transfers in chunks.
+
+* PBAP: use raw text items
+
+ This avoids the redundant parse/generate step on the sending
+ side of the PBAP sync.
+
+* PBAP syncing: updated photo not always stored
+
+ Because photo data was treated like a C string, changes after any
+ embedded null byte were ignored during a comparison.
+
+* ephemeral sync: don't write binfile client files (FDO #55921)
+
+ When doing PBAP caching, we don't want any meta data written because
+ the next sync would not use it anyway. With the latest libsynthesis
+ we can configure "/dev/null" as datadir for the client's binfiles and
+ libsynthesis will avoid writing them.
+
+ The PIM manager uses this for PBAP syncing automatically. For testing
+ it can be enabled by setting the SYNCEVOLUTION_EPHEMERAL env variable.
+
+* PBAP: avoid empty field filter
+
+ Empty field filter is supposed to mean "return all supported
+ fields". This used to work and stopped working with Android phones
+ after an update to 4.3 (seen on Galaxy S3); now the phone only
+ returns the mandatory TEL, FN, N fields.
+
+ The workaround is to replace the empty filter list with the list of
+ known and supported properties. This means we only pull data we really
+ need, but it also means we won't get to see any additional properties
+ that the phone might support.
+
+* PBAP: transfer in chunks (FDO #77272)
+
+ If enabled via env variables, PullAll transfers will be limited to
+ a certain numbers contacts at different offsets until all data got
+ pulled. See PBAP README for details.
+
+ When transfering in chunks, the enumeration of contacts for the engine
+ no longer matches the PBAP enumeration. Debug output uses "offset #x"
+ for PBAP and "ID y" for the engine.
+
+* PBAP: remove transfer via pipe
+
+ Using a pipe was never fully supported by obexd (blocks
+ obexd). Transfering in suitably sized chunks (FDO #77272) will be a
+ more obexd friendly solution with a similar effect (not having to
+ buffer the entire address book in memory).
+
+* PBAP: Suspend/ResumeSync() (FDO #72112)
+
+ By default, the new API freezes a sync by stopping to consume data on the
+ local side of the sync.
+
+ In addition, the information that the sync is freezing is now also handed
+ down to the transport and all sources. In the case of PBAP caching, the local
+ transport notifies the child where the PBAP source then uses Bluez
+ 5.15 Transfer1.Suspend/Resume to freeze/thaw the actual OBEX transfer.
+
+ If that fails (for example, not implemented because Bluez is too old
+ or the transfer is still queueing), then the transfer gets cancelled
+ and the entire sync fails. This is desirable for PBAP caching and
+ Bluetooth because a failed sync can easily be recovered from (just
+ start it again) and the overall goal is to free up Bluetooth bandwidth
+ quickly.
+
+* PBAP: transfer data via pipe (part of FDO #72112)
+
+ The main advantage is that processed data can be discarded
+ immediately. When using a plain file, the entire address book must be
+ stored in it.
+
+ The drawback is that obexd does not react well to a full pipe. It
+ simply gets stuck in a blocking write(); in other words, all obexd
+ operations get frozen and obexd stops responding on D-Bus.
+
+* PIM: include CardDAV in CreatePeer()
+
+ This adds "protocol: CardDAV" as a valid value, with corresponding
+ changes to the interpretation of some existing properties and some new
+ ones. The API itself is not changed.
+
+ Suspending a CardDAV sync is possible. This freezes the internal
+ SyncML message exchange, so data exchange with the CardDAV server may
+ continue for a while after SuspendPeer().
+
+ Photo data is always downloaded immediately. The "pbap-sync" flag
+ in SyncPeerWithFlags() has no effect.
+
+ Syncing can be configured to be one-way (local side is read-only
+ cache) or two-way (local side is read/write). Meta data must be
+ written either way, to speed up caching or allow two-way syncing. The
+ most common case (no changes on either side) will have to be optimized
+ such that existing meta data is not touched and thus no disk writes
+ occur.
+
+* PIM: handle SuspendPeer() before and after transfer (FDO #82863)
+
+ A SuspendPeer() only succeeded while the underlying Bluetooth transfer
+ was active. Outside of that, Bluez errors caused SyncEvolution to
+ attempt a cancelation of the transfer and stopped the sync.
+
+ When the transfer was still queueing, obexd returns
+ org.bluez.obex.Error.NotInProgress. This is difficult to handle for
+ SyncEvolution: it cannot prevent the transfer from starting and has to
+ let it become active before it can suspend the transfer. Canceling
+ would lead to difficult to handle error cases (like partially parsed
+ data) and therefore is not done.
+
+ The Bluez team was asked to implement suspending of queued transfers
+ (see "org.bluez.obex.Transfer1 Suspend/Resume in queued state" on
+ linux-bluetooth@vger.kernel.org), so this case might not happen
+ anymore with future Bluez.
+
+ When the transfer completes before obexd processes the Suspend(),
+ org.freedesktop.DBus.Error.UnknownObject gets returned by
+ obexd. SyncEvolution can ignore errors which occur after the active
+ transfer completed. In addition, it should prevent starting the next
+ one. This may be relevant for transfer in chunks, although the sync
+ engine will also stop asking for data and thus typically no new
+ transfer gets triggered anyway.
+
+* PIM: add suspend/resume/abort to sync.py
+
+ CTRL-C while waiting for the end of a sync causes an interactive
+ prompt to appear where one can choose been suspend/resume/abort and
+ continuing to wait. CTRL-C again in the prompt aborts the script.
+
+* PIM: enhanced progress notifications (FDO #72114)
+
+ This adds GetPeerStatus() and "progress" events. Progress is reported based
+ on the "item received" Synthesis event and the total item count. A modified
+ libsynthesis is needed where the SyncML binfile client on the target side of
+ the local sync actually sends the total item count (via NumberOfChanges).
+ This cannot be done yet right at the start of the sync, only the second SyncML
+ message will have it. That is acceptable, because completion is reached very
+ quickly anyway for syncs involving only one message.
+
+ At the moment, SyncContext::displaySourceProgress() holds back "item
+ received" events until a different event needs to be emitted. Progress
+ reporting might get more fine-grained when adding allowing held back
+ events to be emitted at a fixed rate, every 0.1s. This is not done yet
+ because it seems to work well enough already.
+
+ For testing and demonstration purposes, sync.py gets command line
+ arguments for setting progress frequency and showing progress either
+ via listening to signals or polling.
+
+* PIM: add SyncPeerWithFlags() and 'pbap-sync' flag (FDO #70950)
+
+ The is new API and flag grant control over the PBAP sync mode.
+
+* PIM: fix phone number normalization
+
+ The parsed number always has a country code, whereas SyncEvolution expected it
+ to be zero for strings without an explicit country code. This caused a caller
+ ID lookup of numbers like "089788899" in DE to find only telephone numbers in
+ the current default country, instead of being more permissive and also finding
+ "+189788899". The corresponding unit test was broken and checked for the wrong
+ result. Found while investigating an unrelated test failure when updating
+ libphonenumber.
+
+* engine: enable batching by default (FDO #52669)
+
+ This reverts commit c435e937cd406e904c437eec51a32a6ec6163102.
+
+ Commit 7b636720a in libsynthesis fixes an unitialized memory read in
+ the asynchronous item update code path.
+
+ Testing confirms that we can now used batched writes reliably with EDS
+ (the only backend currently supporting asynchronous writes +
+ batching), so this change enables it again also for local and
+ SyncEvolution<->SyncEvolution sync (with asynchronous execution of
+ contact add/update overlapped with SyncML message exchanges) and other
+ SyncML syncs (with changes combined into batches and executed at the
+ end of each message).
+
+* Various compiler problems and warnings fixed; compiles with
+ --with-warnings=fatal on current Debian Testing and Ubuntu Trusty
+ (FDO #79316).
+
+* D-Bus server: fix unreliable shutdown handling
+
+ Occassionally, syncevo-dbus-server locked up after receiving
+ a CTRL-C. This primarily affected nightly testing, in particular (?)
+ on Ubuntu Lucid.
+
+* D-Bus: use streams for direct IPC with GIO
+
+ When using GIO, it is possible to avoid the DBusServer listening on a
+ publicly accessible address. Connection setup becomes more reliable,
+ too, because the D-Bus server side can detect that a child died
+ because the connection will be closed.
+
+ When using libdbus, the traditional server/listen and client/connect
+ model is still used.
+
+* LogRedirect: safeguard against memory corruption
+
+ When aborting, our AbortHandler gets called to close down logging.
+ This may involve memory allocation, which is unsafe. In FDO #76375, a
+ deadlock on a libc mutex was seen.
+
+ To ensure that the process shuts down anyway, install an alarm and give
+ the process five seconds to shut down before the SIGALRM signal will kill
+ it.
+
+
+Upgrading from releases <= 1.3.99.4:
+
+If the value of "username/databaseUser/proxyUser" contains a colon,
+the "user:" prefix must be added to the value, to continue treating it
+like a plain user name and not some reference to an unknown identity
+provider (like "id:", "goa:", "signon:", etc.).
+
+The lookup of passwords in GNOME Keyring was updated slightly in
+1.3.99.5. It may be necessary to set passwords anew if the old one is
+no longer found.
+
+Upgrading from release 1.2.x:
+
+The sync format of existing configurations for Mobical (aka Everdroid)
+must be updated manually, because the server has encoding problems when
+using vCard 3.0 (now the default for Evolution contacts):
+ syncevolution --configure \
+ syncFormat=text/x-vcard \
+ mobical addressbook
+
+The Funambol template explicitly enables usage of the
+"refresh-from-server" sync mode to avoid getting throttled with 417
+'retry later' errors. The same must be added to existing configs
+manually:
+ syncevolution --configure \
+ enableRefreshSync=TRUE \
+ funambol
+
+Upgrading from releases before 1.2:
+
+Old configurations can still be read. But writing, as it happens
+during a sync, must migrate the configuration first. Releases >= 1.2
+automatically migrates configurations. The old configurations
+will still be available (see "syncevolution --print-configs") but must
+be renamed manually to use them again under their original names with
+older SyncEvolution releases.
+
+
+SyncEvolution 1.4.99.4 -> 1.5, 31.10.2014
+=========================================
+
+Mostly a bug fix release.
+
+Details:
+
+* vcard: fix caching of PBAP contacts (FDO #84710)
+
+ After changing PBAP to send raw items, caching them led to unnecessary
+ disk writes and bogus "contacts changed" reports. That's because
+ the merge script relied on the exact order of properties, which was
+ only the same when doing the redundant decode/encode on the PBAP side.
+
+ Instead of reverting back to sending re-encoded items, better enhance
+ the contact merge script such that it detects contacts as unchanged
+ when just the order of entries in the property arrays is different.
+ This relies on an enhanced libsynthesis with the new RELAXEDCOMPARE()
+ and modified MERGEFIELDS().
+
+* sync: ignore unnecessary username property
+
+ A local sync or Bluetooth sync do not need the 'username' property.
+ When it is set despite that, issue a warning.
+
+ Previously, the value was checked even when not needed, which
+ caused such syncs to fail when set to something other than a plain
+ username.
+
+* D-Bus server: fix unreliable shutdown handling
+
+ Occassionally, syncevo-dbus-server locked up after receiving
+ a CTRL-C. This primarily affected nightly testing, in particular (?)
+ on Ubuntu Lucid.
+
+* scripting: prevent premature loop timeouts
+
+ The more complex "avoid data loss during merging" scripting ran for longer
+ than 5s limit under extreme conditions (full logging, busy system, running
+ under valgrind), which resulted in aborting the script and a 10500 "local
+ internal error" sync failure.
+
+* signon: fix providersignon.so (TC-1667)
+
+ The shared providersignon.so ended up being compiled with "gsso" as
+ prefix for the username. There also was a problem with invalid
+ reference counting.
+
+* PBAP: support SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME <= 0
+
+ When set to 0 or less, the chunk size is not getting adapted at all
+ while still using transfers in chunks.
+
+
SyncEvolution 1.4.99.3 -> 1.4.99.4, 10.09.2014
==============================================
------------------------------------------------
:Manual section: 1
-:Version: 1.4.99.4
-:Date: 2014-09-12
+:Version: 1.5
+:Date: 2014-10-31
SYNOPSIS
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for syncevolution 1.4.99.4.
+# Generated by GNU Autoconf 2.69 for syncevolution 1.5.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# Identity of this package.
PACKAGE_NAME='syncevolution'
PACKAGE_TARNAME='syncevolution'
-PACKAGE_VERSION='1.4.99.4'
-PACKAGE_STRING='syncevolution 1.4.99.4'
+PACKAGE_VERSION='1.5'
+PACKAGE_STRING='syncevolution 1.5'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures syncevolution 1.4.99.4 to adapt to many kinds of systems.
+\`configure' configures syncevolution 1.5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of syncevolution 1.4.99.4:";;
+ short | recursive ) echo "Configuration of syncevolution 1.5:";;
esac
cat <<\_ACEOF
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-release-mode Controls whether resulting binary is for end-users
+ --disable-release-mode Controls whether resulting binary is for end-users
or testers/developers. For example, stable releases
automatically migrate on-disk files without asking,
whereas other releases ask before making downgrades
impossible (or difficult). Default in this source
- code is "stable release: no"
+ code is "stable release: yes"
--enable-silent-rules less verbose build output (undo: `make V=1')
--disable-silent-rules verbose build output (undo: `make V=0')
--disable-dependency-tracking speeds up one-time build
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-syncevolution configure 1.4.99.4
+syncevolution configure 1.5
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by syncevolution $as_me 1.4.99.4, which was
+It was created by syncevolution $as_me 1.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
+
# Minimum version of libsynthesis as defined in its
# configure script and thus .pc files:
if test "${enable_release_mode+set}" = set; then :
enableval=$enable_release_mode; enable_release_mode="$enableval"
else
- enable_release_mode="no"
+ enable_release_mode="yes"
fi
if test "$enable_release_mode" = "yes"; then
# Define the identity of the package.
PACKAGE='syncevolution'
- VERSION='1.4.99.4'
+ VERSION='1.5'
cat >>confdefs.h <<_ACEOF
pkg_cv_SYNTHESIS_CFLAGS="$SYNTHESIS_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.5") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SYNTHESIS_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.47.4" 2>/dev/null`
+ pkg_cv_SYNTHESIS_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.47.5" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
pkg_cv_SYNTHESIS_LIBS="$SYNTHESIS_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.5") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SYNTHESIS_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.47.4" 2>/dev/null`
+ pkg_cv_SYNTHESIS_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.47.5" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.47.4" 2>&1`
+ SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.47.5" 2>&1`
else
- SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.47.4" 2>&1`
+ SYNTHESIS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.47.5" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SYNTHESIS_PKG_ERRORS" >&5
- as_fn_error $? "Package requirements (synthesis >= 3.4.0.47.4) were not met:
+ as_fn_error $? "Package requirements (synthesis >= 3.4.0.47.5) were not met:
$SYNTHESIS_PKG_ERRORS
pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS="$WITH_SYNTHESIS_SRC_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.5") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.47.4" 2>/dev/null`
+ pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS=`$PKG_CONFIG --cflags "synthesis >= 3.4.0.47.5" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
pkg_cv_WITH_SYNTHESIS_SRC_LIBS="$WITH_SYNTHESIS_SRC_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"synthesis >= 3.4.0.47.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "synthesis >= 3.4.0.47.5") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_WITH_SYNTHESIS_SRC_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.47.4" 2>/dev/null`
+ pkg_cv_WITH_SYNTHESIS_SRC_LIBS=`$PKG_CONFIG --libs "synthesis >= 3.4.0.47.5" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.47.4" 2>&1`
+ WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "synthesis >= 3.4.0.47.5" 2>&1`
else
- WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.47.4" 2>&1`
+ WITH_SYNTHESIS_SRC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "synthesis >= 3.4.0.47.5" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$WITH_SYNTHESIS_SRC_PKG_ERRORS" >&5
- as_fn_error $? "need at least libsynthesis >= 3.4.0.47.4; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
+ as_fn_error $? "need at least libsynthesis >= 3.4.0.47.5; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- as_fn_error $? "need at least libsynthesis >= 3.4.0.47.4; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
+ as_fn_error $? "need at least libsynthesis >= 3.4.0.47.5; the latest libsynthesis for SyncEvolution is the one from http://cgit.freedesktop.org/SyncEvolution/" "$LINENO" 5
else
WITH_SYNTHESIS_SRC_CFLAGS=$pkg_cv_WITH_SYNTHESIS_SRC_CFLAGS
WITH_SYNTHESIS_SRC_LIBS=$pkg_cv_WITH_SYNTHESIS_SRC_LIBS
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by syncevolution $as_me 1.4.99.4, which was
+This file was extended by syncevolution $as_me 1.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-syncevolution config.status 1.4.99.4
+syncevolution config.status 1.5
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
#
# Starting with the 1.1 release cycle, the rpm-style
# .99 pseudo-version number is used to mark a pre-release.
-AC_INIT([syncevolution], [m4_esyscmd([build/gen-git-version.sh 1.4.99.4])])
+AC_INIT([syncevolution], [m4_esyscmd([build/gen-git-version.sh 1.5])])
# STABLE_VERSION=1.0.1+
AC_SUBST(STABLE_VERSION)
# Minimum version of libsynthesis as defined in its
# configure script and thus .pc files:
-define([SYNTHESIS_MIN_VERSION], [3.4.0.47.4])
+define([SYNTHESIS_MIN_VERSION], [3.4.0.47.5])
# Line above is patched by gen-autotools.sh. Handle
# both "yes" and "no".
// time. Ignore clipped or suspended transfers, they are
// not representative. Also avoid completely bogus
// observations.
- if (!m_wasSuspended &&
+ if (m_pullParams.m_timePerChunk > 0 &&
+ !m_wasSuspended &&
m_transferMaxCount == m_desiredMaxCount &&
m_lastTransferRate > 0 &&
m_lastContactSizeAverage > 0) {
// so we have to use the "steal" variant to enable that assignment.
GVariantStealCXX resultDataVar;
GErrorCXX gerror;
- // Enforce normal reference counting via _ref_sink.
- GVariantCXX sessionDataVar(g_variant_ref_sink(HashTable2Variant(m_sessionData)),
- TRANSFER_REF);
+ GVariantCXX sessionDataVar(HashTable2Variant(m_sessionData));
PlainGStr buffer(g_variant_print(sessionDataVar, true));
SE_LOG_DEBUG(NULL, "asking for OAuth2 token with method %s, mechanism %s and parameters %s",
signon_auth_session_get_method(m_authSession),
// one to use. If it turns out that the two will never be installed at the
// same time, then this perhaps should be "signon" instead, which then would
// pick either a gSSO or UAO backend depending on which is available.
-#if defined(USE_GSSO) || defined(STATIC_GSSO)
+#if defined(USE_ACCOUNTS) && defined(USE_GSSO) || defined(STATIC_GSSO)
IdentityProvider("gsso",
"gsso:<numeric account ID>[,<service name>]\n"
" Authentication using libgsignond + libaccounts,\n"
" using an account created and managed with libaccounts.\n"
" The service name is optional. If not given, the\n"
" settings from the account will be used.")
-#elif defined(USE_UOA) || defined(STATIC_UOA)
+#elif defined(USE_ACCOUNTS) && defined(USE_UOA) || defined(STATIC_UOA)
IdentityProvider("uoa",
"uoa:<numeric account ID>[,<service name>]\n"
" Authentication using libsignon + libaccounts,\n"
namespace {
GMainLoop *loop = NULL;
- bool shutdownRequested = false;
const char * const execName = "syncevo-dbus-server";
-void niam(int sig)
-{
- shutdownRequested = true;
- SuspendFlags::getSuspendFlags().handleSignal(sig);
- g_main_loop_quit (loop);
-}
-
bool parseDuration(int &duration, const char* value)
{
if(value == NULL) {
// process name for developers in this process, and not in
// syncevo-dbus-helper.
Logger::setProcessName("syncevo-dbus-server");
-
- SE_LOG_DEBUG(NULL, "syncevo-dbus-server: catch SIGINT/SIGTERM in our own shutdown function");
- signal(SIGTERM, niam);
- signal(SIGINT, niam);
boost::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
DBusErrorCXX err;
// make this object the main owner of the connection
boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
- boost::shared_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, shutdownRequested, restart, conn, duration));
+ boost::shared_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, restart, conn, duration));
server->setDBusLogLevel(levelDBus);
server->activate();
#endif
server.reset();
obj.reset();
- guard.reset();
SE_LOG_DEBUG(NULL, "flushing D-Bus connection");
conn.flush();
conn.reset();
SE_LOG_INFO(NULL, "terminating, closing logging");
syslogger.reset();
redirect.reset();
+ guard.reset();
SE_LOG_INFO(NULL, "terminating");
return 0;
} catch ( const std::exception &ex ) {
import dbus
import dbus.service
-import gobject
+try:
+ import gobject
+except ImportError:
+ from gi.repository import GObject as gobject
from dbus.mainloop.glib import DBusGMainLoop
import functools
import subprocess
import dbus
import dbus.service
-import gobject
+try:
+ import gobject
+except ImportError:
+ from gi.repository import GObject as gobject
from dbus.mainloop.glib import DBusGMainLoop
import functools
import sys
// Local sync with files on the target side.
// Format is hard-coded to vCard 3.0.
source->setDatabaseID("file://" + address);
- source->setDatabaseFormat("text/vcard");
+ source->setDatabaseFormat("raw/text/vcard");
source->setBackend("file");
}
config->flush();
self.manager.Start()
self.assertEqual("last/first", self.manager.GetSortOrder())
- @timeout(os.environ.get('TESTPIM_TEST_SYNC_TESTCASES', False) and 300000 or 300)
+ @timeout(os.environ.get('TESTPIM_TEST_SYNC_TESTCASES', False) and 300000 or
+ usingValgrind() and 3000 or
+ 300)
@property("snapshot", "simple-sort")
def testSync(self):
'''TestContacts.testSync - test caching of a dummy peer which uses a real phone or a local directory as fallback'''
src_dbus_server_service_files_in += \
src/dbus/server/pim/org._01.pim.contacts.service.in
+test_SCRIPTS += \
+ src/dbus/server/pim/examples/search.py \
+ src/dbus/server/pim/examples/sync.py \
+ $(NOP)
+
if ENABLE_TESTING
test_SCRIPTS += \
src/dbus/server/pim/testpim.py \
}
Server::Server(GMainLoop *loop,
- bool &shutdownRequested,
boost::shared_ptr<Restart> &restart,
const DBusConnectionPtr &conn,
int duration) :
SessionCommon::SERVER_IFACE,
boost::bind(&Server::autoTermCallback, this)),
m_loop(loop),
- m_shutdownRequested(shutdownRequested),
+ m_suspendFlagsSource(0),
+ m_shutdownRequested(false),
m_restart(restart),
m_conn(conn),
m_lastSession(time(NULL)),
m_configChangedSignal.connect(boost::bind(boost::ref(configChanged)));
}
+gboolean Server::onSuspendFlagsChange(GIOChannel *source,
+ GIOCondition condition,
+ gpointer data) throw ()
+{
+ Server *me = static_cast<Server *>(data);
+ try {
+ if (!SuspendFlags::getSuspendFlags().isNormal()) {
+ me->m_shutdownRequested = true;
+ g_main_loop_quit(me->m_loop);
+ SE_LOG_INFO(NULL, "server shutting down because of SIGINT or SIGTERM");
+ }
+ } catch (...) {
+ Exception::handle();
+ }
+ // Keep watching, just in case that we catch multiple signals.
+ return TRUE;
+}
+
void Server::activate()
{
+ // Watch SuspendFlags fd to react to signals quickly.
+ int fd = SuspendFlags::getSuspendFlags().getEventFD();
+ GIOChannelCXX channel(g_io_channel_unix_new(fd), TRANSFER_REF);
+ m_suspendFlagsSource = g_io_add_watch(channel, G_IO_IN, onSuspendFlagsChange, this);
+
// Activate our D-Bus object *before* interacting with D-Bus
// any further. Otherwise GIO D-Bus will start processing
// messages for us while we start up and reject them because
Server::~Server()
{
// make sure all other objects are gone before destructing ourselves
+ if (m_suspendFlagsSource) {
+ g_source_remove(m_suspendFlagsSource);
+ }
m_syncSession.reset();
m_workQueue.clear();
m_clients.clear();
class Server : public GDBusCXX::DBusObjectHelper
{
GMainLoop *m_loop;
- bool &m_shutdownRequested;
+ guint m_suspendFlagsSource;
+ bool m_shutdownRequested;
Timespec m_lastFileMod;
boost::shared_ptr<SyncEvo::Restart> &m_restart;
GDBusCXX::DBusConnectionPtr m_conn;
/** hooked into m_idleSignal, controls auto-termination */
void onIdleChange(bool idle);
+ /** hooked up to SuspendFlags fd via g_io_add_watch */
+ static gboolean onSuspendFlagsChange(GIOChannel *source,
+ GIOCondition condition,
+ gpointer data) throw ();
+
public:
Server(GMainLoop *loop,
- bool &shutdownRequested,
boost::shared_ptr<Restart> &restart,
const GDBusCXX::DBusConnectionPtr &conn,
int duration);
SE_GLIB_TYPE(GMainLoop, g_main_loop)
SE_GLIB_TYPE(GAsyncQueue, g_async_queue)
SE_GLIB_TYPE(GHashTable, g_hash_table)
+SE_GLIB_TYPE(GIOChannel, g_io_channel)
SE_BEGIN_CXX
while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&value)) {
g_variant_builder_add(&builder, "{sv}", key, g_variant_ref(value));
}
- GVariantStealCXX variant(g_variant_builder_end(&builder));
+ GVariantStealCXX variant(g_variant_ref_sink(g_variant_builder_end(&builder)));
return variant;
}
substTag(xml, "maxobjsize", getMaxObjSize().get());
if (m_serverMode) {
UserIdentity id = getSyncUser();
- Credentials cred = IdentityProviderCredentials(id, getSyncPassword());
- const string &user = cred.m_username;
- const string &password = cred.m_password;
/*
* Do not check username/pwd if this local sync or over
- * bluetooth transport. Need credentials for checking.
+ * bluetooth transport. Need credentials for checking,
+ * and IdentityProviderCredentials() throws an error when
+ * called for a provider which does not support plain
+ * credentials.
*/
- if (!m_localSync &&
- !boost::starts_with(getUsedSyncURL(), "obex-bt") &&
- (!user.empty() || !password.empty())) {
+ bool withauth = !m_localSync && !boost::starts_with(getUsedSyncURL(), "obex-bt");
+ if (withauth) {
+ Credentials cred = IdentityProviderCredentials(id, getSyncPassword());
+ const string &user = cred.m_username;
+ const string &password = cred.m_password;
+
+ if (user.empty() && password.empty()) {
+ withauth = false;
+ }
+ }
+
+ if (withauth) {
// require authentication with the configured password
substTag(xml, "defaultauth",
"<requestedauth>md5</requestedauth>\n"
"<autononce>yes</autononce>\n",
true);
} else {
+ if (id.wasSet()) {
+ SE_LOG_WARNING(getConfigName(), "ignoring username %s, it is not needed",
+ id.toString().c_str());
+ }
+
// no authentication required
substTag(xml, "defaultauth",
"<logininitscript>return TRUE</logininitscript>\n"
--- /dev/null
+<!-- disable endless loop prevention, shouldn't be needed and may abort prematurely -->
+<looptimeout>0</looptimeout>
winningchanged = 0;
loosingchanged = 0;
+ STRING ignorefields;
+ ignorefields = "";
+
if (SESSIONVAR("keepPhotoData") &&
WINNING.PHOTO == EMPTY &&
LOOSING.PHOTO != EMPTY) {
LOOSING.PHOTO = EMPTY;
}
+ // In cache mode, we don't care about the order of entries, so
+ // we do our own relaxed comparison and tell the engine to ignore
+ // fields if the only change is in the ordering.
+ if (CACHEDATA()) {
+ ignorefields = ignorefields + RELAXEDCOMPARE("TEL", "", "TEL_FLAGS", "TEL_SLOT", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("XDATE", "", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("EMAIL", "", "EMAIL_FLAGS", "EMAIL_SLOT", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("WEB", "", "WEB_FLAGS", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("CALURI");
+ ignorefields = ignorefields + RELAXEDCOMPARE("FBURL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("BLOGURL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("VIDEOURL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("RELATEDNAMES", "", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("IMPP", "", "IMPP_SERVICE", "IMPP_SLOT", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("AIM_HANDLE", "", "AIM_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("GADUGADU_HANDLE", "", "GADUGADU_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("GROUPWISE_HANDLE", "", "GROUPWISE_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("ICQ_HANDLE", "", "ICQ_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("JABBER_HANDLE", "", "JABBER_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("MSN_HANDLE", "", "MSN_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("YAHOO_HANDLE", "", "YAHOO_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("SKYPE_HANDLE", "", "SKYPE_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("SIP_HANDLE", "", "SIP_SLOT");
+ ignorefields = ignorefields + RELAXEDCOMPARE("EMAIL", "", "EMAIL_FLAGS", "EMAIL_SLOT", "LABEL");
+ ignorefields = ignorefields + RELAXEDCOMPARE("ADR", "ADR_STREET", "ADR_ADDTL", "ADR_STREET_FLAGS", "ADR_POBOX", "ADR_CITY", "ADR_REG", "ADR_ZIP", "ADR_COUNTRY", "", "LABEL");
+
+ // Always ignore the label. Otherwise reordering will cause unnecessary
+ // writes. We check for reordering more selectively above, but because
+ // the LABEL field is shared, we cannot do the same for it.
+ // The downside is that changes in just the label of an entry will not
+ // cause an update of the cache. Some other value must be modified, too,
+ // to trigger a write.
+ ignorefields = ignorefields + " LABEL";
+ }
+
// When running in caching mode, we end up executing the merge script,
// but in that case we want to remove data from the loosing item and
// thus need to skip the array merging.
i = i - 1;
}
- i = SIZE(LOOSING.WEB) - 1;
- while (i >= 0) {
- val = LOOSING.WEB[i];
- if (val != EMPTY &&
- !CONTAINS(WINNING.WEB, val)) {
- num = SIZE(WINNING.LABEL);
- WINNING.WEB[num] = val;
- WINNING.WEB_FLAGS[num] = LOOSING.WEB_FLAGS[i];
- WINNING.LABEL[num] = LOOSING.LABEL[i];
- winningchanged = 1;
- }
- i = i - 1;
- }
-
- i = SIZE(LOOSING.WEB) - 1;
- while (i >= 0) {
- val = LOOSING.WEB[i];
- if (val != EMPTY &&
- !CONTAINS(WINNING.WEB, val)) {
- num = SIZE(WINNING.LABEL);
- WINNING.WEB[num] = val;
- WINNING.WEB_FLAGS[num] = LOOSING.WEB_FLAGS[i];
- WINNING.LABEL[num] = LOOSING.LABEL[i];
- winningchanged = 1;
- }
- i = i - 1;
- }
-
i = SIZE(LOOSING.CALURI) - 1;
while (i >= 0) {
val = LOOSING.CALURI[i];
i = i - 1;
}
- i = SIZE(LOOSING.CALURI) - 1;
- while (i >= 0) {
- val = LOOSING.CALURI[i];
- if (val != EMPTY &&
- !CONTAINS(WINNING.CALURI, val)) {
- num = SIZE(WINNING.CALURI);
- WINNING.CALURI[num] = val;
- winningchanged = 1;
- }
- i = i - 1;
- }
-
i = SIZE(LOOSING.RELATEDNAMES) - 1;
while (i >= 0) {
val = LOOSING.RELATEDNAMES[i];
if (loosingchanged) { SETLOOSINGCHANGED(1); }
// Continue merge.
- MERGEFIELDS(mode);
+ MERGEFIELDS(mode, ignorefields);
]]></macro>
+++ /dev/null
- <looptimeout>5</looptimeout>
-
# Generated by configure. Do not edit.
-# git revision 3b70881c62ee1909781dec57ac7dad781a0379fd
-# git tag libsynthesis_3.4.0.47+syncevolution-1-4-99-4
+# git revision f9202de6af47a44a227106e7a76f46cdeb1a6d53
+# git tag libsynthesis_3.4.0.47+syncevolution-1-5
+
+2014-10-30 Patrick Ohly <patrick.ohly@intel.com>
+
+ * configure.in:
+
+ autotools: bump Linux/SyncEvolution sub-version for
+ RELAXEDCOMPARE()
+
+2014-10-17 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/sysync/multifielditemtype.cpp:
+
+ merge script: check order of entries in RELAXEDCOMPARE()
+
+2014-10-09 Patrick Ohly <patrick.ohly@intel.com>
+
+ * src/sysync/multifielditem.cpp:
+ * src/sysync/multifielditem.h:
+ * src/sysync/multifielditemtype.cpp:
+
+ merge scripts: new RELAXEDCOMPARE(), enhanced MERGEFIELDS()
2014-09-10 Patrick Ohly <patrick.ohly@intel.com>
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for synthesis 3.4.0.47.4.
+# Generated by GNU Autoconf 2.65 for synthesis 3.4.0.47.5.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# Identity of this package.
PACKAGE_NAME='synthesis'
PACKAGE_TARNAME='synthesis'
-PACKAGE_VERSION='3.4.0.47.4'
-PACKAGE_STRING='synthesis 3.4.0.47.4'
+PACKAGE_VERSION='3.4.0.47.5'
+PACKAGE_STRING='synthesis 3.4.0.47.5'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures synthesis 3.4.0.47.4 to adapt to many kinds of systems.
+\`configure' configures synthesis 3.4.0.47.5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of synthesis 3.4.0.47.4:";;
+ short | recursive ) echo "Configuration of synthesis 3.4.0.47.5:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-synthesis configure 3.4.0.47.4
+synthesis configure 3.4.0.47.5
generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by synthesis $as_me 3.4.0.47.4, which was
+It was created by synthesis $as_me 3.4.0.47.5, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='synthesis'
- VERSION='3.4.0.47.4'
+ VERSION='3.4.0.47.5'
cat >>confdefs.h <<_ACEOF
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by synthesis $as_me 3.4.0.47.4, which was
+This file was extended by synthesis $as_me 3.4.0.47.5, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-synthesis config.status 3.4.0.47.4
+synthesis config.status 3.4.0.47.5
configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
# four digit upstream version, one additional digit for
# Linux/SyncEvolution specific extensions:
-AC_INIT([synthesis], [3.4.0.47.4])
+AC_INIT([synthesis], [3.4.0.47.5])
AM_INIT_AUTOMAKE(subdir-objects)
AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER(config.h)
// returns update status of this and other item. Note that changes of non-relevant fields are
// not reported here.
void TMultiFieldItem::standardMergeWith(TMultiFieldItem &aItem, bool &aChangedThis, bool &aChangedOther,
- int mode)
+ int mode,
+ const std::set<std::string> &aIgnoreFields)
{
// same type of multifield, try to merge
for (sInt16 i=0; i<fFieldDefinitionsP->numFields(); i++) {
+ // Ignore fields if told so by optional MERGEFIELDS() parameter.
+ if (aIgnoreFields.find(fFieldDefinitionsP->fFields[i].fieldname) != aIgnoreFields.end()) {
+ continue;
+ }
// get merge mode
sInt16 sep=fFieldDefinitionsP->fFields[i].mergeMode;
// possible merging is only relevant (=to be reported) for fields that are not eqm_none
#include "configelement.h"
#include "syncappbase.h"
-
+#include <set>
using namespace sysync;
// Note that changes of non-relevant fields are not reported here.
virtual void mergeWith(TSyncItem &aItem, bool &aChangedThis, bool &aChangedOther, TLocalEngineDS *aDatastoreP, int mode = MERGE_OPTION_FROM_CONFIG);
// standard merge (subset of mergeWith, used if no merge script is defined)
- void standardMergeWith(TMultiFieldItem &aItem, bool &aChangedThis, bool &aChangedOther, int mode = MERGE_OPTION_FROM_CONFIG);
+ void standardMergeWith(TMultiFieldItem &aItem, bool &aChangedThis, bool &aChangedOther, int mode = MERGE_OPTION_FROM_CONFIG, const std::set<std::string> &aIgnoreFields = std::set<std::string>());
// compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem
// SYSYNC_NOT_COMPARABLE if not equal and no ordering known
virtual sInt16 compareWith(
}; // func_IgnoreUpdate
- // void MERGEFIELDS(mode = 0)
+ // void MERGEFIELDS(mode = 0, ignoreFields = "")
// Optional mode parameter determines the result of the merge.
// 0 = according to config, 1 = loosing item is overwritten, 2 = winning item is overwritten
+ // Any field names in the space separated ignoreFields parameter will be skipped.
+ // The assumption is that the calling script has already dealt with these fields.
static void func_MergeFields(TItemField *&aTermP, TScriptContext *aFuncContextP)
{
TMultiFieldItemType *mfitP = static_cast<TMultiFieldItemType *>(aFuncContextP->getCallerContext());
if (mfitP->fFirstItemP) {
TItemField *argP = aFuncContextP->getLocalVar(0);
+ int mode = (argP && argP->isAssigned()) ? argP->getAsInteger() : 0;
+ // Split optional string into set of field names.
+ argP = aFuncContextP->getLocalVar(1);
+ std::string fields;
+ if (argP && argP->isAssigned()) {
+ argP->getAsString(fields);
+ }
+ std::set<std::string> ignoreFields;
+ size_t offset = 0;
+ while (offset < fields.size()) {
+ while (offset < fields.size() && isspace(fields[offset])) offset++;
+ size_t start = offset;
+ while (offset < fields.size() && !isspace(fields[offset])) offset++;
+ size_t len = offset - start;
+ if (len)
+ ignoreFields.insert(fields.substr(start, len));
+ }
mfitP->fFirstItemP->standardMergeWith(*(mfitP->fSecondItemP),mfitP->fChangedFirst,mfitP->fChangedSecond,
- (argP && argP->isAssigned()) ? argP->getAsInteger() : 0);
+ mode, ignoreFields);
}
}; // func_MergeFields
+ enum ArrayEntriesState {
+ ALL_UNSET, // All arrays have no entries at the array index -> past end of valid entries.
+ ALL_EMPTY, // Some entries exist, but all of those are empty.
+ NON_EMPTY // Some entry is non-empty.
+ };
+ static ArrayEntriesState checkArrayEntries(sInt16 arridx, TMultiFieldItem &aItem, const std::vector<sInt16> &aFields)
+ {
+ ArrayEntriesState state = ALL_UNSET;
+ for (size_t i = 0; state != NON_EMPTY && i < aFields.size() && aFields[i] >= 0; i++) {
+ TItemField *elemP = aItem.getArrayField(aFields[i],arridx,true);
+ if (elemP && state == ALL_UNSET) {
+ state = elemP->isEmpty() ? ALL_EMPTY : NON_EMPTY;
+ }
+ }
+ return state;
+ }
+
+ // Increments arridx until it runs into ALL_UNSET or NON_EMPTY.
+ static ArrayEntriesState nextArrayEntries(sInt16 &arridx, TMultiFieldItem &aItem, const std::vector<sInt16> &aFields)
+ {
+ while (true) {
+ ++arridx;
+ ArrayEntriesState state = checkArrayEntries(arridx, aItem, aFields);
+ switch (state) {
+ case ALL_UNSET:
+ case NON_EMPTY:
+ return state;
+ case ALL_EMPTY:
+ break;
+ }
+ }
+ }
+
+ // string RELAXEDCOMPARE(mainfield1, mainfield2, mainfield3, "", addfield1, addfield2, ...)
+ // Returns "" if a relaxed comparison of the given fields in the winning and loosing
+ // item finds no differences and string with all given field names concatenated together
+ // with space at the beginning and and the end.
+ //
+ // The intended usage is:
+ // ignorefields = ignorefields + RELAXEDCOMPARE("TEL", "", "TEL_FLAGS", "LABEL");
+ // ignorefields = ignorefields + RELAXEDCOMPARE("ADR", "ADR_STREET", "ADR_CITY", "", "LABEL");
+ // MERGEFIELDS(mode, ignorefields);
+ //
+ // All fields must be arrays. Only entries with non-empty main fields are considered.
+ // However, if the main fields are non-empty, the additional ones must also match.
+ // The order of entries in loosing and winning item *does* matter, a difference
+ // is only reported if an entry has no exact match in the other item.
+ static void func_RelaxedCompare(TItemField *&aTermP, TScriptContext *aFuncContextP)
+ {
+ TMultiFieldItemType *mfitP = static_cast<TMultiFieldItemType *>(aFuncContextP->getCallerContext());
+ bool difference = false;
+ std::string fieldnames;
+ if (mfitP->fFirstItemP && mfitP->fSecondItemP) {
+ // Determine field index of the fields we need to compare.
+ std::vector<sInt16> fields;
+ TFieldListConfig *fieldlist = mfitP->fFirstItemP->getFieldDefinitions();
+ for (int i = 0; ; i++) {
+ TItemField *argP = aFuncContextP->getLocalVar(i);
+ if (!argP || !argP->isAssigned()) {
+ break;
+ }
+ std::string fieldname;
+ argP->getAsString(fieldname);
+ if (fieldname.empty()) {
+ // Separator between main and additional fields.
+ fields.push_back(-1);
+ } else {
+ for (sInt16 e=0; e<fieldlist->numFields(); e++) {
+ if (fieldlist->fFields[e].fieldname == fieldname) {
+ fieldnames.append(" ");
+ fieldnames.append(fieldname);
+ fields.push_back(e);
+ break;
+ }
+ }
+ // TODO (?): error for unknown field
+ }
+ }
+
+ if (!fields.empty()) {
+ // Walk through both array sets in parallel. Skip empty
+ // entries and compare non-empty ones.
+ sInt16 firstArrIdx = -1;
+ ArrayEntriesState firstState = nextArrayEntries(firstArrIdx, *mfitP->fFirstItemP, fields);
+ sInt16 secondArrIdx = -1;
+ ArrayEntriesState secondState = nextArrayEntries(secondArrIdx, *mfitP->fSecondItemP, fields);
+
+ while (firstState == NON_EMPTY &&
+ secondState == NON_EMPTY) {
+ // Compare entries.
+ for (size_t i=0; i<fields.size(); i++) {
+ sInt16 fid = fields[i];
+ if (fid == -1) {
+ continue;
+ }
+ TItemField *firstP = mfitP->fFirstItemP->getArrayField(fid, firstArrIdx, true);
+ TItemField *secondP = mfitP->fSecondItemP->getArrayField(fid, secondArrIdx, true);
+ if (firstP && secondP) {
+ if (firstP->isAssigned() != secondP->isAssigned() ||
+ *firstP != *secondP) {
+ difference = true;
+ break;
+ }
+ } else if ((firstP && firstP->isAssigned()) ||
+ (secondP && secondP->isAssigned())) {
+ difference = true;
+ break;
+ }
+ }
+ firstState = nextArrayEntries(firstArrIdx, *mfitP->fFirstItemP, fields);
+ secondState = nextArrayEntries(secondArrIdx, *mfitP->fSecondItemP, fields);
+ }
+
+ if (firstState != secondState) {
+ // One side has data that the other hasn't.
+ difference = true;
+ }
+ } else {
+ // TODO (?): error if no fields specified.
+ }
+ } else {
+ difference = true;
+ }
+
+ aTermP->setAsString(difference ? "" : fieldnames);
+ }; // func_RelaxedCompare
// integer WINNINGCHANGED()
// returns true if winning was changed
const uInt8 param_StrArg[] = { VAL(fty_string) };
const uInt8 param_IntArg[] = { VAL(fty_integer) };
+const uInt8 param_RelaxedCompare[] = { OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string), OPTVAL(fty_string),};
+const uInt8 param_MergeFields[] = { OPTVAL(fty_integer), OPTVAL(fty_string) };
// builtin functions for datastore-context table
const TBuiltInFuncDef DataTypeFuncDefs[] = {
{ "DELETEWINS", TMFTypeFuncs::func_DeleteWins, fty_none, 0, NULL },
{ "PREVENTADD", TMFTypeFuncs::func_PreventAdd, fty_none, 0, NULL },
{ "IGNOREUPDATE", TMFTypeFuncs::func_IgnoreUpdate, fty_none, 0, NULL },
- { "MERGEFIELDS", TMFTypeFuncs::func_MergeFields, fty_none, 1, param_oneOptInteger },
+ { "MERGEFIELDS", TMFTypeFuncs::func_MergeFields, fty_none, sizeof(param_MergeFields)/sizeof(param_MergeFields[0]), param_MergeFields },
+ { "RELAXEDCOMPARE", TMFTypeFuncs::func_RelaxedCompare, fty_string, sizeof(param_RelaxedCompare)/sizeof(param_RelaxedCompare[0]), param_RelaxedCompare },
{ "WINNINGCHANGED", TMFTypeFuncs::func_WinningChanged, fty_integer, 0, NULL },
{ "LOOSINGCHANGED", TMFTypeFuncs::func_LoosingChanged, fty_integer, 0, NULL },
{ "SETWINNINGCHANGED", TMFTypeFuncs::func_SetWinningChanged, fty_none, 1, param_IntArg },
--- /dev/null
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user17\r
+NICKNAME:user17\r
+NOTE:triggers parser bug in Funambol 3.0: trailing = is mistaken for soft line break=\r
+FN:parserbug=\r
+N:parserbug=;;;;\r
+X-EVOLUTION-FILE-AS:parserbug=\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user16\r
+NICKNAME:user16\r
+NOTE:test case with empty email\r
+FN:incomplete\r
+N:incomplete;;;;\r
+EMAIL:\r
+X-EVOLUTION-FILE-AS:incomplete\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user11\r
+NICKNAME:user11\r
+NOTE:This is a long line without any special characters. This is a simpler \r
+ example that should require folding in vcards. Does folding insert a crlf\r
+ before a space or does it insert crlf _plus_ a space? vCard 2.1 inserts \r
+ before a space\, 3.0 inserts line break plus space.\r
+FN:long line\r
+N:line;long;;;\r
+X-EVOLUTION-FILE-AS:line\, long\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user13\r
+NICKNAME:user13\r
+NOTE:a colon is not a special character so here it comes : and not quoting necessary\r
+FN:colon\r
+N:colon;unquoted;;;\r
+X-EVOLUTION-FILE-AS:colon\, unquoted\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user14\r
+NICKNAME:user14\r
+NOTE:here are some quotation marks: single ' double " back ` - none of them is special\r
+FN:quotation marks\r
+N:marks;quotation;;;\r
+X-EVOLUTION-FILE-AS:marks\, quotation\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user15\r
+NICKNAME:user15\r
+NOTE:Spouse's Name: foobar\r
+FN:spouse name\r
+N:name;spouse;;;\r
+X-EVOLUTION-FILE-AS:spouse\, name\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user9\r
+NICKNAME:user9\r
+NOTE;CHARSET="UTF-8":Tests charset specification with quotation marks.\r
+FN:charset\r
+N:set;char;;;\r
+X-EVOLUTION-FILE-AS:set\, char\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+URL:\r
+TITLE:\r
+ROLE:\r
+X-EVOLUTION-MANAGER:\r
+X-EVOLUTION-ASSISTANT:\r
+UID:unique-id-user7\r
+NICKNAME:user7\r
+X-EVOLUTION-SPOUSE:\r
+NOTE:This test case uses line breaks. This is line 1.\nLine 2.\n\nLine brea\r
+ ks in vcard 2.1 are encoded as =0D=0A.\nThat means the = has to be encod\r
+ ed itself...\r
+FN:line breaks\r
+N:breaks;line;;;\r
+X-EVOLUTION-FILE-AS:breaks\, line\r
+X-EVOLUTION-BLOG-URL:\r
+CALURI:\r
+FBURL:\r
+X-EVOLUTION-VIDEO-URL:\r
+X-MOZILLA-HTML:FALSE\r
+ADR;TYPE=HOME:;Address Line 2\nAddress Line 3;Address Line 1;;;;\r
+LABEL;TYPE=HOME:Address Line 1\nAddress Line 2\nAddress Line 3\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+URL:http://john.doe.com\r
+TITLE:Senior Tester\r
+ORG:Test Inc.;Testing;test#1\r
+ROLE:professional test case\r
+X-EVOLUTION-MANAGER:John Doe Senior\r
+X-EVOLUTION-ASSISTANT:John Doe Junior\r
+UID:unique-id-user1\r
+NICKNAME:user1\r
+BDAY:2006-01-08\r
+X-EVOLUTION-ANNIVERSARY:2006-01-09\r
+X-EVOLUTION-SPOUSE:Joan Doe\r
+NOTE:This is a test case which uses almost all Evolution fields.\r
+FN:John Doe\r
+N:Doe;John;;;\r
+X-EVOLUTION-FILE-AS:Doe\, John\r
+CATEGORIES:TEST\r
+X-EVOLUTION-BLOG-URL:web log\r
+GEO:30.12;-130.34\r
+X-EVOLUTION-VIDEO-URL:chat\r
+X-MOZILLA-HTML:TRUE\r
+ADR;TYPE=WORK:Test Box #2;;Test Drive 2;Test Town;Upper Test County;12346;O\r
+ ld Testovia\r
+LABEL;TYPE=WORK:Test Drive 2\nTest Town\, Upper Test County\n12346\nTest Bo\r
+ x #2\nOld Testovia\r
+ADR;TYPE=HOME:Test Box #1;;Test Drive 1;Test Village;Lower Test County;1234\r
+ 5;Testovia\r
+LABEL;TYPE=HOME:Test Drive 1\nTest Village\, Lower Test County\n12345\nTest\r
+ Box #1\nTestovia\r
+ADR:Test Box #3;;Test Drive 3;Test Megacity;Test County;12347;New Testonia\r
+LABEL;TYPE=OTHER:Test Drive 3\nTest Megacity\, Test County\n12347\nTest Box\r
+ #3\nNew Testonia\r
+EMAIL:john.doe@work.com\r
+EMAIL:john.doe@home.priv\r
+EMAIL:john.doe@other.world\r
+EMAIL:john.doe@yet.another.world\r
+TEL;TYPE=work;TYPE=Voice;X-EVOLUTION-UI-SLOT=1:business 1\r
+TEL;TYPE=homE;TYPE=VOICE;X-EVOLUTION-UI-SLOT=2:home 2\r
+TEL;TYPE=CELL;X-EVOLUTION-UI-SLOT=3:mobile 3\r
+TEL;TYPE=WORK;TYPE=FAX;X-EVOLUTION-UI-SLOT=4:businessfax 4\r
+TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5\r
+TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6\r
+TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7\r
+TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8\r
+X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN\r
+X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE\r
+X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD\r
+X-GROUPWISE;X-EVOLUTION-UI-SLOT=4:GROUPWISE DOE\r
+X-GADUGADU:GADUGADU DOE\r
+X-JABBER:JABBER DOE\r
+X-MSN:MSN DOE\r
+X-SKYPE:SKYPE DOE\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+URL:\r
+TITLE:\r
+ROLE:\r
+X-EVOLUTION-MANAGER:\r
+X-EVOLUTION-ASSISTANT:\r
+UID:unique-id-user5\r
+NICKNAME:user5\r
+X-EVOLUTION-SPOUSE:\r
+NOTE:image in JPG format\r
+FN:Ms. JPG\r
+N:;JPG;;Ms.;\r
+X-EVOLUTION-FILE-AS:JPG\r
+X-EVOLUTION-BLOG-URL:\r
+CALURI:\r
+FBURL:\r
+X-EVOLUTION-VIDEO-URL:\r
+X-MOZILLA-HTML:FALSE\r
+PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAA\r
+ AAgAAAAAAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcM\r
+ CAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEF\r
+ BQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e\r
+ Hh4eHh4eHh4e/8AAEQgAFwAkAwEiAAIRAQMRAf/EABkAAQADAQEAAAAAAAAAAAAAAAAGBwgE\r
+ Bf/EADIQAAECBQMCAwQLAAAAAAAAAAECBAADBQYRBxIhEzEUFSIIFjNBGCRHUVZ3lqXD0+P/\r
+ xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR\r
+ AD8AuX6UehP45/aXv9MTPTLVKxNSvMPcqu+a+XdLxf1SfJ6fU37PioTnOxfbOMc/KIZ7U/2V\r
+ fmTR/wCaKlu6+blu/Ui72zxWtUmmUOrTaWwkWDT09FPR4K587OVrUfVsIwElPPPAbAjxr2um\r
+ hWXbDu5rmfeApLPZ4hx0lzNm9aUJ9KAVHKlJHAPf7ozPLqWt9y6Z0EPGmoLNjTq48a1iaybJ\r
+ YV52yEtCms5KJmAT61JXtJyUdyQTEc1WlMql7N1/oZ6jagVZVFfUyZPpFy5lvWcxU7Z03BUk\r
+ GZLWJqVhPYLkIIPBEBtSEUyNAsjI1q1m/VP+UICwL/sqlXp7v+aOHsnyGttq218MtKd8+Ru2\r
+ JXuScoO45Awe2CIi96aKW1cVyubkYVy6rTqz0J8a5t2qqZl0UjAMwYKScfPAJ+cIQHHP0Dth\r
+ VFaMWt0XwxetnM50Ks2rsxL6ZMnJlJmb5hBBBEiVxjA28dznqo+hdksbQuS3Hs6tVtNzdM1Z\r
+ /VH5nO3Bl/CJmYHKDynjv3zCEB5rLQNo0bIbydWNWxKljbLQLoWkISOAkBKAABCEID//2Q==\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+URL:\r
+TITLE:\r
+ROLE:\r
+X-EVOLUTION-MANAGER:\r
+X-EVOLUTION-ASSISTANT:\r
+UID:unique-id-user4\r
+NICKNAME:user4\r
+X-EVOLUTION-SPOUSE:\r
+NOTE:image in PNG format\r
+FN:Mrs. PNG\r
+N:;PNG;;Mrs.;\r
+X-EVOLUTION-FILE-AS:PNG\r
+X-EVOLUTION-BLOG-URL:\r
+CALURI:\r
+FBURL:\r
+X-EVOLUTION-VIDEO-URL:\r
+X-MOZILLA-HTML:FALSE\r
+PHOTO;ENCODING=b;TYPE=PNG:iVBORw0KGgoAAAANSUhEUgAAACQAAAAXCAYAAABj7u2bAAAAB\r
+ mJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gEICjgdiWkBO\r
+ QAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu\r
+ 0tcURAG8F98gRKTYGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWP\r
+ sAU6wPxHW6aWbgsu+ve3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6TH\r
+ lejbWSt0Bv8QBXX2MF7jKU4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkF\r
+ jQX9g5e4ykGUcBm+FaDexx2MUQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOc\r
+ BHcEv7FvyN8xxqmeynovA1Baf4UVvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdN\r
+ owXWEQlOBXMYyI4j3EavqFUzpOYl4OTqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV\r
+ 8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6Bb/Ae0cnahfg6KuAAAAAElFTkSuQmCC\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+URL:\r
+TITLE:\r
+ROLE:\r
+X-EVOLUTION-MANAGER:\r
+X-EVOLUTION-ASSISTANT:\r
+UID:unique-id-user3\r
+NICKNAME:user3\r
+X-EVOLUTION-SPOUSE:\r
+NOTE:image in GIF format\r
+FN:Mr. GIF\r
+N:;GIF;;Mr.;\r
+X-EVOLUTION-FILE-AS:GIF\r
+X-EVOLUTION-BLOG-URL:\r
+CALURI:\r
+FBURL:\r
+X-EVOLUTION-VIDEO-URL:\r
+X-MOZILLA-HTML:FALSE\r
+PHOTO;ENCODING=b;TYPE=GIF:R0lGODlhJAAXAIABAAAAAP///yH+FUNyZWF0ZWQgd2l0aCBUa\r
+ GUgR0lNUAAh+QQBCgABACwAAAAAJAAXAAACVYyPqcvtD6OctNqLFdi8b/sd3giAJRNmqXaKH\r
+ TIaZJKSpx3McLtyeSuTAWm34e+4WBGFuJ/P1QjZek9ksjiRGqFCTW5pZblmzdiO+GJWncqM+\r
+ w2PwwsAOw==\r
+END:VCARD\r
+\r
+BEGIN:VCARD\r
+VERSION:3.0\r
+UID:unique-id-user10\r
+NICKNAME:user10\r
+X-EVOLUTION-SPOUSE:\r
+NOTE:large vcard with plenty of special chars < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+ & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & < & <\r
+FN:large vcard\r
+N:;vcard;;large;\r
+X-EVOLUTION-FILE-AS:large\r
+END:VCARD\r
CT_ASSERT_NO_THROW(deleteAll());
accessClientB->deleteAll();
+ bool allowLocalUpdate = getenv("CLIENT_TEST_MAY_COPY_BACK") != NULL;
+
// insert into first database, copy to server
CT_ASSERT_NO_THROW(allSourcesInsert());
doSync(__FILE__, __LINE__,
"send",
SyncOptions(SYNC_TWO_WAY,
- CheckSyncReport(0,0,0, 1,0,0, true, SYNC_TWO_WAY)));
+ CheckSyncReport(0, allowLocalUpdate? -1 : 0, 0, 1,0,0, true, SYNC_TWO_WAY)));
// copy into second database
accessClientB->doSync(__FILE__, __LINE__,
close(fd);
if (!skipped) {
CT_ASSERT_EQUAL(STATUS_TRANSPORT_FAILURE, report.getStatus());
- CT_ASSERT(end - start >= 19);
- CT_ASSERT(end - start < 40); // needs to be sufficiently larger than 20s timeout
- // because under valgrind the startup time is considerable
+ std::string delta = StringPrintf("%lds", (long)(end - start));
+ CT_ASSERT_MESSAGE(delta, end - start >= 19);
+ // needs to be sufficiently larger than 20s timeout
+ // because under valgrind the startup time is considerable
+ CT_ASSERT_MESSAGE(delta, end - start < 50);
}
}
#include <signal.h>
#ifdef HAVE_VALGRIND_VALGRIND_H
# include <valgrind/valgrind.h>
+# include <valgrind/memcheck.h>
#endif
#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <fcntl.h>
#include <string>
ClientOutputter(CppUnit::TestResultCollector *result, std::ostream &stream) :
CompilerOutputter(result, stream) {}
void write() {
- CompilerOutputter::write();
+ // Suppress writing useless test summary. We run only one test per process,
+ // so this Outputter would not show the overall results.
+ // CompilerOutputter::write();
}
};
}
}
+static void addEnabledTests(CppUnit::Test *test, bool parentEnabled,
+ char **beginEnabled, char **endEnabled,
+ std::list<std::string> &result)
+{
+ if (!test) {
+ return;
+ }
+
+ std::string name = test->getName();
+ bool enabled = false;
+ if (parentEnabled) {
+ enabled = true;
+ } else {
+ for (char **selected = beginEnabled;
+ selected < endEnabled;
+ selected++) {
+ if (name == *selected) {
+ enabled = true;
+ break;
+ }
+ }
+ }
+
+ if (dynamic_cast<CppUnit::TestLeaf *>(test)) {
+ if (enabled) {
+ result.push_back(name);
+ }
+ } else {
+ for (int i = 0; i < test->getChildTestCount(); i++) {
+ addEnabledTests(test->getChildTestAt(i), enabled,
+ beginEnabled, endEnabled,
+ result);
+ }
+ }
+}
+
static void handler(int sig)
{
void *buffer[100];
int size;
- fprintf(stderr, "\ncaught signal %d\n", sig);
+ fprintf(stderr, "client-test %ld: \ncaught signal %d\n", (long)getpid(), sig);
fflush(stderr);
#ifdef HAVE_EXECINFO_H
size = backtrace(buffer, sizeof(buffer)/sizeof(buffer[0]));
}
try {
- // Run the tests.
+ // Find all enabled tests.
+ std::list<std::string> tests;
if (argc <= 1) {
- // all tests
- runner.run("", false, true, false);
+ // All tests.
+ addEnabledTests(suite, true, NULL, NULL, tests);
} else {
- // run selected tests individually
- for (int test = 1; test < argc; test++) {
- runner.run(argv[test], false, true, false);
+ // Some selected tests.
+ addEnabledTests(suite, false, argv + 1, argv + argc, tests);
+ }
+
+ bool failed = false;
+ if (tests.size() == 1) {
+ // If one test, run it ourselves.
+ runner.run(tests.front(), false, true, false);
+ failed = syncListener.hasFailed();
+ } else {
+ // Otherwise act as test runner which invokes itself
+ // recursively for each test. This way we keep running
+ // even if one test crashes hard, valgrind can check
+ // each test individually and uses less memory.
+ BOOST_FOREACH (const std::string &name, tests) {
+#ifdef USE_SYSTEM
+ if (system(StringPrintf("%s %s", argv[0], name.c_str()).c_str())) {
+ failed = true;
+ }
+#else
+ // Avoid the intermediate shell process that system() uses and
+ // do better result reporting.
+ pid_t child = fork();
+ if (child > 0) {
+ while (true) {
+ int status;
+ pid_t completed = waitpid(child, &status, 0);
+ if (completed == -1) {
+ perror("waitpid");
+ failed = true;
+ } else {
+ if (WIFEXITED(status)) {
+ int retcode = WEXITSTATUS(status);
+ if (retcode != 0) {
+ printf("%s (%ld): failed with return code %d", name.c_str(), (long)child, retcode);
+ failed = true;
+ }
+ } else if (WIFSIGNALED(status)) {
+ printf("%s (%ld): killed by signal %d", name.c_str(), (long)child, WTERMSIG(status));
+ failed = true;
+ }
+ fflush(stdout);
+ break;
+ }
+ }
+ } else if (child == -1) {
+ perror("fork");
+ } else {
+ // Use the test name also as name of the process.
+ execlp(argv[0], name.c_str(), name.c_str(), (char *)NULL);
+ perror("execlp");
+ _exit(1);
+ }
+#endif
}
}
// Return error code 1 if the one of test failed.
+ if (tests.size() > 1) {
+ printf("%s", failed ? "FAILED" : "OK");
+ }
ClientTest::shutdown();
- return syncListener.hasFailed() ? 1 : 0;
+ return failed;
} catch (invalid_argument e) {
// Test path not resolved
std::cout << std::endl
my $zimbra = $server =~ /zimbra/;
my $evolution = $client =~ /evolution/;
my $addressbook = $client =~ /addressbook/;
+my $akonadi = $server =~ /kde/;
sub Usage {
print "$0 <vcards.vcf\n";
s/^(GEO)(;[^:;\n]*)*:.*\r?\n?//gm;
}
+ if ($akonadi) {
+ # Akonadi adds empty GEO propery....
+ s/^(GEO)(;[^:;\n]*)*:0+\.0+;0+\.0+\r?\n?//gm;
+ # ... and rounds other values.
+ s/^(GEO(?:;[^:;\n]*)*):([-+]?\d+)\.\d+;([-+]?\d+)\.\d+/$1:$2;$3/gm;
+ # does not preserve X-EVOLUTION-UI-SLOT=
+ s/^(\w+)([^:\n]*);X-EVOLUTION-UI-SLOT=\d+/$1$2/mg;
+ }
+
if ($googleeas || $exchange) {
# temporarily ignore modified properties
s/^(BDAY|X-ANNIVERSARY)(;[^:;\n]*)*:.*\r?\n?//gm;
TEL;TYPE=HOME;TYPE=FAX:homefax 5
TEL;TYPE=PAGER:pager 6
TEL;TYPE=CAR:car 7
-TEL;TYPE=PREF:primary 80
+TEL;TYPE=PREF:primary 8xx
X-AIM:AIM JOHN
X-YAHOO:YAHOO JDOE
X-ICQ:ICQ JD
TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6
TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7
-TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 80
+TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8xx
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6
TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7
-TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 80
+TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8xx
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
# Modify second and third contact by changing a field.
# The second contact will also get modified locally.
perl -e '$_ = join("", <>); if (/John [23] Doe/) {' \
- -e 's/primary 8/primary 80/;' \
+ -e 's/primary 8/primary 8xx/;' \
-e 's/END:VCARD/BDAY:2006-01-01\r\nEMAIL:new local email\r\nEND:VCARD/;' \
-e 'print;' \
-e '}' \
#
# Each -e generates a line break, so no \n is necessary inside the expanded vCard.
perl -e '$_ = join("", <>); if (/John [12] Doe/) {' \
- -e 's/primary 8/primary 80/;' \
+ -e 's/primary 8/primary 8xx/;' \
-e 's!END:VCARD!BDAY:2006-01-08\r' \
-e 'TEL;TYPE=HOME:new remote tel 1\r' \
-e 'tel2.TEL:new remote tel 2\r' \
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r
TEL;TYPE=HOME;TYPE=FAX:homefax 5
TEL;TYPE=PAGER:pager 6
TEL;TYPE=CAR:car 7
-TEL;TYPE=PREF:primary 80
+TEL;TYPE=PREF:primary 8xx
X-AIM:AIM JOHN
X-YAHOO:YAHOO JDOE
X-ICQ:ICQ JD
TEL;TYPE=HOME;TYPE=FAX:homefax 5
TEL;TYPE=PAGER:pager 6
TEL;TYPE=CAR:car 7
-TEL;TYPE=PREF:primary 80
+TEL;TYPE=PREF:primary 8xx
X-AIM:AIM JOHN
X-YAHOO:YAHOO JDOE
X-ICQ:ICQ JD
TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6
TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7
-TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 80
+TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8xx
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
# The second contact will also get modified locally.
# Add a different BDAY than the peer.
perl -e '$_ = join("", <>); if (/John [23] Doe/) {' \
- -e 's/primary 8/primary 80/;' \
+ -e 's/primary 8/primary 8xx/;' \
-e 's/END:VCARD/BDAY:2006-01-01\r\nEMAIL:new local email\r\nEND:VCARD/;' \
-e 'print;' \
-e '}' \
#
# Each -e generates a line break, so no \n is necessary inside the expanded vCard.
perl -e '$_ = join("", <>); if (/John [12] Doe/) {' \
- -e 's/primary 8/primary 80/;' \
+ -e 's/primary 8/primary 8xx/;' \
-e 's!END:VCARD!BDAY:2006-01-08\r' \
-e 'TEL;TYPE=HOME:new remote tel 1\r' \
-e 'tel2.TEL:new remote tel 2\r' \
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r
TEL;TYPE=FAX,HOME:homefax 5\r
TEL;TYPE=PAGER:pager 6\r
TEL;TYPE=CAR:car 7\r
-TEL;TYPE=PREF:primary 80\r
+TEL;TYPE=PREF:primary 8xx\r
EMAIL;TYPE=WORK:john.doe@work.com\r
EMAIL;TYPE=HOME:john.doe@home.priv\r
EMAIL:john.doe@other.world\r