Commit graph

3731 commits

Author SHA1 Message Date
Patrick Ohly
64a21f8f5d signon: add version check for UOA
Better check in configure that libgsignon-glib and libaccounts-glib
are recent enough to match the code.
2014-01-08 15:51:54 +01:00
Patrick Ohly
48499d3cfd signon: fix compilation with nothing enabled
When neither gSSO nor UOA were enabled, the provideruoa.so was
still enabled and failed to link because its LDFLAGS were not
set. It shouldn't have been enabled at all.

While we are at it, allow both to be enabled in the build rules,
even though the code doesn't support it (symbol clashes).
2014-01-08 15:51:54 +01:00
Alberto Mardegan
80f1deb5e9 signon: add Ubuntu Online Accounts support
Add a new configuration flag (--enable-uoa) to enable building the
signon backend for Ubuntu Online Accounts. The work done for gSSO is
reused and just slightly adapted (using preprocessor conditions) to work
with UOA as well.
2014-01-08 15:51:54 +01:00
Patrick Ohly
143b7022af signon: fix compile error
Converting PlainGStr to bool is ambiguous, some compilers
fail on it. Avoid the ambiguity by checking the actual
char string pointer.
2014-01-08 15:51:54 +01:00
Patrick Ohly
30575344cf command line: randomly did not show output
Because of an uninitialized memory read introduced for DLT after
1.3.99.5, output from the syncevolution command line tool was not
shown randomly.

Other usages of the second constructor for MessageOptions may also
have been affected.

That this was not caught by nightly testing points towards a problem
which will have to be solve separately: test-dbus.py needs to run
syncevolution under valgrind.
2013-12-09 16:35:59 +01:00
Patrick Ohly
0010c03b48 GOA: fix usage with libdbus
We must not request a name, so don't pass "". This caused
assertions inside libdbus when trying to set up a Google
sync config.
2013-12-04 13:53:08 +01:00
Patrick Ohly
607b41723c PBAP: document known issue with obexd < 0.47
PullAll only worked once. Not sure why, but at least document the
issue in the source as comment.
2013-12-04 13:53:08 +01:00
Patrick Ohly
dc05bf78ce PIM: fix sync.py + multiple peers
Due to overwriting a variable, configuring multiple different
peers did not work.
2013-12-04 13:53:08 +01:00
Patrick Ohly
c435e937cd engine: disable batching by default
Change the EDS backend to not batch by default and only enable it
for PIM Manager PBAP syncs.

This avoids unnecessary overhead when running a normal SyncML sync
with a non-SyncEvolution peer, because then the batched operation
would be flushed immediately by the Synthesis engine, and more
importantly, it fixes a segfault in
Client::Sync::eds_event_eds_contact::testLargeObject EDS<->DAV tests.

Enabling batching during general syncs obviously needs further work...
2013-11-29 14:30:16 +01:00
Patrick Ohly
23929575e9 DLT: fix minor memory leak
Found when adding DLT to nightly testing under valgrind.
2013-11-26 17:03:02 +01:00
Patrick Ohly
06e7d0946f compatibility hack: support libical.so.1
libical 1.0 changed the library name to libical.so.1, causing dependency
problems becaus syncevolution.org binaries required libical.so.0.

It turned out that the relevant parts of the API and ABI had not changed,
so simply allowing both versions of the library is sufficient.

In addition, a detection of libical.so.1 gets added, just in case.
2013-11-26 17:03:02 +01:00
Patrick Ohly
5e46710ea9 logging: hide glib warnings from users
Most glib warnings are too technical for normal users. Better restrict
their logging to "for developers", which keeps them out of stderr of normal
invocations.

Triggered by a new warning showing up with GNOME 3.8 which didn't seem
to cause any problems.
2013-11-26 17:03:02 +01:00
Patrick Ohly
9ad092745d CalDAV: remove dead code
The code wasn't used and incorrectly made it look like SyncEvolution used an
enum which changed its value between libical.so.0 and libical.so.1. Better
remove the code...
2013-11-26 17:03:02 +01:00
Patrick Ohly
6a4ab50aee PBAP: add support for obexd 0.48
obexd 0.48 is almost the same as obexd 0.47, except that it dropped
the SetFilter and SetFormat methods in favor of passing a Bluex 5-style
filter parameter to PullAll.

SyncEvolution now supports 4, in words, four different obexd
APIs. Sigh.
2013-11-26 17:03:02 +01:00
Patrick Ohly
28a1483b7e PIM: fix compiler warning
Recent gcc complains about redundant local typedef.
2013-10-29 13:18:13 +01:00
Patrick Ohly
700ddd7b41 PIM testing: check behavior with broken pim-manager.ini (FDO #70772)
The PIM Manager should be able to start normally and the default sort
order should be used instead of the invalid one from the config.

Invalid address books are also tested, without checking for any
specific value from GetActiveAddressBooks().
2013-10-29 13:18:13 +01:00
Patrick Ohly
1f8f2d14ea PIM: ignore broken sort order in config (FDO #70772)
Failure to set the sort order from pim-manager.ini should not
prevent the startup of the PIM Manager because the client
cannot really diagnose and fix the problem. It is better
to try again with the default sort order.
2013-10-29 13:18:13 +01:00
Patrick Ohly
0d7ed20931 PIM testing: cover pim-manager.ini handling during SetPeer() (FDO #70772)
The content of pim-manager.ini should be monitored to find issues
like the one reported in FDO #70772. For that particular problem
to appear we also need to use SetActiveAddressBooks().
2013-10-29 13:18:13 +01:00
Patrick Ohly
b1ca48ca0a PIM: fix incorrect write into pim-manager.ini (FDO #70772)
Removing a peer accidentally wrote the updated list of active address
books into the "sort" property of pim-manager.ini, which then
prevented starting the PIM Manager (a different problem which will
be addressed separately).
2013-10-29 13:18:13 +01:00
Patrick Ohly
04879b6026 PIM: explicitly re-calculate pre-computed data on locale change
The normalization of phone numbers depends on the locale. This commit
adds a test for that and code which works without relying on EDS to
re-calculate those normalized numbers.

This is not the normal mode of operation and thus this can't be the
final solution. The right solution would be for EDS to notice the
locale change, re-check all precomputed phone numbers
(X-EVOLUTION-E164 parameter) and emit change notifications. Those then
would get picked up by folks and from there, update the PIM views.

The tests rely on running dbus-session.sh with
DBUS_SESSION_SH_SYSTEM_BUS set.
2013-10-29 13:18:13 +01:00
Patrick Ohly
73d72502b8 PIM: adapt to locale changes at runtime (FDO #66618)
Listen to signals from localed D-Bus system service and update all
internal state which depends on the current locale. This state includes:
- pre-computed data in all loaded contacts
- filtering (for example, case sensitivity is locale dependent)
- the sort order

In the current implementation, the entire LocaleFactory gets replaced
when the environment changes. The new instance gets installed in
FullView, then the sort comparison gets created anew and the existing
setSortOrder() updates the main view, which includes re-computing all
pre-computed data.

As a last step, the search filter is re-recreated and filtering gets
updated in all active filter views.

There is a minor risk that unnecessary changes get emitted because
first filtered views react to modified contacts and/or reshuffling
them, then later their filter gets replaced.
2013-10-29 13:18:13 +01:00
Patrick Ohly
6285597579 D-Bus server: LocaledListener must not fail without system bus
The listening functionality is meant to be optional, which includes
running inside an environment which doesn't even have a system D-Bus,
like the nightly testing.
2013-10-29 13:08:18 +01:00
Patrick Ohly
76d7af91ce D-Bus server: utility class for localed D-Bus interface
This is the client side for the org.freedesktop.locale1 "Locale"
property. It ensures that new values of that property are made
available locally.

Optionally it can also update the current process' environment and
send a simpler "locale environment changed" if it made some changes.
This needs to be enabled by connecting the setLocale() method to the
m_localeValues signal.
2013-10-29 13:08:04 +01:00
Patrick Ohly
44b31eac29 EDS: disable asynchronous creation of ESourceRegistry
After testing more with EDS 3.8 on Debian Testing, random hangs
were observed inside the glib main loop while waiting for the
registry creation callback. It's uncertain why that happens,
and due to lack of time at the moment it is easier to switch
back to the synchronous method. Needs to be investigated later.
2013-10-29 13:04:44 +01:00
Patrick Ohly
1043dbf9eb PIM: accent-insensitive and transliterated search (FDO #56524)
Accent-insensitive search ignores accents, using the same code as in
EDS.  Transliterated search ignores foreign scripts by transliterating
search term and contact properties to Latin first. That one is using
ICU directly in the same way as EDS, but doesn't use the EDS
ETransliterator class to avoid extra string copying.

This commit changes the default behavior such that searching is by
default most permissive (case- and accent-insensitive, does
transliteration).  Flags exist to restore more restrictive matching.
2013-10-29 13:04:32 +01:00
Patrick Ohly
771ed318eb D-Bus: configure option for overriding default logging
By default, syncevo-dbus-server logs to syslog. This can be changed
with the new parameter of --enable-dbus-service. For example, this
changes the logging to DLT (must be available, or course):
  configure "--enable-dbus-server=--dlt --no-syslog"
2013-10-25 21:07:35 +01:00
Patrick Ohly
e7a8f1b456 logging: support DLT (FDO #66769)
Diagnostic Log and Trace (DLT) manages a sequence of log messages,
with remote controllable level of detail. SyncEvolution optionally
(can be chosen at compile time and again at runtime) uses DLT instead
of its own syncevolution-log.html files.
2013-10-25 21:07:27 +01:00
Patrick Ohly
db5f24e10d autotools: fix make error
Adding link flags to the libsyncevlution.la dependencies only works
for .la file. This started to break on Debian Testing (?) because
a -L<something> flag became a dependency.

A proper fix would be to set libs and dependencies separately,
but for now it is easier to rely on GNU make and filter for the
desired .la files.
2013-10-25 21:07:26 +01:00
Patrick Ohly
317246c352 D-Bus: fix compiler warning
We unintentionally and unnecessarily included boost/signals.hpp instead of
boost/signals2.hpp, which started to trigger warnings with later versions of
boost.
2013-10-25 21:07:26 +01:00
Patrick Ohly
abeefa3a4e EDS: remove redundant libebook-contacts dependency
This fixes compilation with EDS 3.6. libebook-contacts was needed
for a while when configuring address books directly. It is not needed
anymore because now we simply clone the system database.
2013-10-25 21:07:26 +01:00
Patrick Ohly
6c8dc7b194 ActiveSync: don't build Qt UI
The Qt UI no longer works with EDS >= 3.6. We don't need it, so
don't bother with it.
2013-10-25 21:07:26 +01:00
Patrick Ohly
b3b0f3c7e1 EDS: support dual-install of ebook/ecal backends for EDS < 3.6 and EDS >= 3.6
The backends must be compiled differently for EDS < 3.6 (using the old
API before EBookClient, ECalClient and ESource, ideally in
compatibility mode) and for EDS >= 3.6 (using the new API, with hard
linking against libebook-1.2.so.14, libecal-1.2.so.15,
libedataserver-1.2.so.17).

With these changes, a SyncEvolution binary compiled for the older EDS
API will be able to load and use backends compiled against the current
one. Both backends can be installed in the same
lib/syncevolution/backends dir under different names. The newer ones
must have an additional -<version> appendix before the .so suffix.

Then loading will attempt to use those backends first and if
successful, skip the older ones. This is necessary because loading
both into the same process will fail due to symbol clashes. If
unsuccessful (as on systems with only the older EDS), the dynamic
linker will fail and SyncEvolution proceeds with the backends for the
old API.

Packaging of binaries as .dev/.rpm/.tar.gz includes these additional
backends if given in the EXTRA_BACKENDS variable when invoking "make
deb rpm distbin".
2013-10-25 21:07:26 +01:00
Patrick Ohly
4c962b3c49 EDS: improve EDS compatibility mode
The EDS backends for >= 3.6 failed to work property in SyncEvolution
binaries compiled for EDS < 3.6, because the EDS compatibility
layer reported "EDS not found" to the backend.

A backend that gets compiled without compatibility hacks doesn't
need the runtime check, because merely loading already guarantees
that the necessary libs were found. Therefore make the check
a compile-time define when compatibility mode is disabled.

A backend compiled with compatibility mode enabled then fails to load
in a binary compiled without because libsyncevolution.so does not
export the necessary symbols. That's actually desirable, because the
backend would not work anyway.
2013-10-25 21:07:18 +01:00
Patrick Ohly
7e655089e3 EDS: SYNCEVOLUTION_EBOOK_QUERY env variable
Setting the SYNCEVOLUTION_EBOOK_QUERY env variable to a valid EBook
query string limits the results to contacts matching that
query. Useful only in combination with --print-items or --export. Only
implemented for EDS >= 3.6.
2013-10-24 13:19:31 +01:00
Patrick Ohly
ed1f1f4aa2 PIM: relax phone number matching
Previously, the current default country was used to turn phone numbers
without an explicit country code into full E164 numbers, which then
had to match the search term when doing a caller ID lookup.

This was inconsistent with EDS, where a weaker
EQUALS_NATIONAL_PHONE_NUMBER was done. The difference is that a
comparison between a number with country code matches one without if
the national number of the same, regardless of the current default
country. This is better because it reduces the influence of the hard
to guess default country on matching.

SyncEvolution also differed from EDS by doing a prefix comparison,
which in theory might have also ignored differences caused by
extensions. It is uncertain whether that was useful, so for the sake
of consistency, a full number comparison of the national number is now
done.

Another advantage of this change is the lower memory consumption and
faster comparison, because strings are now stored in 4 + 8 byte
numbers instead of strings of varying length.
2013-10-24 13:19:31 +01:00
Patrick Ohly
1260a702f4 glib: prevent accidental usage of PlainGStrArray []
The array operator happens to work on some platforms, but not others
(see previous commit). Make it private without an implementation to
catch the undesired usage of it on platforms whether the code would
happen to work otherwise.
2013-10-18 09:58:28 +02:00
Patrick Ohly
dd61308c67 EDS: fix compile problem with boost and EDS > 3.36
This fixes the following problem, seen with Boost 1.53.0 on altlinux
when compiling for EDS >= 3.6:

/usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of 'typename boost::detail::sp_array_access<T>::type boost::shared_ptr<T>::operator[](std::ptrdiff_t) const [with T = char*; typename boost::detail::sp_array_access<T>::type = void; std::ptrdiff_t = long int]':
src/backends/evolution/EvolutionSyncSource.cpp:163:38: required from here
/usr/include/boost/smart_ptr/shared_ptr.hpp:663:22: error: return-statement with a value, in function returning 'void' [-fpermissive]
make[2]: *** [src/backends/evolution/src_backends_evolution_syncecal_la-EvolutionSyncSource.lo]

The "void" type above is wrong, so it looks like a missing type trait
for the pointer type used in the smart_ptr. PlainGStrArray already had
an at() method to work around such issues, so use it. Not sure why this
one usage of [] slipped through.
2013-10-18 09:58:28 +02:00
Patrick Ohly
9d1b079750 GTK/GTK3 UI: fix crash on 64 bit
While running a sync with a binary compiled with -fPIE -pie, a crash
in strlen() occured because a 64 bit string pointer coming from D-Bus
was incorrectly passed through a 32 bit unsigned variable.

These special compile flags merely caused the problem to occur
reliably, it may also have crashed under other circumstances.

Kudos to Tino Keitel for reporting the problem and identifying the
relation to the compile flags.
2013-10-01 09:28:39 +02:00
Patrick Ohly
5a0f5a9793 GTK/GTK3 UI: fix crash when a sync runs while no service is selected
Running a sync while the UI had no service selected caused a crash in
find_updated_source_progress() because the code dereferences the NULL
prog_data->data->current_service pointer. Affected both the GTK2 and
GTK3 UI.

Fix it by checking for NULL and not doing anything if NULL.
2013-10-01 09:28:39 +02:00
Patrick Ohly
f9f6eda294 autotools: compile client-test with -g by default
When compiling source files of client-test, use -g as default CXXFLAGS
instead of the "-g -O2" that autotools normally picks.  That speeds up
compilation significantly (on some platforms, gcc can't deal with the
many templates in ClientTest.cpp well) and leads to more useful
executables (suitable for interactive debugging) even when the rest of
the code gets optimized.

Explicitly specifying CXXFLAGS still overrides this per-target
default.

This feature depends on GNU make. A configure check is in place
to disable it when not using GNU make.
2013-10-01 09:28:39 +02:00
Patrick Ohly
9edf97bd2b GNOME: work around GNOME keyring communication problem
It seems that sometimes setting up a session with GNOME keyring fails such
that all further communication leads to decoding problem.

There is an internal method to reset the session, but it cannot be called
directly. As a workaround, fake the death of the GNOME keyring daemon
and thus trigger a reconnect when retrying the GNOME keyring access.
2013-10-01 09:28:39 +02:00
Patrick Ohly
02bd2f3a2d GNOME: clean up keyring access
This drops the support for libgnome-keyring < 2.20, because older
versions did not have the error->text conversion method which is now
used in revised error and log messages.

This code also adds a retry loop around reading/writing passwords.
This was meant to work around these intermittent Gkr errors:

Gkr: received an invalid, unencryptable, or non-utf8 secret
Gkr: call to daemon returned an invalid response: (null).(null)()

These lead to an "Error communicating with gnome-keyring-daemon" status
code from libgnome-keyring.

However, once the error occurred in a process, it persists for at least
two seconds, possibly forever. Therefore the retry loop is not enabled.
2013-10-01 09:28:39 +02:00
Patrick Ohly
ed19df3c6f WebDAV: support Google CardDAV, break Yahoo
Google CardDAV has one peculiarity: it renames new contacts during PUT without
returning the new path to the client. See also
http://lists.calconnect.org/pipermail/caldeveloper-l/2013-July/000524.html

SyncEvolution already had a workaround for that (PROPGET on old path, extract
new path from response) which happened to work. This workaround was originally
added for Yahoo, which sometimes merges contacts into existing ones. In
contrast to Yahoo, Google really seems to create new items.

Without some server specific hacks, the client cannot tell what happened.
Because Google is currently supported and Yahoo is not, let's change the
hard-coded behavior to "renamed items are new".
2013-10-01 09:28:39 +02:00
Patrick Ohly
102c90d70c testing: preserve XDG dirs if located inside builddir
The nightly testing configures some platforms such that
XDG_CONFIG/DATA/CACHE_HOME are inside the build dir. It also populates these
dirs with files (for example, GNOME Online Accounts) which must survive all
cleaning of these directories.

Long term it would be better to separate test files from build files,
but that's a task for some other time...
2013-10-01 09:28:39 +02:00
Patrick Ohly
ec9de82a7d SyncContext: use AuthProvider
When running a local sync, the syncURL/username/password are not meant
for the sync and cannot be used if they refer to an AuthProvider which
cannot return plain username/password.

In all other cases, this may or may not work, so at least try it instead
of hard-coding the IdentityProviderCredentials.
2013-10-01 09:28:38 +02:00
Patrick Ohly
8f3f6130ab GOA: get OAuth2 tokens out of GNOME Online Accounts
"username = goa:..." selects an account in GOA and retrieves the
OAuth2 token from that.

The implementation uses the GOA D-Bus API directly, because our C++
D-Bus bindings are easier to use and this avoids an additional library
dependency.
2013-10-01 09:28:38 +02:00
Patrick Ohly
582025171d testing: remove timeout= parameters from D-Bus method calls
These became redundant after patching the bus object to set such
a timeout by default.
2013-10-01 09:28:38 +02:00
Patrick Ohly
83c515b950 SyncContext: use SimpleUserInterface without keyring access
Code-refactoring, the default user interface has the same functionality
as our dummy one if told to not use keyrings.
2013-10-01 09:28:38 +02:00
Patrick Ohly
12f3545e4f UserInterface: provide simple default implementation
A default implementation for optional, read-only access to the keyrings.
2013-10-01 09:28:38 +02:00
Patrick Ohly
8b391dbb79 D-Bus server: password not stored in GNOME keyring or KWallet (FDO #66110)
When clients like the GTK sync-ui stored a password, it was always
stored as plain text in the config.ini file by the
syncevo-dbus-server. The necessary code for redirecting the password
storage in a keyring (GNOME or KWallet) simply wasn't called in that
case.

The command line tool, even when using the D-Bus server to run the
operation, had the necessary code active and thus was not affected.
2013-10-01 09:28:38 +02:00
Patrick Ohly
115137b8b4 templates: don't store username/password for SyncEvolution client
The client template is also used in cases where passwords are not
needed (local sync) and where passwords cannot be stored in a keyring
due to the missing syncURL/remoteDeviceID. Therefore don't set dummy
username/password values in the template.
2013-10-01 09:28:38 +02:00
Patrick Ohly
3f19af6a54 Cmdline: add missing password lookup
When configuring a new peer and looking for databases, we need the
database password of an already existing source config, otherwise the
lookup will fail if that password is hidden in a keyring.
2013-10-01 09:28:38 +02:00
Patrick Ohly
e85cca1912 config: revise default of the "keyring" property
The command line tool in --daemon=no mode did not use the GNOME
keyring or KWallet even if the syncevo-dbus-server did, leading
to failing test cases when actually starting to use it by default
there.

Now all components use the same default: use safe password storage if
any was enabled during compilation, don't use if not.

This also makes SyncEvolution work without user intervention on
systems without a password storage.
2013-10-01 09:28:38 +02:00
Patrick Ohly
e18360d896 GNOME: add debug messages for GNOME Keyring
Makes it easier to determine whether GNOME Keuring is used.
2013-10-01 09:28:38 +02:00
Patrick Ohly
b211506711 KDE: add debug messages around KWallet
Makes it easier to determine whether KWallet is used.
2013-10-01 09:28:38 +02:00
Patrick Ohly
7808af7c46 logging: debug output for password handling
Figuring out where credentials come from became harder. These debug
messages help. Perhaps they should even be logged as INFO messages
such that normal users can see them?
2013-10-01 09:28:37 +02:00
Patrick Ohly
471842e767 signon: README and example Google accounts files
The README explains how to use Google CalDAV/CardDAV together with
the example accounts config files.
2013-10-01 09:28:29 +02:00
Patrick Ohly
c531017185 signon: new backend using libgsignond-glib + libaccounts-glib
The code works with gSSO (https://01.org/gsso). With some tweaks to
the configure check and some ifdefs it probably could be made to work
with Ubuntu Online Accounts.

The code depends on an account accessible via libaccounts-glib which
has a provider and and (optionally) services enabled for that
provider. It is not necessary that the account already has a signon
identity ID, the backend will create that for the provider (and thus
shared between all services) if necessary.

Therefore it is possible to use the ag-tool to create and enable the
account and services. Provider and service templates are in the next
commit.
2013-09-27 08:59:14 -07:00
Patrick Ohly
2102cca90b WebDAV: support OAuth2
If given an AuthProvider which can handle OAuth2, then OAuth2 is
used instead of plain username/password authentication.

Obtaining the OAuth2 token must be done at a point where we can still
abort the request. If obtaining the token fails, then this should be
considered a fatal error which aborts scanning for resources. Other
errors cause the current URL to be skipped while scanning continues.

This commit moves the "execute request" functionality back into the
Neon::Session class, because that is where most of the logic (retry
request?) and state is (access tokens which persist across requests).
2013-09-27 08:59:14 -07:00
Patrick Ohly
306e4c042d WebDAV: testing a WebDAV source depends on password lookup
This becomes relevant once passwords are actually stored in
a keyring.
2013-09-27 08:59:14 -07:00
Patrick Ohly
83768d41ae config: add identity provider registry
Similar to the RegisterSyncSource concept, but trimmed down:
- virtual method creates instances
- keys have to be unique
2013-09-27 08:59:14 -07:00
Patrick Ohly
5d9aa1ac85 config: introduce AuthProvider
AuthProvider is the instance created by specific IdentityProvider
backends which then hands out username/password credentials or OAuth2
bearer tokens.
2013-09-27 08:59:14 -07:00
Patrick Ohly
526723acf5 config: first step towards modular identity providers
Let the conversion to username+password be handled by the
IdentityProvider module.
2013-09-27 08:59:14 -07:00
Patrick Ohly
7a28f3664c config: selectively resolve username during indirect credential lookup
The real username is only relevant when running a sync. When looking
at a config with a D-Bus client like the GTK UI, the username should
always be "id:<config>", to avoid accidentally removing the
indirection, while the password should be the real one, to allow the
user to edit like he normally would with passwords stored in a
keyring.

To achive this, overriding the username must be suppressed when
resolving as part of the D-Bus config API. While at it, move the
entire "iterate over properties" into a common utility function in
PasswordConfigProperty.
2013-09-27 08:59:14 -07:00
Patrick Ohly
1ab5aeac8d SyncConfig: implement "id" handling for reading and writing credentials
save/checkPassword both know how to handle the "id" provider now.
2013-09-27 08:59:13 -07:00
Patrick Ohly
efd6b2aebf ConfigPasswordKey: add toString()
Will be used for debugging messages.
2013-09-27 08:59:13 -07:00
Patrick Ohly
4f423bbf4e GNOME keyring: prevent empty "server" key in password lookup
Storing a password with just "user=foo" as lookup attributes is problematic
because it is too unspecific. Different services or configs with the same
user, but different passwords end up overwriting each other's passwords. In
practice, the config with "user=foo" even had the effect of removing the entry
for "user=foo server=bar".

The situation can be avoided by using the remotePeerId as fallback when the
syncURL is empty. There is a (minor?) risk that some configs were stored
in the past without that additional key and now won't be found anymore in the
keyring. Users need to re-set such passwords.

If an attempt is made to store a password with insufficient lookup attributes,
GNOME keyring will now reject the attempt.
2013-09-27 08:59:13 -07:00
Patrick Ohly
e5bc0a6cd4 config: avoid empty server key during password lookup in keyring
Empty server strings cause problems with GNOME keyring. Removing an
entry with the same user name and a server string has been observed in
practice.
2013-09-27 08:59:13 -07:00
Patrick Ohly
19079c4999 config: reuse existing node and tree instances
When instantiating multiple SyncConfig instances, it is important that
they share filter nodes and the underlying tree, because the nodes
store copies of already retrieved credentials (lookup shall only be
done once!) and the trees represent the current content of the config
(which must be consistent when making changes).

Currently the new code is not thread-safe, but nor are nodes and trees,
so a lot more work would be needed to make this safe. Instead we avoid
concurrency.
2013-09-27 08:59:13 -07:00
Patrick Ohly
2b92db7c1f SyncConfig: do not rely on creating of empty config during test
SyncConfigTest::normalize() only passed because FileConfigTree accidentally
created the "peers" directory inside the peer. That will change, so don't rely
on that. Instead ensure that the config.ini file of the peers gets written
because it contains something.
2013-09-27 08:59:13 -07:00
Patrick Ohly
401de08d5e SyncContext: avoid caching config tree for entire duration of client-test
Instantiating LogDirTest used to create a SyncContext and use that as logger
for the entire duration of testing inside client-test, even when not running
LogDirTest tests at all. This is undesirable and together with caching of the
config tree while in use, broke some other tests (EvolutionCalendarTest)
because obsolete DB names were shared.

It is better to create the context during setUp() and remove it in tearDown().
2013-09-27 08:59:13 -07:00
Patrick Ohly
ba5eaccef9 config: refactor root path handling
The previous approach made FileConfigTree more complex than necessary.
Having an abstract ConfigTree::getRootPath() with undefined behavior
is bad design.

The code was had undesiredable side effects: inside a peer config,
another "peers" directory was created because FileConfigTree didn't
know whether creating that dir was required or not.

Now all of the complexity is in SyncConfig, which arguably knows
better what the tree stands for and how to use
it.
2013-09-27 08:59:13 -07:00
Patrick Ohly
37b03d5e8d SyncConfig: simplify password API
In practice, the methods are always called for a specific SyncConfig.
Passing that allows removing several other parameters and, more
importantly, also grants access to the config and through that other
configs. This will be needed for the indirect credential lookup.
2013-09-27 08:59:13 -07:00
Patrick Ohly
c1808f72aa SyncSourceConfig: remove obsolete password methods
Not used, the per-source password operations are done via the
ConfigProperty interface.
2013-09-27 08:59:13 -07:00
Patrick Ohly
4c52378ec3 config: user name -> identity
"username", "proxyUsername" and "databaseUser" used to be simply a
string containing the name of the respective user or (in the case of
the ActiveSync backend) the account ID in gconf.

Now it is also possible to provide credentials (username + password)
indirectly: when any of these properties is set to "id:<config name>",
then the "username/password" properties in that config are used
instead. This is useful in particular with WebDAV, where credentials
had to be repeated several times (target config, in each database when
used as part of SyncML) or when using a service which requires several
configs (Google via SyncML and CalDAV).

For user names which contain colons, the new "user:<user name>" format
must be used. Strings without colons are assumed to be normal user
names.

This commit changes the SyncConfig APIs for this extension. More work
is needed to make the indirect lookup via "id" functional.
2013-09-27 08:59:13 -07:00
Patrick Ohly
7fa64a040c SyncConfig: remove obsolete caching of passwords
Passwords are cached after the initial check as temporary property
values. The explicit string members are obsolete and can be removed
together with the code using them.
2013-09-27 08:59:12 -07:00
SyncEvolution Nightly Testing
43382e5f44 PIM testing: fix test for sync running longer than auto shutdown period
Somehow an intermediate version ended up in the master branch. It
broke TestContacts.
2013-09-04 16:49:48 +02:00
Patrick Ohly
b9ee14622a PIM: fix D-Bus timeout problem in sync.py
Using asynchronous method calls did not eliminate the default timeout,
as expected. In particular, SyncPeer() still timed out when syncing many
contacts.

Instead set up all necessary parameters (= callbacks and now also a
long timeout) in a hash and pass that to all D-Bus method calls. It's
less code duplication, too.
2013-09-04 11:12:06 +02:00
Patrick Ohly
e6e48ce7f0 PIM: fix UID usage in sync.py example
Using the underscore in the UID has been wrong all along, it only
happened to work because UID sanity checking was missing. After adding
it, the example broke.

Now simply remove the colon. It makes the UID less readable, but it
doesn't have to be, and ensures that file names and database names
contain the UID as-is.
2013-09-04 11:12:06 +02:00
Patrick Ohly
00a13c1307 PBAP: include README in source distribution 2013-09-04 11:12:06 +02:00
Patrick Ohly
928cff942b PBAP: do not end Bluez5 transfer prematurely
A transfer was marked as finished prematurely when encountering the
"active" Status value, which can happen for longer transfers.
2013-09-04 11:12:06 +02:00
Patrick Ohly
83dcba8486 autotools: fix race condition related to src/dbus/interfaces docs
Only saw this once in nightly testing and couldn't reproduce it:

$ make -j 16
perl /data/runtests/work/sources/syncevolution/src/syncevo/readme2c.pl
    /data/runtests/work/sources/syncevolution/README.rst
    >src/syncevo/CmdlineHelp.c
/usr/bin/xsltproc -o src/dbus/interfaces/syncevo-server-doc.xml
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/spec-to-docbook.xsl
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/syncevo-server-full.xml
/usr/bin/xsltproc -o src/dbus/interfaces/syncevo-connection-doc.xml
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/spec-to-docbook.xsl
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/syncevo-connection-full.xml
/usr/bin/xsltproc -o src/dbus/interfaces/syncevo-session-doc.xml
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/spec-to-docbook.xsl
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/syncevo-session-full.xml
/usr/bin/glib-genmarshal
    /data/runtests/work/sources/syncevolution/src/dbus/glib/syncevo-marshal.list
    --header --prefix=syncevo_marshal > src/dbus/glib/syncevo-marshal.h
runtime error
xsltApplyStylesheet: saving to src/dbus/interfaces/syncevo-session-doc.xml may
    not be possible
/usr/bin/xsltproc -o src/dbus/glib/syncevo-server.xml
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/spec-strip-docs.xsl
    /data/runtests/work/sources/syncevolution/src/dbus/interfaces/syncevo-server-full.xml
runtime error
xsltApplyStylesheet: saving to src/dbus/interfaces/syncevo-server-doc.xml may
    not be possible
make: *** [src/dbus/interfaces/syncevo-server-doc.xml] Error 9
make: *** Deleting file `src/dbus/interfaces/syncevo-server-doc.xml'
make: *** Waiting for unfinished jobs....
make: *** [src/dbus/interfaces/syncevo-session-doc.xml] Error 9
make: *** Deleting file `src/dbus/interfaces/syncevo-session-doc.xml'

Looks like multiple xsltproc commands ran in parallel and then stepped on each
others toes while creating the src/dbus/interfaces directory, which does not
exist after an out-of-tree configure.

To address the issue, serialize creating that directory by having make create
it as a prerequisite.
2013-09-04 11:09:34 +02:00
Patrick Ohly
5e4a04e3d6 PIM testing: test for sync running longer than auto shutdown period
This test runs with an artificially low auto shutdown period (set via
a modified run() method) and a delayed sync.
2013-09-04 11:08:02 +02:00
Patrick Ohly
0fcf21ef3a D-Bus server: if busy, don't shut down
While there are sessions pending or active, the server should not shut down.
It did that while executing a long-running PIM Manager SyncPeer() operations,
by default after 10 minutes.

This was not a problem elsewhere because other operations are associated with
a client, whose presence also prevents shutdowns. Perhaps PIM Manager should
also track the caller and treat it like a client.
2013-09-04 11:08:02 +02:00
Patrick Ohly
a882bc7e90 glib: SYNCEVO_GLIB_CALL_SYNC() must use GRunWhile()
Like everything else that waits for a certain event on the main loop,
SYNCEVO_GLIB_CALL_SYNC() should also better use GRunWhile(). This is
necessary to be usable in threads.
2013-09-04 11:05:47 +02:00
Patrick Ohly
b7fa64f15c signon: revert accidental inclusion in master branch
The code wasn't ready and got pushed as part of some other change.
2013-08-02 22:02:03 +02:00
Patrick Ohly
c0212c4585 PBAP: add support for obexd 0.48
obexd 0.48 is almost the same as obexd 0.47, except that it dropped
the SetFilter and SetFormat methods in favor of passing a Bluex 5-style
filter parameter to PullAll.

SyncEvolution now supports 4, in words, four different obexd
APIs. Sigh.
2013-08-02 16:37:01 +02:00
Patrick Ohly
a6b8eea548 signon: README and example Google accounts files
The README explains how to use Google CalDAV/CardDAV together with
the example accounts config files.
2013-08-02 13:17:02 +02:00
Patrick Ohly
f0254a30bb singon: new backend using libgsignond-glib + libaccounts-glib
The code works with gSSO (https://01.org/gsso). With some tweaks to
the configure check and some ifdefs it probably could be made to work
Ubuntu Online Accounts.

The code depends on an account accessible via libaccounts-glib which
has a provider and and (optionally) services enabled for that
provider. It is not necessary that the account already has a signon
identity ID, the backend will create that for the provider (and thus
shared between all services) if necessary.

Therefore it is possible to use the ag-tool to create and enable the
account and services. Provider and service templates are in the next
commit.
2013-08-02 13:16:11 +02:00
Patrick Ohly
3de6da6022 WebDAV: support OAuth2
If given an AuthProvider which can handle OAuth2, then OAuth2 is
used instead of plain username/password authentication.

Obtaining the OAuth2 token must be done at a point where we can still
abort the request. If obtaining the token fails, then this should be
considered a fatal error which aborts scanning for resources. Other
errors cause the current URL to be skipped while scanning continues.

This commit moves the "execute request" functionality back into the
Neon::Session class, because that is where most of the logic (retry
request?) and state is (access tokens which persist across requests).
2013-08-02 13:15:33 +02:00
Patrick Ohly
7fdd878bc1 config: add identity provider registry
Similar to the RegisterSyncSource concept, but trimmed down:
- virtual method creates instances
- keys have to be unique
2013-08-02 13:15:27 +02:00
Patrick Ohly
03efa0c44d config: introduce AuthProvider
AuthProvider is the instance created by specific IdentityProvider
backends which then hands out username/password credentials or OAuth2
bearer tokens.
2013-08-02 13:15:27 +02:00
Patrick Ohly
80e68a747a config: first step towards modular identity providers
Let the conversion to username+password be handled by the
IdentityProvider module.
2013-08-02 13:15:27 +02:00
Patrick Ohly
97863d3b7e config: selectively resolve username during indirect credential lookup
The real username is only relevant when running a sync. When looking
at a config with a D-Bus client like the GTK UI, the username should
always be "id:<config>", to avoid accidentally removing the
indirection, while the password should be the real one, to allow the
user to edit like he normally would with passwords stored in a
keyring.

To achive this, overriding the username must be suppressed when
resolving as part of the D-Bus config API. While at it, move the
entire "iterate over properties" into a common utility function in
PasswordConfigProperty.
2013-08-02 13:15:26 +02:00
Patrick Ohly
c3fdf439da SyncConfig: implement "id" handling for reading and writing credentials
save/checkPassword both know how to handle the "id" provider now.
2013-08-02 13:15:26 +02:00
Patrick Ohly
d2a4164668 SyncConfig: allow sharing file config tree between configs
A SHARED_LAYOUT config tree caches config nodes. Allow a second config
to use those same nodes as an already existing config. This will be
useful in combination with indirect password lookup, because then the
credentials can be stored as temporary property values and be reused
when used multiple times in a process (for example, by CardDAV and by
CalDAV).
2013-08-02 13:15:20 +02:00
Patrick Ohly
d9f87251c0 SyncConfig: simplify password API
In practice, the methods are always called for a specific SyncConfig.
Passing that allows removing several other parameters and, more
importantly, also grants access to the config and through that other
configs. This will be needed for the indirect credential lookup.
2013-08-02 13:15:14 +02:00
Patrick Ohly
1131379cc5 SyncConfig: allow access to ConfigTree
This will be needed to access other configs in the indirect password
lookup.
2013-08-02 13:15:13 +02:00
Patrick Ohly
059bb0bd6f SyncSourceConfig: remove obsolete password methods
Not used, the per-source password operations are done via the
ConfigProperty interface.
2013-08-02 13:15:13 +02:00
Patrick Ohly
5ff97dea44 config: user name -> identity
"username", "proxyUsername" and "databaseUser" used to be simply a
string containing the name of the respective user or (in the case of
the ActiveSync backend) the account ID in gconf.

Now it is also possible to provide credentials (username + password)
indirectly: when any of these properties is set to "id:<config name>",
then the "username/password" properties in that config are used
instead. This is useful in particular with WebDAV, where credentials
had to be repeated several times (target config, in each database when
used as part of SyncML) or when using a service which requires several
configs (Google via SyncML and CalDAV).

For user names which contain colons, the new "user:<user name>" format
must be used. Strings without colons are assumed to be normal user
names.

This commit changes the SyncConfig APIs for this extension. More work
is needed to make the indirect lookup via "id" functional.
2013-08-02 13:15:13 +02:00
Patrick Ohly
56ac0812a4 SyncConfig: remove obsolete caching of passwords
Passwords are cached after the initial check as temporary property
values. The explicit string members are obsolete and can be removed
together with the code using them.
2013-08-02 13:15:13 +02:00
Patrick Ohly
193ef1e534 glib: SYNCEVO_GLIB_CALL_SYNC() must use GRunWhile()
Like everything else that waits for a certain event on the main loop,
SYNCEVO_GLIB_CALL_SYNC() should also better use GRunWhile(). This is
necessary to be usable in threads.
2013-08-02 13:15:13 +02:00
Patrick Ohly
0a8b3f1f48 D-Bus server: password not stored in GNOME keyring or KWallet (FDO #66110)
When clients like the GTK sync-ui stored a password, it was always
stored as plain text in the config.ini file by the
syncevo-dbus-server. The necessary code for redirecting the password
storage in a keyring (GNOME or KWallet) simply wasn't called in that
case.

The command line tool, even when using the D-Bus server to run the
operation, had the necessary code active and thus was not affected.
2013-08-02 13:15:13 +02:00
Patrick Ohly
8bc48fd7d8 PBAP: compile fix for "PBAP: transfer data inside ReadItemAsKey"
uint16 happened to work when compiling with a recent GNOME stack, but
without that uint16 is not defined. The right approach is to use
stdint.h and uint16_t.
2013-07-25 11:19:03 +02:00
Guido Günther
85fca61913 build: use top_builddir instead of builddir
when building syncevo-local-sync. Maemo's old automake doesn't now
about builddir.

This only fixes the one occurence relevant to Maemo.
2013-07-12 16:18:12 +02:00
Patrick Ohly
c16f1b0756 sync: avoid maintaining suspend/resume meta data during ephemeral sync
Both maintaining the map items inside the Synthesis engine and storing
them in .ini hash config nodes inside SyncEvolution are fairly heavy
operations which are not needed at all during an ephemeral sync (= no
meta data stored, done by the PIM Manager when triggering a pure PBAP
sync).

Using the new Synthesis CA_ResumeSupported DB capability it is
possible to suppress these operations without having to fiddle with
the Synthesis DB API that SyncEvolution provides. To make it possible
at the DB layer to detect that the meta data is not needed, the
ConfigNode passed to it must be marked as volatile.

This change sped up a sync with 10000 unmodified, known items from 38s
to 23s.
2013-07-12 11:44:39 +02:00
Patrick Ohly
5aec08d12c SyncSourceConfig: cache synthesisID
The synthesisID value is required for each Synthesis source progress
event, which can be fairly frequent (more than one per item). Instead
of going down to the underlying .ini config node each time, cache the
value in the SyncSourceConfig layer.
2013-07-12 11:44:39 +02:00
Patrick Ohly
a05197891f sync: reduce D-Bus traffic
Syncing was slowed down by fowarding all log messages from the local
sync helper to its parent and from the D-Bus helper to
syncevo-dbus-server. Quite often, the log messages then were simply
discarded by the recipient. To speed up syncing, better filter at the
source.

The syncevo-dbus-helper is told which messages are relevant by
forwarding the syncevo-dbus-server "D-Bus log level" command line
setting to the helper process as part of its argv parameters.

The synevo-local-sync helper applies its own log level now also to the
messages sent to the parent. This ensures that messages stored in the
client log also show up in the parent log (unless the parent has more
restrictive settints, which is uncommon) and that INFO/SHOW messages
still reach the user.
2013-07-12 11:44:39 +02:00
Patrick Ohly
b34d56482e sync: less verbose output, shorter runtime
For each incoming change, one INFO line with "received x[/out of y]"
was printed, immediately followed by another line with total counts
"added x, updated y, removed z". For each outgoing change, a "sent
x[/out of y]" was printed.

In addition, these changes were forwarded to the D-Bus server where a
"percent complete" was calculated and broadcasted to clients. All of
that caused a very high overhead for every single change, even if the
actual logging was off. The syncevo-dbus-server was constantly
consuming CPU time during a sync when it should have been mostly idle.

To avoid this overhead, the updated received/sent numbers that come
from the Synthesis engine are now cached and only processed when done
with a SyncML message or some other event happens (whatever happens
first).

To keep the implementation simple, the "added x, updated y, removed z"
information is ignored completely and no longer appears in the output.

As a result, syncevo-dbus-server is now almost completely idle during
a running sync with no log output. Such a sync involving 10000 contacts
was sped up from 37s to 26s total runtime.
2013-07-12 11:43:40 +02:00
Patrick Ohly
f2378b7909 ForkExec: allow passing arguments to helper
The optional args array will be used when executing the helper
executable.
2013-07-11 11:40:51 +02:00
Patrick Ohly
0a3ec71e92 PIM testing: include testcase from FDO #66618
Ordering of 鳥 = niǎo before 女性 = nǚ xìng depends on the right
env variables. It works in this test.
2013-07-10 13:08:02 +02:00
Patrick Ohly
dc35d87dec D-Bus: better logging of server stub transport exceptions
Use SE_THROW() instead of "throw" because we want the error being
logged in the current sync log.
2013-07-10 13:08:02 +02:00
Patrick Ohly
7059459768 D-Bus: allow catching syncevo-dbus-helper in valgrind debugger
Set SYNCEVOLUTION_DBUS_HELPER_VGDB=1, add --vgdb-error=1 --vgdb=yes
to VALGRIND_ARGS, run test, wait for vgdb message in valgrind*.out files,
attach as instructed.

With --vgdb-error=0, all processes block during startup, waiting for
the debugger to attach.
2013-07-10 13:08:02 +02:00
Patrick Ohly
1538b89b36 PBAP: transfer data inside ReadItemAsKey
The previous attempt with concurrent reading while listing IDs did not
work, that listing must complete before the SyncML client contacts the
server. What works is transfering and parsing after the engine starts
to ask for the actual data.

For that we need to list IDs in advance. We use GetSize() for that.

If contacts get deleted while we read, getting the data for the
contacts at the end of the range will fail with 404, which is
understood by the Synthesis engine and leads to ignoring the ID, as
intended.

If contacts get added while we read, we will ignore them even if they
happen to be in the result of PullAll. The next sync will include
them.
2013-07-10 13:08:02 +02:00
Patrick Ohly
19aeba2029 PIM: use incremental sync for PBAP by default (FDO #59551)
When doing a PBAP sync, PIM manager asks the D-Bus sync helper to set
its SYNCEVOLUTION_PBAP_SYNC to "incremental". If the env variable
is already set, it does not get overwritten, which allows overriding
this default.
2013-07-10 13:08:02 +02:00
Patrick Ohly
7bd8a187d2 PIM testing: more flexible exclusion of empty vcard
Don't depend on order of properties, something else was seen.
2013-07-10 13:08:02 +02:00
Patrick Ohly
ddc1e53b0c PBAP: incremental sync (FDO #59551)
Depending on the SYNCEVOLUTION_PBAP_SYNC env variable, syncing reads
all properties as configured ("all"), excludes photos ("text") or
first text, then all ("incremental").

When excluding photos, only known properties get requested. This
avoids issues with phones which reject the request when enabling
properties via the bit flags. This also helps with
"databaseFormat=^PHOTO".

When excluding photos, the vcard merge script as used by EDS ensures
that existing photo data is preserved. This only works during a slow
sync (merge script not called otherwise, okay for PBAP because it
always syncs in slow sync) and EDS (other backends do not use the
merge script, okay at the moment because PIM Manager is hard-coded to
use EDS).

The PBAP backend must be aware of the PBAP sync mode and request a
second cycle, which again must be a slow sync. This only works because
the sync engine is aware of the special mode and sets a new session
variable "keepPhotoData". It would be better to have the PBAP backend
send CTCap with PHOTO marked as not supported for text-only syncs and
enabled when sending PHOTO data, but that is considerably harder to
implement (CTCap cannot be adjusted at runtime).

beginSync() may only ask for a slow sync when not already called
for one. That's what the command line tool does when accessing
items. It fails when getting the 508 status.

The original goal of overlapping syncing with download has not been
achieved yet. It turned out that all item IDs get requested before
syncing starts, which thus depends on downloading all items in the current
implementation. Can be fixed by making up IDs based on the number of
existing items (see GetSize() in PBAP) and then downloading later when
the data is needed.
2013-07-10 13:08:02 +02:00
Patrick Ohly
309bed01e1 SyncSource: avoid ERROR logging for 508 status code
Returning a 508 status from beginSync() via a StatusException is
valid, this should only be logged by the originator if it deems that
an error.
2013-07-10 13:08:02 +02:00
Patrick Ohly
6d3b1cf64b EDS: update PHOTO+GEO during slow sync, avoid rewriting PHOTO file
If PHOTO and/or GEO were the only modified properties during a slow
sync, the updated item was not written into local storage because
they were marked as compare="never" = "not relevant".

For PHOTO this was intentional in the sample config, with the
rationale that local storages often don't store the data exactly as
requested. When that happens, comparing the data would lead to
unnecessary writes. But EDS and probably all other local SyncEvolution
storages (KDE, file) store the photo exactly as requested, so not
considering changes had the undesirable effect of not always writing
new photo data.

For GEO, ignoring it was accidental.

A special merge script handles EDS file:// photo URIs. When the
loosing item has the data in a file and the winning item has binary
data, the data in the file may still be up-to-date, so before allowing
MERGEFIELDS() to overwrite the file reference with binary data and
thus forcing EDS to write a new file, check the content. If it
matches, use the file reference in both items.
2013-07-10 13:08:02 +02:00
Patrick Ohly
50c06bbe61 EDS contacts: read-ahead cache
Performance is improved by requesting multiple contacts at once and
overlapping reading with processing. On a fast system (SSD, CPU fast
enough to not be the limiting factor), testpim.py's testSync takes 8
seconds for a "match" sync where 1000 contacts get loaded and compared
against the same set of contacts. Read-ahead with only 1 contact per
query speeds that up to 6.7s due to overlapping IO and
processing. Read-ahead with the default 50 contacts per query takes
5.5s. It does not get much faster with larger queries.

While returning items from one cache populated with a single
e_book_client_get_contacts() call, another query is started to overlap
processing and loading.

To achieve efficient read-ahead, the backend relies on the hint given
to it via setReadAheadOrder(). As soon as it detects that a contact is
not the next one according to that order, it switches back to reading
one contact at a time. This happens during the write phase of a sync
where the Synthesis engine needs to read, update, and write back
changes based on updates sent by the peer.

Cache statistics show that this works well for --print-items, --export
and slow syncs.

Writing into the database must invalidate the corresponding cached
contact. Otherwise the backup operation after a sync may end up
reading stale data.
2013-07-10 13:07:53 +02:00
Patrick Ohly
7d12c0a586 read-ahead: tell SyncSource about the upcoming read accesses
Trying to predict in the SyncSource which items will be needed is
hard. It depends what the item is retrieved for (sync or
backup/printing) and on the sync mode (during a sync).

Instead of guessing, better have the user of the source tell the
source in advance what it will read. In most cases this is cheap
because it does not involve copying of items luids ("read all items",
"read new or modified items"). The source then can use its own internal
mechanisms to figure out what that means.

Only extracting specific items specified on the command line and the
backup operation must explicitly pass an ordered list of luids. For
the sake of simplicity, do that in a std::vector even though it
involves copying.
2013-07-10 13:07:44 +02:00
Patrick Ohly
81fdf67437 glib: allow other threads to check something after each main loop iteration
The
  while (<something>) g_main_context_iterate(NULL, true);
pattern only works in the main thread. As soon as multiple
threads are allowed to process events, race conditions occur,
as described before.

But the pattern is useful, so support it in all threads by
shifting the check into the main thread, which will then notify
other threads via a condition variable when something changes.
2013-07-10 13:07:35 +02:00
Patrick Ohly
ce1809d811 Threading: add Cond class
A thin wrapper around GMutex, initializes the condition variable
automatically.
2013-07-05 17:44:20 +02:00
Patrick Ohly
8ba5b42b92 Threading: fix Dyn*Mutex
gcc complained about the "protected" m_mutex access. Apparently
it did not realize that the access was to a base class. An explicit
get() solves that. Another way to get the pointer is a type cast.
2013-07-05 17:44:20 +02:00
Patrick Ohly
a5fd9df29d PBAP: refactor PbapSyncSource, asyncronous transfer, report items immediately
Derive from SyncSource and SyncSourceSession directly instead of going
through TrackingSyncSource. This allows removing several dummy methods
that we have to implement for TrackingSyncSource and allows
reporting existing items incrementally, instead of having to load all
of them at once for the old listAllItems().

Contacts are now already reported to the engine while their transfer
still runs. That depends on monitoring the temporary file, remapping
the larger file and continuing parsing where the previous parsing
stopped.

This only works with obexd 0.47 and obexd from Bluez 5, because it
depends on the temporary file interface. The older PullAll did not
return any data until it had downloaded everything.

Because it isn't known when the contact data will be needed, the backend
still maintains the mapping from ID to vCard data for all contacts seen
in the current session. Because that memory is backed by a temporary file
system, unused memory can be swapped out (and in) well by the OS.

If the file is in a ram-based temp file system, then it may also not
matter at all that the file gets mapped multiple times.
2013-07-05 17:44:20 +02:00
Patrick Ohly
37c29253cf GErrorCXX: add take()
The other methods always make a copy of the GError. The new take()
method takes over ownership. Use in combination with g_error_new().
2013-07-05 17:44:20 +02:00
Patrick Ohly
55c0806800 command line: execute --export and --print-items while the source is still reading
Instead of reading all item IDs, then iterating over them, process
each new ID as soon as it is available. With sources that support
incremental reading (only the PBAP source at the moment) that provides
output sooner and is a bit more memory efficient.
2013-07-05 17:44:20 +02:00
Patrick Ohly
e6c07b32b9 TmpFile: add moreData() and remove()
remove() is useful when want to continue using the file but also want
to ensure that it gets deleted when we crash.

moreData() can be used to determine if the file has grown since the
last time that map() was called. In other words, it supports
processing data while obexd still writes into the file.
2013-07-05 17:44:20 +02:00
Patrick Ohly
d0626ea46c GDBus GIO: support int64_t and uint64_t
The dbus_traits for them were simply missing.
2013-07-05 17:44:20 +02:00
Patrick Ohly
4bf2adbe25 GDBus GIO: avoid unnecessary case-insentive type comparison.
The type is already lower-case on both sides, so there's no
need for the case-insensitive comparison.
2013-07-05 17:44:20 +02:00
Patrick Ohly
25f24387c3 PBAP: fix support for obexd == 0.47, break 0.48
The previous commit "PBAP: fix support for obexd >= 0.47 and < Bluez 5"
made the backend work with obexd 0.48 and broke it with 0.47. That's because
there was another API change between 0.47 and 0.48, which wasn't known
at the time of that commit.

SyncEvolution now works with 0.47 and does not work with 0.48. This choice
was made because 0.47 supports the file-based data transfer (same as in Bluez 5
and thus useful for testing when Bluez 5 is not available) and 0.47 still
compiles against older Bluez versions (which makes it easier to use than 0.48).
2013-07-05 17:44:10 +02:00
Patrick Ohly
eca4dcb4b5 SuspendFlags: make it thread-safe
A new internal recursive mutex protects data that may get accessed
from different threads. It's recursive because callbacks may need to
lock it again.
2013-07-05 17:44:10 +02:00
Patrick Ohly
0c63a4f7f0 D-Bus testing: support git glib/gobject bindings
More recent GNOME Python bindings are provided by gobject
introspection. The traditional gobject/glib modules no
longer exist.

The API is similar enough that we just need to adapt importing: if
importing the normal modules fails, try importing from gi.repository
instead.
2013-07-05 17:44:10 +02:00
Patrick Ohly
dfd0bc29af EDS contacts: avoid unnecessary DB writes during slow sync due to FILE-AS
EDS 3.8 sets X-EVOLUTION-FILE-AS to "last, first" when a contact is
created without it. This leads again to unnecessary DB updates because
the incoming item that the engine works with doesn't have that field
set.

To mitigate that issue, set FILE_AS (renamed to make the field name
valid in a script) like EDS would do during writing.

The downside is that all incoming items now have FILE_AS set, which
will overwrite a locally stored copy of that property even if the peer
did not store X-EVOLUTION-FILE-AS. Previously, as tested by
testExtension, the local value was preserved. There is no good solution
that works for both use cases, so allow X-EVOLUTION-FILE-AS to get lost
and relax the test.
2013-07-05 17:44:10 +02:00
Patrick Ohly
d2a43b1e50 EDS contacts: avoid unnecessary DB writes during slow sync
Traditionally, contacts were modified shortly before writing into EDS
to match with Evolution expectations (must have N, only one CELL TEL,
VOICE flag must be set). During a slow sync, the engine compare the
modified contacts with the unmodified, incoming one. This led to
mismatches and/or merge operations which end up not changing anything
in the DB because the only difference would be removed again before
writing.

To avoid this, define datatypes which include the EDS modifications in
its <incomingscript>. Then the engine works with an item as it would
be written to EDS and correctly determines that the incoming and DB
items are identical.

Found in testpim.py's testSync when applied to the test cases
generated by the Openismus test case generator.
2013-07-05 17:44:10 +02:00
Patrick Ohly
634e5e4e90 EDS: avoid retrieving REV/LAST-MODIFIED if not needed
If the sources are used in a mode which doesn't need revision strings,
then skip the retrieval of items from the EDS daemons when we would
normally do it to get the revision string.
2013-07-05 17:44:10 +02:00
Patrick Ohly
6c551167c4 engine: change tracking optional for caching mode and item modification
Recording the revision of items during a caching sync is unnecessary
because the next sync will not use the information. For item
modifications, the information was not even recorded.

Now a "don't need changes" mode can be set in SyncSource, which is
done for caching and command line item operations. This is better than
second-guessing the mode in which a source is used.

SyncSourceRevision checks that flag and skips updating the
luid->revision mapping if set.

Individual backends can also check the flag and skip calculating the
revision to begin with.
2013-07-05 17:44:10 +02:00
Patrick Ohly
b7ea49ea8d EDS: implement batched add/update of contacts
Only works when compiled for EDS >= 3.6. Uses the new ITEM_AGAIN in
SyncSourceSerialize. Combines multiple add/update operations into one
asynchronous batch operation which can overlap with network IO if
the engine supports it.
2013-07-05 17:44:10 +02:00
Patrick Ohly
0b35ac1e6d engine: enable out-of-order command execution for SyncEvolution<->SyncEvolution
To take full advantage of batch operations, we must enable out-of-order
execution of commands. Otherwise the engine will never issue more than
one change to us. Do it for SyncEvolution as peer.

TODO: do it for all peers or disable batched processing when it is not
enabled.
2013-07-05 17:44:09 +02:00
Patrick Ohly
ebef300ae5 SyncSource: support asynchronous add/update in utility classes
SyncSourceSerialize uses ITEM_AGAIN plus a callback in
InsertItemResult to indicate that and how an insert (aka add or
update) operation must be continued.

TrackingSyncSource merely passes that result through until it finally
completes.

Direct, raw access to items as done by the command line and restore
operations is not done asynchronously. The backend does not need to
know how it is used, the SyncSourceSerialize wrapper around the
backend will flush and wait.

Asynchronous deleting is not supported. It would require throwing an
exception or an API change (better - exceptions are for errors!)
because removeItem() has no return code which could be extended.
2013-07-05 17:44:09 +02:00
Patrick Ohly
856295b1e1 SyncSource: optional support for asynchronous insert/update/delete
The wrapper around the actual operation checks if the operation
returned an error or result code (traditional behavior). If not, it
expects a ContinueOperation instance, remembers it and calls it when
the same operation gets called again for the same item.

For add/insert, "same item" is detected based on the KeyH address,
which must not change. For delete, the item local ID is used.

Pre- and post-signals are called exactly once, before the first call
and after the last call of the item.

ContinueOperation is a simple boost::function pointer for now. The
Synthesis engine itself is not able to force completion of the
operation, it just polls. This can lead to many empty messages with
just an Alert inside, thus triggering the "endless loop" protection,
which aborts the sync.

We overcome this limitation in the SyncEvolution layer above the
Synthesis engine: first, we flush pending operations before starting
network IO. This is a good place to batch together all pending
operations. Second, to overcome the "endless loop" problem, we force
a waiting for completion if the last message already was empty. If
that happened, we are done with items and should start sending our
responses.

Binding a function which returns the traditional TSyError still works
because it gets copied transparently into the boost::variant that the
wrapper expects, so no other code in SyncSource or backends needs to
be adapted. Enabling the use of LOCERR_AGAIN in the utility classes
and backends will follow in the next patches.
2013-07-05 17:44:09 +02:00
Patrick Ohly
b072af3dc1 engine: make FinalizeLocalID a real NOP
The function gets called and always logged the same "not implemented",
which unnecessarily increased the size of log files. Return directly.
2013-07-05 17:44:09 +02:00
Patrick Ohly
c4de1cb227 SyncSource: simplify getPre/PostSignal()
Const-casting the member references is easier (= less code) because we
have a typedef for them and we can omit the access via "this".
2013-07-05 17:44:09 +02:00
Patrick Ohly
790502be21 PIM testing: enhance testFilterLiveLimit
Check conditions each time they change as part of view updates. This
would have helped to find the invalid check earlier and catches
temporary violations of the invariants.
2013-07-05 17:44:09 +02:00
Patrick Ohly
b9e4bb995f PIM testing: fix testView and testViewSorting
The assertEqual() expected 'quiesence' to be seen, but runUntil() was not
asked to run until that was seen. Therefore tests failed randomly depending on
timing: they passed if the quiescence signal was processed in the same event
loop run as the change that was waited for and failed if it arrived later.

Fixed by waiting for 'quiesence' explicitly. It should arrive last.
2013-07-05 17:44:09 +02:00
Patrick Ohly
65fc725020 PIM testing: fixed testFilterLiveLimit
When "Abraham" falls out of the view, it is possible that we have temporarily
no contacts in the view, because first "Abraham" gets reviewed and then
"Benjamin" gets added. The check "at least one contact" therefore was too
strict.
2013-07-05 17:44:09 +02:00
Patrick Ohly
6a69b3f7e7 PIM testing: revise state checking
So far, a "check" callback was passed to runUntil() which checked the state
after each main loop run and at regular time intervals. The downside was that
an incorrect state change inside a single main loop run (for example, removing
a contact and adding one in testMerge) was not detected.

To increase coverage of state changes, the check is now also invoked after
each method call in the ViewAgent. If a check fails, it gets recorded as
error in the view and then will get noticed outside of the event loop by the
check that is passed to runUntil().

These checks needs to be installed before running the command line which
changes the state, not just as part of runTime(), because running the command
line also processes glib events.

This insufficient coverage was found when changes in timing caused testMerge
to fail: the previous check for "always exactly one contact" turned out to be
too strict and merely passed when remove + add were processed together. In
practice, the contact's ID changes because folks ties the merged contact to
a different primary store than the unmerged, original contact.
2013-07-05 17:44:09 +02:00
Patrick Ohly
08053b2ee7 PIM testing: testSync + test case files
TESTPIM_TEST_SYNC_TESTCASES can be set to the name of a file
containing contacts in vCard 3.0 format with an empty line as
separator. In this mode, testSync() measures the duration of cleaning
the local cache, importing all test cases, matching them against the
cache (which must not write into the cache!) and removing the cached
contacts.
2013-07-05 17:44:09 +02:00
Patrick Ohly
a2c9ad75fe PIM: set debug level in peer configs via env variable
Typically the peer configs get created from scratch, in particular
when testing with testpim.py. In that case the log level cannot be set
in advance and doing it via the D-Bus API is also not supported.
Therefore, for debugging, use SYNCEVOLUTION_LOGLEVEL=<level> to create
peers with a specific log level.
2013-07-05 17:44:09 +02:00
Patrick Ohly
445d534388 SyncContext: "server" -> "peer" in debug message
The error message also applies to SyncML clients, so use "peer"
instead of "server".
2013-07-05 17:44:08 +02:00