From c990770ecf3b2d841b1ed9003de08701b02ae021 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Tue, 6 Mar 2012 11:47:00 +0100 Subject: [PATCH 01/46] renamed plugin/src to plugin/cpp --- plugin/CMakeLists.txt | 2 +- plugin/{src => cpp}/CMakeLists.txt | 0 plugin/{src => cpp}/networkplugin.cpp | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename plugin/{src => cpp}/CMakeLists.txt (100%) rename plugin/{src => cpp}/networkplugin.cpp (100%) diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 4b7537b5..6df16409 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -1 +1 @@ -ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(cpp) diff --git a/plugin/src/CMakeLists.txt b/plugin/cpp/CMakeLists.txt similarity index 100% rename from plugin/src/CMakeLists.txt rename to plugin/cpp/CMakeLists.txt diff --git a/plugin/src/networkplugin.cpp b/plugin/cpp/networkplugin.cpp similarity index 100% rename from plugin/src/networkplugin.cpp rename to plugin/cpp/networkplugin.cpp From 6c2ef4c9d8714dd898215f807af6283eb3efe543 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Tue, 6 Mar 2012 12:49:36 +0100 Subject: [PATCH 02/46] place for python binding --- plugin/CMakeLists.txt | 1 + plugin/python/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 plugin/python/CMakeLists.txt diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index 6df16409..798bc96f 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -1 +1,2 @@ ADD_SUBDIRECTORY(cpp) +ADD_SUBDIRECTORY(python) diff --git a/plugin/python/CMakeLists.txt b/plugin/python/CMakeLists.txt new file mode 100644 index 00000000..5bc15fb8 --- /dev/null +++ b/plugin/python/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.6) + +if (PROTOBUF_FOUND) + ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/protocol_pb2.py + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/ ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.proto + COMMENT "Running Python protocol buffer compiler on protocol.proto" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.proto + ) + ADD_CUSTOM_TARGET(pb-python DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/protocol_pb2.py) +endif() + + From fa1b565385454f05b5b3a5bf496622659e2cf0ff Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 7 Mar 2012 10:47:46 +0100 Subject: [PATCH 03/46] Use g_free for freeing glibs data --- backends/libpurple/main.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index cf8d3090..e25d093e 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -89,7 +89,7 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key return def; } std::string ret(str); - free(str); + g_free(str); if (ret.find("#") != std::string::npos) { ret = ret.substr(0, ret.find("#")); @@ -1407,11 +1407,13 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif if (true) { gchar *data; gchar *path = purple_buddy_icon_get_full_path(icon); - if (g_file_get_contents (path, &data, &len, NULL)) { - photo = std::string(data, len); - free(data); + if (path) { + if (g_file_get_contents(path, &data, &len, NULL)) { + photo = std::string(data, len); + g_free(data); + } + g_free(path); } - free(path); } else { const gchar * data = (gchar*)purple_buddy_icon_get_data(icon, &len); From 022a723079d8910366153fc9c3f336fe72262977 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 7 Mar 2012 13:51:35 +0100 Subject: [PATCH 04/46] working joining/leaving XMPP MUC --- backends/libpurple/main.cpp | 46 +++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index e25d093e..7b77a994 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -1256,6 +1256,48 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_); } +static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) { + PurpleAccount *account = purple_conversation_get_account(conv); + + GList *l = cbuddies; + while (l != NULL) { + PurpleConvChatBuddy *cb = (PurpleConvChatBuddy *)l->data; + std::string name(cb->name); + int flags = GPOINTER_TO_INT(cb->flags); + if (flags & PURPLE_CBFLAGS_OP || flags & PURPLE_CBFLAGS_HALFOP) { +// item->addAttribute("affiliation", "admin"); +// item->addAttribute("role", "moderator"); + flags = 1; + } + else if (flags & PURPLE_CBFLAGS_FOUNDER) { +// item->addAttribute("affiliation", "owner"); +// item->addAttribute("role", "moderator"); + flags = 1; + } + else { + flags = 0; +// item->addAttribute("affiliation", "member"); +// item->addAttribute("role", "participant"); + } + + np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), (int) flags, pbnetwork::STATUS_ONLINE); + + l = l->next; + } +} + +static void conv_chat_remove_users(PurpleConversation *conv, GList *users) { + PurpleAccount *account = purple_conversation_get_account(conv); + + GList *l = users; + while (l != NULL) { + std::string name((char *) l->data); + np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), 0, pbnetwork::STATUS_NONE); + + l = l->next; + } +} + static PurpleConversationUiOps conversation_ui_ops = { NULL, @@ -1263,9 +1305,9 @@ static PurpleConversationUiOps conversation_ui_ops = NULL,//conv_write_chat, /* write_chat */ conv_write_im, /* write_im */ NULL,//conv_write_conv, /* write_conv */ - NULL,//conv_chat_add_users, /* chat_add_users */ + conv_chat_add_users, /* chat_add_users */ NULL,//conv_chat_rename_user, /* chat_rename_user */ - NULL,//conv_chat_remove_users, /* chat_remove_users */ + conv_chat_remove_users, /* chat_remove_users */ NULL,//pidgin_conv_chat_update_user, /* chat_update_user */ NULL,//pidgin_conv_present_conversation, /* present */ NULL,//pidgin_conv_has_focus, /* has_focus */ From 87a0a2f49a23806f01c4bae39c2465a40d378be2 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 7 Mar 2012 18:59:21 +0100 Subject: [PATCH 05/46] Working MUC messages for XMPP --- CMakeLists.txt | 1 + backends/libpurple/main.cpp | 35 ++++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e798a842..b64e64fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,7 @@ ADD_SUBDIRECTORY(spectrum) ADD_SUBDIRECTORY(backends) if (NOT WIN32) ADD_SUBDIRECTORY(spectrum_manager) + ADD_SUBDIRECTORY(spectrum2_send_message) endif() if (CPPUNIT_FOUND) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 7b77a994..ec00f706 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -768,17 +768,30 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) { PurpleAccount *account = m_sessions[user]; if (account) { - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account); + PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, legacyName.c_str(), account); if (!conv) { - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str()); + PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account); + if (!conv) { + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str()); + } } if (xhtml.empty()) { gchar *_markup = purple_markup_escape_text(message.c_str(), -1); - purple_conv_im_send(PURPLE_CONV_IM(conv), _markup); + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + purple_conv_im_send(PURPLE_CONV_IM(conv), _markup); + } + else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + purple_conv_chat_send(PURPLE_CONV_CHAT(conv), _markup); + } g_free(_markup); } else { - purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str()); + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str()); + } + else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + purple_conv_chat_send(PURPLE_CONV_CHAT(conv), xhtml.c_str()); + } } } } @@ -1213,8 +1226,10 @@ static PurpleBlistUiOps blistUiOps = static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) { // Don't forwards our own messages. - if (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM) + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM) { + LOG4CXX_INFO(logger, "MSG"); return; + } PurpleAccount *account = purple_conversation_get_account(conv); // char *striped = purple_markup_strip_html(message); @@ -1253,7 +1268,13 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char // LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "'"); - np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_); + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_); + } + else { + LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name(conv) << "' " << w); + np->handleMessage(np->m_accounts[account], purple_conversation_get_name(conv), message_, w, xhtml_); + } } static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) { @@ -1302,7 +1323,7 @@ static PurpleConversationUiOps conversation_ui_ops = { NULL, NULL, - NULL,//conv_write_chat, /* write_chat */ + conv_write_im,//conv_write_chat, /* write_chat */ conv_write_im, /* write_im */ NULL,//conv_write_conv, /* write_conv */ conv_chat_add_users, /* chat_add_users */ From 15e1f34b0392f7d11031589ebfe50b7365ebf9ec Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 7 Mar 2012 19:00:53 +0100 Subject: [PATCH 06/46] Working MUC messages for XMPP --- backends/libpurple/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index ec00f706..01e24e43 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -1226,8 +1226,7 @@ static PurpleBlistUiOps blistUiOps = static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) { // Don't forwards our own messages. - if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM) { - LOG4CXX_INFO(logger, "MSG"); + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)) { return; } PurpleAccount *account = purple_conversation_get_account(conv); From 933a650898cbd6df71f58b357b21f29d6c5baed6 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 8 Mar 2012 08:42:36 +0100 Subject: [PATCH 07/46] Fixed username_mask --- src/userregistration.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/userregistration.cpp b/src/userregistration.cpp index f7de616e..db7ab22e 100644 --- a/src/userregistration.cpp +++ b/src/userregistration.cpp @@ -453,7 +453,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID // #endif if (!registered) { res.jid = barejid; - res.uin = username; + res.uin = newUsername; res.password = *payload->getPassword(); res.language = language; res.encoding = encoding; @@ -462,7 +462,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID } else { res.jid = barejid; - res.uin = username; + res.uin = newUsername; res.password = *payload->getPassword(); res.language = language; res.encoding = encoding; From 1dc49d5237e0665b39df38fa68b26fbcd44bb285 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 8 Mar 2012 08:46:07 +0100 Subject: [PATCH 08/46] do not try to build spectrum2_send_message --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b64e64fa..3c1ef558 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,7 +218,7 @@ ADD_SUBDIRECTORY(spectrum) ADD_SUBDIRECTORY(backends) if (NOT WIN32) ADD_SUBDIRECTORY(spectrum_manager) - ADD_SUBDIRECTORY(spectrum2_send_message) +# ADD_SUBDIRECTORY(spectrum2_send_message) endif() if (CPPUNIT_FOUND) From 98981aec94641db2da4b08bc06a7c0bcff191704 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 8 Mar 2012 11:10:21 +0100 Subject: [PATCH 09/46] Fixed logging for skype --- backends/skype/main.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 9ede8a7f..984d9f60 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -834,7 +834,17 @@ int main(int argc, char **argv) { log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); p.load(istream); - p.setProperty("pid", boost::lexical_cast(getpid())); + + LogString pid, jid; + log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); + log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); +#ifdef _MSC_VER + p.setProperty(L"pid", pid); + p.setProperty(L"jid", jid); +#else + p.setProperty("pid", pid); + p.setProperty("jid", jid); +#endif log4cxx::PropertyConfigurator::configure(p); } From f42aa113b93c9aa7b0ff5b85f532f40554b1caeb Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 8 Mar 2012 11:56:36 +0100 Subject: [PATCH 10/46] support for extra memory usage --- include/transport/networkplugin.h | 2 ++ plugin/cpp/networkplugin.cpp | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index bba9c013..9a0dfb9b 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -211,6 +211,8 @@ class NetworkPlugin { virtual void handleFTPauseRequest(unsigned long ftID) {} virtual void handleFTContinueRequest(unsigned long ftID) {} + virtual void handleMemoryUsage(double &res, double &shared) {res = 0; shared = 0;} + virtual void handleExitRequest() { exit(1); } void handleDataRead(std::string &data); virtual void sendData(const std::string &string) {} diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index df4a6a38..c17adb7f 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -587,13 +587,18 @@ void NetworkPlugin::sendMemoryUsage() { pbnetwork::Stats stats; stats.set_init_res(m_init_res); - double res; - double shared; + double res = 0; + double shared = 0; #ifndef WIN32 process_mem_usage(shared, res); #endif - stats.set_res(res); - stats.set_shared(shared); + + double e_res; + double e_shared; + handleMemoryUsage(e_res, e_shared); + + stats.set_res(res + e_res); + stats.set_shared(shared + e_shared); std::string message; stats.SerializeToString(&message); From 3949b84ed02700f637e1545d3188c59608ff63d3 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Thu, 8 Mar 2012 20:04:56 +0100 Subject: [PATCH 11/46] Allow setting buddies subscriptions --- include/transport/buddy.h | 8 ++++++-- src/buddy.cpp | 11 ++++++----- src/networkpluginserver.cpp | 7 ++++++- src/rosterstorage.cpp | 2 +- src/tests/basictest.h | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/transport/buddy.h b/include/transport/buddy.h index 5e8f1088..929ba337 100644 --- a/include/transport/buddy.h +++ b/include/transport/buddy.h @@ -39,6 +39,9 @@ typedef enum { BUDDY_NO_FLAG = 0, /// Represents one legacy network Buddy. class Buddy { public: + typedef enum { Ask, + Both, + } Subscription; /// Constructor. /// \param rosterManager RosterManager associated with this buddy. @@ -93,12 +96,12 @@ class Buddy { /// Sets current subscription. /// \param subscription "to", "from", "both", "ask" - void setSubscription(const std::string &subscription); + void setSubscription(Subscription subscription); /// Returns current subscription /// \return subscription "to", "from", "both", "ask" - const std::string getSubscription(); + Subscription getSubscription(); /// Sets this buddy's flags. @@ -172,6 +175,7 @@ class Buddy { Swift::JID m_jid; BuddyFlag m_flags; RosterManager *m_rosterManager; + Subscription m_subscription; }; } diff --git a/src/buddy.cpp b/src/buddy.cpp index 6c023539..55f35713 100644 --- a/src/buddy.cpp +++ b/src/buddy.cpp @@ -26,7 +26,8 @@ namespace Transport { -Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){ +Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager), + m_subscription(Ask) { // m_rosterManager->setBuddy(this); } @@ -64,12 +65,12 @@ const Swift::JID &Buddy::getJID() { return m_jid; } -void Buddy::setSubscription(const std::string &subscription) { -// m_subscription = subscription; +void Buddy::setSubscription(Subscription subscription) { + m_subscription = subscription; } -const std::string Buddy::getSubscription() { - return "ask"; +Buddy::Subscription Buddy::getSubscription() { + return m_subscription; } Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) { diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index eeae4c31..5beba002 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -95,7 +95,12 @@ class NetworkFactory : public Factory { LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id); buddy->setAlias(buddyInfo.alias); buddy->setName(buddyInfo.legacyName); - buddy->setSubscription(buddyInfo.subscription); + if (buddyInfo.subscription == "both") { + buddy->setSubscription(Buddy::Both); + } + else { + buddy->setSubscription(Buddy::Ask); + } buddy->setGroups(buddyInfo.groups); buddy->setFlags((BuddyFlag) (buddyInfo.flags)); if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) diff --git a/src/rosterstorage.cpp b/src/rosterstorage.cpp index 294f19e8..30679cb9 100644 --- a/src/rosterstorage.cpp +++ b/src/rosterstorage.cpp @@ -103,7 +103,7 @@ bool RosterStorage::storeBuddies() { buddyInfo.alias = buddy->getAlias(); buddyInfo.legacyName = buddy->getName(); buddyInfo.groups = buddy->getGroups(); - buddyInfo.subscription = buddy->getSubscription(); + buddyInfo.subscription = buddy->getSubscription() == Buddy::Ask ? "ask" : "both"; buddyInfo.id = buddy->getID(); buddyInfo.flags = buddy->getFlags(); buddyInfo.settings["icon_hash"].s = buddy->getIconHash(); diff --git a/src/tests/basictest.h b/src/tests/basictest.h index c67691b3..832cada4 100644 --- a/src/tests/basictest.h +++ b/src/tests/basictest.h @@ -72,7 +72,7 @@ class TestingFactory : public Factory { LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id); buddy->setAlias(buddyInfo.alias); buddy->setName(buddyInfo.legacyName); - buddy->setSubscription(buddyInfo.subscription); + buddy->setSubscription(Buddy::Ask); buddy->setGroups(buddyInfo.groups); buddy->setFlags((BuddyFlag) buddyInfo.flags); if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) From 4c9f82cb3591f2c1f6f1bc68fbebc630ca3bf7ec Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 08:25:03 +0100 Subject: [PATCH 12/46] Report also skype process memory usage --- backends/skype/main.cpp | 30 +++++++++++++++++++----------- include/transport/memoryusage.h | 6 +++++- src/memoryusage.cpp | 21 +++++++++++++++------ 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 984d9f60..a56b985d 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -4,6 +4,7 @@ #include "transport/config.h" #include "transport/transport.h" #include "transport/usermanager.h" +#include "transport/memoryusage.h" #include "transport/logger.h" #include "transport/sqlite3backend.h" #include "transport/userregistration.h" @@ -97,6 +98,10 @@ class Skype { bool createDBusProxy(); bool loadSkypeBuddies(); + int getPid() { + return (int) m_pid; + } + private: std::string m_username; std::string m_password; @@ -134,6 +139,19 @@ class SpectrumNetworkPlugin : public NetworkPlugin { skype->login(); } + void handleMemoryUsage(double &res, double &shared) { + res = 0; + shared = 0; + for(std::map::const_iterator it = m_sessions.begin(); it != m_sessions.end(); it++) { + Skype *skype = it->second; + double r; + double s; + process_mem_usage(s, r, skype->getPid()); + res += r; + shared += s; + } + } + void handleLogoutRequest(const std::string &user, const std::string &legacyName) { Skype *skype = m_sessions[user]; if (skype) { @@ -834,17 +852,7 @@ int main(int argc, char **argv) { log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); p.load(istream); - - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef _MSC_VER - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif + p.setProperty("pid", boost::lexical_cast(getpid())); log4cxx::PropertyConfigurator::configure(p); } diff --git a/include/transport/memoryusage.h b/include/transport/memoryusage.h index d2080e21..d38917d9 100644 --- a/include/transport/memoryusage.h +++ b/include/transport/memoryusage.h @@ -22,10 +22,14 @@ #include +#ifndef WIN32 +#include "signal.h" +#endif + namespace Transport { #ifndef WIN32 - void process_mem_usage(double& shared, double& resident_set); + void process_mem_usage(double& shared, double& resident_set, pid_t pid = 0); #endif } \ No newline at end of file diff --git a/src/memoryusage.cpp b/src/memoryusage.cpp index ded5130e..d620569b 100644 --- a/src/memoryusage.cpp +++ b/src/memoryusage.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #ifndef WIN32 #include #endif @@ -41,13 +42,18 @@ namespace Transport { #ifndef WIN32 #ifdef BSD -void process_mem_usage(double& vm_usage, double& resident_set) { +void process_mem_usage(double& vm_usage, double& resident_set, pid_t pid) { int mib[4]; size_t size; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; - mib[3] = getpid(); + if (pid == 0) { + mib[3] = getpid(); + } + else { + mib[3] = pid; + } struct kinfo_proc proc; size = sizeof(struct kinfo_proc); @@ -75,7 +81,7 @@ void process_mem_usage(double& vm_usage, double& resident_set) { vm_usage = (double) proc.ki_size; } #else /* BSD */ -void process_mem_usage(double& shared, double& resident_set) { +void process_mem_usage(double& shared, double& resident_set, pid_t pid) { using std::ios_base; using std::ifstream; using std::string; @@ -84,8 +90,11 @@ void process_mem_usage(double& shared, double& resident_set) { resident_set = 0.0; // 'file' stat seems to give the most reliable results - // - ifstream stat_stream("/proc/self/statm",ios_base::in); + std::string f = "/proc/self/statm"; + if (pid != 0) { + f = "/proc/" + boost::lexical_cast(pid) + "/statm"; + } + ifstream stat_stream(f.c_str(), ios_base::in); if (!stat_stream.is_open()) { shared = 0; resident_set = 0; @@ -94,7 +103,7 @@ void process_mem_usage(double& shared, double& resident_set) { // dummy vars for leading entries in stat that we don't care about // - string pid, comm, state, ppid, pgrp, session, tty_nr; + string pid1, comm, state, ppid, pgrp, session, tty_nr; string tpgid, flags, minflt, cminflt, majflt, cmajflt; string utime, stime, cutime, cstime, priority, nice; string O, itrealvalue, starttime; From b6645a4ed9def716fcfa63cda01478554973082f Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 09:35:36 +0100 Subject: [PATCH 13/46] Store subscriptions properly in DB and change them during the subscribe process --- src/rostermanager.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index 65135116..4d8afba9 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -137,6 +137,11 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) { request->send(); m_requests.push_back(request); } + + if (buddy->getSubscription() != Buddy::Both) { + buddy->setSubscription(Buddy::Both); + handleBuddyChanged(buddy); + } } void RosterManager::sendBuddySubscribePresence(Buddy *buddy) { @@ -165,6 +170,11 @@ void RosterManager::setBuddyCallback(Buddy *buddy) { sendBuddyRosterPush(buddy); } else { + if (buddy->getSubscription() == Buddy::Both) { + LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Not forwarding this buddy, because subscription=both"); + return; + } + if (m_supportRemoteRoster) { sendBuddyRosterPush(buddy); } @@ -331,7 +341,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { response->setType(Swift::Presence::Subscribed); break; case Swift::Presence::Subscribed: - onBuddyAdded(buddy); +// onBuddyAdded(buddy); break; // buddy is already there, so nothing to do, just answer case Swift::Presence::Unsubscribe: @@ -361,6 +371,10 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { currentPresence->setTo(presence->getFrom()); m_component->getStanzaChannel()->sendPresence(currentPresence); } + if (buddy->getSubscription() != Buddy::Both) { + buddy->setSubscription(Buddy::Both); + handleBuddyChanged(buddy); + } break; // remove buddy case Swift::Presence::Unsubscribe: @@ -370,6 +384,19 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { // just send response case Swift::Presence::Unsubscribed: response->setType(Swift::Presence::Unsubscribe); + // We set both here, because this Unsubscribed can be response to + // subscribe presence and we don't want that unsubscribe presence + // to be send later again + if (buddy->getSubscription() != Buddy::Both) { + buddy->setSubscription(Buddy::Both); + handleBuddyChanged(buddy); + } + break; + case Swift::Presence::Subscribed: + if (buddy->getSubscription() != Buddy::Both) { + buddy->setSubscription(Buddy::Both); + handleBuddyChanged(buddy); + } break; default: return; @@ -394,7 +421,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { // buddy is already there, so nothing to do, just answer case Swift::Presence::Unsubscribe: response->setType(Swift::Presence::Unsubscribed); - onBuddyRemoved(buddy); +// onBuddyRemoved(buddy); break; // just send response case Swift::Presence::Unsubscribed: From 6ec566375c7d1fe285735519f0d11b75e969d61b Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 17:13:32 +0100 Subject: [PATCH 14/46] Send backend id back to main instance --- include/transport/networkpluginserver.h | 1 + include/transport/protocol.proto | 1 + plugin/cpp/networkplugin.cpp | 8 ++++++++ src/networkpluginserver.cpp | 1 + 4 files changed, 11 insertions(+) diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 671c8ba4..e0ce31f9 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -56,6 +56,7 @@ class NetworkPluginServer { bool acceptUsers; bool longRun; bool willDie; + std::string id; }; NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager); diff --git a/include/transport/protocol.proto b/include/transport/protocol.proto index 9a296392..8f3ac42c 100644 --- a/include/transport/protocol.proto +++ b/include/transport/protocol.proto @@ -106,6 +106,7 @@ message Stats { required int32 res = 1; required int32 init_res = 2; required int32 shared = 3; + required string id = 4; } message File { diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index c17adb7f..4c26515a 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -41,6 +41,12 @@ namespace Transport { wrap.set_payload(MESSAGE); \ wrap.SerializeToString(&MESSAGE); +template std::string stringOf(T object) { + std::ostringstream os; + os << object; + return (os.str()); +} + NetworkPlugin::NetworkPlugin() { m_pingReceived = false; @@ -603,6 +609,8 @@ void NetworkPlugin::sendMemoryUsage() { std::string message; stats.SerializeToString(&message); + stats.set_id(stringOf(getpid())); + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATS); send(message); diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 5beba002..f3f891f0 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -612,6 +612,7 @@ void NetworkPluginServer::handleStatsPayload(Backend *c, const std::string &data c->res = payload.res(); c->init_res = payload.init_res(); c->shared = payload.shared(); + c->id = payload.id(); } void NetworkPluginServer::handleFTStartPayload(const std::string &data) { From d4769080ca30af9f9240f8a291ed9f556cc71764 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 17:55:57 +0100 Subject: [PATCH 15/46] More stats --- include/transport/networkpluginserver.h | 5 +++++ include/transport/usermanager.h | 9 +++++++++ src/networkpluginserver.cpp | 4 ++++ src/statsresponder.cpp | 18 +++++++++++++++--- src/usermanager.cpp | 2 ++ 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index e0ce31f9..5572780a 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -71,6 +71,10 @@ class NetworkPluginServer { return m_clients; } + const std::vector &getCrashedBackends() { + return m_crashedBackends; + } + void collectBackend(); bool moveToLongRunBackend(User *user); @@ -138,6 +142,7 @@ class NetworkPluginServer { bool m_isNextLongRun; std::map m_filetransfers; FileTransferManager *m_ftManager; + std::vector m_crashedBackends; }; } diff --git a/include/transport/usermanager.h b/include/transport/usermanager.h index 5ea47d5c..2601be21 100644 --- a/include/transport/usermanager.h +++ b/include/transport/usermanager.h @@ -116,6 +116,13 @@ class UserManager : public Swift::EntityCapsProvider { /// \param user JID of user. void disconnectUser(const Swift::JID &user); + void messageToXMPPSent() { m_sentToXMPP++; } + void messageToBackendSent() { m_sentToBackend++; } + + unsigned long getMessagesToXMPP() { return m_sentToXMPP; } + unsigned long getMessagesToBackend() { return m_sentToBackend; } + + private: void handlePresence(Swift::Presence::ref presence); void handleMessageReceived(Swift::Message::ref message); @@ -134,6 +141,8 @@ class UserManager : public Swift::EntityCapsProvider { StorageResponder *m_storageResponder; UserRegistry *m_userRegistry; Swift::Timer::ref m_removeTimer; + unsigned long m_sentToXMPP; + unsigned long m_sentToBackend; friend class RosterResponder; }; diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index f3f891f0..2ae551af 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -351,6 +351,10 @@ void NetworkPluginServer::handleSessionFinished(Backend *c) { // If there are users associated with this backend, it must have crashed, so print error output // and disconnect users + if (!c->users.empty()) { + m_crashedBackends.push_back(c->id); + } + for (std::list::const_iterator it = c->users.begin(); it != c->users.end(); it++) { LOG4CXX_ERROR(logger, "Backend " << c << " disconnected (probably crashed) with active user " << (*it)->getJID().toString()); (*it)->setData(NULL); diff --git a/src/statsresponder.cpp b/src/statsresponder.cpp index 802a1bbd..bf4e4b5f 100644 --- a/src/statsresponder.cpp +++ b/src/statsresponder.cpp @@ -81,7 +81,10 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& response->addItem(StatsPayload::Item("users/online")); response->addItem(StatsPayload::Item("contacts/online")); response->addItem(StatsPayload::Item("contacts/total")); - response->addItem(StatsPayload::Item("backends")); + response->addItem(StatsPayload::Item("messages/from-xmpp")); + response->addItem(StatsPayload::Item("messages/to-xmpp")); + response->addItem(StatsPayload::Item("backends/running")); + response->addItem(StatsPayload::Item("backends/crashed")); response->addItem(StatsPayload::Item("memory-usage")); } else { @@ -115,8 +118,11 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& else if (item.getName() == "users/online") { response->addItem(StatsPayload::Item("users/online", "users", boost::lexical_cast(m_userManager->getUserCount()))); } - else if (item.getName() == "backends") { - response->addItem(StatsPayload::Item("backends", "backends", boost::lexical_cast(m_server->getBackendCount()))); + else if (item.getName() == "backends/running") { + response->addItem(StatsPayload::Item("backends/running", "backends", boost::lexical_cast(m_server->getBackendCount()))); + } + else if (item.getName() == "backends/crashed") { + response->addItem(StatsPayload::Item("backends/crashed", "backends", boost::lexical_cast(m_server->getCrashedBackends().size()))); } else if (item.getName() == "memory-usage") { response->addItem(StatsPayload::Item("memory-usage", "KB", boost::lexical_cast(usedMemory()))); @@ -127,6 +133,12 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& else if (item.getName() == "contacts/total") { response->addItem(StatsPayload::Item("contacts/total", "contacts", boost::lexical_cast(contactsTotal))); } + else if (item.getName() == "messages/from-xmpp") { + response->addItem(StatsPayload::Item("messages/from-xmpp", "messages", boost::lexical_cast(m_userManager->getMessagesToBackend()))); + } + else if (item.getName() == "messages/to-xmpp") { + response->addItem(StatsPayload::Item("messages/to-xmpp", "messages", boost::lexical_cast(m_userManager->getMessagesToXMPP()))); + } } } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 08823715..ed99e668 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -42,6 +42,8 @@ static LoggerPtr logger = Logger::getLogger("UserManager"); UserManager::UserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) { m_cachedUser = NULL; m_onlineBuddies = 0; + m_sentToXMPP = 0; + m_sentToBackend = 0; m_component = component; m_storageBackend = storageBackend; m_storageResponder = NULL; From 7ec58e0024366cfae4556ea6558278f2ee278203 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 18:41:58 +0100 Subject: [PATCH 16/46] fixed setting backend id --- plugin/cpp/networkplugin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index 4c26515a..94fc82c0 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -605,12 +605,11 @@ void NetworkPlugin::sendMemoryUsage() { stats.set_res(res + e_res); stats.set_shared(shared + e_shared); + stats.set_id(stringOf(getpid())); std::string message; stats.SerializeToString(&message); - stats.set_id(stringOf(getpid())); - WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATS); send(message); From 5407885d87e772765b49a35d8622012f41a1ec1d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 19:36:48 +0100 Subject: [PATCH 17/46] Do not send available presence as response to subscribed --- src/rostermanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index 4d8afba9..1bde0173 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -342,7 +342,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { break; case Swift::Presence::Subscribed: // onBuddyAdded(buddy); - break; + return; // buddy is already there, so nothing to do, just answer case Swift::Presence::Unsubscribe: response->setType(Swift::Presence::Unsubscribed); @@ -397,7 +397,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { buddy->setSubscription(Buddy::Both); handleBuddyChanged(buddy); } - break; + return; default: return; } From 6d09f9e42f94d9765f94706b374bc3aa46a5f9de Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 20:13:33 +0100 Subject: [PATCH 18/46] Updated changelog --- ChangeLog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index d0d28034..d731f169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Version 2.0.0-beta2 (2012-XX-XX): + General: + * Fixed bug when Roster Item Exchange and subscribe stanzas were send + repeatedly. + * Fixed username_mask setting. + * Added new fields into statistics. + + libpurple: + * Added support for MUC for prpl-jabber protocol. + + Skype: + * Fixed logging issue when the logs were not stored in the proper instance + directory. + * Skype backend includes also Skype client memory usage into the account. + Version 2.0.0-beta (2012-02-28): General: * Added PostreSQL support (thanks to Jadestorm). From f522ee311c938aac030a7bc8862c0a2af974157e Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 9 Mar 2012 21:44:03 +0100 Subject: [PATCH 19/46] Handle buddy updates and removal in skype --- backends/skype/main.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index a56b985d..7952bc59 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -196,6 +196,21 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } } + void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups) { + Skype *skype = m_sessions[user]; + if (skype) { + skype->send_command("SET USER " + buddyName + " BUDDYSTATUS 2 Please authorize me"); + skype->send_command("SET USER " + buddyName + " ISAUTHORIZED TRUE"); + } + } + + void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups) { + Skype *skype = m_sessions[user]; + if (skype) { + skype->send_command("SET USER " + buddyName + " BUDDYSTATUS 1"); + } + } + void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) { Skype *skype = m_sessions[user]; if (skype) { @@ -286,13 +301,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleVCardUpdatedRequest(const std::string &user, const std::string &p, const std::string &nickname) { } - void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups) { - } - - void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups) { - - } - void handleBuddyBlockToggled(const std::string &user, const std::string &buddyName, bool blocked) { } From 51167fe71f1fe0667efcdc1551fdeee684951411 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sat, 10 Mar 2012 10:51:58 +0100 Subject: [PATCH 20/46] Fixed conversation creationg introduced by previous commits --- backends/libpurple/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 01e24e43..ce8ad051 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -770,7 +770,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { if (account) { PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, legacyName.c_str(), account); if (!conv) { - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account); + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account); if (!conv) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str()); } From a9f468f8f3fe71663a581591db51d55bec39e48c Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sat, 10 Mar 2012 11:22:39 +0100 Subject: [PATCH 21/46] Fill the stats --- src/networkpluginserver.cpp | 1 + src/usermanager.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 2ae551af..591c9650 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -579,6 +579,7 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool // Forward it conv->handleMessage(msg, payload.nickname()); + m_userManager->messageToXMPPSent(); } void NetworkPluginServer::handleAttentionPayload(const std::string &data) { diff --git a/src/usermanager.cpp b/src/usermanager.cpp index ed99e668..1845d94e 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -268,6 +268,7 @@ void UserManager::handleMessageReceived(Swift::Message::ref message) { } user->getConversationManager()->handleMessageReceived(message); + messageToBackendSent(); } void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) { From 8dba1176b5c0543cd12be6e0f4c3ed1eb9380367 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sat, 10 Mar 2012 11:31:13 +0100 Subject: [PATCH 22/46] Remove skype tmp directory before login --- backends/skype/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 7952bc59..e8a56baf 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -386,6 +386,12 @@ static gboolean create_dbus_proxy(gpointer data) { } void Skype::login() { + if (m_username.find("..") == 0 || m_username.find("/") != std::string::npos) { + np->handleDisconnected(m_user, 0, "Invalid username"); + return; + } + boost::filesystem::remove_all(std::string("/tmp/skype/") + m_username); + boost::filesystem::path path(std::string("/tmp/skype/") + m_username); if (!boost::filesystem::exists(path)) { boost::filesystem::create_directories(path); From b627e6177f20b7369a9d73829e7a846b21dcb939 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 11 Mar 2012 11:31:02 +0100 Subject: [PATCH 23/46] Fixed crash in skype handleMemoryUsage --- backends/skype/main.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index e8a56baf..0e849f4c 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -129,7 +129,9 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { std::string name = legacyName; - name = name.substr(name.find(".") + 1); + if (name.find("skype.") == 0 || name.find("prpl-skype.") == 0) { + name = name.substr(name.find(".") + 1); + } LOG4CXX_INFO(logger, "Creating account with name '" << name << "'"); Skype *skype = new Skype(user, name, password); @@ -144,11 +146,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin { shared = 0; for(std::map::const_iterator it = m_sessions.begin(); it != m_sessions.end(); it++) { Skype *skype = it->second; - double r; - double s; - process_mem_usage(s, r, skype->getPid()); - res += r; - shared += s; + if (skype) { + double r; + double s; + process_mem_usage(s, r, skype->getPid()); + res += r; + shared += s; + } } } From 7ecce75babd489c1ff1102bbc9689034a246dded Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 11 Mar 2012 12:08:54 +0100 Subject: [PATCH 24/46] More skype tweaks --- backends/skype/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 0e849f4c..54e7025e 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -434,7 +434,7 @@ void Skype::login() { char *db = (char *) malloc(db_path.size() + 1); strcpy(db, db_path.c_str()); LOG4CXX_INFO(logger, m_username << ": Spawning new Skype instance dbpath=" << db); - gchar* argv[6] = {"skype", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0}; + gchar* argv[8] = {"skype", "--enable-dbus", "--use-session-dbus", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0}; int fd; g_spawn_async_with_pipes(NULL, @@ -608,8 +608,10 @@ std::string Skype::send_command(const std::string &message) { { LOG4CXX_INFO(logger, m_username << ": DBUS Error: " << error->message); g_error_free(error); + return ""; } else { LOG4CXX_INFO(logger, m_username << ": DBUS no response"); + return ""; } } From c43a4b4fc1f3342656878959f47a2cbb02702f5d Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 12 Mar 2012 10:48:24 +0100 Subject: [PATCH 25/46] sleep for 2 seconds before trying to connect skype using dbus and try it repeatedly when skype refuses to authenticate spectrum --- backends/skype/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 54e7025e..23ac6825 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -473,6 +473,7 @@ void Skype::login() { } } + sleep(2); m_timer = g_timeout_add_seconds(1, create_dbus_proxy, this); } @@ -499,7 +500,7 @@ bool Skype::loadSkypeBuddies() { return FALSE; } - if (re.empty() || re == "CONNSTATUS OFFLINE") { + if (re.empty() || re == "CONNSTATUS OFFLINE" || re == "ERROR 68") { return TRUE; } From 4c1285a8e1da653e3012ed12b37b6c4b41c22312 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 12 Mar 2012 14:02:09 +0100 Subject: [PATCH 26/46] log sent messages --- backends/skype/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 23ac6825..988a2ad1 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -430,6 +430,7 @@ void Skype::login() { "\n"; g_file_set_contents(std::string(std::string("/tmp/skype/") + m_username + "/" + m_username +"/config.xml").c_str(), config_xml.c_str(), -1, NULL); + sleep(1); std::string db_path = std::string("/tmp/skype/") + m_username; char *db = (char *) malloc(db_path.size() + 1); strcpy(db, db_path.c_str()); @@ -473,7 +474,7 @@ void Skype::login() { } } - sleep(2); + sleep(1); m_timer = g_timeout_add_seconds(1, create_dbus_proxy, this); } @@ -602,6 +603,7 @@ std::string Skype::send_command(const std::string &message) { // int message_num; // gchar error_return[30]; + LOG4CXX_INFO(logger, "Sending: " << message); if (!dbus_g_proxy_call (m_proxy, "Invoke", &error, G_TYPE_STRING, message.c_str(), G_TYPE_INVALID, G_TYPE_STRING, &str, G_TYPE_INVALID)) { From 1846c3953d39471a3975253d0224bf5151bcb370 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Tue, 13 Mar 2012 09:52:28 +0100 Subject: [PATCH 27/46] Fixed skype hopeful --- backends/skype/main.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 988a2ad1..dd8031d4 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -82,7 +82,7 @@ static pbnetwork::StatusType getStatus(const std::string &st) { class Skype { public: Skype(const std::string &user, const std::string &username, const std::string &password); - ~Skype() { logout(); } + ~Skype() { LOG4CXX_INFO(logger, "Skype instance desctuctor"); logout(); } void login(); void logout(); std::string send_command(const std::string &message); @@ -159,6 +159,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleLogoutRequest(const std::string &user, const std::string &legacyName) { Skype *skype = m_sessions[user]; if (skype) { + LOG4CXX_INFO(logger, "User wants to logout, logging out"); skype->logout(); exit(1); } @@ -361,6 +362,7 @@ bool Skype::createDBusProxy() { LOG4CXX_INFO(logger, m_username << ":" << error->message); if (m_counter == 15) { + LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created"); np->handleDisconnected(m_user, 0, error->message); logout(); g_error_free(error); @@ -483,18 +485,19 @@ bool Skype::loadSkypeBuddies() { // while (re == "CONNSTATUS OFFLINE" || re.empty()) { // sleep(1); - gchar buffer[1024]; - int bytes_read = read(fd_output, buffer, 1023); - if (bytes_read > 0) { - buffer[bytes_read] = 0; - np->handleDisconnected(m_user, 0, buffer); - close(fd_output); - logout(); - return FALSE; - } +// gchar buffer[1024]; +// int bytes_read = read(fd_output, buffer, 1023); +// if (bytes_read > 0) { +// buffer[bytes_read] = 0; +// np->handleDisconnected(m_user, 0, buffer); +// close(fd_output); +// logout(); +// return FALSE; +// } std::string re = send_command("NAME Spectrum"); if (m_counter++ > 15) { + LOG4CXX_ERROR(logger, "Logging out, because we tried to connect the Skype over DBUS 15 times without success"); np->handleDisconnected(m_user, 0, ""); close(fd_output); logout(); @@ -508,6 +511,7 @@ bool Skype::loadSkypeBuddies() { close(fd_output); if (send_command("PROTOCOL 7") != "PROTOCOL 7") { + LOG4CXX_ERROR(logger, "PROTOCOL 7 failed, logging out"); np->handleDisconnected(m_user, 0, "Skype is not ready"); logout(); return FALSE; From eea254d29c46de4244adddf0f4040288ac86c298 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 13 Mar 2012 21:57:09 +0100 Subject: [PATCH 28/46] log error on disconnect everytime --- src/user.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user.cpp b/src/user.cpp index e94ae872..8cfcd0ea 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -328,7 +328,7 @@ void User::handleDisconnected(const std::string &error, Swift::SpectrumErrorPayl if (e == Swift::SpectrumErrorPayload::CONNECTION_ERROR_OTHER_ERROR || e == Swift::SpectrumErrorPayload::CONNECTION_ERROR_NETWORK_ERROR) { if (m_reconnectCounter < 3) { m_reconnectCounter++; - LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network for, trying to reconnect automatically."); + LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network " << error << ", trying to reconnect automatically."); // Simulate destruction/resurrection :) // TODO: If this stops working, create onReconnect signal m_userManager->onUserDestroyed(this); From 4cd528271c09dd3def2a01aa1399f97d313c1ffc Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 14 Mar 2012 09:00:19 +0100 Subject: [PATCH 29/46] send info about missed calls + probably fixed Incorrect Password notification --- backends/skype/main.cpp | 49 +++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index dd8031d4..fbc765d1 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -485,15 +485,20 @@ bool Skype::loadSkypeBuddies() { // while (re == "CONNSTATUS OFFLINE" || re.empty()) { // sleep(1); -// gchar buffer[1024]; -// int bytes_read = read(fd_output, buffer, 1023); -// if (bytes_read > 0) { -// buffer[bytes_read] = 0; -// np->handleDisconnected(m_user, 0, buffer); -// close(fd_output); -// logout(); -// return FALSE; -// } + gchar buffer[1024]; + int bytes_read = read(fd_output, buffer, 1023); + if (bytes_read > 0) { + buffer[bytes_read] = 0; + std::string b(buffer); + LOG4CXX_WARN(logger, "Skype wrote this on stdout '" << b << "'"); + if (b.find("Incorrect Password") != std::string::npos) { + LOG4CXX_INFO(logger, "Incorrect password, logging out") + np->handleDisconnected(m_user, 0, "Incorrect password"); + close(fd_output); + logout(); + return FALSE; + } + } std::string re = send_command("NAME Spectrum"); if (m_counter++ > 15) { @@ -710,6 +715,32 @@ static void handle_skype_message(std::string &message, Skype *sk) { np->handleMessage(sk->getUser(), from, body); } } + else if (cmd[0] == "CALL") { + // CALL 884 STATUS RINGING + if (cmd[2] == "STATUS") { + if (cmd[3] == "RINGING" || cmd[3] == "MISSED") { + // handle only incoming calls + std::string type = sk->send_command("GET CALL " + cmd[1] + " TYPE"); + type = type.substr(type.find("TYPE") + 5); + if (type.find("INCOMING") != 0) { + return; + } + + std::string from = sk->send_command("GET CALL " + cmd[1] + " PARTNER_HANDLE"); + from = from.substr(from.find("PARTNER_HANDLE") + 15); + + std::string dispname = sk->send_command("GET CALL " + cmd[1] + " PARTNER_DISPNAME"); + dispname = dispname.substr(dispname.find("PARTNER_DISPNAME") + 17); + + if (cmd[3] == "RINGING") { + np->handleMessage(sk->getUser(), from, "User " + dispname + " is calling you."); + } + else { + np->handleMessage(sk->getUser(), from, "You have missed call from user " + dispname + "."); + } + } + } + } } DBusHandlerResult skype_notify_handler(DBusConnection *connection, DBusMessage *message, gpointer user_data) { From 55c27481103e63e8cd18bb8cebf01bd4f9606955 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 14 Mar 2012 09:22:29 +0100 Subject: [PATCH 30/46] Removed unrecognized commands --- backends/skype/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index fbc765d1..4622f464 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -437,7 +437,7 @@ void Skype::login() { char *db = (char *) malloc(db_path.size() + 1); strcpy(db, db_path.c_str()); LOG4CXX_INFO(logger, m_username << ": Spawning new Skype instance dbpath=" << db); - gchar* argv[8] = {"skype", "--enable-dbus", "--use-session-dbus", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0}; + gchar* argv[6] = {"skype", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0}; int fd; g_spawn_async_with_pipes(NULL, From 0e01945c9839eaeec61af49db1920cb5cf8fe628 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 14 Mar 2012 14:48:24 +0100 Subject: [PATCH 31/46] Forward proper errors to XMPP user instead of Internal Server Error --- backends/skype/main.cpp | 10 +++++----- spectrum/src/sample.cfg | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 4622f464..137c7b8a 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -363,7 +363,7 @@ bool Skype::createDBusProxy() { if (m_counter == 15) { LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created"); - np->handleDisconnected(m_user, 0, error->message); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, error->message); logout(); g_error_free(error); return FALSE; @@ -393,7 +393,7 @@ static gboolean create_dbus_proxy(gpointer data) { void Skype::login() { if (m_username.find("..") == 0 || m_username.find("/") != std::string::npos) { - np->handleDisconnected(m_user, 0, "Invalid username"); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Invalid username"); return; } boost::filesystem::remove_all(std::string("/tmp/skype/") + m_username); @@ -493,7 +493,7 @@ bool Skype::loadSkypeBuddies() { LOG4CXX_WARN(logger, "Skype wrote this on stdout '" << b << "'"); if (b.find("Incorrect Password") != std::string::npos) { LOG4CXX_INFO(logger, "Incorrect password, logging out") - np->handleDisconnected(m_user, 0, "Incorrect password"); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_FAILED, "Incorrect password"); close(fd_output); logout(); return FALSE; @@ -503,7 +503,7 @@ bool Skype::loadSkypeBuddies() { std::string re = send_command("NAME Spectrum"); if (m_counter++ > 15) { LOG4CXX_ERROR(logger, "Logging out, because we tried to connect the Skype over DBUS 15 times without success"); - np->handleDisconnected(m_user, 0, ""); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not read."); close(fd_output); logout(); return FALSE; @@ -517,7 +517,7 @@ bool Skype::loadSkypeBuddies() { if (send_command("PROTOCOL 7") != "PROTOCOL 7") { LOG4CXX_ERROR(logger, "PROTOCOL 7 failed, logging out"); - np->handleDisconnected(m_user, 0, "Skype is not ready"); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready"); logout(); return FALSE; } diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index d0e234e9..57e601eb 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -13,11 +13,12 @@ admin_password=test #cert=server.pfx #patch to PKCS#12 certificate #cert_password=test #password to that certificate if any users_per_backend=10 -backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend +#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend #backend=/home/hanzz/code/libtransport/backends/smstools3/spectrum2_smstools3_backend #backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe #backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend #backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend +backend=/usr/bin/xvfb-run -n BACKEND_ID -s "-screen 0 10x10x8" -f /tmp/x-skype-gw /home/hanzz/code/libtransport/backends/skype/spectrum2_skype_backend #protocol=prpl-msn protocol=any #protocol=prpl-icq From c6c322f51f948d64336eedf538b470b7604aa5f0 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 14 Mar 2012 18:11:32 +0100 Subject: [PATCH 32/46] Logs shows backends PID + there's new crashed_backends command to find out PIDs of crashed backends to make log inspection easier --- src/admininterface.cpp | 21 +++++++++++++++------ src/networkpluginserver.cpp | 12 ++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/admininterface.cpp b/src/admininterface.cpp index 7df84772..cec4dfa6 100644 --- a/src/admininterface.cpp +++ b/src/admininterface.cpp @@ -112,7 +112,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { const std::list &backends = m_server->getBackends(); for (std::list ::const_iterator b = backends.begin(); b != backends.end(); b++) { NetworkPluginServer::Backend *backend = *b; - lst += "Backend " + boost::lexical_cast(id); + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + ")"; lst += backend->acceptUsers ? "" : " - not-accepting"; lst += backend->longRun ? " - long-running" : ""; lst += ":\n"; @@ -204,7 +204,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { int id = 1; const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { - lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->res) + "\n"; + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + "): " + boost::lexical_cast(backend->res) + "\n"; id++; } @@ -215,7 +215,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { int id = 1; const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { - lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->shared) + "\n"; + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + "): " + boost::lexical_cast(backend->shared) + "\n"; id++; } @@ -226,7 +226,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { int id = 1; const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { - lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->res - backend->shared) + "\n"; + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + "): " + boost::lexical_cast(backend->res - backend->shared) + "\n"; id++; } @@ -238,10 +238,10 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { if (backend->users.size() == 0) { - lst += "Backend " + boost::lexical_cast(id) + ": 0\n"; + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + "): 0\n"; } else { - lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast((backend->res - backend->init_res) / backend->users.size()) + "\n"; + lst += "Backend " + boost::lexical_cast(id) + " (ID=" + backend->id + "): " + boost::lexical_cast((backend->res - backend->init_res) / backend->users.size()) + "\n"; } id++; } @@ -251,6 +251,14 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { else if (message->getBody() == "collect_backend") { m_server->collectBackend(); } + else if (message->getBody() == "crashed_backends") { + std::string lst; + const std::vector &backends = m_server->getCrashedBackends(); + BOOST_FOREACH(const std::string &backend, backends) { + lst += backend + "\n"; + } + message->setBody(lst); + } else if (message->getBody().find("help") == 0) { std::string help; help += "General:\n"; @@ -263,6 +271,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { help += " has_online_user - returns 1 if user is online\n"; help += "Backends:\n"; help += " backends_count - number of active backends\n"; + help += " crashed_backends - returns IDs of crashed backends\n"; help += "Memory:\n"; help += " res_memory - Total RESident memory spectrum2 and its backends use in KB\n"; help += " shr_memory - Total SHaRed memory spectrum2 backends share together in KB\n"; diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 591c9650..a36699be 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -344,7 +344,7 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptrgetJID().toString()); + LOG4CXX_ERROR(logger, "Backend " << c << " (ID=" << c->id << ") disconnected (probably crashed) with active user " << (*it)->getJID().toString()); (*it)->setData(NULL); (*it)->handleDisconnected("Internal Server Error, please reconnect."); } @@ -864,12 +864,12 @@ void NetworkPluginServer::pingTimeout() { sendPing((*it)); } else { - LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". PING response not received."); + LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << " (ID=" << (*it)->id << "). PING response not received."); toRemove.push_back(*it); } if ((*it)->users.size() == 0) { - LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". There are no users."); + LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << " (ID=" << (*it)->id << "). There are no users."); toRemove.push_back(*it); } } @@ -898,7 +898,7 @@ void NetworkPluginServer::collectBackend() { if (m_collectTimer) { m_collectTimer->start(); } - LOG4CXX_INFO(logger, "Backend " << backend << "is set to die"); + LOG4CXX_INFO(logger, "Backend " << backend << " (ID=" << backend->id << ") is set to die"); backend->acceptUsers = false; } } @@ -1366,7 +1366,7 @@ void NetworkPluginServer::sendPing(Backend *c) { wrap.SerializeToString(&message); if (c->connection) { - LOG4CXX_INFO(logger, "PING to " << c); + LOG4CXX_INFO(logger, "PING to " << c << " (ID=" << c->id << ")"); send(c->connection, message); c->pongReceived = false; } From 48f2d9d6b146b8a395ee474a625e44d110644089 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 14 Mar 2012 18:56:23 +0100 Subject: [PATCH 33/46] Moved database initialization into StorageBackend --- backends/smstools3/main.cpp | 53 ++++------------------------ include/transport/storagebackend.h | 4 +++ spectrum/src/main.cpp | 55 ++++-------------------------- 3 files changed, 18 insertions(+), 94 deletions(-) diff --git a/backends/smstools3/main.cpp b/backends/smstools3/main.cpp index 1b0bb044..c152ef4f 100644 --- a/backends/smstools3/main.cpp +++ b/backends/smstools3/main.cpp @@ -337,55 +337,16 @@ int main (int argc, char* argv[]) { log4cxx::PropertyConfigurator::configure(p); } -#ifdef WITH_SQLITE - if (CONFIG_STRING(&config, "database.type") == "sqlite3") { - storageBackend = new SQLite3Backend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "sqlite3") { - std::cerr << "Spectrum2 is not compiled with mysql backend.\n"; + std::string error; + storageBackend = StorageBackend::createBackend(&config, error); + if (storageBackend == NULL) { + std::cerr << error << "\n"; return -2; } -#endif -#ifdef WITH_MYSQL - if (CONFIG_STRING(&config, "database.type") == "mysql") { - storageBackend = new MySQLBackend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "mysql") { - std::cerr << "Spectrum2 is not compiled with mysql backend.\n"; - return -2; - } -#endif - -#ifdef WITH_PQXX - if (CONFIG_STRING(&config, "database.type") == "pqxx") { - storageBackend = new PQXXBackend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "pqxx") { - std::cerr << "Spectrum2 is not compiled with pqxx backend.\n"; - return -2; - } -#endif - - if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3" - && CONFIG_STRING(&config, "database.type") != "pqxx" && CONFIG_STRING(&config, "database.type") != "none") { - std::cerr << "Unknown storage backend " << CONFIG_STRING(&config, "database.type") << "\n"; - return -2; + if (!storageBackend->connect()) { + std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; + return -1; } Swift::SimpleEventLoop eventLoop; diff --git a/include/transport/storagebackend.h b/include/transport/storagebackend.h index 6bac4aa7..f0a13df5 100644 --- a/include/transport/storagebackend.h +++ b/include/transport/storagebackend.h @@ -80,6 +80,8 @@ struct BuddyInfo { int flags; }; +class Config; + /// Abstract class defining storage backends. class StorageBackend { @@ -87,6 +89,8 @@ class StorageBackend /// Virtual desctructor. virtual ~StorageBackend() {} + static StorageBackend *createBackend(Config *config, std::string &error); + /// connect virtual bool connect() = 0; diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index d05bdeb8..02e9e226 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -349,57 +349,16 @@ int main(int argc, char **argv) component_ = &transport; // Logger logger(&transport); - StorageBackend *storageBackend = NULL; - -#ifdef WITH_SQLITE - if (CONFIG_STRING(&config, "database.type") == "sqlite3") { - storageBackend = new SQLite3Backend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "sqlite3") { - std::cerr << "Spectrum2 is not compiled with mysql backend.\n"; + std::string error; + StorageBackend *storageBackend = StorageBackend::createBackend(&config, error); + if (storageBackend == NULL) { + std::cerr << error << "\n"; return -2; } -#endif -#ifdef WITH_MYSQL - if (CONFIG_STRING(&config, "database.type") == "mysql") { - storageBackend = new MySQLBackend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "mysql") { - std::cerr << "Spectrum2 is not compiled with mysql backend.\n"; - return -2; - } -#endif - -#ifdef WITH_PQXX - if (CONFIG_STRING(&config, "database.type") == "pqxx") { - storageBackend = new PQXXBackend(&config); - if (!storageBackend->connect()) { - std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; - return -1; - } - } -#else - if (CONFIG_STRING(&config, "database.type") == "pqxx") { - std::cerr << "Spectrum2 is not compiled with pqxx backend.\n"; - return -2; - } -#endif - - if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3" - && CONFIG_STRING(&config, "database.type") != "pqxx" && CONFIG_STRING(&config, "database.type") != "none") { - std::cerr << "Unknown storage backend " << CONFIG_STRING(&config, "database.type") << "\n"; - return -2; + if (!storageBackend->connect()) { + std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; + return -1; } UserManager userManager(&transport, &userRegistry, storageBackend); From a06a47ed110e45de38e60259955c4cfaf87a1b88 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 14 Mar 2012 21:18:10 +0100 Subject: [PATCH 34/46] moved log4cxx initialization to libtransport --- backends/libcommuni/main.cpp | 26 +------ backends/skype/main.cpp | 14 +--- backends/smstools3/main.cpp | 37 +++------- include/transport/logging.h | 39 +++++++++++ spectrum/src/main.cpp | 77 +++----------------- src/logging.cpp | 132 +++++++++++++++++++++++++++++++++++ src/storagebackend.cpp | 49 +++++++++++++ 7 files changed, 240 insertions(+), 134 deletions(-) create mode 100644 include/transport/logging.h create mode 100644 src/logging.cpp create mode 100644 src/storagebackend.cpp diff --git a/backends/libcommuni/main.cpp b/backends/libcommuni/main.cpp index f5af84fb..6443c2bd 100644 --- a/backends/libcommuni/main.cpp +++ b/backends/libcommuni/main.cpp @@ -10,6 +10,7 @@ #include "transport/config.h" #include "transport/networkplugin.h" +#include "transport/logging.h" #include "session.h" #include #include @@ -83,30 +84,7 @@ int main (int argc, char* argv[]) { } QCoreApplication app(argc, argv); - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifndef _MSC_VER - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef _MSC_VER - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); Swift::QtEventLoop eventLoop; diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 137c7b8a..40118f67 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -2,6 +2,7 @@ #include #include "transport/config.h" +#include "transport/logging.h" #include "transport/transport.h" #include "transport/usermanager.h" #include "transport/memoryusage.h" @@ -901,18 +902,7 @@ int main(int argc, char **argv) { return 1; } - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - - p.load(istream); - p.setProperty("pid", boost::lexical_cast(getpid())); - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); // initPurple(config); diff --git a/backends/smstools3/main.cpp b/backends/smstools3/main.cpp index c152ef4f..a6502bdc 100644 --- a/backends/smstools3/main.cpp +++ b/backends/smstools3/main.cpp @@ -9,6 +9,7 @@ */ #include "transport/config.h" +#include "transport/logging.h" #include "transport/networkplugin.h" #include "transport/sqlite3backend.h" #include "transport/mysqlbackend.h" @@ -312,39 +313,17 @@ int main (int argc, char* argv[]) { return 1; } - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifndef _MSC_VER - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef _MSC_VER - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); std::string error; - storageBackend = StorageBackend::createBackend(&config, error); + StorageBackend *storageBackend = StorageBackend::createBackend(&config, error); if (storageBackend == NULL) { - std::cerr << error << "\n"; - return -2; + if (!error.empty()) { + std::cerr << error << "\n"; + return -2; + } } - - if (!storageBackend->connect()) { + else if (!storageBackend->connect()) { std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; return -1; } diff --git a/include/transport/logging.h b/include/transport/logging.h new file mode 100644 index 00000000..79b1dfd5 --- /dev/null +++ b/include/transport/logging.h @@ -0,0 +1,39 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#pragma once + +#include +#include +#include +#include + +namespace Transport { + +class Config; + +namespace Logging { + +void initBackendLogging(Config *config); +void initMainLogging(Config *config); + +} + +} diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index 02e9e226..be525f60 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -13,6 +13,7 @@ #include "transport/usersreconnecter.h" #include "transport/util.h" #include "transport/gatewayresponder.h" +#include "transport/logging.h" #include "Swiften/EventLoop/SimpleEventLoop.h" #include #include @@ -235,71 +236,7 @@ int main(int argc, char **argv) } #endif - if (CONFIG_STRING(&config, "logging.config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifdef WIN32 - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.config")); - - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef WIN32 - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - - std::string dir; - BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) { - if (boost::ends_with(prop, ".File")) { - log4cxx::helpers::Transcoder::encode(p.get(prop), dir); - boost::replace_all(dir, "${jid}", jid); - break; - } - } - - if (!dir.empty()) { - // create directories - try { - boost::filesystem::create_directories( - boost::filesystem::path(dir).parent_path().string() - ); - } - catch (...) { - std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n"; - return 1; - } - -#ifndef WIN32 - if (!CONFIG_STRING(&config, "service.group").empty() && !CONFIG_STRING(&config, "service.user").empty()) { - struct group *gr; - if ((gr = getgrnam(CONFIG_STRING(&config, "service.group").c_str())) == NULL) { - std::cerr << "Invalid service.group name " << CONFIG_STRING(&config, "service.group") << "\n"; - return 1; - } - struct passwd *pw; - if ((pw = getpwnam(CONFIG_STRING(&config, "service.user").c_str())) == NULL) { - std::cerr << "Invalid service.user name " << CONFIG_STRING(&config, "service.user") << "\n"; - return 1; - } - chown(dir.c_str(), pw->pw_uid, gr->gr_gid); - } - -#endif - } - - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initMainLogging(&config); #ifndef WIN32 if (!CONFIG_STRING(&config, "service.group").empty() ||!CONFIG_STRING(&config, "service.user").empty() ) { @@ -352,11 +289,12 @@ int main(int argc, char **argv) std::string error; StorageBackend *storageBackend = StorageBackend::createBackend(&config, error); if (storageBackend == NULL) { - std::cerr << error << "\n"; - return -2; + if (!error.empty()) { + std::cerr << error << "\n"; + return -2; + } } - - if (!storageBackend->connect()) { + else if (!storageBackend->connect()) { std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; return -1; } @@ -399,4 +337,5 @@ int main(int argc, char **argv) delete storageBackend; delete factories; + return 0; } diff --git a/src/logging.cpp b/src/logging.cpp new file mode 100644 index 00000000..19dee6cf --- /dev/null +++ b/src/logging.cpp @@ -0,0 +1,132 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include "transport/logging.h" +#include "transport/config.h" +#include +#include +#include +#include + +#include "log4cxx/logger.h" +#include "log4cxx/consoleappender.h" +#include "log4cxx/patternlayout.h" +#include "log4cxx/propertyconfigurator.h" +#include "log4cxx/helpers/properties.h" +#include "log4cxx/helpers/fileinputstream.h" +#include "log4cxx/helpers/transcoder.h" +#include +#include + +#ifndef WIN32 +#include "sys/signal.h" +#include +#include +#include +#include "libgen.h" +#else +#include +#endif + +using namespace boost::filesystem; +using namespace log4cxx; + +namespace Transport { + +namespace Logging { + +static LoggerPtr root; + +static void initLogging(Config *config, std::string key) { + if (CONFIG_STRING(config, key).empty()) { + root = log4cxx::Logger::getRootLogger(); +#ifdef WIN32 + root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); +#else + root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); +#endif + } + else { + log4cxx::helpers::Properties p; + log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(config, key)); + + p.load(istream); + LogString pid, jid; + log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); + log4cxx::helpers::Transcoder::decode(CONFIG_STRING(config, "service.jid"), jid); +#ifdef WIN32 + p.setProperty(L"pid", pid); + p.setProperty(L"jid", jid); +#else + p.setProperty("pid", pid); + p.setProperty("jid", jid); +#endif + + std::string dir; + BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) { + if (boost::ends_with(prop, ".File")) { + log4cxx::helpers::Transcoder::encode(p.get(prop), dir); + boost::replace_all(dir, "${jid}", jid); + break; + } + } + + if (!dir.empty()) { + // create directories + try { + boost::filesystem::create_directories( + boost::filesystem::path(dir).parent_path().string() + ); + } + catch (...) { + std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n"; + } + +#ifndef WIN32 + if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) { + struct group *gr; + if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) { + std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n"; + } + struct passwd *pw; + if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) { + std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n"; + } + chown(dir.c_str(), pw->pw_uid, gr->gr_gid); + } + +#endif + } + + log4cxx::PropertyConfigurator::configure(p); + } +} + +void initBackendLogging(Config *config) { + initLogging(config, "logging.backend_config"); +} + +void initMainLogging(Config *config) { + initLogging(config, "logging.config"); +} + +} + +} diff --git a/src/storagebackend.cpp b/src/storagebackend.cpp new file mode 100644 index 00000000..17657a48 --- /dev/null +++ b/src/storagebackend.cpp @@ -0,0 +1,49 @@ +#include "transport/storagebackend.h" +#include "transport/config.h" + +#include "transport/sqlite3backend.h" +#include "transport/mysqlbackend.h" +#include "transport/pqxxbackend.h" + +namespace Transport { + +StorageBackend *StorageBackend::createBackend(Config *config, std::string &error) { + StorageBackend *storageBackend = NULL; +#ifdef WITH_SQLITE + if (CONFIG_STRING(config, "database.type") == "sqlite3") { + storageBackend = new SQLite3Backend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "sqlite3") { + error = "Libtransport is not compiled with sqlite3 backend support."; + } +#endif + +#ifdef WITH_MYSQL + if (CONFIG_STRING(config, "database.type") == "mysql") { + storageBackend = new MySQLBackend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "mysql") { + error = "Spectrum2 is not compiled with mysql backend support."; + } +#endif + +#ifdef WITH_PQXX + if (CONFIG_STRING(config, "database.type") == "pqxx") { + storageBackend = new PQXXBackend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "pqxx") { + error = "Spectrum2 is not compiled with pqxx backend support."; + } +#endif + + if (CONFIG_STRING(config, "database.type") != "mysql" && CONFIG_STRING(config, "database.type") != "sqlite3" + && CONFIG_STRING(config, "database.type") != "pqxx" && CONFIG_STRING(config, "database.type") != "none") { + error = "Unknown storage backend " + CONFIG_STRING(config, "database.type"); + } + return storageBackend; +} + +} From 23457aedcfa77ae0e22cde112eadc3d086c677e4 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 15 Mar 2012 08:09:41 +0100 Subject: [PATCH 35/46] GET_PROPERTY in Skype --- backends/skype/main.cpp | 93 ++++++++++++++++------------------------- spectrum/src/sample.cfg | 2 +- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 40118f67..6731b96b 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -36,6 +36,10 @@ using namespace Transport; class SpectrumNetworkPlugin; +#define GET_RESPONSE_DATA(RESP, DATA) (RESP.find(DATA) != std::string::npos ? RESP.substr(RESP.find(DATA) + strlen(DATA) + 1) : ""); +#define GET_PROPERTY(VAR, OBJ, WHICH, PROP) std::string VAR = sk->send_command(std::string("GET ") + OBJ + " " + WHICH + " " + PROP); \ + VAR = GET_RESPONSE_DATA(VAR, PROP); + SpectrumNetworkPlugin *np; @@ -292,7 +296,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { std::cout << skype->getUsername() << " " << name << "\n"; if (skype->getUsername() == name) { alias = skype->send_command("GET PROFILE FULLNAME"); - alias = alias.substr(17); + alias = GET_RESPONSE_DATA(alias, "FULLNAME") } handleVCard(user, id, legacyName, "", alias, photo); } @@ -504,7 +508,7 @@ bool Skype::loadSkypeBuddies() { std::string re = send_command("NAME Spectrum"); if (m_counter++ > 15) { LOG4CXX_ERROR(logger, "Logging out, because we tried to connect the Skype over DBUS 15 times without success"); - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not read."); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon."); close(fd_output); logout(); return FALSE; @@ -518,7 +522,7 @@ bool Skype::loadSkypeBuddies() { if (send_command("PROTOCOL 7") != "PROTOCOL 7") { LOG4CXX_ERROR(logger, "PROTOCOL 7 failed, logging out"); - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready"); + np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon."); logout(); return FALSE; } @@ -527,20 +531,22 @@ bool Skype::loadSkypeBuddies() { std::map group_map; std::string groups = send_command("SEARCH GROUPS CUSTOM"); - groups = groups.substr(groups.find(' ') + 1); - std::vector grps; - boost::split(grps, groups, boost::is_any_of(",")); - BOOST_FOREACH(std::string grp, grps) { - std::vector data; - std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME"); - boost::split(data, name, boost::is_any_of(" ")); - name = name.substr(name.find("DISPLAYNAME") + 12); + if (groups.find(' ') != std::string::npos) { + groups = groups.substr(groups.find(' ') + 1); + std::vector grps; + boost::split(grps, groups, boost::is_any_of(",")); + BOOST_FOREACH(std::string grp, grps) { + std::vector data; + std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME"); + boost::split(data, name, boost::is_any_of(" ")); + name = GET_RESPONSE_DATA(name, "DISPLAYNAME"); - std::string users = send_command("GET GROUP " + data[1] + " USERS"); - users = name.substr(name.find("USERS") + 6); - boost::split(data, users, boost::is_any_of(",")); - BOOST_FOREACH(std::string u, data) { - group_map[u] = grp; + std::string users = send_command("GET GROUP " + data[1] + " USERS"); + users = GET_RESPONSE_DATA(users, "USERS"); + boost::split(data, users, boost::is_any_of(",")); + BOOST_FOREACH(std::string u, data) { + group_map[u] = grp; + } } } @@ -650,70 +656,49 @@ static void handle_skype_message(std::string &message, Skype *sk) { } else { pbnetwork::StatusType status = getStatus(cmd[3]); - std::string mood_text = sk->send_command("GET USER " + cmd[1] + " MOOD_TEXT"); - mood_text = mood_text.substr(mood_text.find("MOOD_TEXT") + 10); - - std::string alias = sk->send_command("GET USER " + cmd[1] + " FULLNAME"); - alias = alias.substr(alias.find("FULLNAME") + 9); + GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); + GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME"); std::vector groups; np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text); } } else if (cmd[2] == "MOOD_TEXT") { - std::string st = sk->send_command("GET USER " + cmd[1] + " ONLINESTATUS"); - st = st.substr(st.find("ONLINESTATUS") + 13); + GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); pbnetwork::StatusType status = getStatus(st); - std::string mood_text = message.substr(message.find("MOOD_TEXT") + 10); + std::string mood_text = GET_RESPONSE_DATA(message, "MOOD_TEXT"); std::vector groups; np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text); } else if (cmd[2] == "BUDDYSTATUS" && cmd[3] == "3") { - std::string st = sk->send_command("GET USER " + cmd[1] + " ONLINESTATUS"); - st = st.substr(st.find("ONLINESTATUS") + 13); + GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); + GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); pbnetwork::StatusType status = getStatus(st); - std::string mood_text = message.substr(message.find("MOOD_TEXT") + 10); - std::vector groups; np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text); } else if (cmd[2] == "FULLNAME") { - std::string st = sk->send_command("GET USER " + cmd[1] + " ONLINESTATUS"); - st = st.substr(st.find("ONLINESTATUS") + 13); + GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME"); + GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); + GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); pbnetwork::StatusType status = getStatus(st); - std::string mood_text = sk->send_command("GET USER " + cmd[1] + " MOOD_TEXT"); - mood_text = mood_text.substr(mood_text.find("MOOD_TEXT") + 10); - - std::string alias = message.substr(message.find("FULLNAME") + 9); - std::vector groups; np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text); } } else if (cmd[0] == "CHATMESSAGE") { if (cmd[3] == "RECEIVED") { - std::string body = sk->send_command("GET CHATMESSAGE " + cmd[1] + " BODY"); - body = body.substr(body.find("BODY") + 5); + GET_PROPERTY(body, "CHATMESSAGE", cmd[1], "BODY"); + GET_PROPERTY(from_handle, "CHATMESSAGE", cmd[1], "FROM_HANDLE"); - std::string chatname = sk->send_command("GET CHATMESSAGE " + cmd[1] + " CHATNAME"); - size_t start = chatname.find("$") + 1; - size_t len = chatname.find(";") - start; - std::string from = chatname.substr(start, len); - - std::string from_handle = sk->send_command("GET CHATMESSAGE " + cmd[1] + " FROM_HANDLE"); - from_handle = from_handle.substr(from_handle.find("FROM_HANDLE") + 12); - -// if (from_handle != sk->getUsername()) { - from = from_handle; -// } if (from_handle == sk->getUsername()) return; - np->handleMessage(sk->getUser(), from, body); + np->handleMessage(sk->getUser(), from_handle, body); } } else if (cmd[0] == "CALL") { @@ -721,17 +706,13 @@ static void handle_skype_message(std::string &message, Skype *sk) { if (cmd[2] == "STATUS") { if (cmd[3] == "RINGING" || cmd[3] == "MISSED") { // handle only incoming calls - std::string type = sk->send_command("GET CALL " + cmd[1] + " TYPE"); - type = type.substr(type.find("TYPE") + 5); + GET_PROPERTY(type, "CALL", cmd[1], "TYPE"); if (type.find("INCOMING") != 0) { return; } - std::string from = sk->send_command("GET CALL " + cmd[1] + " PARTNER_HANDLE"); - from = from.substr(from.find("PARTNER_HANDLE") + 15); - - std::string dispname = sk->send_command("GET CALL " + cmd[1] + " PARTNER_DISPNAME"); - dispname = dispname.substr(dispname.find("PARTNER_DISPNAME") + 17); + GET_PROPERTY(from, "CALL", cmd[1], "PARTNER_HANDLE"); + GET_PROPERTY(dispname, "CALL", cmd[1], "PARTNER_DISPNAME"); if (cmd[3] == "RINGING") { np->handleMessage(sk->getUser(), from, "User " + dispname + " is calling you."); diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index 57e601eb..78c22a80 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -7,7 +7,7 @@ server_mode = 1 backend_host=localhost pidfile=./test.pid # < this option doesn't work yet -backend_port=10001 +#backend_port=10001 admin_username=admin admin_password=test #cert=server.pfx #patch to PKCS#12 certificate From c4e327423f743994bb4dd0b80e355dfb530dd3d6 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 15 Mar 2012 09:06:52 +0100 Subject: [PATCH 36/46] inform skype that we seen the received message --- backends/skype/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 6731b96b..176f1110 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -699,6 +699,8 @@ static void handle_skype_message(std::string &message, Skype *sk) { return; np->handleMessage(sk->getUser(), from_handle, body); + + sk->send_command("SET CHATMESSAGE " + cmd[1] + " SEEN"); } } else if (cmd[0] == "CALL") { From 19ebf447d6dad28ddb5b3c6b19a6321c5175c2c9 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 16 Mar 2012 10:37:40 +0100 Subject: [PATCH 37/46] GET_RESPONSE_DATA fix --- backends/skype/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 176f1110..2e39124c 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -36,7 +36,7 @@ using namespace Transport; class SpectrumNetworkPlugin; -#define GET_RESPONSE_DATA(RESP, DATA) (RESP.find(DATA) != std::string::npos ? RESP.substr(RESP.find(DATA) + strlen(DATA) + 1) : ""); +#define GET_RESPONSE_DATA(RESP, DATA) ((RESP.find(std::string(DATA) + " ") != std::string::npos) ? RESP.substr(RESP.find(DATA) + strlen(DATA) + 1) : ""); #define GET_PROPERTY(VAR, OBJ, WHICH, PROP) std::string VAR = sk->send_command(std::string("GET ") + OBJ + " " + WHICH + " " + PROP); \ VAR = GET_RESPONSE_DATA(VAR, PROP); From 8a471b73f7d1ab6ede685ea041987463237be23c Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 16 Mar 2012 12:00:55 +0100 Subject: [PATCH 38/46] Changelog --- ChangeLog | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d731f169..69a7fd12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,22 @@ Version 2.0.0-beta2 (2012-XX-XX): General: - * Fixed bug when Roster Item Exchange and subscribe stanzas were send + * Fixed bug when Roster Item Exchange and subscribe stanzas were sent repeatedly. + * Backends related logs now contain the backend PID. * Fixed username_mask setting. - * Added new fields into statistics. + * Added new fields into statistics (backends_crashed, messages related + stats). libpurple: * Added support for MUC for prpl-jabber protocol. Skype: + * Memory usage statistic now includes the Skype client. * Fixed logging issue when the logs were not stored in the proper instance directory. * Skype backend includes also Skype client memory usage into the account. + * Working buddies adding/removing. + * Information about missed call is now forwarded to XMPP user. Version 2.0.0-beta (2012-02-28): General: From dd8627bbfef108501b121287bd1ec45418293337 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 16 Mar 2012 12:27:59 +0100 Subject: [PATCH 39/46] little cleanup in libpurple backend --- backends/libpurple/main.cpp | 458 ++--------------------------------- backends/libpurple/utils.cpp | 129 ++++++++++ backends/libpurple/utils.h | 30 +++ 3 files changed, 176 insertions(+), 441 deletions(-) create mode 100644 backends/libpurple/utils.cpp create mode 100644 backends/libpurple/utils.h diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index ce8ad051..39c53627 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -1,3 +1,5 @@ +#include "utils.h" + #include "glib.h" #include "purple.h" #include @@ -12,25 +14,7 @@ #include "log4cxx/helpers/properties.h" #include "log4cxx/helpers/fileinputstream.h" #include "log4cxx/helpers/transcoder.h" -#ifndef WIN32 -#include "sys/wait.h" -#include "sys/signal.h" -#include -#include -#include -#include -#include -#include -#include "sys/socket.h" -#include -#include -#include -#else -#include -#define getpid _getpid -#define ssize_t SSIZE_T -#include "win32/win32dep.h" -#endif + // #include "valgrind/memcheck.h" #include "malloc.h" #include @@ -44,7 +28,7 @@ using namespace log4cxx; static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple"); static LoggerPtr logger = log4cxx::Logger::getLogger("backend"); -int m_sock; +int main_socket; static int writeInput; using namespace Transport; @@ -107,13 +91,8 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key #define KEYFILE_BOOL(CAT, KEY) g_key_file_get_boolean(keyfile, CAT, KEY, 0) -static gboolean nodaemon = FALSE; -static gchar *logfile = NULL; -static gchar *lock_file = NULL; static gchar *host = NULL; static int port = 10000; -static gboolean ver = FALSE; -static gboolean list_purple_settings = FALSE; struct FTData { unsigned long id; @@ -122,121 +101,12 @@ struct FTData { }; static GOptionEntry options_entries[] = { - { "nodaemon", 'n', 0, G_OPTION_ARG_NONE, &nodaemon, "Disable background daemon mode", NULL }, - { "logfile", 'l', 0, G_OPTION_ARG_STRING, &logfile, "Set file to log", NULL }, - { "pidfile", 'p', 0, G_OPTION_ARG_STRING, &lock_file, "File where to write transport PID", NULL }, - { "version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Shows Spectrum version", NULL }, - { "list-purple-settings", 's', 0, G_OPTION_ARG_NONE, &list_purple_settings, "Lists purple settings which can be used in config file", NULL }, { "host", 'h', 0, G_OPTION_ARG_STRING, &host, "Host to connect to", NULL }, { "port", 'p', 0, G_OPTION_ARG_INT, &port, "Port to connect to", NULL }, { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL } }; static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info); -static GHashTable *ui_info = NULL; - -static GHashTable *spectrum_ui_get_info(void) -{ - if(NULL == ui_info) { - ui_info = g_hash_table_new(g_str_hash, g_str_equal); - - g_hash_table_insert(ui_info, g_strdup("name"), g_strdup("Spectrum")); - g_hash_table_insert(ui_info, g_strdup("version"), g_strdup("0.5")); - g_hash_table_insert(ui_info, g_strdup("website"), g_strdup("http://spectrum.im")); - g_hash_table_insert(ui_info, g_strdup("dev_website"), g_strdup("http://spectrum.im")); - g_hash_table_insert(ui_info, g_strdup("client_type"), g_strdup("pc")); - - /* - * This is the client key for "Pidgin." It is owned by the AIM - * account "markdoliner." Please don't use this key for other - * applications. You can either not specify a client key, in - * which case the default "libpurple" key will be used, or you - * can register for your own client key at - * http://developer.aim.com/manageKeys.jsp - */ - g_hash_table_insert(ui_info, g_strdup("prpl-aim-clientkey"), g_strdup("ma1cSASNCKFtrdv9")); - g_hash_table_insert(ui_info, g_strdup("prpl-icq-clientkey"), g_strdup("ma1cSASNCKFtrdv9")); - - /* - * This is the distid for Pidgin, given to us by AOL. Please - * don't use this for other applications. You can just not - * specify a distid and libpurple will use a default. - */ - g_hash_table_insert(ui_info, g_strdup("prpl-aim-distid"), GINT_TO_POINTER(1550)); - g_hash_table_insert(ui_info, g_strdup("prpl-icq-distid"), GINT_TO_POINTER(1550)); - } - - return ui_info; -} - -static gboolean -badchar(char c) -{ - switch (c) { - case ' ': - case ',': - case '\0': - case '\n': - case '\r': - case '<': - case '>': - case '"': - return TRUE; - default: - return FALSE; - } -} - -static gboolean -badentity(const char *c) -{ - if (!g_ascii_strncasecmp(c, "<", 4) || - !g_ascii_strncasecmp(c, ">", 4) || - !g_ascii_strncasecmp(c, """, 6)) { - return TRUE; - } - return FALSE; -} - -static const char * -process_link(GString *ret, - const char *start, const char *c, - int matchlen, - const char *urlprefix, - int inside_paren) -{ - char *url_buf; - const char *t; - - for (t = c;; t++) { - if (!badchar(*t) && !badentity(t)) - continue; - - if (t - c == matchlen) - break; - - if (*t == ',' && *(t + 1) != ' ') { - continue; - } - - if (t > start && *(t - 1) == '.') - t--; - if (t > start && *(t - 1) == ')' && inside_paren > 0) - t--; - - url_buf = g_strndup(c, t - c); -// tmpurlbuf = purple_unescape_html(url_buf); -// std::cout << url_buf << "\n"; - g_string_append_printf(ret, "%s", - urlprefix, - url_buf, url_buf); -// g_free(tmpurlbuf); - g_free(url_buf); - return t; - } - - return c; -} static gboolean ft_ui_ready(void *data) { PurpleXfer *xfer = (PurpleXfer *) data; @@ -246,184 +116,6 @@ static gboolean ft_ui_ready(void *data) { return FALSE; } -static char * -spectrum_markup_linkify(const char *text) -{ - const char *c, *t, *q = NULL; - char *tmpurlbuf, *url_buf; - gunichar g; - gboolean inside_html = FALSE; - int inside_paren = 0; - GString *ret; - - if (text == NULL) - return NULL; - - ret = g_string_new(""); - - c = text; - while (*c) { - - if(*c == '(' && !inside_html) { - inside_paren++; - ret = g_string_append_c(ret, *c); - c++; - } - - if(inside_html) { - if(*c == '>') { - inside_html = FALSE; - } else if(!q && (*c == '\"' || *c == '\'')) { - q = c; - } else if(q) { - if(*c == *q) - q = NULL; - } - } else if(*c == '<') { - inside_html = TRUE; - if (!g_ascii_strncasecmp(c, "", 3)) { - inside_html = FALSE; - break; - } - ret = g_string_append_c(ret, *c); - c++; - if (!(*c)) - break; - } - } - } else if (!g_ascii_strncasecmp(c, "http://", 7)) { - c = process_link(ret, text, c, 7, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "https://", 8)) { - c = process_link(ret, text, c, 8, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "ftp://", 6)) { - c = process_link(ret, text, c, 6, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "sftp://", 7)) { - c = process_link(ret, text, c, 7, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "file://", 7)) { - c = process_link(ret, text, c, 7, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "www.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) { - c = process_link(ret, text, c, 4, "http://", inside_paren); - } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) { - c = process_link(ret, text, c, 4, "ftp://", inside_paren); - } else if (!g_ascii_strncasecmp(c, "xmpp:", 5) && (c == text || badchar(c[-1]) || badentity(c-1))) { - c = process_link(ret, text, c, 5, "", inside_paren); - } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) { - t = c; - while (1) { - if (badchar(*t) || badentity(t)) { - const char *d; - if (t - c == 7) { - break; - } - if (t > text && *(t - 1) == '.') - t--; - if ((d = strstr(c + 7, "?")) != NULL && d < t) - url_buf = g_strndup(c + 7, d - c - 7); - else - url_buf = g_strndup(c + 7, t - c - 7); - if (!purple_email_is_valid(url_buf)) { - g_free(url_buf); - break; - } - g_free(url_buf); - url_buf = g_strndup(c, t - c); -// tmpurlbuf = purple_unescape_html(url_buf); - g_string_append_printf(ret, "%s", - url_buf, url_buf); - g_free(url_buf); -// g_free(tmpurlbuf); - c = t; - break; - } - t++; - } - } else if (c != text && (*c == '@')) { - int flag; - GString *gurl_buf = NULL; - const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0"; - - if (strchr(illegal_chars,*(c - 1)) || strchr(illegal_chars, *(c + 1))) - flag = 0; - else { - flag = 1; - gurl_buf = g_string_new(""); - } - - t = c; - while (flag) { - /* iterate backwards grabbing the local part of an email address */ - g = g_utf8_get_char(t); - if (badchar(*t) || (g >= 127) || (*t == '(') || - ((*t == ';') && ((t > (text+2) && (!g_ascii_strncasecmp(t - 3, "<", 4) || - !g_ascii_strncasecmp(t - 3, ">", 4))) || - (t > (text+4) && (!g_ascii_strncasecmp(t - 5, """, 6)))))) { - /* local part will already be part of ret, strip it out */ - ret = g_string_truncate(ret, ret->len - (c - t)); - ret = g_string_append_unichar(ret, g); - break; - } else { - g_string_prepend_unichar(gurl_buf, g); - t = g_utf8_find_prev_char(text, t); - if (t < text) { - ret = g_string_assign(ret, ""); - break; - } - } - } - - t = g_utf8_find_next_char(c, NULL); - - while (flag) { - /* iterate forwards grabbing the domain part of an email address */ - g = g_utf8_get_char(t); - if (badchar(*t) || (g >= 127) || (*t == ')') || badentity(t)) { - char *d; - - url_buf = g_string_free(gurl_buf, FALSE); - - /* strip off trailing periods */ - if (strlen(url_buf) > 0) { - for (d = url_buf + strlen(url_buf) - 1; *d == '.'; d--, t--) - *d = '\0'; - } - - tmpurlbuf = purple_unescape_html(url_buf); - if (purple_email_is_valid(tmpurlbuf)) { - g_string_append_printf(ret, "%s", - url_buf, url_buf); - } else { - g_string_append(ret, url_buf); - } - g_free(url_buf); - g_free(tmpurlbuf); - c = t; - - break; - } else { - g_string_append_unichar(gurl_buf, g); - t = g_utf8_find_next_char(t, NULL); - } - } - } - - if(*c == ')' && !inside_html) { - inside_paren--; - ret = g_string_append_c(ret, *c); - c++; - } - - if (*c == 0) - break; - - ret = g_string_append_c(ret, *c); - c++; - - } - return g_string_free(ret, FALSE); -} - struct authRequest { PurpleAccountRequestAuthorizationCb authorize_cb; PurpleAccountRequestAuthorizationCb deny_cb; @@ -509,13 +201,13 @@ static std::string getAlias(PurpleBuddy *m_buddy) { class SpectrumNetworkPlugin : public NetworkPlugin { public: - SpectrumNetworkPlugin(const std::string &host, int port) : NetworkPlugin() { + SpectrumNetworkPlugin() : NetworkPlugin() { } void handleExitRequest() { LOG4CXX_INFO(logger, "Exiting..."); - exit(1); + exit(0); } void getProtocolAndName(const std::string &legacyName, std::string &name, std::string &protocol) { @@ -597,7 +289,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { PurpleAccount *account = NULL; - + std::string name; std::string protocol; getProtocolAndName(legacyName, name, protocol); @@ -614,7 +306,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin { return; } - if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL) { LOG4CXX_INFO(logger, "Using previously created account with name '" << name.c_str() << "' and protocol '" << protocol << "'"); account = purple_accounts_find(name.c_str(), protocol.c_str()); @@ -637,11 +328,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin { setDefaultAccountOptions(account); + // Enable account + privacy lists purple_account_set_enabled(account, "spectrum", TRUE); if (KEYFILE_BOOL("service", "enable_privacy_lists")) { purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS); } + // Set the status const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE); if (status_type != NULL) { purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL); @@ -661,50 +354,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin { m_accounts.erase(account); purple_accounts_delete(account); -// -// // Remove conversations. -// // This has to be called before m_account->ui_data = NULL;, because it uses -// // ui_data to call SpectrumMessageHandler::purpleConversationDestroyed() callback. -// GList *iter; -// for (iter = purple_get_conversations(); iter; ) { -// PurpleConversation *conv = (PurpleConversation*) iter->data; -// iter = iter->next; -// if (purple_conversation_get_account(conv) == account) -// purple_conversation_destroy(conv); -// } -// -// g_free(account->ui_data); -// account->ui_data = NULL; -// m_accounts.erase(account); -// -// purple_notify_close_with_handle(account); -// purple_request_close_with_handle(account); -// -// purple_accounts_remove(account); -// -// GSList *buddies = purple_find_buddies(account, NULL); -// while(buddies) { -// PurpleBuddy *b = (PurpleBuddy *) buddies->data; -// purple_blist_remove_buddy(b); -// buddies = g_slist_delete_link(buddies, buddies); -// } -// -// /* Remove any open conversation for this account */ -// for (GList *it = purple_get_conversations(); it; ) { -// PurpleConversation *conv = (PurpleConversation *) it->data; -// it = it->next; -// if (purple_conversation_get_account(conv) == account) -// purple_conversation_destroy(conv); -// } -// -// /* Remove this account's pounces */ -// // purple_pounce_destroy_all_by_account(account); -// -// /* This will cause the deletion of an old buddy icon. */ -// purple_buddy_icons_set_account_icon(account, NULL, 0); -// -// purple_account_destroy(account); - // force returning of memory chunks allocated by libxml2 to kernel #ifndef WIN32 malloc_trim(0); #endif @@ -1002,9 +651,9 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } void sendData(const std::string &string) { - write(m_sock, string.c_str(), string.size()); + write(main_socket, string.c_str(), string.size()); if (writeInput == 0) - writeInput = purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL); + writeInput = purple_input_add(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL); } void readyForData() { @@ -1864,9 +1513,8 @@ static bool initPurple() { remove("./accounts.xml"); remove("./blist.xml"); -// if (m_configuration.logAreas & LOG_AREA_PURPLE) - purple_debug_set_ui_ops(&debugUiOps); - purple_debug_set_verbose(true); + purple_debug_set_ui_ops(&debugUiOps); + purple_debug_set_verbose(true); purple_core_set_ui_ops(&coreUiOps); if (KEYFILE_STRING("service", "eventloop") == "libev") { @@ -1930,50 +1578,7 @@ static bool initPurple() { } return ret; } -#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 - -static int create_socket(char *host, int portno) { - struct sockaddr_in serv_addr; - - int m_sock = socket(AF_INET, SOCK_STREAM, 0); - memset((char *) &serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(portno); - - hostent *hos; // Resolve name - if ((hos = gethostbyname(host)) == NULL) { - // strerror() will not work for gethostbyname() and hstrerror() - // is supposedly obsolete - exit(1); - } - serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]); - - if (connect(m_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - close(m_sock); - m_sock = 0; - } - - int flags = fcntl(m_sock, F_GETFL); - flags |= O_NONBLOCK; - fcntl(m_sock, F_SETFL, flags); - return m_sock; -} static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond) { if (cond & PURPLE_INPUT_READ) { @@ -2002,17 +1607,10 @@ int main(int argc, char **argv) { context = g_option_context_new("config_file_name or profile name"); g_option_context_add_main_entries(context, options_entries, ""); if (!g_option_context_parse (context, &argc, &argv, &error)) { - std::cout << "option parsing failed: " << error->message << "\n"; + std::cerr << "option parsing failed: " << error->message << "\n"; return -1; } - if (ver) { -// std::cout << VERSION << "\n"; - std::cout << "verze\n"; - g_option_context_free(context); - return 0; - } - if (argc != 2) { #ifdef WIN32 std::cout << "Usage: spectrum.exe \n"; @@ -2036,27 +1634,6 @@ int main(int argc, char **argv) { g_option_context_free(context); return -1; } -// -// if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) { -// std::cout << "SIGINT handler can't be set\n"; -// g_option_context_free(context); -// return -1; -// } -// -// if (signal(SIGTERM, spectrum_sigterm_handler) == SIG_ERR) { -// std::cout << "SIGTERM handler can't be set\n"; -// g_option_context_free(context); -// return -1; -// } -// -// struct sigaction sa; -// memset(&sa, 0, sizeof(sa)); -// sa.sa_handler = spectrum_sighup_handler; -// if (sigaction(SIGHUP, &sa, NULL)) { -// std::cout << "SIGHUP handler can't be set\n"; -// g_option_context_free(context); -// return -1; -// } #endif keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, argv[1], (GKeyFileFlags) 0, 0)) { @@ -2091,12 +1668,11 @@ int main(int argc, char **argv) { initPurple(); - m_sock = create_socket(host, port); - - purple_input_add(m_sock, PURPLE_INPUT_READ, &transportDataReceived, NULL); + main_socket = create_socket(host, port); + purple_input_add(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL); purple_timeout_add_seconds(30, pingTimeout, NULL); - np = new SpectrumNetworkPlugin(host, port); + np = new SpectrumNetworkPlugin(); bool libev = KEYFILE_STRING("service", "eventloop") == "libev"; GMainLoop *m_loop; diff --git a/backends/libpurple/utils.cpp b/backends/libpurple/utils.cpp new file mode 100644 index 00000000..417ad67d --- /dev/null +++ b/backends/libpurple/utils.cpp @@ -0,0 +1,129 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include "utils.h" + +#include "glib.h" +#include "purple.h" +#include +#include + +#include "errno.h" + +#ifndef WIN32 +#include "sys/wait.h" +#include "sys/signal.h" +#include +#include +#include +#include +#include +#include +#include "sys/socket.h" +#include +#include +#include +#else +#include +#define getpid _getpid +#define ssize_t SSIZE_T +#include "win32/win32dep.h" +#endif + +static GHashTable *ui_info = NULL; + +GHashTable *spectrum_ui_get_info(void) +{ + if(NULL == ui_info) { + ui_info = g_hash_table_new(g_str_hash, g_str_equal); + + g_hash_table_insert(ui_info, g_strdup("name"), g_strdup("Spectrum")); + g_hash_table_insert(ui_info, g_strdup("version"), g_strdup("0.5")); + g_hash_table_insert(ui_info, g_strdup("website"), g_strdup("http://spectrum.im")); + g_hash_table_insert(ui_info, g_strdup("dev_website"), g_strdup("http://spectrum.im")); + g_hash_table_insert(ui_info, g_strdup("client_type"), g_strdup("pc")); + + /* + * This is the client key for "Pidgin." It is owned by the AIM + * account "markdoliner." Please don't use this key for other + * applications. You can either not specify a client key, in + * which case the default "libpurple" key will be used, or you + * can register for your own client key at + * http://developer.aim.com/manageKeys.jsp + */ + g_hash_table_insert(ui_info, g_strdup("prpl-aim-clientkey"), g_strdup("ma1cSASNCKFtrdv9")); + g_hash_table_insert(ui_info, g_strdup("prpl-icq-clientkey"), g_strdup("ma1cSASNCKFtrdv9")); + + /* + * This is the distid for Pidgin, given to us by AOL. Please + * don't use this for other applications. You can just not + * specify a distid and libpurple will use a default. + */ + g_hash_table_insert(ui_info, g_strdup("prpl-aim-distid"), GINT_TO_POINTER(1550)); + g_hash_table_insert(ui_info, g_strdup("prpl-icq-distid"), GINT_TO_POINTER(1550)); + } + + return ui_info; +} + +#ifndef WIN32 +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 create_socket(char *host, int portno) { + struct sockaddr_in serv_addr; + + int main_socket = socket(AF_INET, SOCK_STREAM, 0); + memset((char *) &serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(portno); + + hostent *hos; // Resolve name + if ((hos = gethostbyname(host)) == NULL) { + // strerror() will not work for gethostbyname() and hstrerror() + // is supposedly obsolete + exit(1); + } + serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]); + + if (connect(main_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + close(main_socket); + main_socket = 0; + } + + int flags = fcntl(main_socket, F_GETFL); + flags |= O_NONBLOCK; + fcntl(main_socket, F_SETFL, flags); + return main_socket; +} diff --git a/backends/libpurple/utils.h b/backends/libpurple/utils.h new file mode 100644 index 00000000..2055b6c1 --- /dev/null +++ b/backends/libpurple/utils.h @@ -0,0 +1,30 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#pragma once + +#include "purple.h" + +#ifndef WIN32 +void spectrum_sigchld_handler(int sig); +#endif + +int create_socket(char *host, int portno); +GHashTable *spectrum_ui_get_info(void); \ No newline at end of file From ab72dd03c64ac9e5ab868edec78d33831ef7c794 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Mon, 19 Mar 2012 15:09:55 +0100 Subject: [PATCH 40/46] new sample.cfg --- spectrum/src/sample.cfg | 12 +++--------- src/user.cpp | 1 + 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index 78c22a80..acdd93f5 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -13,22 +13,16 @@ admin_password=test #cert=server.pfx #patch to PKCS#12 certificate #cert_password=test #password to that certificate if any users_per_backend=10 -#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend -#backend=/home/hanzz/code/libtransport/backends/smstools3/spectrum2_smstools3_backend -#backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe -#backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend -#backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend -backend=/usr/bin/xvfb-run -n BACKEND_ID -s "-screen 0 10x10x8" -f /tmp/x-skype-gw /home/hanzz/code/libtransport/backends/skype/spectrum2_skype_backend +backend=../..//backends/libpurple/spectrum2_libpurple_backend +protocol=prpl-xmpp #protocol=prpl-msn -protocol=any +#protocol=any #protocol=prpl-icq -irc_server=irc.freenode.org working_dir=./ [backend] #default_avatar=catmelonhead.jpg #no_vcard_fetch=true -incoming_dir=/var/spool/sms/incoming [logging] #config=logging.cfg # log4cxx/log4j logging configuration file diff --git a/src/user.cpp b/src/user.cpp index 8cfcd0ea..0baedfa9 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -210,6 +210,7 @@ void User::handlePresence(Swift::Presence::ref presence) { } } } + bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; if (isMUC) { if (presence->getType() == Swift::Presence::Unavailable) { From a10cccd1e1c09ad3fc8121dc9a244e1fd847b32a Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Tue, 20 Mar 2012 08:12:10 +0100 Subject: [PATCH 41/46] Fixed skype crash --- backends/skype/main.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 2e39124c..ccb60559 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -538,6 +538,11 @@ bool Skype::loadSkypeBuddies() { BOOST_FOREACH(std::string grp, grps) { std::vector data; std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME"); + + if (name.find("ERROR") == 0) { + continue; + } + boost::split(data, name, boost::is_any_of(" ")); name = GET_RESPONSE_DATA(name, "DISPLAYNAME"); @@ -619,7 +624,7 @@ std::string Skype::send_command(const std::string &message) { // int message_num; // gchar error_return[30]; - LOG4CXX_INFO(logger, "Sending: " << message); + LOG4CXX_INFO(logger, "Sending: '" << message << "'"); if (!dbus_g_proxy_call (m_proxy, "Invoke", &error, G_TYPE_STRING, message.c_str(), G_TYPE_INVALID, G_TYPE_STRING, &str, G_TYPE_INVALID)) { @@ -636,7 +641,7 @@ std::string Skype::send_command(const std::string &message) { } if (str != NULL) { - LOG4CXX_INFO(logger, m_username << ": DBUS:" << str); + LOG4CXX_INFO(logger, m_username << ": DBUS:'" << str << "'"); } return str ? std::string(str) : std::string(); } From 7067865738d06ea9b649caf06e6c729893fe405d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 20 Mar 2012 22:06:51 +0100 Subject: [PATCH 42/46] Send admin contac tot user --- spectrum/src/sample.cfg | 2 +- src/usermanager.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index acdd93f5..d3b4f317 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -8,7 +8,7 @@ backend_host=localhost pidfile=./test.pid # < this option doesn't work yet #backend_port=10001 -admin_username=admin +admin_jid=admin@localhost admin_password=test #cert=server.pfx #patch to PKCS#12 certificate #cert_password=test #password to that certificate if any diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 1845d94e..52e41607 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -152,6 +152,21 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { if (!user) { // Admin user is not legacy network user, so do not create User class instance for him if (m_component->inServerMode() && CONFIG_STRING(m_component->getConfig(), "service.admin_jid") == presence->getFrom().toBare().toString()) { + // Send admin contact to the user. + Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload()); + Swift::RosterItemPayload item; + item.setJID(m_component->getJID()); + item.setName("Admin"); + item.setSubscription(Swift::RosterItemPayload::Both); + payload->addItem(item); + + Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, presence->getFrom(), m_component->getIQRouter()); + request->send(); + + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(m_component->getJID()); + m_component->getStanzaChannel()->sendPresence(response); return; } From 9c7d577b0e3aac70f6e1e8ce56f23c8c638c1514 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 20 Mar 2012 22:45:13 +0100 Subject: [PATCH 43/46] define getpid on windows --- plugin/cpp/networkplugin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index 94fc82c0..1b7f448c 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -28,6 +28,8 @@ #else #include #include +#include +#define getpid _getpid #endif using namespace log4cxx; From e910508a9cc9cd37f93c3895efe1644b44a89307 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 20 Mar 2012 22:45:41 +0100 Subject: [PATCH 44/46] define getpid on windows --- src/logging.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/logging.cpp b/src/logging.cpp index 19dee6cf..dfc3f447 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -43,6 +43,8 @@ #include "libgen.h" #else #include +#include +#define getpid _getpid #endif using namespace boost::filesystem; From 2bf17991b5fae854bf99d57c716f051b68ec2acd Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 20 Mar 2012 22:51:17 +0100 Subject: [PATCH 45/46] define getpid on windows --- backends/libpurple/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 39c53627..8defa6b9 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -24,6 +24,11 @@ #include #endif +#ifdef WIN32 +#include +#define getpid _getpid +#endif + using namespace log4cxx; static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple"); From 3b4c7b384b0cb96f5b42f47afae5ab2dc92614ca Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 20 Mar 2012 22:58:00 +0100 Subject: [PATCH 46/46] ssize_t on windows... --- backends/libpurple/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 8defa6b9..e05ba412 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -25,6 +25,8 @@ #endif #ifdef WIN32 +#include "win32/win32dep.h" +#define ssize_t SSIZE_T #include #define getpid _getpid #endif