From 95a144a285b9a44a6f905eece9f13717540cbb40 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Mon, 25 Feb 2013 08:02:49 +0100 Subject: [PATCH] Rename swiften_raw backend to swiften backend, remove old swiften backend --- backends/swiften/main.cpp | 317 ++++++++++---------- backends/swiften_raw/CMakeLists.txt | 14 - backends/swiften_raw/main.cpp | 441 ---------------------------- 3 files changed, 147 insertions(+), 625 deletions(-) delete mode 100644 backends/swiften_raw/CMakeLists.txt delete mode 100644 backends/swiften_raw/main.cpp diff --git a/backends/swiften/main.cpp b/backends/swiften/main.cpp index 3ccc632e..5a2c1f37 100644 --- a/backends/swiften/main.cpp +++ b/backends/swiften/main.cpp @@ -30,6 +30,7 @@ using namespace boost::program_options; using namespace Transport; DEFINE_LOGGER(logger, "Swiften"); +DEFINE_LOGGER(logger_xml, "backend.xml"); // eventloop Swift::SimpleEventLoop *loop_; @@ -37,96 +38,60 @@ Swift::SimpleEventLoop *loop_; // Plugins class SwiftenPlugin; NetworkPlugin *np = NULL; +Swift::XMPPSerializer *serializer; -class MUCController { +class ForwardIQHandler : public Swift::IQHandler { public: - MUCController(const std::string &user, boost::shared_ptr client, const std::string &room, const std::string &nickname, const std::string &password) { + std::map m_id2resource; + + ForwardIQHandler(NetworkPlugin *np, const std::string &user) { + m_np = np; m_user = user; - m_room = room; - muc = client->getMUCManager()->createMUC(room); - if (!password.empty()) { - muc->setPassword(password); + } + + bool handleIQ(boost::shared_ptr iq) { + if (iq->getPayload() != NULL) { + return false; + } + if (iq->getType() == Swift::IQ::Get) { + m_id2resource[iq->getID()] = iq->getFrom().getResource(); } - muc->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); - muc->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); - muc->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); - muc->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); - muc->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); - muc->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); - muc->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); - - muc->joinAs(nickname); - } - - virtual ~MUCController() { - muc->onJoinComplete.disconnect(boost::bind(&MUCController::handleJoinComplete, this, _1)); - muc->onJoinFailed.disconnect(boost::bind(&MUCController::handleJoinFailed, this, _1)); - muc->onOccupantJoined.disconnect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); - muc->onOccupantPresenceChange.disconnect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); - muc->onOccupantLeft.disconnect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); - muc->onOccupantRoleChanged.disconnect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); - muc->onOccupantAffiliationChanged.disconnect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); - } - - const std::string &getNickname() { - //return muc->getCurrentNick(); - return m_nick; - } - - void handleOccupantJoined(const Swift::MUCOccupant& occupant) { - np->handleParticipantChanged(m_user, occupant.getNick(), m_room, occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_ONLINE); - } - - void handleOccupantLeft(const Swift::MUCOccupant& occupant, Swift::MUC::LeavingType type, const std::string& reason) { - np->handleParticipantChanged(m_user, occupant.getNick(), m_room, occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_NONE); - } - - void handleOccupantPresenceChange(boost::shared_ptr presence) { - const Swift::MUCOccupant& occupant = muc->getOccupant(presence->getFrom().getResource()); - np->handleParticipantChanged(m_user, presence->getFrom().getResource(), m_room, (int) occupant.getRole() == Swift::MUCOccupant::Moderator, (pbnetwork::StatusType) presence->getShow(), presence->getStatus()); - } - - void handleOccupantRoleChanged(const std::string& nick, const Swift::MUCOccupant& occupant, const Swift::MUCOccupant::Role& oldRole) { - - } - - void handleOccupantAffiliationChanged(const std::string& nick, const Swift::MUCOccupant::Affiliation& affiliation, const Swift::MUCOccupant::Affiliation& oldAffiliation) { -// np->handleParticipantChanged(m_user, occupant->getNick(), m_room, (int) occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_ONLINE); - } - - void handleJoinComplete(const std::string& nick) { - m_nick = nick; - } - - void handleJoinFailed(boost::shared_ptr error) { - - } - - void part() { - muc->part(); + iq->setTo(m_user); + std::string xml = safeByteArrayToString(serializer->serializeElement(iq)); + m_np->sendRawXML(xml); + return true; } private: - Swift::MUC::ref muc; + NetworkPlugin *m_np; std::string m_user; - std::string m_room; - std::string m_nick; + }; -class SwiftenPlugin : public NetworkPlugin { +class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient { public: Swift::BoostNetworkFactories *m_factories; Swift::BoostIOServiceThread m_boostIOServiceThread; boost::shared_ptr m_conn; + bool m_firstPing; + + Swift::FullPayloadSerializerCollection collection; + Swift::XMPPParser *m_xmppParser; + Swift::FullPayloadParserFactoryCollection m_collection2; SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { this->config = config; + m_firstPing = true; m_factories = new Swift::BoostNetworkFactories(loop); m_conn = m_factories->getConnectionFactory()->createConnection(); m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1)); m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port)); + serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType); + m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory()); + m_xmppParser->parse(""); + LOG4CXX_INFO(logger, "Starting the plugin."); } @@ -137,10 +102,61 @@ class SwiftenPlugin : public NetworkPlugin { // This method has to call handleDataRead with all received data from network plugin server void _handleDataRead(boost::shared_ptr data) { + if (m_firstPing) { + m_firstPing = false; + NetworkPlugin::PluginConfig cfg; + cfg.setRawXML(true); + sendConfig(cfg); + } std::string d(data->begin(), data->end()); handleDataRead(d); } + void handleStreamStart(const Swift::ProtocolHeader&) {} + + void handleElement(boost::shared_ptr element) { + boost::shared_ptr stanza = boost::dynamic_pointer_cast(element); + if (!stanza) { + return; + } + + std::string user = stanza->getFrom().toBare(); + + boost::shared_ptr client = m_users[user]; + if (!client) + return; + + stanza->setFrom(client->getJID()); + + boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); + if (message) { + client->sendMessage(message); + return; + } + + boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); + if (presence) { + client->sendPresence(presence); + return; + } + + boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); + if (iq) { + if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) { + iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), m_handlers[user]->m_id2resource[stanza->getID()])); + m_handlers[user]->m_id2resource.erase(stanza->getID()); + } + client->getIQRouter()->sendIQ(iq); + return; + } + } + + void handleStreamEnd() {} + + void handleRawXML(const std::string &xml) { + m_xmppParser->parse(xml); + } + void handleSwiftDisconnected(const std::string &user, const boost::optional &error) { std::string message = ""; bool reconnect = false; @@ -186,7 +202,7 @@ class SwiftenPlugin : public NetworkPlugin { client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1)); client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1)); m_users.erase(user); - m_mucs.erase(user); + m_handlers.erase(user); } #ifndef WIN32 @@ -219,67 +235,53 @@ class SwiftenPlugin : public NetworkPlugin { } void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) { - boost::shared_ptr client = m_users[user]; - if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) { - return; - } - - if (presence->getPayload() != NULL || presence->getPayload() != NULL) { - return; - } - - LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed"); - - std::string message = presence->getStatus(); - std::string photo = ""; - - boost::shared_ptr update = presence->getPayload(); - if (update) { - photo = update->getPhotoHash(); - } - - boost::optional item = m_users[user]->getRoster()->getItem(presence->getFrom()); - if (item) { - handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo); - } - else { - std::vector groups; - handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo); - } +// boost::shared_ptr client = m_users[user]; +// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) { +// return; +// } +// +// if (presence->getPayload() != NULL || presence->getPayload() != NULL) { +// return; +// } +// +// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed"); +// +// std::string message = presence->getStatus(); +// std::string photo = ""; +// +// boost::shared_ptr update = presence->getPayload(); +// if (update) { +// photo = update->getPhotoHash(); +// } +// +// boost::optional item = m_users[user]->getRoster()->getItem(presence->getFrom()); +// if (item) { +// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo); +// } +// else { +// std::vector groups; +// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo); +// } + presence->setTo(user); + std::string xml = safeByteArrayToString(serializer->serializeElement(presence)); + sendRawXML(xml); } void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) { - std::string body = message->getBody(); - boost::shared_ptr client = m_users[user]; - if (client) { - if (message->getType() == Swift::Message::Groupchat) { - boost::shared_ptr delay = message->getPayload(); - std::string timestamp = ""; - if (delay) { - timestamp = boost::posix_time::to_iso_string(delay->getStamp()); - } - handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", timestamp); - } - else { - if (client->getMUCRegistry()->isMUC(message->getFrom().toBare())) { - handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", "", false, true); - } - else { - handleMessage(user, message->getFrom().toBare().toString(), body, "", ""); - } - } + message->setTo(user); + std::string xml = safeByteArrayToString(serializer->serializeElement(message)); + sendRawXML(xml); + } + + void handleSwiftenDataRead(const Swift::SafeByteArray &data) { + std::string d = safeByteArrayToString(data); + if (!boost::starts_with(d, "onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1)); client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user)); client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1)); + client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1)); + client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1)); + client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3)); + client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2)); Swift::ClientOptions opt; opt.allowPLAINWithoutTLS = true; client->connect(opt); + + boost::shared_ptr handler = boost::make_shared(this, user); + client->getIQRouter()->addHandler(handler); + m_handlers[user] = handler; + } + + void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) { + handleSwiftPresenceChanged(user, presence); + } + + void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) { + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setTo(user); + presence->setFrom(jid); + presence->setType(Swift::Presence::Unsubscribe); + handleSwiftPresenceChanged(user, presence); } void handleLogoutRequest(const std::string &user, const std::string &legacyName) { @@ -306,43 +328,20 @@ class SwiftenPlugin : public NetworkPlugin { client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user)); client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1)); client->disconnect(); - m_mucs.erase(user); } } void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") { - LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << "."); - boost::shared_ptr client = m_users[user]; - if (client) { - boost::shared_ptr message(new Swift::Message()); - message->setTo(Swift::JID(legacyName)); - message->setFrom(client->getJID()); - message->setBody(msg); - if (client->getMUCRegistry()->isMUC(legacyName)) { - message->setType(Swift::Message::Groupchat); - boost::shared_ptr muc = m_mucs[user][legacyName]; -// handleMessage(user, legacyName, msg, muc->getNickname(), xhtml); - } - - client->sendMessage(message); - } } void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) { - boost::shared_ptr client = m_users[user]; - if (client) { - LOG4CXX_INFO(logger, user << ": fetching VCard of " << legacyName << " id=" << id); - Swift::GetVCardRequest::ref request = Swift::GetVCardRequest::create(Swift::JID(legacyName), client->getIQRouter()); - request->onResponse.connect(boost::bind(&SwiftenPlugin::handleSwiftVCardReceived, this, user, id, _1, _2)); - request->send(); - } } void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups) { boost::shared_ptr client = m_users[user]; if (client) { LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << "."); - if (!client->getRoster()->containsJID(buddyName)) { + if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) { Swift::RosterItemPayload item; item.setName(alias); item.setJID(buddyName); @@ -381,39 +380,17 @@ class SwiftenPlugin : public NetworkPlugin { } void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { - boost::shared_ptr client = m_users[user]; - if (client) { - if (client->getMUCRegistry()->isMUC(room)) { - return; - } - boost::shared_ptr muc = boost::shared_ptr( new MUCController(user, client, room, nickname, password)); - m_mucs[user][room] = muc; - } } void handleLeaveRoomRequest(const std::string &user, const std::string &room) { - boost::shared_ptr client = m_users[user]; - if (client) { - if (!client->getMUCRegistry()->isMUC(room)) { - return; - } - boost::shared_ptr muc = m_mucs[user][room]; - if (!muc) { - m_mucs[user].erase(room); - return; - } - - muc->part(); - m_mucs[user].erase(room); - } } private: Config *config; std::map > m_users; - std::map > > m_mucs; + std::map > m_handlers; }; #ifndef WIN32 diff --git a/backends/swiften_raw/CMakeLists.txt b/backends/swiften_raw/CMakeLists.txt deleted file mode 100644 index 5d656002..00000000 --- a/backends/swiften_raw/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - -FILE(GLOB SRC *.cpp) - -ADD_EXECUTABLE(spectrum2_swiften_raw_backend ${SRC}) - -IF (NOT WIN32) -target_link_libraries(spectrum2_swiften_raw_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) -else() -target_link_libraries(spectrum2_swiften_raw_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) -endif() - -#INSTALL(TARGETS spectrum2_swiften_raw_backend RUNTIME DESTINATION bin) - diff --git a/backends/swiften_raw/main.cpp b/backends/swiften_raw/main.cpp deleted file mode 100644 index 5a2c1f37..00000000 --- a/backends/swiften_raw/main.cpp +++ /dev/null @@ -1,441 +0,0 @@ -// Transport includes -#include "transport/config.h" -#include "transport/networkplugin.h" -#include "transport/logging.h" - -#include "boost/date_time/posix_time/posix_time.hpp" - -// Swiften -#include "Swiften/Swiften.h" - -#ifndef WIN32 -// for signal handler -#include "unistd.h" -#include "signal.h" -#include "sys/wait.h" -#include "sys/signal.h" -#endif - -#ifndef __FreeBSD__ -#ifndef __MACH__ -// malloc_trim -#include "malloc.h" -#endif -#endif - -// Boost -#include -using namespace boost::filesystem; -using namespace boost::program_options; -using namespace Transport; - -DEFINE_LOGGER(logger, "Swiften"); -DEFINE_LOGGER(logger_xml, "backend.xml"); - -// eventloop -Swift::SimpleEventLoop *loop_; - -// Plugins -class SwiftenPlugin; -NetworkPlugin *np = NULL; -Swift::XMPPSerializer *serializer; - -class ForwardIQHandler : public Swift::IQHandler { - public: - std::map m_id2resource; - - ForwardIQHandler(NetworkPlugin *np, const std::string &user) { - m_np = np; - m_user = user; - } - - bool handleIQ(boost::shared_ptr iq) { - if (iq->getPayload() != NULL) { - return false; - } - if (iq->getType() == Swift::IQ::Get) { - m_id2resource[iq->getID()] = iq->getFrom().getResource(); - } - - iq->setTo(m_user); - std::string xml = safeByteArrayToString(serializer->serializeElement(iq)); - m_np->sendRawXML(xml); - return true; - } - - private: - NetworkPlugin *m_np; - std::string m_user; - -}; - -class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient { - public: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - boost::shared_ptr m_conn; - bool m_firstPing; - - Swift::FullPayloadSerializerCollection collection; - Swift::XMPPParser *m_xmppParser; - Swift::FullPayloadParserFactoryCollection m_collection2; - - SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { - this->config = config; - m_firstPing = true; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port)); - - serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType); - m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory()); - m_xmppParser->parse(""); - - LOG4CXX_INFO(logger, "Starting the plugin."); - } - - // NetworkPlugin uses this method to send the data to networkplugin server - void sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); - } - - // This method has to call handleDataRead with all received data from network plugin server - void _handleDataRead(boost::shared_ptr data) { - if (m_firstPing) { - m_firstPing = false; - NetworkPlugin::PluginConfig cfg; - cfg.setRawXML(true); - sendConfig(cfg); - } - std::string d(data->begin(), data->end()); - handleDataRead(d); - } - - void handleStreamStart(const Swift::ProtocolHeader&) {} - - void handleElement(boost::shared_ptr element) { - boost::shared_ptr stanza = boost::dynamic_pointer_cast(element); - if (!stanza) { - return; - } - - std::string user = stanza->getFrom().toBare(); - - boost::shared_ptr client = m_users[user]; - if (!client) - return; - - stanza->setFrom(client->getJID()); - - boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); - if (message) { - client->sendMessage(message); - return; - } - - boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); - if (presence) { - client->sendPresence(presence); - return; - } - - boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); - if (iq) { - if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) { - iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), m_handlers[user]->m_id2resource[stanza->getID()])); - m_handlers[user]->m_id2resource.erase(stanza->getID()); - } - client->getIQRouter()->sendIQ(iq); - return; - } - } - - void handleStreamEnd() {} - - void handleRawXML(const std::string &xml) { - m_xmppParser->parse(xml); - } - - void handleSwiftDisconnected(const std::string &user, const boost::optional &error) { - std::string message = ""; - bool reconnect = false; - if (error) { - switch(error->getType()) { - case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break; - case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break; - case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break; - case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break; - case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break; - case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break; - case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break; - case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break; - case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break; - case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break; - case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break; - case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break; - case Swift::ClientError::SessionStartError: message = ("Error starting session"); break; - case Swift::ClientError::StreamError: message = ("Stream error"); break; - case Swift::ClientError::TLSError: message = ("Encryption error"); break; - case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break; - case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break; - - case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break; - case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break; - case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break; - case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break; - case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break; - case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break; - case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break; - case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break; - case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break; - case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break; - case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break; - } - } - LOG4CXX_INFO(logger, user << ": Disconnected " << message); - handleDisconnected(user, reconnect ? 0 : 3, message); - - boost::shared_ptr client = m_users[user]; - if (client) { - client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user)); - client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1)); - client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1)); - m_users.erase(user); - m_handlers.erase(user); - } - -#ifndef WIN32 -#ifndef __FreeBSD__ -#ifndef __MACH__ - // force returning of memory chunks allocated by libxml2 to kernel - malloc_trim(0); -#endif -#endif -#endif - } - - void handleSwiftConnected(const std::string &user) { - LOG4CXX_INFO(logger, user << ": Connected to XMPP server."); - handleConnected(user); - m_users[user]->requestRoster(); - Swift::Presence::ref response = Swift::Presence::create(); - response->setFrom(m_users[user]->getJID()); - m_users[user]->sendPresence(response); - } - - void handleSwiftRosterReceived(const std::string &user) { - Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle(); - BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) { - Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID()); - pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE; - handleBuddyChanged(user, item.getJID().toBare().toString(), - item.getName(), item.getGroups(), status); - } - } - - void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) { -// boost::shared_ptr client = m_users[user]; -// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) { -// return; -// } -// -// if (presence->getPayload() != NULL || presence->getPayload() != NULL) { -// return; -// } -// -// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed"); -// -// std::string message = presence->getStatus(); -// std::string photo = ""; -// -// boost::shared_ptr update = presence->getPayload(); -// if (update) { -// photo = update->getPhotoHash(); -// } -// -// boost::optional item = m_users[user]->getRoster()->getItem(presence->getFrom()); -// if (item) { -// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo); -// } -// else { -// std::vector groups; -// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo); -// } - presence->setTo(user); - std::string xml = safeByteArrayToString(serializer->serializeElement(presence)); - sendRawXML(xml); - } - - void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) { - message->setTo(user); - std::string xml = safeByteArrayToString(serializer->serializeElement(message)); - sendRawXML(xml); - } - - void handleSwiftenDataRead(const Swift::SafeByteArray &data) { - std::string d = safeByteArrayToString(data); - if (!boost::starts_with(d, " client = boost::make_shared(Swift::JID(legacyName), password, m_factories); - m_users[user] = client; - client->setAlwaysTrustCertificates(); - client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user)); - client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1)); - client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1)); - client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user)); - client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1)); - client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1)); - client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1)); - client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3)); - client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2)); - Swift::ClientOptions opt; - opt.allowPLAINWithoutTLS = true; - client->connect(opt); - - boost::shared_ptr handler = boost::make_shared(this, user); - client->getIQRouter()->addHandler(handler); - m_handlers[user] = handler; - } - - void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) { - handleSwiftPresenceChanged(user, presence); - } - - void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) { - Swift::Presence::ref presence = Swift::Presence::create(); - presence->setTo(user); - presence->setFrom(jid); - presence->setType(Swift::Presence::Unsubscribe); - handleSwiftPresenceChanged(user, presence); - } - - void handleLogoutRequest(const std::string &user, const std::string &legacyName) { - boost::shared_ptr client = m_users[user]; - if (client) { - client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user)); -// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1)); - client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1)); - client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user)); - client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1)); - client->disconnect(); - } - } - - void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") { - } - - void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) { - } - - void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups) { - boost::shared_ptr client = m_users[user]; - if (client) { - LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << "."); - if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) { - Swift::RosterItemPayload item; - item.setName(alias); - item.setJID(buddyName); - item.setGroups(groups); - boost::shared_ptr roster(new Swift::RosterPayload()); - roster->addItem(item); - Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter()); -// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - client->getSubscriptionManager()->requestSubscription(buddyName); - } - else { - Swift::JID contact(buddyName); - Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact)); - item.setGroups(groups); - boost::shared_ptr roster(new Swift::RosterPayload()); - roster->addItem(item); - Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter()); -// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - } - - } - } - - void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups) { - boost::shared_ptr client = m_users[user]; - if (client) { - Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove); - boost::shared_ptr roster(new Swift::RosterPayload()); - roster->addItem(item); - Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter()); -// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - } - } - - void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { - - } - - void handleLeaveRoomRequest(const std::string &user, const std::string &room) { - - } - - private: - Config *config; - std::map > m_users; - std::map > m_handlers; -}; - -#ifndef WIN32 -static void spectrum_sigchld_handler(int sig) -{ - int status; - pid_t pid; - - do { - pid = waitpid(-1, &status, WNOHANG); - } while (pid != 0 && pid != (pid_t)-1); - - if ((pid == (pid_t) - 1) && (errno != ECHILD)) { - char errmsg[BUFSIZ]; - snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid); - perror(errmsg); - } -} -#endif - - -int main (int argc, char* argv[]) { - std::string host; - int port; - -#ifndef WIN32 - if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) { - std::cout << "SIGCHLD handler can't be set\n"; - return -1; - } -#endif - - std::string error; - Config *cfg = Config::createFromArgs(argc, argv, error, host, port); - if (cfg == NULL) { - std::cerr << error; - return 1; - } - - Logging::initBackendLogging(cfg); - - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new SwiftenPlugin(cfg, &eventLoop, host, port); - loop_->run(); - - return 0; -}