From 4055180802abda864fc07ab593fe524ea66fbfd5 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 23 Oct 2012 18:27:04 +0200 Subject: [PATCH] Send subscribe/subscribed presence from transport contact when connecting --- backends/libpurple/utils.cpp | 2 +- src/tests/basictest.cpp | 2 ++ src/tests/usermanager.cpp | 10 +++++++++- src/usermanager.cpp | 29 +++++++++++++++++++++++++---- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/backends/libpurple/utils.cpp b/backends/libpurple/utils.cpp index 4857f37c..c375421e 100644 --- a/backends/libpurple/utils.cpp +++ b/backends/libpurple/utils.cpp @@ -155,7 +155,7 @@ int create_socket(const char *host, int portno) { stSockAddr.sin_family = AF_INET; stSockAddr.sin_port = htons(portno); - bcopy(hos->h_addr, &(stSockAddr.sin_addr.s_addr), hos->h_length); + memcpy(&(stSockAddr.sin_addr.s_addr), hos->h_addr, hos->h_length); if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { close(SocketFD); diff --git a/src/tests/basictest.cpp b/src/tests/basictest.cpp index 7c3ef14c..1c0b2eed 100644 --- a/src/tests/basictest.cpp +++ b/src/tests/basictest.cpp @@ -202,6 +202,7 @@ void BasicTest::connectUser() { CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + received.clear(); receivedData.clear(); } @@ -236,6 +237,7 @@ void BasicTest::connectSecondResource() { } void BasicTest::disconnectUser() { + received.clear(); userManager->disconnectUser("user@localhost"); dynamic_cast(factories->getTimerFactory())->setTime(10); loop->processEvents(); diff --git a/src/tests/usermanager.cpp b/src/tests/usermanager.cpp index 1f03575d..a0adceff 100644 --- a/src/tests/usermanager.cpp +++ b/src/tests/usermanager.cpp @@ -79,12 +79,20 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { dynamic_cast(component->getStanzaChannel())->onPresenceReceived(response); loop->processEvents(); - CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); + CPPUNIT_ASSERT_EQUAL(4, (int) received.size()); CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); Swift::Presence *presence = dynamic_cast(getStanza(received[1])); CPPUNIT_ASSERT(presence); CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType()); + + presence = dynamic_cast(getStanza(received[2])); + CPPUNIT_ASSERT(presence); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribe, presence->getType()); + + presence = dynamic_cast(getStanza(received[3])); + CPPUNIT_ASSERT(presence); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribed, presence->getType()); } void connectTwoResources() { diff --git a/src/usermanager.cpp b/src/usermanager.cpp index a24161f2..20247ba8 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -184,14 +184,33 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { } } + UserInfo res; + bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false; + // No user and unavailable presence -> answer with unavailable - if (presence->getType() == Swift::Presence::Unavailable) { + if (presence->getType() == Swift::Presence::Unavailable || presence->getType() == Swift::Presence::Probe) { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom()); response->setFrom(presence->getTo()); response->setType(Swift::Presence::Unavailable); m_component->getStanzaChannel()->sendPresence(response); + // bother him with subscribe presence, just to be + // sure he is subscribed to us. + if (/*registered && */presence->getType() == Swift::Presence::Probe) { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(presence->getTo()); + response->setType(Swift::Presence::Subscribe); + m_component->getStanzaChannel()->sendPresence(response); + + response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(presence->getTo()); + response->setType(Swift::Presence::Subscribed); + m_component->getStanzaChannel()->sendPresence(response); + } + // Set user offline in database if (m_storageBackend) { UserInfo res; @@ -203,9 +222,6 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { return; } - UserInfo res; - bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false; - // In server mode, we don't need registration normally, but for networks like IRC // or Twitter where there's no real authorization using password, we have to force // registration otherwise some data (like bookmarked rooms) could leak. @@ -378,6 +394,11 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) { } void UserManager::handleProbePresence(Swift::Presence::ref presence) { + // Don't let RosterManager to handle presences for us + if (presence->getTo().getNode().empty()) { + return; + } + User *user = getUser(presence->getFrom().toBare().toString()); if (user) {