2005-11-25 21:50:21 +01:00
|
|
|
/*
|
2006-12-10 18:35:20 +01:00
|
|
|
* Copyright (C) 2005-2006 Patrick Ohly
|
|
|
|
* Copyright (C) 2007 Funambol
|
2005-11-25 21:50:21 +01:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2007-03-11 23:13:13 +01:00
|
|
|
#include <config.h>
|
|
|
|
|
2007-10-11 23:02:49 +02:00
|
|
|
#include "EvolutionSyncClient.h"
|
2005-11-25 21:50:21 +01:00
|
|
|
#include "EvolutionSyncSource.h"
|
2005-11-26 22:16:03 +01:00
|
|
|
#include "EvolutionContactSource.h"
|
2006-04-09 13:48:11 +02:00
|
|
|
#include "EvolutionCalendarSource.h"
|
2007-04-15 15:42:42 +02:00
|
|
|
#include "EvolutionMemoSource.h"
|
2007-08-13 22:46:49 +02:00
|
|
|
#include "SQLiteContactSource.h"
|
2007-08-19 21:11:20 +02:00
|
|
|
#include "AddressBookSource.h"
|
2005-11-25 21:50:21 +01:00
|
|
|
|
2005-11-26 22:16:03 +01:00
|
|
|
#include <common/base/Log.h>
|
|
|
|
|
2007-03-11 23:13:13 +01:00
|
|
|
#include <list>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
2007-08-13 22:46:49 +02:00
|
|
|
#ifdef HAVE_EDS
|
2005-11-26 22:16:03 +01:00
|
|
|
ESource *EvolutionSyncSource::findSource( ESourceList *list, const string &id )
|
2005-11-25 21:50:21 +01:00
|
|
|
{
|
|
|
|
for (GSList *g = e_source_list_peek_groups (list); g; g = g->next) {
|
|
|
|
ESourceGroup *group = E_SOURCE_GROUP (g->data);
|
|
|
|
GSList *s;
|
|
|
|
for (s = e_source_group_peek_sources (group); s; s = s->next) {
|
|
|
|
ESource *source = E_SOURCE (s->data);
|
2006-06-10 14:26:44 +02:00
|
|
|
char *uri = e_source_get_uri(source);
|
|
|
|
bool found = !id.compare(e_source_peek_name(source)) ||
|
|
|
|
(uri && !id.compare(uri));
|
|
|
|
g_free(uri);
|
|
|
|
if (found) {
|
2005-11-25 21:50:21 +01:00
|
|
|
return source;
|
2006-06-10 14:26:44 +02:00
|
|
|
}
|
2005-11-25 21:50:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-08-13 22:46:49 +02:00
|
|
|
#endif // HAVE_EDS
|
2005-11-25 21:50:21 +01:00
|
|
|
|
2007-08-13 22:46:49 +02:00
|
|
|
void EvolutionSyncSource::throwError( const string &action
|
|
|
|
#ifdef HAVE_EDS
|
|
|
|
, GError *gerror
|
|
|
|
#endif
|
|
|
|
)
|
2005-11-25 21:50:21 +01:00
|
|
|
{
|
|
|
|
string gerrorstr;
|
2007-08-13 22:46:49 +02:00
|
|
|
#ifdef HAVE_EDS
|
2005-11-25 21:50:21 +01:00
|
|
|
if (gerror) {
|
2006-05-29 21:32:58 +02:00
|
|
|
gerrorstr += ": ";
|
2005-11-25 21:50:21 +01:00
|
|
|
gerrorstr += gerror->message;
|
|
|
|
g_clear_error(&gerror);
|
2007-08-13 22:46:49 +02:00
|
|
|
} else
|
|
|
|
#endif
|
2007-10-11 23:02:49 +02:00
|
|
|
gerrorstr = ": failure";
|
2005-11-26 22:16:03 +01:00
|
|
|
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(string(getName()) + ": " + action + gerrorstr);
|
2005-11-26 22:16:03 +01:00
|
|
|
}
|
|
|
|
|
2007-08-13 22:46:49 +02:00
|
|
|
|
2005-11-26 22:16:03 +01:00
|
|
|
void EvolutionSyncSource::resetItems()
|
|
|
|
{
|
|
|
|
m_allItems.clear();
|
|
|
|
m_newItems.clear();
|
|
|
|
m_updatedItems.clear();
|
|
|
|
m_deletedItems.clear();
|
2005-11-25 21:50:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
string EvolutionSyncSource::getData(SyncItem& item)
|
|
|
|
{
|
|
|
|
char *mem = (char *)malloc(item.getDataSize() + 1);
|
|
|
|
memcpy(mem, item.getData(), item.getDataSize());
|
|
|
|
mem[item.getDataSize()] = 0;
|
|
|
|
|
|
|
|
string res(mem);
|
|
|
|
free(mem);
|
|
|
|
return res;
|
|
|
|
}
|
2005-11-26 22:16:03 +01:00
|
|
|
|
|
|
|
string EvolutionSyncSource::getPropertyValue(ManagementNode &node, const string &property)
|
|
|
|
{
|
2006-11-27 22:08:12 +01:00
|
|
|
char *value = node.readPropertyValue(property.c_str());
|
2005-11-26 22:16:03 +01:00
|
|
|
string res;
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
res = value;
|
|
|
|
delete [] value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2006-05-26 14:49:19 +02:00
|
|
|
void EvolutionSyncSource::handleException()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
throw;
|
|
|
|
} catch (std::exception &ex) {
|
|
|
|
if (lastErrorCode == ERR_NONE) {
|
|
|
|
lastErrorCode = ERR_UNSPECIFIED;
|
|
|
|
strcpy(lastErrorMsg, ex.what());
|
|
|
|
}
|
|
|
|
LOG.error("%s", ex.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-26 22:16:03 +01:00
|
|
|
EvolutionSyncSource *EvolutionSyncSource::createSource(
|
|
|
|
const string &name,
|
2007-08-21 22:15:32 +02:00
|
|
|
ManagementNode *node,
|
2006-10-03 13:44:34 +02:00
|
|
|
SyncSourceConfig *sc,
|
2005-11-26 22:16:03 +01:00
|
|
|
const string &changeId,
|
|
|
|
const string &id,
|
2007-03-11 23:13:13 +01:00
|
|
|
const string &mimeType,
|
|
|
|
bool error
|
2005-11-26 22:16:03 +01:00
|
|
|
)
|
|
|
|
{
|
2006-04-09 13:48:11 +02:00
|
|
|
// remove special characters from change ID
|
|
|
|
string strippedChangeId = changeId;
|
2006-06-11 22:07:26 +02:00
|
|
|
size_t offset = 0;
|
2006-04-09 13:48:11 +02:00
|
|
|
while (offset < strippedChangeId.size()) {
|
|
|
|
switch (strippedChangeId[offset]) {
|
|
|
|
case ':':
|
|
|
|
case '/':
|
|
|
|
case '\\':
|
|
|
|
strippedChangeId.erase(offset, 1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
offset++;
|
2005-12-03 15:33:41 +01:00
|
|
|
}
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
2007-03-11 23:13:13 +01:00
|
|
|
#ifdef ENABLE_MODULES
|
|
|
|
|
|
|
|
static list<CreateSource_t>createSources;
|
|
|
|
static bool scannedModules;
|
|
|
|
static string available;
|
|
|
|
static string missing;
|
|
|
|
|
|
|
|
if (!scannedModules) {
|
|
|
|
// possible extension: scan directories for matching module names instead of hard-coding known names
|
|
|
|
const char *modules[] = {
|
|
|
|
"syncebook.so.0",
|
|
|
|
"syncecal.so.0",
|
2007-08-13 22:46:49 +02:00
|
|
|
"syncsqlite.so.0",
|
2007-10-12 18:50:08 +02:00
|
|
|
"addressbook.so.0",
|
2007-03-11 23:13:13 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
for (int i = 0; modules[i]; i++) {
|
|
|
|
void *dlhandle;
|
|
|
|
|
2007-03-24 23:50:25 +01:00
|
|
|
dlhandle = dlopen(modules[i], RTLD_NOW|RTLD_GLOBAL);
|
2007-03-11 23:13:13 +01:00
|
|
|
if (dlhandle) {
|
|
|
|
void *createSource = dlsym(dlhandle, "SyncEvolutionCreateSource");
|
|
|
|
|
|
|
|
if (createSource) {
|
|
|
|
createSources.push_back((CreateSource_t)createSource);
|
|
|
|
} else {
|
|
|
|
dlclose(dlhandle);
|
|
|
|
dlhandle = NULL;
|
|
|
|
}
|
|
|
|
} else if(error) {
|
2007-03-24 23:50:25 +01:00
|
|
|
LOG.debug("%s", dlerror());
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// remember which modules were found and which were not
|
|
|
|
string &res(dlhandle ? available : missing);
|
|
|
|
if (res.size()) {
|
|
|
|
res += " ";
|
|
|
|
}
|
|
|
|
res += modules[i];
|
|
|
|
}
|
|
|
|
scannedModules = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (list<CreateSource_t>::const_iterator it = createSources.begin();
|
|
|
|
it != createSources.end();
|
|
|
|
++it) {
|
|
|
|
EvolutionSyncSource *source = (*it)(name, sc, strippedChangeId, id, mimeType);
|
|
|
|
if (source) {
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
string problem = name + ": type '" + mimeType + "' not supported";
|
|
|
|
if (available.size()) {
|
|
|
|
problem += " by any of the available backends (";
|
|
|
|
problem += available;
|
|
|
|
problem += ")";
|
|
|
|
}
|
|
|
|
if (missing.size()) {
|
|
|
|
problem += ". The following backend(s) were not found: ";
|
|
|
|
problem += missing;
|
|
|
|
}
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(problem);
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#else // ENABLE_MODULES
|
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
if (mimeType == "text/x-vcard") {
|
2006-07-23 12:27:21 +02:00
|
|
|
#ifdef ENABLE_EBOOK
|
2006-09-29 01:02:43 +02:00
|
|
|
return new EvolutionContactSource(name, sc, strippedChangeId, id, EVC_FORMAT_VCARD_21);
|
2006-07-23 12:27:21 +02:00
|
|
|
#else
|
2007-03-11 23:13:13 +01:00
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to addressbooks not compiled into this binary, text/x-vcard not supported");
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
2006-07-23 12:27:21 +02:00
|
|
|
#endif
|
2006-04-26 22:44:41 +02:00
|
|
|
} else if (mimeType == "text/vcard") {
|
2006-07-23 12:27:21 +02:00
|
|
|
#ifdef ENABLE_EBOOK
|
2006-09-29 01:02:43 +02:00
|
|
|
return new EvolutionContactSource(name, sc, strippedChangeId, id, EVC_FORMAT_VCARD_30);
|
2006-07-23 12:27:21 +02:00
|
|
|
#else
|
2007-03-11 23:13:13 +01:00
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to addressbooks not compiled into this binary, text/vcard not supported");
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
2006-07-23 12:27:21 +02:00
|
|
|
#endif
|
2006-04-09 13:48:11 +02:00
|
|
|
} else if (mimeType == "text/x-todo") {
|
2006-07-23 12:27:21 +02:00
|
|
|
#ifdef ENABLE_ECAL
|
2006-09-29 01:02:43 +02:00
|
|
|
return new EvolutionCalendarSource(E_CAL_SOURCE_TYPE_TODO, name, sc, strippedChangeId, id);
|
2006-07-23 12:27:21 +02:00
|
|
|
#else
|
2007-03-11 23:13:13 +01:00
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to calendars not compiled into this binary, text/x-todo not supported");
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
2007-01-04 21:54:11 +01:00
|
|
|
#endif
|
|
|
|
} else if (mimeType == "text/x-journal") {
|
|
|
|
#ifdef ENABLE_ECAL
|
|
|
|
return new EvolutionCalendarSource(E_CAL_SOURCE_TYPE_JOURNAL, name, sc, strippedChangeId, id);
|
|
|
|
#else
|
2007-03-11 23:13:13 +01:00
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to memos not compiled into this binary, text/x-journal not supported");
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
2007-04-15 15:42:42 +02:00
|
|
|
#endif
|
|
|
|
} else if (mimeType == "text/plain") {
|
|
|
|
#ifdef ENABLE_ECAL
|
|
|
|
return new EvolutionMemoSource(E_CAL_SOURCE_TYPE_JOURNAL, name, sc, strippedChangeId, id);
|
|
|
|
#else
|
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to memos not compiled into this binary, text/plain not supported");
|
2007-04-15 15:42:42 +02:00
|
|
|
}
|
2006-07-23 12:27:21 +02:00
|
|
|
#endif
|
2006-04-09 13:48:11 +02:00
|
|
|
} else if (mimeType == "text/calendar" ||
|
|
|
|
mimeType == "text/x-vcalendar") {
|
2006-07-23 12:27:21 +02:00
|
|
|
#ifdef ENABLE_ECAL
|
2006-09-29 01:02:43 +02:00
|
|
|
return new EvolutionCalendarSource(E_CAL_SOURCE_TYPE_EVENT, name, sc, strippedChangeId, id);
|
2006-07-23 12:27:21 +02:00
|
|
|
#else
|
2007-03-11 23:13:13 +01:00
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to calendars not compiled into this binary, " + mimeType + " not supported");
|
2007-03-11 23:13:13 +01:00
|
|
|
}
|
2007-08-13 22:46:49 +02:00
|
|
|
#endif
|
|
|
|
} else if (mimeType == "sqlite") {
|
|
|
|
#ifdef ENABLE_SQLITE
|
2008-01-14 22:25:03 +01:00
|
|
|
arrayptr<char> configNodeName(node ? node->createFullName() : wstrdup(""));
|
|
|
|
string trackingNodeName = configNodeName.get();
|
|
|
|
trackingNodeName += "/changes";
|
|
|
|
eptr<spdm::DeviceManagementNode> trackingNode(new spdm::DeviceManagementNode(trackingNodeName.c_str()), "tracking node");
|
|
|
|
|
|
|
|
return new SQLiteContactSource(name, sc, strippedChangeId, id, trackingNode);
|
2007-08-13 22:46:49 +02:00
|
|
|
#else
|
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to sqlite not compiled into this binary, " + mimeType + " not supported");
|
2007-08-13 22:46:49 +02:00
|
|
|
}
|
2007-08-19 21:11:20 +02:00
|
|
|
#endif
|
2007-08-25 15:23:25 +02:00
|
|
|
} else if (mimeType == "addressbook") {
|
2007-08-19 21:11:20 +02:00
|
|
|
#ifdef ENABLE_ADDRESSBOOK
|
2007-08-21 22:15:32 +02:00
|
|
|
return new AddressBookSource(name, sc, strippedChangeId, id, string(configNodeName));
|
2007-08-19 21:11:20 +02:00
|
|
|
#else
|
|
|
|
if (error) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError(name + ": access to Mac OS X address book not compiled into this binary, not supported");
|
2007-08-19 21:11:20 +02:00
|
|
|
}
|
2006-07-23 12:27:21 +02:00
|
|
|
#endif
|
2005-11-26 22:16:03 +01:00
|
|
|
}
|
2007-03-11 23:13:13 +01:00
|
|
|
#endif // ENABLE_MODULES
|
2005-11-26 22:16:03 +01:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
int EvolutionSyncSource::beginSync()
|
|
|
|
{
|
2006-05-25 19:32:07 +02:00
|
|
|
string buffer;
|
|
|
|
buffer += getName();
|
|
|
|
buffer += ": sync mode is ";
|
2006-04-09 13:48:11 +02:00
|
|
|
SyncMode mode = getSyncMode();
|
2006-05-25 19:32:07 +02:00
|
|
|
buffer += mode == SYNC_SLOW ? "'slow'" :
|
|
|
|
mode == SYNC_TWO_WAY ? "'two-way'" :
|
|
|
|
mode == SYNC_REFRESH_FROM_SERVER ? "'refresh from server'" :
|
|
|
|
mode == SYNC_REFRESH_FROM_CLIENT ? "'refresh from client'" :
|
2006-09-08 21:55:40 +02:00
|
|
|
mode == SYNC_ONE_WAY_FROM_SERVER ? "'one-way from server'" :
|
|
|
|
mode == SYNC_ONE_WAY_FROM_CLIENT ? "'one-way from client'" :
|
2006-05-25 19:32:07 +02:00
|
|
|
mode == SYNC_NONE ? "'none' (for debugging)" :
|
2006-04-09 13:48:11 +02:00
|
|
|
"???";
|
|
|
|
LOG.info( buffer.c_str() );
|
|
|
|
|
2007-11-03 18:07:42 +01:00
|
|
|
// start background thread if not running yet:
|
|
|
|
// necessary to catch problems with Evolution backend
|
|
|
|
EvolutionSyncClient::startLoopThread();
|
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
try {
|
2007-04-21 15:14:43 +02:00
|
|
|
// reset anchors now, once we proceed there is no going back
|
|
|
|
// (because the change marker is about to be moved)
|
|
|
|
// and the sync must either complete or result in a slow sync
|
|
|
|
// the next time
|
|
|
|
getConfig().setLast(0);
|
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
const char *error = getenv("SYNCEVOLUTION_BEGIN_SYNC_ERROR");
|
|
|
|
if (error && strstr(error, getName())) {
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError("artificial error in beginSync()");
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// reset state
|
|
|
|
m_isModified = false;
|
|
|
|
m_allItems.clear();
|
|
|
|
m_newItems.clear();
|
|
|
|
m_updatedItems.clear();
|
|
|
|
m_deletedItems.clear();
|
|
|
|
|
|
|
|
// determine what to do
|
|
|
|
bool needAll = false;
|
|
|
|
bool needPartial = false;
|
|
|
|
bool deleteLocal = false;
|
|
|
|
switch (mode) {
|
|
|
|
case SYNC_SLOW:
|
|
|
|
needAll = true;
|
|
|
|
m_isModified = true;
|
|
|
|
break;
|
2006-11-04 14:00:47 +01:00
|
|
|
case SYNC_ONE_WAY_FROM_CLIENT:
|
2006-04-09 13:48:11 +02:00
|
|
|
case SYNC_TWO_WAY:
|
|
|
|
needPartial = true;
|
|
|
|
break;
|
|
|
|
case SYNC_REFRESH_FROM_SERVER:
|
|
|
|
deleteLocal = true;
|
|
|
|
m_isModified = true;
|
|
|
|
break;
|
|
|
|
case SYNC_REFRESH_FROM_CLIENT:
|
|
|
|
needAll = true;
|
2006-08-17 23:39:29 +02:00
|
|
|
m_isModified = true;
|
2006-04-09 13:48:11 +02:00
|
|
|
break;
|
|
|
|
case SYNC_NONE:
|
|
|
|
// special mode for testing: prepare both all and partial lists
|
|
|
|
needAll = needPartial = true;
|
|
|
|
break;
|
2006-11-04 14:00:47 +01:00
|
|
|
case SYNC_ONE_WAY_FROM_SERVER:
|
|
|
|
// nothing to do, just wait for server's changes
|
|
|
|
break;
|
2006-04-09 13:48:11 +02:00
|
|
|
default:
|
2007-10-11 23:02:49 +02:00
|
|
|
EvolutionSyncClient::throwError("unsupported sync mode, valid are only: slow, two-way, refresh");
|
2006-04-09 13:48:11 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
beginSyncThrow(needAll, needPartial, deleteLocal);
|
|
|
|
} catch( ... ) {
|
2006-05-26 14:49:19 +02:00
|
|
|
handleException();
|
2007-08-21 22:15:32 +02:00
|
|
|
setFailed(true);
|
2006-04-09 13:48:11 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int EvolutionSyncSource::endSync()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
endSyncThrow();
|
|
|
|
} catch ( ... ) {
|
2006-05-26 14:49:19 +02:00
|
|
|
handleException();
|
2007-08-21 22:15:32 +02:00
|
|
|
setFailed(true);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
2006-05-25 19:32:07 +02:00
|
|
|
|
|
|
|
// Do _not_ tell the caller (SyncManager) if an error occurred
|
|
|
|
// because that causes Sync4jClient to abort processing for all
|
|
|
|
// sync sources. Instead deal with failed sync sources in
|
|
|
|
// EvolutionSyncClient::sync().
|
|
|
|
return 0;
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
2005-11-26 22:16:03 +01:00
|
|
|
void EvolutionSyncSource::setItemStatus(const char *key, int status)
|
|
|
|
{
|
2006-04-09 13:48:11 +02:00
|
|
|
try {
|
|
|
|
// TODO: logging
|
|
|
|
setItemStatusThrow(key, status);
|
|
|
|
} catch (...) {
|
2006-05-26 14:49:19 +02:00
|
|
|
handleException();
|
2007-08-21 22:15:32 +02:00
|
|
|
setFailed(true);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int EvolutionSyncSource::addItem(SyncItem& item)
|
|
|
|
{
|
2006-06-15 17:12:11 +02:00
|
|
|
return processItem("add", &EvolutionSyncSource::addItemThrow, item, true);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
2005-11-26 22:16:03 +01:00
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
int EvolutionSyncSource::updateItem(SyncItem& item)
|
|
|
|
{
|
2006-06-15 17:12:11 +02:00
|
|
|
return processItem("update", &EvolutionSyncSource::updateItemThrow, item, true);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int EvolutionSyncSource::deleteItem(SyncItem& item)
|
|
|
|
{
|
2006-06-15 17:12:11 +02:00
|
|
|
return processItem("delete", &EvolutionSyncSource::deleteItemThrow, item, false);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int EvolutionSyncSource::processItem(const char *action,
|
2006-04-17 11:41:37 +02:00
|
|
|
int (EvolutionSyncSource::*func)(SyncItem& item),
|
2006-06-15 17:12:11 +02:00
|
|
|
SyncItem& item,
|
|
|
|
bool needData)
|
2006-04-09 13:48:11 +02:00
|
|
|
{
|
2006-04-17 11:41:37 +02:00
|
|
|
int status = STC_COMMAND_FAILED;
|
|
|
|
|
2006-04-09 13:48:11 +02:00
|
|
|
try {
|
|
|
|
logItem(item, action);
|
2006-06-17 22:07:38 +02:00
|
|
|
if (needData && (item.getDataSize() < 0 || !item.getData())) {
|
2006-06-15 17:12:11 +02:00
|
|
|
// Something went wrong in the server: update or add without data.
|
|
|
|
// Shouldn't happen, but it did with one server and thus this
|
|
|
|
// security check was added to prevent segfaults.
|
|
|
|
logItem(item, "ignored due to missing data");
|
|
|
|
status = STC_OK;
|
|
|
|
} else {
|
|
|
|
status = (this->*func)(item);
|
|
|
|
}
|
2006-04-09 13:48:11 +02:00
|
|
|
m_isModified = true;
|
|
|
|
} catch (...) {
|
2006-05-26 14:49:19 +02:00
|
|
|
handleException();
|
2007-08-21 22:15:32 +02:00
|
|
|
setFailed(true);
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
2006-04-17 11:41:37 +02:00
|
|
|
return status;
|
2006-04-09 13:48:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void EvolutionSyncSource::setItemStatusThrow(const char *key, int status)
|
|
|
|
{
|
2006-05-25 12:35:36 +02:00
|
|
|
switch (status) {
|
|
|
|
case STC_ALREADY_EXISTS:
|
|
|
|
// found pair during slow sync, that's okay
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (status < 200 || status > 300) {
|
2006-05-25 19:32:07 +02:00
|
|
|
LOG.error("%s: unexpected SyncML status response %d for item %.80s\n",
|
|
|
|
getName(), status, key);
|
2007-08-21 22:15:32 +02:00
|
|
|
setFailed(true);
|
2006-05-25 12:35:36 +02:00
|
|
|
}
|
2005-11-26 22:16:03 +01:00
|
|
|
}
|
|
|
|
}
|