C++: replace boost::shared_ptr, boost::function, boost::bind
We can use std::shared_ptr and std::function instead now. Lambdas are usually a better alternative to boost/std::bind. The downside is the need to explicitly specify parameters completely. When inlining callbacks entirely with lambdas, duplication of that parameter list can be avoided. Whenever possible, use std::make_shared to construct objects that are tracked by std::shared_ptr. Some objects need a std::weak_ptr during object destruction. For that we have to use our own implementation of std::enable_shared_from_this, with a matching creator function. The additional benefit is that we can get rid of explicit static "create" methods by making that create function a friend. Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
This commit is contained in:
parent
d0c08bf0dd
commit
2fa3c3335a
|
@ -70,9 +70,9 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
||||||
size_t nextpos = value.find('/', pos + 1);
|
size_t nextpos = value.find('/', pos + 1);
|
||||||
if (nextpos != value.npos) {
|
if (nextpos != value.npos) {
|
||||||
std::string uid = m_escape.unescape(value.substr(pos + 1, nextpos - pos - 1));
|
std::string uid = m_escape.unescape(value.substr(pos + 1, nextpos - pos - 1));
|
||||||
boost::shared_ptr<Event> &eventptr = m_cache[easid];
|
std::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||||
if (!eventptr) {
|
if (!eventptr) {
|
||||||
eventptr = boost::shared_ptr<Event>(new Event);
|
eventptr = std::make_shared<Event>();
|
||||||
}
|
}
|
||||||
eventptr->m_easid = easid;
|
eventptr->m_easid = easid;
|
||||||
eventptr->m_uid = uid;
|
eventptr->m_uid = uid;
|
||||||
|
@ -220,7 +220,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
||||||
// old items + new (added to m_events above) - deleted (removed above)
|
// old items + new (added to m_events above) - deleted (removed above)
|
||||||
for (const auto &entry: m_cache) {
|
for (const auto &entry: m_cache) {
|
||||||
const std::string &easid = entry.first;
|
const std::string &easid = entry.first;
|
||||||
const boost::shared_ptr<Event> &eventptr = entry.second;
|
const std::shared_ptr<Event> &eventptr = entry.second;
|
||||||
for (const std::string &subid: eventptr->m_subids) {
|
for (const std::string &subid: eventptr->m_subids) {
|
||||||
SE_LOG_DEBUG(getDisplayName(), "existing eas item %s = uid %s + rid %s",
|
SE_LOG_DEBUG(getDisplayName(), "existing eas item %s = uid %s + rid %s",
|
||||||
easid.c_str(), eventptr->m_uid.c_str(), subid.c_str());
|
easid.c_str(), eventptr->m_uid.c_str(), subid.c_str());
|
||||||
|
@ -235,7 +235,7 @@ std::string ActiveSyncCalendarSource::endSync(bool success)
|
||||||
if (success) {
|
if (success) {
|
||||||
for (const auto &entry: m_cache) {
|
for (const auto &entry: m_cache) {
|
||||||
const std::string &easid = entry.first;
|
const std::string &easid = entry.first;
|
||||||
const boost::shared_ptr<Event> &eventptr = entry.second;
|
const std::shared_ptr<Event> &eventptr = entry.second;
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << "//"; // use same format as in MapSyncSource, just in case - was '/' << m_escape.escape(ids.m_revision) << '/';
|
buffer << "//"; // use same format as in MapSyncSource, just in case - was '/' << m_escape.escape(ids.m_revision) << '/';
|
||||||
buffer << m_escape.escape(eventptr->m_uid) << '/';
|
buffer << m_escape.escape(eventptr->m_uid) << '/';
|
||||||
|
@ -324,12 +324,12 @@ ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::loadItem(Event &event
|
||||||
|
|
||||||
ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::setItemData(const std::string &easid, const std::string &data)
|
ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::setItemData(const std::string &easid, const std::string &data)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Event> &eventptr = m_cache[easid];
|
std::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||||
if (eventptr) {
|
if (eventptr) {
|
||||||
eventptr->m_uid.clear();
|
eventptr->m_uid.clear();
|
||||||
eventptr->m_subids.clear();
|
eventptr->m_subids.clear();
|
||||||
} else {
|
} else {
|
||||||
eventptr = boost::shared_ptr<Event>(new Event);
|
eventptr = std::make_shared<Event>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Event &event = *eventptr;
|
Event &event = *eventptr;
|
||||||
|
@ -408,7 +408,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
||||||
const std::string &callerSubID = ids.second;
|
const std::string &callerSubID = ids.second;
|
||||||
|
|
||||||
// parse new event
|
// parse new event
|
||||||
boost::shared_ptr<Event> newEvent(new Event);
|
auto newEvent = std::make_shared<Event>();
|
||||||
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
|
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
|
||||||
"parsing iCalendar 2.0");
|
"parsing iCalendar 2.0");
|
||||||
icalcomponent *firstcomp = NULL;
|
icalcomponent *firstcomp = NULL;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -119,7 +119,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
|
||||||
* A cache of information about each merged item. Maps from
|
* A cache of information about each merged item. Maps from
|
||||||
* easid to Event.
|
* easid to Event.
|
||||||
*/
|
*/
|
||||||
class EventCache : public std::map<std::string, boost::shared_ptr<Event> >
|
class EventCache : public std::map<std::string, std::shared_ptr<Event> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EventCache() : m_initialized(false) {}
|
EventCache() : m_initialized(false) {}
|
||||||
|
@ -141,7 +141,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
|
||||||
* On-disk representation of m_cache (without the item data).
|
* On-disk representation of m_cache (without the item data).
|
||||||
* Format same as in MapSyncSource (code copied, refactor!).
|
* Format same as in MapSyncSource (code copied, refactor!).
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<ConfigNode> m_trackingNode;
|
std::shared_ptr<ConfigNode> m_trackingNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
#include <syncevo/GLibSupport.h>
|
#include <syncevo/GLibSupport.h>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -135,7 +133,7 @@ class ActiveSyncSource :
|
||||||
// that we use a common prefix, so that we can use the key/value store
|
// that we use a common prefix, so that we can use the key/value store
|
||||||
// also for other keys if the need ever arises).
|
// also for other keys if the need ever arises).
|
||||||
m_itemNode(new PrefixConfigNode("item-",
|
m_itemNode(new PrefixConfigNode("item-",
|
||||||
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode())))),
|
std::static_pointer_cast<ConfigNode>(std::make_shared<SafeConfigNode>(params.m_nodes.getTrackingNode())))),
|
||||||
m_context(params.m_context)
|
m_context(params.m_context)
|
||||||
{
|
{
|
||||||
if (!m_context) {
|
if (!m_context) {
|
||||||
|
@ -183,11 +181,11 @@ class ActiveSyncSource :
|
||||||
void findCollections(const std::string &account, bool force_update);
|
void findCollections(const std::string &account, bool force_update);
|
||||||
std::string lookupFolder(const std::string &folder);
|
std::string lookupFolder(const std::string &folder);
|
||||||
|
|
||||||
boost::shared_ptr<ConfigNode> m_itemNode;
|
std::shared_ptr<ConfigNode> m_itemNode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** "target-config@<context>" instance which holds our username == ActiveSync account ID */
|
/** "target-config@<context>" instance which holds our username == ActiveSync account ID */
|
||||||
boost::shared_ptr<SyncConfig> m_context;
|
std::shared_ptr<SyncConfig> m_context;
|
||||||
|
|
||||||
/** account ID for libeas, must be set in "username" config property */
|
/** account ID for libeas, must be set in "username" config property */
|
||||||
std::string m_account;
|
std::string m_account;
|
||||||
|
@ -208,7 +206,7 @@ class ActiveSyncSource :
|
||||||
* server-side IDs of all items, updated as changes are reported and/or are made;
|
* server-side IDs of all items, updated as changes are reported and/or are made;
|
||||||
* NULL if not using change tracking
|
* NULL if not using change tracking
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<ConfigNode> m_ids;
|
std::shared_ptr<ConfigNode> m_ids;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cache of all items, filled at begin of session and updated as
|
* cache of all items, filled at begin of session and updated as
|
||||||
|
|
|
@ -114,7 +114,7 @@ class ActiveSyncsTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
|
source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
|
||||||
source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
|
source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
|
||||||
source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
|
source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
|
||||||
|
@ -218,17 +218,20 @@ static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
|
||||||
// cannot run tests involving a second database:
|
// cannot run tests involving a second database:
|
||||||
// wrap orginal source creation, set default database for
|
// wrap orginal source creation, set default database for
|
||||||
// database #0 and refuse to return a source for database #1
|
// database #0 and refuse to return a source for database #1
|
||||||
config.m_createSourceA = boost::bind(createEASSource, config.m_createSourceA,
|
config.m_createSourceA = [create=config.m_createSourceA] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
|
||||||
_1, _2, _3, _4);
|
return createEASSource(create, client, clientID, source, isSourceA);
|
||||||
config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB,
|
};
|
||||||
_1, _2, _3, _4);
|
config.m_createSourceB = [create=config.m_createSourceB] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
|
||||||
|
return createEASSource(create, client, clientID, source, isSourceA);
|
||||||
config.m_dump = boost::bind(DumpItems, _1, _2, _3,
|
};
|
||||||
|
config.m_dump = [type] (ClientTest &client, TestingSyncSource &source, const std::string &file) {
|
||||||
|
return DumpItems(client, source, file,
|
||||||
type == EAS_ITEM_CONTACT ||
|
type == EAS_ITEM_CONTACT ||
|
||||||
// need to read from our cache for Google Calendar,
|
// need to read from our cache for Google Calendar,
|
||||||
// because it does not support Fetch
|
// because it does not support Fetch
|
||||||
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
|
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
|
||||||
);
|
);
|
||||||
|
};
|
||||||
config.m_sourceLUIDsAreVolatile = true;
|
config.m_sourceLUIDsAreVolatile = true;
|
||||||
// TODO: find out how ActiveSync/Exchange handle children without parent;
|
// TODO: find out how ActiveSync/Exchange handle children without parent;
|
||||||
// at the moment, the child is stored as if it was a stand-alone event
|
// at the moment, the child is stored as if it was a stand-alone event
|
||||||
|
|
|
@ -147,14 +147,14 @@ class AkonadiTest : public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||||
string &data) {
|
string &data) {
|
||||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||||
return res.m_luid;
|
return res.m_luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "kde-contacts", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "kde-contacts", true));
|
||||||
|
@ -180,25 +180,25 @@ protected:
|
||||||
// TODO: support default databases
|
// TODO: support default databases
|
||||||
|
|
||||||
// void testOpenDefaultAddressBook() {
|
// void testOpenDefaultAddressBook() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void testOpenDefaultCalendar() {
|
// void testOpenDefaultCalendar() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void testOpenDefaultTodo() {
|
// void testOpenDefaultTodo() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void testOpenDefaultMemo() {
|
// void testOpenDefaultMemo() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
@ -209,7 +209,7 @@ protected:
|
||||||
prefix = "SyncEvolution_Test_";
|
prefix = "SyncEvolution_Test_";
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,6 @@
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <boost/lambda/lambda.hpp>
|
|
||||||
#include <boost/lambda/bind.hpp>
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -75,7 +71,7 @@ bool AkonadiSyncSource::isEmpty()
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
bool result;
|
bool result;
|
||||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::isEmpty, this));
|
GRunInMain([this, &result] () { result = isEmpty(); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +86,7 @@ bool AkonadiSyncSource::isEmpty()
|
||||||
void AkonadiSyncSource::start()
|
void AkonadiSyncSource::start()
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
GRunInMain(boost::bind(&AkonadiSyncSource::start, this));
|
GRunInMain([this]() { start(); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +113,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
Databases result;
|
Databases result;
|
||||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::getDatabases, this));
|
GRunInMain([this, &result] () { result = getDatabases(); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +151,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
|
||||||
void AkonadiSyncSource::open()
|
void AkonadiSyncSource::open()
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
GRunInMain(boost::bind(&AkonadiSyncSource::open, this));
|
GRunInMain([this] () { open(); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +219,7 @@ void AkonadiSyncSource::open()
|
||||||
void AkonadiSyncSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
|
void AkonadiSyncSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
GRunInMain(boost::bind(&AkonadiSyncSource::listAllItems, this, boost::ref(revisions)));
|
GRunInMain([this, &revisions] () { listAllItems(revisions); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +247,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
InsertItemResult result;
|
InsertItemResult result;
|
||||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::insertItem, this, boost::cref(luid), boost::cref(data), raw));
|
GRunInMain([this, &result, &luid, &data, raw] () { return insertItem(luid, data, raw); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +292,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
||||||
void AkonadiSyncSource::removeItem(const string &luid)
|
void AkonadiSyncSource::removeItem(const string &luid)
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
GRunInMain(boost::bind(&AkonadiSyncSource::removeItem, this, boost::cref(luid)));
|
GRunInMain([this, &luid] () { removeItem(luid); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +309,7 @@ void AkonadiSyncSource::removeItem(const string &luid)
|
||||||
void AkonadiSyncSource::readItem(const std::string &luid, std::string &data, bool raw)
|
void AkonadiSyncSource::readItem(const std::string &luid, std::string &data, bool raw)
|
||||||
{
|
{
|
||||||
if (!GRunIsMain()) {
|
if (!GRunIsMain()) {
|
||||||
GRunInMain(boost::bind(&AkonadiSyncSource::readItem, this, boost::cref(luid), boost::ref(data), raw));
|
GRunInMain([this, &luid, &data, raw] () { readItem(luid, data, raw); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,14 +180,7 @@ SyncSource::Databases EvolutionCalendarSource::getDatabases()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifndef USE_EDS_CLIENT
|
||||||
static EClient *newECalClient(ESource *source,
|
|
||||||
ECalClientSourceType ecalSourceType,
|
|
||||||
GError **gerror)
|
|
||||||
{
|
|
||||||
return E_CLIENT(e_cal_client_new(source, ecalSourceType, gerror));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
char *EvolutionCalendarSource::authenticate(const char *prompt,
|
char *EvolutionCalendarSource::authenticate(const char *prompt,
|
||||||
const char *key)
|
const char *key)
|
||||||
{
|
{
|
||||||
|
@ -214,15 +207,15 @@ void EvolutionCalendarSource::open()
|
||||||
// be others with similar problems and for local storage it is
|
// be others with similar problems and for local storage it is
|
||||||
// a reasonably cheap operation (so no harm there).
|
// a reasonably cheap operation (so no harm there).
|
||||||
for (int retries = 0; retries < 2; retries++) {
|
for (int retries = 0; retries < 2; retries++) {
|
||||||
|
auto create = [type=sourceType()] (ESource *source, GError **gerror) {
|
||||||
|
return E_CLIENT(e_cal_client_new(source, type, gerror));
|
||||||
|
};
|
||||||
m_calendar.reset(E_CAL_CLIENT(openESource(sourceExtension(),
|
m_calendar.reset(E_CAL_CLIENT(openESource(sourceExtension(),
|
||||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar :
|
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar :
|
||||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list :
|
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list :
|
||||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list :
|
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list :
|
||||||
NULL,
|
NULL,
|
||||||
boost::bind(newECalClient,
|
create).get()));
|
||||||
_1,
|
|
||||||
sourceType(),
|
|
||||||
_2)).get()));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
GErrorCXX gerror;
|
GErrorCXX gerror;
|
||||||
|
@ -303,7 +296,7 @@ bool EvolutionCalendarSource::isEmpty()
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifdef USE_EDS_CLIENT
|
||||||
class ECalClientViewSyncHandler {
|
class ECalClientViewSyncHandler {
|
||||||
public:
|
public:
|
||||||
typedef boost::function<void(const GSList *list)> Process_t;
|
typedef std::function<void(const GSList *list)> Process_t;
|
||||||
|
|
||||||
ECalClientViewSyncHandler(ECalClientViewCXX &view,
|
ECalClientViewSyncHandler(ECalClientViewCXX &view,
|
||||||
const Process_t &process) :
|
const Process_t &process) :
|
||||||
|
@ -316,10 +309,10 @@ class ECalClientViewSyncHandler {
|
||||||
// Listen for view signals
|
// Listen for view signals
|
||||||
m_view.connectSignal<ECalClientView *,
|
m_view.connectSignal<ECalClientView *,
|
||||||
const GSList *>()("objects-added",
|
const GSList *>()("objects-added",
|
||||||
boost::bind(m_process, _2));
|
[this] (ECalClientView *, const GSList *list) { m_process(list); });
|
||||||
m_view.connectSignal<EBookClientView *,
|
m_view.connectSignal<ECalClientView *,
|
||||||
const GError *>()("complete",
|
const GError *>()("complete",
|
||||||
boost::bind(&ECalClientViewSyncHandler::completed, this, _2));
|
[this] (ECalClientView *, const GError *gerror) { completed(gerror); });
|
||||||
|
|
||||||
// Start the view
|
// Start the view
|
||||||
e_cal_client_view_start (m_view, m_error);
|
e_cal_client_view_start (m_view, m_error);
|
||||||
|
@ -360,21 +353,7 @@ class ECalClientViewSyncHandler {
|
||||||
// Possible error while watching the view
|
// Possible error while watching the view
|
||||||
GErrorCXX m_error;
|
GErrorCXX m_error;
|
||||||
};
|
};
|
||||||
|
#endif // USE_EDS_CLIENT
|
||||||
static void list_revisions(const GSList *objects, EvolutionCalendarSource::RevisionMap_t *revisions)
|
|
||||||
{
|
|
||||||
const GSList *l;
|
|
||||||
|
|
||||||
for (l = objects; l; l = l->next) {
|
|
||||||
icalcomponent *icomp = (icalcomponent*)l->data;
|
|
||||||
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
|
|
||||||
string luid = id.getLUID();
|
|
||||||
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
|
|
||||||
|
|
||||||
(*revisions)[luid] = modTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
||||||
{
|
{
|
||||||
|
@ -389,7 +368,18 @@ void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
||||||
|
|
||||||
// TODO: Optimization: use set fields_of_interest (UID / REV / LAST-MODIFIED)
|
// TODO: Optimization: use set fields_of_interest (UID / REV / LAST-MODIFIED)
|
||||||
|
|
||||||
ECalClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions));
|
auto process = [&revisions] (const GSList *objects) {
|
||||||
|
const GSList *l;
|
||||||
|
|
||||||
|
for (l = objects; l; l = l->next) {
|
||||||
|
icalcomponent *icomp = (icalcomponent*)l->data;
|
||||||
|
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
|
||||||
|
string luid = id.getLUID();
|
||||||
|
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
|
||||||
|
revisions[luid] = modTime;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ECalClientViewSyncHandler handler(viewPtr, process);
|
||||||
if (!handler.processSync(gerror)) {
|
if (!handler.processSync(gerror)) {
|
||||||
throwError(SE_HERE, "watching view", gerror);
|
throwError(SE_HERE, "watching view", gerror);
|
||||||
}
|
}
|
||||||
|
@ -646,7 +636,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
||||||
|
|
||||||
// Recreate any children removed earlier: when we get here,
|
// Recreate any children removed earlier: when we get here,
|
||||||
// the parent exists and we must update it.
|
// the parent exists and we must update it.
|
||||||
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||||
if (
|
if (
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifdef USE_EDS_CLIENT
|
||||||
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
||||||
|
@ -738,7 +728,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
||||||
|
|
||||||
// Recreate any children removed earlier: when we get here,
|
// Recreate any children removed earlier: when we get here,
|
||||||
// the parent exists and we must update it.
|
// the parent exists and we must update it.
|
||||||
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||||
if (
|
if (
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifdef USE_EDS_CLIENT
|
||||||
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
||||||
|
@ -858,7 +848,7 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
||||||
|
|
||||||
// recreate children
|
// recreate children
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||||
if (first) {
|
if (first) {
|
||||||
char *uid;
|
char *uid;
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
||||||
* will destroy the smart pointer, which then calls
|
* will destroy the smart pointer, which then calls
|
||||||
* icalcomponent_free().
|
* icalcomponent_free().
|
||||||
*/
|
*/
|
||||||
typedef list< boost::shared_ptr< eptr<icalcomponent> > > ICalComps_t;
|
typedef list< std::shared_ptr< eptr<icalcomponent> > > ICalComps_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function which extracts all icalcomponents with
|
* Utility function which extracts all icalcomponents with
|
||||||
|
|
|
@ -124,14 +124,14 @@ class EvolutionCalendarTest : public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||||
string &data) {
|
string &data) {
|
||||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||||
return res.m_luid;
|
return res.m_luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "calendar", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "calendar", true));
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true));
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true));
|
||||||
|
@ -148,19 +148,19 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void testOpenDefaultCalendar() {
|
void testOpenDefaultCalendar() {
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true, NULL));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true, NULL));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
}
|
}
|
||||||
|
|
||||||
void testOpenDefaultTodo() {
|
void testOpenDefaultTodo() {
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true, NULL));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true, NULL));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
}
|
}
|
||||||
|
|
||||||
void testOpenDefaultMemo() {
|
void testOpenDefaultMemo() {
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true, NULL));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true, NULL));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ protected:
|
||||||
prefix = "SyncEvolution_Test_";
|
prefix = "SyncEvolution_Test_";
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
|
|
||||||
|
|
|
@ -287,7 +287,7 @@ bool EvolutionContactSource::isEmpty()
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifdef USE_EDS_CLIENT
|
||||||
class EBookClientViewSyncHandler {
|
class EBookClientViewSyncHandler {
|
||||||
public:
|
public:
|
||||||
typedef boost::function<void (const GSList *list)> Process_t;
|
typedef std::function<void (const GSList *list)> Process_t;
|
||||||
|
|
||||||
EBookClientViewSyncHandler(const EBookClientViewCXX &view,
|
EBookClientViewSyncHandler(const EBookClientViewCXX &view,
|
||||||
const Process_t &process) :
|
const Process_t &process) :
|
||||||
|
@ -299,10 +299,10 @@ class EBookClientViewSyncHandler {
|
||||||
// Listen for view signals
|
// Listen for view signals
|
||||||
m_view.connectSignal<EBookClientView *,
|
m_view.connectSignal<EBookClientView *,
|
||||||
const GSList *>()("objects-added",
|
const GSList *>()("objects-added",
|
||||||
boost::bind(m_process, _2));
|
[this] (EBookClientView *, const GSList *list) { m_process(list); } );
|
||||||
m_view.connectSignal<EBookClientView *,
|
m_view.connectSignal<EBookClientView *,
|
||||||
const GError *>()("complete",
|
const GError *>()("complete",
|
||||||
boost::bind(&EBookClientViewSyncHandler::completed, this, _2));
|
[this] (EBookClientView *, const GError *gerror) { completed(gerror); });
|
||||||
|
|
||||||
// Start the view
|
// Start the view
|
||||||
e_book_client_view_start (m_view, m_error);
|
e_book_client_view_start (m_view, m_error);
|
||||||
|
@ -334,39 +334,12 @@ class EBookClientViewSyncHandler {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Process list callback
|
// Process list callback
|
||||||
boost::function<void (const GSList *list)> m_process;
|
std::function<void (const GSList *list)> m_process;
|
||||||
// View watched
|
// View watched
|
||||||
EBookClientViewCXX m_view;
|
EBookClientViewCXX m_view;
|
||||||
// Possible error while watching the view
|
// Possible error while watching the view
|
||||||
GErrorCXX m_error;
|
GErrorCXX m_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void list_revisions(const GSList *contacts, EvolutionContactSource::RevisionMap_t *revisions)
|
|
||||||
{
|
|
||||||
const GSList *l;
|
|
||||||
|
|
||||||
for (l = contacts; l; l = l->next) {
|
|
||||||
EContact *contact = E_CONTACT(l->data);
|
|
||||||
if (!contact) {
|
|
||||||
SE_THROW("contact entry without data");
|
|
||||||
}
|
|
||||||
pair<string, string> revmapping;
|
|
||||||
const char *uid = (const char *)e_contact_get_const(contact,
|
|
||||||
E_CONTACT_UID);
|
|
||||||
if (!uid || !uid[0]) {
|
|
||||||
SE_THROW("contact entry without UID");
|
|
||||||
}
|
|
||||||
revmapping.first = uid;
|
|
||||||
const char *rev = (const char *)e_contact_get_const(contact,
|
|
||||||
E_CONTACT_REV);
|
|
||||||
if (!rev || !rev[0]) {
|
|
||||||
SE_THROW(string("contact entry without REV: ") + revmapping.first);
|
|
||||||
}
|
|
||||||
revmapping.second = rev;
|
|
||||||
revisions->insert(revmapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
||||||
|
@ -399,7 +372,28 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
||||||
gerror.clear();
|
gerror.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
EBookClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions));
|
auto process = [&revisions] (const GSList *contacts) {
|
||||||
|
const GSList *l;
|
||||||
|
|
||||||
|
for (l = contacts; l; l = l->next) {
|
||||||
|
EContact *contact = E_CONTACT(l->data);
|
||||||
|
if (!contact) {
|
||||||
|
SE_THROW("contact entry without data");
|
||||||
|
}
|
||||||
|
const char *uid = (const char *)e_contact_get_const(contact,
|
||||||
|
E_CONTACT_UID);
|
||||||
|
if (!uid || !uid[0]) {
|
||||||
|
SE_THROW("contact entry without UID");
|
||||||
|
}
|
||||||
|
const char *rev = (const char *)e_contact_get_const(contact,
|
||||||
|
E_CONTACT_REV);
|
||||||
|
if (!rev || !rev[0]) {
|
||||||
|
SE_THROW(string("contact entry without REV: ") + uid);
|
||||||
|
}
|
||||||
|
revisions[uid] = rev;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EBookClientViewSyncHandler handler(viewPtr, process);
|
||||||
if (!handler.process(gerror)) {
|
if (!handler.process(gerror)) {
|
||||||
throwError(SE_HERE, "watching view", gerror);
|
throwError(SE_HERE, "watching view", gerror);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +519,7 @@ void EvolutionContactSource::getReadAheadOrder(ReadAheadOrder &order,
|
||||||
luids = m_nextLUIDs;
|
luids = m_nextLUIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvolutionContactSource::checkCacheForError(boost::shared_ptr<ContactCache> &cache)
|
void EvolutionContactSource::checkCacheForError(std::shared_ptr<ContactCache> &cache)
|
||||||
{
|
{
|
||||||
if (cache->m_gerror) {
|
if (cache->m_gerror) {
|
||||||
GErrorCXX gerror;
|
GErrorCXX gerror;
|
||||||
|
@ -541,7 +535,7 @@ void EvolutionContactSource::invalidateCachedContact(const std::string &luid)
|
||||||
invalidateCachedContact(m_contactCacheNext, luid);
|
invalidateCachedContact(m_contactCacheNext, luid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvolutionContactSource::invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid)
|
void EvolutionContactSource::invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid)
|
||||||
{
|
{
|
||||||
if (cache) {
|
if (cache) {
|
||||||
ContactCache::iterator it = cache->find(luid);
|
ContactCache::iterator it = cache->find(luid);
|
||||||
|
@ -670,7 +664,7 @@ static int MaxBatchSize()
|
||||||
return maxBatchSize;
|
return maxBatchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode)
|
std::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode)
|
||||||
{
|
{
|
||||||
SE_LOG_DEBUG(getDisplayName(), "reading: %s contact %s",
|
SE_LOG_DEBUG(getDisplayName(), "reading: %s contact %s",
|
||||||
mode == START ? "must read" :
|
mode == START ? "must read" :
|
||||||
|
@ -764,7 +758,7 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
||||||
m_readAheadOrder = READ_NONE;
|
m_readAheadOrder = READ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<ContactCache> cache;
|
std::shared_ptr<ContactCache> cache;
|
||||||
if (size) {
|
if (size) {
|
||||||
// Prepare parameter for EDS C call. Ownership of query instances is in uidQueries array.
|
// Prepare parameter for EDS C call. Ownership of query instances is in uidQueries array.
|
||||||
boost::scoped_array<EBookQuery *> queries(new EBookQuery *[size]);
|
boost::scoped_array<EBookQuery *> queries(new EBookQuery *[size]);
|
||||||
|
@ -789,24 +783,11 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
||||||
}
|
}
|
||||||
m_contactsFromDB += size;
|
m_contactsFromDB += size;
|
||||||
m_contactQueries++;
|
m_contactQueries++;
|
||||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts,
|
auto process = [this, cachePtr=std::weak_ptr<ContactCache>(cache)] (gboolean success, GSList *contactsPtr, const GError *gerror) noexcept {
|
||||||
boost::bind(&EvolutionContactSource::completedRead,
|
|
||||||
this,
|
|
||||||
boost::weak_ptr<ContactCache>(cache),
|
|
||||||
_1, _2, _3),
|
|
||||||
m_addressbook, sexp, NULL);
|
|
||||||
SE_LOG_DEBUG(getDisplayName(), "reading: started contact read %s", cache->m_name.c_str());
|
|
||||||
}
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GListCXX< EContact, GSList, GObjectDestructor<EContact> > ContactListCXX;
|
|
||||||
|
|
||||||
void EvolutionContactSource::completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw()
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
|
using ContactListCXX = GListCXX< EContact, GSList, GObjectDestructor<EContact> >;
|
||||||
ContactListCXX contacts(contactsPtr); // transfers ownership
|
ContactListCXX contacts(contactsPtr); // transfers ownership
|
||||||
boost::shared_ptr<ContactCache> cache = cachePtr.lock();
|
std::shared_ptr<ContactCache> cache = cachePtr.lock();
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>");
|
SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>");
|
||||||
return;
|
return;
|
||||||
|
@ -828,6 +809,12 @@ void EvolutionContactSource::completedRead(const boost::weak_ptr<ContactCache> &
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, process,
|
||||||
|
m_addressbook, sexp, NULL);
|
||||||
|
SE_LOG_DEBUG(getDisplayName(), "reading: started contact read %s", cache->m_name.c_str());
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvolutionContactSource::logCacheStats(Logger::Level level)
|
void EvolutionContactSource::logCacheStats(Logger::Level level)
|
||||||
|
@ -890,11 +877,11 @@ void EvolutionContactSource::readItem(const string &luid, std::string &item, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_EDS_CLIENT
|
#ifdef USE_EDS_CLIENT
|
||||||
TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const boost::shared_ptr<Pending> &pending)
|
TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const std::shared_ptr<Pending> &pending)
|
||||||
{
|
{
|
||||||
SE_LOG_DEBUG(pending->m_name, "checking operation: %s", pending->m_status == MODIFYING ? "waiting" : "inserted");
|
SE_LOG_DEBUG(pending->m_name, "checking operation: %s", pending->m_status == MODIFYING ? "waiting" : "inserted");
|
||||||
if (pending->m_status == MODIFYING) {
|
if (pending->m_status == MODIFYING) {
|
||||||
return TrackingSyncSource::InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending));
|
return TrackingSyncSource::InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
|
||||||
}
|
}
|
||||||
if (pending->m_gerror) {
|
if (pending->m_gerror) {
|
||||||
pending->m_gerror.throwError(SE_HERE, pending->m_name);
|
pending->m_gerror.throwError(SE_HERE, pending->m_name);
|
||||||
|
@ -903,8 +890,20 @@ TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(
|
||||||
return TrackingSyncSource::InsertItemResult(pending->m_uid, newrev, ITEM_OKAY);
|
return TrackingSyncSource::InsertItemResult(pending->m_uid, newrev, ITEM_OKAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvolutionContactSource::completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, GSList *uids, const GError *gerror) throw()
|
void EvolutionContactSource::flushItemChanges()
|
||||||
{
|
{
|
||||||
|
if (!m_batchedAdd.empty()) {
|
||||||
|
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts starting", (int)m_batchedAdd.size());
|
||||||
|
m_numRunningOperations++;
|
||||||
|
GListCXX<EContact, GSList> contacts;
|
||||||
|
// Iterate backwards, push to front (cheaper for single-linked list) -> same order in the end.
|
||||||
|
for (const auto &pending: reverse(m_batchedAdd)) {
|
||||||
|
contacts.push_front(pending->m_contact.get());
|
||||||
|
}
|
||||||
|
// Transfer content without copying and then copy only the shared pointer.
|
||||||
|
auto batched = std::make_shared<PendingContainer_t>();
|
||||||
|
std::swap(*batched, m_batchedAdd);
|
||||||
|
auto process = [this, batched] (gboolean success, GSList *uids, const GError *gerror) noexcept {
|
||||||
try {
|
try {
|
||||||
// The destructor ensures that the pending operations complete
|
// The destructor ensures that the pending operations complete
|
||||||
// before destructing the instance, so our "this" pointer is
|
// before destructing the instance, so our "this" pointer is
|
||||||
|
@ -941,10 +940,20 @@ void EvolutionContactSource::completedAdd(const boost::shared_ptr<PendingContain
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts, process,
|
||||||
|
m_addressbook, contacts, NULL);
|
||||||
}
|
}
|
||||||
|
if (!m_batchedUpdate.empty()) {
|
||||||
void EvolutionContactSource::completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw()
|
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts starting", (int)m_batchedUpdate.size());
|
||||||
{
|
m_numRunningOperations++;
|
||||||
|
GListCXX<EContact, GSList> contacts;
|
||||||
|
for (const auto &pending: reverse(m_batchedUpdate)) {
|
||||||
|
contacts.push_front(pending->m_contact.get());
|
||||||
|
}
|
||||||
|
auto batched = std::make_shared<PendingContainer_t>();
|
||||||
|
std::swap(*batched, m_batchedUpdate);
|
||||||
|
auto process = [this, batched] (gboolean success, const GError *gerror) noexcept {
|
||||||
try {
|
try {
|
||||||
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size());
|
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size());
|
||||||
m_numRunningOperations--;
|
m_numRunningOperations--;
|
||||||
|
@ -965,42 +974,8 @@ void EvolutionContactSource::completedUpdate(const boost::shared_ptr<PendingCont
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts, process,
|
||||||
void EvolutionContactSource::flushItemChanges()
|
|
||||||
{
|
|
||||||
if (!m_batchedAdd.empty()) {
|
|
||||||
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts starting", (int)m_batchedAdd.size());
|
|
||||||
m_numRunningOperations++;
|
|
||||||
GListCXX<EContact, GSList> contacts;
|
|
||||||
// Iterate backwards, push to front (cheaper for single-linked list) -> same order in the end.
|
|
||||||
for (const auto &pending: reverse(m_batchedAdd)) {
|
|
||||||
contacts.push_front(pending->m_contact.get());
|
|
||||||
}
|
|
||||||
// Transfer content without copying and then copy only the shared pointer.
|
|
||||||
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
|
|
||||||
std::swap(*batched, m_batchedAdd);
|
|
||||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts,
|
|
||||||
boost::bind(&EvolutionContactSource::completedAdd,
|
|
||||||
this,
|
|
||||||
batched,
|
|
||||||
_1, _2, _3),
|
|
||||||
m_addressbook, contacts, NULL);
|
|
||||||
}
|
|
||||||
if (!m_batchedUpdate.empty()) {
|
|
||||||
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts starting", (int)m_batchedUpdate.size());
|
|
||||||
m_numRunningOperations++;
|
|
||||||
GListCXX<EContact, GSList> contacts;
|
|
||||||
for (const auto &pending: reverse(m_batchedUpdate)) {
|
|
||||||
contacts.push_front(pending->m_contact.get());
|
|
||||||
}
|
|
||||||
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
|
|
||||||
std::swap(*batched, m_batchedUpdate);
|
|
||||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts,
|
|
||||||
boost::bind(&EvolutionContactSource::completedUpdate,
|
|
||||||
this,
|
|
||||||
batched,
|
|
||||||
_1, _2),
|
|
||||||
m_addressbook, contacts, NULL);
|
m_addressbook, contacts, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1055,7 +1030,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
||||||
uid.empty() ? "add" : ("insert " + uid).c_str(),
|
uid.empty() ? "add" : ("insert " + uid).c_str(),
|
||||||
m_asyncOpCounter++);
|
m_asyncOpCounter++);
|
||||||
SE_LOG_DEBUG(name, "queueing for batched %s", uid.empty() ? "add" : "update");
|
SE_LOG_DEBUG(name, "queueing for batched %s", uid.empty() ? "add" : "update");
|
||||||
boost::shared_ptr<Pending> pending(new Pending);
|
auto pending = std::make_shared<Pending>();
|
||||||
pending->m_name = name;
|
pending->m_name = name;
|
||||||
pending->m_contact = contact;
|
pending->m_contact = contact;
|
||||||
pending->m_uid = uid;
|
pending->m_uid = uid;
|
||||||
|
@ -1066,7 +1041,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
||||||
}
|
}
|
||||||
// SyncSource is going to live longer than Synthesis
|
// SyncSource is going to live longer than Synthesis
|
||||||
// engine, so using "this" is safe here.
|
// engine, so using "this" is safe here.
|
||||||
return InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending));
|
return InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -137,7 +137,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
||||||
|
|
||||||
Pending() : m_status(MODIFYING) {}
|
Pending() : m_status(MODIFYING) {}
|
||||||
};
|
};
|
||||||
typedef std::list< boost::shared_ptr<Pending> >PendingContainer_t;
|
typedef std::list< std::shared_ptr<Pending> >PendingContainer_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batched "contact add/update" operations.
|
* Batched "contact add/update" operations.
|
||||||
|
@ -148,14 +148,12 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
||||||
PendingContainer_t m_batchedUpdate;
|
PendingContainer_t m_batchedUpdate;
|
||||||
InitState<int> m_numRunningOperations;
|
InitState<int> m_numRunningOperations;
|
||||||
|
|
||||||
InsertItemResult checkBatchedInsert(const boost::shared_ptr<Pending> &pending);
|
InsertItemResult checkBatchedInsert(const std::shared_ptr<Pending> &pending);
|
||||||
void completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, /* const GStringListFreeCXX &uids */ GSList *uids, const GError *gerror) throw ();
|
|
||||||
void completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw ();
|
|
||||||
virtual void flushItemChanges();
|
virtual void flushItemChanges();
|
||||||
virtual void finishItemChanges();
|
virtual void finishItemChanges();
|
||||||
|
|
||||||
// Read-ahead of item data.
|
// Read-ahead of item data.
|
||||||
boost::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext;
|
std::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext;
|
||||||
int m_cacheMisses, m_cacheStalls;
|
int m_cacheMisses, m_cacheStalls;
|
||||||
int m_contactReads; /**< number of readItemAsKey() calls */
|
int m_contactReads; /**< number of readItemAsKey() calls */
|
||||||
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
|
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
|
||||||
|
@ -164,9 +162,9 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
||||||
ReadAheadOrder m_readAheadOrder;
|
ReadAheadOrder m_readAheadOrder;
|
||||||
ReadAheadItems m_nextLUIDs;
|
ReadAheadItems m_nextLUIDs;
|
||||||
|
|
||||||
void checkCacheForError(boost::shared_ptr<ContactCache> &cache);
|
void checkCacheForError(std::shared_ptr<ContactCache> &cache);
|
||||||
void invalidateCachedContact(const std::string &luid);
|
void invalidateCachedContact(const std::string &luid);
|
||||||
void invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid);
|
void invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid);
|
||||||
bool getContact(const string &luid, EContact **contact, GErrorCXX &gerror);
|
bool getContact(const string &luid, EContact **contact, GErrorCXX &gerror);
|
||||||
bool getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror);
|
bool getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror);
|
||||||
enum ReadingMode
|
enum ReadingMode
|
||||||
|
@ -174,8 +172,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
||||||
START, /**< luid is needed, must be read */
|
START, /**< luid is needed, must be read */
|
||||||
CONTINUE /**< luid is from old request, find next ones */
|
CONTINUE /**< luid is from old request, find next ones */
|
||||||
};
|
};
|
||||||
boost::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode);
|
std::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode);
|
||||||
void completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw();
|
|
||||||
void logCacheStats(Logger::Level level);
|
void logCacheStats(Logger::Level level);
|
||||||
|
|
||||||
// Use the information provided to us to implement read-ahead efficiently.
|
// Use the information provided to us to implement read-ahead efficiently.
|
||||||
|
|
|
@ -77,7 +77,7 @@ class EvolutionContactTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "evolution-contacts", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "evolution-contacts", true));
|
||||||
|
@ -94,8 +94,8 @@ protected:
|
||||||
void testImport() {
|
void testImport() {
|
||||||
// this only tests that we can instantiate something under the type "addressbook";
|
// this only tests that we can instantiate something under the type "addressbook";
|
||||||
// it might not be an EvolutionContactSource
|
// it might not be an EvolutionContactSource
|
||||||
boost::shared_ptr<EvolutionContactSource> source21(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true)));
|
std::shared_ptr<EvolutionContactSource> source21(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true)));
|
||||||
boost::shared_ptr<EvolutionContactSource> source30(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true)));
|
std::shared_ptr<EvolutionContactSource> source30(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true)));
|
||||||
string parsed;
|
string parsed;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -58,7 +58,7 @@ static void handleErrorCB(EClient */*client*/, const gchar *error_msg, gpointer
|
||||||
|
|
||||||
EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
||||||
ESource *(*refBuiltin)(ESourceRegistry *),
|
ESource *(*refBuiltin)(ESourceRegistry *),
|
||||||
const boost::function<EClient *(ESource *, GError **gerror)> &newClient)
|
const std::function<EClient *(ESource *, GError **gerror)> &newClient)
|
||||||
{
|
{
|
||||||
EClientCXX client;
|
EClientCXX client;
|
||||||
GErrorCXX gerror;
|
GErrorCXX gerror;
|
||||||
|
|
|
@ -71,7 +71,7 @@ class EvolutionSyncSource : public TrackingSyncSource
|
||||||
ESource *(*getDef)(ESourceRegistry *));
|
ESource *(*getDef)(ESourceRegistry *));
|
||||||
EClientCXX openESource(const char *extension,
|
EClientCXX openESource(const char *extension,
|
||||||
ESource *(*refBuiltin)(ESourceRegistry *),
|
ESource *(*refBuiltin)(ESourceRegistry *),
|
||||||
const boost::function<EClient *(ESource *, GError **gerror)> &newClient);
|
const std::function<EClient *(ESource *, GError **gerror)> &newClient);
|
||||||
|
|
||||||
// Implementation of SyncSource calls which only works when using EDS Client API
|
// Implementation of SyncSource calls which only works when using EDS Client API
|
||||||
// and EDS > 3.4. Older EDS has no way of creating sources easily (or at all).
|
// and EDS > 3.4. Older EDS has no way of creating sources easily (or at all).
|
||||||
|
|
|
@ -88,7 +88,7 @@ class FileSyncSourceUnitTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("file", "file:text/vcard:3.0", true));
|
source.reset(SyncSource::createTestingSource("file", "file:text/vcard:3.0", true));
|
||||||
source.reset(SyncSource::createTestingSource("file", "file:text/plain:1.0", true));
|
source.reset(SyncSource::createTestingSource("file", "file:text/plain:1.0", true));
|
||||||
source.reset(SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true));
|
source.reset(SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true));
|
||||||
|
|
|
@ -36,11 +36,11 @@ public:
|
||||||
" using an account created and managed with GNOME Control Center.")
|
" using an account created and managed with GNOME Control Center.")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username,
|
virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
// Returning NULL if not enabled...
|
// Returning NULL if not enabled...
|
||||||
boost::shared_ptr<AuthProvider> provider;
|
std::shared_ptr<AuthProvider> provider;
|
||||||
#ifdef USE_GOA
|
#ifdef USE_GOA
|
||||||
provider = createGOAAuthProvider(username, password);
|
provider = createGOAAuthProvider(username, password);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,7 +74,7 @@ class GOAManager : private GDBusCXX::DBusRemoteObject
|
||||||
* (the unique user visible string). The account must support OAuth2,
|
* (the unique user visible string). The account must support OAuth2,
|
||||||
* otherwise an error is thrown.
|
* otherwise an error is thrown.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID);
|
std::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GOAAccount
|
class GOAAccount
|
||||||
|
@ -97,7 +97,7 @@ GOAManager::GOAManager(const GDBusCXX::DBusConnectionPtr &conn) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username)
|
std::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username)
|
||||||
{
|
{
|
||||||
SE_LOG_DEBUG(NULL, "Looking up all accounts in GNOME Online Accounts, searching for '%s'.", username.c_str());
|
SE_LOG_DEBUG(NULL, "Looking up all accounts in GNOME Online Accounts, searching for '%s'.", username.c_str());
|
||||||
ManagedObjects objects = m_getManagedObjects();
|
ManagedObjects objects = m_getManagedObjects();
|
||||||
|
@ -172,7 +172,7 @@ boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &usern
|
||||||
username.c_str()));
|
username.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<GOAAccount> account(new GOAAccount(getConnection(), accountPath));
|
auto account = std::make_shared<GOAAccount>(getConnection(), accountPath);
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,10 +187,10 @@ GOAAccount::GOAAccount(const GDBusCXX::DBusConnectionPtr &conn,
|
||||||
|
|
||||||
class GOAAuthProvider : public AuthProvider
|
class GOAAuthProvider : public AuthProvider
|
||||||
{
|
{
|
||||||
boost::shared_ptr<GOAAccount> m_account;
|
std::shared_ptr<GOAAccount> m_account;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GOAAuthProvider(const boost::shared_ptr<GOAAccount> &account) :
|
GOAAuthProvider(const std::shared_ptr<GOAAccount> &account) :
|
||||||
m_account(account)
|
m_account(account)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ public:
|
||||||
virtual std::string getUsername() const { return ""; }
|
virtual std::string getUsername() const { return ""; }
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
// Because we share the connection, hopefully this won't be too expensive.
|
// Because we share the connection, hopefully this won't be too expensive.
|
||||||
|
@ -222,8 +222,8 @@ boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &use
|
||||||
}
|
}
|
||||||
|
|
||||||
GOAManager manager(conn);
|
GOAManager manager(conn);
|
||||||
boost::shared_ptr<GOAAccount> account = manager.lookupAccount(username);
|
std::shared_ptr<GOAAccount> account = manager.lookupAccount(username);
|
||||||
boost::shared_ptr<AuthProvider> provider(new GOAAuthProvider(account));
|
auto provider = std::make_shared<GOAAuthProvider>(account);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
class AuthProvider;
|
class AuthProvider;
|
||||||
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password);
|
const InitStateString &password);
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -126,7 +126,7 @@ class KCalExtendedSourceUnitTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true));
|
source.reset(SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,7 +115,7 @@ class MaemoCalendarSourceUnitTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("calendar", "calendar", true));
|
source.reset(SyncSource::createTestingSource("calendar", "calendar", true));
|
||||||
source.reset(SyncSource::createTestingSource("calendar", "maemo-events", true));
|
source.reset(SyncSource::createTestingSource("calendar", "maemo-events", true));
|
||||||
source.reset(SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true));
|
source.reset(SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true));
|
||||||
|
|
|
@ -31,7 +31,7 @@ SE_BEGIN_CXX
|
||||||
|
|
||||||
class RefreshTokenAuthProvider : public AuthProvider
|
class RefreshTokenAuthProvider : public AuthProvider
|
||||||
{
|
{
|
||||||
boost::shared_ptr<HTTPTransportAgent> m_agent;
|
std::shared_ptr<HTTPTransportAgent> m_agent;
|
||||||
std::string m_tokenHost;
|
std::string m_tokenHost;
|
||||||
std::string m_tokenPath;
|
std::string m_tokenPath;
|
||||||
std::string m_scope;
|
std::string m_scope;
|
||||||
|
@ -47,6 +47,13 @@ public:
|
||||||
const char* clientID,
|
const char* clientID,
|
||||||
const char* clientSecret,
|
const char* clientSecret,
|
||||||
const char* refreshToken) :
|
const char* refreshToken) :
|
||||||
|
m_agent(
|
||||||
|
#ifdef ENABLE_LIBSOUP
|
||||||
|
make_weak_shared::make<SoupTransportAgent>(static_cast<GMainLoop *>(NULL))
|
||||||
|
#elif defined(ENABLE_LIBCURL)
|
||||||
|
std::make_shared<CurlTransportAgent>()
|
||||||
|
#endif
|
||||||
|
),
|
||||||
m_tokenHost(tokenHost),
|
m_tokenHost(tokenHost),
|
||||||
m_tokenPath(tokenPath),
|
m_tokenPath(tokenPath),
|
||||||
m_scope(scope),
|
m_scope(scope),
|
||||||
|
@ -54,12 +61,6 @@ public:
|
||||||
m_clientSecret(clientSecret),
|
m_clientSecret(clientSecret),
|
||||||
m_refreshToken(refreshToken)
|
m_refreshToken(refreshToken)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_LIBSOUP
|
|
||||||
m_agent = SoupTransportAgent::create(static_cast<GMainLoop *>(NULL));
|
|
||||||
#elif defined(ENABLE_LIBCURL)
|
|
||||||
boost::shared_ptr<CurlTransportAgent> agent(new CurlTransportAgent());
|
|
||||||
m_agent = agent;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_OAUTH2; }
|
virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_OAUTH2; }
|
||||||
|
@ -158,11 +159,11 @@ public:
|
||||||
virtual std::string getUsername() const { return ""; }
|
virtual std::string getUsername() const { return ""; }
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
// Expected content of parameter GVariant.
|
// Expected content of parameter GVariant.
|
||||||
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free);
|
std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free);
|
||||||
|
|
||||||
// 'username' is the part after oauth2: which we can parse directly.
|
// 'username' is the part after oauth2: which we can parse directly.
|
||||||
GErrorCXX gerror;
|
GErrorCXX gerror;
|
||||||
|
@ -207,7 +208,7 @@ boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &
|
||||||
if (password.empty()) {
|
if (password.empty()) {
|
||||||
SE_THROW("need refresh token provided as password");
|
SE_THROW("need refresh token provided as password");
|
||||||
}
|
}
|
||||||
boost::shared_ptr<AuthProvider> provider(new RefreshTokenAuthProvider(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str()));
|
auto provider = std::make_shared<RefreshTokenAuthProvider>(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str());
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
class AuthProvider;
|
class AuthProvider;
|
||||||
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password);
|
const InitStateString &password);
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -41,10 +41,10 @@ public:
|
||||||
" 'Scope', 'ClientID', 'ClientSecret'\n")
|
" 'Scope', 'ClientID', 'ClientSecret'\n")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username,
|
virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<AuthProvider> provider;
|
std::shared_ptr<AuthProvider> provider;
|
||||||
provider = createOAuth2AuthProvider(username, password);
|
provider = createOAuth2AuthProvider(username, password);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "gdbus-cxx-bridge.h"
|
#include "gdbus-cxx-bridge.h"
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <synthesis/SDK_util.h>
|
#include <synthesis/SDK_util.h>
|
||||||
|
|
||||||
|
@ -226,7 +225,7 @@ class PullAll
|
||||||
|
|
||||||
uint16_t m_numContacts; // Number of existing contacts, according to GetSize() or after downloading.
|
uint16_t m_numContacts; // Number of existing contacts, according to GetSize() or after downloading.
|
||||||
uint16_t m_currentContact; // Numbered starting with zero according to discovery in addVCards.
|
uint16_t m_currentContact; // Numbered starting with zero according to discovery in addVCards.
|
||||||
boost::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing.
|
std::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing.
|
||||||
size_t m_tmpFileOffset; // Number of bytes already parsed.
|
size_t m_tmpFileOffset; // Number of bytes already parsed.
|
||||||
uint16_t m_transferOffset; // First contact requested as part of current transfer.
|
uint16_t m_transferOffset; // First contact requested as part of current transfer.
|
||||||
uint16_t m_initialOffset; // First contact request by first transfer.
|
uint16_t m_initialOffset; // First contact request by first transfer.
|
||||||
|
@ -269,15 +268,16 @@ PullAll::~PullAll()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class PbapSession : private boost::noncopyable {
|
class PbapSession : private boost::noncopyable, public enable_weak_from_this<PbapSession> {
|
||||||
public:
|
public:
|
||||||
static boost::shared_ptr<PbapSession> create(PbapSyncSource &parent);
|
// Construct via make_weak_shared.
|
||||||
|
friend make_weak_shared;
|
||||||
|
|
||||||
void initSession(const std::string &address, const std::string &format);
|
void initSession(const std::string &address, const std::string &format);
|
||||||
|
|
||||||
typedef std::map<std::string, pcrecpp::StringPiece> Content;
|
typedef std::map<std::string, pcrecpp::StringPiece> Content;
|
||||||
|
|
||||||
boost::shared_ptr<PullAll> startPullAll(const PullParams &pullParams);
|
std::shared_ptr<PullAll> startPullAll(const PullParams &pullParams);
|
||||||
void continuePullAll(PullAll &state);
|
void continuePullAll(PullAll &state);
|
||||||
void checkForError(); // Throws exception if transfer failed.
|
void checkForError(); // Throws exception if transfer failed.
|
||||||
Timespec transferComplete() const;
|
Timespec transferComplete() const;
|
||||||
|
@ -290,7 +290,6 @@ private:
|
||||||
PbapSession(PbapSyncSource &parent);
|
PbapSession(PbapSyncSource &parent);
|
||||||
|
|
||||||
PbapSyncSource &m_parent;
|
PbapSyncSource &m_parent;
|
||||||
boost::weak_ptr<PbapSession> m_self;
|
|
||||||
std::unique_ptr<GDBusCXX::DBusRemoteObject> m_client;
|
std::unique_ptr<GDBusCXX::DBusRemoteObject> m_client;
|
||||||
bool m_frozen;
|
bool m_frozen;
|
||||||
enum {
|
enum {
|
||||||
|
@ -335,8 +334,6 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> >
|
std::unique_ptr<GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> >
|
||||||
m_errorSignal;
|
m_errorSignal;
|
||||||
void errorCb(const GDBusCXX::Path_t &path, const std::string &error,
|
|
||||||
const std::string &msg);
|
|
||||||
|
|
||||||
// Bluez 5
|
// Bluez 5
|
||||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t;
|
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t;
|
||||||
|
@ -349,7 +346,6 @@ private:
|
||||||
// new obexd API
|
// new obexd API
|
||||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t> CompleteSignal_t;
|
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t> CompleteSignal_t;
|
||||||
std::unique_ptr<CompleteSignal_t> m_completeSignal;
|
std::unique_ptr<CompleteSignal_t> m_completeSignal;
|
||||||
void completeCb(const GDBusCXX::Path_t &path);
|
|
||||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t;
|
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t;
|
||||||
std::unique_ptr<PropertyChangedSignal_t> m_propertyChangedSignal;
|
std::unique_ptr<PropertyChangedSignal_t> m_propertyChangedSignal;
|
||||||
void propertyChangedCb(const GDBusCXX::Path_t &path, const std::string &name, const boost::variant<int64_t> &value);
|
void propertyChangedCb(const GDBusCXX::Path_t &path, const std::string &name, const boost::variant<int64_t> &value);
|
||||||
|
@ -363,13 +359,6 @@ PbapSession::PbapSession(PbapSyncSource &parent) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<PbapSession> PbapSession::create(PbapSyncSource &parent)
|
|
||||||
{
|
|
||||||
boost::shared_ptr<PbapSession> session(new PbapSession(parent));
|
|
||||||
session->m_self = session;
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
||||||
const std::string &interface,
|
const std::string &interface,
|
||||||
const Params &changed,
|
const Params &changed,
|
||||||
|
@ -413,24 +402,6 @@ void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PbapSession::completeCb(const GDBusCXX::Path_t &path)
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
|
|
||||||
m_transfers[path] = Completion::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PbapSession::errorCb(const GDBusCXX::Path_t &path,
|
|
||||||
const std::string &error,
|
|
||||||
const std::string &msg)
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
|
|
||||||
path.c_str(), error.c_str(), msg.c_str());
|
|
||||||
Completion &completion = m_transfers[path];
|
|
||||||
completion.m_transferComplete = Timespec::monotonic();
|
|
||||||
completion.m_transferErrorCode = error;
|
|
||||||
completion.m_transferErrorMsg = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path,
|
void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const boost::variant<int64_t> &value)
|
const boost::variant<int64_t> &value)
|
||||||
|
@ -598,7 +569,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
// pointer and ignore callback when the instance is already gone.
|
// pointer and ignore callback when the instance is already gone.
|
||||||
// Should not happen with signals (destructing the class unregisters
|
// Should not happen with signals (destructing the class unregisters
|
||||||
// the watch), but very well may happen in asynchronous method
|
// the watch), but very well may happen in asynchronous method
|
||||||
// calls. Therefore maintain m_self and show how to use it here.
|
// calls.
|
||||||
if (m_obexAPI == BLUEZ5) {
|
if (m_obexAPI == BLUEZ5) {
|
||||||
// Bluez 5
|
// Bluez 5
|
||||||
m_propChangedSignal.reset(new PropChangedSignal_t
|
m_propChangedSignal.reset(new PropChangedSignal_t
|
||||||
|
@ -607,7 +578,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"PropertiesChanged",
|
"PropertiesChanged",
|
||||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||||
m_propChangedSignal->activate(boost::bind(&PbapSession::propChangedCb, m_self, _1, _2, _3, _4));
|
m_propChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface, const Params &changed, const std::vector<std::string> &invalidated) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
if (lock) {
|
||||||
|
lock->propChangedCb(path, interface, changed, invalidated);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// obexd >= 0.47
|
// obexd >= 0.47
|
||||||
m_completeSignal.reset(new CompleteSignal_t
|
m_completeSignal.reset(new CompleteSignal_t
|
||||||
|
@ -616,7 +592,13 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
OBC_TRANSFER_INTERFACE_NEW,
|
OBC_TRANSFER_INTERFACE_NEW,
|
||||||
"Complete",
|
"Complete",
|
||||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||||
m_completeSignal->activate(boost::bind(&PbapSession::completeCb, m_self, _1));
|
m_completeSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
|
||||||
|
if (lock) {
|
||||||
|
lock->m_transfers[path] = Completion::now();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// same for error
|
// same for error
|
||||||
m_errorSignal.reset(new GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string>
|
m_errorSignal.reset(new GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string>
|
||||||
|
@ -625,7 +607,17 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
OBC_TRANSFER_INTERFACE_NEW,
|
OBC_TRANSFER_INTERFACE_NEW,
|
||||||
"Error",
|
"Error",
|
||||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||||
m_errorSignal->activate(boost::bind(&PbapSession::errorCb, m_self, _1, _2, _3));
|
m_errorSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &error, const std::string &msg) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
|
||||||
|
path.c_str(), error.c_str(), msg.c_str());
|
||||||
|
if (lock) {
|
||||||
|
Completion &completion = lock->m_transfers[path];
|
||||||
|
completion.m_transferComplete = Timespec::monotonic();
|
||||||
|
completion.m_transferErrorCode = error;
|
||||||
|
completion.m_transferErrorMsg = msg;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// and property changes
|
// and property changes
|
||||||
m_propertyChangedSignal.reset(new PropertyChangedSignal_t(GDBusCXX::SignalFilter(m_client->getConnection(),
|
m_propertyChangedSignal.reset(new PropertyChangedSignal_t(GDBusCXX::SignalFilter(m_client->getConnection(),
|
||||||
|
@ -633,7 +625,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
OBC_TRANSFER_INTERFACE_NEW,
|
OBC_TRANSFER_INTERFACE_NEW,
|
||||||
"PropertyChanged",
|
"PropertyChanged",
|
||||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||||
m_propertyChangedSignal->activate(boost::bind(&PbapSession::propertyChangedCb, m_self, _1, _2, _3));
|
m_propertyChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface , const boost::variant<int64_t> &value) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
if (lock) {
|
||||||
|
lock->propertyChangedCb(path, interface, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// obexd < 0.47
|
// obexd < 0.47
|
||||||
|
@ -666,7 +663,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
Properties::const_iterator entry =
|
Properties::const_iterator entry =
|
||||||
std::find_if(m_filterFields.begin(),
|
std::find_if(m_filterFields.begin(),
|
||||||
m_filterFields.end(),
|
m_filterFields.end(),
|
||||||
boost::bind(&boost::iequals<std::string,std::string>, _1, prop, std::locale()));
|
[&prop] (const std::string &other) { return boost::iequals(other, prop, std::locale()); });
|
||||||
|
|
||||||
if (entry == m_filterFields.end()) {
|
if (entry == m_filterFields.end()) {
|
||||||
m_parent.throwError(SE_HERE, StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s",
|
m_parent.throwError(SE_HERE, StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s",
|
||||||
|
@ -687,7 +684,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
||||||
SE_LOG_DEBUG(NULL, "PBAP session initialized");
|
SE_LOG_DEBUG(NULL, "PBAP session initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams)
|
std::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams)
|
||||||
{
|
{
|
||||||
resetTransfer();
|
resetTransfer();
|
||||||
blockOnFreeze();
|
blockOnFreeze();
|
||||||
|
@ -744,7 +741,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<PullAll> state(new PullAll);
|
auto state = std::make_shared<PullAll>();
|
||||||
state->m_pullParams = pullParams;
|
state->m_pullParams = pullParams;
|
||||||
state->m_contentStartIndex = 0;
|
state->m_contentStartIndex = 0;
|
||||||
state->m_currentContact = 0;
|
state->m_currentContact = 0;
|
||||||
|
@ -812,7 +809,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
||||||
// and the Synthesis engine will ignore the ID (src/sysync/binfileimplds.cpp:
|
// and the Synthesis engine will ignore the ID (src/sysync/binfileimplds.cpp:
|
||||||
// "Record does not exist any more in database%s -> ignore").
|
// "Record does not exist any more in database%s -> ignore").
|
||||||
state->m_tmpFileOffset = 0;
|
state->m_tmpFileOffset = 0;
|
||||||
state->m_session = m_self.lock();
|
state->m_session = shared_from_this();
|
||||||
state->m_filter = currentFilter;
|
state->m_filter = currentFilter;
|
||||||
} else {
|
} else {
|
||||||
// < 0.47
|
// < 0.47
|
||||||
|
@ -1135,10 +1132,15 @@ PbapSyncSource::PbapSyncSource(const SyncSourceParams ¶ms) :
|
||||||
SyncSource(params)
|
SyncSource(params)
|
||||||
{
|
{
|
||||||
SyncSourceSession::init(m_operations);
|
SyncSourceSession::init(m_operations);
|
||||||
m_operations.m_readNextItem = boost::bind(&PbapSyncSource::readNextItem, this, _1, _2, _3);
|
m_operations.m_readNextItem = [this] (sysync::ItemID aID,
|
||||||
m_operations.m_readItemAsKey = boost::bind(&PbapSyncSource::readItemAsKey,
|
sysync::sInt32 *aStatus,
|
||||||
this, _1, _2);
|
bool aFirst) {
|
||||||
m_session = PbapSession::create(*this);
|
return readNextItem(aID, aStatus, aFirst);
|
||||||
|
};
|
||||||
|
m_operations.m_readItemAsKey = [this] (sysync::cItemID aID, sysync::KeyH aItemKey) {
|
||||||
|
return readItemAsKey(aID, aItemKey);
|
||||||
|
};
|
||||||
|
m_session = make_weak_shared::make<PbapSession>(*this);
|
||||||
const char *PBAPSyncMode = getenv("SYNCEVOLUTION_PBAP_SYNC");
|
const char *PBAPSyncMode = getenv("SYNCEVOLUTION_PBAP_SYNC");
|
||||||
m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_INCREMENTAL :
|
m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_INCREMENTAL :
|
||||||
boost::iequals(PBAPSyncMode, "incremental") ? PBAP_SYNC_INCREMENTAL :
|
boost::iequals(PBAPSyncMode, "incremental") ? PBAP_SYNC_INCREMENTAL :
|
||||||
|
|
|
@ -65,8 +65,8 @@ class PbapSyncSource : virtual public SyncSource, virtual public SyncSourceSessi
|
||||||
virtual void readItemRaw(const std::string &luid, std::string &item);
|
virtual void readItemRaw(const std::string &luid, std::string &item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<PbapSession> m_session;
|
std::shared_ptr<PbapSession> m_session;
|
||||||
boost::shared_ptr<PullAll> m_pullAll;
|
std::shared_ptr<PullAll> m_pullAll;
|
||||||
enum PBAPSyncMode {
|
enum PBAPSyncMode {
|
||||||
PBAP_SYNC_NORMAL, ///< Read contact data according to filter.
|
PBAP_SYNC_NORMAL, ///< Read contact data according to filter.
|
||||||
PBAP_SYNC_TEXT, ///< Sync without reading photo data from phone and keeping local photos instead.
|
PBAP_SYNC_TEXT, ///< Sync without reading photo data from phone and keeping local photos instead.
|
||||||
|
|
|
@ -76,7 +76,7 @@ class QtContactsSourceUnitTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true));
|
source.reset(SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true));
|
||||||
source.reset(SyncSource::createTestingSource("qtcontacts", "QtContacts", true));
|
source.reset(SyncSource::createTestingSource("qtcontacts", "QtContacts", true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,6 @@
|
||||||
#include <syncevo/GVariantSupport.h>
|
#include <syncevo/GVariantSupport.h>
|
||||||
#include <pcrecpp.h>
|
#include <pcrecpp.h>
|
||||||
|
|
||||||
#include <boost/lambda/core.hpp>
|
|
||||||
|
|
||||||
SE_GOBJECT_TYPE(SignonAuthService)
|
SE_GOBJECT_TYPE(SignonAuthService)
|
||||||
SE_GOBJECT_TYPE(SignonAuthSession)
|
SE_GOBJECT_TYPE(SignonAuthSession)
|
||||||
SE_GOBJECT_TYPE(SignonIdentity)
|
SE_GOBJECT_TYPE(SignonIdentity)
|
||||||
|
@ -210,10 +208,10 @@ static void StoreIdentityCB(SignonIdentity *self,
|
||||||
data->m_gerror = error;
|
data->m_gerror = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<AuthProvider> provider;
|
std::shared_ptr<AuthProvider> provider;
|
||||||
|
|
||||||
// Split username into <account ID> and <service name>.
|
// Split username into <account ID> and <service name>.
|
||||||
// Be flexible and allow leading/trailing white space.
|
// Be flexible and allow leading/trailing white space.
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
#include <syncevo/GVariantSupport.h>
|
#include <syncevo/GVariantSupport.h>
|
||||||
#include <pcrecpp.h>
|
#include <pcrecpp.h>
|
||||||
|
|
||||||
#include <boost/lambda/core.hpp>
|
|
||||||
|
|
||||||
SE_GOBJECT_TYPE(SignonAuthService)
|
SE_GOBJECT_TYPE(SignonAuthService)
|
||||||
SE_GOBJECT_TYPE(SignonAuthSession)
|
SE_GOBJECT_TYPE(SignonAuthSession)
|
||||||
SE_GOBJECT_TYPE(SignonIdentity)
|
SE_GOBJECT_TYPE(SignonIdentity)
|
||||||
|
@ -124,11 +122,11 @@ public:
|
||||||
virtual std::string getUsername() const { return ""; }
|
virtual std::string getUsername() const { return ""; }
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
// Expected content of parameter GVariant.
|
// Expected content of parameter GVariant.
|
||||||
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);
|
std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);
|
||||||
|
|
||||||
// 'username' is the part after signon: which we can parse directly.
|
// 'username' is the part after signon: which we can parse directly.
|
||||||
GErrorCXX gerror;
|
GErrorCXX gerror;
|
||||||
|
@ -179,7 +177,7 @@ boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &
|
||||||
SE_LOG_DEBUG(NULL, "using signond identity %d", signonID);
|
SE_LOG_DEBUG(NULL, "using signond identity %d", signonID);
|
||||||
SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF);
|
SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF);
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> provider(new SignonAuthProvider(authSession, sessionData, mechanism));
|
auto provider = std::make_shared<SignonAuthProvider>(authSession, sessionData, mechanism);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -35,7 +35,7 @@ SE_BEGIN_CXX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class AuthProvider;
|
class AuthProvider;
|
||||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||||
const InitStateString &password);
|
const InitStateString &password);
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -64,10 +64,10 @@ public:
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username,
|
virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||||
const InitStateString &password)
|
const InitStateString &password)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<AuthProvider> provider;
|
std::shared_ptr<AuthProvider> provider;
|
||||||
provider = createSignonAuthProvider(username, password);
|
provider = createSignonAuthProvider(username, password);
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#include <syncevo/SafeConfigNode.h>
|
#include <syncevo/SafeConfigNode.h>
|
||||||
#include <SQLiteUtil.h>
|
#include <SQLiteUtil.h>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
|
@ -64,17 +62,17 @@ class SQLiteContactSource : public SyncSource,
|
||||||
SQLiteContactSource(const SyncSourceParams ¶ms) :
|
SQLiteContactSource(const SyncSourceParams ¶ms) :
|
||||||
SyncSource(params),
|
SyncSource(params),
|
||||||
m_trackingNode(new PrefixConfigNode("item-",
|
m_trackingNode(new PrefixConfigNode("item-",
|
||||||
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode()))))
|
std::static_pointer_cast<ConfigNode>(std::make_shared<SafeConfigNode>(params.m_nodes.getTrackingNode()))))
|
||||||
{
|
{
|
||||||
SyncSourceSession::init(m_operations);
|
SyncSourceSession::init(m_operations);
|
||||||
SyncSourceDelete::init(m_operations);
|
SyncSourceDelete::init(m_operations);
|
||||||
SyncSourceRevisions::init(NULL, NULL, 1, m_operations);
|
SyncSourceRevisions::init(NULL, NULL, 1, m_operations);
|
||||||
SyncSourceChanges::init(m_operations);
|
SyncSourceChanges::init(m_operations);
|
||||||
|
|
||||||
m_operations.m_isEmpty = boost::bind(&SQLiteContactSource::isEmpty, this);
|
m_operations.m_isEmpty = [this] () { return isEmpty(); };
|
||||||
m_operations.m_readItemAsKey = boost::bind(&SQLiteContactSource::readItemAsKey, this, _1, _2);
|
m_operations.m_readItemAsKey = [this] (sysync::cItemID aID, sysync::KeyH aItemKey) { return readItemAsKey(aID, aItemKey); };
|
||||||
m_operations.m_insertItemAsKey = boost::bind(&SQLiteContactSource::insertItemAsKey, this, _1, (sysync::cItemID)NULL, _2);
|
m_operations.m_insertItemAsKey = [this] (sysync::KeyH aItemKey, sysync::ItemID newID) { return insertItemAsKey(aItemKey, (sysync::cItemID)NULL, newID); };
|
||||||
m_operations.m_updateItemAsKey = boost::bind(&SQLiteContactSource::insertItemAsKey, this, _1, _2, _3);
|
m_operations.m_updateItemAsKey = [this] (sysync::KeyH aItemKey, sysync::cItemID aID, sysync::ItemID newID) { return insertItemAsKey(aItemKey, aID, newID); };
|
||||||
SyncSourceLogging::init(InitList<std::string> ("N_FIRST")+"N_MIDDLE"+"N_LAST", ", ", m_operations);
|
SyncSourceLogging::init(InitList<std::string> ("N_FIRST")+"N_MIDDLE"+"N_LAST", ", ", m_operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +101,7 @@ class SQLiteContactSource : public SyncSource,
|
||||||
virtual void listAllItems(RevisionMap_t &revisions);
|
virtual void listAllItems(RevisionMap_t &revisions);
|
||||||
private:
|
private:
|
||||||
/** encapsulates access to database */
|
/** encapsulates access to database */
|
||||||
boost::shared_ptr<ConfigNode> m_trackingNode;
|
std::shared_ptr<ConfigNode> m_trackingNode;
|
||||||
SQLiteUtil m_sqlite;
|
SQLiteUtil m_sqlite;
|
||||||
|
|
||||||
/** implements the m_isEmpty operation */
|
/** implements the m_isEmpty operation */
|
||||||
|
|
|
@ -71,7 +71,7 @@ class EvolutionSQLiteContactsTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("contacts", "contacts", true));
|
source.reset(SyncSource::createTestingSource("contacts", "contacts", true));
|
||||||
source.reset(SyncSource::createTestingSource("contacts", "addressbook", true));
|
source.reset(SyncSource::createTestingSource("contacts", "addressbook", true));
|
||||||
source.reset(SyncSource::createTestingSource("contacts", "sqlite-contacts", true));
|
source.reset(SyncSource::createTestingSource("contacts", "sqlite-contacts", true));
|
||||||
|
|
|
@ -87,14 +87,14 @@ class TDEAddressBookTest : public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||||
string &data) {
|
string &data) {
|
||||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||||
return res.m_luid;
|
return res.m_luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
|
||||||
|
@ -106,7 +106,7 @@ protected:
|
||||||
// TODO: support default databases
|
// TODO: support default databases
|
||||||
|
|
||||||
// void testOpenDefaultAddressBook() {
|
// void testOpenDefaultAddressBook() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -147,14 +147,14 @@ class TDECalendarTest : public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||||
string &data) {
|
string &data) {
|
||||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||||
return res.m_luid;
|
return res.m_luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||||
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||||
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
|
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
|
||||||
|
@ -180,19 +180,19 @@ protected:
|
||||||
// TODO: support default databases
|
// TODO: support default databases
|
||||||
|
|
||||||
// void testOpenDefaultCalendar() {
|
// void testOpenDefaultCalendar() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tdepim-calendar", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tdepim-calendar", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void testOpenDefaultTodo() {
|
// void testOpenDefaultTodo() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "tdepim-tasks", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "tdepim-tasks", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void testOpenDefaultMemo() {
|
// void testOpenDefaultMemo() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
@ -203,7 +203,7 @@ protected:
|
||||||
prefix = "SyncEvolution_Test_";
|
prefix = "SyncEvolution_Test_";
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-calendar", true, prefix));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-calendar", true, prefix));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
|
|
||||||
|
|
|
@ -102,14 +102,14 @@ class TDENotesTest : public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||||
string &data) {
|
string &data) {
|
||||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||||
return res.m_luid;
|
return res.m_luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
|
|
||||||
// source.reset(SyncSource::createTestingSource("memos", "memos", true));
|
// source.reset(SyncSource::createTestingSource("memos", "memos", true));
|
||||||
source.reset(SyncSource::createTestingSource("memos", "tdepim-notes", true));
|
source.reset(SyncSource::createTestingSource("memos", "tdepim-notes", true));
|
||||||
|
@ -119,7 +119,7 @@ protected:
|
||||||
// TODO: support default databases
|
// TODO: support default databases
|
||||||
|
|
||||||
// void testOpenDefaultMemo() {
|
// void testOpenDefaultMemo() {
|
||||||
// boost::shared_ptr<TestingSyncSource> source;
|
// std::shared_ptr<TestingSyncSource> source;
|
||||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
|
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
|
||||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
// }
|
// }
|
||||||
|
@ -130,7 +130,7 @@ protected:
|
||||||
prefix = "SyncEvolution_Test_";
|
prefix = "SyncEvolution_Test_";
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-notes", true, prefix));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-notes", true, prefix));
|
||||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include "CalDAVSource.h"
|
#include "CalDAVSource.h"
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
|
@ -42,7 +41,7 @@ static void removeSyncEvolutionExdateDetached(icalcomponent *parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
CalDAVSource::CalDAVSource(const SyncSourceParams ¶ms,
|
CalDAVSource::CalDAVSource(const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<Neon::Settings> &settings) :
|
const std::shared_ptr<Neon::Settings> &settings) :
|
||||||
WebDAVSource(params, settings)
|
WebDAVSource(params, settings)
|
||||||
{
|
{
|
||||||
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
|
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
|
||||||
|
@ -50,10 +49,16 @@ CalDAVSource::CalDAVSource(const SyncSourceParams ¶ms,
|
||||||
m_operations);
|
m_operations);
|
||||||
// override default backup/restore from base class with our own
|
// override default backup/restore from base class with our own
|
||||||
// version
|
// version
|
||||||
m_operations.m_backupData = boost::bind(&CalDAVSource::backupData,
|
m_operations.m_backupData = [this] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
||||||
this, _1, _2, _3);
|
const SyncSource::Operations::BackupInfo &newBackup,
|
||||||
m_operations.m_restoreData = boost::bind(&CalDAVSource::restoreData,
|
BackupReport &backupReport) {
|
||||||
this, _1, _2, _3);
|
backupData(oldBackup, newBackup, backupReport);
|
||||||
|
};
|
||||||
|
m_operations.m_restoreData = [this] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
||||||
|
bool dryrun,
|
||||||
|
SyncSourceReport &report) {
|
||||||
|
restoreData(oldBackup, dryrun, report);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
|
void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
|
||||||
|
@ -106,13 +111,14 @@ void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
|
||||||
while (true) {
|
while (true) {
|
||||||
string data;
|
string data;
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initReportParser(boost::bind(&CalDAVSource::appendItem, this,
|
auto process = [this, &revisions, &data] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
boost::ref(revisions),
|
return appendItem(revisions, href, etag, data);
|
||||||
_1, _2, boost::ref(data)));
|
};
|
||||||
|
parser.initReportParser(process);
|
||||||
m_cache.clear();
|
m_cache.clear();
|
||||||
m_cache.m_initialized = false;
|
m_cache.m_initialized = false;
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
Neon::XMLParser::append(data));
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -124,14 +130,6 @@ void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
|
||||||
m_cache.m_initialized = true;
|
m_cache.m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalDAVSource::addResource(StringMap &items,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag)
|
|
||||||
{
|
|
||||||
std::string davLUID = path2luid(Neon::URI::parse(href).m_path);
|
|
||||||
items[davLUID] = ETag2Rev(etag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
|
void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
|
||||||
{
|
{
|
||||||
// list items to identify new, updated and removed ones
|
// list items to identify new, updated and removed ones
|
||||||
|
@ -157,8 +155,11 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
|
||||||
string data;
|
string data;
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
items.clear();
|
items.clear();
|
||||||
parser.initReportParser(boost::bind(&CalDAVSource::addResource,
|
auto process = [this, &items] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
this, boost::ref(items), _1, _2));
|
std::string davLUID = path2luid(Neon::URI::parse(href).m_path);
|
||||||
|
items[davLUID] = ETag2Rev(etag);
|
||||||
|
};
|
||||||
|
parser.initReportParser(process);
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -250,12 +251,15 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
|
||||||
while (true) {
|
while (true) {
|
||||||
string data;
|
string data;
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initReportParser(boost::bind(&CalDAVSource::appendMultigetResult, this,
|
auto process = [this, &revisions, &results, &data] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
boost::ref(revisions),
|
// record which items were seen in the response...
|
||||||
boost::ref(results),
|
results.insert(path2luid(href));
|
||||||
_1, _2, boost::ref(data)));
|
// and store information about them
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
return appendItem(revisions, href, etag, data);
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
};
|
||||||
|
parser.initReportParser(process);
|
||||||
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
|
Neon::XMLParser::append(data));
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path,
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path,
|
||||||
query, parser);
|
query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
|
@ -289,18 +293,6 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CalDAVSource::appendMultigetResult(SubRevisionMap_t &revisions,
|
|
||||||
std::set<std::string> &luids,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data)
|
|
||||||
{
|
|
||||||
// record which items were seen in the response...
|
|
||||||
luids.insert(path2luid(href));
|
|
||||||
// and store information about them
|
|
||||||
return appendItem(revisions, href, etag, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
|
int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
|
||||||
const std::string &href,
|
const std::string &href,
|
||||||
const std::string &etag,
|
const std::string &etag,
|
||||||
|
@ -351,7 +343,7 @@ int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_cache.m_initialized) {
|
if (!m_cache.m_initialized) {
|
||||||
boost::shared_ptr<Event> event(new Event);
|
auto event = std::make_shared<Event>();
|
||||||
event->m_DAVluid = davLUID;
|
event->m_DAVluid = davLUID;
|
||||||
event->m_UID = uid;
|
event->m_UID = uid;
|
||||||
event->m_etag = entry.m_revision;
|
event->m_etag = entry.m_revision;
|
||||||
|
@ -376,7 +368,7 @@ int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
|
||||||
void CalDAVSource::addSubItem(const std::string &luid,
|
void CalDAVSource::addSubItem(const std::string &luid,
|
||||||
const SubRevisionEntry &entry)
|
const SubRevisionEntry &entry)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Event> &event = m_cache[luid];
|
std::shared_ptr<Event> &event = m_cache[luid];
|
||||||
event.reset(new Event);
|
event.reset(new Event);
|
||||||
event->m_DAVluid = luid;
|
event->m_DAVluid = luid;
|
||||||
event->m_etag = entry.m_revision;
|
event->m_etag = entry.m_revision;
|
||||||
|
@ -406,7 +398,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
||||||
SubItemResult subres;
|
SubItemResult subres;
|
||||||
|
|
||||||
// parse new event
|
// parse new event
|
||||||
boost::shared_ptr<Event> newEvent(new Event);
|
auto newEvent = std::make_shared<Event>();
|
||||||
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
|
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
|
||||||
"parsing iCalendar 2.0");
|
"parsing iCalendar 2.0");
|
||||||
|
|
||||||
|
@ -1062,20 +1054,6 @@ CalDAVSource::Event &CalDAVSource::loadItem(const std::string &davLUID)
|
||||||
return loadItem(event);
|
return loadItem(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CalDAVSource::storeItem(const std::string &wantedLuid,
|
|
||||||
std::string &item,
|
|
||||||
std::string &data,
|
|
||||||
const std::string &href)
|
|
||||||
{
|
|
||||||
std::string luid = path2luid(Neon::URI::parse(href).m_path);
|
|
||||||
if (luid == wantedLuid) {
|
|
||||||
SE_LOG_DEBUG(NULL, "got item %s via REPORT fallback", luid.c_str());
|
|
||||||
item = data;
|
|
||||||
}
|
|
||||||
data.clear();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
|
CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
|
||||||
{
|
{
|
||||||
if (!event.m_calendar) {
|
if (!event.m_calendar) {
|
||||||
|
@ -1111,8 +1089,8 @@ CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
|
||||||
std::string href, etag;
|
std::string href, etag;
|
||||||
item = "";
|
item = "";
|
||||||
parser.initReportParser(href, etag);
|
parser.initReportParser(href, etag);
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(item), _2, _3));
|
Neon::XMLParser::append(item));
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
report.run();
|
report.run();
|
||||||
|
@ -1142,14 +1120,19 @@ CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
|
||||||
while (true) {
|
while (true) {
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
std::string data;
|
std::string data;
|
||||||
parser.initReportParser(boost::bind(&CalDAVSource::storeItem,
|
|
||||||
this,
|
auto store = [this, &event, &item, &data] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
boost::ref(event.m_DAVluid),
|
std::string luid = path2luid(Neon::URI::parse(href).m_path);
|
||||||
boost::ref(item),
|
if (luid == event.m_DAVluid) {
|
||||||
boost::ref(data),
|
SE_LOG_DEBUG(NULL, "got item %s via REPORT fallback", luid.c_str());
|
||||||
_1));
|
item = data;
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
}
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
data.clear();
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
parser.initReportParser(store);
|
||||||
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
|
Neon::XMLParser::append(data));
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -1365,30 +1348,7 @@ void CalDAVSource::backupData(const SyncSource::Operations::ConstBackupInfo &old
|
||||||
"</C:calendar-query>\n";
|
"</C:calendar-query>\n";
|
||||||
string data;
|
string data;
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initReportParser(boost::bind(&CalDAVSource::backupItem, this,
|
auto process = [this, &cache, &data] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
boost::ref(cache),
|
|
||||||
_1, _2, boost::ref(data)));
|
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
|
||||||
Timespec deadline = createDeadline();
|
|
||||||
getSession()->startOperation("REPORT 'full calendar'", deadline);
|
|
||||||
while (true) {
|
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
|
||||||
report.addHeader("Depth", "1");
|
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
|
||||||
if (report.run()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cache.reset();
|
|
||||||
}
|
|
||||||
cache.finalize(backupReport);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CalDAVSource::backupItem(ItemCache &cache,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data)
|
|
||||||
{
|
|
||||||
// detect and ignore empty items, like we do in appendItem()
|
// detect and ignore empty items, like we do in appendItem()
|
||||||
eptr<icalcomponent> calendar(icalcomponent_new_from_string((char *)data.c_str()), // cast is a hack for broken definition in old libical
|
eptr<icalcomponent> calendar(icalcomponent_new_from_string((char *)data.c_str()), // cast is a hack for broken definition in old libical
|
||||||
"iCalendar 2.0");
|
"iCalendar 2.0");
|
||||||
|
@ -1404,7 +1364,24 @@ int CalDAVSource::backupItem(ItemCache &cache,
|
||||||
// reset data for next item
|
// reset data for next item
|
||||||
data.clear();
|
data.clear();
|
||||||
return 0;
|
return 0;
|
||||||
|
};
|
||||||
|
parser.initReportParser(process);
|
||||||
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
|
Neon::XMLParser::append(data));
|
||||||
|
Timespec deadline = createDeadline();
|
||||||
|
getSession()->startOperation("REPORT 'full calendar'", deadline);
|
||||||
|
while (true) {
|
||||||
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
|
report.addHeader("Depth", "1");
|
||||||
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
if (report.run()) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
cache.reset();
|
||||||
|
}
|
||||||
|
cache.finalize(backupReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CalDAVSource::restoreData(const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
void CalDAVSource::restoreData(const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
||||||
bool dryrun,
|
bool dryrun,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -25,7 +25,7 @@ class CalDAVSource : public WebDAVSource,
|
||||||
public SyncSourceLogging
|
public SyncSourceLogging
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CalDAVSource(const SyncSourceParams ¶ms, const boost::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
CalDAVSource(const SyncSourceParams ¶ms, const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
||||||
|
|
||||||
/* implementation of SyncSourceSerialize interface */
|
/* implementation of SyncSourceSerialize interface */
|
||||||
virtual std::string getMimeType() const { return "text/calendar"; }
|
virtual std::string getMimeType() const { return "text/calendar"; }
|
||||||
|
@ -160,7 +160,7 @@ class CalDAVSource : public WebDAVSource,
|
||||||
* again before parsing (depends on server preserving X-
|
* again before parsing (depends on server preserving X-
|
||||||
* extensions, see Event::unescapeRecurrenceID()).
|
* extensions, see Event::unescapeRecurrenceID()).
|
||||||
*/
|
*/
|
||||||
class EventCache : public std::map<std::string, boost::shared_ptr<Event> >
|
class EventCache : public std::map<std::string, std::shared_ptr<Event> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EventCache() : m_initialized(false) {}
|
EventCache() : m_initialized(false) {}
|
||||||
|
@ -175,40 +175,15 @@ class CalDAVSource : public WebDAVSource,
|
||||||
|
|
||||||
std::string getSubDescription(Event &event, const string &subid);
|
std::string getSubDescription(Event &event, const string &subid);
|
||||||
|
|
||||||
/** calback for multiget: same as appendItem, but also records luid of all responses */
|
|
||||||
int appendMultigetResult(SubRevisionMap_t &revisions,
|
|
||||||
std::set<std::string> &luids,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data);
|
|
||||||
|
|
||||||
|
|
||||||
/** callback for listAllSubItems: parse and add new item */
|
/** callback for listAllSubItems: parse and add new item */
|
||||||
int appendItem(SubRevisionMap_t &revisions,
|
int appendItem(SubRevisionMap_t &revisions,
|
||||||
const std::string &href,
|
const std::string &href,
|
||||||
const std::string &etag,
|
const std::string &etag,
|
||||||
std::string &data);
|
std::string &data);
|
||||||
|
|
||||||
/** callback for backupData(): dump into backup */
|
|
||||||
int backupItem(ItemCache &cache,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data);
|
|
||||||
|
|
||||||
/** callback for loadItem(): store right item from REPORT */
|
|
||||||
int storeItem(const std::string &wantedLuid,
|
|
||||||
std::string &item,
|
|
||||||
std::string &data,
|
|
||||||
const std::string &href);
|
|
||||||
|
|
||||||
/** add to m_cache */
|
/** add to m_cache */
|
||||||
void addSubItem(const std::string &luid,
|
void addSubItem(const std::string &luid,
|
||||||
const SubRevisionEntry &entry);
|
const SubRevisionEntry &entry);
|
||||||
|
|
||||||
/** store as luid + revision */
|
|
||||||
void addResource(StringMap &items,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -14,7 +14,7 @@ SE_BEGIN_CXX
|
||||||
|
|
||||||
CalDAVVxxSource::CalDAVVxxSource(const std::string &content,
|
CalDAVVxxSource::CalDAVVxxSource(const std::string &content,
|
||||||
const SyncSourceParams ¶ms,
|
const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<Neon::Settings> &settings) :
|
const std::shared_ptr<Neon::Settings> &settings) :
|
||||||
WebDAVSource(params, settings),
|
WebDAVSource(params, settings),
|
||||||
m_content(content)
|
m_content(content)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -39,7 +39,7 @@ class CalDAVVxxSource : public WebDAVSource,
|
||||||
*/
|
*/
|
||||||
CalDAVVxxSource(const std::string &content,
|
CalDAVVxxSource(const std::string &content,
|
||||||
const SyncSourceParams ¶ms,
|
const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
||||||
|
|
||||||
/* implementation of SyncSourceSerialize interface */
|
/* implementation of SyncSourceSerialize interface */
|
||||||
virtual std::string getMimeType() const {
|
virtual std::string getMimeType() const {
|
||||||
|
|
|
@ -12,7 +12,7 @@ SE_BEGIN_CXX
|
||||||
// TODO: use EDS backend icalstrdup.c
|
// TODO: use EDS backend icalstrdup.c
|
||||||
#define ical_strdup(_x) (_x)
|
#define ical_strdup(_x) (_x)
|
||||||
|
|
||||||
typedef boost::shared_ptr<TransportStatusException> BatchReadFailure;
|
typedef std::shared_ptr<TransportStatusException> BatchReadFailure;
|
||||||
|
|
||||||
class CardDAVCache : public std::map< std::string, boost::variant<std::string, BatchReadFailure> >
|
class CardDAVCache : public std::map< std::string, boost::variant<std::string, BatchReadFailure> >
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ class CardDAVCache : public std::map< std::string, boost::variant<std::string, B
|
||||||
|
|
||||||
|
|
||||||
CardDAVSource::CardDAVSource(const SyncSourceParams ¶ms,
|
CardDAVSource::CardDAVSource(const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<Neon::Settings> &settings) :
|
const std::shared_ptr<Neon::Settings> &settings) :
|
||||||
WebDAVSource(params, settings),
|
WebDAVSource(params, settings),
|
||||||
m_readAheadOrder(READ_NONE),
|
m_readAheadOrder(READ_NONE),
|
||||||
m_cacheMisses(0),
|
m_cacheMisses(0),
|
||||||
|
@ -100,7 +100,7 @@ static size_t MaxBatchSize()
|
||||||
return maxBatchSize;
|
return maxBatchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid)
|
std::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid)
|
||||||
{
|
{
|
||||||
static size_t maxBatchSize = MaxBatchSize();
|
static size_t maxBatchSize = MaxBatchSize();
|
||||||
BatchLUIDs luids;
|
BatchLUIDs luids;
|
||||||
|
@ -167,7 +167,7 @@ boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<CardDAVCache> cache;
|
std::shared_ptr<CardDAVCache> cache;
|
||||||
if (m_readAheadOrder != READ_NONE &&
|
if (m_readAheadOrder != READ_NONE &&
|
||||||
!found) {
|
!found) {
|
||||||
// The requested contact was not on our list. Consider this
|
// The requested contact was not on our list. Consider this
|
||||||
|
@ -207,41 +207,7 @@ boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid
|
||||||
// The purpose of that is two-fold: don't request data again that
|
// The purpose of that is two-fold: don't request data again that
|
||||||
// we already got when resending, and detect missing 404 status errors
|
// we already got when resending, and detect missing 404 status errors
|
||||||
// with Google.
|
// with Google.
|
||||||
parser.initReportParser(boost::bind(&CardDAVSource::addItemToCache, this,
|
auto process = [this, &luids, &data, &cache] (const std::string &href, const std::string &etag, const std::string &status) {
|
||||||
cache, boost::ref(luids),
|
|
||||||
_1, _2, boost::ref(data)));
|
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:carddav", "address-data", _2, _3),
|
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
|
||||||
std::string request = query.str();
|
|
||||||
Neon::Request req(*getSession(), "REPORT", getCalendar().m_path,
|
|
||||||
request, parser);
|
|
||||||
req.addHeader("Depth", "0");
|
|
||||||
req.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
|
||||||
if (req.run()) {
|
|
||||||
// CardDAV servers must include a response for each requested item.
|
|
||||||
// Google CardDAV doesn't due that at the time of implementing the
|
|
||||||
// batched read. As a workaround assume that any remaining item
|
|
||||||
// isn't available.
|
|
||||||
for (const std::string *luid: luids) {
|
|
||||||
boost::shared_ptr<TransportStatusException> failure(new TransportStatusException(__FILE__,
|
|
||||||
__LINE__,
|
|
||||||
StringPrintf("%s: not contained in multiget response", luid->c_str()),
|
|
||||||
STATUS_NOT_FOUND));
|
|
||||||
(*cache)[*luid] = failure;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CardDAVSource::addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
|
|
||||||
BatchLUIDs &luids,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data)
|
|
||||||
{
|
|
||||||
std::string luid = path2luid(href);
|
std::string luid = path2luid(href);
|
||||||
|
|
||||||
// TODO: error checking
|
// TODO: error checking
|
||||||
|
@ -273,6 +239,32 @@ void CardDAVSource::addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
|
||||||
|
|
||||||
// reset data for next item
|
// reset data for next item
|
||||||
data.clear();
|
data.clear();
|
||||||
|
};
|
||||||
|
parser.initReportParser(process);
|
||||||
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:carddav", "address-data"),
|
||||||
|
Neon::XMLParser::append(data));
|
||||||
|
std::string request = query.str();
|
||||||
|
Neon::Request req(*getSession(), "REPORT", getCalendar().m_path,
|
||||||
|
request, parser);
|
||||||
|
req.addHeader("Depth", "0");
|
||||||
|
req.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
if (req.run()) {
|
||||||
|
// CardDAV servers must include a response for each requested item.
|
||||||
|
// Google CardDAV doesn't due that at the time of implementing the
|
||||||
|
// batched read. As a workaround assume that any remaining item
|
||||||
|
// isn't available.
|
||||||
|
for (const std::string *luid: luids) {
|
||||||
|
auto failure = std::make_shared<TransportStatusException>(__FILE__,
|
||||||
|
__LINE__,
|
||||||
|
StringPrintf("%s: not contained in multiget response", luid->c_str()),
|
||||||
|
STATUS_NOT_FOUND);
|
||||||
|
(*cache)[*luid] = failure;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDAVSource::InsertItemResult CardDAVSource::insertItem(const string &luid, const std::string &item, bool raw)
|
CardDAVSource::InsertItemResult CardDAVSource::insertItem(const string &luid, const std::string &item, bool raw)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -26,7 +26,7 @@ class CardDAVSource : public WebDAVSource,
|
||||||
public SyncSourceLogging
|
public SyncSourceLogging
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CardDAVSource(const SyncSourceParams ¶ms, const boost::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
CardDAVSource(const SyncSourceParams ¶ms, const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
|
||||||
|
|
||||||
/* implementation of SyncSourceSerialize interface */
|
/* implementation of SyncSourceSerialize interface */
|
||||||
virtual std::string getMimeType() const { return "text/vcard"; }
|
virtual std::string getMimeType() const { return "text/vcard"; }
|
||||||
|
@ -59,7 +59,7 @@ class CardDAVSource : public WebDAVSource,
|
||||||
private:
|
private:
|
||||||
ReadAheadOrder m_readAheadOrder;
|
ReadAheadOrder m_readAheadOrder;
|
||||||
ReadAheadItems m_nextLUIDs;
|
ReadAheadItems m_nextLUIDs;
|
||||||
boost::shared_ptr<CardDAVCache> m_cardDAVCache;
|
std::shared_ptr<CardDAVCache> m_cardDAVCache;
|
||||||
int m_cacheMisses; /**< number of times that we had to get a contact without using the cache */
|
int m_cacheMisses; /**< number of times that we had to get a contact without using the cache */
|
||||||
int m_contactReads; /**< number of readItem() calls */
|
int m_contactReads; /**< number of readItem() calls */
|
||||||
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
|
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
|
||||||
|
@ -68,13 +68,8 @@ class CardDAVSource : public WebDAVSource,
|
||||||
typedef std::vector<const std::string *> BatchLUIDs;
|
typedef std::vector<const std::string *> BatchLUIDs;
|
||||||
|
|
||||||
void logCacheStats(Logger::Level level);
|
void logCacheStats(Logger::Level level);
|
||||||
boost::shared_ptr<CardDAVCache> readBatch(const std::string &luid);
|
std::shared_ptr<CardDAVCache> readBatch(const std::string &luid);
|
||||||
void invalidateCachedItem(const std::string &luid);
|
void invalidateCachedItem(const std::string &luid);
|
||||||
void addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
|
|
||||||
BatchLUIDs &luids,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string &data);
|
|
||||||
void readItemInternal(const std::string &luid, std::string &item, bool raw);
|
void readItemInternal(const std::string &luid, std::string &item, bool raw);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <boost/algorithm/string/split.hpp>
|
#include <boost/algorithm/string/split.hpp>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/lambda/lambda.hpp>
|
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
#include <syncevo/Logging.h>
|
#include <syncevo/Logging.h>
|
||||||
|
@ -187,7 +185,7 @@ std::string Status2String(const ne_status *status)
|
||||||
status->reason_phrase ? status->reason_phrase : "\"\"");
|
status->reason_phrase ? status->reason_phrase : "\"\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
Session::Session(const boost::shared_ptr<Settings> &settings) :
|
Session::Session(const std::shared_ptr<Settings> &settings) :
|
||||||
m_forceAuthorizationOnce(AUTH_ON_DEMAND),
|
m_forceAuthorizationOnce(AUTH_ON_DEMAND),
|
||||||
m_credentialsSent(false),
|
m_credentialsSent(false),
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
|
@ -285,9 +283,9 @@ Session::~Session()
|
||||||
ne_sock_exit();
|
ne_sock_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Session> Session::m_cachedSession;
|
std::shared_ptr<Session> Session::m_cachedSession;
|
||||||
|
|
||||||
boost::shared_ptr<Session> Session::create(const boost::shared_ptr<Settings> &settings)
|
std::shared_ptr<Session> Session::create(const std::shared_ptr<Settings> &settings)
|
||||||
{
|
{
|
||||||
URI uri = URI::parse(settings->getURL());
|
URI uri = URI::parse(settings->getURL());
|
||||||
if (m_cachedSession &&
|
if (m_cachedSession &&
|
||||||
|
@ -306,7 +304,7 @@ boost::shared_ptr<Session> Session::create(const boost::shared_ptr<Settings> &se
|
||||||
int Session::getCredentials(const char *realm, int attempt, char *username, char *password) noexcept
|
int Session::getCredentials(const char *realm, int attempt, char *username, char *password) noexcept
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
boost::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
|
std::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
|
||||||
if (authProvider && authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
|
if (authProvider && authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
|
||||||
// We have to fail here because we cannot provide neon
|
// We have to fail here because we cannot provide neon
|
||||||
// with a username/password combination. Instead we rely
|
// with a username/password combination. Instead we rely
|
||||||
|
@ -335,7 +333,7 @@ int Session::getCredentials(const char *realm, int attempt, char *username, char
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::forceAuthorization(ForceAuthorization forceAuthorization,
|
void Session::forceAuthorization(ForceAuthorization forceAuthorization,
|
||||||
const boost::shared_ptr<AuthProvider> &authProvider)
|
const std::shared_ptr<AuthProvider> &authProvider)
|
||||||
{
|
{
|
||||||
m_forceAuthorizationOnce = forceAuthorization;
|
m_forceAuthorizationOnce = forceAuthorization;
|
||||||
m_authProvider = authProvider;
|
m_authProvider = authProvider;
|
||||||
|
@ -444,11 +442,11 @@ void Session::propfindURI(const std::string &path, int depth,
|
||||||
startOperation("PROPFIND", deadline);
|
startOperation("PROPFIND", deadline);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
boost::shared_ptr<ne_propfind_handler> handler;
|
std::shared_ptr<ne_propfind_handler> handler;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
checkAuthorization();
|
checkAuthorization();
|
||||||
handler = boost::shared_ptr<ne_propfind_handler>(ne_propfind_create(m_session, path.c_str(), depth),
|
handler = std::shared_ptr<ne_propfind_handler>(ne_propfind_create(m_session, path.c_str(), depth),
|
||||||
PropFindDeleter());
|
PropFindDeleter());
|
||||||
auto propsResult = [] (void *userdata, const ne_uri *uri,
|
auto propsResult = [] (void *userdata, const ne_uri *uri,
|
||||||
const ne_prop_result_set *results) noexcept {
|
const ne_prop_result_set *results) noexcept {
|
||||||
|
@ -806,16 +804,10 @@ XMLParser &XMLParser::pushHandler(const StartCB_t &start,
|
||||||
{
|
{
|
||||||
m_stack.push_back(Callbacks(start, data, end));
|
m_stack.push_back(Callbacks(start, data, end));
|
||||||
Callbacks &cb = m_stack.back();
|
Callbacks &cb = m_stack.back();
|
||||||
ne_xml_push_handler(m_parser,
|
|
||||||
startCB, dataCB, endCB,
|
|
||||||
&cb);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int XMLParser::startCB(void *userdata, int parent,
|
auto startCB = [] (void *userdata, int parent,
|
||||||
const char *nspace, const char *name,
|
const char *nspace, const char *name,
|
||||||
const char **atts)
|
const char **atts) noexcept {
|
||||||
{
|
|
||||||
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
||||||
try {
|
try {
|
||||||
return cb->m_start(parent, nspace, name, atts);
|
return cb->m_start(parent, nspace, name, atts);
|
||||||
|
@ -824,11 +816,10 @@ int XMLParser::startCB(void *userdata, int parent,
|
||||||
SE_LOG_ERROR(NULL, "startCB %s %s failed", nspace, name);
|
SE_LOG_ERROR(NULL, "startCB %s %s failed", nspace, name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
int XMLParser::dataCB(void *userdata, int state,
|
auto dataCB = [] (void *userdata, int state,
|
||||||
const char *cdata, size_t len)
|
const char *cdata, size_t len) noexcept {
|
||||||
{
|
|
||||||
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
||||||
try {
|
try {
|
||||||
return cb->m_data ?
|
return cb->m_data ?
|
||||||
|
@ -839,11 +830,10 @@ int XMLParser::dataCB(void *userdata, int state,
|
||||||
SE_LOG_ERROR(NULL, "dataCB failed");
|
SE_LOG_ERROR(NULL, "dataCB failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
int XMLParser::endCB(void *userdata, int state,
|
auto endCB = [] (void *userdata, int state,
|
||||||
const char *nspace, const char *name)
|
const char *nspace, const char *name) noexcept {
|
||||||
{
|
|
||||||
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
Callbacks *cb = static_cast<Callbacks *>(userdata);
|
||||||
try {
|
try {
|
||||||
return cb->m_end ?
|
return cb->m_end ?
|
||||||
|
@ -854,68 +844,73 @@ int XMLParser::endCB(void *userdata, int state,
|
||||||
SE_LOG_ERROR(NULL, "endCB %s %s failed", nspace, name);
|
SE_LOG_ERROR(NULL, "endCB %s %s failed", nspace, name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ne_xml_push_handler(m_parser,
|
||||||
|
startCB, dataCB, endCB,
|
||||||
|
&cb);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMLParser::StartCB_t XMLParser::accept(const std::string &nspaceExpected,
|
||||||
int XMLParser::accept(const std::string &nspaceExpected,
|
const std::string &nameExpected)
|
||||||
const std::string &nameExpected,
|
|
||||||
const char *nspace,
|
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
|
return [nspaceExpected, nameExpected] (int state, const char *nspace, const char *name, const char **attributes) {
|
||||||
if (nspace && nspaceExpected == nspace &&
|
if (nspace && nspaceExpected == nspace &&
|
||||||
name && nameExpected == name) {
|
name && nameExpected == name) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int XMLParser::append(std::string &buffer,
|
XMLParser::DataCB_t XMLParser::append(std::string &buffer)
|
||||||
const char *data,
|
|
||||||
size_t len)
|
|
||||||
{
|
{
|
||||||
buffer.append(data, len);
|
return [&buffer] (int state, const char *newdata, size_t len) {
|
||||||
return 0;
|
buffer.append(newdata, len);
|
||||||
}
|
|
||||||
|
|
||||||
int XMLParser::reset(std::string &buffer)
|
|
||||||
{
|
|
||||||
buffer.clear();
|
|
||||||
return 0;
|
return 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::initAbortingReportParser(const ResponseEndCB_t &responseEnd)
|
void XMLParser::initAbortingReportParser(const ResponseEndCB_t &responseEnd)
|
||||||
{
|
{
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "multistatus", _2, _3));
|
pushHandler(accept("DAV:", "multistatus"));
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "response", _2, _3),
|
pushHandler(accept("DAV:", "response"),
|
||||||
Neon::XMLParser::DataCB_t(),
|
{},
|
||||||
boost::bind(&Neon::XMLParser::doResponseEnd,
|
[this, responseEnd] (int state, const char *nspace, const char *name) {
|
||||||
this, responseEnd));
|
int abort = 0;
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "href", _2, _3),
|
if (responseEnd) {
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(m_href), _2, _3));
|
abort = responseEnd(m_href, m_etag, m_status);
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "propstat", _2, _3));
|
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "status", _2, _3),
|
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(m_status), _2, _3));
|
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "prop", _2, _3));
|
|
||||||
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "getetag", _2, _3),
|
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(m_etag), _2, _3));
|
|
||||||
}
|
}
|
||||||
|
// clean up for next response
|
||||||
static int VoidResponseEndCBWrapper(const XMLParser::VoidResponseEndCB_t &responseEnd,
|
m_href.clear();
|
||||||
const std::string &href,
|
m_etag.clear();
|
||||||
const std::string &etag,
|
m_status.clear();
|
||||||
const std::string &status)
|
return abort;
|
||||||
{
|
});
|
||||||
responseEnd(href, etag, status);
|
pushHandler(accept("DAV:", "href"),
|
||||||
return 0;
|
append(m_href));
|
||||||
|
pushHandler(accept("DAV:", "propstat"));
|
||||||
|
pushHandler(accept("DAV:", "status"),
|
||||||
|
append(m_status));
|
||||||
|
pushHandler(accept("DAV:", "prop"));
|
||||||
|
pushHandler(accept("DAV:", "getetag"),
|
||||||
|
append(m_etag));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::initReportParser(const VoidResponseEndCB_t &responseEnd)
|
void XMLParser::initReportParser(const VoidResponseEndCB_t &responseEnd)
|
||||||
{
|
{
|
||||||
if (responseEnd) {
|
if (responseEnd) {
|
||||||
initAbortingReportParser(boost::bind(VoidResponseEndCBWrapper, responseEnd, _1, _2, _3));
|
auto end = [responseEnd] (const std::string &href,
|
||||||
|
const std::string &etag,
|
||||||
|
const std::string &status) {
|
||||||
|
responseEnd(href, etag, status);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
initAbortingReportParser(end);
|
||||||
} else {
|
} else {
|
||||||
initAbortingReportParser(ResponseEndCB_t());
|
initAbortingReportParser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,7 +969,10 @@ void Session::checkAuthorization()
|
||||||
// Count the number of times we asked for new tokens. This helps
|
// Count the number of times we asked for new tokens. This helps
|
||||||
// the provider determine whether the token that it returns are valid.
|
// the provider determine whether the token that it returns are valid.
|
||||||
try {
|
try {
|
||||||
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(boost::bind(&Settings::updatePassword, m_settings, _1));
|
auto update_password = [this] (const std::string& password) {
|
||||||
|
m_settings->updatePassword(password);
|
||||||
|
};
|
||||||
|
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(update_password);
|
||||||
SE_LOG_DEBUG(NULL, "got new OAuth2 token '%s' for next request", m_oauth2Bearer.c_str());
|
SE_LOG_DEBUG(NULL, "got new OAuth2 token '%s' for next request", m_oauth2Bearer.c_str());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
std::string explanation;
|
std::string explanation;
|
||||||
|
@ -988,7 +986,7 @@ void Session::checkAuthorization()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::run(Request &request, const std::set<int> *expectedCodes, const boost::function<bool ()> &aborted)
|
bool Session::run(Request &request, const std::set<int> *expectedCodes, const std::function<bool ()> &aborted)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -999,8 +997,13 @@ bool Session::run(Request &request, const std::set<int> *expectedCodes, const bo
|
||||||
ne_request *req = request.getRequest();
|
ne_request *req = request.getRequest();
|
||||||
if (result) {
|
if (result) {
|
||||||
result->clear();
|
result->clear();
|
||||||
|
auto addResultData = [] (void *userdata, const char *buf, size_t len) {
|
||||||
|
Request *me = static_cast<Request *>(userdata);
|
||||||
|
me->m_result->append(buf, len);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
ne_add_response_body_reader(req, ne_accept_2xx,
|
ne_add_response_body_reader(req, ne_accept_2xx,
|
||||||
Request::addResultData, &request);
|
addResultData, &request);
|
||||||
error = ne_request_dispatch(req);
|
error = ne_request_dispatch(req);
|
||||||
} else {
|
} else {
|
||||||
error = ne_xml_dispatch_request(req, request.getParser()->get());
|
error = ne_xml_dispatch_request(req, request.getParser()->get());
|
||||||
|
@ -1017,13 +1020,6 @@ bool Session::run(Request &request, const std::set<int> *expectedCodes, const bo
|
||||||
expectedCodes);
|
expectedCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Request::addResultData(void *userdata, const char *buf, size_t len)
|
|
||||||
{
|
|
||||||
Request *me = static_cast<Request *>(userdata);
|
|
||||||
me->m_result->append(buf, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -16,13 +16,12 @@
|
||||||
#include <ne_props.h>
|
#include <ne_props.h>
|
||||||
#include <ne_request.h>
|
#include <ne_request.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -88,7 +87,7 @@ class Settings {
|
||||||
* Grant access to AuthProvider. In addition to plain username/password
|
* Grant access to AuthProvider. In addition to plain username/password
|
||||||
* in getCredentials, this one here might also be used for OAuth2.
|
* in getCredentials, this one here might also be used for OAuth2.
|
||||||
*/
|
*/
|
||||||
virtual boost::shared_ptr<AuthProvider> getAuthProvider() = 0;
|
virtual std::shared_ptr<AuthProvider> getAuthProvider() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates password to new one returned during OAuth2 authorization.
|
* Updates password to new one returned during OAuth2 authorization.
|
||||||
|
@ -307,11 +306,11 @@ class Session {
|
||||||
/**
|
/**
|
||||||
* @param settings must provide information about settings on demand
|
* @param settings must provide information about settings on demand
|
||||||
*/
|
*/
|
||||||
Session(const boost::shared_ptr<Settings> &settings);
|
Session(const std::shared_ptr<Settings> &settings);
|
||||||
static boost::shared_ptr<Session> m_cachedSession;
|
static std::shared_ptr<Session> m_cachedSession;
|
||||||
|
|
||||||
ForceAuthorization m_forceAuthorizationOnce;
|
ForceAuthorization m_forceAuthorizationOnce;
|
||||||
boost::shared_ptr<AuthProvider> m_authProvider;
|
std::shared_ptr<AuthProvider> m_authProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count how often a request was sent with credentials.
|
* Count how often a request was sent with credentials.
|
||||||
|
@ -347,7 +346,7 @@ class Session {
|
||||||
* to reuse proxy information (libproxy has a considerably delay during
|
* to reuse proxy information (libproxy has a considerably delay during
|
||||||
* initialization) and HTTP connection/authentication.
|
* initialization) and HTTP connection/authentication.
|
||||||
*/
|
*/
|
||||||
static boost::shared_ptr<Session> create(const boost::shared_ptr<Settings> &settings);
|
static std::shared_ptr<Session> create(const std::shared_ptr<Settings> &settings);
|
||||||
~Session();
|
~Session();
|
||||||
|
|
||||||
#ifdef HAVE_LIBNEON_OPTIONS
|
#ifdef HAVE_LIBNEON_OPTIONS
|
||||||
|
@ -358,13 +357,13 @@ class Session {
|
||||||
/**
|
/**
|
||||||
* called with URI and complete result set; exceptions are logged, but ignored
|
* called with URI and complete result set; exceptions are logged, but ignored
|
||||||
*/
|
*/
|
||||||
typedef boost::function<void (const URI &, const ne_prop_result_set *)> PropfindURICallback_t;
|
typedef std::function<void (const URI &, const ne_prop_result_set *)> PropfindURICallback_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called with URI and specific property, value string may be NULL (error case);
|
* called with URI and specific property, value string may be NULL (error case);
|
||||||
* exceptions are logged and abort iterating over properties (but not URIs)
|
* exceptions are logged and abort iterating over properties (but not URIs)
|
||||||
*/
|
*/
|
||||||
typedef boost::function<void (const URI &, const ne_propname *, const char *, const ne_status *)> PropfindPropCallback_t;
|
typedef std::function<void (const URI &, const ne_propname *, const char *, const ne_status *)> PropfindPropCallback_t;
|
||||||
|
|
||||||
/** ne_simple_propfind(): invoke callback for each URI */
|
/** ne_simple_propfind(): invoke callback for each URI */
|
||||||
void propfindURI(const std::string &path, int depth,
|
void propfindURI(const std::string &path, int depth,
|
||||||
|
@ -413,7 +412,7 @@ class Session {
|
||||||
* @return result of Session::checkError()
|
* @return result of Session::checkError()
|
||||||
*/
|
*/
|
||||||
bool run(Request &request, const std::set<int> *expectedCodes,
|
bool run(Request &request, const std::set<int> *expectedCodes,
|
||||||
const boost::function<bool ()> &aborted = boost::function<bool ()>());
|
const std::function<bool ()> &aborted = {});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to be called after each operation which might have produced debugging output by neon;
|
* to be called after each operation which might have produced debugging output by neon;
|
||||||
|
@ -428,10 +427,10 @@ class Session {
|
||||||
* (when username/password are provided by AuthProvider) or all
|
* (when username/password are provided by AuthProvider) or all
|
||||||
* requests to use OAuth2 authentication.
|
* requests to use OAuth2 authentication.
|
||||||
*/
|
*/
|
||||||
void forceAuthorization(ForceAuthorization forceAuthorization, const boost::shared_ptr<AuthProvider> &authProvider);
|
void forceAuthorization(ForceAuthorization forceAuthorization, const std::shared_ptr<AuthProvider> &authProvider);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
bool m_debugging;
|
bool m_debugging;
|
||||||
ne_session *m_session;
|
ne_session *m_session;
|
||||||
URI m_uri;
|
URI m_uri;
|
||||||
|
@ -489,7 +488,7 @@ class XMLParser
|
||||||
* arguments are parent state, namespace, name, attributes (NULL terminated)
|
* arguments are parent state, namespace, name, attributes (NULL terminated)
|
||||||
* @return < 0 abort, 0 decline, > 0 accept
|
* @return < 0 abort, 0 decline, > 0 accept
|
||||||
*/
|
*/
|
||||||
typedef boost::function<int (int, const char *, const char *, const char **)> StartCB_t;
|
typedef std::function<int (int, const char *, const char *, const char **)> StartCB_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ne_xml_cdata_cb:
|
* See ne_xml_cdata_cb:
|
||||||
|
@ -497,7 +496,7 @@ class XMLParser
|
||||||
* May be NULL.
|
* May be NULL.
|
||||||
* @return != 0 to abort
|
* @return != 0 to abort
|
||||||
*/
|
*/
|
||||||
typedef boost::function<int (int, const char *, size_t)> DataCB_t;
|
typedef std::function<int (int, const char *, size_t)> DataCB_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ne_xml_endelm_cb:
|
* See ne_xml_endelm_cb:
|
||||||
|
@ -505,7 +504,7 @@ class XMLParser
|
||||||
* May be NULL.
|
* May be NULL.
|
||||||
* @return != 0 to abort
|
* @return != 0 to abort
|
||||||
*/
|
*/
|
||||||
typedef boost::function<int (int, const char *, const char *)> EndCB_t;
|
typedef std::function<int (int, const char *, const char *)> EndCB_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add new handler, see ne_xml_push_handler()
|
* add new handler, see ne_xml_push_handler()
|
||||||
|
@ -517,22 +516,13 @@ class XMLParser
|
||||||
/**
|
/**
|
||||||
* StartCB_t: accepts a new element if namespace and name match
|
* StartCB_t: accepts a new element if namespace and name match
|
||||||
*/
|
*/
|
||||||
static int accept(const std::string &nspaceExpected,
|
static StartCB_t accept(const std::string &nspaceExpected,
|
||||||
const std::string &nameExpected,
|
const std::string &nameExpected);
|
||||||
const char *nspace,
|
|
||||||
const char *name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DataCB_t: append to std::string
|
* DataCB_t: append to std::string
|
||||||
*/
|
*/
|
||||||
static int append(std::string &buffer,
|
static DataCB_t append(std::string &buffer);
|
||||||
const char *data,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EndCB_t: clear std::string
|
|
||||||
*/
|
|
||||||
static int reset(std::string &buffer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called each time a response is completely parsed.
|
* Called each time a response is completely parsed.
|
||||||
|
@ -542,8 +532,8 @@ class XMLParser
|
||||||
* @param status it's status line, empty if not requested or unavailable
|
* @param status it's status line, empty if not requested or unavailable
|
||||||
* @return non-zero for aborting the parsing
|
* @return non-zero for aborting the parsing
|
||||||
*/
|
*/
|
||||||
typedef boost::function<int (const std::string &, const std::string &, const std::string &)> ResponseEndCB_t;
|
typedef std::function<int (const std::string &, const std::string &, const std::string &)> ResponseEndCB_t;
|
||||||
typedef boost::function<void (const std::string &, const std::string &, const std::string &)> VoidResponseEndCB_t;
|
typedef std::function<void (const std::string &, const std::string &, const std::string &)> VoidResponseEndCB_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup parser for handling REPORT result.
|
* Setup parser for handling REPORT result.
|
||||||
|
@ -561,8 +551,8 @@ class XMLParser
|
||||||
* when expecting only one response, the callback
|
* when expecting only one response, the callback
|
||||||
* is not needed
|
* is not needed
|
||||||
*/
|
*/
|
||||||
void initReportParser(const VoidResponseEndCB_t &responseEnd = VoidResponseEndCB_t());
|
void initReportParser(const VoidResponseEndCB_t &responseEnd = {});
|
||||||
void initAbortingReportParser(const ResponseEndCB_t &responseEnd);
|
void initAbortingReportParser(const ResponseEndCB_t &responseEnd = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ne_xml_parser *m_parser;
|
ne_xml_parser *m_parser;
|
||||||
|
@ -583,18 +573,6 @@ class XMLParser
|
||||||
/** buffers for initReportParser() */
|
/** buffers for initReportParser() */
|
||||||
std::string m_href, m_etag, m_status;
|
std::string m_href, m_etag, m_status;
|
||||||
|
|
||||||
int doResponseEnd(const ResponseEndCB_t &responseEnd) {
|
|
||||||
int abort = 0;
|
|
||||||
if (responseEnd) {
|
|
||||||
abort = responseEnd(m_href, m_etag, m_status);
|
|
||||||
}
|
|
||||||
// clean up for next response
|
|
||||||
m_href.clear();
|
|
||||||
m_etag.clear();
|
|
||||||
m_status.clear();
|
|
||||||
return abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int startCB(void *userdata, int parent,
|
static int startCB(void *userdata, int parent,
|
||||||
const char *nspace, const char *name,
|
const char *nspace, const char *name,
|
||||||
const char **atts);
|
const char **atts);
|
||||||
|
@ -652,9 +630,6 @@ class Request
|
||||||
XMLParser *getParser() const { return m_parser; }
|
XMLParser *getParser() const { return m_parser; }
|
||||||
std::string getPath() const { return m_path; }
|
std::string getPath() const { return m_path; }
|
||||||
|
|
||||||
/** ne_block_reader implementation */
|
|
||||||
static int addResultData(void *userdata, const char *buf, size_t len);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// buffers for string (copied by ne_request_create(),
|
// buffers for string (copied by ne_request_create(),
|
||||||
// but due to a bug in neon, our method string is still used
|
// but due to a bug in neon, our method string is still used
|
||||||
|
@ -669,6 +644,8 @@ class Request
|
||||||
ne_request *m_req;
|
ne_request *m_req;
|
||||||
std::string *m_result;
|
std::string *m_result;
|
||||||
XMLParser *m_parser;
|
XMLParser *m_parser;
|
||||||
|
|
||||||
|
friend Session;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** thrown for 301 HTTP status */
|
/** thrown for 301 HTTP status */
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "WebDAVSource.h"
|
#include "WebDAVSource.h"
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/algorithm/string/classification.hpp>
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
|
@ -42,7 +41,7 @@ public:
|
||||||
typedef std::vector<std::string> URLs;
|
typedef std::vector<std::string> URLs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<SyncConfig> m_context;
|
std::shared_ptr<SyncConfig> m_context;
|
||||||
SyncSourceConfig *m_sourceConfig;
|
SyncSourceConfig *m_sourceConfig;
|
||||||
URLs m_urls;
|
URLs m_urls;
|
||||||
std::string m_urlsDescription;
|
std::string m_urlsDescription;
|
||||||
|
@ -56,7 +55,7 @@ private:
|
||||||
bool m_credentialsOkay;
|
bool m_credentialsOkay;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContextSettings(const boost::shared_ptr<SyncConfig> &context,
|
ContextSettings(const std::shared_ptr<SyncConfig> &context,
|
||||||
SyncSourceConfig *sourceConfig) :
|
SyncSourceConfig *sourceConfig) :
|
||||||
m_context(context),
|
m_context(context),
|
||||||
m_sourceConfig(sourceConfig),
|
m_sourceConfig(sourceConfig),
|
||||||
|
@ -106,7 +105,7 @@ public:
|
||||||
// never know that credentials should work (bad for Google,
|
// never know that credentials should work (bad for Google,
|
||||||
// with its temporary authentication errors)
|
// with its temporary authentication errors)
|
||||||
if (m_context) {
|
if (m_context) {
|
||||||
boost::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
|
std::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
|
||||||
m_credentialsOkay = WebDAVCredentialsOkay().getPropertyValue(*node);
|
m_credentialsOkay = WebDAVCredentialsOkay().getPropertyValue(*node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +154,7 @@ public:
|
||||||
std::string &username,
|
std::string &username,
|
||||||
std::string &password);
|
std::string &password);
|
||||||
|
|
||||||
virtual boost::shared_ptr<AuthProvider> getAuthProvider();
|
virtual std::shared_ptr<AuthProvider> getAuthProvider();
|
||||||
|
|
||||||
void updatePassword(const string &password);
|
void updatePassword(const string &password);
|
||||||
|
|
||||||
|
@ -168,7 +167,7 @@ public:
|
||||||
virtual bool getCredentialsOkay() { return m_credentialsOkay; }
|
virtual bool getCredentialsOkay() { return m_credentialsOkay; }
|
||||||
virtual void setCredentialsOkay(bool okay) {
|
virtual void setCredentialsOkay(bool okay) {
|
||||||
if (m_credentialsOkay != okay && m_context) {
|
if (m_credentialsOkay != okay && m_context) {
|
||||||
boost::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
|
std::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
|
||||||
if (!node->isReadOnly()) {
|
if (!node->isReadOnly()) {
|
||||||
WebDAVCredentialsOkay().setProperty(*node, okay);
|
WebDAVCredentialsOkay().setProperty(*node, okay);
|
||||||
node->flush();
|
node->flush();
|
||||||
|
@ -186,7 +185,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeFlags(const std::string &url);
|
void initializeFlags(const std::string &url);
|
||||||
boost::shared_ptr<AuthProvider> m_authProvider;
|
std::shared_ptr<AuthProvider> m_authProvider;
|
||||||
void lookupAuthProvider();
|
void lookupAuthProvider();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -201,7 +200,7 @@ void ContextSettings::getCredentials(const std::string &realm,
|
||||||
password = creds.m_password;
|
password = creds.m_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> ContextSettings::getAuthProvider()
|
std::shared_ptr<AuthProvider> ContextSettings::getAuthProvider()
|
||||||
{
|
{
|
||||||
lookupAuthProvider();
|
lookupAuthProvider();
|
||||||
return m_authProvider;
|
return m_authProvider;
|
||||||
|
@ -310,7 +309,7 @@ WebDAVSource::Props_t::iterator WebDAVSource::Props_t::find(const WebDAVSource::
|
||||||
}
|
}
|
||||||
|
|
||||||
WebDAVSource::WebDAVSource(const SyncSourceParams ¶ms,
|
WebDAVSource::WebDAVSource(const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<Neon::Settings> &settings) :
|
const std::shared_ptr<Neon::Settings> &settings) :
|
||||||
TrackingSyncSource(params),
|
TrackingSyncSource(params),
|
||||||
m_settings(settings)
|
m_settings(settings)
|
||||||
{
|
{
|
||||||
|
@ -320,10 +319,18 @@ WebDAVSource::WebDAVSource(const SyncSourceParams ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert contactServer() into BackupData_t and RestoreData_t (implemented by SyncSourceRevisions) */
|
/* insert contactServer() into BackupData_t and RestoreData_t (implemented by SyncSourceRevisions) */
|
||||||
m_operations.m_backupData = boost::bind(&WebDAVSource::backupData,
|
m_operations.m_backupData = [this, backup = m_operations.m_backupData] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
||||||
this, m_operations.m_backupData, _1, _2, _3);
|
const SyncSource::Operations::BackupInfo &newBackup,
|
||||||
m_operations.m_restoreData = boost::bind(&WebDAVSource::restoreData,
|
BackupReport &backupReport) {
|
||||||
this, m_operations.m_restoreData, _1, _2, _3);
|
contactServer();
|
||||||
|
backup(oldBackup, newBackup, backupReport);
|
||||||
|
};
|
||||||
|
m_operations.m_restoreData = [this, restore = m_operations.m_restoreData] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
|
||||||
|
bool dryrun,
|
||||||
|
SyncSourceReport &report) {
|
||||||
|
contactServer();
|
||||||
|
restore(oldBackup, dryrun, report);
|
||||||
|
};
|
||||||
|
|
||||||
// ignore the "Request ends, status 207 class 2xx, error line:" printed by neon
|
// ignore the "Request ends, status 207 class 2xx, error line:" printed by neon
|
||||||
LogRedirect::addIgnoreError(", error line:");
|
LogRedirect::addIgnoreError(", error line:");
|
||||||
|
@ -571,22 +578,6 @@ void WebDAVSource::open()
|
||||||
// Nothing to do here, expensive initialization is in contactServer().
|
// Nothing to do here, expensive initialization is in contactServer().
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool setFirstURL(Neon::URI &result,
|
|
||||||
bool &resultIsReadOnly,
|
|
||||||
const std::string &name,
|
|
||||||
const Neon::URI &uri,
|
|
||||||
bool isReadOnly)
|
|
||||||
{
|
|
||||||
if (result.empty() ||
|
|
||||||
// Overwrite read-only with read/write collection.
|
|
||||||
(resultIsReadOnly && !isReadOnly)) {
|
|
||||||
result = uri;
|
|
||||||
resultIsReadOnly = isReadOnly;
|
|
||||||
}
|
|
||||||
// Stop if read/write found.
|
|
||||||
return resultIsReadOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebDAVSource::contactServer()
|
void WebDAVSource::contactServer()
|
||||||
{
|
{
|
||||||
if (!m_calendar.empty() &&
|
if (!m_calendar.empty() &&
|
||||||
|
@ -623,10 +614,19 @@ void WebDAVSource::contactServer()
|
||||||
m_calendar = Neon::URI();
|
m_calendar = Neon::URI();
|
||||||
SE_LOG_INFO(getDisplayName(), "determine final URL based on %s",
|
SE_LOG_INFO(getDisplayName(), "determine final URL based on %s",
|
||||||
m_contextSettings ? m_contextSettings->getURLDescription().c_str() : "");
|
m_contextSettings ? m_contextSettings->getURLDescription().c_str() : "");
|
||||||
findCollections(boost::bind(setFirstURL,
|
auto setFirstURL = [this, &isReadOnly] (const std::string &name,
|
||||||
boost::ref(m_calendar),
|
const Neon::URI &uri,
|
||||||
boost::ref(isReadOnly),
|
bool isReadOnlyURI) {
|
||||||
_1, _2, _3));
|
if (m_calendar.empty() ||
|
||||||
|
// Overwrite read-only with read/write collection.
|
||||||
|
(isReadOnly && !isReadOnlyURI)) {
|
||||||
|
m_calendar = uri;
|
||||||
|
isReadOnly = isReadOnlyURI;
|
||||||
|
}
|
||||||
|
// Stop if read/write found.
|
||||||
|
return isReadOnly;
|
||||||
|
};
|
||||||
|
findCollections(setFirstURL);
|
||||||
if (m_calendar.empty()) {
|
if (m_calendar.empty()) {
|
||||||
throwError(SE_HERE, "no database found");
|
throwError(SE_HERE, "no database found");
|
||||||
}
|
}
|
||||||
|
@ -802,7 +802,7 @@ std::string WebDAVSource::lookupDNSSRV(const std::string &domain)
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebDAVSource::findCollections(const boost::function<bool (const std::string &,
|
bool WebDAVSource::findCollections(const std::function<bool (const std::string &,
|
||||||
const Neon::URI &,
|
const Neon::URI &,
|
||||||
bool isReadOnly)> &storeResult)
|
bool isReadOnly)> &storeResult)
|
||||||
{
|
{
|
||||||
|
@ -814,7 +814,7 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
|
||||||
(timeoutSeconds <= 0 ||
|
(timeoutSeconds <= 0 ||
|
||||||
retrySeconds <= 0) ? "resending disabled" : "resending allowed");
|
retrySeconds <= 0) ? "resending disabled" : "resending allowed");
|
||||||
|
|
||||||
boost::shared_ptr<AuthProvider> authProvider = m_contextSettings->getAuthProvider();
|
std::shared_ptr<AuthProvider> authProvider = m_contextSettings->getAuthProvider();
|
||||||
std::string username = authProvider->getUsername();
|
std::string username = authProvider->getUsername();
|
||||||
|
|
||||||
// If no URL was configured, then try DNS SRV lookup.
|
// If no URL was configured, then try DNS SRV lookup.
|
||||||
|
@ -947,9 +947,7 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
|
||||||
|
|
||||||
Candidate candidate = tried.getNextCandidate();
|
Candidate candidate = tried.getNextCandidate();
|
||||||
Props_t davProps;
|
Props_t davProps;
|
||||||
Neon::Session::PropfindPropCallback_t callback =
|
auto callback = openPropCallback(davProps);
|
||||||
boost::bind(&WebDAVSource::openPropCallback,
|
|
||||||
this, boost::ref(davProps), _1, _2, _3, _4);
|
|
||||||
|
|
||||||
// With Yahoo! the initial connection often failed with 50x
|
// With Yahoo! the initial connection often failed with 50x
|
||||||
// errors. Retrying individual requests is error prone because at
|
// errors. Retrying individual requests is error prone because at
|
||||||
|
@ -1054,14 +1052,11 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
|
||||||
try {
|
try {
|
||||||
SE_LOG_DEBUG(NULL, "debugging: read all WebDAV properties of %s", candidate.m_uri.toURL().c_str());
|
SE_LOG_DEBUG(NULL, "debugging: read all WebDAV properties of %s", candidate.m_uri.toURL().c_str());
|
||||||
// Use OAuth2, if available.
|
// Use OAuth2, if available.
|
||||||
boost::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
|
std::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
|
||||||
if (authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
|
if (authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
|
||||||
m_session->forceAuthorization(Neon::Session::AUTH_HTTPS, authProvider);
|
m_session->forceAuthorization(Neon::Session::AUTH_HTTPS, authProvider);
|
||||||
}
|
}
|
||||||
Neon::Session::PropfindPropCallback_t callback =
|
m_session->propfindProp(candidate.m_uri.m_path, 0, NULL, openPropCallback(davProps), Timespec());
|
||||||
boost::bind(&WebDAVSource::openPropCallback,
|
|
||||||
this, boost::ref(davProps), _1, _2, _3, _4);
|
|
||||||
m_session->propfindProp(candidate.m_uri.m_path, 0, NULL, callback, Timespec());
|
|
||||||
} catch (const Neon::FatalException &ex) {
|
} catch (const Neon::FatalException &ex) {
|
||||||
throw;
|
throw;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -1551,12 +1546,12 @@ std::list<std::string> WebDAVSource::extractHREFs(const std::string &propval)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebDAVSource::openPropCallback(Props_t &davProps,
|
Neon::Session::PropfindPropCallback_t WebDAVSource::openPropCallback(Props_t &davProps)
|
||||||
const Neon::URI &uri,
|
{
|
||||||
|
return [this, &davProps] (const Neon::URI &uri,
|
||||||
const ne_propname *prop,
|
const ne_propname *prop,
|
||||||
const char *value,
|
const char *value,
|
||||||
const ne_status *status)
|
const ne_status *status) {
|
||||||
{
|
|
||||||
// TODO: recognize CALDAV:calendar-timezone and use it for local time conversion of events
|
// TODO: recognize CALDAV:calendar-timezone and use it for local time conversion of events
|
||||||
std::string name;
|
std::string name;
|
||||||
if (prop->nspace) {
|
if (prop->nspace) {
|
||||||
|
@ -1569,6 +1564,7 @@ void WebDAVSource::openPropCallback(Props_t &davProps,
|
||||||
boost::trim_if(davProps[uri.m_path][name],
|
boost::trim_if(davProps[uri.m_path][name],
|
||||||
boost::is_space());
|
boost::is_space());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ne_propname getetag[] = {
|
static const ne_propname getetag[] = {
|
||||||
|
@ -1577,22 +1573,6 @@ static const ne_propname getetag[] = {
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int FoundItem(bool &isEmpty,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
const std::string &status)
|
|
||||||
{
|
|
||||||
if (isEmpty) {
|
|
||||||
Neon::Status parsed;
|
|
||||||
// Err on the side of caution: if unsure about status, include item.
|
|
||||||
if (parsed.parse(status.c_str()) ||
|
|
||||||
parsed.klass == 2) {
|
|
||||||
isEmpty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isEmpty ? 0 : 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebDAVSource::isEmpty()
|
bool WebDAVSource::isEmpty()
|
||||||
{
|
{
|
||||||
contactServer();
|
contactServer();
|
||||||
|
@ -1605,9 +1585,7 @@ bool WebDAVSource::isEmpty()
|
||||||
RevisionMap_t revisions;
|
RevisionMap_t revisions;
|
||||||
Timespec deadline = createDeadline();
|
Timespec deadline = createDeadline();
|
||||||
m_session->propfindURI(m_calendar.m_path, 1, getetag,
|
m_session->propfindURI(m_calendar.m_path, 1, getetag,
|
||||||
boost::bind(&WebDAVSource::listAllItemsCallback,
|
listAllItemsCallback(revisions, failed),
|
||||||
this, _1, _2, boost::ref(revisions),
|
|
||||||
boost::ref(failed)),
|
|
||||||
deadline);
|
deadline);
|
||||||
if (failed) {
|
if (failed) {
|
||||||
SE_THROW("incomplete listing of all items");
|
SE_THROW("incomplete listing of all items");
|
||||||
|
@ -1641,9 +1619,20 @@ bool WebDAVSource::isEmpty()
|
||||||
getSession()->startOperation("REPORT 'check for items'", deadline);
|
getSession()->startOperation("REPORT 'check for items'", deadline);
|
||||||
while (true) {
|
while (true) {
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initAbortingReportParser(boost::bind(FoundItem,
|
auto foundItem = [&isEmpty] (const std::string &href,
|
||||||
boost::ref(isEmpty),
|
const std::string &etag,
|
||||||
_1, _2, _3));
|
const std::string &status) {
|
||||||
|
if (isEmpty) {
|
||||||
|
Neon::Status parsed;
|
||||||
|
// Err on the side of caution: if unsure about status, include item.
|
||||||
|
if (parsed.parse(status.c_str()) ||
|
||||||
|
parsed.klass == 2) {
|
||||||
|
isEmpty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isEmpty ? 0 : 100;
|
||||||
|
};
|
||||||
|
parser.initAbortingReportParser(foundItem);
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -1679,11 +1668,16 @@ void WebDAVSource::close()
|
||||||
m_session.reset();
|
m_session.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool storeCollection(SyncSource::Databases &result,
|
WebDAVSource::Databases WebDAVSource::getDatabases()
|
||||||
const std::string &name,
|
|
||||||
const Neon::URI &uri,
|
|
||||||
bool isReadOnly)
|
|
||||||
{
|
{
|
||||||
|
Databases result;
|
||||||
|
|
||||||
|
// do a scan if some kind of credentials were set
|
||||||
|
if (m_contextSettings->getAuthProvider()->wasConfigured()) {
|
||||||
|
|
||||||
|
auto storeCollection = [&result] (const std::string &name,
|
||||||
|
const Neon::URI &uri,
|
||||||
|
bool isReadOnly) {
|
||||||
std::string url = uri.toURL();
|
std::string url = uri.toURL();
|
||||||
|
|
||||||
// avoid duplicates
|
// avoid duplicates
|
||||||
|
@ -1693,20 +1687,10 @@ static bool storeCollection(SyncSource::Databases &result,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push_back(SyncSource::Database(name, url, false, isReadOnly));
|
result.push_back(SyncSource::Database(name, url, false, isReadOnly));
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
findCollections(storeCollection);
|
||||||
WebDAVSource::Databases WebDAVSource::getDatabases()
|
|
||||||
{
|
|
||||||
Databases result;
|
|
||||||
|
|
||||||
// do a scan if some kind of credentials were set
|
|
||||||
if (m_contextSettings->getAuthProvider()->wasConfigured()) {
|
|
||||||
findCollections(boost::bind(storeCollection,
|
|
||||||
boost::ref(result),
|
|
||||||
_1, _2, _3));
|
|
||||||
|
|
||||||
// Move all read-only collections to the end of the array.
|
// Move all read-only collections to the end of the array.
|
||||||
// They are probably not the default calendar (for example,
|
// They are probably not the default calendar (for example,
|
||||||
|
@ -1842,11 +1826,8 @@ void WebDAVSource::checkPostSupport()
|
||||||
};
|
};
|
||||||
Timespec deadline = createDeadline();
|
Timespec deadline = createDeadline();
|
||||||
Props_t davProps;
|
Props_t davProps;
|
||||||
Neon::Session::PropfindPropCallback_t callback =
|
|
||||||
boost::bind(&WebDAVSource::openPropCallback,
|
|
||||||
this, boost::ref(davProps), _1, _2, _3, _4);
|
|
||||||
SE_LOG_DEBUG(NULL, "check POST support of %s", m_calendar.m_path.c_str());
|
SE_LOG_DEBUG(NULL, "check POST support of %s", m_calendar.m_path.c_str());
|
||||||
m_session->propfindProp(m_calendar.m_path, 0, getaddmember, callback, deadline);
|
m_session->propfindProp(m_calendar.m_path, 0, getaddmember, openPropCallback(davProps), deadline);
|
||||||
// Fatal communication problems will be reported via exceptions.
|
// Fatal communication problems will be reported via exceptions.
|
||||||
// Once we get here, invalid or incomplete results can be
|
// Once we get here, invalid or incomplete results can be
|
||||||
// treated as "don't have revision string".
|
// treated as "don't have revision string".
|
||||||
|
@ -1875,11 +1856,8 @@ std::string WebDAVSource::databaseRevision()
|
||||||
|
|
||||||
Timespec deadline = createDeadline();
|
Timespec deadline = createDeadline();
|
||||||
Props_t davProps;
|
Props_t davProps;
|
||||||
Neon::Session::PropfindPropCallback_t callback =
|
|
||||||
boost::bind(&WebDAVSource::openPropCallback,
|
|
||||||
this, boost::ref(davProps), _1, _2, _3, _4);
|
|
||||||
SE_LOG_DEBUG(NULL, "read ctag of %s", m_calendar.m_path.c_str());
|
SE_LOG_DEBUG(NULL, "read ctag of %s", m_calendar.m_path.c_str());
|
||||||
m_session->propfindProp(m_calendar.m_path, 0, getctag, callback, deadline);
|
m_session->propfindProp(m_calendar.m_path, 0, getctag, openPropCallback(davProps), deadline);
|
||||||
// Fatal communication problems will be reported via exceptions.
|
// Fatal communication problems will be reported via exceptions.
|
||||||
// Once we get here, invalid or incomplete results can be
|
// Once we get here, invalid or incomplete results can be
|
||||||
// treated as "don't have revision string".
|
// treated as "don't have revision string".
|
||||||
|
@ -1897,9 +1875,7 @@ void WebDAVSource::listAllItems(RevisionMap_t &revisions)
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
Timespec deadline = createDeadline();
|
Timespec deadline = createDeadline();
|
||||||
m_session->propfindURI(m_calendar.m_path, 1, getetag,
|
m_session->propfindURI(m_calendar.m_path, 1, getetag,
|
||||||
boost::bind(&WebDAVSource::listAllItemsCallback,
|
listAllItemsCallback(revisions, failed),
|
||||||
this, _1, _2, boost::ref(revisions),
|
|
||||||
boost::ref(failed)),
|
|
||||||
deadline);
|
deadline);
|
||||||
if (failed) {
|
if (failed) {
|
||||||
SE_THROW("incomplete listing of all items");
|
SE_THROW("incomplete listing of all items");
|
||||||
|
@ -1938,11 +1914,9 @@ void WebDAVSource::listAllItems(RevisionMap_t &revisions)
|
||||||
while (true) {
|
while (true) {
|
||||||
string data;
|
string data;
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initReportParser(boost::bind(&WebDAVSource::checkItem, this,
|
parser.initReportParser(checkItem(revisions, &data));
|
||||||
boost::ref(revisions),
|
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
|
||||||
_1, _2, &data));
|
Neon::XMLParser::append(data));
|
||||||
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
|
|
||||||
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
|
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -2001,9 +1975,7 @@ std::string WebDAVSource::findByUID(const std::string &uid,
|
||||||
getSession()->startOperation("REPORT 'UID lookup'", deadline);
|
getSession()->startOperation("REPORT 'UID lookup'", deadline);
|
||||||
while (true) {
|
while (true) {
|
||||||
Neon::XMLParser parser;
|
Neon::XMLParser parser;
|
||||||
parser.initReportParser(boost::bind(&WebDAVSource::checkItem, this,
|
parser.initReportParser(checkItem(revisions, nullptr));
|
||||||
boost::ref(revisions),
|
|
||||||
_1, _2, (std::string *)0));
|
|
||||||
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
|
||||||
report.addHeader("Depth", "1");
|
report.addHeader("Depth", "1");
|
||||||
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
|
||||||
|
@ -2030,11 +2002,11 @@ std::string WebDAVSource::findByUID(const std::string &uid,
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebDAVSource::listAllItemsCallback(const Neon::URI &uri,
|
Neon::Session::PropfindURICallback_t WebDAVSource::listAllItemsCallback(RevisionMap_t &revisions,
|
||||||
const ne_prop_result_set *results,
|
|
||||||
RevisionMap_t &revisions,
|
|
||||||
bool &failed)
|
bool &failed)
|
||||||
{
|
{
|
||||||
|
return [this, &revisions, &failed] (const Neon::URI &uri,
|
||||||
|
const ne_prop_result_set *results) {
|
||||||
static const ne_propname prop = {
|
static const ne_propname prop = {
|
||||||
"DAV:", "getetag"
|
"DAV:", "getetag"
|
||||||
};
|
};
|
||||||
|
@ -2067,13 +2039,15 @@ void WebDAVSource::listAllItemsCallback(const Neon::URI &uri,
|
||||||
uri.toURL().c_str(),
|
uri.toURL().c_str(),
|
||||||
Neon::Status2String(ne_propset_status(results, &prop)).c_str());
|
Neon::Status2String(ne_propset_status(results, &prop)).c_str());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebDAVSource::checkItem(RevisionMap_t &revisions,
|
Neon::XMLParser::VoidResponseEndCB_t WebDAVSource::checkItem(RevisionMap_t &revisions,
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string *data)
|
std::string *data)
|
||||||
{
|
{
|
||||||
|
return [this, &revisions, data] (const std::string &href,
|
||||||
|
const std::string &etag,
|
||||||
|
const std::string &status) {
|
||||||
// Ignore responses with no data: this is not perfect (should better
|
// Ignore responses with no data: this is not perfect (should better
|
||||||
// try to figure out why there is no data), but better than
|
// try to figure out why there is no data), but better than
|
||||||
// failing.
|
// failing.
|
||||||
|
@ -2081,7 +2055,7 @@ int WebDAVSource::checkItem(RevisionMap_t &revisions,
|
||||||
// One situation is the response for the collection itself,
|
// One situation is the response for the collection itself,
|
||||||
// which comes with a 404 status and no data with Google Calendar.
|
// which comes with a 404 status and no data with Google Calendar.
|
||||||
if (data && data->empty()) {
|
if (data && data->empty()) {
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to parse, user content cannot start at start of line in
|
// No need to parse, user content cannot start at start of line in
|
||||||
|
@ -2097,7 +2071,7 @@ int WebDAVSource::checkItem(RevisionMap_t &revisions,
|
||||||
if (data) {
|
if (data) {
|
||||||
data->clear();
|
data->clear();
|
||||||
}
|
}
|
||||||
return 0;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2297,9 +2271,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
||||||
RevisionMap_t revisions;
|
RevisionMap_t revisions;
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
m_session->propfindURI(luid2path(new_uid), 0, getetag,
|
m_session->propfindURI(luid2path(new_uid), 0, getetag,
|
||||||
boost::bind(&WebDAVSource::listAllItemsCallback,
|
listAllItemsCallback(revisions, failed),
|
||||||
this, _1, _2, boost::ref(revisions),
|
|
||||||
boost::ref(failed)),
|
|
||||||
deadline);
|
deadline);
|
||||||
// Turns out we get a result for our original path even in
|
// Turns out we get a result for our original path even in
|
||||||
// the case of a merge, although the original path is not
|
// the case of a merge, although the original path is not
|
||||||
|
@ -2370,9 +2342,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
RevisionMap_t revisions;
|
RevisionMap_t revisions;
|
||||||
m_session->propfindURI(luid2path(new_uid), 0, getetag,
|
m_session->propfindURI(luid2path(new_uid), 0, getetag,
|
||||||
boost::bind(&WebDAVSource::listAllItemsCallback,
|
listAllItemsCallback(revisions, failed),
|
||||||
this, _1, _2, boost::ref(revisions),
|
|
||||||
boost::ref(failed)),
|
|
||||||
deadline);
|
deadline);
|
||||||
rev = revisions[new_uid];
|
rev = revisions[new_uid];
|
||||||
if (failed || rev.empty()) {
|
if (failed || rev.empty()) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
|
||||||
* @param settings instance which provides necessary settings callbacks for Neon
|
* @param settings instance which provides necessary settings callbacks for Neon
|
||||||
*/
|
*/
|
||||||
WebDAVSource(const SyncSourceParams ¶ms,
|
WebDAVSource(const SyncSourceParams ¶ms,
|
||||||
const boost::shared_ptr<Neon::Settings> &settings);
|
const std::shared_ptr<Neon::Settings> &settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function: replace HTML entities until none are left
|
* Utility function: replace HTML entities until none are left
|
||||||
|
@ -69,7 +69,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
|
||||||
*
|
*
|
||||||
* @return true if scanning completed, false if callback requested stop
|
* @return true if scanning completed, false if callback requested stop
|
||||||
*/
|
*/
|
||||||
bool findCollections(const boost::function<bool (const std::string &,
|
bool findCollections(const std::function<bool (const std::string &,
|
||||||
const Neon::URI &,
|
const Neon::URI &,
|
||||||
bool isReadOnly)> &callback);
|
bool isReadOnly)> &callback);
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
|
||||||
Timespec createDeadline() const;
|
Timespec createDeadline() const;
|
||||||
|
|
||||||
// access to neon session and calendar, valid between open() and close()
|
// access to neon session and calendar, valid between open() and close()
|
||||||
boost::shared_ptr<Neon::Session> getSession() { return m_session; }
|
std::shared_ptr<Neon::Session> getSession() { return m_session; }
|
||||||
Neon::URI &getCalendar() { return m_calendar; }
|
Neon::URI &getCalendar() { return m_calendar; }
|
||||||
|
|
||||||
// access to settings owned by this instance
|
// access to settings owned by this instance
|
||||||
|
@ -230,10 +230,10 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** settings to be used, never NULL, may be the same as m_contextSettings */
|
/** settings to be used, never NULL, may be the same as m_contextSettings */
|
||||||
boost::shared_ptr<Neon::Settings> m_settings;
|
std::shared_ptr<Neon::Settings> m_settings;
|
||||||
/** settings constructed by us instead of caller, may be NULL */
|
/** settings constructed by us instead of caller, may be NULL */
|
||||||
boost::shared_ptr<ContextSettings> m_contextSettings;
|
std::shared_ptr<ContextSettings> m_contextSettings;
|
||||||
boost::shared_ptr<Neon::Session> m_session;
|
std::shared_ptr<Neon::Session> m_session;
|
||||||
|
|
||||||
/** normalized path: including backslash, URI encoded */
|
/** normalized path: including backslash, URI encoded */
|
||||||
Neon::URI m_calendar;
|
Neon::URI m_calendar;
|
||||||
|
@ -266,38 +266,12 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
|
||||||
/** extract all <DAV:href>value</DAV:href> values from a set, empty if none */
|
/** extract all <DAV:href>value</DAV:href> values from a set, empty if none */
|
||||||
std::list<std::string> extractHREFs(const std::string &propval);
|
std::list<std::string> extractHREFs(const std::string &propval);
|
||||||
|
|
||||||
void openPropCallback(Props_t &davProps,
|
Neon::Session::PropfindPropCallback_t openPropCallback(Props_t &davProps);
|
||||||
const Neon::URI &uri,
|
Neon::Session::PropfindURICallback_t listAllItemsCallback(RevisionMap_t &revisions,
|
||||||
const ne_propname *prop,
|
|
||||||
const char *value,
|
|
||||||
const ne_status *status);
|
|
||||||
|
|
||||||
void listAllItemsCallback(const Neon::URI &uri,
|
|
||||||
const ne_prop_result_set *results,
|
|
||||||
RevisionMap_t &revisions,
|
|
||||||
bool &failed);
|
bool &failed);
|
||||||
|
Neon::XMLParser::VoidResponseEndCB_t checkItem(RevisionMap_t &revisions,
|
||||||
int checkItem(RevisionMap_t &revisions,
|
|
||||||
const std::string &href,
|
|
||||||
const std::string &etag,
|
|
||||||
std::string *data);
|
std::string *data);
|
||||||
|
|
||||||
void backupData(const boost::function<Operations::BackupData_t> &op,
|
|
||||||
const Operations::ConstBackupInfo &oldBackup,
|
|
||||||
const Operations::BackupInfo &newBackup,
|
|
||||||
BackupReport &report) {
|
|
||||||
contactServer();
|
|
||||||
op(oldBackup, newBackup, report);
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreData(const boost::function<Operations::RestoreData_t> &op,
|
|
||||||
const Operations::ConstBackupInfo &oldBackup,
|
|
||||||
bool dryrun,
|
|
||||||
SyncSourceReport &report) {
|
|
||||||
contactServer();
|
|
||||||
op(oldBackup, dryrun, report);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return true if the resource with the given properties is one
|
* return true if the resource with the given properties is one
|
||||||
* of those collections which is guaranteed to not contain
|
* of those collections which is guaranteed to not contain
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
|
|
||||||
|
@ -60,9 +59,9 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||||
sourceType.m_format == "text/x-vcalendar") {
|
sourceType.m_format == "text/x-vcalendar") {
|
||||||
#ifdef ENABLE_DAV
|
#ifdef ENABLE_DAV
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
boost::shared_ptr<Neon::Settings> settings;
|
std::shared_ptr<Neon::Settings> settings;
|
||||||
if (sourceType.m_backend == "CalDAV") {
|
if (sourceType.m_backend == "CalDAV") {
|
||||||
boost::shared_ptr<SubSyncSource> sub(new CalDAVSource(params, settings));
|
auto sub = std::make_shared<CalDAVSource>(params, settings);
|
||||||
return new MapSyncSource(params, sub);
|
return new MapSyncSource(params, sub);
|
||||||
} else {
|
} else {
|
||||||
return new CalDAVVxxSource(sourceType.m_backend == "CalDAVTodo" ? "VTODO" : "VJOURNAL",
|
return new CalDAVVxxSource(sourceType.m_backend == "CalDAVTodo" ? "VTODO" : "VJOURNAL",
|
||||||
|
@ -81,7 +80,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||||
sourceType.m_format == "text/vcard") {
|
sourceType.m_format == "text/vcard") {
|
||||||
#ifdef ENABLE_DAV
|
#ifdef ENABLE_DAV
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
boost::shared_ptr<Neon::Settings> settings;
|
std::shared_ptr<Neon::Settings> settings;
|
||||||
return new CardDAVSource(params, settings);
|
return new CardDAVSource(params, settings);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -138,7 +137,7 @@ class WebDAVTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<TestingSyncSource> source;
|
std::shared_ptr<TestingSyncSource> source;
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV", true));
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/calendar", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/calendar", true));
|
||||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/x-vcalendar", true));
|
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/x-vcalendar", true));
|
||||||
|
@ -262,8 +261,11 @@ public:
|
||||||
m_type == "caldav" ||
|
m_type == "caldav" ||
|
||||||
m_type == "caldavjournal" ||
|
m_type == "caldavjournal" ||
|
||||||
m_type == "caldavtodo";
|
m_type == "caldavtodo";
|
||||||
config.m_createSourceA = boost::bind(&WebDAVTest::createSource, this, _2, _4);
|
auto create = [this] (ClientTest &, const std::string &clientID, int, bool isSourceA) {
|
||||||
config.m_createSourceB = boost::bind(&WebDAVTest::createSource, this, _2, _4);
|
return createSource(clientID, isSourceA);
|
||||||
|
};
|
||||||
|
config.m_createSourceA =
|
||||||
|
config.m_createSourceB = create;
|
||||||
ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
|
ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
|
||||||
if (it != m_props.end() ||
|
if (it != m_props.end() ||
|
||||||
(it = m_props.find("testcases")) != m_props.end()) {
|
(it = m_props.find("testcases")) != m_props.end()) {
|
||||||
|
@ -293,7 +295,7 @@ public:
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
config.c_str(),
|
config.c_str(),
|
||||||
tracking.c_str());
|
tracking.c_str());
|
||||||
boost::shared_ptr<SyncConfig> context(new SyncConfig(config));
|
auto context = std::make_shared<SyncConfig>(config);
|
||||||
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
|
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
|
||||||
|
|
||||||
// Copy properties from the Client::Sync
|
// Copy properties from the Client::Sync
|
||||||
|
@ -301,7 +303,7 @@ public:
|
||||||
// that a testing source used as part of Client::Sync uses the
|
// that a testing source used as part of Client::Sync uses the
|
||||||
// same settings.
|
// same settings.
|
||||||
std::string peerName = std::string(server ? server : "no-such-server") + "_" + clientID;
|
std::string peerName = std::string(server ? server : "no-such-server") + "_" + clientID;
|
||||||
boost::shared_ptr<SyncConfig> peer(new SyncConfig(peerName));
|
auto peer = std::make_shared<SyncConfig>(peerName);
|
||||||
// Resolve credentials.
|
// Resolve credentials.
|
||||||
SimpleUserInterface ui(peer->getKeyring());
|
SimpleUserInterface ui(peer->getKeyring());
|
||||||
PasswordConfigProperty::checkPasswords(ui,
|
PasswordConfigProperty::checkPasswords(ui,
|
||||||
|
@ -317,7 +319,7 @@ public:
|
||||||
if (prop->isHidden()) {
|
if (prop->isHidden()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boost::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
|
std::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
|
||||||
InitStateString value = prop->getProperty(*node);
|
InitStateString value = prop->getProperty(*node);
|
||||||
SE_LOG_DEBUG(NULL, " %s = %s (%s)",
|
SE_LOG_DEBUG(NULL, " %s = %s (%s)",
|
||||||
prop->getMainName().c_str(),
|
prop->getMainName().c_str(),
|
||||||
|
@ -336,7 +338,7 @@ public:
|
||||||
SE_LOG_DEBUG(NULL, " additional property backend = %s (from CLIENT_TEST_WEBDAV)",
|
SE_LOG_DEBUG(NULL, " additional property backend = %s (from CLIENT_TEST_WEBDAV)",
|
||||||
m_type.c_str());
|
m_type.c_str());
|
||||||
for (const StringPair &propval: m_props) {
|
for (const StringPair &propval: m_props) {
|
||||||
boost::shared_ptr<FilterConfigNode> node = context->getNode(propval.first);
|
std::shared_ptr<FilterConfigNode> node = context->getNode(propval.first);
|
||||||
if (node) {
|
if (node) {
|
||||||
SE_LOG_DEBUG(NULL, " additional property %s = %s (from CLIENT_TEST_WEBDAV)",
|
SE_LOG_DEBUG(NULL, " additional property %s = %s (from CLIENT_TEST_WEBDAV)",
|
||||||
propval.first.c_str(), propval.second.c_str());
|
propval.first.c_str(), propval.second.c_str());
|
||||||
|
@ -376,10 +378,10 @@ static class WebDAVTestSingleton : RegisterSyncSourceTest {
|
||||||
*/
|
*/
|
||||||
class WebDAVList
|
class WebDAVList
|
||||||
{
|
{
|
||||||
list< boost::shared_ptr<WebDAVTest> >m_sources;
|
list< std::shared_ptr<WebDAVTest> >m_sources;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void push_back(const boost::shared_ptr<WebDAVTest> &source)
|
void push_back(const std::shared_ptr<WebDAVTest> &source)
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<TestingSyncSource> instance(source->createSource("1", true));
|
boost::scoped_ptr<TestingSyncSource> instance(source->createSource("1", true));
|
||||||
std::string database = instance->getDatabaseID();
|
std::string database = instance->getDatabaseID();
|
||||||
|
@ -448,19 +450,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (caldav) {
|
if (caldav) {
|
||||||
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldav", props));
|
auto ptr = std::make_shared<WebDAVTest>(server, "caldav", props);
|
||||||
m_sources.push_back(ptr);
|
m_sources.push_back(ptr);
|
||||||
}
|
}
|
||||||
if (caldavtodo) {
|
if (caldavtodo) {
|
||||||
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldavtodo", props));
|
auto ptr = std::make_shared<WebDAVTest>(server, "caldavtodo", props);
|
||||||
m_sources.push_back(ptr);
|
m_sources.push_back(ptr);
|
||||||
}
|
}
|
||||||
if (caldavjournal) {
|
if (caldavjournal) {
|
||||||
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldavjournal", props));
|
auto ptr = std::make_shared<WebDAVTest>(server, "caldavjournal", props);
|
||||||
m_sources.push_back(ptr);
|
m_sources.push_back(ptr);
|
||||||
}
|
}
|
||||||
if (carddav) {
|
if (carddav) {
|
||||||
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "carddav", props));
|
auto ptr = std::make_shared<WebDAVTest>(server, "carddav", props);
|
||||||
m_sources.push_back(ptr);
|
m_sources.push_back(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class XMLRPCSyncSourceUnitTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void testInstantiate() {
|
void testInstantiate() {
|
||||||
boost::shared_ptr<SyncSource> source;
|
std::shared_ptr<SyncSource> source;
|
||||||
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/vcard:3.0", true));
|
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/vcard:3.0", true));
|
||||||
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/plain:1.0", true));
|
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/plain:1.0", true));
|
||||||
source.reset(SyncSource::createTestingSource("xmlrpc", "XMLRPC interface:text/x-vcard:2.1", true));
|
source.reset(SyncSource::createTestingSource("xmlrpc", "XMLRPC interface:text/x-vcard:2.1", true));
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
#include <syncevo/VolatileConfigNode.h>
|
#include <syncevo/VolatileConfigNode.h>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -68,7 +66,7 @@ public:
|
||||||
* around for each of eds_event and eds_contact/30, if they ever were used
|
* around for each of eds_event and eds_contact/30, if they ever were used
|
||||||
* during testing.
|
* during testing.
|
||||||
*/
|
*/
|
||||||
static map<string, boost::shared_ptr<TestingSyncSource> > lockEvolution;
|
static map<string, std::shared_ptr<TestingSyncSource> > lockEvolution;
|
||||||
static void CleanupSources()
|
static void CleanupSources()
|
||||||
{
|
{
|
||||||
lockEvolution.clear();
|
lockEvolution.clear();
|
||||||
|
@ -210,8 +208,8 @@ public:
|
||||||
// get configuration and set obligatory fields
|
// get configuration and set obligatory fields
|
||||||
Logger::instance().setLevel(Logger::DEBUG);
|
Logger::instance().setLevel(Logger::DEBUG);
|
||||||
std::string root = std::string("evolution/") + server + "_" + m_clientID;
|
std::string root = std::string("evolution/") + server + "_" + m_clientID;
|
||||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(string(server) + "_" + m_clientID));
|
auto config = std::make_shared<SyncConfig>(string(server) + "_" + m_clientID);
|
||||||
boost::shared_ptr<SyncConfig> from = boost::shared_ptr<SyncConfig> ();
|
std::shared_ptr<SyncConfig> from = std::shared_ptr<SyncConfig> ();
|
||||||
|
|
||||||
if (!config->exists()) {
|
if (!config->exists()) {
|
||||||
// no configuration yet, create in different contexts because
|
// no configuration yet, create in different contexts because
|
||||||
|
@ -234,7 +232,7 @@ public:
|
||||||
getSourceConfig(test, testconfig);
|
getSourceConfig(test, testconfig);
|
||||||
CPPUNIT_ASSERT(!testconfig.m_type.empty());
|
CPPUNIT_ASSERT(!testconfig.m_type.empty());
|
||||||
|
|
||||||
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName);
|
std::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName);
|
||||||
if (!sc || !sc->exists()) {
|
if (!sc || !sc->exists()) {
|
||||||
// no configuration yet
|
// no configuration yet
|
||||||
config->setSourceDefaults(testconfig.m_sourceName);
|
config->setSourceDefaults(testconfig.m_sourceName);
|
||||||
|
@ -242,7 +240,7 @@ public:
|
||||||
CPPUNIT_ASSERT(sc);
|
CPPUNIT_ASSERT(sc);
|
||||||
sc->setURI(testconfig.m_uri);
|
sc->setURI(testconfig.m_uri);
|
||||||
if(from && !testconfig.m_sourceNameServerTemplate.empty()) {
|
if(from && !testconfig.m_sourceNameServerTemplate.empty()) {
|
||||||
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate);
|
std::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate);
|
||||||
sc->setURI(scServerTemplate->getURI());
|
sc->setURI(scServerTemplate->getURI());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,10 +395,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual boost::shared_ptr<TransportAgent> createTransportAgent()
|
virtual std::shared_ptr<TransportAgent> createTransportAgent()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<TransportAgent>wrapper = m_options.m_transport;
|
std::shared_ptr<TransportAgent>wrapper = m_options.m_transport;
|
||||||
boost::shared_ptr<TransportAgent>agent =SyncContext::createTransportAgent();
|
std::shared_ptr<TransportAgent>agent =SyncContext::createTransportAgent();
|
||||||
if (!wrapper.get())
|
if (!wrapper.get())
|
||||||
return agent;
|
return agent;
|
||||||
dynamic_cast<TransportWrapper*>(wrapper.get())->setAgent(agent);
|
dynamic_cast<TransportWrapper*>(wrapper.get())->setAgent(agent);
|
||||||
|
@ -487,7 +485,7 @@ private:
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
config.c_str(),
|
config.c_str(),
|
||||||
tracking.c_str());
|
tracking.c_str());
|
||||||
boost::shared_ptr<SyncConfig> context(new SyncConfig(config));
|
auto context = std::make_shared<SyncConfig>(config);
|
||||||
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
|
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
|
||||||
|
|
||||||
// The user of client-test must have configured the source
|
// The user of client-test must have configured the source
|
||||||
|
@ -495,7 +493,7 @@ private:
|
||||||
// Client::Sync testing. Our testing source must use the same
|
// Client::Sync testing. Our testing source must use the same
|
||||||
// properties, but different change tracking.
|
// properties, but different change tracking.
|
||||||
std::string peerName = server ? (std::string(server) + "_" + m_clientID) : "@default";
|
std::string peerName = server ? (std::string(server) + "_" + m_clientID) : "@default";
|
||||||
boost::shared_ptr<SyncConfig> peer(new SyncConfig(peerName));
|
auto peer = std::make_shared<SyncConfig>(peerName);
|
||||||
SyncSourceNodes peerNodes = peer->getSyncSourceNodes(name);
|
SyncSourceNodes peerNodes = peer->getSyncSourceNodes(name);
|
||||||
SE_LOG_DEBUG(NULL, "overriding testing source %s properties with the ones from config %s = %s",
|
SE_LOG_DEBUG(NULL, "overriding testing source %s properties with the ones from config %s = %s",
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
|
@ -505,7 +503,7 @@ private:
|
||||||
if (prop->isHidden()) {
|
if (prop->isHidden()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boost::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
|
std::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
|
||||||
InitStateString value = prop->getProperty(*node);
|
InitStateString value = prop->getProperty(*node);
|
||||||
SE_LOG_DEBUG(NULL, " %s = %s (%s)",
|
SE_LOG_DEBUG(NULL, " %s = %s (%s)",
|
||||||
prop->getMainName().c_str(),
|
prop->getMainName().c_str(),
|
||||||
|
@ -518,7 +516,7 @@ private:
|
||||||
|
|
||||||
// Same as in init() above: set values if still empty, but don't
|
// Same as in init() above: set values if still empty, but don't
|
||||||
// overwrite anything.
|
// overwrite anything.
|
||||||
boost::shared_ptr<FilterConfigNode> props = nodes.getProperties();
|
std::shared_ptr<FilterConfigNode> props = nodes.getProperties();
|
||||||
std::string value;
|
std::string value;
|
||||||
if (!props->getProperty("database", value)) {
|
if (!props->getProperty("database", value)) {
|
||||||
props->setProperty("database", database);
|
props->setProperty("database", database);
|
||||||
|
|
|
@ -43,17 +43,16 @@ static void updatePresence(Timespec *t, bool present)
|
||||||
Timespec();
|
Timespec();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server &server)
|
std::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server &server)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<AutoSyncManager> result(new AutoSyncManager(server));
|
auto result = make_weak_shared::make<AutoSyncManager>(server);
|
||||||
result->m_me = result;
|
|
||||||
result->init();
|
result->init();
|
||||||
|
|
||||||
// update cached information about a config each time it changes
|
// update cached information about a config each time it changes
|
||||||
server.m_configChangedSignal.connect(Server::ConfigChangedSignal_t::slot_type(&AutoSyncManager::initConfig, result.get(), _1).track(result));
|
server.m_configChangedSignal.connect(Server::ConfigChangedSignal_t::slot_type(&AutoSyncManager::initConfig, result.get(), _1).track_foreign(result));
|
||||||
|
|
||||||
// monitor running sessions
|
// monitor running sessions
|
||||||
server.m_newSyncSessionSignal.connect(Server::NewSyncSessionSignal_t::slot_type(&AutoSyncManager::sessionStarted, result.get(), _1).track(result));
|
server.m_newSyncSessionSignal.connect(Server::NewSyncSessionSignal_t::slot_type(&AutoSyncManager::sessionStarted, result.get(), _1).track_foreign(result));
|
||||||
|
|
||||||
// Keep track of the time when a transport became online. As with
|
// Keep track of the time when a transport became online. As with
|
||||||
// time of last sync, we are pessimistic here and assume that the
|
// time of last sync, we are pessimistic here and assume that the
|
||||||
|
@ -65,13 +64,13 @@ boost::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server
|
||||||
}
|
}
|
||||||
p.m_btPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
|
p.m_btPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
|
||||||
&result->m_btStartTime,
|
&result->m_btStartTime,
|
||||||
_1).track(result));
|
_1).track_foreign(result));
|
||||||
if (p.getHttpPresence()) {
|
if (p.getHttpPresence()) {
|
||||||
result->m_httpStartTime = now;
|
result->m_httpStartTime = now;
|
||||||
}
|
}
|
||||||
p.m_httpPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
|
p.m_httpPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
|
||||||
&result->m_httpStartTime,
|
&result->m_httpStartTime,
|
||||||
_1).track(result));
|
_1).track_foreign(result));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +121,7 @@ void AutoSyncManager::initConfig(const std::string &configName)
|
||||||
// Create anew or update, directly in map. Never remove
|
// Create anew or update, directly in map. Never remove
|
||||||
// old entries, because we want to keep the m_lastSyncTime
|
// old entries, because we want to keep the m_lastSyncTime
|
||||||
// in cases where configs get removed and recreated.
|
// in cases where configs get removed and recreated.
|
||||||
boost::shared_ptr<AutoSyncTask> &task = m_peerMap[configName];
|
std::shared_ptr<AutoSyncTask> &task = m_peerMap[configName];
|
||||||
if (!task) {
|
if (!task) {
|
||||||
task.reset(new AutoSyncTask(configName));
|
task.reset(new AutoSyncTask(configName));
|
||||||
// We should check past sessions here. Instead we assume
|
// We should check past sessions here. Instead we assume
|
||||||
|
@ -250,7 +249,7 @@ void AutoSyncManager::schedule(const std::string &reason)
|
||||||
Timespec now = Timespec::monotonic();
|
Timespec now = Timespec::monotonic();
|
||||||
for (const auto &entry: m_peerMap) {
|
for (const auto &entry: m_peerMap) {
|
||||||
const std::string &configName = entry.first;
|
const std::string &configName = entry.first;
|
||||||
const boost::shared_ptr<AutoSyncTask> &task = entry.second;
|
const std::shared_ptr<AutoSyncTask> &task = entry.second;
|
||||||
|
|
||||||
if (task->m_interval <= 0 || // not enabled
|
if (task->m_interval <= 0 || // not enabled
|
||||||
task->m_permanentFailure) { // don't try again
|
task->m_permanentFailure) { // don't try again
|
||||||
|
@ -269,9 +268,7 @@ void AutoSyncManager::schedule(const std::string &reason)
|
||||||
configName.c_str(),
|
configName.c_str(),
|
||||||
seconds);
|
seconds);
|
||||||
task->m_intervalTimeout.runOnce(seconds,
|
task->m_intervalTimeout.runOnce(seconds,
|
||||||
boost::bind(&AutoSyncManager::schedule,
|
[this, configName] () { schedule(configName + " interval timer"); });
|
||||||
this,
|
|
||||||
configName + " interval timer"));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +316,7 @@ void AutoSyncManager::schedule(const std::string &reason)
|
||||||
// check again when it becomes present
|
// check again when it becomes present
|
||||||
signal->connect(PresenceStatus::PresenceSignal_t::slot_type(&AutoSyncManager::schedule,
|
signal->connect(PresenceStatus::PresenceSignal_t::slot_type(&AutoSyncManager::schedule,
|
||||||
this,
|
this,
|
||||||
"presence change").track(m_me));
|
"presence change").track_foreign(shared_from_this()));
|
||||||
SE_LOG_DEBUG(NULL, "auto sync: %s: transport for %s not present",
|
SE_LOG_DEBUG(NULL, "auto sync: %s: transport for %s not present",
|
||||||
configName.c_str(),
|
configName.c_str(),
|
||||||
urlinfo.second.c_str());
|
urlinfo.second.c_str());
|
||||||
|
@ -331,9 +328,7 @@ void AutoSyncManager::schedule(const std::string &reason)
|
||||||
urlinfo.second.c_str(),
|
urlinfo.second.c_str(),
|
||||||
seconds);
|
seconds);
|
||||||
timeout->runOnce(seconds,
|
timeout->runOnce(seconds,
|
||||||
boost::bind(&AutoSyncManager::schedule,
|
[this, configName] () { schedule(configName + " transport timer"); });
|
||||||
this,
|
|
||||||
configName + " transport timer"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,25 +342,21 @@ void AutoSyncManager::schedule(const std::string &reason)
|
||||||
m_server.delaySessionDestruction(m_session);
|
m_server.delaySessionDestruction(m_session);
|
||||||
|
|
||||||
task->m_syncSuccessStart = false;
|
task->m_syncSuccessStart = false;
|
||||||
m_session = Session::createSession(m_server,
|
m_session = make_weak_shared::make<Session>(m_server,
|
||||||
task->m_remoteDeviceId,
|
task->m_remoteDeviceId,
|
||||||
configName,
|
configName,
|
||||||
m_server.getNextSession());
|
m_server.getNextSession());
|
||||||
|
|
||||||
// Temporarily set sync URL to the one which we picked above
|
// Temporarily set sync URL to the one which we picked above
|
||||||
// once the session is active (setConfig() not allowed earlier).
|
// once the session is active (setConfig() not allowed earlier).
|
||||||
|
// Run sync as soon as it is active.
|
||||||
|
m_session->m_sessionActiveSignal.connect([session=m_session.get(), readyURL] () {
|
||||||
ReadOperations::Config_t config;
|
ReadOperations::Config_t config;
|
||||||
config[""]["syncURL"] = readyURL;
|
config[""]["syncURL"] = readyURL;
|
||||||
m_session->m_sessionActiveSignal.connect(boost::bind(&Session::setConfig,
|
|
||||||
m_session.get(),
|
|
||||||
true, true,
|
|
||||||
config));
|
|
||||||
|
|
||||||
// Run sync as soon as it is active.
|
session->setConfig(true, true, config);
|
||||||
m_session->m_sessionActiveSignal.connect(boost::bind(&Session::sync,
|
session->sync("", {});
|
||||||
m_session.get(),
|
});
|
||||||
"",
|
|
||||||
SessionCommon::SourceModes_t()));
|
|
||||||
|
|
||||||
// Now run it.
|
// Now run it.
|
||||||
m_session->activate();
|
m_session->activate();
|
||||||
|
@ -386,10 +377,10 @@ void AutoSyncManager::connectIdle()
|
||||||
m_idleConnection =
|
m_idleConnection =
|
||||||
m_server.m_idleSignal.connect(Server::IdleSignal_t::slot_type(&AutoSyncManager::schedule,
|
m_server.m_idleSignal.connect(Server::IdleSignal_t::slot_type(&AutoSyncManager::schedule,
|
||||||
this,
|
this,
|
||||||
"server is idle").track(m_me));
|
"server is idle").track_foreign(shared_from_this()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session)
|
void AutoSyncManager::sessionStarted(const std::shared_ptr<Session> &session)
|
||||||
{
|
{
|
||||||
// Do we have a task for this config?
|
// Do we have a task for this config?
|
||||||
std::string configName = session->getConfigName();
|
std::string configName = session->getConfigName();
|
||||||
|
@ -400,18 +391,20 @@ void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<AutoSyncManager> me = m_me.lock();
|
std::shared_ptr<AutoSyncManager> me;
|
||||||
if (!me) {
|
try {
|
||||||
|
me = shared_from_this();
|
||||||
|
} catch (...) {
|
||||||
SE_LOG_DEBUG(NULL, "auto sync: already destructing, ignore new sync %s",
|
SE_LOG_DEBUG(NULL, "auto sync: already destructing, ignore new sync %s",
|
||||||
configName.c_str());
|
configName.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const boost::shared_ptr<AutoSyncTask> &task = it->second;
|
const std::shared_ptr<AutoSyncTask> &task = it->second;
|
||||||
task->m_lastSyncTime = Timespec::monotonic();
|
task->m_lastSyncTime = Timespec::monotonic();
|
||||||
|
|
||||||
// track permanent failure
|
// track permanent failure
|
||||||
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::anySyncDone, this, task.get(), _1).track(task).track(me));
|
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::anySyncDone, this, task.get(), _1).track_foreign(task).track_foreign(me));
|
||||||
|
|
||||||
if (m_session == session) {
|
if (m_session == session) {
|
||||||
// Only for our own auto sync session: notify user once session starts successful.
|
// Only for our own auto sync session: notify user once session starts successful.
|
||||||
|
@ -419,18 +412,18 @@ void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session)
|
||||||
// In the (unlikely) case that the AutoSyncTask gets deleted, the
|
// In the (unlikely) case that the AutoSyncTask gets deleted, the
|
||||||
// slot won't get involved, thus skipping user notifications.
|
// slot won't get involved, thus skipping user notifications.
|
||||||
// Also protects against manager destructing before session.
|
// Also protects against manager destructing before session.
|
||||||
session->m_syncSuccessStartSignal.connect(Session::SyncSuccessStartSignal_t::slot_type(&AutoSyncManager::autoSyncSuccessStart, this, task.get()).track(task).track(me));
|
session->m_syncSuccessStartSignal.connect(Session::SyncSuccessStartSignal_t::slot_type(&AutoSyncManager::autoSyncSuccessStart, this, task.get()).track_foreign(task).track_foreign(me));
|
||||||
|
|
||||||
// Notify user once session ends, with or without failure.
|
// Notify user once session ends, with or without failure.
|
||||||
// Same instance tracking as for sync success start.
|
// Same instance tracking as for sync success start.
|
||||||
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::autoSyncDone, this, task.get(), _1).track(task).track(me));
|
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::autoSyncDone, this, task.get(), _1).track_foreign(task).track_foreign(me));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoSyncManager::preventTerm()
|
bool AutoSyncManager::preventTerm()
|
||||||
{
|
{
|
||||||
for (const auto &entry: m_peerMap) {
|
for (const auto &entry: m_peerMap) {
|
||||||
const boost::shared_ptr<AutoSyncTask> &task = entry.second;
|
const std::shared_ptr<AutoSyncTask> &task = entry.second;
|
||||||
if (task->m_interval > 0 &&
|
if (task->m_interval > 0 &&
|
||||||
!task->m_permanentFailure &&
|
!task->m_permanentFailure &&
|
||||||
!task->m_urls.empty()) {
|
!task->m_urls.empty()) {
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
#define AUTO_SYNC_MANAGER_H
|
#define AUTO_SYNC_MANAGER_H
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/weak_ptr.hpp>
|
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
|
|
||||||
#include <syncevo/SyncML.h>
|
#include <syncevo/SyncML.h>
|
||||||
|
@ -55,16 +53,15 @@ class Session;
|
||||||
* Syncs triggered by local or remote changes will be added
|
* Syncs triggered by local or remote changes will be added
|
||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
class AutoSyncManager
|
class AutoSyncManager : public enable_weak_from_this<AutoSyncManager>, private boost::noncopyable
|
||||||
{
|
{
|
||||||
Server &m_server;
|
Server &m_server;
|
||||||
boost::weak_ptr<AutoSyncManager> m_me;
|
|
||||||
|
|
||||||
/** true if we currently hold a ref for AutoTerm */
|
/** true if we currently hold a ref for AutoTerm */
|
||||||
bool m_autoTermLocked;
|
bool m_autoTermLocked;
|
||||||
|
|
||||||
/** currently running auto sync session */
|
/** currently running auto sync session */
|
||||||
boost::shared_ptr<Session> m_session;
|
std::shared_ptr<Session> m_session;
|
||||||
|
|
||||||
/** connects m_server.m_idleSignal with schedule() */
|
/** connects m_server.m_idleSignal with schedule() */
|
||||||
boost::signals2::connection m_idleConnection;
|
boost::signals2::connection m_idleConnection;
|
||||||
|
@ -173,11 +170,11 @@ class AutoSyncManager
|
||||||
* enabled (to track when and if they ran) and deleted configs
|
* enabled (to track when and if they ran) and deleted configs
|
||||||
* (because they might get recreated).
|
* (because they might get recreated).
|
||||||
*/
|
*/
|
||||||
typedef std::map<std::string, boost::shared_ptr<AutoSyncTask> > PeerMap;
|
typedef std::map<std::string, std::shared_ptr<AutoSyncTask> > PeerMap;
|
||||||
PeerMap m_peerMap;
|
PeerMap m_peerMap;
|
||||||
|
|
||||||
/** used to send notifications */
|
/** used to send notifications */
|
||||||
boost::shared_ptr<NotificationManagerBase> m_notificationManager;
|
std::shared_ptr<NotificationManagerBase> m_notificationManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It reads all peers which are enabled to do auto sync and store them in
|
* It reads all peers which are enabled to do auto sync and store them in
|
||||||
|
@ -197,7 +194,7 @@ class AutoSyncManager
|
||||||
* Watch further progress (if auto sync session),
|
* Watch further progress (if auto sync session),
|
||||||
* record start time (in all cases).
|
* record start time (in all cases).
|
||||||
*/
|
*/
|
||||||
void sessionStarted(const boost::shared_ptr<Session> &session);
|
void sessionStarted(const std::shared_ptr<Session> &session);
|
||||||
|
|
||||||
/** Show "sync started" notification. */
|
/** Show "sync started" notification. */
|
||||||
void autoSyncSuccessStart(AutoSyncTask *task);
|
void autoSyncSuccessStart(AutoSyncTask *task);
|
||||||
|
@ -211,7 +208,7 @@ class AutoSyncManager
|
||||||
AutoSyncManager(Server &server);
|
AutoSyncManager(Server &server);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static boost::shared_ptr<AutoSyncManager> createAutoSyncManager(Server &server);
|
static std::shared_ptr<AutoSyncManager> createAutoSyncManager(Server &server);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prevent dbus server automatic termination when it has
|
* prevent dbus server automatic termination when it has
|
||||||
|
|
|
@ -48,8 +48,8 @@ BluezManager::BluezManager(Server &server) :
|
||||||
if (getConnection()) {
|
if (getConnection()) {
|
||||||
m_done = false;
|
m_done = false;
|
||||||
DBusClientCall<DBusObject_t> getAdapter(*this, "DefaultAdapter");
|
DBusClientCall<DBusObject_t> getAdapter(*this, "DefaultAdapter");
|
||||||
getAdapter.start(boost::bind(&BluezManager::defaultAdapterCb, this, _1, _2 ));
|
getAdapter.start([this] (const DBusObject_t &adapter, const string &error) { defaultAdapterCb(adapter, error); });
|
||||||
m_adapterChanged.activate(boost::bind(&BluezManager::defaultAdapterChanged, this, _1));
|
m_adapterChanged.activate([this] (const DBusObject_t &adapter) { defaultAdapterChanged(adapter); });
|
||||||
} else {
|
} else {
|
||||||
m_done = true;
|
m_done = true;
|
||||||
}
|
}
|
||||||
|
@ -85,9 +85,9 @@ BluezManager::BluezAdapter::BluezAdapter(BluezManager &manager, const string &pa
|
||||||
m_deviceRemoved(*this, "DeviceRemoved"), m_deviceAdded(*this, "DeviceCreated")
|
m_deviceRemoved(*this, "DeviceRemoved"), m_deviceAdded(*this, "DeviceCreated")
|
||||||
{
|
{
|
||||||
DBusClientCall<std::vector<DBusObject_t> > listDevices(*this, "ListDevices");
|
DBusClientCall<std::vector<DBusObject_t> > listDevices(*this, "ListDevices");
|
||||||
listDevices.start(boost::bind(&BluezAdapter::listDevicesCb, this, _1, _2));
|
listDevices.start([this] (const std::vector<DBusObject_t> &devices, const string &error) { listDevicesCb(devices, error); });
|
||||||
m_deviceRemoved.activate(boost::bind(&BluezAdapter::deviceRemoved, this, _1));
|
m_deviceRemoved.activate([this] (const DBusObject_t &object) { deviceRemoved(object); });
|
||||||
m_deviceAdded.activate(boost::bind(&BluezAdapter::deviceCreated, this, _1));
|
m_deviceAdded.activate([this] (const DBusObject_t &object) { deviceCreated(object); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &devices, const string &error)
|
void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &devices, const string &error)
|
||||||
|
@ -99,7 +99,7 @@ void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &
|
||||||
}
|
}
|
||||||
m_devNo = devices.size();
|
m_devNo = devices.size();
|
||||||
for (const auto &device: devices) {
|
for (const auto &device: devices) {
|
||||||
boost::shared_ptr<BluezDevice> bluezDevice(new BluezDevice(*this, device));
|
auto bluezDevice = std::make_shared<BluezDevice>(*this, device);
|
||||||
m_devices.push_back(bluezDevice);
|
m_devices.push_back(bluezDevice);
|
||||||
}
|
}
|
||||||
checkDone();
|
checkDone();
|
||||||
|
@ -108,7 +108,7 @@ void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &
|
||||||
void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object)
|
void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object)
|
||||||
{
|
{
|
||||||
string address;
|
string address;
|
||||||
std::vector<boost::shared_ptr<BluezDevice> >::iterator devIt;
|
std::vector<std::shared_ptr<BluezDevice> >::iterator devIt;
|
||||||
for(devIt = m_devices.begin(); devIt != m_devices.end(); ++devIt) {
|
for(devIt = m_devices.begin(); devIt != m_devices.end(); ++devIt) {
|
||||||
if(boost::equals((*devIt)->getPath(), object)) {
|
if(boost::equals((*devIt)->getPath(), object)) {
|
||||||
address = (*devIt)->m_mac;
|
address = (*devIt)->m_mac;
|
||||||
|
@ -126,7 +126,7 @@ void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object)
|
||||||
void BluezManager::BluezAdapter::deviceCreated(const DBusObject_t &object)
|
void BluezManager::BluezAdapter::deviceCreated(const DBusObject_t &object)
|
||||||
{
|
{
|
||||||
m_devNo++;
|
m_devNo++;
|
||||||
boost::shared_ptr<BluezDevice> bluezDevice(new BluezDevice(*this, object));
|
auto bluezDevice = std::make_shared<BluezDevice>(*this, object);
|
||||||
m_devices.push_back(bluezDevice);
|
m_devices.push_back(bluezDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +136,10 @@ BluezManager::BluezDevice::BluezDevice (BluezAdapter &adapter, const string &pat
|
||||||
m_adapter(adapter), m_reply(false), m_propertyChanged(*this, "PropertyChanged")
|
m_adapter(adapter), m_reply(false), m_propertyChanged(*this, "PropertyChanged")
|
||||||
{
|
{
|
||||||
DBusClientCall<PropDict> getProperties(*this, "GetProperties");
|
DBusClientCall<PropDict> getProperties(*this, "GetProperties");
|
||||||
getProperties.start(boost::bind(&BluezDevice::getPropertiesCb, this, _1, _2));
|
getProperties.start([this] (const PropDict &props, const string &error) { getPropertiesCb(props, error); });
|
||||||
|
|
||||||
m_propertyChanged.activate(boost::bind(&BluezDevice::propertyChanged, this, _1, _2));
|
m_propertyChanged.activate([this] (const string &name,
|
||||||
|
const boost::variant<vector<string>, string> &prop) { propertyChanged(name, prop); });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,8 +175,8 @@ void BluezManager::BluezDevice::checkSyncService(const std::vector<std::string>
|
||||||
DBusClientCall<ServiceDict> discoverServices(*this,
|
DBusClientCall<ServiceDict> discoverServices(*this,
|
||||||
"DiscoverServices");
|
"DiscoverServices");
|
||||||
static const std::string PNP_INFO_UUID("0x1200");
|
static const std::string PNP_INFO_UUID("0x1200");
|
||||||
discoverServices.start(boost::bind(&BluezDevice::discoverServicesCb,
|
discoverServices.start([this] (const ServiceDict &serviceDict,
|
||||||
this, _1, _2),
|
const string &error) { discoverServicesCb(serviceDict, error); },
|
||||||
PNP_INFO_UUID);
|
PNP_INFO_UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,9 +240,9 @@ bool BluezManager::getPnpInfoNamesFromValues(const std::string &vendorValue, std
|
||||||
if (!m_watchedFile) {
|
if (!m_watchedFile) {
|
||||||
m_lookupTable.bt_key_file = g_key_file_new();
|
m_lookupTable.bt_key_file = g_key_file_new();
|
||||||
string filePath(SyncEvolutionDataDir() + "/bluetooth_products.ini");
|
string filePath(SyncEvolutionDataDir() + "/bluetooth_products.ini");
|
||||||
m_watchedFile = boost::shared_ptr<SyncEvo::GLibNotify>(
|
m_watchedFile = std::shared_ptr<SyncEvo::GLibNotify>(
|
||||||
new GLibNotify(filePath.c_str(),
|
new GLibNotify(filePath.c_str(),
|
||||||
boost::bind(&BluezManager::loadBluetoothDeviceLookupTable, this)));
|
[this] (GFile *, GFile *, GFileMonitorEvent) { loadBluetoothDeviceLookupTable(); }));
|
||||||
}
|
}
|
||||||
loadBluetoothDeviceLookupTable();
|
loadBluetoothDeviceLookupTable();
|
||||||
// Make sure the file was actually loaded
|
// Make sure the file was actually loaded
|
||||||
|
@ -311,7 +312,7 @@ void BluezManager::BluezDevice::discoverServicesCb(const ServiceDict &serviceDic
|
||||||
SyncConfig::DeviceDescription devDesc;
|
SyncConfig::DeviceDescription devDesc;
|
||||||
if (server.getDevice(m_mac, devDesc)) {
|
if (server.getDevice(m_mac, devDesc)) {
|
||||||
devDesc.m_pnpInformation =
|
devDesc.m_pnpInformation =
|
||||||
boost::shared_ptr<SyncConfig::PnpInformation>(
|
std::shared_ptr<SyncConfig::PnpInformation>(
|
||||||
new SyncConfig::PnpInformation(vendorName, productName));
|
new SyncConfig::PnpInformation(vendorName, productName));
|
||||||
server.updateDevice(m_mac, devDesc);
|
server.updateDevice(m_mac, devDesc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<boost::shared_ptr<BluezDevice> >& getDevices() { return m_devices; }
|
std::vector<std::shared_ptr<BluezDevice> >& getDevices() { return m_devices; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** callback of 'ListDevices' signal. Used to get all available devices of the adapter */
|
/** callback of 'ListDevices' signal. Used to get all available devices of the adapter */
|
||||||
|
@ -98,7 +98,7 @@ private:
|
||||||
int m_devReplies;
|
int m_devReplies;
|
||||||
|
|
||||||
/** all available devices */
|
/** all available devices */
|
||||||
std::vector<boost::shared_ptr<BluezDevice> > m_devices;
|
std::vector<std::shared_ptr<BluezDevice> > m_devices;
|
||||||
|
|
||||||
/** represents 'DeviceRemoved' signal of org.bluez.Adapter*/
|
/** represents 'DeviceRemoved' signal of org.bluez.Adapter*/
|
||||||
GDBusCXX::SignalWatch<GDBusCXX::DBusObject_t> m_deviceRemoved;
|
GDBusCXX::SignalWatch<GDBusCXX::DBusObject_t> m_deviceRemoved;
|
||||||
|
@ -167,7 +167,7 @@ private:
|
||||||
|
|
||||||
Server &m_server;
|
Server &m_server;
|
||||||
GDBusCXX::DBusConnectionPtr m_bluezConn;
|
GDBusCXX::DBusConnectionPtr m_bluezConn;
|
||||||
boost::shared_ptr<BluezAdapter> m_adapter;
|
std::shared_ptr<BluezAdapter> m_adapter;
|
||||||
|
|
||||||
// Holds the bluetooth lookup table and whether it was successfully loaded.
|
// Holds the bluetooth lookup table and whether it was successfully loaded.
|
||||||
class lookupTable : private boost::noncopyable {
|
class lookupTable : private boost::noncopyable {
|
||||||
|
@ -179,7 +179,7 @@ private:
|
||||||
bool isLoaded;
|
bool isLoaded;
|
||||||
} m_lookupTable;
|
} m_lookupTable;
|
||||||
|
|
||||||
boost::shared_ptr<GLibNotify> m_watchedFile;
|
std::shared_ptr<GLibNotify> m_watchedFile;
|
||||||
void loadBluetoothDeviceLookupTable();
|
void loadBluetoothDeviceLookupTable();
|
||||||
bool getPnpInfoNamesFromValues(const std::string &vendorValue, std::string &vendorName,
|
bool getPnpInfoNamesFromValues(const std::string &vendorValue, std::string &vendorName,
|
||||||
const std::string &productValue, std::string &productName);
|
const std::string &productValue, std::string &productName);
|
||||||
|
|
|
@ -45,7 +45,7 @@ void Client::detach(Resource *resource)
|
||||||
if (it->unique()) {
|
if (it->unique()) {
|
||||||
// client was the last owner, and thus the session must be idle (otherwise
|
// client was the last owner, and thus the session must be idle (otherwise
|
||||||
// it would also be referenced as active session)
|
// it would also be referenced as active session)
|
||||||
boost::shared_ptr<Session> session = boost::dynamic_pointer_cast<Session>(*it);
|
std::shared_ptr<Session> session = std::dynamic_pointer_cast<Session>(*it);
|
||||||
if (session) {
|
if (session) {
|
||||||
// give clients a chance to query the session
|
// give clients a chance to query the session
|
||||||
m_server.delaySessionDestruction(session);
|
m_server.delaySessionDestruction(session);
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Client
|
||||||
{
|
{
|
||||||
Server &m_server;
|
Server &m_server;
|
||||||
|
|
||||||
typedef std::list< boost::shared_ptr<Resource> > Resources_t;
|
typedef std::list< std::shared_ptr<Resource> > Resources_t;
|
||||||
Resources_t m_resources;
|
Resources_t m_resources;
|
||||||
|
|
||||||
/** counts how often a client has called Attach() without Detach() */
|
/** counts how often a client has called Attach() without Detach() */
|
||||||
|
@ -74,7 +74,7 @@ public:
|
||||||
* multiple times, which means that detach() also has to be called
|
* multiple times, which means that detach() also has to be called
|
||||||
* the same number of times to finally detach the resource.
|
* the same number of times to finally detach the resource.
|
||||||
*/
|
*/
|
||||||
void attach(boost::shared_ptr<Resource> resource)
|
void attach(std::shared_ptr<Resource> resource)
|
||||||
{
|
{
|
||||||
m_resources.push_back(resource);
|
m_resources.push_back(resource);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void detach(Resource *resource);
|
void detach(Resource *resource);
|
||||||
|
|
||||||
void detach(boost::shared_ptr<Resource> resource)
|
void detach(std::shared_ptr<Resource> resource)
|
||||||
{
|
{
|
||||||
detach(resource.get());
|
detach(resource.get());
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void detachAll(boost::shared_ptr<Resource> resource)
|
void detachAll(std::shared_ptr<Resource> resource)
|
||||||
{
|
{
|
||||||
detachAll(resource.get());
|
detachAll(resource.get());
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
* return corresponding smart pointer for a certain resource,
|
* return corresponding smart pointer for a certain resource,
|
||||||
* empty pointer if not found
|
* empty pointer if not found
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Resource> findResource(Resource *resource)
|
std::shared_ptr<Resource> findResource(Resource *resource)
|
||||||
{
|
{
|
||||||
for (Resources_t::iterator it = m_resources.begin();
|
for (Resources_t::iterator it = m_resources.begin();
|
||||||
it != m_resources.end();
|
it != m_resources.end();
|
||||||
|
@ -125,7 +125,7 @@ public:
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return boost::shared_ptr<Resource>();
|
return std::shared_ptr<Resource>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "session-helper.h"
|
#include "session-helper.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,9 +60,9 @@ public:
|
||||||
bool run()
|
bool run()
|
||||||
{
|
{
|
||||||
//temporarily set environment variables and restore them after running
|
//temporarily set environment variables and restore them after running
|
||||||
list<boost::shared_ptr<ScopedEnvChange> > changes;
|
list<std::shared_ptr<ScopedEnvChange> > changes;
|
||||||
for (const StringPair &var: m_envVars) {
|
for (const StringPair &var: m_envVars) {
|
||||||
changes.push_back(boost::shared_ptr<ScopedEnvChange>(new ScopedEnvChange(var.first, var.second)));
|
changes.push_back(std::make_unique<ScopedEnvChange>(var.first, var.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = Cmdline::run();
|
bool success = Cmdline::run();
|
||||||
|
|
|
@ -54,7 +54,7 @@ void Connection::failed(const std::string &reason)
|
||||||
//
|
//
|
||||||
// But don't delete ourselves while some code of the Connection still
|
// But don't delete ourselves while some code of the Connection still
|
||||||
// runs. Instead let server do that as part of its event loop.
|
// runs. Instead let server do that as part of its event loop.
|
||||||
boost::shared_ptr<Connection> c = m_me.lock();
|
auto c = weak_from_this().lock();
|
||||||
if (c) {
|
if (c) {
|
||||||
m_server.delayDeletion(c);
|
m_server.delayDeletion(c);
|
||||||
m_server.detach(this);
|
m_server.detach(this);
|
||||||
|
@ -114,13 +114,13 @@ void Connection::process(const Caller_t &caller,
|
||||||
message_type.c_str(),
|
message_type.c_str(),
|
||||||
SessionCommon::ConnectionStateToString(m_state).c_str());
|
SessionCommon::ConnectionStateToString(m_state).c_str());
|
||||||
|
|
||||||
boost::shared_ptr<Client> client(m_server.findClient(caller));
|
std::shared_ptr<Client> client(m_server.findClient(caller));
|
||||||
if (!client) {
|
if (!client) {
|
||||||
SE_THROW("unknown client");
|
SE_THROW("unknown client");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Connection> myself =
|
std::shared_ptr<Connection> myself =
|
||||||
boost::static_pointer_cast<Connection, Resource>(client->findResource(this));
|
std::static_pointer_cast<Connection, Resource>(client->findResource(this));
|
||||||
if (!myself) {
|
if (!myself) {
|
||||||
SE_THROW("client does not own connection");
|
SE_THROW("client does not own connection");
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ void Connection::process(const Caller_t &caller,
|
||||||
|
|
||||||
// run session as client or server
|
// run session as client or server
|
||||||
m_state = SessionCommon::PROCESSING;
|
m_state = SessionCommon::PROCESSING;
|
||||||
m_session = Session::createSession(m_server,
|
m_session = make_weak_shared::make<Session>(m_server,
|
||||||
peerDeviceID,
|
peerDeviceID,
|
||||||
config,
|
config,
|
||||||
m_sessionID);
|
m_sessionID);
|
||||||
|
@ -323,7 +323,7 @@ void Connection::process(const Caller_t &caller,
|
||||||
// it might go away before killing completes and/or
|
// it might go away before killing completes and/or
|
||||||
// fails - need to use shared pointer tracking).
|
// fails - need to use shared pointer tracking).
|
||||||
//
|
//
|
||||||
// boost::shared_ptr<Connection> c = m_me.lock();
|
// std::shared_ptr<Connection> c = m_me.lock();
|
||||||
// if (!c) {
|
// if (!c) {
|
||||||
// SE_THROW("internal error: Connection::process() cannot lock its own instance");
|
// SE_THROW("internal error: Connection::process() cannot lock its own instance");
|
||||||
// }
|
// }
|
||||||
|
@ -423,7 +423,7 @@ void Connection::close(const Caller_t &caller,
|
||||||
error.c_str(),
|
error.c_str(),
|
||||||
SessionCommon::ConnectionStateToString(m_state).c_str());
|
SessionCommon::ConnectionStateToString(m_state).c_str());
|
||||||
|
|
||||||
boost::shared_ptr<Client> client(m_server.findClient(caller));
|
std::shared_ptr<Client> client(m_server.findClient(caller));
|
||||||
if (!client) {
|
if (!client) {
|
||||||
SE_THROW("unknown client");
|
SE_THROW("unknown client");
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ void Connection::close(const Caller_t &caller,
|
||||||
// Remove reference to us from client, will destruct *this*
|
// Remove reference to us from client, will destruct *this*
|
||||||
// instance. To let us finish our work safely, keep a reference
|
// instance. To let us finish our work safely, keep a reference
|
||||||
// that the server will unref when everything is idle again.
|
// that the server will unref when everything is idle again.
|
||||||
boost::shared_ptr<Connection> c = m_me.lock();
|
auto c = weak_from_this().lock();
|
||||||
if (!c) {
|
if (!c) {
|
||||||
SE_THROW("connection already destructing");
|
SE_THROW("connection already destructing");
|
||||||
}
|
}
|
||||||
|
@ -495,7 +495,7 @@ Connection::Connection(Server &server,
|
||||||
DBusObjectHelper(conn,
|
DBusObjectHelper(conn,
|
||||||
std::string("/org/syncevolution/Connection/") + sessionID,
|
std::string("/org/syncevolution/Connection/") + sessionID,
|
||||||
"org.syncevolution.Connection",
|
"org.syncevolution.Connection",
|
||||||
boost::bind(&Server::autoTermCallback, &server)),
|
[serverPtr=&server] () { serverPtr->autoTermCallback(); }),
|
||||||
m_server(server),
|
m_server(server),
|
||||||
m_peer(peer),
|
m_peer(peer),
|
||||||
m_mustAuthenticate(must_authenticate),
|
m_mustAuthenticate(must_authenticate),
|
||||||
|
@ -517,17 +517,6 @@ Connection::Connection(Server &server,
|
||||||
m_sessionID.c_str());
|
m_sessionID.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Connection> Connection::createConnection(Server &server,
|
|
||||||
const DBusConnectionPtr &conn,
|
|
||||||
const std::string &sessionID,
|
|
||||||
const StringMap &peer,
|
|
||||||
bool must_authenticate)
|
|
||||||
{
|
|
||||||
boost::shared_ptr<Connection> c(new Connection(server, conn, sessionID, peer, must_authenticate));
|
|
||||||
c->m_me = c;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection::~Connection()
|
Connection::~Connection()
|
||||||
{
|
{
|
||||||
SE_LOG_DEBUG(NULL, "Connection %s: done with '%s'%s%s%s (old state %s)",
|
SE_LOG_DEBUG(NULL, "Connection %s: done with '%s'%s%s%s (old state %s)",
|
||||||
|
@ -593,7 +582,7 @@ void Connection::ready()
|
||||||
//uint32_t contentType = m_SANContent->m_contentType[sync];
|
//uint32_t contentType = m_SANContent->m_contentType[sync];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (const std::string &source: sources) {
|
for (const std::string &source: sources) {
|
||||||
boost::shared_ptr<const PersistentSyncSourceConfig> sourceConfig(context.getSyncSourceConfig(source));
|
std::shared_ptr<const PersistentSyncSourceConfig> sourceConfig(context.getSyncSourceConfig(source));
|
||||||
// prefix match because the local
|
// prefix match because the local
|
||||||
// configuration might contain
|
// configuration might contain
|
||||||
// additional parameters (like date
|
// additional parameters (like date
|
||||||
|
@ -630,20 +619,16 @@ void Connection::ready()
|
||||||
void Connection::activateTimeout()
|
void Connection::activateTimeout()
|
||||||
{
|
{
|
||||||
if (m_timeoutSeconds >= 0) {
|
if (m_timeoutSeconds >= 0) {
|
||||||
m_timeout.runOnce(m_timeoutSeconds,
|
auto timeoutCb = [this] () {
|
||||||
boost::bind(&Connection::timeoutCb,
|
SE_LOG_DEBUG(NULL, "Connection %s: timed out after %ds (state %s)",
|
||||||
this));
|
m_sessionID.c_str(), m_timeoutSeconds,
|
||||||
|
SessionCommon::ConnectionStateToString(m_state).c_str());
|
||||||
|
failed(StringPrintf("timed out after %ds", m_timeoutSeconds));
|
||||||
|
};
|
||||||
|
m_timeout.runOnce(m_timeoutSeconds, timeoutCb);
|
||||||
} else {
|
} else {
|
||||||
m_timeout.deactivate();
|
m_timeout.deactivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::timeoutCb()
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "Connection %s: timed out after %ds (state %s)",
|
|
||||||
m_sessionID.c_str(), m_timeoutSeconds,
|
|
||||||
SessionCommon::ConnectionStateToString(m_state).c_str());
|
|
||||||
failed(StringPrintf("timed out after %ds", m_timeoutSeconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -47,11 +47,10 @@ class Session;
|
||||||
* this means the Session has to abort, unless reconnecting is
|
* this means the Session has to abort, unless reconnecting is
|
||||||
* supported.
|
* supported.
|
||||||
*/
|
*/
|
||||||
class Connection : public GDBusCXX::DBusObjectHelper, public Resource
|
class Connection : public GDBusCXX::DBusObjectHelper, public Resource, public enable_weak_from_this<Connection>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Server &m_server;
|
Server &m_server;
|
||||||
boost::weak_ptr<Connection> m_me;
|
|
||||||
StringMap m_peer;
|
StringMap m_peer;
|
||||||
bool m_mustAuthenticate;
|
bool m_mustAuthenticate;
|
||||||
SessionCommon::ConnectionState m_state;
|
SessionCommon::ConnectionState m_state;
|
||||||
|
@ -63,7 +62,7 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
|
||||||
SessionCommon::SourceModes_t m_sourceModes;
|
SessionCommon::SourceModes_t m_sourceModes;
|
||||||
|
|
||||||
const std::string m_sessionID;
|
const std::string m_sessionID;
|
||||||
boost::shared_ptr<Session> m_session;
|
std::shared_ptr<Session> m_session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the timeout in seconds. -1 and thus "no timeout" by default.
|
* Defines the timeout in seconds. -1 and thus "no timeout" by default.
|
||||||
|
@ -75,7 +74,6 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
|
||||||
int m_timeoutSeconds;
|
int m_timeoutSeconds;
|
||||||
Timeout m_timeout;
|
Timeout m_timeout;
|
||||||
void activateTimeout();
|
void activateTimeout();
|
||||||
void timeoutCb();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer for received data, waiting here for engine to ask
|
* buffer for received data, waiting here for engine to ask
|
||||||
|
@ -94,7 +92,7 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
|
||||||
* The content of a parsed SAN package to be processed via
|
* The content of a parsed SAN package to be processed via
|
||||||
* connection.ready
|
* connection.ready
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr <SANContent> m_SANContent;
|
std::shared_ptr <SANContent> m_SANContent;
|
||||||
std::string m_peerBtAddr;
|
std::string m_peerBtAddr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,13 +135,8 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const std::string m_description;
|
const std::string m_description;
|
||||||
|
// Construct via make_weak_shared.
|
||||||
static boost::shared_ptr<Connection> createConnection(Server &server,
|
friend make_weak_shared;
|
||||||
const GDBusCXX::DBusConnectionPtr &conn,
|
|
||||||
const std::string &session_num,
|
|
||||||
const StringMap &peer,
|
|
||||||
bool must_authenticate);
|
|
||||||
|
|
||||||
~Connection();
|
~Connection();
|
||||||
|
|
||||||
/** session requested by us is ready to run a sync */
|
/** session requested by us is ready to run a sync */
|
||||||
|
|
|
@ -38,14 +38,8 @@ ConnmanClient::ConnmanClient(Server &server):
|
||||||
if (getConnection()) {
|
if (getConnection()) {
|
||||||
typedef std::map <std::string, boost::variant<std::string> > PropDict;
|
typedef std::map <std::string, boost::variant<std::string> > PropDict;
|
||||||
GDBusCXX::DBusClientCall<PropDict> getProp(*this,"GetProperties");
|
GDBusCXX::DBusClientCall<PropDict> getProp(*this,"GetProperties");
|
||||||
getProp.start(boost::bind(&ConnmanClient::getPropCb, this, _1, _2));
|
|
||||||
m_propertyChanged.activate(boost::bind(&ConnmanClient::propertyChanged, this, _1, _2));
|
|
||||||
}else{
|
|
||||||
SE_LOG_DEBUG(NULL, "DBus connection setup for connman failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnmanClient::getPropCb (const std::map <std::string,
|
auto getPropCb = [this] (const std::map <std::string,
|
||||||
boost::variant<std::string> >& props, const string &error) {
|
boost::variant<std::string> >& props, const string &error) {
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
m_available = false;
|
m_available = false;
|
||||||
|
@ -74,16 +68,21 @@ void ConnmanClient::getPropCb (const std::map <std::string,
|
||||||
|
|
||||||
//now delivering the signals
|
//now delivering the signals
|
||||||
m_server.getPresenceStatus().updatePresenceStatus (httpPresence, PresenceStatus::HTTP_TRANSPORT);
|
m_server.getPresenceStatus().updatePresenceStatus (httpPresence, PresenceStatus::HTTP_TRANSPORT);
|
||||||
}
|
};
|
||||||
|
getProp.start(getPropCb);
|
||||||
|
|
||||||
void ConnmanClient::propertyChanged(const std::string &name,
|
auto propertyChanged = [this] (const std::string &name,
|
||||||
const boost::variant<std::vector<std::string>, std::string> &prop)
|
const boost::variant<std::vector<std::string>, std::string> &prop) {
|
||||||
{
|
|
||||||
if (name == "State") {
|
if (name == "State") {
|
||||||
std::string state = boost::get<std::string>(prop);
|
std::string state = boost::get<std::string>(prop);
|
||||||
m_server.getPresenceStatus().updatePresenceStatus(state == "online",
|
m_server.getPresenceStatus().updatePresenceStatus(state == "online",
|
||||||
PresenceStatus::HTTP_TRANSPORT);
|
PresenceStatus::HTTP_TRANSPORT);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
m_propertyChanged.activate(propertyChanged);
|
||||||
|
}else{
|
||||||
|
SE_LOG_DEBUG(NULL, "DBus connection setup for connman failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -39,11 +39,6 @@ class ConnmanClient : public GDBusCXX::DBusRemoteObject
|
||||||
public:
|
public:
|
||||||
ConnmanClient (Server &server);
|
ConnmanClient (Server &server);
|
||||||
|
|
||||||
void propertyChanged(const std::string &name,
|
|
||||||
const boost::variant<std::vector<std::string>, std::string> &prop);
|
|
||||||
|
|
||||||
void getPropCb(const std::map <std::string, boost::variant<std::string> >& props, const std::string &error);
|
|
||||||
|
|
||||||
/** TRUE if watching ConnMan status */
|
/** TRUE if watching ConnMan status */
|
||||||
bool isAvailable() { return m_available; }
|
bool isAvailable() { return m_available; }
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result)
|
uint32_t dbusErrorCallback(const std::shared_ptr<GDBusCXX::ResultBase> &result)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// If there is no pending exception, the process will abort
|
// If there is no pending exception, the process will abort
|
||||||
|
@ -52,9 +52,9 @@ uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCb_t createDBusErrorCb(const boost::shared_ptr<GDBusCXX::ResultBase> &result)
|
ErrorCb_t createDBusErrorCb(const std::shared_ptr<GDBusCXX::ResultBase> &result)
|
||||||
{
|
{
|
||||||
return boost::bind(dbusErrorCallback, result);
|
return [result] () { dbusErrorCallback(result); };
|
||||||
}
|
}
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -20,16 +20,14 @@
|
||||||
#ifndef INCL_DBUS_CALLBACKS
|
#ifndef INCL_DBUS_CALLBACKS
|
||||||
#define INCL_DBUS_CALLBACKS
|
#define INCL_DBUS_CALLBACKS
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
#include <boost/function.hpp>
|
#include <functional>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <gdbus-cxx-bridge.h>
|
#include <gdbus-cxx-bridge.h>
|
||||||
|
|
||||||
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +60,7 @@ SE_BEGIN_CXX
|
||||||
* It is the responsibility of the caller to ensure that any objects
|
* It is the responsibility of the caller to ensure that any objects
|
||||||
* bound to the callback are still around when the callback gets
|
* bound to the callback are still around when the callback gets
|
||||||
* invoked. One simple way of doing that is via BoostHelper.h and
|
* invoked. One simple way of doing that is via BoostHelper.h and
|
||||||
* binding to a boost::weak_ptr that tracks the instance to which
|
* binding to a std::weak_ptr that tracks the instance to which
|
||||||
* the callback belongs.
|
* the callback belongs.
|
||||||
*
|
*
|
||||||
* The recommended naming is to use the "Async" suffix in the function
|
* The recommended naming is to use the "Async" suffix in the function
|
||||||
|
@ -76,16 +74,16 @@ SE_BEGIN_CXX
|
||||||
* relaying them to the D-Bus client. Example:
|
* relaying them to the D-Bus client. Example:
|
||||||
*
|
*
|
||||||
* void runOperationAsync(RunOperation op,
|
* void runOperationAsync(RunOperation op,
|
||||||
* const boost::shared_ptr< GDBusCXX::Result<> > &dbusResult,
|
* const std::shared_ptr< GDBusCXX::Result<> > &dbusResult,
|
||||||
* const SuccessCb_t &helperReady)
|
* const SuccessCb_t &helperReady)
|
||||||
* ...
|
* ...
|
||||||
* useHelperAsync(SimpleResult(helperReady,
|
* useHelperAsync(SimpleResult(helperReady,
|
||||||
* boost::bind(&Session::failureCb, this)));
|
* [this] () { failureCb(); } ));
|
||||||
*
|
*
|
||||||
* Session::failureCb() in this example then does some work on its own
|
* Session::failureCb() in this example then does some work on its own
|
||||||
* and finally calls dbusErrorCallback(dbusResult).
|
* and finally calls dbusErrorCallback(dbusResult).
|
||||||
*/
|
*/
|
||||||
typedef boost::function<void ()> ErrorCb_t;
|
typedef std::function<void ()> ErrorCb_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Because callbacks always come in pairs, the following
|
* Because callbacks always come in pairs, the following
|
||||||
|
@ -95,17 +93,17 @@ typedef boost::function<void ()> ErrorCb_t;
|
||||||
*/
|
*/
|
||||||
template <class P> class Result
|
template <class P> class Result
|
||||||
{
|
{
|
||||||
boost::function<P> m_onSuccess;
|
std::function<P> m_onSuccess;
|
||||||
ErrorCb_t m_onError;
|
ErrorCb_t m_onError;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Result(const boost::function<P> &onSuccess,
|
Result(const std::function<P> &onSuccess,
|
||||||
const ErrorCb_t &onError) :
|
const ErrorCb_t &onError) :
|
||||||
m_onSuccess(onSuccess),
|
m_onSuccess(onSuccess),
|
||||||
m_onError(onError)
|
m_onError(onError)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
boost::function<P> getOnSuccess() const { return m_onSuccess; }
|
std::function<P> getOnSuccess() const { return m_onSuccess; }
|
||||||
ErrorCb_t getOnError() const { return m_onError; }
|
ErrorCb_t getOnError() const { return m_onError; }
|
||||||
|
|
||||||
void done() const { if (m_onSuccess) m_onSuccess(); }
|
void done() const { if (m_onSuccess) m_onSuccess(); }
|
||||||
|
@ -121,7 +119,7 @@ template <class P> class Result
|
||||||
* and failure callbacks. Determines type automatically based on type
|
* and failure callbacks. Determines type automatically based on type
|
||||||
* of success callback.
|
* of success callback.
|
||||||
*/
|
*/
|
||||||
template <class P> Result<P> makeCb(const boost::function<P> &onSuccess,
|
template <class P> Result<P> makeCb(const std::function<P> &onSuccess,
|
||||||
const ErrorCb_t &onFailure)
|
const ErrorCb_t &onFailure)
|
||||||
{
|
{
|
||||||
return Result<P>(onSuccess, onFailure);
|
return Result<P>(onSuccess, onFailure);
|
||||||
|
@ -134,51 +132,25 @@ template <class P> Result<P> makeCb(const boost::function<P> &onSuccess,
|
||||||
* @param result failed() is called here
|
* @param result failed() is called here
|
||||||
* @return status code (see SyncML.h)
|
* @return status code (see SyncML.h)
|
||||||
*/
|
*/
|
||||||
uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result);
|
uint32_t dbusErrorCallback(const std::shared_ptr<GDBusCXX::ResultBase> &result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an error callback which can be used to return a pending
|
* Creates an error callback which can be used to return a pending
|
||||||
* exception as a D-Bus error. Template call which is parameterized
|
* exception as a D-Bus error. Template call which is parameterized
|
||||||
* with the GDBusCXX::Result* class that takes the error.
|
* with the GDBusCXX::Result* class that takes the error.
|
||||||
*/
|
*/
|
||||||
ErrorCb_t createDBusErrorCb(const boost::shared_ptr<GDBusCXX::ResultBase> &result);
|
ErrorCb_t createDBusErrorCb(const std::shared_ptr<GDBusCXX::ResultBase> &result);
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a result object which passes back results and turns
|
|
||||||
* exceptions into dbus_error instances with the given interface
|
|
||||||
* name.
|
|
||||||
* TODO: interface name
|
|
||||||
*/
|
|
||||||
template<class R1> Result<void (const R1 &)> createDBusCb(const boost::shared_ptr< GDBusCXX::Result<R1> > &result)
|
|
||||||
{
|
|
||||||
return Result<void (const R1 &)>(boost::bind(&GDBusCXX::Result<R1>::done,
|
|
||||||
result,
|
|
||||||
_1),
|
|
||||||
createDBusErrorCb(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a result object which passes back zero results and turns
|
|
||||||
* exceptions into dbus_error instances with the given interface name.
|
|
||||||
* TODO: interface name
|
|
||||||
*/
|
|
||||||
static inline Result<void ()> createDBusCb(const boost::shared_ptr< GDBusCXX::Result<> > &result)
|
|
||||||
{
|
|
||||||
return Result<void ()>(boost::bind(&GDBusCXX::Result<>::done,
|
|
||||||
result),
|
|
||||||
createDBusErrorCb(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a generic "operation successful" callback with no parameters
|
* a generic "operation successful" callback with no parameters
|
||||||
*/
|
*/
|
||||||
typedef boost::function<void ()> SuccessCb_t;
|
typedef std::function<void ()> SuccessCb_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic "operation completed/failed" result pair (no parameters
|
* A generic "operation completed/failed" result pair (no parameters
|
||||||
* for completion). Same as Result<void ()>, but because it doesn't
|
* for completion). Same as Result<void ()>, but because it doesn't
|
||||||
* have overloaded done() template methods the done method can be used
|
* have overloaded done() template methods the done method can be used
|
||||||
* in boost::bind().
|
* in std::bind().
|
||||||
*/
|
*/
|
||||||
class SimpleResult {
|
class SimpleResult {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -49,11 +49,15 @@ DBusSync::DBusSync(const SessionCommon::SyncParams ¶ms,
|
||||||
|
|
||||||
// Watch status of parent and our own process and cancel
|
// Watch status of parent and our own process and cancel
|
||||||
// any pending password request if parent or we go down.
|
// any pending password request if parent or we go down.
|
||||||
boost::shared_ptr<ForkExecChild> forkexec = m_helper.getForkExecChild();
|
auto forkexec = m_helper.getForkExecChild();
|
||||||
if (forkexec) {
|
if (forkexec) {
|
||||||
m_parentWatch = forkexec->m_onQuit.connect(boost::bind(&DBusSync::passwordResponse, this, true, false, ""));
|
m_parentWatch = forkexec->m_onQuit.connect([this] () { passwordResponse(true, false, ""); });
|
||||||
}
|
}
|
||||||
m_suspendFlagsWatch = SuspendFlags::getSuspendFlags().m_stateChanged.connect(boost::bind(&DBusSync::suspendFlagsChanged, this, _1));
|
m_suspendFlagsWatch = SuspendFlags::getSuspendFlags().m_stateChanged.connect([this] (SuspendFlags &flags) {
|
||||||
|
if (flags.getState() != SuspendFlags::NORMAL) {
|
||||||
|
passwordResponse(true, false, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Apply temporary config filters. The parameters of this function
|
// Apply temporary config filters. The parameters of this function
|
||||||
// override the source filters, if set.
|
// override the source filters, if set.
|
||||||
|
@ -97,7 +101,7 @@ DBusSync::DBusSync(const SessionCommon::SyncParams ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward the SourceSyncedSignal via D-Bus.
|
// Forward the SourceSyncedSignal via D-Bus.
|
||||||
m_sourceSyncedSignal.connect(boost::bind(m_helper.emitSourceSynced, _1, _2));
|
m_sourceSyncedSignal.connect([this] (const std::string &name, const SyncSourceReport &source) { m_helper.emitSourceSynced(name, source); });
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusSync::~DBusSync()
|
DBusSync::~DBusSync()
|
||||||
|
@ -106,21 +110,21 @@ DBusSync::~DBusSync()
|
||||||
m_suspendFlagsWatch.disconnect();
|
m_suspendFlagsWatch.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TransportAgent> DBusSync::createTransportAgent()
|
std::shared_ptr<TransportAgent> DBusSync::createTransportAgent()
|
||||||
{
|
{
|
||||||
if (m_params.m_serverAlerted || m_params.m_serverMode) {
|
if (m_params.m_serverAlerted || m_params.m_serverMode) {
|
||||||
// Use the D-Bus Connection to send and receive messages.
|
// Use the D-Bus Connection to send and receive messages.
|
||||||
boost::shared_ptr<DBusTransportAgent> agent(new DBusTransportAgent(m_helper));
|
auto agent = std::make_shared<DBusTransportAgent>(m_helper);
|
||||||
|
|
||||||
// Hook up agent with D-Bus in the helper. The agent may go
|
// Hook up agent with D-Bus in the helper. The agent may go
|
||||||
// away at any time, so use instance tracking.
|
// away at any time, so use instance tracking.
|
||||||
m_helper.m_messageSignal.connect(SessionHelper::MessageSignal_t::slot_type(&DBusTransportAgent::storeMessage,
|
m_helper.m_messageSignal.connect(SessionHelper::MessageSignal_t::slot_type(&DBusTransportAgent::storeMessage,
|
||||||
agent.get(),
|
agent.get(),
|
||||||
_1,
|
_1,
|
||||||
_2).track(agent));
|
_2).track_foreign(agent));
|
||||||
m_helper.m_connectionStateSignal.connect(SessionHelper::ConnectionStateSignal_t::slot_type(&DBusTransportAgent::storeState,
|
m_helper.m_connectionStateSignal.connect(SessionHelper::ConnectionStateSignal_t::slot_type(&DBusTransportAgent::storeState,
|
||||||
agent.get(),
|
agent.get(),
|
||||||
_1).track(agent));
|
_1).track_foreign(agent));
|
||||||
|
|
||||||
if (m_params.m_serverAlerted) {
|
if (m_params.m_serverAlerted) {
|
||||||
// A SAN message was sent to us, need to reply.
|
// A SAN message was sent to us, need to reply.
|
||||||
|
@ -132,11 +136,11 @@ boost::shared_ptr<TransportAgent> DBusSync::createTransportAgent()
|
||||||
m_params.m_initialMessageType);
|
m_params.m_initialMessageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return agent;
|
return std::static_pointer_cast<TransportAgent>(agent);
|
||||||
} else {
|
} else {
|
||||||
// no connection, use HTTP via libsoup/GMainLoop
|
// no connection, use HTTP via libsoup/GMainLoop
|
||||||
GMainLoop *loop = m_helper.getLoop();
|
GMainLoop *loop = m_helper.getLoop();
|
||||||
boost::shared_ptr<TransportAgent> agent = SyncContext::createTransportAgent(loop);
|
auto agent = SyncContext::createTransportAgent(loop);
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,10 +209,8 @@ string DBusSync::askPassword(const string &passwordName,
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
||||||
askPasswordAsync(passwordName, descr, key,
|
askPasswordAsync(passwordName, descr, key,
|
||||||
boost::bind(static_cast<std::string & (std::string::*)(const std::string &)>(&std::string::assign),
|
[&password] (const std::string &passwordArg) { password = passwordArg; },
|
||||||
&password, _1),
|
[&error] () { Exception::handle(error, HANDLE_EXCEPTION_NO_ERROR); });
|
||||||
boost::bind(static_cast<SyncMLStatus (*)(std::string &, HandleExceptionFlags)>(&Exception::handle),
|
|
||||||
boost::ref(error), HANDLE_EXCEPTION_NO_ERROR));
|
|
||||||
// We know that askPasswordAsync() is done when it cleared the
|
// We know that askPasswordAsync() is done when it cleared the
|
||||||
// callback functors.
|
// callback functors.
|
||||||
while (m_passwordSuccess) {
|
while (m_passwordSuccess) {
|
||||||
|
@ -224,12 +226,12 @@ string DBusSync::askPassword(const string &passwordName,
|
||||||
void DBusSync::askPasswordAsync(const std::string &passwordName,
|
void DBusSync::askPasswordAsync(const std::string &passwordName,
|
||||||
const std::string &descr,
|
const std::string &descr,
|
||||||
const ConfigPasswordKey &key,
|
const ConfigPasswordKey &key,
|
||||||
const boost::function<void (const std::string &)> &success,
|
const std::function<void (const std::string &)> &success,
|
||||||
const boost::function<void ()> &failureException)
|
const std::function<void ()> &failureException)
|
||||||
{
|
{
|
||||||
// cannot handle more than one password request at a time
|
// cannot handle more than one password request at a time
|
||||||
m_passwordSuccess.clear();
|
m_passwordSuccess = {};
|
||||||
m_passwordFailure.clear();
|
m_passwordFailure = {};
|
||||||
m_passwordDescr = descr;
|
m_passwordDescr = descr;
|
||||||
|
|
||||||
InitStateString password;
|
InitStateString password;
|
||||||
|
@ -260,16 +262,16 @@ void DBusSync::askPasswordAsync(const std::string &passwordName,
|
||||||
STATUS_PASSWORD_TIMEOUT);
|
STATUS_PASSWORD_TIMEOUT);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_passwordSuccess.clear();
|
m_passwordSuccess = {};
|
||||||
m_passwordFailure.clear();
|
m_passwordFailure = {};
|
||||||
failureException();
|
failureException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &password)
|
void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &password)
|
||||||
{
|
{
|
||||||
boost::function<void (const std::string &)> success;
|
std::function<void (const std::string &)> success;
|
||||||
boost::function<void ()> failureException;
|
std::function<void ()> failureException;
|
||||||
|
|
||||||
std::swap(success, m_passwordSuccess);
|
std::swap(success, m_passwordSuccess);
|
||||||
std::swap(failureException, m_passwordFailure);
|
std::swap(failureException, m_passwordFailure);
|
||||||
|
@ -300,13 +302,6 @@ void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBusSync::suspendFlagsChanged(SuspendFlags &flags)
|
|
||||||
{
|
|
||||||
if (flags.getState() != SuspendFlags::NORMAL) {
|
|
||||||
passwordResponse(true, false, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DBusSync::savePassword(const std::string &passwordName,
|
bool DBusSync::savePassword(const std::string &passwordName,
|
||||||
const std::string &password,
|
const std::string &password,
|
||||||
const ConfigPasswordKey &key)
|
const ConfigPasswordKey &key)
|
||||||
|
|
|
@ -48,14 +48,12 @@ class DBusSync : public SyncContext, private UserInterface
|
||||||
SessionHelper &m_helper;
|
SessionHelper &m_helper;
|
||||||
SessionCommon::SyncParams m_params;
|
SessionCommon::SyncParams m_params;
|
||||||
bool m_waiting;
|
bool m_waiting;
|
||||||
boost::function<void (const std::string &)> m_passwordSuccess;
|
std::function<void (const std::string &)> m_passwordSuccess;
|
||||||
boost::function<void ()> m_passwordFailure;
|
std::function<void ()> m_passwordFailure;
|
||||||
std::string m_passwordDescr;
|
std::string m_passwordDescr;
|
||||||
boost::signals2::connection m_parentWatch;
|
boost::signals2::connection m_parentWatch;
|
||||||
boost::signals2::connection m_suspendFlagsWatch;
|
boost::signals2::connection m_suspendFlagsWatch;
|
||||||
|
|
||||||
void suspendFlagsChanged(SuspendFlags &flags);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DBusSync(const SessionCommon::SyncParams ¶ms,
|
DBusSync(const SessionCommon::SyncParams ¶ms,
|
||||||
SessionHelper &helper);
|
SessionHelper &helper);
|
||||||
|
@ -65,7 +63,7 @@ public:
|
||||||
void passwordResponse(bool timedOut, bool aborted, const std::string &password);
|
void passwordResponse(bool timedOut, bool aborted, const std::string &password);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual boost::shared_ptr<TransportAgent> createTransportAgent();
|
virtual std::shared_ptr<TransportAgent> createTransportAgent();
|
||||||
virtual void displaySyncProgress(sysync::TProgressEventEnum type,
|
virtual void displaySyncProgress(sysync::TProgressEventEnum type,
|
||||||
int32_t extra1, int32_t extra2, int32_t extra3);
|
int32_t extra1, int32_t extra2, int32_t extra3);
|
||||||
virtual bool displaySourceProgress(SyncSource &source,
|
virtual bool displaySourceProgress(SyncSource &source,
|
||||||
|
@ -79,8 +77,8 @@ protected:
|
||||||
virtual void askPasswordAsync(const std::string &passwordName,
|
virtual void askPasswordAsync(const std::string &passwordName,
|
||||||
const std::string &descr,
|
const std::string &descr,
|
||||||
const ConfigPasswordKey &key,
|
const ConfigPasswordKey &key,
|
||||||
const boost::function<void (const std::string &)> &success,
|
const std::function<void (const std::string &)> &success,
|
||||||
const boost::function<void ()> &failureException);
|
const std::function<void ()> &failureException);
|
||||||
|
|
||||||
virtual bool savePassword(const std::string &passwordName,
|
virtual bool savePassword(const std::string &passwordName,
|
||||||
const std::string &password,
|
const std::string &password,
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <syncevo/TransportAgent.h>
|
#include <syncevo/TransportAgent.h>
|
||||||
#include <syncevo/SmartPtr.h>
|
#include <syncevo/SmartPtr.h>
|
||||||
#include <syncevo/SynthesisEngine.h>
|
#include <syncevo/SynthesisEngine.h>
|
||||||
#include <boost/weak_ptr.hpp>
|
|
||||||
|
|
||||||
#include <gdbus-cxx-bridge.h>
|
#include <gdbus-cxx-bridge.h>
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ InfoReq::InfoReq(Server &server,
|
||||||
m_param(parameters)
|
m_param(parameters)
|
||||||
{
|
{
|
||||||
m_server.emitInfoReq(*this);
|
m_server.emitInfoReq(*this);
|
||||||
m_timeout.runOnce(m_timeoutSeconds, boost::bind(boost::ref(m_timeoutSignal)));
|
m_timeout.runOnce(m_timeoutSeconds, [this] () { m_timeoutSignal(); });
|
||||||
m_param.clear();
|
m_param.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ void InfoReq::setResponse(const Caller_t &caller, const string &state, const Inf
|
||||||
m_infoState = IN_WAIT;
|
m_infoState = IN_WAIT;
|
||||||
m_server.emitInfoReq(*this);
|
m_server.emitInfoReq(*this);
|
||||||
//reset the timer, used to check timeout
|
//reset the timer, used to check timeout
|
||||||
m_timeout.runOnce(m_timeoutSeconds, boost::bind(boost::ref(m_timeoutSignal)));
|
m_timeout.runOnce(m_timeoutSeconds, [this] () { m_timeoutSignal(); });
|
||||||
} else if ((m_infoState == IN_WAIT || m_infoState == IN_REQ) && state == "response") {
|
} else if ((m_infoState == IN_WAIT || m_infoState == IN_REQ) && state == "response") {
|
||||||
m_response = response;
|
m_response = response;
|
||||||
m_handler = caller;
|
m_handler = caller;
|
||||||
|
|
|
@ -74,20 +74,24 @@ LocaledListener::LocaledListener():
|
||||||
m_propertiesGet(*this, PROPERTIES_GET)
|
m_propertiesGet(*this, PROPERTIES_GET)
|
||||||
{
|
{
|
||||||
if (getConnection()) {
|
if (getConnection()) {
|
||||||
m_propertiesChanged.activate(boost::bind(&LocaledListener::onPropertiesChange, this, _1, _2, _3));
|
auto change = [this] (const std::string &interface,
|
||||||
|
const Properties &properties,
|
||||||
|
const Invalidated &invalidated) {
|
||||||
|
onPropertiesChange(interface, properties, invalidated);
|
||||||
|
};
|
||||||
|
m_propertiesChanged.activate(change);
|
||||||
} else {
|
} else {
|
||||||
SE_LOG_DEBUG(NULL, "localed: not activating, no connection");
|
SE_LOG_DEBUG(NULL, "localed: not activating, no connection");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<LocaledListener> LocaledListener::create()
|
std::shared_ptr<LocaledListener> LocaledListener::create()
|
||||||
{
|
{
|
||||||
static boost::weak_ptr<LocaledListener> singleton;
|
static std::weak_ptr<LocaledListener> singleton;
|
||||||
boost::shared_ptr<LocaledListener> self = singleton.lock();
|
std::shared_ptr<LocaledListener> self = singleton.lock();
|
||||||
if (!self) {
|
if (!self) {
|
||||||
self.reset(new LocaledListener());
|
self.reset(new LocaledListener());
|
||||||
self->m_self = self;
|
|
||||||
singleton = self;
|
singleton = self;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -98,7 +102,12 @@ void LocaledListener::onPropertiesChange(const std::string &interface,
|
||||||
const Invalidated &invalidated)
|
const Invalidated &invalidated)
|
||||||
{
|
{
|
||||||
if (interface == LOCALED_INTERFACE) {
|
if (interface == LOCALED_INTERFACE) {
|
||||||
boost::function<void (const LocaleEnv &env)> result(boost::bind(&LocaledListener::emitLocaleEnv, m_self, _1));
|
auto result = [self=weak_from_this()] (const LocaleEnv &env) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
if (lock) {
|
||||||
|
lock->emitLocaleEnv(env);
|
||||||
|
}
|
||||||
|
};
|
||||||
for (const auto &entry: properties) {
|
for (const auto &entry: properties) {
|
||||||
if (entry.first == LOCALED_LOCALE_PROPERTY) {
|
if (entry.first == LOCALED_LOCALE_PROPERTY) {
|
||||||
const LocaleEnv *locale = boost::get<LocaleEnv>(&entry.second);
|
const LocaleEnv *locale = boost::get<LocaleEnv>(&entry.second);
|
||||||
|
@ -115,9 +124,12 @@ void LocaledListener::onPropertiesChange(const std::string &interface,
|
||||||
invalidated.end(),
|
invalidated.end(),
|
||||||
LOCALED_LOCALE_PROPERTY) != invalidated.end()) {
|
LOCALED_LOCALE_PROPERTY) != invalidated.end()) {
|
||||||
SE_LOG_DEBUG(NULL, "localed: Locale changed, need to get new value");
|
SE_LOG_DEBUG(NULL, "localed: Locale changed, need to get new value");
|
||||||
m_propertiesGet.start(boost::bind(&LocaledListener::processLocaleProperty, m_self,
|
m_propertiesGet.start([self=weak_from_this(), result] (const LocaleVariant &variant, const std::string &error) {
|
||||||
_1, _2, false,
|
auto lock = self.lock();
|
||||||
result),
|
if (lock) {
|
||||||
|
lock->processLocaleProperty(variant, error, false, result);
|
||||||
|
}
|
||||||
|
},
|
||||||
std::string(LOCALED_INTERFACE),
|
std::string(LOCALED_INTERFACE),
|
||||||
std::string(LOCALED_LOCALE_PROPERTY));
|
std::string(LOCALED_LOCALE_PROPERTY));
|
||||||
}
|
}
|
||||||
|
@ -158,11 +170,16 @@ void LocaledListener::emitLocaleEnv(const LocaleEnv &env)
|
||||||
m_localeValues(env);
|
m_localeValues(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocaledListener::check(const boost::function<void (const LocaleEnv &env)> &result)
|
void LocaledListener::check(const std::function<void (const LocaleEnv &env)> &result)
|
||||||
{
|
{
|
||||||
if (getConnection()) {
|
if (getConnection()) {
|
||||||
SE_LOG_DEBUG(NULL, "localed: get current Locale property");
|
SE_LOG_DEBUG(NULL, "localed: get current Locale property");
|
||||||
m_propertiesGet.start(boost::bind(&LocaledListener::processLocaleProperty, m_self, _1, _2, true, result),
|
m_propertiesGet.start([self=weak_from_this(), result] (const LocaleVariant &variant, const std::string &error) {
|
||||||
|
auto lock = self.lock();
|
||||||
|
if (lock) {
|
||||||
|
lock->processLocaleProperty(variant, error, true, result);
|
||||||
|
}
|
||||||
|
},
|
||||||
std::string(LOCALED_INTERFACE),
|
std::string(LOCALED_INTERFACE),
|
||||||
std::string(LOCALED_LOCALE_PROPERTY));
|
std::string(LOCALED_LOCALE_PROPERTY));
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,8 +193,8 @@ void LocaledListener::setLocale(const LocaleEnv &locale)
|
||||||
for (const char *name: LOCALED_ENV_VARS) {
|
for (const char *name: LOCALED_ENV_VARS) {
|
||||||
const char *value = getenv(name);
|
const char *value = getenv(name);
|
||||||
std::string assignment = StringPrintf("%s=", name);
|
std::string assignment = StringPrintf("%s=", name);
|
||||||
LocaleEnv::const_iterator instance = std::find_if(locale.begin(), locale.end(),
|
auto instance = std::find_if(locale.begin(), locale.end(),
|
||||||
boost::bind(boost::starts_with<std::string, std::string>, _1, name));
|
[&name] (const std::string &l) { return boost::starts_with(l, name); });
|
||||||
const char *newvalue = instance != locale.end() ? instance->c_str() + assignment.size() : NULL;
|
const char *newvalue = instance != locale.end() ? instance->c_str() + assignment.size() : NULL;
|
||||||
if ((value && newvalue && strcmp(value, newvalue)) ||
|
if ((value && newvalue && strcmp(value, newvalue)) ||
|
||||||
(!value && newvalue)) {
|
(!value && newvalue)) {
|
||||||
|
|
|
@ -22,8 +22,10 @@
|
||||||
|
|
||||||
#include <gdbus-cxx-bridge.h>
|
#include <gdbus-cxx-bridge.h>
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/weak_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -31,14 +33,14 @@ SE_BEGIN_CXX
|
||||||
/**
|
/**
|
||||||
* The D-Bus binding for http://www.freedesktop.org/wiki/Software/systemd/localed/
|
* The D-Bus binding for http://www.freedesktop.org/wiki/Software/systemd/localed/
|
||||||
*/
|
*/
|
||||||
class LocaledListener : public GDBusCXX::DBusRemoteObject
|
class LocaledListener : public GDBusCXX::DBusRemoteObject, public enable_weak_from_this<LocaledListener>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Singleton - at most one instance of LocaledListener will exist.
|
* Singleton - at most one instance of LocaledListener will exist.
|
||||||
* It lives as long as one of the create() callers keeps the reference.
|
* It lives as long as one of the create() callers keeps the reference.
|
||||||
*/
|
*/
|
||||||
static boost::shared_ptr<LocaledListener> create();
|
static std::shared_ptr<LocaledListener> create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* array of var=value, for example LANG, LC_NUMERIC, etc.
|
* array of var=value, for example LANG, LC_NUMERIC, etc.
|
||||||
|
@ -56,7 +58,7 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
|
||||||
* either with the current settings from localed or, if
|
* either with the current settings from localed or, if
|
||||||
* retrieving those fails, with the current environment.
|
* retrieving those fails, with the current environment.
|
||||||
*/
|
*/
|
||||||
void check(const boost::function<void (const LocaleEnv &env)> &result);
|
void check(const std::function<void (const LocaleEnv &env)> &result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates current environment to match the one in the parameter.
|
* Updates current environment to match the one in the parameter.
|
||||||
|
@ -81,7 +83,6 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
|
||||||
LocaleChangedSignal m_localeChanged;
|
LocaleChangedSignal m_localeChanged;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::weak_ptr<LocaledListener> m_self;
|
|
||||||
typedef boost::variant<LocaleEnv> LocaleVariant;
|
typedef boost::variant<LocaleEnv> LocaleVariant;
|
||||||
typedef std::map<std::string, LocaleVariant> Properties;
|
typedef std::map<std::string, LocaleVariant> Properties;
|
||||||
typedef std::vector<std::string> Invalidated;
|
typedef std::vector<std::string> Invalidated;
|
||||||
|
@ -92,7 +93,7 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
|
||||||
void onPropertiesChange(const std::string &interface,
|
void onPropertiesChange(const std::string &interface,
|
||||||
const Properties &properties,
|
const Properties &properties,
|
||||||
const Invalidated &invalidated);
|
const Invalidated &invalidated);
|
||||||
typedef boost::function<void (const LocaleEnv &env)> ProcessLocalePropCB_t;
|
typedef std::function<void (const LocaleEnv &env)> ProcessLocalePropCB_t;
|
||||||
void processLocaleProperty(const LocaleVariant &locale,
|
void processLocaleProperty(const LocaleVariant &locale,
|
||||||
const std::string &error,
|
const std::string &error,
|
||||||
bool mustCall,
|
bool mustCall,
|
||||||
|
|
|
@ -79,7 +79,7 @@ static Logger::Level checkLogLevel(const char *option, int logLevel)
|
||||||
int main(int argc, char **argv, char **envp)
|
int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
// remember environment for restart
|
// remember environment for restart
|
||||||
boost::shared_ptr<Restart> restart;
|
std::shared_ptr<Restart> restart;
|
||||||
restart.reset(new Restart(argv, envp));
|
restart.reset(new Restart(argv, envp));
|
||||||
|
|
||||||
// Internationalization for auto sync messages.
|
// Internationalization for auto sync messages.
|
||||||
|
@ -212,7 +212,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
// process name for developers in this process, and not in
|
// process name for developers in this process, and not in
|
||||||
// syncevo-dbus-helper.
|
// syncevo-dbus-helper.
|
||||||
Logger::setProcessName("syncevo-dbus-server");
|
Logger::setProcessName("syncevo-dbus-server");
|
||||||
boost::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
|
std::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
|
||||||
|
|
||||||
DBusErrorCXX err;
|
DBusErrorCXX err;
|
||||||
DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
|
DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
|
||||||
|
@ -225,12 +225,12 @@ int main(int argc, char **argv, char **envp)
|
||||||
// make this object the main owner of the connection
|
// make this object the main owner of the connection
|
||||||
boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
|
boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
|
||||||
|
|
||||||
boost::shared_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, restart, conn, duration));
|
auto server = std::make_shared<SyncEvo::Server>(loop, restart, conn, duration);
|
||||||
server->setDBusLogLevel(levelDBus);
|
server->setDBusLogLevel(levelDBus);
|
||||||
server->activate();
|
server->activate();
|
||||||
|
|
||||||
#ifdef ENABLE_DBUS_PIM
|
#ifdef ENABLE_DBUS_PIM
|
||||||
boost::shared_ptr<GDBusCXX::DBusObjectHelper> manager(SyncEvo::CreateContactManager(server, startPIM));
|
std::shared_ptr<GDBusCXX::DBusObjectHelper> manager(SyncEvo::CreateContactManager(server, startPIM));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gdbus) {
|
if (gdbus) {
|
||||||
|
|
|
@ -42,9 +42,7 @@ NetworkManagerClient::NetworkManagerClient(Server &server) :
|
||||||
{
|
{
|
||||||
if (getConnection()) {
|
if (getConnection()) {
|
||||||
m_properties.get();
|
m_properties.get();
|
||||||
m_stateChanged.activate(boost::bind(
|
m_stateChanged.activate([this] (uint32_t uiState) { stateChanged(uiState); });
|
||||||
&NetworkManagerClient::stateChanged,
|
|
||||||
this, _1));
|
|
||||||
} else {
|
} else {
|
||||||
SE_LOG_DEBUG(NULL,
|
SE_LOG_DEBUG(NULL,
|
||||||
"DBus connection setup for NetworkManager failed");
|
"DBus connection setup for NetworkManager failed");
|
||||||
|
@ -86,14 +84,8 @@ NetworkManagerClient::NetworkManagerProperties::NetworkManagerProperties(
|
||||||
void NetworkManagerClient::NetworkManagerProperties::get()
|
void NetworkManagerClient::NetworkManagerProperties::get()
|
||||||
{
|
{
|
||||||
GDBusCXX::DBusClientCall<boost::variant<uint32_t, std::string> > get(*this, "Get");
|
GDBusCXX::DBusClientCall<boost::variant<uint32_t, std::string> > get(*this, "Get");
|
||||||
get.start(boost::bind(&NetworkManagerProperties::getCallback, this, _1, _2),
|
auto callback = [this] (const boost::variant<uint32_t, std::string> &prop,
|
||||||
std::string(m_manager.getInterface()), std::string("State"));
|
const std::string &error) {
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkManagerClient::NetworkManagerProperties::getCallback(
|
|
||||||
const boost::variant<uint32_t, std::string> &prop,
|
|
||||||
const std::string &error)
|
|
||||||
{
|
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
SE_LOG_DEBUG(NULL, "Error in calling Get of Interface org.freedesktop.DBus.Properties : %s", error.c_str());
|
SE_LOG_DEBUG(NULL, "Error in calling Get of Interface org.freedesktop.DBus.Properties : %s", error.c_str());
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,6 +93,8 @@ void NetworkManagerClient::NetworkManagerProperties::getCallback(
|
||||||
m_manager.m_available = true;
|
m_manager.m_available = true;
|
||||||
m_manager.stateChanged(boost::get<uint32_t>(prop));
|
m_manager.stateChanged(boost::get<uint32_t>(prop));
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
get.start(callback, std::string(m_manager.getInterface()), std::string("State"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -74,8 +74,6 @@ private:
|
||||||
NetworkManagerProperties(NetworkManagerClient& manager);
|
NetworkManagerProperties(NetworkManagerClient& manager);
|
||||||
|
|
||||||
void get();
|
void get();
|
||||||
void getCallback(const boost::variant<uint32_t, std::string> &prop,
|
|
||||||
const std::string &error);
|
|
||||||
private:
|
private:
|
||||||
NetworkManagerClient &m_manager;
|
NetworkManagerClient &m_manager;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,9 +30,9 @@ SE_BEGIN_CXX
|
||||||
|
|
||||||
#define SYNC_UI_PATH "/usr/bin/sync-ui"
|
#define SYNC_UI_PATH "/usr/bin/sync-ui"
|
||||||
|
|
||||||
boost::shared_ptr<NotificationManagerBase> NotificationManagerFactory::createManager()
|
std::shared_ptr<NotificationManagerBase> NotificationManagerFactory::createManager()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<NotificationManagerBase> mgr;
|
std::shared_ptr<NotificationManagerBase> mgr;
|
||||||
|
|
||||||
/* Detect what kind of manager we need: if /usr/bin/sync-ui
|
/* Detect what kind of manager we need: if /usr/bin/sync-ui
|
||||||
* doesn't exists, we shall use the MLite backend; otherwise, if
|
* doesn't exists, we shall use the MLite backend; otherwise, if
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "syncevo/declarations.h"
|
#include "syncevo/declarations.h"
|
||||||
#include "notification-manager.h"
|
#include "notification-manager.h"
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class NotificationManagerFactory {
|
||||||
* Note: NotificationManagerFactory does not take ownership of
|
* Note: NotificationManagerFactory does not take ownership of
|
||||||
* the returned pointer: the user must delete it when done.
|
* the returned pointer: the user must delete it when done.
|
||||||
*/
|
*/
|
||||||
static boost::shared_ptr<NotificationManagerBase> createManager();
|
static std::shared_ptr<NotificationManagerBase> createManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -76,13 +76,13 @@ void ReadOperations::getConfigs(bool getTemplates, std::vector<std::string> &con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<SyncConfig> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
|
std::shared_ptr<SyncConfig> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
|
||||||
{
|
{
|
||||||
string peer, context;
|
string peer, context;
|
||||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
|
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
|
||||||
peer, context);
|
peer, context);
|
||||||
|
|
||||||
boost::shared_ptr<SyncConfig> syncConfig(new SyncConfig(configName));
|
auto syncConfig = std::make_shared<SyncConfig>(configName);
|
||||||
|
|
||||||
/** if config was not set temporarily */
|
/** if config was not set temporarily */
|
||||||
if (!setFilters(*syncConfig)) {
|
if (!setFilters(*syncConfig)) {
|
||||||
|
@ -108,14 +108,14 @@ void ReadOperations::getNamedConfig(const std::string &configName,
|
||||||
Config_t &config)
|
Config_t &config)
|
||||||
{
|
{
|
||||||
map<string, string> localConfigs;
|
map<string, string> localConfigs;
|
||||||
boost::shared_ptr<SyncConfig> dbusConfig;
|
std::shared_ptr<SyncConfig> dbusConfig;
|
||||||
SyncConfig *syncConfig;
|
SyncConfig *syncConfig;
|
||||||
string syncURL;
|
string syncURL;
|
||||||
/** get server template */
|
/** get server template */
|
||||||
if(getTemplate) {
|
if(getTemplate) {
|
||||||
string peer, context;
|
string peer, context;
|
||||||
|
|
||||||
boost::shared_ptr<SyncConfig::TemplateDescription> peerTemplate =
|
std::shared_ptr<SyncConfig::TemplateDescription> peerTemplate =
|
||||||
m_server.getPeerTempl(configName);
|
m_server.getPeerTempl(configName);
|
||||||
if(peerTemplate) {
|
if(peerTemplate) {
|
||||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId),
|
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId),
|
||||||
|
@ -157,7 +157,7 @@ void ReadOperations::getNamedConfig(const std::string &configName,
|
||||||
|
|
||||||
// use the shared properties from the right context as filter
|
// use the shared properties from the right context as filter
|
||||||
// so that the returned template preserves existing properties
|
// so that the returned template preserves existing properties
|
||||||
boost::shared_ptr<SyncConfig> shared = getLocalConfig(string("@") + context, false);
|
std::shared_ptr<SyncConfig> shared = getLocalConfig(string("@") + context, false);
|
||||||
|
|
||||||
ConfigProps props;
|
ConfigProps props;
|
||||||
shared->getProperties()->readProperties(props);
|
shared->getProperties()->readProperties(props);
|
||||||
|
@ -252,7 +252,7 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
|
||||||
SyncReport report;
|
SyncReport report;
|
||||||
// peerName is also extracted from the dir
|
// peerName is also extracted from the dir
|
||||||
string peerName = client.readSessionInfo(dir,report);
|
string peerName = client.readSessionInfo(dir,report);
|
||||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
auto config = std::make_shared<SyncConfig>(m_configName);
|
||||||
string storedPeerName = config->getPeerName();
|
string storedPeerName = config->getPeerName();
|
||||||
//if can't find peer name, use the peer name from the log dir
|
//if can't find peer name, use the peer name from the log dir
|
||||||
if(!storedPeerName.empty()) {
|
if(!storedPeerName.empty()) {
|
||||||
|
@ -278,7 +278,7 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
|
||||||
|
|
||||||
void ReadOperations::checkSource(const std::string &sourceName)
|
void ReadOperations::checkSource(const std::string &sourceName)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
auto config = std::make_shared<SyncConfig>(m_configName);
|
||||||
setFilters(*config);
|
setFilters(*config);
|
||||||
|
|
||||||
list<std::string> sourceNames = config->getSyncSources();
|
list<std::string> sourceNames = config->getSyncSources();
|
||||||
|
@ -312,7 +312,7 @@ void ReadOperations::checkSource(const std::string &sourceName)
|
||||||
}
|
}
|
||||||
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
|
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
auto config = std::make_shared<SyncConfig>(m_configName);
|
||||||
setFilters(*config);
|
setFilters(*config);
|
||||||
|
|
||||||
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
||||||
|
|
|
@ -91,7 +91,7 @@ private:
|
||||||
* - configName = @default (considered always available)
|
* - configName = @default (considered always available)
|
||||||
* - mustExist = false (used when reading a templates for a context which might not exist yet)
|
* - mustExist = false (used when reading a templates for a context which might not exist yet)
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<SyncConfig> getLocalConfig(const std::string &configName, bool mustExist = true);
|
std::shared_ptr<SyncConfig> getLocalConfig(const std::string &configName, bool mustExist = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
|
|
||||||
#include <syncevo/GLibSupport.h>
|
#include <syncevo/GLibSupport.h>
|
||||||
#include <syncevo/timeout.h>
|
#include <syncevo/timeout.h>
|
||||||
|
|
||||||
|
@ -43,25 +41,15 @@ using namespace GDBusCXX;
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
void Server::onIdleChange(bool idle)
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "server is %s", idle ? "idle" : "not idle");
|
|
||||||
if (idle) {
|
|
||||||
autoTermUnref();
|
|
||||||
} else {
|
|
||||||
autoTermRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ServerLogger : public Logger
|
class ServerLogger : public Logger
|
||||||
{
|
{
|
||||||
Logger::Handle m_parentLogger;
|
Logger::Handle m_parentLogger;
|
||||||
// Currently a strong reference. Would be a weak reference
|
// Currently a strong reference. Would be a weak reference
|
||||||
// if we had proper reference counting for Server.
|
// if we had proper reference counting for Server.
|
||||||
boost::shared_ptr<Server> m_server;
|
std::shared_ptr<Server> m_server;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ServerLogger(const boost::shared_ptr<Server> &server) :
|
ServerLogger(const std::shared_ptr<Server> &server) :
|
||||||
m_parentLogger(Logger::instance()),
|
m_parentLogger(Logger::instance()),
|
||||||
m_server(server)
|
m_server(server)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +63,7 @@ public:
|
||||||
// from holding onto the server while it tries to shut down.
|
// from holding onto the server while it tries to shut down.
|
||||||
//
|
//
|
||||||
// This is important because the server's live time is not
|
// This is important because the server's live time is not
|
||||||
// really controlled via the boost::shared_ptr, it may
|
// really controlled via the std::shared_ptr, it may
|
||||||
// destruct while there are still references. See
|
// destruct while there are still references. See
|
||||||
// Server::m_logger instantiation below.
|
// Server::m_logger instantiation below.
|
||||||
RecMutex::Guard guard = lock();
|
RecMutex::Guard guard = lock();
|
||||||
|
@ -191,16 +179,16 @@ StringMap Server::getVersions()
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::attachClient(const Caller_t &caller,
|
void Server::attachClient(const Caller_t &caller,
|
||||||
const boost::shared_ptr<Watch> &watch)
|
const std::shared_ptr<Watch> &watch)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client = addClient(caller, watch);
|
std::shared_ptr<Client> client = addClient(caller, watch);
|
||||||
autoTermRef();
|
autoTermRef();
|
||||||
client->increaseAttachCount();
|
client->increaseAttachCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::detachClient(const Caller_t &caller)
|
void Server::detachClient(const Caller_t &caller)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client = findClient(caller);
|
std::shared_ptr<Client> client = findClient(caller);
|
||||||
if (client) {
|
if (client) {
|
||||||
autoTermUnref();
|
autoTermUnref();
|
||||||
client->decreaseAttachCount();
|
client->decreaseAttachCount();
|
||||||
|
@ -211,7 +199,7 @@ void Server::setNotifications(bool enabled,
|
||||||
const Caller_t &caller,
|
const Caller_t &caller,
|
||||||
const string & /* notifications */)
|
const string & /* notifications */)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client = findClient(caller);
|
std::shared_ptr<Client> client = findClient(caller);
|
||||||
if (client && client->getAttachCount()) {
|
if (client && client->getAttachCount()) {
|
||||||
client->setNotificationsEnabled(enabled);
|
client->setNotificationsEnabled(enabled);
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,7 +220,7 @@ bool Server::notificationsEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::connect(const Caller_t &caller,
|
void Server::connect(const Caller_t &caller,
|
||||||
const boost::shared_ptr<Watch> &watch,
|
const std::shared_ptr<Watch> &watch,
|
||||||
const StringMap &peer,
|
const StringMap &peer,
|
||||||
bool must_authenticate,
|
bool must_authenticate,
|
||||||
const std::string &session,
|
const std::string &session,
|
||||||
|
@ -249,17 +237,17 @@ void Server::connect(const Caller_t &caller,
|
||||||
}
|
}
|
||||||
std::string new_session = getNextSession();
|
std::string new_session = getNextSession();
|
||||||
|
|
||||||
boost::shared_ptr<Connection> c(Connection::createConnection(*this,
|
auto c = make_weak_shared::make<Connection>(*this,
|
||||||
getConnection(),
|
getConnection(),
|
||||||
new_session,
|
new_session,
|
||||||
peer,
|
peer,
|
||||||
must_authenticate));
|
must_authenticate);
|
||||||
SE_LOG_DEBUG(NULL, "connecting D-Bus client %s with connection %s '%s'",
|
SE_LOG_DEBUG(NULL, "connecting D-Bus client %s with connection %s '%s'",
|
||||||
caller.c_str(),
|
caller.c_str(),
|
||||||
c->getPath(),
|
c->getPath(),
|
||||||
c->m_description.c_str());
|
c->m_description.c_str());
|
||||||
|
|
||||||
boost::shared_ptr<Client> client = addClient(caller,
|
std::shared_ptr<Client> client = addClient(caller,
|
||||||
watch);
|
watch);
|
||||||
client->attach(c);
|
client->attach(c);
|
||||||
c->activate();
|
c->activate();
|
||||||
|
@ -268,7 +256,7 @@ void Server::connect(const Caller_t &caller,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::startSessionWithFlags(const Caller_t &caller,
|
void Server::startSessionWithFlags(const Caller_t &caller,
|
||||||
const boost::shared_ptr<Watch> &watch,
|
const std::shared_ptr<Watch> &watch,
|
||||||
const std::string &server,
|
const std::string &server,
|
||||||
const std::vector<std::string> &flags,
|
const std::vector<std::string> &flags,
|
||||||
DBusObject_t &object)
|
DBusObject_t &object)
|
||||||
|
@ -278,10 +266,10 @@ void Server::startSessionWithFlags(const Caller_t &caller,
|
||||||
SE_THROW("server shutting down");
|
SE_THROW("server shutting down");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Client> client = addClient(caller,
|
std::shared_ptr<Client> client = addClient(caller,
|
||||||
watch);
|
watch);
|
||||||
std::string new_session = getNextSession();
|
std::string new_session = getNextSession();
|
||||||
boost::shared_ptr<Session> session = Session::createSession(*this,
|
auto session = make_weak_shared::make<Session>(*this,
|
||||||
"is this a client or server session?",
|
"is this a client or server session?",
|
||||||
server,
|
server,
|
||||||
new_session,
|
new_session,
|
||||||
|
@ -293,9 +281,9 @@ void Server::startSessionWithFlags(const Caller_t &caller,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<Session> Server::startInternalSession(const std::string &server,
|
std::shared_ptr<Session> Server::startInternalSession(const std::string &server,
|
||||||
SessionFlags flags,
|
SessionFlags flags,
|
||||||
const boost::function<void (const boost::weak_ptr<Session> &session)> &callback)
|
const std::function<void (const std::weak_ptr<Session> &session)> &callback)
|
||||||
{
|
{
|
||||||
if (m_shutdownRequested) {
|
if (m_shutdownRequested) {
|
||||||
// don't allow new sessions, we cannot activate them
|
// don't allow new sessions, we cannot activate them
|
||||||
|
@ -311,12 +299,12 @@ boost::shared_ptr<Session> Server::startInternalSession(const std::string &serve
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string new_session = getNextSession();
|
std::string new_session = getNextSession();
|
||||||
boost::shared_ptr<Session> session = Session::createSession(*this,
|
auto session = make_weak_shared::make<Session>(*this,
|
||||||
"is this a client or server session?",
|
"is this a client or server session?",
|
||||||
server,
|
server,
|
||||||
new_session,
|
new_session,
|
||||||
dbusFlags);
|
dbusFlags);
|
||||||
session->m_sessionActiveSignal.connect(boost::bind(callback, boost::weak_ptr<Session>(session)));
|
session->m_sessionActiveSignal.connect([weakSessionPtr=std::weak_ptr<Session>(session), callback] () { callback(weakSessionPtr); });
|
||||||
session->activate();
|
session->activate();
|
||||||
enqueue(session);
|
enqueue(session);
|
||||||
return session;
|
return session;
|
||||||
|
@ -336,8 +324,8 @@ void Server::getSessions(std::vector<DBusObject_t> &sessions)
|
||||||
if (m_activeSession) {
|
if (m_activeSession) {
|
||||||
sessions.push_back(m_activeSession->getPath());
|
sessions.push_back(m_activeSession->getPath());
|
||||||
}
|
}
|
||||||
for (boost::weak_ptr<Session> &session: m_workQueue) {
|
for (std::weak_ptr<Session> &session: m_workQueue) {
|
||||||
boost::shared_ptr<Session> s = session.lock();
|
std::shared_ptr<Session> s = session.lock();
|
||||||
if (s) {
|
if (s) {
|
||||||
sessions.push_back(s->getPath());
|
sessions.push_back(s->getPath());
|
||||||
}
|
}
|
||||||
|
@ -345,13 +333,13 @@ void Server::getSessions(std::vector<DBusObject_t> &sessions)
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Server(GMainLoop *loop,
|
Server::Server(GMainLoop *loop,
|
||||||
boost::shared_ptr<Restart> &restart,
|
std::shared_ptr<Restart> &restart,
|
||||||
const DBusConnectionPtr &conn,
|
const DBusConnectionPtr &conn,
|
||||||
int duration) :
|
int duration) :
|
||||||
DBusObjectHelper(conn,
|
DBusObjectHelper(conn,
|
||||||
SessionCommon::SERVER_PATH,
|
SessionCommon::SERVER_PATH,
|
||||||
SessionCommon::SERVER_IFACE,
|
SessionCommon::SERVER_IFACE,
|
||||||
boost::bind(&Server::autoTermCallback, this)),
|
[this] () { autoTermCallback(); }),
|
||||||
m_loop(loop),
|
m_loop(loop),
|
||||||
m_suspendFlagsSource(0),
|
m_suspendFlagsSource(0),
|
||||||
m_shutdownRequested(false),
|
m_shutdownRequested(false),
|
||||||
|
@ -373,7 +361,7 @@ Server::Server(GMainLoop *loop,
|
||||||
// This would help with dangling references to it when other threads
|
// This would help with dangling references to it when other threads
|
||||||
// use it for logging, see ServerLogger. However, with mutex locking
|
// use it for logging, see ServerLogger. However, with mutex locking
|
||||||
// in ServerLogger that shouldn't be a problem.
|
// in ServerLogger that shouldn't be a problem.
|
||||||
m_logger(new ServerLogger(boost::shared_ptr<Server>(this, NopDestructor())))
|
m_logger(new ServerLogger(std::shared_ptr<Server>(this, NopDestructor())))
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
@ -405,16 +393,28 @@ Server::Server(GMainLoop *loop,
|
||||||
|
|
||||||
// Log entering and leaving idle state and
|
// Log entering and leaving idle state and
|
||||||
// allow/prevent auto-termination.
|
// allow/prevent auto-termination.
|
||||||
m_idleSignal.connect(boost::bind(&Server::onIdleChange, this, _1));
|
auto onIdleChange = [this] (bool idle) {
|
||||||
|
SE_LOG_DEBUG(NULL, "server is %s", idle ? "idle" : "not idle");
|
||||||
|
if (idle) {
|
||||||
|
autoTermUnref();
|
||||||
|
} else {
|
||||||
|
autoTermRef();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_idleSignal.connect(onIdleChange);
|
||||||
|
|
||||||
// connect ConfigChanged signal to source for that information
|
// connect ConfigChanged signal to source for that information
|
||||||
m_configChangedSignal.connect(boost::bind(boost::ref(configChanged)));
|
m_configChangedSignal.connect([this] (const std::string &configName) { configChanged(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean Server::onSuspendFlagsChange(GIOChannel *source,
|
void Server::activate()
|
||||||
GIOCondition condition,
|
|
||||||
gpointer data) throw ()
|
|
||||||
{
|
{
|
||||||
|
// Watch SuspendFlags fd to react to signals quickly.
|
||||||
|
int fd = SuspendFlags::getSuspendFlags().getEventFD();
|
||||||
|
GIOChannelCXX channel(g_io_channel_unix_new(fd), TRANSFER_REF);
|
||||||
|
auto onSuspendFlagsChange = [] (GIOChannel *source,
|
||||||
|
GIOCondition condition,
|
||||||
|
gpointer data) throw () {
|
||||||
Server *me = static_cast<Server *>(data);
|
Server *me = static_cast<Server *>(data);
|
||||||
try {
|
try {
|
||||||
if (!SuspendFlags::getSuspendFlags().isNormal()) {
|
if (!SuspendFlags::getSuspendFlags().isNormal()) {
|
||||||
|
@ -426,14 +426,8 @@ gboolean Server::onSuspendFlagsChange(GIOChannel *source,
|
||||||
Exception::handle();
|
Exception::handle();
|
||||||
}
|
}
|
||||||
// Keep watching, just in case that we catch multiple signals.
|
// Keep watching, just in case that we catch multiple signals.
|
||||||
return TRUE;
|
return (gboolean)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);
|
m_suspendFlagsSource = g_io_add_watch(channel, G_IO_IN, onSuspendFlagsChange, this);
|
||||||
|
|
||||||
// Activate our D-Bus object *before* interacting with D-Bus
|
// Activate our D-Bus object *before* interacting with D-Bus
|
||||||
|
@ -517,7 +511,7 @@ void Server::fileModified(const std::string &file)
|
||||||
m_lastFileMod = Timespec::monotonic();
|
m_lastFileMod = Timespec::monotonic();
|
||||||
if (!m_activeSession) {
|
if (!m_activeSession) {
|
||||||
m_shutdownTimer.activate(SHUTDOWN_QUIESENCE_SECONDS,
|
m_shutdownTimer.activate(SHUTDOWN_QUIESENCE_SECONDS,
|
||||||
boost::bind(&Server::shutdown, this));
|
[this] () { return shutdown(); });
|
||||||
}
|
}
|
||||||
m_shutdownRequested = true;
|
m_shutdownRequested = true;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +543,7 @@ void Server::run()
|
||||||
for (const string &file: files) {
|
for (const string &file: files) {
|
||||||
try {
|
try {
|
||||||
SE_LOG_DEBUG(NULL, "watching: %s", file.c_str());
|
SE_LOG_DEBUG(NULL, "watching: %s", file.c_str());
|
||||||
boost::shared_ptr<SyncEvo::GLibNotify> notify(new GLibNotify(file.c_str(), boost::bind(&Server::fileModified, this, file)));
|
auto notify = std::make_shared<GLibNotify>(file.c_str(), [this, file] (GFile *, GFile *, GFileMonitorEvent) { fileModified(file); });
|
||||||
m_files.push_back(notify);
|
m_files.push_back(notify);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// ignore errors for indidividual files
|
// ignore errors for indidividual files
|
||||||
|
@ -576,7 +570,7 @@ void Server::run()
|
||||||
/**
|
/**
|
||||||
* look up client by its ID
|
* look up client by its ID
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Client> Server::findClient(const Caller_t &ID)
|
std::shared_ptr<Client> Server::findClient(const Caller_t &ID)
|
||||||
{
|
{
|
||||||
for (Clients_t::iterator it = m_clients.begin();
|
for (Clients_t::iterator it = m_clients.begin();
|
||||||
it != m_clients.end();
|
it != m_clients.end();
|
||||||
|
@ -585,13 +579,13 @@ boost::shared_ptr<Client> Server::findClient(const Caller_t &ID)
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return boost::shared_ptr<Client>();
|
return std::shared_ptr<Client>();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Client> Server::addClient(const Caller_t &ID,
|
std::shared_ptr<Client> Server::addClient(const Caller_t &ID,
|
||||||
const boost::shared_ptr<Watch> &watch)
|
const std::shared_ptr<Watch> &watch)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client(findClient(ID));
|
std::shared_ptr<Client> client(findClient(ID));
|
||||||
if (client) {
|
if (client) {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -599,7 +593,9 @@ boost::shared_ptr<Client> Server::addClient(const Caller_t &ID,
|
||||||
// add to our list *before* checking that peer exists, so
|
// add to our list *before* checking that peer exists, so
|
||||||
// that clientGone() can remove it if the check fails
|
// that clientGone() can remove it if the check fails
|
||||||
m_clients.push_back(std::make_pair(watch, client));
|
m_clients.push_back(std::make_pair(watch, client));
|
||||||
watch->setCallback(boost::bind(&Server::clientGone, this, client.get()));
|
// Here we intentionally bind the raw pointer. It's only going to be used for
|
||||||
|
// comparisons.
|
||||||
|
watch->setCallback([this, clientPtr=client.get()] () { Server::clientGone(clientPtr); });
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +607,7 @@ void Server::detach(Resource *resource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::enqueue(const boost::shared_ptr<Session> &session)
|
void Server::enqueue(const std::shared_ptr<Session> &session)
|
||||||
{
|
{
|
||||||
bool idle = isIdle();
|
bool idle = isIdle();
|
||||||
|
|
||||||
|
@ -619,7 +615,7 @@ void Server::enqueue(const boost::shared_ptr<Session> &session)
|
||||||
while (it != m_workQueue.begin()) {
|
while (it != m_workQueue.begin()) {
|
||||||
--it;
|
--it;
|
||||||
// skip over dead sessions, they will get cleaned up elsewhere
|
// skip over dead sessions, they will get cleaned up elsewhere
|
||||||
boost::shared_ptr<Session> session = it->lock();
|
std::shared_ptr<Session> session = it->lock();
|
||||||
if (session && session->getPriority() <= session->getPriority()) {
|
if (session && session->getPriority() <= session->getPriority()) {
|
||||||
++it;
|
++it;
|
||||||
break;
|
break;
|
||||||
|
@ -638,13 +634,13 @@ void Server::killSessionsAsync(const std::string &peerDeviceID,
|
||||||
{
|
{
|
||||||
WorkQueue_t::iterator it = m_workQueue.begin();
|
WorkQueue_t::iterator it = m_workQueue.begin();
|
||||||
while (it != m_workQueue.end()) {
|
while (it != m_workQueue.end()) {
|
||||||
boost::shared_ptr<Session> session = it->lock();
|
std::shared_ptr<Session> session = it->lock();
|
||||||
if (session && session->getPeerDeviceID() == peerDeviceID) {
|
if (session && session->getPeerDeviceID() == peerDeviceID) {
|
||||||
SE_LOG_DEBUG(NULL, "removing pending session %s because it matches deviceID %s",
|
SE_LOG_DEBUG(NULL, "removing pending session %s because it matches deviceID %s",
|
||||||
session->getSessionID().c_str(),
|
session->getSessionID().c_str(),
|
||||||
peerDeviceID.c_str());
|
peerDeviceID.c_str());
|
||||||
// remove session and its corresponding connection
|
// remove session and its corresponding connection
|
||||||
boost::shared_ptr<Connection> c = session->getStubConnection().lock();
|
std::shared_ptr<Connection> c = session->getStubConnection().lock();
|
||||||
if (c) {
|
if (c) {
|
||||||
c->shutdown();
|
c->shutdown();
|
||||||
}
|
}
|
||||||
|
@ -655,7 +651,7 @@ void Server::killSessionsAsync(const std::string &peerDeviceID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check active session. We need to wait for it to shut down cleanly.
|
// Check active session. We need to wait for it to shut down cleanly.
|
||||||
boost::shared_ptr<Session> active = m_activeSessionRef.lock();
|
std::shared_ptr<Session> active = m_activeSessionRef.lock();
|
||||||
if (active &&
|
if (active &&
|
||||||
active->getPeerDeviceID() == peerDeviceID) {
|
active->getPeerDeviceID() == peerDeviceID) {
|
||||||
SE_LOG_DEBUG(NULL, "aborting active session %s because it matches deviceID %s",
|
SE_LOG_DEBUG(NULL, "aborting active session %s because it matches deviceID %s",
|
||||||
|
@ -705,7 +701,7 @@ void Server::dequeue(Session *session)
|
||||||
if (shutdown >= now) {
|
if (shutdown >= now) {
|
||||||
SE_LOG_DEBUG(NULL, "file modified, initiating shutdown after session finished");
|
SE_LOG_DEBUG(NULL, "file modified, initiating shutdown after session finished");
|
||||||
m_shutdownTimer.activate((shutdown - now).seconds(),
|
m_shutdownTimer.activate((shutdown - now).seconds(),
|
||||||
boost::bind(&Server::shutdown, this));
|
[this] () { return this->shutdown(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkQueue();
|
checkQueue();
|
||||||
|
@ -752,12 +748,6 @@ void Server::removeSyncSession(Session *session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quitLoop(GMainLoop *loop)
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "stopping server's event loop");
|
|
||||||
g_main_loop_quit(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::checkQueue()
|
void Server::checkQueue()
|
||||||
{
|
{
|
||||||
if (m_activeSession) {
|
if (m_activeSession) {
|
||||||
|
@ -776,13 +766,17 @@ void Server::checkQueue()
|
||||||
// then the server shut down immediately after Detach()).
|
// then the server shut down immediately after Detach()).
|
||||||
if (!m_shutdownTimer) {
|
if (!m_shutdownTimer) {
|
||||||
SE_LOG_DEBUG(NULL, "shutting down in checkQueue(), idle and shutdown was requested");
|
SE_LOG_DEBUG(NULL, "shutting down in checkQueue(), idle and shutdown was requested");
|
||||||
addTimeout(boost::bind(quitLoop, m_loop), 0);
|
addTimeout([this] () {
|
||||||
|
SE_LOG_DEBUG(NULL, "stopping server's event loop");
|
||||||
|
g_main_loop_quit(m_loop);
|
||||||
|
},
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!m_workQueue.empty()) {
|
while (!m_workQueue.empty()) {
|
||||||
boost::shared_ptr<Session> session = m_workQueue.front().lock();
|
std::shared_ptr<Session> session = m_workQueue.front().lock();
|
||||||
m_workQueue.pop_front();
|
m_workQueue.pop_front();
|
||||||
if (session) {
|
if (session) {
|
||||||
// activate the session
|
// activate the session
|
||||||
|
@ -796,13 +790,7 @@ void Server::checkQueue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sessionExpired(const boost::shared_ptr<Session> &session)
|
void Server::delaySessionDestruction(const std::shared_ptr<Session> &session)
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "session %s expired",
|
|
||||||
session->getSessionID().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::delaySessionDestruction(const boost::shared_ptr<Session> &session)
|
|
||||||
{
|
{
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
|
@ -810,8 +798,12 @@ void Server::delaySessionDestruction(const boost::shared_ptr<Session> &session)
|
||||||
|
|
||||||
SE_LOG_DEBUG(NULL, "delaying destruction of session %s by one minute",
|
SE_LOG_DEBUG(NULL, "delaying destruction of session %s by one minute",
|
||||||
session->getSessionID().c_str());
|
session->getSessionID().c_str());
|
||||||
addTimeout(boost::bind(&Server::sessionExpired,
|
// The trick here is to bind the shared pointer to the timeout instance
|
||||||
session),
|
// for the duration of the timeout.
|
||||||
|
addTimeout([session] () {
|
||||||
|
SE_LOG_DEBUG(NULL, "session %s expired",
|
||||||
|
session->getSessionID().c_str());
|
||||||
|
},
|
||||||
60 /* 1 minute */);
|
60 /* 1 minute */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,14 +817,14 @@ inline void insertPair(std::map<string, string> ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<InfoReq> Server::passwordRequest(const string &descr,
|
std::shared_ptr<InfoReq> Server::passwordRequest(const string &descr,
|
||||||
const ConfigPasswordKey &key,
|
const ConfigPasswordKey &key,
|
||||||
const boost::weak_ptr<Session> &s)
|
const std::weak_ptr<Session> &s)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Session> session = s.lock();
|
std::shared_ptr<Session> session = s.lock();
|
||||||
if (!session) {
|
if (!session) {
|
||||||
// already gone, ignore request
|
// already gone, ignore request
|
||||||
return boost::shared_ptr<InfoReq>();
|
return std::shared_ptr<InfoReq>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<string, string> params;
|
std::map<string, string> params;
|
||||||
|
@ -844,30 +836,25 @@ boost::shared_ptr<InfoReq> Server::passwordRequest(const string &descr,
|
||||||
insertPair(params, "protocol", key.protocol);
|
insertPair(params, "protocol", key.protocol);
|
||||||
insertPair(params, "authtype", key.authtype);
|
insertPair(params, "authtype", key.authtype);
|
||||||
insertPair(params, "port", key.port ? StringPrintf("%u",key.port) : "");
|
insertPair(params, "port", key.port ? StringPrintf("%u",key.port) : "");
|
||||||
boost::shared_ptr<InfoReq> req = createInfoReq("password", params, *session);
|
std::shared_ptr<InfoReq> req = createInfoReq("password", params, *session);
|
||||||
// Return password or failure to Session and thus the session helper.
|
// Return password or failure to Session and thus the session helper.
|
||||||
req->m_responseSignal.connect(boost::bind(&Server::passwordResponse,
|
req->m_responseSignal.connect([this, s] (const InfoReq::InfoMap &response) { passwordResponse(response, s); });
|
||||||
this,
|
|
||||||
_1,
|
|
||||||
s));
|
|
||||||
// Tell session about timeout.
|
// Tell session about timeout.
|
||||||
req->m_timeoutSignal.connect(InfoReq::TimeoutSignal_t::slot_type(&Session::passwordResponse,
|
req->m_timeoutSignal.connect(InfoReq::TimeoutSignal_t::slot_type(&Session::passwordResponse,
|
||||||
session.get(),
|
session.get(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
"").track(s));
|
"").track_foreign(s));
|
||||||
// Request becomes obsolete when session is done.
|
// Request becomes obsolete when session is done.
|
||||||
session->m_doneSignal.connect(boost::bind(&Server::removeInfoReq,
|
session->m_doneSignal.connect([this, id=req->getId()] (SyncEvo::SyncMLStatus, const SyncEvo::SyncReport &) { removeInfoReq(id); });
|
||||||
this,
|
|
||||||
req->getId()));
|
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::passwordResponse(const InfoReq::InfoMap &response,
|
void Server::passwordResponse(const InfoReq::InfoMap &response,
|
||||||
const boost::weak_ptr<Session> &s)
|
const std::weak_ptr<Session> &s)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Session> session = s.lock();
|
std::shared_ptr<Session> session = s.lock();
|
||||||
if (!session) {
|
if (!session) {
|
||||||
// already gone, ignore request
|
// already gone, ignore request
|
||||||
return;
|
return;
|
||||||
|
@ -884,29 +871,24 @@ void Server::passwordResponse(const InfoReq::InfoMap &response,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Server::callTimeout(const boost::shared_ptr<Timeout> &timeout, const boost::function<void ()> &callback)
|
void Server::addTimeout(const std::function<void ()> &callback,
|
||||||
|
int seconds)
|
||||||
{
|
{
|
||||||
|
auto timeout = std::make_shared<Timeout>();
|
||||||
|
m_timeouts.push_back(timeout);
|
||||||
|
auto callTimeout = [this, timeoutWeak=std::weak_ptr<Timeout>(timeout), callback] () {
|
||||||
|
auto timeout = timeoutWeak.lock();
|
||||||
|
if (timeout) {
|
||||||
callback();
|
callback();
|
||||||
// We are executing the timeout, don't invalidate the instance
|
// We are executing the timeout, don't invalidate the instance
|
||||||
// until later when our caller is no longer using the instance to
|
// until later when our caller is no longer using the instance to
|
||||||
// call us.
|
// call us.
|
||||||
delayDeletion(timeout);
|
delayDeletion(timeout);
|
||||||
m_timeouts.remove(timeout);
|
m_timeouts.remove(timeout);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
void Server::addTimeout(const boost::function<void ()> &callback,
|
};
|
||||||
int seconds)
|
timeout->activate(seconds, callTimeout);
|
||||||
{
|
|
||||||
boost::shared_ptr<Timeout> timeout(new Timeout);
|
|
||||||
m_timeouts.push_back(timeout);
|
|
||||||
timeout->activate(seconds,
|
|
||||||
boost::bind(&Server::callTimeout,
|
|
||||||
this,
|
|
||||||
// avoid copying the shared pointer here,
|
|
||||||
// otherwise the Timeout will never be deleted
|
|
||||||
boost::ref(m_timeouts.back()),
|
|
||||||
callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::infoResponse(const Caller_t &caller,
|
void Server::infoResponse(const Caller_t &caller,
|
||||||
|
@ -917,26 +899,23 @@ void Server::infoResponse(const Caller_t &caller,
|
||||||
InfoReqMap::iterator it = m_infoReqMap.find(id);
|
InfoReqMap::iterator it = m_infoReqMap.find(id);
|
||||||
// if not found, ignore
|
// if not found, ignore
|
||||||
if (it != m_infoReqMap.end()) {
|
if (it != m_infoReqMap.end()) {
|
||||||
const boost::shared_ptr<InfoReq> infoReq = it->second.lock();
|
const std::shared_ptr<InfoReq> infoReq = it->second.lock();
|
||||||
if (infoReq) {
|
if (infoReq) {
|
||||||
infoReq->setResponse(caller, state, response);
|
infoReq->setResponse(caller, state, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<InfoReq> Server::createInfoReq(const string &type,
|
std::shared_ptr<InfoReq> Server::createInfoReq(const string &type,
|
||||||
const std::map<string, string> ¶meters,
|
const std::map<std::string, std::string> ¶meters,
|
||||||
const Session &session)
|
const Session &session)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<InfoReq> infoReq(new InfoReq(*this, type, parameters, session.getPath()));
|
auto infoReq = std::make_shared<InfoReq>(*this, type, parameters, session.getPath());
|
||||||
m_infoReqMap.insert(std::make_pair(infoReq->getId(), infoReq));
|
m_infoReqMap.insert(std::make_pair(infoReq->getId(), infoReq));
|
||||||
// will be removed automatically
|
// will be removed automatically
|
||||||
infoReq->m_responseSignal.connect(boost::bind(&Server::removeInfoReq,
|
auto remove = [this, id=infoReq->getId()] () { removeInfoReq(id); };
|
||||||
this,
|
infoReq->m_responseSignal.connect([this, id=infoReq->getId()] (const std::map<std::string, std::string> &) { removeInfoReq(id); });
|
||||||
infoReq->getId()));
|
infoReq->m_timeoutSignal.connect([this, id=infoReq->getId()] () { removeInfoReq(id); });
|
||||||
infoReq->m_timeoutSignal.connect(boost::bind(&Server::removeInfoReq,
|
|
||||||
this,
|
|
||||||
infoReq->getId()));
|
|
||||||
return infoReq;
|
return infoReq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,14 +961,14 @@ void Server::getDeviceList(SyncConfig::DeviceList &devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addPeerTempl(const string &templName,
|
void Server::addPeerTempl(const string &templName,
|
||||||
const boost::shared_ptr<SyncConfig::TemplateDescription> peerTempl)
|
const std::shared_ptr<SyncConfig::TemplateDescription> &peerTempl)
|
||||||
{
|
{
|
||||||
std::string lower = templName;
|
std::string lower = templName;
|
||||||
boost::to_lower(lower);
|
boost::to_lower(lower);
|
||||||
m_matchedTempls.insert(MatchedTemplates::value_type(lower, peerTempl));
|
m_matchedTempls.insert(MatchedTemplates::value_type(lower, peerTempl));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const string &peer)
|
std::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const string &peer)
|
||||||
{
|
{
|
||||||
std::string lower = peer;
|
std::string lower = peer;
|
||||||
boost::to_lower(lower);
|
boost::to_lower(lower);
|
||||||
|
@ -997,7 +976,7 @@ boost::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const st
|
||||||
if(it != m_matchedTempls.end()) {
|
if(it != m_matchedTempls.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
} else {
|
} else {
|
||||||
return boost::shared_ptr<SyncConfig::TemplateDescription>();
|
return std::shared_ptr<SyncConfig::TemplateDescription>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1008,7 +987,7 @@ bool Server::getDevice(const string &deviceId, SyncConfig::DeviceDescription &de
|
||||||
if (boost::equals(syncDevIt->m_deviceId, deviceId)) {
|
if (boost::equals(syncDevIt->m_deviceId, deviceId)) {
|
||||||
device = *syncDevIt;
|
device = *syncDevIt;
|
||||||
if (syncDevIt->m_pnpInformation) {
|
if (syncDevIt->m_pnpInformation) {
|
||||||
device.m_pnpInformation = boost::shared_ptr<SyncConfig::PnpInformation>(
|
device.m_pnpInformation = std::shared_ptr<SyncConfig::PnpInformation>(
|
||||||
new SyncConfig::PnpInformation(syncDevIt->m_pnpInformation->m_vendor,
|
new SyncConfig::PnpInformation(syncDevIt->m_pnpInformation->m_vendor,
|
||||||
syncDevIt->m_pnpInformation->m_product));
|
syncDevIt->m_pnpInformation->m_product));
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef SYNCEVO_DBUS_SERVER_H
|
#ifndef SYNCEVO_DBUS_SERVER_H
|
||||||
#define SYNCEVO_DBUS_SERVER_H
|
#define SYNCEVO_DBUS_SERVER_H
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/weak_ptr.hpp>
|
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
|
|
||||||
#include <syncevo/SyncConfig.h>
|
#include <syncevo/SyncConfig.h>
|
||||||
|
@ -34,6 +30,9 @@
|
||||||
#include "dbus-callbacks.h"
|
#include "dbus-callbacks.h"
|
||||||
#include "read-operations.h"
|
#include "read-operations.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
|
@ -66,11 +65,11 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
guint m_suspendFlagsSource;
|
guint m_suspendFlagsSource;
|
||||||
bool m_shutdownRequested;
|
bool m_shutdownRequested;
|
||||||
Timespec m_lastFileMod;
|
Timespec m_lastFileMod;
|
||||||
boost::shared_ptr<SyncEvo::Restart> &m_restart;
|
std::shared_ptr<SyncEvo::Restart> &m_restart;
|
||||||
GDBusCXX::DBusConnectionPtr m_conn;
|
GDBusCXX::DBusConnectionPtr m_conn;
|
||||||
|
|
||||||
uint32_t m_lastSession;
|
uint32_t m_lastSession;
|
||||||
typedef std::list< std::pair< boost::shared_ptr<GDBusCXX::Watch>, boost::shared_ptr<Client> > > Clients_t;
|
typedef std::list< std::pair< std::shared_ptr<GDBusCXX::Watch>, std::shared_ptr<Client> > > Clients_t;
|
||||||
Clients_t m_clients;
|
Clients_t m_clients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +78,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
* server terminates, thus unrefing anything encapsulated inside
|
* server terminates, thus unrefing anything encapsulated inside
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
std::list< boost::function<void ()> > m_delayDeletion;
|
std::list< std::function<void ()> > m_delayDeletion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch all files mapped into our address space. When
|
* Watch all files mapped into our address space. When
|
||||||
|
@ -93,7 +92,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
* down or restarts. The latter is necessary if the daemon has
|
* down or restarts. The latter is necessary if the daemon has
|
||||||
* automatic syncing enabled in a config.
|
* automatic syncing enabled in a config.
|
||||||
*/
|
*/
|
||||||
list< boost::shared_ptr<GLibNotify> > m_files;
|
list< std::shared_ptr<GLibNotify> > m_files;
|
||||||
void fileModified(const std::string &file);
|
void fileModified(const std::string &file);
|
||||||
bool shutdown();
|
bool shutdown();
|
||||||
|
|
||||||
|
@ -121,7 +120,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
/**
|
/**
|
||||||
* The weak pointer that corresponds to m_activeSession.
|
* The weak pointer that corresponds to m_activeSession.
|
||||||
*/
|
*/
|
||||||
boost::weak_ptr<Session> m_activeSessionRef;
|
std::weak_ptr<Session> m_activeSessionRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The running sync session. Having a separate reference to it
|
* The running sync session. Having a separate reference to it
|
||||||
|
@ -132,9 +131,9 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
* addSyncSession() and remove itself with removeSyncSession() when
|
* addSyncSession() and remove itself with removeSyncSession() when
|
||||||
* done.
|
* done.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Session> m_syncSession;
|
std::shared_ptr<Session> m_syncSession;
|
||||||
|
|
||||||
typedef std::list< boost::weak_ptr<Session> > WorkQueue_t;
|
typedef std::list< std::weak_ptr<Session> > WorkQueue_t;
|
||||||
/**
|
/**
|
||||||
* A queue of pending, idle Sessions. Sorted by priority, most
|
* A queue of pending, idle Sessions. Sorted by priority, most
|
||||||
* important one first. Currently this is used to give client
|
* important one first. Currently this is used to give client
|
||||||
|
@ -150,7 +149,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
/**
|
/**
|
||||||
* a hash of pending InfoRequest
|
* a hash of pending InfoRequest
|
||||||
*/
|
*/
|
||||||
typedef std::map<string, boost::weak_ptr<InfoReq> > InfoReqMap;
|
typedef std::map<string, std::weak_ptr<InfoReq> > InfoReqMap;
|
||||||
|
|
||||||
// hash map of pending info requests
|
// hash map of pending info requests
|
||||||
InfoReqMap m_infoReqMap;
|
InfoReqMap m_infoReqMap;
|
||||||
|
@ -160,11 +159,11 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
// a hash to represent matched templates for devices, the key is
|
// a hash to represent matched templates for devices, the key is
|
||||||
// the peer name
|
// the peer name
|
||||||
typedef std::map<string, boost::shared_ptr<SyncConfig::TemplateDescription> > MatchedTemplates;
|
typedef std::map<string, std::shared_ptr<SyncConfig::TemplateDescription> > MatchedTemplates;
|
||||||
|
|
||||||
MatchedTemplates m_matchedTempls;
|
MatchedTemplates m_matchedTempls;
|
||||||
|
|
||||||
boost::shared_ptr<BluezManager> m_bluezManager;
|
std::shared_ptr<BluezManager> m_bluezManager;
|
||||||
|
|
||||||
/** devices which have sync services */
|
/** devices which have sync services */
|
||||||
SyncConfig::DeviceList m_syncDevices;
|
SyncConfig::DeviceList m_syncDevices;
|
||||||
|
@ -186,7 +185,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
/** Server.Attach() */
|
/** Server.Attach() */
|
||||||
void attachClient(const GDBusCXX::Caller_t &caller,
|
void attachClient(const GDBusCXX::Caller_t &caller,
|
||||||
const boost::shared_ptr<GDBusCXX::Watch> &watch);
|
const std::shared_ptr<GDBusCXX::Watch> &watch);
|
||||||
|
|
||||||
/** Server.Detach() */
|
/** Server.Detach() */
|
||||||
void detachClient(const GDBusCXX::Caller_t &caller);
|
void detachClient(const GDBusCXX::Caller_t &caller);
|
||||||
|
@ -228,7 +227,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
/** Server.Connect() */
|
/** Server.Connect() */
|
||||||
void connect(const GDBusCXX::Caller_t &caller,
|
void connect(const GDBusCXX::Caller_t &caller,
|
||||||
const boost::shared_ptr<GDBusCXX::Watch> &watch,
|
const std::shared_ptr<GDBusCXX::Watch> &watch,
|
||||||
const StringMap &peer,
|
const StringMap &peer,
|
||||||
bool must_authenticate,
|
bool must_authenticate,
|
||||||
const std::string &session,
|
const std::string &session,
|
||||||
|
@ -236,7 +235,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
/** Server.StartSession() */
|
/** Server.StartSession() */
|
||||||
void startSession(const GDBusCXX::Caller_t &caller,
|
void startSession(const GDBusCXX::Caller_t &caller,
|
||||||
const boost::shared_ptr<GDBusCXX::Watch> &watch,
|
const std::shared_ptr<GDBusCXX::Watch> &watch,
|
||||||
const std::string &server,
|
const std::string &server,
|
||||||
GDBusCXX::DBusObject_t &object) {
|
GDBusCXX::DBusObject_t &object) {
|
||||||
startSessionWithFlags(caller, watch, server, std::vector<std::string>(), object);
|
startSessionWithFlags(caller, watch, server, std::vector<std::string>(), object);
|
||||||
|
@ -244,7 +243,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
/** Server.StartSessionWithFlags() */
|
/** Server.StartSessionWithFlags() */
|
||||||
void startSessionWithFlags(const GDBusCXX::Caller_t &caller,
|
void startSessionWithFlags(const GDBusCXX::Caller_t &caller,
|
||||||
const boost::shared_ptr<GDBusCXX::Watch> &watch,
|
const std::shared_ptr<GDBusCXX::Watch> &watch,
|
||||||
const std::string &server,
|
const std::string &server,
|
||||||
const std::vector<std::string> &flags,
|
const std::vector<std::string> &flags,
|
||||||
GDBusCXX::DBusObject_t &object);
|
GDBusCXX::DBusObject_t &object);
|
||||||
|
@ -263,9 +262,9 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
* that reference, the session gets deleted and the callback
|
* that reference, the session gets deleted and the callback
|
||||||
* will not be called.
|
* will not be called.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Session> startInternalSession(const std::string &server,
|
std::shared_ptr<Session> startInternalSession(const std::string &server,
|
||||||
SessionFlags flags,
|
SessionFlags flags,
|
||||||
const boost::function<void (const boost::weak_ptr<Session> &session)> &callback);
|
const std::function<void (const std::weak_ptr<Session> &session)> &callback);
|
||||||
|
|
||||||
/** Server.GetConfig() */
|
/** Server.GetConfig() */
|
||||||
void getConfig(const std::string &config_name,
|
void getConfig(const std::string &config_name,
|
||||||
|
@ -384,7 +383,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
boost::scoped_ptr<NetworkManagerClient> m_networkManager;
|
boost::scoped_ptr<NetworkManagerClient> m_networkManager;
|
||||||
|
|
||||||
/** Manager to automatic sync */
|
/** Manager to automatic sync */
|
||||||
boost::shared_ptr<AutoSyncManager> m_autoSync;
|
std::shared_ptr<AutoSyncManager> m_autoSync;
|
||||||
|
|
||||||
//automatic termination
|
//automatic termination
|
||||||
AutoTerm m_autoTerm;
|
AutoTerm m_autoTerm;
|
||||||
|
@ -394,7 +393,7 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
|
|
||||||
// Created in constructor and captures parent logger there,
|
// Created in constructor and captures parent logger there,
|
||||||
// then pushed as default logger in activate().
|
// then pushed as default logger in activate().
|
||||||
boost::shared_ptr<ServerLogger> m_logger;
|
std::shared_ptr<ServerLogger> m_logger;
|
||||||
PushLogger<ServerLogger> m_pushLogger;
|
PushLogger<ServerLogger> m_pushLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -402,28 +401,11 @@ class Server : public GDBusCXX::DBusObjectHelper
|
||||||
* Each timeout which requests to be not called
|
* Each timeout which requests to be not called
|
||||||
* again will be removed from this list.
|
* again will be removed from this list.
|
||||||
*/
|
*/
|
||||||
list< boost::shared_ptr<Timeout> > m_timeouts;
|
list< std::shared_ptr<Timeout> > m_timeouts;
|
||||||
|
|
||||||
/**
|
|
||||||
* called each time a timeout triggers,
|
|
||||||
* removes those which are done
|
|
||||||
*/
|
|
||||||
bool callTimeout(const boost::shared_ptr<Timeout> &timeout, const boost::function<void ()> &callback);
|
|
||||||
|
|
||||||
/** called 1 minute after last client detached from a session */
|
|
||||||
static void sessionExpired(const boost::shared_ptr<Session> &session);
|
|
||||||
|
|
||||||
/** 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:
|
public:
|
||||||
Server(GMainLoop *loop,
|
Server(GMainLoop *loop,
|
||||||
boost::shared_ptr<Restart> &restart,
|
std::shared_ptr<Restart> &restart,
|
||||||
const GDBusCXX::DBusConnectionPtr &conn,
|
const GDBusCXX::DBusConnectionPtr &conn,
|
||||||
int duration);
|
int duration);
|
||||||
void activate();
|
void activate();
|
||||||
|
@ -436,7 +418,7 @@ public:
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
/** currently running operation */
|
/** currently running operation */
|
||||||
boost::shared_ptr<Session> getSyncSession() const { return m_syncSession; }
|
std::shared_ptr<Session> getSyncSession() const { return m_syncSession; }
|
||||||
|
|
||||||
/** true iff no work is pending */
|
/** true iff no work is pending */
|
||||||
bool isIdle() const { return !m_activeSession && m_workQueue.empty(); }
|
bool isIdle() const { return !m_activeSession && m_workQueue.empty(); }
|
||||||
|
@ -456,19 +438,19 @@ public:
|
||||||
/**
|
/**
|
||||||
* Called when a session starts its real work (= calls addSyncSession()).
|
* Called when a session starts its real work (= calls addSyncSession()).
|
||||||
*/
|
*/
|
||||||
typedef boost::signals2::signal<void (const boost::shared_ptr<Session> &)> NewSyncSessionSignal_t;
|
typedef boost::signals2::signal<void (const std::shared_ptr<Session> &)> NewSyncSessionSignal_t;
|
||||||
NewSyncSessionSignal_t m_newSyncSessionSignal;
|
NewSyncSessionSignal_t m_newSyncSessionSignal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* look up client by its ID
|
* look up client by its ID
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Client> findClient(const GDBusCXX::Caller_t &ID);
|
std::shared_ptr<Client> findClient(const GDBusCXX::Caller_t &ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find client by its ID or create one anew
|
* find client by its ID or create one anew
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<Client> addClient(const GDBusCXX::Caller_t &ID,
|
std::shared_ptr<Client> addClient(const GDBusCXX::Caller_t &ID,
|
||||||
const boost::shared_ptr<GDBusCXX::Watch> &watch);
|
const std::shared_ptr<GDBusCXX::Watch> &watch);
|
||||||
|
|
||||||
/** detach this resource from all clients which own it */
|
/** detach this resource from all clients which own it */
|
||||||
void detach(Resource *resource);
|
void detach(Resource *resource);
|
||||||
|
@ -479,7 +461,7 @@ public:
|
||||||
* by the creator of the session, *after* the session is
|
* by the creator of the session, *after* the session is
|
||||||
* ready to run.
|
* ready to run.
|
||||||
*/
|
*/
|
||||||
void enqueue(const boost::shared_ptr<Session> &session);
|
void enqueue(const std::shared_ptr<Session> &session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all sessions with this device ID from the
|
* Remove all sessions with this device ID from the
|
||||||
|
@ -535,21 +517,21 @@ public:
|
||||||
* session. Once the timeout fires, it is called and then removed,
|
* session. Once the timeout fires, it is called and then removed,
|
||||||
* which removes the reference.
|
* which removes the reference.
|
||||||
*/
|
*/
|
||||||
void delaySessionDestruction(const boost::shared_ptr<Session> &session);
|
void delaySessionDestruction(const std::shared_ptr<Session> &session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works for any kind of object: keep shared pointer until the
|
* Works for any kind of object: keep shared pointer until the
|
||||||
* event loop is idle, then unref it inside. Useful for instances
|
* event loop is idle, then unref it inside. Useful for instances
|
||||||
* which need to delete themselves.
|
* which need to delete themselves.
|
||||||
*/
|
*/
|
||||||
template <class T> void delayDeletion(const boost::shared_ptr<T> &t) {
|
template <class T> void delayDeletion(const std::shared_ptr<T> &t) {
|
||||||
// The functor will never be called, important here is only
|
// The functor will never be called, important here is only
|
||||||
// that it contains a copy of the shared pointer.
|
// that it contains a copy of the shared pointer.
|
||||||
m_delayDeletion.push_back(boost::bind(delayDeletionDummy<T>, t));
|
m_delayDeletion.push_back([t] () {});
|
||||||
g_idle_add(&Server::delayDeletionCb, this);
|
g_idle_add(&Server::delayDeletionCb, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> static void delayDeletionDummy(const boost::shared_ptr<T> &t) throw () {}
|
template <class T> static void delayDeletionDummy(const std::shared_ptr<T> &t) throw () {}
|
||||||
static gboolean delayDeletionCb(gpointer userData) throw () {
|
static gboolean delayDeletionCb(gpointer userData) throw () {
|
||||||
Server *me = static_cast<Server *>(userData);
|
Server *me = static_cast<Server *>(userData);
|
||||||
|
|
||||||
|
@ -571,13 +553,13 @@ public:
|
||||||
* caller must do that or the request will automatically be
|
* caller must do that or the request will automatically be
|
||||||
* deleted.
|
* deleted.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<InfoReq> passwordRequest(const std::string &descr,
|
std::shared_ptr<InfoReq> passwordRequest(const std::string &descr,
|
||||||
const ConfigPasswordKey &key,
|
const ConfigPasswordKey &key,
|
||||||
const boost::weak_ptr<Session> &session);
|
const std::weak_ptr<Session> &session);
|
||||||
|
|
||||||
/** got response for earlier request, need to extract password and tell session */
|
/** got response for earlier request, need to extract password and tell session */
|
||||||
void passwordResponse(const StringMap &response,
|
void passwordResponse(const StringMap &response,
|
||||||
const boost::weak_ptr<Session> &session);
|
const std::weak_ptr<Session> &session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the given callback once in the given amount of seconds.
|
* Invokes the given callback once in the given amount of seconds.
|
||||||
|
@ -585,7 +567,7 @@ public:
|
||||||
* before that time, then the callback will be deleted without
|
* before that time, then the callback will be deleted without
|
||||||
* being called.
|
* being called.
|
||||||
*/
|
*/
|
||||||
void addTimeout(const boost::function<void ()> &callback,
|
void addTimeout(const std::function<void ()> &callback,
|
||||||
int seconds);
|
int seconds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -594,7 +576,7 @@ public:
|
||||||
* calling removeInfoReq() when the request becomes obsolete
|
* calling removeInfoReq() when the request becomes obsolete
|
||||||
* sooner than that.
|
* sooner than that.
|
||||||
*/
|
*/
|
||||||
boost::shared_ptr<InfoReq> createInfoReq(const string &type,
|
std::shared_ptr<InfoReq> createInfoReq(const string &type,
|
||||||
const std::map<string, string> ¶meters,
|
const std::map<string, string> ¶meters,
|
||||||
const Session &session);
|
const Session &session);
|
||||||
void autoTermRef(int counts = 1) { m_autoTerm.ref(counts); }
|
void autoTermRef(int counts = 1) { m_autoTerm.ref(counts); }
|
||||||
|
@ -610,9 +592,9 @@ public:
|
||||||
PresenceStatus& getPresenceStatus();
|
PresenceStatus& getPresenceStatus();
|
||||||
|
|
||||||
void clearPeerTempls() { m_matchedTempls.clear(); }
|
void clearPeerTempls() { m_matchedTempls.clear(); }
|
||||||
void addPeerTempl(const string &templName, const boost::shared_ptr<SyncConfig::TemplateDescription> peerTempl);
|
void addPeerTempl(const string &templName, const std::shared_ptr<SyncConfig::TemplateDescription> &peerTempl);
|
||||||
|
|
||||||
boost::shared_ptr<SyncConfig::TemplateDescription> getPeerTempl(const string &peer);
|
std::shared_ptr<SyncConfig::TemplateDescription> getPeerTempl(const string &peer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* methods to operate device list. See DeviceList definition.
|
* methods to operate device list. See DeviceList definition.
|
||||||
|
@ -671,7 +653,7 @@ public:
|
||||||
|
|
||||||
// extensions to the D-Bus server, created dynamically by main()
|
// extensions to the D-Bus server, created dynamically by main()
|
||||||
#ifdef ENABLE_DBUS_PIM
|
#ifdef ENABLE_DBUS_PIM
|
||||||
boost::shared_ptr<GDBusCXX::DBusObjectHelper> CreateContactManager(const boost::shared_ptr<Server> &server, bool start);
|
std::shared_ptr<GDBusCXX::DBusObjectHelper> CreateContactManager(const std::shared_ptr<Server> &server, bool start);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
static void dumpString(const std::string &output)
|
|
||||||
{
|
|
||||||
fputs(output.c_str(), stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same logging approach as in Server class: pretend that we
|
* Same logging approach as in Server class: pretend that we
|
||||||
* have reference counting for the SessionHelper class and
|
* have reference counting for the SessionHelper class and
|
||||||
|
@ -41,11 +36,11 @@ static void dumpString(const std::string &output)
|
||||||
class SessionHelperLogger : public Logger
|
class SessionHelperLogger : public Logger
|
||||||
{
|
{
|
||||||
Handle m_parentLogger;
|
Handle m_parentLogger;
|
||||||
boost::shared_ptr<SessionHelper> m_helper;
|
std::shared_ptr<SessionHelper> m_helper;
|
||||||
Level m_dbusLogLevel;
|
Level m_dbusLogLevel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SessionHelperLogger(const boost::shared_ptr<SessionHelper> &helper):
|
SessionHelperLogger(const std::shared_ptr<SessionHelper> &helper):
|
||||||
m_parentLogger(Logger::instance()),
|
m_parentLogger(Logger::instance()),
|
||||||
m_helper(helper),
|
m_helper(helper),
|
||||||
m_dbusLogLevel(DEBUG)
|
m_dbusLogLevel(DEBUG)
|
||||||
|
@ -87,7 +82,9 @@ public:
|
||||||
options.m_processName,
|
options.m_processName,
|
||||||
options.m_prefix,
|
options.m_prefix,
|
||||||
format, argsCopy,
|
format, argsCopy,
|
||||||
boost::bind(dumpString, _1));
|
[] (const std::string &output, size_t expectedTotal) {
|
||||||
|
fputs(output.c_str(), stdout);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
va_end(argsCopy);
|
va_end(argsCopy);
|
||||||
} else if (m_parentLogger) {
|
} else if (m_parentLogger) {
|
||||||
|
@ -126,7 +123,7 @@ public:
|
||||||
|
|
||||||
SessionHelper::SessionHelper(GMainLoop *loop,
|
SessionHelper::SessionHelper(GMainLoop *loop,
|
||||||
const GDBusCXX::DBusConnectionPtr &conn,
|
const GDBusCXX::DBusConnectionPtr &conn,
|
||||||
const boost::shared_ptr<ForkExecChild> &forkexec) :
|
const std::shared_ptr<ForkExecChild> &forkexec) :
|
||||||
GDBusCXX::DBusObjectHelper(conn,
|
GDBusCXX::DBusObjectHelper(conn,
|
||||||
std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(),
|
std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(),
|
||||||
SessionCommon::HELPER_IFACE,
|
SessionCommon::HELPER_IFACE,
|
||||||
|
@ -135,7 +132,7 @@ SessionHelper::SessionHelper(GMainLoop *loop,
|
||||||
m_loop(loop),
|
m_loop(loop),
|
||||||
m_conn(conn),
|
m_conn(conn),
|
||||||
m_forkexec(forkexec),
|
m_forkexec(forkexec),
|
||||||
m_logger(new SessionHelperLogger(boost::shared_ptr<SessionHelper>(this, NopDestructor()))),
|
m_logger(new SessionHelperLogger(std::shared_ptr<SessionHelper>(this, NopDestructor()))),
|
||||||
emitLogOutput(*this, "LogOutput"),
|
emitLogOutput(*this, "LogOutput"),
|
||||||
emitSyncProgress(*this, "SyncProgress"),
|
emitSyncProgress(*this, "SyncProgress"),
|
||||||
emitSourceProgress(*this, "SourceProgress"),
|
emitSourceProgress(*this, "SourceProgress"),
|
||||||
|
@ -210,15 +207,17 @@ bool SessionHelper::connected()
|
||||||
return m_forkexec && m_forkexec->getState() == ForkExecChild::CONNECTED;
|
return m_forkexec && m_forkexec->getState() == ForkExecChild::CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: the common wrapper code (i.e. sync/restore/execute) could be moved into a template function...
|
||||||
|
|
||||||
void SessionHelper::sync(const SessionCommon::SyncParams ¶ms,
|
void SessionHelper::sync(const SessionCommon::SyncParams ¶ms,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
|
||||||
{
|
{
|
||||||
m_operation = boost::bind(&SessionHelper::doSync, this, params, result);
|
m_operation = [this, params, result] () { return doSync(params, result); };
|
||||||
g_main_loop_quit(m_loop);
|
g_main_loop_quit(m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionHelper::doSync(const SessionCommon::SyncParams ¶ms,
|
bool SessionHelper::doSync(const SessionCommon::SyncParams ¶ms,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_sync.reset(new DBusSync(params, *this));
|
m_sync.reset(new DBusSync(params, *this));
|
||||||
|
@ -245,15 +244,15 @@ bool SessionHelper::doSync(const SessionCommon::SyncParams ¶ms,
|
||||||
|
|
||||||
void SessionHelper::restore(const std::string &configName,
|
void SessionHelper::restore(const std::string &configName,
|
||||||
const string &dir, bool before, const std::vector<std::string> &sources,
|
const string &dir, bool before, const std::vector<std::string> &sources,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result)
|
||||||
{
|
{
|
||||||
m_operation = boost::bind(&SessionHelper::doRestore, this, configName, dir, before, sources, result);
|
m_operation = [this, configName, dir, before, sources, result] () { return doRestore(configName, dir, before, sources, result); };
|
||||||
g_main_loop_quit(m_loop);
|
g_main_loop_quit(m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionHelper::doRestore(const std::string &configName,
|
bool SessionHelper::doRestore(const std::string &configName,
|
||||||
const string &dir, bool before, const std::vector<std::string> &sources,
|
const string &dir, bool before, const std::vector<std::string> &sources,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
SessionCommon::SyncParams params;
|
SessionCommon::SyncParams params;
|
||||||
|
@ -285,14 +284,14 @@ bool SessionHelper::doRestore(const std::string &configName,
|
||||||
|
|
||||||
|
|
||||||
void SessionHelper::execute(const vector<string> &args, const map<string, string> &vars,
|
void SessionHelper::execute(const vector<string> &args, const map<string, string> &vars,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result)
|
||||||
{
|
{
|
||||||
m_operation = boost::bind(&SessionHelper::doExecute, this, args, vars, result);
|
m_operation = [this, args, vars, result] () { return doExecute(args, vars, result); };
|
||||||
g_main_loop_quit(m_loop);
|
g_main_loop_quit(m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionHelper::doExecute(const vector<string> &args, const map<string, string> &vars,
|
bool SessionHelper::doExecute(const vector<string> &args, const map<string, string> &vars,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result)
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
CmdlineWrapper cmdline(*this, args, vars);
|
CmdlineWrapper cmdline(*this, args, vars);
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
#include "dbus-sync.h"
|
#include "dbus-sync.h"
|
||||||
|
|
||||||
#include <gdbus-cxx-bridge.h>
|
#include <gdbus-cxx-bridge.h>
|
||||||
#include <boost/function.hpp>
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -48,9 +48,9 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
|
||||||
{
|
{
|
||||||
GMainLoop *m_loop;
|
GMainLoop *m_loop;
|
||||||
GDBusCXX::DBusConnectionPtr m_conn;
|
GDBusCXX::DBusConnectionPtr m_conn;
|
||||||
boost::shared_ptr<ForkExecChild> m_forkexec;
|
std::shared_ptr<ForkExecChild> m_forkexec;
|
||||||
boost::function<bool ()> m_operation;
|
std::function<bool ()> m_operation;
|
||||||
boost::shared_ptr<SessionHelperLogger> m_logger;
|
std::shared_ptr<SessionHelperLogger> m_logger;
|
||||||
PushLogger<Logger> m_pushLogger;
|
PushLogger<Logger> m_pushLogger;
|
||||||
|
|
||||||
/** valid during doSync() */
|
/** valid during doSync() */
|
||||||
|
@ -58,26 +58,26 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
|
||||||
|
|
||||||
/** called by main event loop: initiate a sync operation */
|
/** called by main event loop: initiate a sync operation */
|
||||||
void sync(const SessionCommon::SyncParams ¶ms,
|
void sync(const SessionCommon::SyncParams ¶ms,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by run(): do the sync operation
|
* called by run(): do the sync operation
|
||||||
* @return true if the helper is meant to terminate
|
* @return true if the helper is meant to terminate
|
||||||
*/
|
*/
|
||||||
bool doSync(const SessionCommon::SyncParams ¶ms,
|
bool doSync(const SessionCommon::SyncParams ¶ms,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
|
||||||
|
|
||||||
void restore(const std::string &configName,
|
void restore(const std::string &configName,
|
||||||
const string &dir, bool before, const std::vector<std::string> &sources,
|
const string &dir, bool before, const std::vector<std::string> &sources,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result);
|
||||||
bool doRestore(const std::string &configName,
|
bool doRestore(const std::string &configName,
|
||||||
const string &dir, bool before, const std::vector<std::string> &sources,
|
const string &dir, bool before, const std::vector<std::string> &sources,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result);
|
||||||
|
|
||||||
void execute(const vector<string> &args, const map<string, string> &vars,
|
void execute(const vector<string> &args, const map<string, string> &vars,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result);
|
||||||
bool doExecute(const vector<string> &args, const map<string, string> &vars,
|
bool doExecute(const vector<string> &args, const map<string, string> &vars,
|
||||||
const boost::shared_ptr< GDBusCXX::Result<bool> > &result);
|
const std::shared_ptr< GDBusCXX::Result<bool> > &result);
|
||||||
|
|
||||||
/** SessionHelper.PasswordResponse */
|
/** SessionHelper.PasswordResponse */
|
||||||
void passwordResponse(bool timedOut, bool aborted, const std::string &password);
|
void passwordResponse(bool timedOut, bool aborted, const std::string &password);
|
||||||
|
@ -88,7 +88,7 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
|
||||||
public:
|
public:
|
||||||
SessionHelper(GMainLoop *loop,
|
SessionHelper(GMainLoop *loop,
|
||||||
const GDBusCXX::DBusConnectionPtr &conn,
|
const GDBusCXX::DBusConnectionPtr &conn,
|
||||||
const boost::shared_ptr<ForkExecChild> &forkexec);
|
const std::shared_ptr<ForkExecChild> &forkexec);
|
||||||
~SessionHelper();
|
~SessionHelper();
|
||||||
|
|
||||||
void setDBusLogLevel(Logger::Level level);
|
void setDBusLogLevel(Logger::Level level);
|
||||||
|
@ -101,7 +101,7 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
|
||||||
/** Still have connection to parent. Shortcut which asks the ForkExecChild class. */
|
/** Still have connection to parent. Shortcut which asks the ForkExecChild class. */
|
||||||
bool connected();
|
bool connected();
|
||||||
|
|
||||||
boost::shared_ptr<ForkExecChild> getForkExecChild() { return m_forkexec; }
|
std::shared_ptr<ForkExecChild> getForkExecChild() { return m_forkexec; }
|
||||||
|
|
||||||
/** Server.LogOutput for the session D-Bus object */
|
/** Server.LogOutput for the session D-Bus object */
|
||||||
GDBusCXX::EmitSignalOptional<std::string,
|
GDBusCXX::EmitSignalOptional<std::string,
|
||||||
|
|
|
@ -120,20 +120,17 @@ public:
|
||||||
|
|
||||||
void Session::attach(const Caller_t &caller)
|
void Session::attach(const Caller_t &caller)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client(m_server.findClient(caller));
|
std::shared_ptr<Client> client(m_server.findClient(caller));
|
||||||
if (!client) {
|
if (!client) {
|
||||||
throw runtime_error("unknown client");
|
throw runtime_error("unknown client");
|
||||||
}
|
}
|
||||||
boost::shared_ptr<Session> me = m_me.lock();
|
std::shared_ptr<Session> me = shared_from_this();
|
||||||
if (!me) {
|
|
||||||
throw runtime_error("session already deleted?!");
|
|
||||||
}
|
|
||||||
client->attach(me);
|
client->attach(me);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::detach(const Caller_t &caller)
|
void Session::detach(const Caller_t &caller)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Client> client(m_server.findClient(caller));
|
std::shared_ptr<Client> client(m_server.findClient(caller));
|
||||||
if (!client) {
|
if (!client) {
|
||||||
throw runtime_error("unknown client");
|
throw runtime_error("unknown client");
|
||||||
}
|
}
|
||||||
|
@ -206,7 +203,7 @@ void Session::setNamedConfig(const std::string &configName,
|
||||||
bool update, bool temporary,
|
bool update, bool temporary,
|
||||||
const ReadOperations::Config_t &config)
|
const ReadOperations::Config_t &config)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation != SessionCommon::OP_NULL) {
|
if (m_runOperation != SessionCommon::OP_NULL) {
|
||||||
string msg = StringPrintf("%s started, cannot change configuration at this time", runOpToString(m_runOperation).c_str());
|
string msg = StringPrintf("%s started, cannot change configuration at this time", runOpToString(m_runOperation).c_str());
|
||||||
SE_THROW_EXCEPTION(InvalidCall, msg);
|
SE_THROW_EXCEPTION(InvalidCall, msg);
|
||||||
|
@ -237,7 +234,7 @@ void Session::setNamedConfig(const std::string &configName,
|
||||||
m_server.getPresenceStatus().updateConfigPeers (configName, config);
|
m_server.getPresenceStatus().updateConfigPeers (configName, config);
|
||||||
/** check whether we need remove the entire configuration */
|
/** check whether we need remove the entire configuration */
|
||||||
if(!update && !temporary && config.empty()) {
|
if(!update && !temporary && config.empty()) {
|
||||||
boost::shared_ptr<SyncConfig> syncConfig(new SyncConfig(configName));
|
auto syncConfig = std::make_shared<SyncConfig>(configName);
|
||||||
if(syncConfig.get()) {
|
if(syncConfig.get()) {
|
||||||
syncConfig->remove();
|
syncConfig->remove();
|
||||||
m_setConfig = true;
|
m_setConfig = true;
|
||||||
|
@ -275,7 +272,7 @@ void Session::setNamedConfig(const std::string &configName,
|
||||||
m_tempConfig = true;
|
m_tempConfig = true;
|
||||||
} else {
|
} else {
|
||||||
/* need to save configurations */
|
/* need to save configurations */
|
||||||
boost::shared_ptr<SyncConfig> from(new SyncConfig(configName));
|
auto from = std::make_shared<SyncConfig>(configName);
|
||||||
/* if it is not clear mode and config does not exist, an error throws */
|
/* if it is not clear mode and config does not exist, an error throws */
|
||||||
if(update && !from->exists()) {
|
if(update && !from->exists()) {
|
||||||
SE_THROW_EXCEPTION(NoSuchConfig, "The configuration '" + configName + "' doesn't exist" );
|
SE_THROW_EXCEPTION(NoSuchConfig, "The configuration '" + configName + "' doesn't exist" );
|
||||||
|
@ -313,7 +310,7 @@ void Session::setNamedConfig(const std::string &configName,
|
||||||
|
|
||||||
// We need no interactive user interface, but we do need to handle
|
// We need no interactive user interface, but we do need to handle
|
||||||
// storing passwords in a keyring here.
|
// storing passwords in a keyring here.
|
||||||
boost::shared_ptr<SyncContext> syncConfig(new SyncContext(configName));
|
auto syncConfig = std::make_shared<SyncContext>(configName);
|
||||||
syncConfig->prepareConfigForWrite();
|
syncConfig->prepareConfigForWrite();
|
||||||
syncConfig->copy(*from, NULL);
|
syncConfig->copy(*from, NULL);
|
||||||
|
|
||||||
|
@ -349,7 +346,7 @@ void Session::setNamedConfig(const std::string &configName,
|
||||||
|
|
||||||
void Session::initServer(SharedBuffer data, const std::string &messageType)
|
void Session::initServer(SharedBuffer data, const std::string &messageType)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
m_serverMode = true;
|
m_serverMode = true;
|
||||||
m_initialMessage = data;
|
m_initialMessage = data;
|
||||||
m_initialMessageType = messageType;
|
m_initialMessageType = messageType;
|
||||||
|
@ -358,7 +355,7 @@ void Session::initServer(SharedBuffer data, const std::string &messageType)
|
||||||
void Session::syncExtended(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes,
|
void Session::syncExtended(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes,
|
||||||
const StringMap &env)
|
const StringMap &env)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation == SessionCommon::OP_SYNC) {
|
if (m_runOperation == SessionCommon::OP_SYNC) {
|
||||||
string msg = StringPrintf("%s started, cannot start again", runOpToString(m_runOperation).c_str());
|
string msg = StringPrintf("%s started, cannot start again", runOpToString(m_runOperation).c_str());
|
||||||
SE_THROW_EXCEPTION(InvalidCall, msg);
|
SE_THROW_EXCEPTION(InvalidCall, msg);
|
||||||
|
@ -377,13 +374,13 @@ void Session::syncExtended(const std::string &mode, const SessionCommon::SourceM
|
||||||
// caller. Starting the helper (if needed) and making it
|
// caller. Starting the helper (if needed) and making it
|
||||||
// execute the sync is part of "running sync".
|
// execute the sync is part of "running sync".
|
||||||
runOperationAsync(SessionCommon::OP_SYNC,
|
runOperationAsync(SessionCommon::OP_SYNC,
|
||||||
boost::bind(&Session::sync2, this, mode, sourceModes),
|
[this, mode, sourceModes] () { sync2(mode, sourceModes); },
|
||||||
env);
|
env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes)
|
void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (!m_forkExecParent || !m_helper) {
|
if (!m_forkExecParent || !m_helper) {
|
||||||
SE_THROW("syncing cannot continue, helper died");
|
SE_THROW("syncing cannot continue, helper died");
|
||||||
}
|
}
|
||||||
|
@ -403,7 +400,7 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
|
||||||
params.m_sourceFilter = m_sourceFilter;
|
params.m_sourceFilter = m_sourceFilter;
|
||||||
params.m_sourceFilters = m_sourceFilters;
|
params.m_sourceFilters = m_sourceFilters;
|
||||||
|
|
||||||
boost::shared_ptr<Connection> c = m_connection.lock();
|
std::shared_ptr<Connection> c = m_connection.lock();
|
||||||
if (c && !c->mustAuthenticate()) {
|
if (c && !c->mustAuthenticate()) {
|
||||||
// unsetting username/password disables checking them
|
// unsetting username/password disables checking them
|
||||||
params.m_syncFilter["password"] = InitStateString("", true);
|
params.m_syncFilter["password"] = InitStateString("", true);
|
||||||
|
@ -421,19 +418,52 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
|
||||||
//
|
//
|
||||||
// Session might quit before connection, so use instance
|
// Session might quit before connection, so use instance
|
||||||
// tracking.
|
// tracking.
|
||||||
m_helper->m_sendMessage.activate(boost::bind(&Session::sendViaConnection,
|
auto sendViaConnection = [this] (const DBusArray<uint8_t> buffer,
|
||||||
this,
|
const std::string &type,
|
||||||
_1, _2, _3));
|
const std::string &url) {
|
||||||
m_helper->m_shutdownConnection.activate(boost::bind(&Session::shutdownConnection,
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
this));
|
try {
|
||||||
boost::shared_ptr<Connection> connection = m_connection.lock();
|
std::shared_ptr<Connection> connection = m_connection.lock();
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
SE_THROW_EXCEPTION(TransportException,
|
||||||
|
"D-Bus peer has disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->send(buffer, type, url);
|
||||||
|
} catch (...) {
|
||||||
|
std::string explanation;
|
||||||
|
Exception::handle(explanation);
|
||||||
|
connectionState(explanation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_helper->m_sendMessage.activate(sendViaConnection);
|
||||||
|
auto shutdownConnection = [this] () {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
try {
|
||||||
|
std::shared_ptr<Connection> connection = m_connection.lock();
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
SE_THROW_EXCEPTION(TransportException,
|
||||||
|
"D-Bus peer has disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->sendFinalMsg();
|
||||||
|
} catch (...) {
|
||||||
|
std::string explanation;
|
||||||
|
Exception::handle(explanation);
|
||||||
|
connectionState(explanation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_helper->m_shutdownConnection.activate(shutdownConnection);
|
||||||
|
std::shared_ptr<Connection> connection = m_connection.lock();
|
||||||
if (connection) {
|
if (connection) {
|
||||||
connection->m_messageSignal.connect(Connection::MessageSignal_t::slot_type(&Session::storeMessage,
|
connection->m_messageSignal.connect(Connection::MessageSignal_t::slot_type(&Session::storeMessage,
|
||||||
this,
|
this,
|
||||||
_1, _2).track(m_me));
|
_1, _2).track_foreign(weak_from_this()));
|
||||||
connection->m_statusSignal.connect(Connection::StatusSignal_t::slot_type(&Session::connectionState,
|
connection->m_statusSignal.connect(Connection::StatusSignal_t::slot_type(&Session::connectionState,
|
||||||
this,
|
this,
|
||||||
_1));
|
_1).track_foreign(weak_from_this()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper implements Sync() asynchronously. If it completes
|
// Helper implements Sync() asynchronously. If it completes
|
||||||
|
@ -441,13 +471,15 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
|
||||||
// the error is recorded before ending the session. Premature
|
// the error is recorded before ending the session. Premature
|
||||||
// exits by the helper are handled by D-Bus, which then will abort
|
// exits by the helper are handled by D-Bus, which then will abort
|
||||||
// the pending method call.
|
// the pending method call.
|
||||||
m_helper->m_sync.start(boost::bind(&Session::dbusResultCb, m_me, "sync()", _1, _2, _3),
|
m_helper->m_sync.start([me = weak_from_this()] (bool success, const SyncReport &report, const std::string &error) {
|
||||||
|
dbusResultCb(me, "sync()", success, report, error);
|
||||||
|
},
|
||||||
params);
|
params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::abort()
|
void Session::abort()
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
|
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
|
||||||
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot abort at this time");
|
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot abort at this time");
|
||||||
}
|
}
|
||||||
|
@ -468,29 +500,18 @@ void Session::abort()
|
||||||
|
|
||||||
void Session::setFreezeAsync(bool freeze, const Result<void (bool)> &result)
|
void Session::setFreezeAsync(bool freeze, const Result<void (bool)> &result)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s), %s",
|
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s), %s",
|
||||||
getPath(),
|
getPath(),
|
||||||
freeze ? "freeze" : "thaw",
|
freeze ? "freeze" : "thaw",
|
||||||
m_forkExecParent ? "send to helper" : "no effect, because no helper");
|
m_forkExecParent ? "send to helper" : "no effect, because no helper");
|
||||||
if (m_forkExecParent) {
|
if (m_forkExecParent) {
|
||||||
m_helper->m_setFreeze.start(boost::bind(&Session::setFreezeDone,
|
auto done = [this, me = weak_from_this(), freeze, result] (bool changed, const std::string &error) noexcept {
|
||||||
m_me,
|
auto lock = me.lock();
|
||||||
_1, _2,
|
if (!lock) {
|
||||||
freeze,
|
return;
|
||||||
result),
|
|
||||||
freeze);
|
|
||||||
} else {
|
|
||||||
// Had no effect.
|
|
||||||
result.done(false);
|
|
||||||
}
|
}
|
||||||
}
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
|
||||||
void Session::setFreezeDone(bool changed, const std::string &error,
|
|
||||||
bool freeze,
|
|
||||||
const Result<void (bool)> &result)
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
try {
|
||||||
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s) returned from helper %s, error %s",
|
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s) returned from helper %s, error %s",
|
||||||
getPath(),
|
getPath(),
|
||||||
|
@ -507,11 +528,17 @@ void Session::setFreezeDone(bool changed, const std::string &error,
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
result.failed();
|
result.failed();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
m_helper->m_setFreeze.start(done, freeze);
|
||||||
|
} else {
|
||||||
|
// Had no effect.
|
||||||
|
result.done(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::suspend()
|
void Session::suspend()
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
|
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
|
||||||
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot suspend at this time");
|
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot suspend at this time");
|
||||||
}
|
}
|
||||||
|
@ -528,7 +555,7 @@ void Session::suspend()
|
||||||
|
|
||||||
void Session::abortAsync(const SimpleResult &result)
|
void Session::abortAsync(const SimpleResult &result)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (!m_forkExecParent) {
|
if (!m_forkExecParent) {
|
||||||
result.done();
|
result.done();
|
||||||
} else {
|
} else {
|
||||||
|
@ -537,7 +564,7 @@ void Session::abortAsync(const SimpleResult &result)
|
||||||
// This must succeed; there is no timeout or failure mode.
|
// This must succeed; there is no timeout or failure mode.
|
||||||
// TODO: kill helper after a certain amount of time?!
|
// TODO: kill helper after a certain amount of time?!
|
||||||
m_forkExecParent->stop(SIGTERM);
|
m_forkExecParent->stop(SIGTERM);
|
||||||
m_forkExecParent->m_onQuit.connect(boost::bind(&SimpleResult::done, result));
|
m_forkExecParent->m_onQuit.connect([result] (int) { result.done(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +572,7 @@ void Session::getStatus(std::string &status,
|
||||||
uint32_t &error,
|
uint32_t &error,
|
||||||
SourceStatuses_t &sources)
|
SourceStatuses_t &sources)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
status = syncStatusToString(m_syncStatus);
|
status = syncStatusToString(m_syncStatus);
|
||||||
if (m_stepIsWaiting) {
|
if (m_stepIsWaiting) {
|
||||||
status += ";waiting";
|
status += ";waiting";
|
||||||
|
@ -558,7 +585,7 @@ void Session::getStatus(std::string &status,
|
||||||
void Session::getAPIProgress(int32_t &progress,
|
void Session::getAPIProgress(int32_t &progress,
|
||||||
APISourceProgresses_t &sources)
|
APISourceProgresses_t &sources)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
progress = m_progData.getProgress();
|
progress = m_progData.getProgress();
|
||||||
sources = m_sourceProgress;
|
sources = m_sourceProgress;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +593,7 @@ void Session::getAPIProgress(int32_t &progress,
|
||||||
void Session::getProgress(int32_t &progress,
|
void Session::getProgress(int32_t &progress,
|
||||||
SourceProgresses_t &sources)
|
SourceProgresses_t &sources)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
progress = m_progData.getProgress();
|
progress = m_progData.getProgress();
|
||||||
sources = m_sourceProgress;
|
sources = m_sourceProgress;
|
||||||
}
|
}
|
||||||
|
@ -584,7 +611,7 @@ bool Session::getSyncSourceReport(const std::string &sourceName, SyncSourceRepor
|
||||||
|
|
||||||
void Session::fireStatus(bool flush)
|
void Session::fireStatus(bool flush)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
std::string status;
|
std::string status;
|
||||||
uint32_t error;
|
uint32_t error;
|
||||||
SourceStatuses_t sources;
|
SourceStatuses_t sources;
|
||||||
|
@ -601,7 +628,7 @@ void Session::fireStatus(bool flush)
|
||||||
|
|
||||||
void Session::fireProgress(bool flush)
|
void Session::fireProgress(bool flush)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
int32_t progress;
|
int32_t progress;
|
||||||
SourceProgresses_t sources;
|
SourceProgresses_t sources;
|
||||||
|
|
||||||
|
@ -615,22 +642,6 @@ void Session::fireProgress(bool flush)
|
||||||
m_progressSignal(progress, sources);
|
m_progressSignal(progress, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Session> Session::createSession(Server &server,
|
|
||||||
const std::string &peerDeviceID,
|
|
||||||
const std::string &config_name,
|
|
||||||
const std::string &session,
|
|
||||||
const std::vector<std::string> &flags)
|
|
||||||
{
|
|
||||||
boost::shared_ptr<Session> me(new Session(server, peerDeviceID, config_name, session, flags));
|
|
||||||
me->m_me = me;
|
|
||||||
return me;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetProgress(Session::SourceProgresses_t &to, const Session::SourceProgresses_t &from)
|
|
||||||
{
|
|
||||||
to = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::Session(Server &server,
|
Session::Session(Server &server,
|
||||||
const std::string &peerDeviceID,
|
const std::string &peerDeviceID,
|
||||||
const std::string &config_name,
|
const std::string &config_name,
|
||||||
|
@ -639,7 +650,7 @@ Session::Session(Server &server,
|
||||||
DBusObjectHelper(server.getConnection(),
|
DBusObjectHelper(server.getConnection(),
|
||||||
std::string("/org/syncevolution/Session/") + session,
|
std::string("/org/syncevolution/Session/") + session,
|
||||||
"org.syncevolution.Session",
|
"org.syncevolution.Session",
|
||||||
boost::bind(&Server::autoTermCallback, &server)),
|
[serverPtr = &server] () { serverPtr->autoTermCallback(); }),
|
||||||
ReadOperations(config_name, server),
|
ReadOperations(config_name, server),
|
||||||
m_flags(flags),
|
m_flags(flags),
|
||||||
m_sessionID(session),
|
m_sessionID(session),
|
||||||
|
@ -689,23 +700,30 @@ Session::Session(Server &server,
|
||||||
add(this, &Session::execute, "Execute");
|
add(this, &Session::execute, "Execute");
|
||||||
add(emitStatus);
|
add(emitStatus);
|
||||||
add(emitProgress);
|
add(emitProgress);
|
||||||
m_statusSignal.connect(boost::bind(boost::ref(emitStatus), _1, _2, _3));
|
auto status = [this] (const std::string &status,
|
||||||
m_progressSignal.connect(boost::bind(&Timespec::resetMonotonic, &m_lastProgressTimestamp));
|
uint32_t error,
|
||||||
m_progressSignal.connect(boost::bind(SetProgress, boost::ref(m_lastProgress), _2));
|
const SourceStatuses_t &sources) {
|
||||||
m_progressSignal.connect(boost::bind(boost::ref(emitProgress), _1, _2));
|
emitStatus(status, error, sources);
|
||||||
|
};
|
||||||
|
m_statusSignal.connect(status);
|
||||||
|
auto progress = [this] (int32_t progress,
|
||||||
|
const SourceProgresses_t &sources) {
|
||||||
|
m_lastProgressTimestamp.resetMonotonic();
|
||||||
|
m_lastProgress = sources;
|
||||||
|
emitProgress(progress, sources);
|
||||||
|
};
|
||||||
|
m_progressSignal.connect(progress);
|
||||||
|
|
||||||
SE_LOG_DEBUG(NULL, "session %s created", getPath());
|
SE_LOG_DEBUG(NULL, "session %s created", getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::passwordRequest(const std::string &descr, const ConfigPasswordKey &key)
|
void Session::dbusResultCb(const std::weak_ptr<Session> &me, const std::string &operation, bool success, const SyncReport &report, const std::string &error) noexcept
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
auto lock = me.lock();
|
||||||
m_passwordRequest = m_server.passwordRequest(descr, key, m_me);
|
if (!lock) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
PushLogger<Logger> guard(me);
|
||||||
void Session::dbusResultCb(const std::string &operation, bool success, const SyncReport &report, const std::string &error) throw()
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
try {
|
||||||
SE_LOG_DEBUG(NULL, "%s helper call completed, %s",
|
SE_LOG_DEBUG(NULL, "%s helper call completed, %s",
|
||||||
operation.c_str(),
|
operation.c_str(),
|
||||||
|
@ -713,7 +731,7 @@ void Session::dbusResultCb(const std::string &operation, bool success, const Syn
|
||||||
success ? "<<successfully>>" :
|
success ? "<<successfully>>" :
|
||||||
"<<unsuccessfully>>");
|
"<<unsuccessfully>>");
|
||||||
if (error.empty()) {
|
if (error.empty()) {
|
||||||
doneCb(success, report);
|
lock->doneCb(false, success, report);
|
||||||
} else {
|
} else {
|
||||||
// Translate back into local exception, will be handled by
|
// Translate back into local exception, will be handled by
|
||||||
// catch clause and (eventually) failureCb().
|
// catch clause and (eventually) failureCb().
|
||||||
|
@ -723,13 +741,13 @@ void Session::dbusResultCb(const std::string &operation, bool success, const Syn
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
failureCb();
|
lock->failureCb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::failureCb() throw()
|
void Session::failureCb() throw()
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
try {
|
try {
|
||||||
if (m_status == SESSION_DONE) {
|
if (m_status == SESSION_DONE) {
|
||||||
// ignore errors that happen after session already closed,
|
// ignore errors that happen after session already closed,
|
||||||
|
@ -760,7 +778,7 @@ void Session::failureCb() throw()
|
||||||
m_error = error;
|
m_error = error;
|
||||||
}
|
}
|
||||||
// will fire status signal, including the error
|
// will fire status signal, including the error
|
||||||
doneCb(false);
|
doneCb(false, false);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// fatal problem, log it and terminate
|
// fatal problem, log it and terminate
|
||||||
|
@ -768,9 +786,15 @@ void Session::failureCb() throw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::doneCb(bool success, const SyncReport &report) throw()
|
void Session::doneCb(bool destruct, bool success, const SyncReport &report) noexcept
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
// When called from our destructor, then weak_from_this() fails (__cxa_call_unexpected).
|
||||||
|
// We have to ignore logging in that case.
|
||||||
|
std::weak_ptr<Session> me;
|
||||||
|
if (!destruct) {
|
||||||
|
me = weak_from_this();
|
||||||
|
}
|
||||||
|
PushLogger<Logger> guard(me);
|
||||||
try {
|
try {
|
||||||
if (m_status == SESSION_DONE) {
|
if (m_status == SESSION_DONE) {
|
||||||
return;
|
return;
|
||||||
|
@ -784,7 +808,7 @@ void Session::doneCb(bool success, const SyncReport &report) throw()
|
||||||
|
|
||||||
fireStatus(true);
|
fireStatus(true);
|
||||||
|
|
||||||
boost::shared_ptr<Connection> connection = m_connection.lock();
|
std::shared_ptr<Connection> connection = m_connection.lock();
|
||||||
if (connection) {
|
if (connection) {
|
||||||
connection->shutdown();
|
connection->shutdown();
|
||||||
}
|
}
|
||||||
|
@ -823,38 +847,27 @@ Session::~Session()
|
||||||
{
|
{
|
||||||
SE_LOG_DEBUG(NULL, "session %s deconstructing", getPath());
|
SE_LOG_DEBUG(NULL, "session %s deconstructing", getPath());
|
||||||
// If we are not done yet, then something went wrong.
|
// If we are not done yet, then something went wrong.
|
||||||
doneCb(false);
|
doneCb(true, false);
|
||||||
}
|
|
||||||
|
|
||||||
/** child has quit before connecting, invoke result.failed() with suitable exception pending */
|
|
||||||
static void raiseChildTermError(int status, const SimpleResult &result)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
SE_THROW(StringPrintf("helper died unexpectedly with return code %d before connecting", status));
|
|
||||||
} catch (...) {
|
|
||||||
result.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::runOperationAsync(SessionCommon::RunOperation op,
|
void Session::runOperationAsync(SessionCommon::RunOperation op,
|
||||||
const SuccessCb_t &helperReady,
|
const SuccessCb_t &helperReady,
|
||||||
const StringMap &env)
|
const StringMap &env)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
m_server.addSyncSession(this);
|
m_server.addSyncSession(this);
|
||||||
m_runOperation = op;
|
m_runOperation = op;
|
||||||
m_status = SESSION_RUNNING;
|
m_status = SESSION_RUNNING;
|
||||||
m_syncStatus = SYNC_RUNNING;
|
m_syncStatus = SYNC_RUNNING;
|
||||||
fireStatus(true);
|
fireStatus(true);
|
||||||
|
|
||||||
useHelperAsync(SimpleResult(helperReady,
|
useHelperAsync(SimpleResult(helperReady, [this] () { failureCb(); }),
|
||||||
boost::bind(&Session::failureCb, this)),
|
|
||||||
env);
|
env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
|
void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
try {
|
try {
|
||||||
if (m_helper) {
|
if (m_helper) {
|
||||||
// exists already, invoke callback directly
|
// exists already, invoke callback directly
|
||||||
|
@ -871,7 +884,7 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
args.push_back("--dbus-verbosity");
|
args.push_back("--dbus-verbosity");
|
||||||
args.push_back(StringPrintf("%d", m_server.getDBusLogLevel()));
|
args.push_back(StringPrintf("%d", m_server.getDBusLogLevel()));
|
||||||
m_forkExecParent = SyncEvo::ForkExecParent::create("syncevo-dbus-helper", args);
|
m_forkExecParent = make_weak_shared::make<ForkExecParent>("syncevo-dbus-helper", args);
|
||||||
#ifdef USE_DLT
|
#ifdef USE_DLT
|
||||||
if (getenv("SYNCEVOLUTION_USE_DLT")) {
|
if (getenv("SYNCEVOLUTION_USE_DLT")) {
|
||||||
m_forkExecParent->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel()));
|
m_forkExecParent->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel()));
|
||||||
|
@ -887,9 +900,114 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
|
||||||
// m_forkExecParent -> no need for resource
|
// m_forkExecParent -> no need for resource
|
||||||
// tracking. onConnect sets up m_helper. The other two
|
// tracking. onConnect sets up m_helper. The other two
|
||||||
// only log the event.
|
// only log the event.
|
||||||
m_forkExecParent->m_onConnect.connect(bind(&Session::onConnect, this, _1));
|
auto onConnect = [this] (const GDBusCXX::DBusConnectionPtr &conn) noexcept {
|
||||||
m_forkExecParent->m_onQuit.connect(boost::bind(&Session::onQuit, this, _1));
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
m_forkExecParent->m_onFailure.connect(boost::bind(&Session::onFailure, this, _1, _2));
|
try {
|
||||||
|
std::string instance = m_forkExecParent->getInstance();
|
||||||
|
SE_LOG_DEBUG(NULL, "helper %s has connected", instance.c_str());
|
||||||
|
m_helper.reset(new SessionProxy(conn, instance));
|
||||||
|
|
||||||
|
// Activate signal watch on helper signals.
|
||||||
|
m_helper->m_syncProgress.activate([this] (sysync::TProgressEventEnum type,
|
||||||
|
int32_t extra1, int32_t extra2, int32_t extra3) {
|
||||||
|
syncProgress(type, extra1, extra2, extra3);
|
||||||
|
});
|
||||||
|
m_helper->m_sourceProgress.activate([this] (sysync::TProgressEventEnum type,
|
||||||
|
const std::string &sourceName,
|
||||||
|
SyncMode sourceSyncMode,
|
||||||
|
int32_t extra1, int32_t extra2, int32_t extra3) {
|
||||||
|
sourceProgress(type, sourceName, sourceSyncMode, extra1, extra2, extra3);
|
||||||
|
});
|
||||||
|
m_helper->m_sourceSynced.activate([this] (const std::string &name, const SyncSourceReport &report) {
|
||||||
|
m_sourceSynced(name, report);
|
||||||
|
});
|
||||||
|
m_sourceSynced.connect([this] (const std::string &name, const SyncSourceReport &report) {
|
||||||
|
m_syncSourceReports[name] = report;
|
||||||
|
});
|
||||||
|
auto setWaiting = [this] (bool isWaiting) {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
// if stepInfo doesn't change, then ignore it to avoid duplicate status info
|
||||||
|
if (m_stepIsWaiting != isWaiting) {
|
||||||
|
m_stepIsWaiting = isWaiting;
|
||||||
|
fireStatus(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_helper->m_waiting.activate(setWaiting);
|
||||||
|
m_helper->m_syncSuccessStart.activate([this] () {
|
||||||
|
m_syncSuccessStartSignal();
|
||||||
|
});
|
||||||
|
m_helper->m_configChanged.activate([this] () {
|
||||||
|
m_server.m_configChangedSignal("");
|
||||||
|
});
|
||||||
|
auto passwordRequest = [this] (const std::string &descr, const ConfigPasswordKey &key) {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
m_passwordRequest = m_server.passwordRequest(descr, key, weak_from_this());
|
||||||
|
};
|
||||||
|
m_helper->m_passwordRequest.activate(passwordRequest);
|
||||||
|
} catch (...) {
|
||||||
|
Exception::handle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto onQuit = [this] (int status) noexcept {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
try {
|
||||||
|
SE_LOG_DEBUG(NULL, "helper quit with return code %d, was %s",
|
||||||
|
status,
|
||||||
|
m_wasAborted ? "aborted" : "not aborted");
|
||||||
|
if (m_status == SESSION_DONE) {
|
||||||
|
// don't care anymore whether the helper goes down, not an error
|
||||||
|
SE_LOG_DEBUG(NULL, "session already completed, ignore helper");
|
||||||
|
} else if (m_wasAborted &&
|
||||||
|
((WIFEXITED(status) && WEXITSTATUS(status) == 0) ||
|
||||||
|
(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM))) {
|
||||||
|
SE_LOG_DEBUG(NULL, "helper terminated via SIGTERM, as expected");
|
||||||
|
if (!m_error) {
|
||||||
|
m_error = sysync::LOCERR_USERABORT;
|
||||||
|
SE_LOG_DEBUG(NULL, "helper was asked to quit -> error %d = LOCERR_USERABORT",
|
||||||
|
m_error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Premature exit from helper?! Not necessarily, it could
|
||||||
|
// be that we get the "helper has quit" signal from
|
||||||
|
// ForkExecParent before processing the helper's D-Bus
|
||||||
|
// method reply. So instead of recording an error here,
|
||||||
|
// wait for that reply. If the helper died without sending
|
||||||
|
// it, then D-Bus will generate a "connection lost" error
|
||||||
|
// for our pending method call.
|
||||||
|
//
|
||||||
|
// Except that libdbus does not deliver that error
|
||||||
|
// reliably. As a workaround, schedule closing the
|
||||||
|
// session as an idle callback, after that potential
|
||||||
|
// future method return call was handled. The assumption
|
||||||
|
// is that it is pending - it must be, because with the
|
||||||
|
// helper gone, IO with it must be ready. Just to be sure
|
||||||
|
// a small delay is used.
|
||||||
|
}
|
||||||
|
auto done = [me = weak_from_this()] () {
|
||||||
|
auto lock = me.lock();
|
||||||
|
if (lock) {
|
||||||
|
lock->doneCb(false, {});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_server.addTimeout(done, 1 /* seconds */);
|
||||||
|
} catch (...) {
|
||||||
|
Exception::handle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto onFailure = [this] (SyncMLStatus status, const std::string &explanation) noexcept {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
try {
|
||||||
|
SE_LOG_DEBUG(NULL, "helper failed, status code %d = %s, %s",
|
||||||
|
status,
|
||||||
|
Status2String(status).c_str(),
|
||||||
|
explanation.c_str());
|
||||||
|
} catch (...) {
|
||||||
|
Exception::handle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_forkExecParent->m_onConnect.connect(onConnect);
|
||||||
|
m_forkExecParent->m_onQuit.connect(onQuit);
|
||||||
|
m_forkExecParent->m_onFailure.connect(onFailure);
|
||||||
|
|
||||||
if (!getenv("SYNCEVOLUTION_DEBUG")) {
|
if (!getenv("SYNCEVOLUTION_DEBUG")) {
|
||||||
// Any output from the helper is unexpected and will be
|
// Any output from the helper is unexpected and will be
|
||||||
|
@ -897,25 +1015,37 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
|
||||||
// stdout redirection once it runs, so anything that
|
// stdout redirection once it runs, so anything that
|
||||||
// reaches us must have been problems during early process
|
// reaches us must have been problems during early process
|
||||||
// startup or final shutdown.
|
// startup or final shutdown.
|
||||||
m_forkExecParent->m_onOutput.connect(bind(&Session::onOutput, this, _1, _2));
|
auto onOutput = [this] (const char *buffer, size_t length) {
|
||||||
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
|
// treat null-bytes inside the buffer like line breaks
|
||||||
|
size_t off = 0;
|
||||||
|
do {
|
||||||
|
SE_LOG_ERROR("session-helper", "%s", buffer + off);
|
||||||
|
off += strlen(buffer + off) + 1;
|
||||||
|
} while (off < length);
|
||||||
|
};
|
||||||
|
m_forkExecParent->m_onOutput.connect(onOutput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now also connect result with the right events. Will be
|
// Now also connect result with the right events. Will be
|
||||||
// called after setting up m_helper (first come, first
|
// called after setting up m_helper (first come, first
|
||||||
// serve). We copy the "result" instance with boost::bind, and
|
// serve). We copy the "result" instance with the closure, and
|
||||||
// the creator of it must have made sure that we can invoke it
|
// the creator of it must have made sure that we can invoke it
|
||||||
// at any time without crashing.
|
// at any time without crashing.
|
||||||
//
|
//
|
||||||
// If the helper quits before connecting, the startup
|
// If the helper quits before connecting, the startup
|
||||||
// failed. Need to remove that connection when successful.
|
// failed. Need to remove that connection when successful.
|
||||||
boost::signals2::connection c = m_forkExecParent->m_onQuit.connect(boost::bind(&raiseChildTermError,
|
auto raiseChildTermError = [result] (int status) noexcept {
|
||||||
_1,
|
try {
|
||||||
result));
|
SE_THROW(StringPrintf("helper died unexpectedly with return code %d before connecting", status));
|
||||||
m_forkExecParent->m_onConnect.connect(boost::bind(&Session::useHelper2,
|
} catch (...) {
|
||||||
this,
|
result.failed();
|
||||||
result,
|
}
|
||||||
c));
|
};
|
||||||
|
auto c = m_forkExecParent->m_onQuit.connect(raiseChildTermError);
|
||||||
|
|
||||||
|
m_forkExecParent->m_onConnect.connect([this, result, c] (const GDBusCXX::DBusConnectionPtr &) { useHelper2(result, c); });
|
||||||
|
|
||||||
if (m_forkExecParent->getState() == ForkExecParent::IDLE) {
|
if (m_forkExecParent->getState() == ForkExecParent::IDLE) {
|
||||||
m_forkExecParent->start();
|
m_forkExecParent->start();
|
||||||
|
@ -980,7 +1110,7 @@ static void Logging2Server(Server &server,
|
||||||
|
|
||||||
void Session::useHelper2(const SimpleResult &result, const boost::signals2::connection &c)
|
void Session::useHelper2(const SimpleResult &result, const boost::signals2::connection &c)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
try {
|
try {
|
||||||
// helper is running, don't call result.failed() when it quits
|
// helper is running, don't call result.failed() when it quits
|
||||||
// sometime in the future
|
// sometime in the future
|
||||||
|
@ -1003,13 +1133,12 @@ void Session::useHelper2(const SimpleResult &result, const boost::signals2::conn
|
||||||
// The downside is that unrelated output (like
|
// The downside is that unrelated output (like
|
||||||
// book-keeping messages about other clients) will also be
|
// book-keeping messages about other clients) will also be
|
||||||
// captured.
|
// captured.
|
||||||
m_helper->m_logOutput.activate(boost::bind(Logging2Server,
|
m_helper->m_logOutput.activate([this] (const std::string &strLevel,
|
||||||
boost::ref(m_server),
|
const std::string &explanation,
|
||||||
getPath(),
|
const std::string &procname) {
|
||||||
_1,
|
Logging2Server(m_server, getPath(),
|
||||||
_2,
|
strLevel, explanation, procname);
|
||||||
_3));
|
});
|
||||||
|
|
||||||
result.done();
|
result.done();
|
||||||
} else {
|
} else {
|
||||||
SE_THROW("internal error, helper not ready");
|
SE_THROW("internal error, helper not ready");
|
||||||
|
@ -1021,101 +1150,9 @@ void Session::useHelper2(const SimpleResult &result, const boost::signals2::conn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::onConnect(const GDBusCXX::DBusConnectionPtr &conn) throw ()
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
|
||||||
std::string instance = m_forkExecParent->getInstance();
|
|
||||||
SE_LOG_DEBUG(NULL, "helper %s has connected", instance.c_str());
|
|
||||||
m_helper.reset(new SessionProxy(conn, instance));
|
|
||||||
|
|
||||||
// Activate signal watch on helper signals.
|
|
||||||
m_helper->m_syncProgress.activate(boost::bind(&Session::syncProgress, this, _1, _2, _3, _4));
|
|
||||||
m_helper->m_sourceProgress.activate(boost::bind(&Session::sourceProgress, this, _1, _2, _3, _4, _5, _6));
|
|
||||||
m_helper->m_sourceSynced.activate(boost::bind(boost::ref(m_sourceSynced), _1, _2));
|
|
||||||
m_sourceSynced.connect(boost::bind(StoreSyncSourceReport, boost::ref(m_syncSourceReports), _1, _2));
|
|
||||||
m_helper->m_waiting.activate(boost::bind(&Session::setWaiting, this, _1));
|
|
||||||
m_helper->m_syncSuccessStart.activate(boost::bind(boost::ref(Session::m_syncSuccessStartSignal)));
|
|
||||||
m_helper->m_configChanged.activate(boost::bind(boost::ref(m_server.m_configChangedSignal), ""));
|
|
||||||
m_helper->m_passwordRequest.activate(boost::bind(&Session::passwordRequest, this, _1, _2));
|
|
||||||
} catch (...) {
|
|
||||||
Exception::handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::onQuit(int status) throw ()
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
|
||||||
SE_LOG_DEBUG(NULL, "helper quit with return code %d, was %s",
|
|
||||||
status,
|
|
||||||
m_wasAborted ? "aborted" : "not aborted");
|
|
||||||
if (m_status == SESSION_DONE) {
|
|
||||||
// don't care anymore whether the helper goes down, not an error
|
|
||||||
SE_LOG_DEBUG(NULL, "session already completed, ignore helper");
|
|
||||||
} else if (m_wasAborted &&
|
|
||||||
((WIFEXITED(status) && WEXITSTATUS(status) == 0) ||
|
|
||||||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM))) {
|
|
||||||
SE_LOG_DEBUG(NULL, "helper terminated via SIGTERM, as expected");
|
|
||||||
if (!m_error) {
|
|
||||||
m_error = sysync::LOCERR_USERABORT;
|
|
||||||
SE_LOG_DEBUG(NULL, "helper was asked to quit -> error %d = LOCERR_USERABORT",
|
|
||||||
m_error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Premature exit from helper?! Not necessarily, it could
|
|
||||||
// be that we get the "helper has quit" signal from
|
|
||||||
// ForkExecParent before processing the helper's D-Bus
|
|
||||||
// method reply. So instead of recording an error here,
|
|
||||||
// wait for that reply. If the helper died without sending
|
|
||||||
// it, then D-Bus will generate a "connection lost" error
|
|
||||||
// for our pending method call.
|
|
||||||
//
|
|
||||||
// Except that libdbus does not deliver that error
|
|
||||||
// reliably. As a workaround, schedule closing the
|
|
||||||
// session as an idle callback, after that potential
|
|
||||||
// future method return call was handled. The assumption
|
|
||||||
// is that it is pending - it must be, because with the
|
|
||||||
// helper gone, IO with it must be ready. Just to be sure
|
|
||||||
// a small delay is used.
|
|
||||||
}
|
|
||||||
m_server.addTimeout(boost::bind(&Session::doneCb,
|
|
||||||
m_me,
|
|
||||||
false,
|
|
||||||
SyncReport()),
|
|
||||||
1 /* seconds */);
|
|
||||||
} catch (...) {
|
|
||||||
Exception::handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::onFailure(SyncMLStatus status, const std::string &explanation) throw ()
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
|
||||||
SE_LOG_DEBUG(NULL, "helper failed, status code %d = %s, %s",
|
|
||||||
status,
|
|
||||||
Status2String(status).c_str(),
|
|
||||||
explanation.c_str());
|
|
||||||
} catch (...) {
|
|
||||||
Exception::handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::onOutput(const char *buffer, size_t length)
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
// treat null-bytes inside the buffer like line breaks
|
|
||||||
size_t off = 0;
|
|
||||||
do {
|
|
||||||
SE_LOG_ERROR("session-helper", "%s", buffer + off);
|
|
||||||
off += strlen(buffer + off) + 1;
|
|
||||||
} while (off < length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::activateSession()
|
void Session::activateSession()
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_status != SESSION_IDLE) {
|
if (m_status != SESSION_IDLE) {
|
||||||
SE_THROW("internal error, session changing from non-idle to active");
|
SE_THROW("internal error, session changing from non-idle to active");
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1163,7 @@ void Session::activateSession()
|
||||||
fireStatus(true);
|
fireStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Connection> c = m_connection.lock();
|
std::shared_ptr<Connection> c = m_connection.lock();
|
||||||
if (c) {
|
if (c) {
|
||||||
c->ready();
|
c->ready();
|
||||||
}
|
}
|
||||||
|
@ -1136,11 +1173,11 @@ void Session::activateSession()
|
||||||
|
|
||||||
void Session::passwordResponse(bool timedOut, bool aborted, const std::string &password)
|
void Session::passwordResponse(bool timedOut, bool aborted, const std::string &password)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_helper) {
|
if (m_helper) {
|
||||||
// Ignore communicaton failures with helper here,
|
// Ignore communicaton failures with helper here,
|
||||||
// we'll notice that elsewhere
|
// we'll notice that elsewhere
|
||||||
m_helper->m_passwordResponse.start(boost::function<void (const std::string &)>(),
|
m_helper->m_passwordResponse.start(std::function<void (const std::string &)>(),
|
||||||
timedOut, aborted, password);
|
timedOut, aborted, password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1186,7 @@ void Session::passwordResponse(bool timedOut, bool aborted, const std::string &p
|
||||||
void Session::syncProgress(sysync::TProgressEventEnum type,
|
void Session::syncProgress(sysync::TProgressEventEnum type,
|
||||||
int32_t extra1, int32_t extra2, int32_t extra3)
|
int32_t extra1, int32_t extra2, int32_t extra3)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case sysync::PEV_CUSTOM_START:
|
case sysync::PEV_CUSTOM_START:
|
||||||
m_cmdlineOp = (RunOperation)extra1;
|
m_cmdlineOp = (RunOperation)extra1;
|
||||||
|
@ -1202,7 +1239,7 @@ void Session::sourceProgress(sysync::TProgressEventEnum type,
|
||||||
SyncMode sourceSyncMode,
|
SyncMode sourceSyncMode,
|
||||||
int32_t extra1, int32_t extra2, int32_t extra3)
|
int32_t extra1, int32_t extra2, int32_t extra3)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
// a command line operation can be many things, helper must have told us
|
// a command line operation can be many things, helper must have told us
|
||||||
SessionCommon::RunOperation op = m_runOperation == SessionCommon::OP_CMDLINE ?
|
SessionCommon::RunOperation op = m_runOperation == SessionCommon::OP_CMDLINE ?
|
||||||
m_cmdlineOp :
|
m_cmdlineOp :
|
||||||
|
@ -1334,7 +1371,7 @@ void Session::sourceProgress(sysync::TProgressEventEnum type,
|
||||||
|
|
||||||
bool Session::setFilters(SyncConfig &config)
|
bool Session::setFilters(SyncConfig &config)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
/** apply temporary configs to config */
|
/** apply temporary configs to config */
|
||||||
config.setConfigFilter(true, "", m_syncFilter);
|
config.setConfigFilter(true, "", m_syncFilter);
|
||||||
// set all sources in the filter to config
|
// set all sources in the filter to config
|
||||||
|
@ -1344,19 +1381,9 @@ bool Session::setFilters(SyncConfig &config)
|
||||||
return m_tempConfig;
|
return m_tempConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::setWaiting(bool isWaiting)
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
// if stepInfo doesn't change, then ignore it to avoid duplicate status info
|
|
||||||
if(m_stepIsWaiting != isWaiting) {
|
|
||||||
m_stepIsWaiting = isWaiting;
|
|
||||||
fireStatus(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::restore(const string &dir, bool before, const std::vector<std::string> &sources)
|
void Session::restore(const string &dir, bool before, const std::vector<std::string> &sources)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation == SessionCommon::OP_RESTORE) {
|
if (m_runOperation == SessionCommon::OP_RESTORE) {
|
||||||
string msg = StringPrintf("restore started, cannot restore again");
|
string msg = StringPrintf("restore started, cannot restore again");
|
||||||
SE_THROW_EXCEPTION(InvalidCall, msg);
|
SE_THROW_EXCEPTION(InvalidCall, msg);
|
||||||
|
@ -1371,24 +1398,28 @@ void Session::restore(const string &dir, bool before, const std::vector<std::str
|
||||||
}
|
}
|
||||||
|
|
||||||
runOperationAsync(SessionCommon::OP_RESTORE,
|
runOperationAsync(SessionCommon::OP_RESTORE,
|
||||||
boost::bind(&Session::restore2, this, dir, before, sources));
|
[this, dir, before, sources] () {
|
||||||
|
restore2(dir, before, sources);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::restore2(const string &dir, bool before, const std::vector<std::string> &sources)
|
void Session::restore2(const string &dir, bool before, const std::vector<std::string> &sources)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (!m_forkExecParent || !m_helper) {
|
if (!m_forkExecParent || !m_helper) {
|
||||||
SE_THROW("syncing cannot continue, helper died");
|
SE_THROW("syncing cannot continue, helper died");
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper is ready, tell it what to do
|
// helper is ready, tell it what to do
|
||||||
m_helper->m_restore.start(boost::bind(&Session::dbusResultCb, m_me, "restore()", _1, SyncReport(), _2),
|
m_helper->m_restore.start([me = weak_from_this()] (bool success, const std::string &error) {
|
||||||
|
dbusResultCb(me, "restore()", success, {}, error);
|
||||||
|
},
|
||||||
m_configName, dir, before, sources);
|
m_configName, dir, before, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::execute(const vector<string> &args, const map<string, string> &vars)
|
void Session::execute(const vector<string> &args, const map<string, string> &vars)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (m_runOperation == SessionCommon::OP_CMDLINE) {
|
if (m_runOperation == SessionCommon::OP_CMDLINE) {
|
||||||
SE_THROW_EXCEPTION(InvalidCall, "cmdline started, cannot start again");
|
SE_THROW_EXCEPTION(InvalidCall, "cmdline started, cannot start again");
|
||||||
} else if (m_runOperation != SessionCommon::OP_NULL) {
|
} else if (m_runOperation != SessionCommon::OP_NULL) {
|
||||||
|
@ -1400,88 +1431,50 @@ void Session::execute(const vector<string> &args, const map<string, string> &var
|
||||||
}
|
}
|
||||||
|
|
||||||
runOperationAsync(SessionCommon::OP_CMDLINE,
|
runOperationAsync(SessionCommon::OP_CMDLINE,
|
||||||
boost::bind(&Session::execute2,
|
[this, args, vars] () {
|
||||||
this,
|
execute2(args, vars);
|
||||||
args, vars));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::execute2(const vector<string> &args, const map<string, string> &vars)
|
void Session::execute2(const vector<string> &args, const map<string, string> &vars)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
if (!m_forkExecParent || !m_helper) {
|
if (!m_forkExecParent || !m_helper) {
|
||||||
SE_THROW("syncing cannot continue, helper died");
|
SE_THROW("syncing cannot continue, helper died");
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper is ready, tell it what to do
|
// helper is ready, tell it what to do
|
||||||
m_helper->m_execute.start(boost::bind(&Session::dbusResultCb, m_me, "execute()", _1, SyncReport(), _2),
|
m_helper->m_execute.start([me = weak_from_this()] (bool success, const std::string &error) {
|
||||||
|
dbusResultCb(me, "execute()", success, {}, error);
|
||||||
|
},
|
||||||
args, vars);
|
args, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Implementation of Session.CheckPresence */
|
/*Implementation of Session.CheckPresence */
|
||||||
void Session::checkPresence (string &status)
|
void Session::checkPresence (string &status)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
vector<string> transport;
|
vector<string> transport;
|
||||||
m_server.checkPresence(m_configName, status, transport);
|
m_server.checkPresence(m_configName, status, transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::sendViaConnection(const DBusArray<uint8_t> buffer,
|
|
||||||
const std::string &type,
|
|
||||||
const std::string &url)
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
|
||||||
boost::shared_ptr<Connection> connection = m_connection.lock();
|
|
||||||
|
|
||||||
if (!connection) {
|
|
||||||
SE_THROW_EXCEPTION(TransportException,
|
|
||||||
"D-Bus peer has disconnected");
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->send(buffer, type, url);
|
|
||||||
} catch (...) {
|
|
||||||
std::string explanation;
|
|
||||||
Exception::handle(explanation);
|
|
||||||
connectionState(explanation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::shutdownConnection()
|
|
||||||
{
|
|
||||||
PushLogger<Logger> guard(m_me);
|
|
||||||
try {
|
|
||||||
boost::shared_ptr<Connection> connection = m_connection.lock();
|
|
||||||
|
|
||||||
if (!connection) {
|
|
||||||
SE_THROW_EXCEPTION(TransportException,
|
|
||||||
"D-Bus peer has disconnected");
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->sendFinalMsg();
|
|
||||||
} catch (...) {
|
|
||||||
std::string explanation;
|
|
||||||
Exception::handle(explanation);
|
|
||||||
connectionState(explanation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::storeMessage(const DBusArray<uint8_t> &message,
|
void Session::storeMessage(const DBusArray<uint8_t> &message,
|
||||||
const std::string &type)
|
const std::string &type)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
// ignore errors
|
// ignore errors
|
||||||
if (m_helper) {
|
if (m_helper) {
|
||||||
m_helper->m_storeMessage.start(boost::function<void (const std::string &)>(),
|
m_helper->m_storeMessage.start(std::function<void (const std::string &)>(),
|
||||||
message, type);
|
message, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::connectionState(const std::string &error)
|
void Session::connectionState(const std::string &error)
|
||||||
{
|
{
|
||||||
PushLogger<Logger> guard(m_me);
|
PushLogger<Logger> guard(weak_from_this());
|
||||||
// ignore errors
|
// ignore errors
|
||||||
if (m_helper) {
|
if (m_helper) {
|
||||||
m_helper->m_connectionState.start(boost::function<void (const std::string &)>(),
|
m_helper->m_connectionState.start(std::function<void (const std::string &)>(),
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#define SESSION_H
|
#define SESSION_H
|
||||||
|
|
||||||
#include <syncevo/SynthesisEngine.h>
|
#include <syncevo/SynthesisEngine.h>
|
||||||
#include <boost/weak_ptr.hpp>
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
#include <gdbus-cxx-bridge.h>
|
#include <gdbus-cxx-bridge.h>
|
||||||
|
@ -48,7 +47,7 @@ class InfoReq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents and implements the Session interface. Use
|
* Represents and implements the Session interface. Use
|
||||||
* boost::shared_ptr to track it and ensure that there are references
|
* std::shared_ptr to track it and ensure that there are references
|
||||||
* to it as long as the connection is needed.
|
* to it as long as the connection is needed.
|
||||||
*
|
*
|
||||||
* The actual implementation is split into two parts:
|
* The actual implementation is split into two parts:
|
||||||
|
@ -64,6 +63,7 @@ class InfoReq;
|
||||||
class Session : public GDBusCXX::DBusObjectHelper,
|
class Session : public GDBusCXX::DBusObjectHelper,
|
||||||
public Logger,
|
public Logger,
|
||||||
public Resource,
|
public Resource,
|
||||||
|
public enable_weak_from_this<Session>,
|
||||||
private ReadOperations,
|
private ReadOperations,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
{
|
{
|
||||||
|
@ -101,9 +101,9 @@ class Session : public GDBusCXX::DBusObjectHelper,
|
||||||
std::string m_peerDeviceID;
|
std::string m_peerDeviceID;
|
||||||
|
|
||||||
/** Starts the helper, on demand (see useHelperAsync()). */
|
/** Starts the helper, on demand (see useHelperAsync()). */
|
||||||
boost::shared_ptr<ForkExecParent> m_forkExecParent;
|
std::shared_ptr<ForkExecParent> m_forkExecParent;
|
||||||
/** The D-Bus proxy for the helper. */
|
/** The D-Bus proxy for the helper. */
|
||||||
boost::shared_ptr<SessionProxy> m_helper;
|
std::shared_ptr<SessionProxy> m_helper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that helper is running and that its D-Bus API is
|
* Ensures that helper is running and that its D-Bus API is
|
||||||
|
@ -135,23 +135,15 @@ class Session : public GDBusCXX::DBusObjectHelper,
|
||||||
*/
|
*/
|
||||||
void useHelper2(const SimpleResult &result, const boost::signals2::connection &c);
|
void useHelper2(const SimpleResult &result, const boost::signals2::connection &c);
|
||||||
|
|
||||||
/** set up m_helper */
|
|
||||||
void onConnect(const GDBusCXX::DBusConnectionPtr &conn) throw ();
|
|
||||||
/** unset m_helper but not m_forkExecParent (still processing signals) */
|
|
||||||
void onQuit(int result) throw ();
|
|
||||||
/** set after abort() and suspend(), to turn "child died' into the LOCERR_USERABORT status code */
|
/** set after abort() and suspend(), to turn "child died' into the LOCERR_USERABORT status code */
|
||||||
void expectChildTerm(int result) throw ();
|
void expectChildTerm(int result) throw ();
|
||||||
/** log failure */
|
|
||||||
void onFailure(SyncMLStatus status, const std::string &explanation) throw ();
|
|
||||||
/** log error output from helper */
|
|
||||||
void onOutput(const char *buffer, size_t length);
|
|
||||||
|
|
||||||
bool m_serverMode;
|
bool m_serverMode;
|
||||||
bool m_serverAlerted;
|
bool m_serverAlerted;
|
||||||
SharedBuffer m_initialMessage;
|
SharedBuffer m_initialMessage;
|
||||||
string m_initialMessageType;
|
string m_initialMessageType;
|
||||||
|
|
||||||
boost::weak_ptr<Connection> m_connection;
|
std::weak_ptr<Connection> m_connection;
|
||||||
std::string m_connectionError;
|
std::string m_connectionError;
|
||||||
bool m_useConnection;
|
bool m_useConnection;
|
||||||
|
|
||||||
|
@ -272,7 +264,6 @@ class Session : public GDBusCXX::DBusObjectHelper,
|
||||||
StringMap m_syncEnv;
|
StringMap m_syncEnv;
|
||||||
|
|
||||||
typedef std::map<std::string, SyncSourceReport> SyncSourceReports;
|
typedef std::map<std::string, SyncSourceReport> SyncSourceReports;
|
||||||
static void StoreSyncSourceReport(SyncSourceReports &reports, const std::string &name, const SyncSourceReport &report) { reports[name] = report; }
|
|
||||||
/** Recorded during a sync for getSyncSourceReport. */
|
/** Recorded during a sync for getSyncSourceReport. */
|
||||||
SyncSourceReports m_syncSourceReports;
|
SyncSourceReports m_syncSourceReports;
|
||||||
|
|
||||||
|
@ -356,19 +347,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void setProgressTimeout(unsigned long ms) { m_progressTimer.setTimeout(ms); }
|
void setProgressTimeout(unsigned long ms) { m_progressTimer.setTimeout(ms); }
|
||||||
|
|
||||||
/**
|
// Construct via make_weak_shared.
|
||||||
* Sessions must always be held in a shared pointer
|
friend make_weak_shared;
|
||||||
* because some operations depend on that. This
|
|
||||||
* constructor function here ensures that and
|
|
||||||
* also adds a weak pointer to the instance itself,
|
|
||||||
* so that it can create more shared pointers as
|
|
||||||
* needed.
|
|
||||||
*/
|
|
||||||
static boost::shared_ptr<Session> createSession(Server &server,
|
|
||||||
const std::string &peerDeviceID,
|
|
||||||
const std::string &config_name,
|
|
||||||
const std::string &session,
|
|
||||||
const std::vector<std::string> &flags = std::vector<std::string>());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* automatically marks the session as completed before deleting it
|
* automatically marks the session as completed before deleting it
|
||||||
|
@ -379,7 +359,7 @@ public:
|
||||||
* explicitly mark an idle session as completed, even if it doesn't
|
* explicitly mark an idle session as completed, even if it doesn't
|
||||||
* get deleted yet (exceptions not expected by caller)
|
* get deleted yet (exceptions not expected by caller)
|
||||||
*/
|
*/
|
||||||
void done(bool success) throw () { doneCb(success); }
|
void done(bool success) throw () { doneCb(false, success); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Session(Server &server,
|
Session(Server &server,
|
||||||
|
@ -387,13 +367,7 @@ private:
|
||||||
const std::string &config_name,
|
const std::string &config_name,
|
||||||
const std::string &session,
|
const std::string &session,
|
||||||
const std::vector<std::string> &flags = std::vector<std::string>());
|
const std::vector<std::string> &flags = std::vector<std::string>());
|
||||||
boost::weak_ptr<Session> m_me;
|
std::shared_ptr<InfoReq> m_passwordRequest;
|
||||||
boost::shared_ptr<InfoReq> m_passwordRequest;
|
|
||||||
void passwordRequest(const std::string &descr, const ConfigPasswordKey &key);
|
|
||||||
void sendViaConnection(const GDBusCXX::DBusArray<uint8_t> buffer,
|
|
||||||
const std::string &type,
|
|
||||||
const std::string &url);
|
|
||||||
void shutdownConnection();
|
|
||||||
void storeMessage(const GDBusCXX::DBusArray<uint8_t> &message,
|
void storeMessage(const GDBusCXX::DBusArray<uint8_t> &message,
|
||||||
const std::string &type);
|
const std::string &type);
|
||||||
void connectionState(const std::string &error);
|
void connectionState(const std::string &error);
|
||||||
|
@ -425,8 +399,8 @@ public:
|
||||||
void setServerAlerted(bool serverAlerted) { m_serverAlerted = serverAlerted; }
|
void setServerAlerted(bool serverAlerted) { m_serverAlerted = serverAlerted; }
|
||||||
|
|
||||||
void initServer(SharedBuffer data, const std::string &messageType);
|
void initServer(SharedBuffer data, const std::string &messageType);
|
||||||
void setStubConnection(const boost::shared_ptr<Connection> c) { m_connection = c; m_useConnection = static_cast<bool>(c); }
|
void setStubConnection(const std::shared_ptr<Connection> &c) { m_connection = c; m_useConnection = static_cast<bool>(c); }
|
||||||
boost::weak_ptr<Connection> getStubConnection() { return m_connection; }
|
std::weak_ptr<Connection> getStubConnection() { return m_connection; }
|
||||||
bool useStubConnection() { return m_useConnection; }
|
bool useStubConnection() { return m_useConnection; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -492,13 +466,6 @@ public:
|
||||||
|
|
||||||
bool getFreeze() const { return m_freeze; }
|
bool getFreeze() const { return m_freeze; }
|
||||||
|
|
||||||
/**
|
|
||||||
* step info for engine: whether the engine is blocked by something
|
|
||||||
* If yes, 'waiting' will be appended as specifiers in the status string.
|
|
||||||
* see GetStatus documentation.
|
|
||||||
*/
|
|
||||||
void setWaiting(bool isWaiting);
|
|
||||||
|
|
||||||
SyncStatus getSyncStatus() const { return m_syncStatus; }
|
SyncStatus getSyncStatus() const { return m_syncStatus; }
|
||||||
|
|
||||||
/** session was just activated */
|
/** session was just activated */
|
||||||
|
@ -539,11 +506,7 @@ private:
|
||||||
/** set m_syncFilter and m_sourceFilters to config */
|
/** set m_syncFilter and m_sourceFilters to config */
|
||||||
virtual bool setFilters(SyncConfig &config);
|
virtual bool setFilters(SyncConfig &config);
|
||||||
|
|
||||||
void dbusResultCb(const std::string &operation, bool success, const SyncReport &report, const std::string &error) throw();
|
static void dbusResultCb(const std::weak_ptr<Session> &me, const std::string &operation, bool success, const SyncReport &report, const std::string &error) noexcept;
|
||||||
|
|
||||||
void setFreezeDone(bool changed, const std::string &error,
|
|
||||||
bool freeze,
|
|
||||||
const Result<void (bool)> &result);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to be called inside a catch() clause: returns error for any
|
* to be called inside a catch() clause: returns error for any
|
||||||
|
@ -556,11 +519,12 @@ private:
|
||||||
* get deleted yet (invoked directly or indirectly from event
|
* get deleted yet (invoked directly or indirectly from event
|
||||||
* loop and thus must not throw exceptions)
|
* loop and thus must not throw exceptions)
|
||||||
*
|
*
|
||||||
|
* @param destruct called from destructor
|
||||||
* @param success if false, then ensure that m_error is set
|
* @param success if false, then ensure that m_error is set
|
||||||
* before finalizing the session
|
* before finalizing the session
|
||||||
* @param report valid only in case of success
|
* @param report valid only in case of success
|
||||||
*/
|
*/
|
||||||
void doneCb(bool success, const SyncReport &report = SyncReport()) throw();
|
void doneCb(bool destruct, bool success, const SyncReport &report = SyncReport()) throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -33,33 +33,6 @@
|
||||||
using namespace SyncEvo;
|
using namespace SyncEvo;
|
||||||
using namespace GDBusCXX;
|
using namespace GDBusCXX;
|
||||||
|
|
||||||
namespace {
|
|
||||||
GMainLoop *loop = NULL;
|
|
||||||
int logLevelDBus = Logger::INFO;
|
|
||||||
|
|
||||||
// that one is actually never called. probably a bug in ForkExec - it should
|
|
||||||
// call m_onFailure instead of throwing an exception
|
|
||||||
void onFailure(const std::string &error, bool &failed) throw ()
|
|
||||||
{
|
|
||||||
SE_LOG_DEBUG(NULL, "failure, quitting now: %s", error.c_str());
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onConnect(const DBusConnectionPtr &conn,
|
|
||||||
const boost::shared_ptr<ForkExecChild> &forkexec,
|
|
||||||
boost::shared_ptr<SessionHelper> &helper)
|
|
||||||
{
|
|
||||||
helper.reset(new SessionHelper(loop, conn, forkexec));
|
|
||||||
helper->activate();
|
|
||||||
helper->setDBusLogLevel(Logger::Level(logLevelDBus));
|
|
||||||
}
|
|
||||||
|
|
||||||
void onAbort()
|
|
||||||
{
|
|
||||||
g_main_loop_quit(loop);
|
|
||||||
}
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This program is a helper of syncevo-dbus-server which provides the
|
* This program is a helper of syncevo-dbus-server which provides the
|
||||||
* Connection and Session DBus interfaces and runs individual sync
|
* Connection and Session DBus interfaces and runs individual sync
|
||||||
|
@ -87,7 +60,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
SyncContext::initMain("syncevo-dbus-helper");
|
SyncContext::initMain("syncevo-dbus-helper");
|
||||||
|
|
||||||
loop = g_main_loop_new(NULL, FALSE);
|
GMainLoopCXX loop(g_main_loop_new(NULL, FALSE), TRANSFER_REF);
|
||||||
|
|
||||||
// Suspend and abort are signaled via SIGINT/SIGTERM
|
// Suspend and abort are signaled via SIGINT/SIGTERM
|
||||||
// respectively. SuspendFlags handle that for us.
|
// respectively. SuspendFlags handle that for us.
|
||||||
|
@ -95,16 +68,17 @@ int main(int argc, char **argv, char **envp)
|
||||||
// can quite.
|
// can quite.
|
||||||
SuspendFlags &s = SuspendFlags::getSuspendFlags();
|
SuspendFlags &s = SuspendFlags::getSuspendFlags();
|
||||||
s.setLevel(Logger::DEV);
|
s.setLevel(Logger::DEV);
|
||||||
boost::shared_ptr<SuspendFlags::Guard> guard = s.activate((1<<SIGINT)|(1<<SIGTERM)|(1<<SIGURG));
|
std::shared_ptr<SuspendFlags::Guard> guard = s.activate((1<<SIGINT)|(1<<SIGTERM)|(1<<SIGURG));
|
||||||
|
|
||||||
bool debug = getenv("SYNCEVOLUTION_DEBUG");
|
bool debug = getenv("SYNCEVOLUTION_DEBUG");
|
||||||
|
int logLevelDBus = Logger::INFO;
|
||||||
|
|
||||||
// Redirect both stdout and stderr. The only code
|
// Redirect both stdout and stderr. The only code
|
||||||
// writing to it should be third-party libraries
|
// writing to it should be third-party libraries
|
||||||
// which are unaware of the SyncEvolution logging system.
|
// which are unaware of the SyncEvolution logging system.
|
||||||
// Redirecting is useful to get such output into our
|
// Redirecting is useful to get such output into our
|
||||||
// sync logfile, once we have one.
|
// sync logfile, once we have one.
|
||||||
boost::shared_ptr<LogRedirect> redirect;
|
std::shared_ptr<LogRedirect> redirect;
|
||||||
PushLogger<LogRedirect> pushRedirect;
|
PushLogger<LogRedirect> pushRedirect;
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
|
redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
|
||||||
|
@ -122,7 +96,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
static GOptionEntry entries[] = {
|
GOptionEntry entries[] = {
|
||||||
{ "dbus-verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevelDBus,
|
{ "dbus-verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevelDBus,
|
||||||
"Choose amount of output via D-Bus signals with Logger::Level; default is INFO = 3.",
|
"Choose amount of output via D-Bus signals with Logger::Level; default is INFO = 3.",
|
||||||
"level" },
|
"level" },
|
||||||
|
@ -147,19 +121,34 @@ int main(int argc, char **argv, char **envp)
|
||||||
// the brackets, like the other processes do.
|
// the brackets, like the other processes do.
|
||||||
// Logger::setProcessName("syncevo-dbus-helper");
|
// Logger::setProcessName("syncevo-dbus-helper");
|
||||||
|
|
||||||
boost::shared_ptr<ForkExecChild> forkexec = ForkExecChild::create();
|
auto forkexec = make_weak_shared::make<ForkExecChild>();
|
||||||
|
|
||||||
boost::shared_ptr<SessionHelper> helper;
|
std::shared_ptr<SessionHelper> helper;
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
forkexec->m_onConnect.connect(boost::bind(onConnect, _1,
|
|
||||||
boost::cref(forkexec),
|
// that one is actually never called. probably a bug in ForkExec - it should
|
||||||
boost::ref(helper)));
|
// call m_onFailure instead of throwing an exception
|
||||||
forkexec->m_onFailure.connect(boost::bind(onFailure, _2, boost::ref(failed)));
|
auto onFailure = [&failed] (SyncMLStatus, const std::string &error) noexcept {
|
||||||
|
SE_LOG_DEBUG(NULL, "failure, quitting now: %s", error.c_str());
|
||||||
|
failed = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto onConnect = [&helper, &forkexec, loop, logLevelDBus] (const DBusConnectionPtr &conn) {
|
||||||
|
helper.reset(new SessionHelper(loop, conn, forkexec));
|
||||||
|
helper->activate();
|
||||||
|
helper->setDBusLogLevel(Logger::Level(logLevelDBus));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto onAbort = [loop] (SuspendFlags &) {
|
||||||
|
g_main_loop_quit(loop);
|
||||||
|
};
|
||||||
|
|
||||||
|
forkexec->m_onConnect.connect(onConnect);
|
||||||
|
forkexec->m_onFailure.connect(onFailure);
|
||||||
forkexec->connect();
|
forkexec->connect();
|
||||||
|
|
||||||
// Run until we are connected, failed or get interrupted.
|
// Run until we are connected, failed or get interrupted.
|
||||||
boost::signals2::connection c =
|
boost::signals2::connection c = s.m_stateChanged.connect(onAbort);
|
||||||
s.m_stateChanged.connect(boost::bind(&onAbort));
|
|
||||||
SE_LOG_DEBUG(NULL, "helper (pid %d) finished setup, waiting for parent connection", getpid());
|
SE_LOG_DEBUG(NULL, "helper (pid %d) finished setup, waiting for parent connection", getpid());
|
||||||
while (true) {
|
while (true) {
|
||||||
if (s.getState() != SuspendFlags::NORMAL) {
|
if (s.getState() != SuspendFlags::NORMAL) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace GDBusCXX {
|
||||||
using namespace SyncEvo;
|
using namespace SyncEvo;
|
||||||
|
|
||||||
MethodHandler::MethodMap MethodHandler::m_methodMap;
|
MethodHandler::MethodMap MethodHandler::m_methodMap;
|
||||||
boost::function<void (void)> MethodHandler::m_callback;
|
std::function<void (void)> MethodHandler::m_callback;
|
||||||
|
|
||||||
void appendArgInfo(GPtrArray *pa, const std::string &type)
|
void appendArgInfo(GPtrArray *pa, const std::string &type)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ struct OwnNameAsyncData
|
||||||
};
|
};
|
||||||
|
|
||||||
OwnNameAsyncData(const std::string &name,
|
OwnNameAsyncData(const std::string &name,
|
||||||
const boost::function<void (bool)> &obtainedCB) :
|
const std::function<void (bool)> &obtainedCB) :
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_obtainedCB(obtainedCB),
|
m_obtainedCB(obtainedCB),
|
||||||
m_state(OWN_NAME_WAITING)
|
m_state(OWN_NAME_WAITING)
|
||||||
|
@ -79,7 +79,7 @@ struct OwnNameAsyncData
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gpointer userData) throw ()
|
gpointer userData) throw ()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<OwnNameAsyncData> *data = static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData);
|
std::shared_ptr<OwnNameAsyncData> *data = static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
|
||||||
(*data)->m_state = OWN_NAME_OBTAINED;
|
(*data)->m_state = OWN_NAME_OBTAINED;
|
||||||
try {
|
try {
|
||||||
g_debug("got D-Bus name %s", name);
|
g_debug("got D-Bus name %s", name);
|
||||||
|
@ -95,7 +95,7 @@ struct OwnNameAsyncData
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gpointer userData) throw ()
|
gpointer userData) throw ()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<OwnNameAsyncData> *data = static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData);
|
std::shared_ptr<OwnNameAsyncData> *data = static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
|
||||||
(*data)->m_state = OWN_NAME_LOST;
|
(*data)->m_state = OWN_NAME_LOST;
|
||||||
try {
|
try {
|
||||||
g_debug("lost %s %s",
|
g_debug("lost %s %s",
|
||||||
|
@ -109,26 +109,26 @@ struct OwnNameAsyncData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boost::shared_ptr<OwnNameAsyncData> ownName(GDBusConnection *conn,
|
static std::shared_ptr<OwnNameAsyncData> ownName(GDBusConnection *conn,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
boost::function<void (bool)> obtainedCB =
|
std::function<void (bool)> obtainedCB =
|
||||||
boost::function<void (bool)>()) {
|
std::function<void (bool)>()) {
|
||||||
boost::shared_ptr<OwnNameAsyncData> data(new OwnNameAsyncData(name, obtainedCB));
|
auto data = std::make_shared<OwnNameAsyncData>(name, obtainedCB);
|
||||||
auto free_data = [] (gpointer userData) noexcept {
|
auto free_data = [] (gpointer userData) noexcept {
|
||||||
delete static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData);
|
delete static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
|
||||||
};
|
};
|
||||||
g_bus_own_name_on_connection(conn,
|
g_bus_own_name_on_connection(conn,
|
||||||
data->m_name.c_str(),
|
data->m_name.c_str(),
|
||||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||||
OwnNameAsyncData::busNameAcquired,
|
OwnNameAsyncData::busNameAcquired,
|
||||||
OwnNameAsyncData::busNameLost,
|
OwnNameAsyncData::busNameLost,
|
||||||
new boost::shared_ptr<OwnNameAsyncData>(data),
|
new std::shared_ptr<OwnNameAsyncData>(data),
|
||||||
free_data);
|
free_data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string m_name;
|
const std::string m_name;
|
||||||
const boost::function<void (bool)> m_obtainedCB;
|
const std::function<void (bool)> m_obtainedCB;
|
||||||
State m_state;
|
State m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ void DBusConnectionPtr::undelay() const
|
||||||
{
|
{
|
||||||
if (!m_name.empty()) {
|
if (!m_name.empty()) {
|
||||||
g_debug("starting to acquire D-Bus name %s", m_name.c_str());
|
g_debug("starting to acquire D-Bus name %s", m_name.c_str());
|
||||||
boost::shared_ptr<OwnNameAsyncData> data = OwnNameAsyncData::ownName(get(),
|
std::shared_ptr<OwnNameAsyncData> data = OwnNameAsyncData::ownName(get(),
|
||||||
m_name);
|
m_name);
|
||||||
while (data->m_state == OwnNameAsyncData::OWN_NAME_WAITING) {
|
while (data->m_state == OwnNameAsyncData::OWN_NAME_WAITING) {
|
||||||
g_main_context_iteration(NULL, true);
|
g_main_context_iteration(NULL, true);
|
||||||
|
@ -150,7 +150,7 @@ void DBusConnectionPtr::undelay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBusConnectionPtr::ownNameAsync(const std::string &name,
|
void DBusConnectionPtr::ownNameAsync(const std::string &name,
|
||||||
const boost::function<void (bool)> &obtainedCB) const
|
const std::function<void (bool)> &obtainedCB) const
|
||||||
{
|
{
|
||||||
OwnNameAsyncData::ownName(get(), name, obtainedCB);
|
OwnNameAsyncData::ownName(get(), name, obtainedCB);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ void DBusConnectionPtr::setDisconnect(const Disconnect_t &func)
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *)
|
std::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *)
|
||||||
{
|
{
|
||||||
// Create two fds connected via a two-way stream. The parent
|
// Create two fds connected via a two-way stream. The parent
|
||||||
// keeps fd[0] which gets closed automatically when the child
|
// keeps fd[0] which gets closed automatically when the child
|
||||||
|
@ -317,7 +317,8 @@ boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &ne
|
||||||
|
|
||||||
// A fake DBusServerCXX which does nothing more than return the address, aka
|
// A fake DBusServerCXX which does nothing more than return the address, aka
|
||||||
// our FD number, and store data for the idle callback.
|
// our FD number, and store data for the idle callback.
|
||||||
boost::shared_ptr<DBusServerCXX> res(new DBusServerCXX(address));
|
// Private constructor, can't use make_shared() here.
|
||||||
|
std::shared_ptr<DBusServerCXX> res(new DBusServerCXX(address));
|
||||||
res->m_newConnection = newConnection;
|
res->m_newConnection = newConnection;
|
||||||
res->m_connection = connection;
|
res->m_connection = connection;
|
||||||
// Will be freed in the idle callback. Caller must have forked by then.
|
// Will be freed in the idle callback. Caller must have forked by then.
|
||||||
|
@ -399,7 +400,7 @@ void Watch::disconnected()
|
||||||
}
|
}
|
||||||
|
|
||||||
Watch::Watch(const DBusConnectionPtr &conn,
|
Watch::Watch(const DBusConnectionPtr &conn,
|
||||||
const boost::function<void (void)> &callback) :
|
const std::function<void (void)> &callback) :
|
||||||
m_conn(conn),
|
m_conn(conn),
|
||||||
m_callback(callback),
|
m_callback(callback),
|
||||||
m_called(false),
|
m_called(false),
|
||||||
|
@ -407,7 +408,7 @@ Watch::Watch(const DBusConnectionPtr &conn,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Watch::setCallback(const boost::function<void (void)> &callback)
|
void Watch::setCallback(const std::function<void (void)> &callback)
|
||||||
{
|
{
|
||||||
m_callback = callback;
|
m_callback = callback;
|
||||||
if (m_called && m_callback) {
|
if (m_called && m_callback) {
|
||||||
|
@ -480,7 +481,7 @@ Watch::~Watch()
|
||||||
}
|
}
|
||||||
|
|
||||||
void getWatch(ExtractArgs &context,
|
void getWatch(ExtractArgs &context,
|
||||||
boost::shared_ptr<Watch> &value)
|
std::shared_ptr<Watch> &value)
|
||||||
{
|
{
|
||||||
std::unique_ptr<Watch> watch(new Watch(context.m_conn));
|
std::unique_ptr<Watch> watch(new Watch(context.m_conn));
|
||||||
watch->activate((context.m_msg && *context.m_msg) ?
|
watch->activate((context.m_msg && *context.m_msg) ?
|
||||||
|
|
|
@ -62,15 +62,15 @@
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/intrusive_ptr.hpp>
|
#include <boost/intrusive_ptr.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
#include <boost/variant/get.hpp>
|
#include <boost/variant/get.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
@ -229,7 +229,7 @@ class DBusConnectionPtr : public boost::intrusive_ptr<GDBusConnection>
|
||||||
*/
|
*/
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
typedef boost::function<void ()> Disconnect_t;
|
typedef std::function<void ()> Disconnect_t;
|
||||||
void setDisconnect(const Disconnect_t &func);
|
void setDisconnect(const Disconnect_t &func);
|
||||||
// #define GDBUS_CXX_HAVE_DISCONNECT 1
|
// #define GDBUS_CXX_HAVE_DISCONNECT 1
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ class DBusConnectionPtr : public boost::intrusive_ptr<GDBusConnection>
|
||||||
* The callback is allowed to be empty.
|
* The callback is allowed to be empty.
|
||||||
*/
|
*/
|
||||||
void ownNameAsync(const std::string &name,
|
void ownNameAsync(const std::string &name,
|
||||||
const boost::function<void (bool)> &obtainedCB) const;
|
const std::function<void (bool)> &obtainedCB) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DBusMessagePtr : public boost::intrusive_ptr<GDBusMessage>
|
class DBusMessagePtr : public boost::intrusive_ptr<GDBusMessage>
|
||||||
|
@ -361,7 +361,7 @@ class DBusServerCXX : private boost::noncopyable
|
||||||
* connection, so the callback can set up objects and then must undelay
|
* connection, so the callback can set up objects and then must undelay
|
||||||
* the connection.
|
* the connection.
|
||||||
*/
|
*/
|
||||||
typedef boost::function<void (DBusServerCXX &, DBusConnectionPtr &)> NewConnection_t;
|
typedef std::function<void (DBusServerCXX &, DBusConnectionPtr &)> NewConnection_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start listening for new connections. Mimics the libdbus DBusServer API, but
|
* Start listening for new connections. Mimics the libdbus DBusServer API, but
|
||||||
|
@ -372,7 +372,7 @@ class DBusServerCXX : private boost::noncopyable
|
||||||
*
|
*
|
||||||
* All errors are reported via exceptions, not "err".
|
* All errors are reported via exceptions, not "err".
|
||||||
*/
|
*/
|
||||||
static boost::shared_ptr<DBusServerCXX> listen(const NewConnection_t &newConnection, DBusErrorCXX *err);
|
static std::shared_ptr<DBusServerCXX> listen(const NewConnection_t &newConnection, DBusErrorCXX *err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* address used by the server
|
* address used by the server
|
||||||
|
@ -411,7 +411,7 @@ struct dbus_traits_base
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* A C++ method or function can handle a call asynchronously by
|
* A C++ method or function can handle a call asynchronously by
|
||||||
* asking to be passed a "boost::shared_ptr<Result*>" parameter.
|
* asking to be passed a "std::shared_ptr<Result*>" parameter.
|
||||||
* The dbus_traits for those parameters have "asynchronous" set to
|
* The dbus_traits for those parameters have "asynchronous" set to
|
||||||
* true, which skips all processing after calling the method.
|
* true, which skips all processing after calling the method.
|
||||||
*/
|
*/
|
||||||
|
@ -850,23 +850,23 @@ struct FunctionWrapperBase {
|
||||||
|
|
||||||
template<typename M>
|
template<typename M>
|
||||||
struct FunctionWrapper : public FunctionWrapperBase {
|
struct FunctionWrapper : public FunctionWrapperBase {
|
||||||
FunctionWrapper(boost::function<M>* func_ptr)
|
FunctionWrapper(std::function<M>* func_ptr)
|
||||||
: FunctionWrapperBase(reinterpret_cast<void*>(func_ptr))
|
: FunctionWrapperBase(reinterpret_cast<void*>(func_ptr))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~FunctionWrapper() {
|
virtual ~FunctionWrapper() {
|
||||||
delete reinterpret_cast<boost::function<M>*>(m_func_ptr);
|
delete reinterpret_cast<std::function<M>*>(m_func_ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MethodHandler
|
struct MethodHandler
|
||||||
{
|
{
|
||||||
typedef GDBusMessage *(*MethodFunction)(GDBusConnection *conn, GDBusMessage *msg, void *data);
|
typedef GDBusMessage *(*MethodFunction)(GDBusConnection *conn, GDBusMessage *msg, void *data);
|
||||||
typedef boost::shared_ptr<FunctionWrapperBase> FuncWrapper;
|
typedef std::shared_ptr<FunctionWrapperBase> FuncWrapper;
|
||||||
typedef std::pair<MethodFunction, FuncWrapper > CallbackPair;
|
typedef std::pair<MethodFunction, FuncWrapper > CallbackPair;
|
||||||
typedef std::map<const std::string, CallbackPair > MethodMap;
|
typedef std::map<const std::string, CallbackPair > MethodMap;
|
||||||
static MethodMap m_methodMap;
|
static MethodMap m_methodMap;
|
||||||
static boost::function<void (void)> m_callback;
|
static std::function<void (void)> m_callback;
|
||||||
|
|
||||||
static std::string make_prefix(const char *object_path) {
|
static std::string make_prefix(const char *object_path) {
|
||||||
return std::string(object_path) + "~";
|
return std::string(object_path) + "~";
|
||||||
|
@ -989,7 +989,7 @@ class DBusObjectHelper : public DBusObject
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef boost::function<void (void)> Callback_t;
|
typedef std::function<void (void)> Callback_t;
|
||||||
|
|
||||||
DBusObjectHelper(const DBusConnectionPtr &conn,
|
DBusObjectHelper(const DBusConnectionPtr &conn,
|
||||||
const std::string &path,
|
const std::string &path,
|
||||||
|
@ -1047,10 +1047,10 @@ class DBusObjectHelper : public DBusObject
|
||||||
throw std::logic_error("You can't add new methods after registration!");
|
throw std::logic_error("You can't add new methods after registration!");
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef MakeMethodEntry< boost::function<M> > entry_type;
|
typedef MakeMethodEntry< std::function<M> > entry_type;
|
||||||
g_ptr_array_add(m_methods, entry_type::make(name));
|
g_ptr_array_add(m_methods, entry_type::make(name));
|
||||||
|
|
||||||
boost::function<M> *func = new boost::function<M>(entry_type::boostptr(method, instance));
|
std::function<M> *func = new std::function<M>(entry_type::boostptr(method, instance));
|
||||||
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
|
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
|
||||||
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction, wrapper);
|
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction, wrapper);
|
||||||
const std::string key(MethodHandler::make_method_key(getPath(), name));
|
const std::string key(MethodHandler::make_method_key(getPath(), name));
|
||||||
|
@ -1068,10 +1068,10 @@ class DBusObjectHelper : public DBusObject
|
||||||
throw std::logic_error("You can't add new functions after registration!");
|
throw std::logic_error("You can't add new functions after registration!");
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef MakeMethodEntry< boost::function<M> > entry_type;
|
typedef MakeMethodEntry< std::function<M> > entry_type;
|
||||||
g_ptr_array_add(m_methods, entry_type::make(name));
|
g_ptr_array_add(m_methods, entry_type::make(name));
|
||||||
|
|
||||||
boost::function<M> *func = new boost::function<M>(function);
|
std::function<M> *func = new std::function<M>(function);
|
||||||
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
|
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
|
||||||
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction,
|
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction,
|
||||||
wrapper);
|
wrapper);
|
||||||
|
@ -2209,7 +2209,7 @@ static inline GDBusMessage *handleException(GDBusMessage *&callerMsg)
|
||||||
class Watch : private boost::noncopyable
|
class Watch : private boost::noncopyable
|
||||||
{
|
{
|
||||||
DBusConnectionPtr m_conn;
|
DBusConnectionPtr m_conn;
|
||||||
boost::function<void (void)> m_callback;
|
std::function<void (void)> m_callback;
|
||||||
bool m_called;
|
bool m_called;
|
||||||
guint m_watchID;
|
guint m_watchID;
|
||||||
std::string m_peer;
|
std::string m_peer;
|
||||||
|
@ -2226,14 +2226,14 @@ class Watch : private boost::noncopyable
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Watch(const DBusConnectionPtr &conn,
|
Watch(const DBusConnectionPtr &conn,
|
||||||
const boost::function<void (void)> &callback = boost::function<void (void)>());
|
const std::function<void (void)> &callback = {});
|
||||||
~Watch();
|
~Watch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the callback triggered by this Watch. If the watch has
|
* Changes the callback triggered by this Watch. If the watch has
|
||||||
* already fired, the callback is invoked immediately.
|
* already fired, the callback is invoked immediately.
|
||||||
*/
|
*/
|
||||||
void setCallback(const boost::function<void (void)> &callback);
|
void setCallback(const std::function<void (void)> &callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts watching for disconnect of that peer
|
* Starts watching for disconnect of that peer
|
||||||
|
@ -2243,24 +2243,24 @@ class Watch : private boost::noncopyable
|
||||||
void activate(const char *peer);
|
void activate(const char *peer);
|
||||||
};
|
};
|
||||||
|
|
||||||
void getWatch(ExtractArgs &context, boost::shared_ptr<Watch> &value);
|
void getWatch(ExtractArgs &context, std::shared_ptr<Watch> &value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pseudo-parameter: not part of D-Bus signature,
|
* pseudo-parameter: not part of D-Bus signature,
|
||||||
* but rather extracted from message attributes
|
* but rather extracted from message attributes
|
||||||
*/
|
*/
|
||||||
template <> struct dbus_traits< boost::shared_ptr<Watch> > : public dbus_traits_base
|
template <> struct dbus_traits< std::shared_ptr<Watch> > : public dbus_traits_base
|
||||||
{
|
{
|
||||||
static std::string getType() { return ""; }
|
static std::string getType() { return ""; }
|
||||||
static std::string getSignature() { return ""; }
|
static std::string getSignature() { return ""; }
|
||||||
static std::string getReply() { return ""; }
|
static std::string getReply() { return ""; }
|
||||||
|
|
||||||
static void get(ExtractArgs &context,
|
static void get(ExtractArgs &context,
|
||||||
GVariantIter &iter, boost::shared_ptr<Watch> &value) { getWatch(context, value); }
|
GVariantIter &iter, std::shared_ptr<Watch> &value) { getWatch(context, value); }
|
||||||
static void append(GVariantBuilder &builder, const boost::shared_ptr<Watch> &value) {}
|
static void append(GVariantBuilder &builder, const std::shared_ptr<Watch> &value) {}
|
||||||
|
|
||||||
typedef boost::shared_ptr<Watch> host_type;
|
typedef std::shared_ptr<Watch> host_type;
|
||||||
typedef const boost::shared_ptr<Watch> &arg_type;
|
typedef const std::shared_ptr<Watch> &arg_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2320,7 +2320,7 @@ template<typename ...A> class DBusResult : virtual public Result<A...>
|
||||||
sendMsg(errMsg);
|
sendMsg(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Watch *createWatch(const boost::function<void (void)> &callback)
|
virtual Watch *createWatch(const std::function<void (void)> &callback)
|
||||||
{
|
{
|
||||||
std::unique_ptr<Watch> watch(new Watch(m_conn, callback));
|
std::unique_ptr<Watch> watch(new Watch(m_conn, callback));
|
||||||
watch->activate(g_dbus_message_get_sender(m_msg.get()));
|
watch->activate(g_dbus_message_get_sender(m_msg.get()));
|
||||||
|
@ -2348,14 +2348,14 @@ template<typename ...A> class DBusResult : virtual public Result<A...>
|
||||||
* destructs and transfers the responsibility for sending a reply to
|
* destructs and transfers the responsibility for sending a reply to
|
||||||
* the DBusResult instance.
|
* the DBusResult instance.
|
||||||
*/
|
*/
|
||||||
template <class DBusR> class DBusResultGuard : public boost::shared_ptr<DBusR>
|
template <class DBusR> class DBusResultGuard : public std::shared_ptr<DBusR>
|
||||||
{
|
{
|
||||||
GDBusMessage **m_msg;
|
GDBusMessage **m_msg;
|
||||||
public:
|
public:
|
||||||
DBusResultGuard() : m_msg(NULL) {}
|
DBusResultGuard() : m_msg(NULL) {}
|
||||||
~DBusResultGuard() throw ()
|
~DBusResultGuard() throw ()
|
||||||
{
|
{
|
||||||
DBusR *result = boost::shared_ptr<DBusR>::get();
|
DBusR *result = std::shared_ptr<DBusR>::get();
|
||||||
// Our caller has not cleared its "msg" instance,
|
// Our caller has not cleared its "msg" instance,
|
||||||
// which means that from now on it will be our
|
// which means that from now on it will be our
|
||||||
// responsibility to provide a response.
|
// responsibility to provide a response.
|
||||||
|
@ -2367,19 +2367,19 @@ template <class DBusR> class DBusResultGuard : public boost::shared_ptr<DBusR>
|
||||||
void initDBusResult(ExtractArgs &context)
|
void initDBusResult(ExtractArgs &context)
|
||||||
{
|
{
|
||||||
m_msg = context.m_msg;
|
m_msg = context.m_msg;
|
||||||
boost::shared_ptr<DBusR>::reset(new DBusR(context.m_conn, context.m_msg ? *context.m_msg : NULL));
|
std::shared_ptr<DBusR>::reset(new DBusR(context.m_conn, context.m_msg ? *context.m_msg : NULL));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ...A>
|
template <typename ...A>
|
||||||
struct dbus_traits< boost::shared_ptr<Result<A...> > >
|
struct dbus_traits< std::shared_ptr<Result<A...> > >
|
||||||
{
|
{
|
||||||
static std::string getType() { return DBusResult<A...>::getSignature(); }
|
static std::string getType() { return DBusResult<A...>::getSignature(); }
|
||||||
static std::string getSignature() { return ""; }
|
static std::string getSignature() { return ""; }
|
||||||
static std::string getReply() { return getType(); }
|
static std::string getReply() { return getType(); }
|
||||||
|
|
||||||
typedef DBusResultGuard< DBusResult<A...> > host_type;
|
typedef DBusResultGuard< DBusResult<A...> > host_type;
|
||||||
typedef boost::shared_ptr< Result<A...> > &arg_type;
|
typedef std::shared_ptr< Result<A...> > &arg_type;
|
||||||
static const bool asynchronous = true;
|
static const bool asynchronous = true;
|
||||||
|
|
||||||
static void get(ExtractArgs &context,
|
static void get(ExtractArgs &context,
|
||||||
|
@ -2421,10 +2421,10 @@ namespace {
|
||||||
|
|
||||||
/** return value */
|
/** return value */
|
||||||
template <typename R, typename ...A>
|
template <typename R, typename ...A>
|
||||||
struct MakeMethodEntry< boost::function<R (A...)> >
|
struct MakeMethodEntry< std::function<R (A...)> >
|
||||||
{
|
{
|
||||||
typedef R (Mptr)(A...);
|
typedef R (Mptr)(A...);
|
||||||
typedef boost::function<Mptr> M;
|
typedef std::function<Mptr> M;
|
||||||
|
|
||||||
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
|
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
|
||||||
return [method, instance] (A... a) {
|
return [method, instance] (A... a) {
|
||||||
|
@ -2491,10 +2491,10 @@ struct MakeMethodEntry< boost::function<R (A...)> >
|
||||||
|
|
||||||
/** no return value */
|
/** no return value */
|
||||||
template <typename ...A>
|
template <typename ...A>
|
||||||
struct MakeMethodEntry< boost::function<void (A...)> >
|
struct MakeMethodEntry< std::function<void (A...)> >
|
||||||
{
|
{
|
||||||
typedef void (Mptr)(A...);
|
typedef void (Mptr)(A...);
|
||||||
typedef boost::function<Mptr> M;
|
typedef std::function<Mptr> M;
|
||||||
|
|
||||||
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
|
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
|
||||||
return [method, instance] (A... a) {
|
return [method, instance] (A... a) {
|
||||||
|
@ -2588,7 +2588,7 @@ template<typename R1, typename R2, typename R3, typename ...R> struct DBusClient
|
||||||
|
|
||||||
template<typename ...R> class DBusClientCall
|
template<typename ...R> class DBusClientCall
|
||||||
{
|
{
|
||||||
typedef boost::function<void (R..., const std::string &)> Callback_t;
|
typedef std::function<void (R..., const std::string &)> Callback_t;
|
||||||
typedef typename DBusClientCallReturnType<R...>::Return_t Return_t;
|
typedef typename DBusClientCallReturnType<R...>::Return_t Return_t;
|
||||||
typedef typename DBusClientCallReturnType<R...>::Buffer_t Buffer_t;
|
typedef typename DBusClientCallReturnType<R...>::Buffer_t Buffer_t;
|
||||||
|
|
||||||
|
@ -2877,7 +2877,7 @@ template <typename ...A> class SignalWatch : public SignalFilter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef boost::function<void (A...)> Callback_t;
|
typedef std::function<void (A...)> Callback_t;
|
||||||
const Callback_t &getCallback() const { return m_callback; }
|
const Callback_t &getCallback() const { return m_callback; }
|
||||||
|
|
||||||
void activate(const Callback_t &callback)
|
void activate(const Callback_t &callback)
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <boost/function.hpp>
|
#include <functional>
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
namespace GDBusCXX {
|
namespace GDBusCXX {
|
||||||
|
@ -122,10 +123,10 @@ class ResultBase : private boost::noncopyable
|
||||||
* is requested.
|
* is requested.
|
||||||
*
|
*
|
||||||
* Alternatively a method can ask to get called with a life Watch
|
* Alternatively a method can ask to get called with a life Watch
|
||||||
* by specifying "const boost::shared_ptr<Watch> &" as parameter
|
* by specifying "const std::shared_ptr<Watch> &" as parameter
|
||||||
* and then calling its setCallback().
|
* and then calling its setCallback().
|
||||||
*/
|
*/
|
||||||
virtual Watch *createWatch(const boost::function<void (void)> &callback) = 0;
|
virtual Watch *createWatch(const std::function<void (void)> &callback) = 0;
|
||||||
};
|
};
|
||||||
template<typename ...A> class Result : public ResultBase
|
template<typename ...A> class Result : public ResultBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Including this header file allows to use boost::bind() with
|
* Including this header file allows to use boost::bind() with
|
||||||
* a class member as first parameter and a boost::weak_ptr
|
* a class member as first parameter and a std::weak_ptr
|
||||||
* as second parameter.
|
* as second parameter.
|
||||||
*
|
*
|
||||||
* When the functor is invoked, it will lock the instance
|
* When the functor is invoked, it will lock the instance
|
||||||
|
@ -44,7 +44,6 @@
|
||||||
#ifndef INCL_SYNCEVOLUTION_BOOST_HELPER
|
#ifndef INCL_SYNCEVOLUTION_BOOST_HELPER
|
||||||
# define INCL_SYNCEVOLUTION_BOOST_HELPER
|
# define INCL_SYNCEVOLUTION_BOOST_HELPER
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <boost/smart_ptr.hpp>
|
#include <boost/smart_ptr.hpp>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
|
@ -146,26 +145,26 @@ class WeakPtrInvoker
|
||||||
template <typename T> class WeakPtrAdapter
|
template <typename T> class WeakPtrAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WeakPtrAdapter(const boost::shared_ptr<T> &ptr) :
|
WeakPtrAdapter(const std::shared_ptr<T> &ptr) :
|
||||||
m_ptr(ptr)
|
m_ptr(ptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename M>
|
template <typename M>
|
||||||
WeakPtrInvoker<boost::shared_ptr<T>, M> operator->*(M member) const
|
WeakPtrInvoker<std::shared_ptr<T>, M> operator->*(M member) const
|
||||||
{
|
{
|
||||||
return WeakPtrInvoker<boost::shared_ptr<T>, M>(m_ptr, member);
|
return WeakPtrInvoker<std::shared_ptr<T>, M>(m_ptr, member);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<T> m_ptr;
|
std::shared_ptr<T> m_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
||||||
namespace boost
|
namespace std
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
SyncEvo::WeakPtrAdapter<T> get_pointer(const boost::weak_ptr<T> &ptr)
|
SyncEvo::WeakPtrAdapter<T> get_pointer(const std::weak_ptr<T> &ptr)
|
||||||
{
|
{
|
||||||
return SyncEvo::WeakPtrAdapter<T>(ptr.lock());
|
return SyncEvo::WeakPtrAdapter<T>(ptr.lock());
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <boost/algorithm/string/split.hpp>
|
#include <boost/algorithm/string/split.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
@ -441,7 +440,7 @@ bool Cmdline::dontRun() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
void Cmdline::makeObsolete(std::shared_ptr<SyncConfig> &from)
|
||||||
{
|
{
|
||||||
string oldname = from->getRootPath();
|
string oldname = from->getRootPath();
|
||||||
string newname, suffix;
|
string newname, suffix;
|
||||||
|
@ -454,7 +453,7 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
||||||
suffix = newsuffix.str();
|
suffix = newsuffix.str();
|
||||||
newname = oldname + suffix;
|
newname = oldname + suffix;
|
||||||
if (from->hasPeerProperties()) {
|
if (from->hasPeerProperties()) {
|
||||||
boost::shared_ptr<SyncConfig> renamed(new SyncConfig(from->getPeerName() + suffix));
|
auto renamed = std::make_shared<SyncConfig>(from->getPeerName() + suffix);
|
||||||
if (renamed->exists()) {
|
if (renamed->exists()) {
|
||||||
// don't pick a config name which has the same peer name
|
// don't pick a config name which has the same peer name
|
||||||
// as some other, existing config
|
// as some other, existing config
|
||||||
|
@ -489,8 +488,8 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
||||||
from.reset(new SyncConfig(newConfigName));
|
from.reset(new SyncConfig(newConfigName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmdline::copyConfig(const boost::shared_ptr<SyncConfig> &from,
|
void Cmdline::copyConfig(const std::shared_ptr<SyncConfig> &from,
|
||||||
const boost::shared_ptr<SyncConfig> &to,
|
const std::shared_ptr<SyncConfig> &to,
|
||||||
const set<string> &selectedSources)
|
const set<string> &selectedSources)
|
||||||
{
|
{
|
||||||
const set<string> *sources = NULL;
|
const set<string> *sources = NULL;
|
||||||
|
@ -533,8 +532,8 @@ void Cmdline::copyConfig(const boost::shared_ptr<SyncConfig> &from,
|
||||||
to->copy(*from, sources);
|
to->copy(*from, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmdline::finishCopy(const boost::shared_ptr<SyncConfig> &from,
|
void Cmdline::finishCopy(const std::shared_ptr<SyncConfig> &from,
|
||||||
const boost::shared_ptr<SyncContext> &to)
|
const std::shared_ptr<SyncContext> &to)
|
||||||
{
|
{
|
||||||
// give a change to do something before flushing configs to files
|
// give a change to do something before flushing configs to files
|
||||||
to->preFlush(to->getUserInterfaceNonNull());
|
to->preFlush(to->getUserInterfaceNonNull());
|
||||||
|
@ -599,11 +598,11 @@ void Cmdline::finishCopy(const boost::shared_ptr<SyncConfig> &from,
|
||||||
|
|
||||||
void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer)
|
void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<SyncConfig> from(new SyncConfig(fromPeer));
|
auto from = std::make_shared<SyncConfig>(fromPeer);
|
||||||
makeObsolete(from);
|
makeObsolete(from);
|
||||||
// hack: move to different target config for createSyncClient()
|
// hack: move to different target config for createSyncClient()
|
||||||
m_server = toPeer;
|
m_server = toPeer;
|
||||||
boost::shared_ptr<SyncContext> to(createSyncClient());
|
std::shared_ptr<SyncContext> to(createSyncClient());
|
||||||
|
|
||||||
// Special case for Memotoo: explicitly set preferred sync format
|
// Special case for Memotoo: explicitly set preferred sync format
|
||||||
// to vCard 3.0 as part of the SyncEvolution 1.1.x -> 1.2 migration,
|
// to vCard 3.0 as part of the SyncEvolution 1.1.x -> 1.2 migration,
|
||||||
|
@ -613,7 +612,7 @@ void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer
|
||||||
vector<string> urls = from->getSyncURL();
|
vector<string> urls = from->getSyncURL();
|
||||||
if (urls.size() == 1 &&
|
if (urls.size() == 1 &&
|
||||||
urls[0] == "http://sync.memotoo.com/syncML") {
|
urls[0] == "http://sync.memotoo.com/syncML") {
|
||||||
boost::shared_ptr<SyncContext> to(createSyncClient());
|
std::shared_ptr<SyncContext> to(createSyncClient());
|
||||||
m_props[to->getContextName()].m_sourceProps["addressbook"].insert(make_pair("syncFormat", "text/vcard"));
|
m_props[to->getContextName()].m_sourceProps["addressbook"].insert(make_pair("syncFormat", "text/vcard"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,18 +657,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ShowLUID(SyncSourceLogging *logging, const std::string &luid)
|
|
||||||
{
|
|
||||||
string description;
|
|
||||||
if (logging) {
|
|
||||||
description = logging->getDescription(luid);
|
|
||||||
}
|
|
||||||
SE_LOG_SHOW(NULL, "%s%s%s",
|
|
||||||
CmdlineLUID::fromLUID(luid).c_str(),
|
|
||||||
description.empty() ? "" : ": ",
|
|
||||||
description.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ExportLUID(SyncSourceRaw *raw,
|
static void ExportLUID(SyncSourceRaw *raw,
|
||||||
ostream *out,
|
ostream *out,
|
||||||
const std::string &defDelimiter,
|
const std::string &defDelimiter,
|
||||||
|
@ -754,9 +741,9 @@ bool Cmdline::run() {
|
||||||
} else if (m_printDatabases || m_createDatabase || m_removeDatabase) {
|
} else if (m_printDatabases || m_createDatabase || m_removeDatabase) {
|
||||||
// manipulate databases
|
// manipulate databases
|
||||||
const SourceRegistry ®istry(SyncSource::getSourceRegistry());
|
const SourceRegistry ®istry(SyncSource::getSourceRegistry());
|
||||||
boost::shared_ptr<SyncSourceNodes> nodes;
|
std::shared_ptr<SyncSourceNodes> nodes;
|
||||||
std::string header;
|
std::string header;
|
||||||
boost::shared_ptr<SyncContext> context;
|
std::shared_ptr<SyncContext> context;
|
||||||
FilterConfigNode::ConfigFilter sourceFilter;
|
FilterConfigNode::ConfigFilter sourceFilter;
|
||||||
std::string sourceName;
|
std::string sourceName;
|
||||||
FilterConfigNode::ConfigFilter::const_iterator backend;
|
FilterConfigNode::ConfigFilter::const_iterator backend;
|
||||||
|
@ -789,11 +776,11 @@ bool Cmdline::run() {
|
||||||
sourceFilter = m_props.createSourceFilter(m_server, "");
|
sourceFilter = m_props.createSourceFilter(m_server, "");
|
||||||
backend = sourceFilter.find("backend");
|
backend = sourceFilter.find("backend");
|
||||||
context.reset(createSyncClient());
|
context.reset(createSyncClient());
|
||||||
boost::shared_ptr<FilterConfigNode> sharedNode(new VolatileConfigNode());
|
auto sharedNode = std::make_shared<VolatileConfigNode>();
|
||||||
boost::shared_ptr<FilterConfigNode> configNode(new VolatileConfigNode());
|
auto configNode = std::make_shared<VolatileConfigNode>();
|
||||||
boost::shared_ptr<FilterConfigNode> hiddenNode(new VolatileConfigNode());
|
auto hiddenNode = std::make_shared<VolatileConfigNode>();
|
||||||
boost::shared_ptr<FilterConfigNode> trackingNode(new VolatileConfigNode());
|
auto trackingNode = std::make_shared<VolatileConfigNode>();
|
||||||
boost::shared_ptr<FilterConfigNode> serverNode(new VolatileConfigNode());
|
auto serverNode = std::make_shared<VolatileConfigNode>();
|
||||||
nodes.reset(new SyncSourceNodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, ""));
|
nodes.reset(new SyncSourceNodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, ""));
|
||||||
header = backend != sourceFilter.end() ?
|
header = backend != sourceFilter.end() ?
|
||||||
backend->second :
|
backend->second :
|
||||||
|
@ -844,7 +831,7 @@ bool Cmdline::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m_printConfig) {
|
} else if (m_printConfig) {
|
||||||
boost::shared_ptr<SyncConfig> config;
|
std::shared_ptr<SyncConfig> config;
|
||||||
ConfigProps syncFilter;
|
ConfigProps syncFilter;
|
||||||
SourceProps sourceFilters;
|
SourceProps sourceFilters;
|
||||||
|
|
||||||
|
@ -896,7 +883,7 @@ bool Cmdline::run() {
|
||||||
|
|
||||||
if (m_sources.empty() ||
|
if (m_sources.empty() ||
|
||||||
m_sources.find("main") != m_sources.end()) {
|
m_sources.find("main") != m_sources.end()) {
|
||||||
boost::shared_ptr<FilterConfigNode> syncProps(config->getProperties());
|
std::shared_ptr<FilterConfigNode> syncProps(config->getProperties());
|
||||||
syncProps->setFilter(syncFilter);
|
syncProps->setFilter(syncFilter);
|
||||||
dumpProperties(*syncProps, config->getRegistry(), flags);
|
dumpProperties(*syncProps, config->getRegistry(), flags);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +895,7 @@ bool Cmdline::run() {
|
||||||
m_sources.find(name) != m_sources.end()) {
|
m_sources.find(name) != m_sources.end()) {
|
||||||
SE_LOG_SHOW(NULL, "[%s]", name.c_str());
|
SE_LOG_SHOW(NULL, "[%s]", name.c_str());
|
||||||
SyncSourceNodes nodes = config->getSyncSourceNodes(name);
|
SyncSourceNodes nodes = config->getSyncSourceNodes(name);
|
||||||
boost::shared_ptr<FilterConfigNode> sourceProps = nodes.getProperties();
|
std::shared_ptr<FilterConfigNode> sourceProps = nodes.getProperties();
|
||||||
sourceProps->setFilter(sourceFilters.createSourceFilter(name));
|
sourceProps->setFilter(sourceFilters.createSourceFilter(name));
|
||||||
dumpProperties(*sourceProps, SyncSourceConfig::getRegistry(),
|
dumpProperties(*sourceProps, SyncSourceConfig::getRegistry(),
|
||||||
flags | ((name != *(--sources.end())) ? HIDE_LEGEND : DUMP_PROPS_NORMAL));
|
flags | ((name != *(--sources.end())) ? HIDE_LEGEND : DUMP_PROPS_NORMAL));
|
||||||
|
@ -953,8 +940,8 @@ bool Cmdline::run() {
|
||||||
// another config (template resp. old one). Migration also moves
|
// another config (template resp. old one). Migration also moves
|
||||||
// the old config. The target configuration is determined by m_server,
|
// the old config. The target configuration is determined by m_server,
|
||||||
// but the exact semantic of it depends on the operation.
|
// but the exact semantic of it depends on the operation.
|
||||||
boost::shared_ptr<SyncConfig> from;
|
std::shared_ptr<SyncConfig> from;
|
||||||
boost::shared_ptr<SyncContext> to;
|
std::shared_ptr<SyncContext> to;
|
||||||
string origPeer;
|
string origPeer;
|
||||||
if (m_migrate) {
|
if (m_migrate) {
|
||||||
if (!m_sources.empty()) {
|
if (!m_sources.empty()) {
|
||||||
|
@ -1210,7 +1197,7 @@ bool Cmdline::run() {
|
||||||
SuspendFlags &s = SuspendFlags::getSuspendFlags();
|
SuspendFlags &s = SuspendFlags::getSuspendFlags();
|
||||||
|
|
||||||
for (const string &source: configuredSources) {
|
for (const string &source: configuredSources) {
|
||||||
boost::shared_ptr<PersistentSyncSourceConfig> sourceConfig(to->getSyncSourceConfig(source));
|
std::shared_ptr<PersistentSyncSourceConfig> sourceConfig(to->getSyncSourceConfig(source));
|
||||||
string disable = "";
|
string disable = "";
|
||||||
set<string>::iterator entry = sources.find(source);
|
set<string>::iterator entry = sources.find(source);
|
||||||
bool selected = entry != sources.end();
|
bool selected = entry != sources.end();
|
||||||
|
@ -1342,7 +1329,7 @@ bool Cmdline::run() {
|
||||||
usage(false, "too many parameters for --remove");
|
usage(false, "too many parameters for --remove");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
boost::shared_ptr<SyncConfig> config;
|
std::shared_ptr<SyncConfig> config;
|
||||||
config.reset(new SyncConfig(m_server));
|
config.reset(new SyncConfig(m_server));
|
||||||
if (!config->exists()) {
|
if (!config->exists()) {
|
||||||
Exception::throwError(SE_HERE, string("no such configuration: ") + m_server);
|
Exception::throwError(SE_HERE, string("no such configuration: ") + m_server);
|
||||||
|
@ -1353,7 +1340,7 @@ bool Cmdline::run() {
|
||||||
}
|
}
|
||||||
} else if (m_accessItems) {
|
} else if (m_accessItems) {
|
||||||
// need access to specific source
|
// need access to specific source
|
||||||
boost::shared_ptr<SyncContext> context;
|
std::shared_ptr<SyncContext> context;
|
||||||
context.reset(createSyncClient());
|
context.reset(createSyncClient());
|
||||||
|
|
||||||
// operating on exactly one source (can be optional)
|
// operating on exactly one source (can be optional)
|
||||||
|
@ -1420,7 +1407,17 @@ bool Cmdline::run() {
|
||||||
err = ops.m_startDataRead("", "");
|
err = ops.m_startDataRead("", "");
|
||||||
CHECK_ERROR("reading items");
|
CHECK_ERROR("reading items");
|
||||||
source->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
|
source->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
|
||||||
processLUIDs(source, boost::bind(ShowLUID, logging, _1));
|
auto showLUID = [logging] (const std::string &luid) {
|
||||||
|
string description;
|
||||||
|
if (logging) {
|
||||||
|
description = logging->getDescription(luid);
|
||||||
|
}
|
||||||
|
SE_LOG_SHOW(NULL, "%s%s%s",
|
||||||
|
CmdlineLUID::fromLUID(luid).c_str(),
|
||||||
|
description.empty() ? "" : ": ",
|
||||||
|
description.c_str());
|
||||||
|
};
|
||||||
|
processLUIDs(source, showLUID);
|
||||||
} else if (m_deleteItems) {
|
} else if (m_deleteItems) {
|
||||||
if (!ops.m_deleteItem) {
|
if (!ops.m_deleteItem) {
|
||||||
source->throwError(SE_HERE, "deleting items not supported");
|
source->throwError(SE_HERE, "deleting items not supported");
|
||||||
|
@ -1570,14 +1567,10 @@ bool Cmdline::run() {
|
||||||
if (m_luids.empty()) {
|
if (m_luids.empty()) {
|
||||||
// Read all items.
|
// Read all items.
|
||||||
raw->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
|
raw->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
|
||||||
processLUIDs(source, boost::bind(ExportLUID,
|
auto exportOne = [this, raw, out, &haveItem, &haveNewline] (const std::string &luid) {
|
||||||
raw,
|
ExportLUID(raw, out, m_delimiter, m_itemPath, haveItem, haveNewline, luid);
|
||||||
out,
|
};
|
||||||
boost::ref(m_delimiter),
|
processLUIDs(source, exportOne);
|
||||||
boost::ref(m_itemPath),
|
|
||||||
boost::ref(haveItem),
|
|
||||||
boost::ref(haveNewline),
|
|
||||||
_1));
|
|
||||||
} else {
|
} else {
|
||||||
SyncSourceBase::ReadAheadItems luids;
|
SyncSourceBase::ReadAheadItems luids;
|
||||||
luids.reserve(m_luids.size());
|
luids.reserve(m_luids.size());
|
||||||
|
@ -1603,7 +1596,7 @@ bool Cmdline::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> unmatchedSources;
|
std::set<std::string> unmatchedSources;
|
||||||
boost::shared_ptr<SyncContext> context;
|
std::shared_ptr<SyncContext> context;
|
||||||
context.reset(createSyncClient());
|
context.reset(createSyncClient());
|
||||||
context->setConfigProps(m_props);
|
context->setConfigProps(m_props);
|
||||||
context->setQuiet(m_quiet);
|
context->setQuiet(m_quiet);
|
||||||
|
@ -1617,7 +1610,7 @@ bool Cmdline::run() {
|
||||||
// accidentally when the sync mode is modified
|
// accidentally when the sync mode is modified
|
||||||
// temporarily.
|
// temporarily.
|
||||||
for (const std::string &source: context->getSyncSources()) {
|
for (const std::string &source: context->getSyncSources()) {
|
||||||
boost::shared_ptr<PersistentSyncSourceConfig> source_config =
|
std::shared_ptr<PersistentSyncSourceConfig> source_config =
|
||||||
context->getSyncSourceConfig(source);
|
context->getSyncSourceConfig(source);
|
||||||
if (!source_config->isDisabled()) {
|
if (!source_config->isDisabled()) {
|
||||||
context->setConfigFilter(false, source, m_props.createSourceFilter(m_server, source));
|
context->setConfigFilter(false, source, m_props.createSourceFilter(m_server, source));
|
||||||
|
@ -1626,7 +1619,7 @@ bool Cmdline::run() {
|
||||||
} else {
|
} else {
|
||||||
// apply (possibly empty) source filter to selected sources
|
// apply (possibly empty) source filter to selected sources
|
||||||
for (const std::string &source: m_sources) {
|
for (const std::string &source: m_sources) {
|
||||||
boost::shared_ptr<PersistentSyncSourceConfig> source_config =
|
std::shared_ptr<PersistentSyncSourceConfig> source_config =
|
||||||
context->getSyncSourceConfig(source);
|
context->getSyncSourceConfig(source);
|
||||||
ConfigProps filter = m_props.createSourceFilter(m_server, source);
|
ConfigProps filter = m_props.createSourceFilter(m_server, source);
|
||||||
if (!source_config || !source_config->exists()) {
|
if (!source_config || !source_config->exists()) {
|
||||||
|
@ -1721,10 +1714,13 @@ bool Cmdline::run() {
|
||||||
|
|
||||||
void Cmdline::readLUIDs(SyncSource *source, list<string> &luids)
|
void Cmdline::readLUIDs(SyncSource *source, list<string> &luids)
|
||||||
{
|
{
|
||||||
processLUIDs(source, boost::bind(static_cast<void (list<string>::*)(const string &)>(&list<string>::push_back), boost::ref(luids), _1));
|
auto append = [&luids] (const std::string &luid) {
|
||||||
|
luids.push_back(luid);
|
||||||
|
};
|
||||||
|
processLUIDs(source, append);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmdline::processLUIDs(SyncSource *source, const boost::function<void (const std::string &)> &process)
|
void Cmdline::processLUIDs(SyncSource *source, const std::function<void (const std::string &)> &process)
|
||||||
{
|
{
|
||||||
const SyncSource::Operations &ops = source->getOperations();
|
const SyncSource::Operations &ops = source->getOperations();
|
||||||
sysync::ItemIDType id;
|
sysync::ItemIDType id;
|
||||||
|
@ -3298,7 +3294,7 @@ protected:
|
||||||
rm_r(m_testDir);
|
rm_r(m_testDir);
|
||||||
{
|
{
|
||||||
TestCmdline cmdline(NULL, NULL);
|
TestCmdline cmdline(NULL, NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
|
||||||
|
@ -3306,7 +3302,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring", NULL);
|
TestCmdline cmdline("--keyring", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3314,7 +3310,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--sync-property", "keyring=True", NULL);
|
TestCmdline cmdline("--sync-property", "keyring=True", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3322,7 +3318,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("keyring=True", NULL);
|
TestCmdline cmdline("keyring=True", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3330,7 +3326,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=true", NULL);
|
TestCmdline cmdline("--keyring=true", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3338,7 +3334,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=1", NULL);
|
TestCmdline cmdline("--keyring=1", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3346,7 +3342,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=Yes", NULL);
|
TestCmdline cmdline("--keyring=Yes", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3354,7 +3350,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=false", NULL);
|
TestCmdline cmdline("--keyring=false", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3362,7 +3358,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=0", NULL);
|
TestCmdline cmdline("--keyring=0", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3370,7 +3366,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=NO", NULL);
|
TestCmdline cmdline("--keyring=NO", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3378,7 +3374,7 @@ protected:
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=GNOME", NULL);
|
TestCmdline cmdline("--keyring=GNOME", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3422,7 +3418,7 @@ protected:
|
||||||
|
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("@foobar", NULL);
|
TestCmdline cmdline("@foobar", NULL);
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
|
||||||
|
@ -3433,7 +3429,7 @@ protected:
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring", "--configure", "@default", NULL);
|
TestCmdline cmdline("--keyring", "--configure", "@default", NULL);
|
||||||
cmdline.doit();
|
cmdline.doit();
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3442,7 +3438,7 @@ protected:
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("--keyring=KDE", "--configure", "@default", NULL);
|
TestCmdline cmdline("--keyring=KDE", "--configure", "@default", NULL);
|
||||||
cmdline.doit();
|
cmdline.doit();
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3456,7 +3452,7 @@ protected:
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("keyring=KDE", "--configure", "@default", NULL);
|
TestCmdline cmdline("keyring=KDE", "--configure", "@default", NULL);
|
||||||
cmdline.doit();
|
cmdline.doit();
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -3465,7 +3461,7 @@ protected:
|
||||||
{
|
{
|
||||||
TestCmdline cmdline("keyring=yes", "--configure", "@default", NULL);
|
TestCmdline cmdline("keyring=yes", "--configure", "@default", NULL);
|
||||||
cmdline.doit();
|
cmdline.doit();
|
||||||
boost::shared_ptr<SyncContext> context = cmdline.parse();
|
std::shared_ptr<SyncContext> context = cmdline.parse();
|
||||||
CPPUNIT_ASSERT(context);
|
CPPUNIT_ASSERT(context);
|
||||||
InitStateTri keyring = context->getKeyring();
|
InitStateTri keyring = context->getKeyring();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
|
||||||
|
@ -4415,7 +4411,7 @@ private:
|
||||||
*/
|
*/
|
||||||
class TestCmdline : public Logger {
|
class TestCmdline : public Logger {
|
||||||
void init() {
|
void init() {
|
||||||
addLogger(boost::shared_ptr<Logger>(this, NopDestructor()));
|
addLogger(std::shared_ptr<Logger>(this, NopDestructor()));
|
||||||
|
|
||||||
m_argv.reset(new const char *[m_argvstr.size() + 1]);
|
m_argv.reset(new const char *[m_argvstr.size() + 1]);
|
||||||
m_argv[0] = "client-test";
|
m_argv[0] = "client-test";
|
||||||
|
@ -4452,12 +4448,12 @@ private:
|
||||||
removeLogger(this);
|
removeLogger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<SyncContext> parse()
|
std::shared_ptr<SyncContext> parse()
|
||||||
{
|
{
|
||||||
if (!m_cmdline->parse()) {
|
if (!m_cmdline->parse()) {
|
||||||
return boost::shared_ptr<SyncContext>();
|
return std::shared_ptr<SyncContext>();
|
||||||
}
|
}
|
||||||
boost::shared_ptr<SyncContext> context(new SyncContext(m_cmdline->m_server));
|
auto context = std::make_shared<SyncContext>(m_cmdline->m_server);
|
||||||
context->setConfigFilter(true, "", m_cmdline->m_props.createSyncFilter(m_cmdline->m_server));
|
context->setConfigFilter(true, "", m_cmdline->m_props.createSyncFilter(m_cmdline->m_server));
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
#include <syncevo/util.h>
|
#include <syncevo/util.h>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/scoped_array.hpp>
|
#include <boost/scoped_array.hpp>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
|
@ -178,7 +178,7 @@ protected:
|
||||||
* rename file or directory by appending .old or (if that already
|
* rename file or directory by appending .old or (if that already
|
||||||
* exists) .old.x for x >= 1; updates config to point to the renamed directory
|
* exists) .old.x for x >= 1; updates config to point to the renamed directory
|
||||||
*/
|
*/
|
||||||
void makeObsolete(boost::shared_ptr<SyncConfig> &from);
|
void makeObsolete(std::shared_ptr<SyncConfig> &from);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy from one config into another, with filters
|
* Copy from one config into another, with filters
|
||||||
|
@ -186,15 +186,15 @@ protected:
|
||||||
* if selectedSources is empty, otherwise only
|
* if selectedSources is empty, otherwise only
|
||||||
* those.
|
* those.
|
||||||
*/
|
*/
|
||||||
void copyConfig(const boost::shared_ptr<SyncConfig> &from,
|
void copyConfig(const std::shared_ptr<SyncConfig> &from,
|
||||||
const boost::shared_ptr<SyncConfig> &to,
|
const std::shared_ptr<SyncConfig> &to,
|
||||||
const std::set<std::string> &selectedSources);
|
const std::set<std::string> &selectedSources);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* flush, move .synthesis dir, set ConsumerReady, ...
|
* flush, move .synthesis dir, set ConsumerReady, ...
|
||||||
*/
|
*/
|
||||||
void finishCopy(const boost::shared_ptr<SyncConfig> &from,
|
void finishCopy(const std::shared_ptr<SyncConfig> &from,
|
||||||
const boost::shared_ptr<SyncContext> &to);
|
const std::shared_ptr<SyncContext> &to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* migrate peer config; target context must be ready
|
* migrate peer config; target context must be ready
|
||||||
|
@ -324,7 +324,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Invoke a callback for each local ID.
|
* Invoke a callback for each local ID.
|
||||||
*/
|
*/
|
||||||
void processLUIDs(SyncSource *source, const boost::function<void (const std::string &)> &callback);
|
void processLUIDs(SyncSource *source, const std::function<void (const std::string &)> &callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add or update one item.
|
* Add or update one item.
|
||||||
|
|
|
@ -164,7 +164,7 @@ void FullProps::createFilters(const std::string &context,
|
||||||
ConfigProps &syncFilter,
|
ConfigProps &syncFilter,
|
||||||
SourceProps &sourceFilters)
|
SourceProps &sourceFilters)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<SyncConfig> shared;
|
std::shared_ptr<SyncConfig> shared;
|
||||||
|
|
||||||
if (!context.empty()) {
|
if (!context.empty()) {
|
||||||
// Read from context. If it does not exist, we simply set no properties
|
// Read from context. If it does not exist, we simply set no properties
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
|
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
boost::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &filename)
|
std::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &filename)
|
||||||
{
|
{
|
||||||
std::string::size_type off = filename.rfind('/');
|
std::string::size_type off = filename.rfind('/');
|
||||||
boost::shared_ptr<ConfigNode> filenode;
|
std::shared_ptr<ConfigNode> filenode;
|
||||||
if (off != filename.npos) {
|
if (off != filename.npos) {
|
||||||
filenode.reset(new IniFileConfigNode(filename.substr(0, off),
|
filenode.reset(new IniFileConfigNode(filename.substr(0, off),
|
||||||
filename.substr(off + 1),
|
filename.substr(off + 1),
|
||||||
|
@ -37,7 +37,7 @@ boost::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &file
|
||||||
} else {
|
} else {
|
||||||
filenode.reset(new IniFileConfigNode(".", filename, false));
|
filenode.reset(new IniFileConfigNode(".", filename, false));
|
||||||
}
|
}
|
||||||
boost::shared_ptr<SafeConfigNode> savenode(new SafeConfigNode(filenode));
|
auto savenode = std::make_shared<SafeConfigNode>(filenode);
|
||||||
savenode->setMode(false);
|
savenode->setMode(false);
|
||||||
return savenode;
|
return savenode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
|
@ -47,7 +47,7 @@ class ConfigNode {
|
||||||
virtual ~ConfigNode() {}
|
virtual ~ConfigNode() {}
|
||||||
|
|
||||||
/** creates a file-backed config node which accepts arbitrary key/value pairs */
|
/** creates a file-backed config node which accepts arbitrary key/value pairs */
|
||||||
static boost::shared_ptr<ConfigNode> createFileNode(const std::string &filename);
|
static std::shared_ptr<ConfigNode> createFileNode(const std::string &filename);
|
||||||
|
|
||||||
/** a name for the node that the user can understand */
|
/** a name for the node that the user can understand */
|
||||||
virtual std::string getName() const = 0;
|
virtual std::string getName() const = 0;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef INCL_EVOLUTION_CONFIG_TREE
|
#ifndef INCL_EVOLUTION_CONFIG_TREE
|
||||||
# define INCL_EVOLUTION_CONFIG_TREE
|
# define INCL_EVOLUTION_CONFIG_TREE
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -104,7 +104,7 @@ class ConfigTree {
|
||||||
* node's name (allows having multiple different such
|
* node's name (allows having multiple different such
|
||||||
* nodes); an empty string is allowed
|
* nodes); an empty string is allowed
|
||||||
*/
|
*/
|
||||||
virtual boost::shared_ptr<ConfigNode> open(const std::string &path,
|
virtual std::shared_ptr<ConfigNode> open(const std::string &path,
|
||||||
PropertyType type,
|
PropertyType type,
|
||||||
const std::string &otherId = std::string("")) = 0;
|
const std::string &otherId = std::string("")) = 0;
|
||||||
|
|
||||||
|
@ -121,8 +121,8 @@ class ConfigTree {
|
||||||
* @param node default instance if not opened before, discarded if a
|
* @param node default instance if not opened before, discarded if a
|
||||||
* node was registered or opened under the given path before
|
* node was registered or opened under the given path before
|
||||||
*/
|
*/
|
||||||
virtual boost::shared_ptr<ConfigNode> add(const std::string &path,
|
virtual std::shared_ptr<ConfigNode> add(const std::string &path,
|
||||||
const boost::shared_ptr<ConfigNode> &node) = 0;
|
const std::shared_ptr<ConfigNode> &node) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns names of all existing nodes beneath the given path
|
* returns names of all existing nodes beneath the given path
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
# define INCL_EVOLUTION_DATA_BLOB
|
# define INCL_EVOLUTION_DATA_BLOB
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
@ -41,12 +41,12 @@ class DataBlob
|
||||||
* Create stream for writing data.
|
* Create stream for writing data.
|
||||||
* Always overwrites old data.
|
* Always overwrites old data.
|
||||||
*/
|
*/
|
||||||
virtual boost::shared_ptr<std::ostream> write() = 0;
|
virtual std::shared_ptr<std::ostream> write() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create stream for reading data.
|
* Create stream for reading data.
|
||||||
*/
|
*/
|
||||||
virtual boost::shared_ptr<std::istream> read() = 0;
|
virtual std::shared_ptr<std::istream> read() = 0;
|
||||||
|
|
||||||
/** some kind of user visible name for the data */
|
/** some kind of user visible name for the data */
|
||||||
virtual std::string getName() const = 0;
|
virtual std::string getName() const = 0;
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader)
|
EDSRegistryLoader &EDSRegistryLoaderSingleton(const std::shared_ptr<EDSRegistryLoader> &loader)
|
||||||
{
|
{
|
||||||
static boost::shared_ptr<EDSRegistryLoader> singleton;
|
static std::shared_ptr<EDSRegistryLoader> singleton;
|
||||||
if (!singleton) {
|
if (!singleton) {
|
||||||
singleton = loader;
|
singleton = loader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,16 +22,17 @@
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <memory>
|
||||||
|
|
||||||
#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
|
#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
|
||||||
|
|
||||||
#include <syncevo/GLibSupport.h>
|
#include <syncevo/GLibSupport.h>
|
||||||
|
|
||||||
#include <libedataserver/libedataserver.h>
|
#include <libedataserver/libedataserver.h>
|
||||||
#include <boost/function.hpp>
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX;
|
typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX;
|
||||||
|
@ -48,7 +49,7 @@ SE_BEGIN_CXX
|
||||||
// It may get used by backends which were compiled against
|
// It may get used by backends which were compiled against
|
||||||
// EDS >= 3.6 even when the libsyncevolution itself wasn't.
|
// EDS >= 3.6 even when the libsyncevolution itself wasn't.
|
||||||
class EDSRegistryLoader;
|
class EDSRegistryLoader;
|
||||||
EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader);
|
EDSRegistryLoader &EDSRegistryLoaderSingleton(const std::shared_ptr<EDSRegistryLoader> &loader);
|
||||||
|
|
||||||
// The following code implements EDSRegistryLoader.
|
// The following code implements EDSRegistryLoader.
|
||||||
// For the sake of simplicity, its all in the header file,
|
// For the sake of simplicity, its all in the header file,
|
||||||
|
@ -65,7 +66,7 @@ EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistr
|
||||||
class EDSRegistryLoader : private boost::noncopyable
|
class EDSRegistryLoader : private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef boost::function<void (const ESourceRegistryCXX ®istry,
|
typedef std::function<void (const ESourceRegistryCXX ®istry,
|
||||||
const GError *gerror)> Callback_t;
|
const GError *gerror)> Callback_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +75,7 @@ class EDSRegistryLoader : private boost::noncopyable
|
||||||
*/
|
*/
|
||||||
static void getESourceRegistryAsync(const Callback_t &cb)
|
static void getESourceRegistryAsync(const Callback_t &cb)
|
||||||
{
|
{
|
||||||
EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).async(cb);
|
EDSRegistryLoaderSingleton(std::make_shared<EDSRegistryLoader>()).async(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +83,7 @@ class EDSRegistryLoader : private boost::noncopyable
|
||||||
*/
|
*/
|
||||||
static ESourceRegistryCXX getESourceRegistry()
|
static ESourceRegistryCXX getESourceRegistry()
|
||||||
{
|
{
|
||||||
return EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).sync();
|
return EDSRegistryLoaderSingleton(std::make_shared<EDSRegistryLoader>()).sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -131,7 +131,7 @@ void FileConfigTree::clearNodes(const std::string &fullpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path,
|
std::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path,
|
||||||
ConfigTree::PropertyType type,
|
ConfigTree::PropertyType type,
|
||||||
const std::string &otherId)
|
const std::string &otherId)
|
||||||
{
|
{
|
||||||
|
@ -167,16 +167,16 @@ boost::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path,
|
||||||
if (found != m_nodes.end()) {
|
if (found != m_nodes.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
} else if(type != other && type != server) {
|
} else if(type != other && type != server) {
|
||||||
boost::shared_ptr<ConfigNode> node(new IniFileConfigNode(fullpath, filename, m_readonly));
|
auto node = std::make_shared<IniFileConfigNode>(fullpath, filename, m_readonly);
|
||||||
return m_nodes[fullname] = node;
|
return m_nodes[fullname] = node;
|
||||||
} else {
|
} else {
|
||||||
boost::shared_ptr<ConfigNode> node(new IniHashConfigNode(fullpath, filename, m_readonly));
|
auto node = std::make_shared<IniHashConfigNode>(fullpath, filename, m_readonly);
|
||||||
return m_nodes[fullname] = node;
|
return m_nodes[fullname] = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<ConfigNode> FileConfigTree::add(const std::string &path,
|
std::shared_ptr<ConfigNode> FileConfigTree::add(const std::string &path,
|
||||||
const boost::shared_ptr<ConfigNode> &node)
|
const std::shared_ptr<ConfigNode> &node)
|
||||||
{
|
{
|
||||||
NodeCache_t::iterator found = m_nodes.find(path);
|
NodeCache_t::iterator found = m_nodes.find(path);
|
||||||
if (found != m_nodes.end()) {
|
if (found != m_nodes.end()) {
|
||||||
|
|
|
@ -56,11 +56,11 @@ class FileConfigTree : public ConfigTree {
|
||||||
virtual void reload();
|
virtual void reload();
|
||||||
virtual void remove(const std::string &path);
|
virtual void remove(const std::string &path);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual boost::shared_ptr<ConfigNode> open(const std::string &path,
|
virtual std::shared_ptr<ConfigNode> open(const std::string &path,
|
||||||
PropertyType type,
|
PropertyType type,
|
||||||
const std::string &otherId = std::string(""));
|
const std::string &otherId = std::string(""));
|
||||||
virtual boost::shared_ptr<ConfigNode> add(const std::string &path,
|
virtual std::shared_ptr<ConfigNode> add(const std::string &path,
|
||||||
const boost::shared_ptr<ConfigNode> &node);
|
const std::shared_ptr<ConfigNode> &node);
|
||||||
std::list<std::string> getChildren(const std::string &path);
|
std::list<std::string> getChildren(const std::string &path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -75,7 +75,7 @@ class FileConfigTree : public ConfigTree {
|
||||||
SyncConfig::Layout m_layout;
|
SyncConfig::Layout m_layout;
|
||||||
bool m_readonly;
|
bool m_readonly;
|
||||||
|
|
||||||
typedef std::map< std::string, boost::shared_ptr<ConfigNode> > NodeCache_t;
|
typedef std::map< std::string, std::shared_ptr<ConfigNode> > NodeCache_t;
|
||||||
/** cache of all nodes ever accessed */
|
/** cache of all nodes ever accessed */
|
||||||
NodeCache_t m_nodes;
|
NodeCache_t m_nodes;
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,7 @@ FileDataBlob::FileDataBlob(const std::string &fullpath, bool readonly) :
|
||||||
splitPath(fullpath, m_path, m_fileName);
|
splitPath(fullpath, m_path, m_fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<std::ostream> FileDataBlob::write()
|
std::shared_ptr<std::ostream> FileDataBlob::write()
|
||||||
{
|
{
|
||||||
if (m_readonly) {
|
if (m_readonly) {
|
||||||
SE_THROW(getName() + ": internal error: attempt to write read-only FileDataBlob");
|
SE_THROW(getName() + ": internal error: attempt to write read-only FileDataBlob");
|
||||||
|
@ -47,13 +47,13 @@ boost::shared_ptr<std::ostream> FileDataBlob::write()
|
||||||
|
|
||||||
mkdir_p(m_path);
|
mkdir_p(m_path);
|
||||||
|
|
||||||
boost::shared_ptr<std::ostream> file(new SafeOstream(getName()));
|
auto file = std::make_shared<SafeOstream>(getName());
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<std::istream> FileDataBlob::read()
|
std::shared_ptr<std::istream> FileDataBlob::read()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<std::istream> file(new std::ifstream(getName().c_str()));
|
auto file = std::make_shared<std::ifstream>(getName().c_str());
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ class FileDataBlob : public DataBlob
|
||||||
FileDataBlob(const std::string &path, const std::string &fileName, bool readonly);
|
FileDataBlob(const std::string &path, const std::string &fileName, bool readonly);
|
||||||
FileDataBlob(const std::string &fullpath, bool readonly);
|
FileDataBlob(const std::string &fullpath, bool readonly);
|
||||||
|
|
||||||
boost::shared_ptr<std::ostream> write();
|
std::shared_ptr<std::ostream> write();
|
||||||
boost::shared_ptr<std::istream> read();
|
std::shared_ptr<std::istream> read();
|
||||||
|
|
||||||
virtual std::string getName() const;
|
virtual std::string getName() const;
|
||||||
virtual bool exists() const;
|
virtual bool exists() const;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <syncevo/declarations.h>
|
#include <syncevo/declarations.h>
|
||||||
SE_BEGIN_CXX
|
SE_BEGIN_CXX
|
||||||
|
|
||||||
FilterConfigNode::FilterConfigNode(const boost::shared_ptr<ConfigNode> &node,
|
FilterConfigNode::FilterConfigNode(const std::shared_ptr<ConfigNode> &node,
|
||||||
const ConfigFilter &filter) :
|
const ConfigFilter &filter) :
|
||||||
m_filter(filter),
|
m_filter(filter),
|
||||||
m_node(node),
|
m_node(node),
|
||||||
|
@ -33,7 +33,7 @@ FilterConfigNode::FilterConfigNode(const boost::shared_ptr<ConfigNode> &node,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterConfigNode::FilterConfigNode(const boost::shared_ptr<const ConfigNode> &node,
|
FilterConfigNode::FilterConfigNode(const std::shared_ptr<const ConfigNode> &node,
|
||||||
const ConfigFilter &filter) :
|
const ConfigFilter &filter) :
|
||||||
m_filter(filter),
|
m_filter(filter),
|
||||||
m_readOnlyNode(node)
|
m_readOnlyNode(node)
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
# define INCL_EVOLUTION_FILTER_CONFIG_NODE
|
# define INCL_EVOLUTION_FILTER_CONFIG_NODE
|
||||||
|
|
||||||
#include <syncevo/ConfigNode.h>
|
#include <syncevo/ConfigNode.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -48,11 +48,11 @@ class FilterConfigNode : public ConfigNode {
|
||||||
typedef ConfigProps ConfigFilter;
|
typedef ConfigProps ConfigFilter;
|
||||||
|
|
||||||
/** read-write access to underlying node */
|
/** read-write access to underlying node */
|
||||||
FilterConfigNode(const boost::shared_ptr<ConfigNode> &node,
|
FilterConfigNode(const std::shared_ptr<ConfigNode> &node,
|
||||||
const ConfigFilter &filter = ConfigFilter());
|
const ConfigFilter &filter = ConfigFilter());
|
||||||
|
|
||||||
/** read-only access to underlying node */
|
/** read-only access to underlying node */
|
||||||
FilterConfigNode(const boost::shared_ptr<const ConfigNode> &node,
|
FilterConfigNode(const std::shared_ptr<const ConfigNode> &node,
|
||||||
const ConfigFilter &filter = ConfigFilter());
|
const ConfigFilter &filter = ConfigFilter());
|
||||||
|
|
||||||
virtual std::string getName() const { return m_readOnlyNode->getName(); }
|
virtual std::string getName() const { return m_readOnlyNode->getName(); }
|
||||||
|
@ -80,8 +80,8 @@ class FilterConfigNode : public ConfigNode {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigFilter m_filter;
|
ConfigFilter m_filter;
|
||||||
boost::shared_ptr<ConfigNode> m_node;
|
std::shared_ptr<ConfigNode> m_node;
|
||||||
boost::shared_ptr<const ConfigNode> m_readOnlyNode;
|
std::shared_ptr<const ConfigNode> m_readOnlyNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue