From 81beee07a288ce4ac4f21c7a984707358073f6cb Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 23 Oct 2011 13:07:26 +0200 Subject: [PATCH 01/26] Libpurple backend compiles on Windows, yay! thanks _vt --- backends/libpurple/CMakeLists.txt | 4 +++ backends/libpurple/geventloop.cpp | 2 ++ backends/libpurple/main.cpp | 44 ++++++++++++++++++++++++------- cmake_modules/SwiftenConfig.cmake | 4 +-- cmake_modules/glibConfig.cmake | 8 +++++- plugin/src/CMakeLists.txt | 8 +++--- 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/backends/libpurple/CMakeLists.txt b/backends/libpurple/CMakeLists.txt index 1bfbbf1b..a53ef6d3 100644 --- a/backends/libpurple/CMakeLists.txt +++ b/backends/libpurple/CMakeLists.txt @@ -3,7 +3,11 @@ FILE(GLOB SRC *.cpp) ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC}) +if(NOT WIN32) target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread) +else() +target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin) +endif() INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin) diff --git a/backends/libpurple/geventloop.cpp b/backends/libpurple/geventloop.cpp index 75126707..b32c893d 100644 --- a/backends/libpurple/geventloop.cpp +++ b/backends/libpurple/geventloop.cpp @@ -21,6 +21,8 @@ #include "geventloop.h" #ifdef _WIN32 #include "win32/win32dep.h" +#undef read +#undef write #endif #ifdef WITH_LIBEVENT #include "event.h" diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 3acc3d08..9e03792a 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -1,5 +1,6 @@ #include "glib.h" #include "purple.h" +#include #include #include "transport/networkplugin.h" @@ -10,13 +11,10 @@ #include "log4cxx/propertyconfigurator.h" #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 "valgrind/memcheck.h" -#include "malloc.h" -#include -#include "errno.h" - #include #include #include @@ -27,6 +25,16 @@ #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 +#include "errno.h" #ifdef WITH_LIBEVENT #include @@ -650,7 +658,9 @@ class SpectrumNetworkPlugin : public NetworkPlugin { // // purple_account_destroy(account); // force returning of memory chunks allocated by libxml2 to kernel +#ifndef WIN32 malloc_trim(0); +#endif // VALGRIND_DO_LEAK_CHECK; } } @@ -1210,7 +1220,7 @@ static PurpleConnectionUiOps conn_ui_ops = static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) { PurpleAccount *account = purple_connection_get_account(gc); std::string name(purple_normalize(account, who)); - std::transform(name.begin(), name.end(), name.begin(),(int(*)(int)) std::tolower); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); size_t pos = name.find("/"); if (pos != std::string::npos) @@ -1544,8 +1554,10 @@ static PurpleCoreUiOps coreUiOps = static void signed_on(PurpleConnection *gc, gpointer unused) { PurpleAccount *account = purple_connection_get_account(gc); np->handleConnected(np->m_accounts[account]); +#ifndef WIN32 // force returning of memory chunks allocated by libxml2 to kernel malloc_trim(0); +#endif } static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) { @@ -1680,7 +1692,7 @@ static bool initPurple() { } return ret; } - +#ifndef WIN32 static void spectrum_sigchld_handler(int sig) { int status; @@ -1696,6 +1708,7 @@ static void spectrum_sigchld_handler(int sig) perror(errmsg); } } +#endif static int create_socket(char *host, int portno) { struct sockaddr_in serv_addr; @@ -1811,15 +1824,26 @@ int main(int argc, char **argv) { if (KEYFILE_STRING("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(KEYFILE_STRING("logging", "backend_config")); - p.load(istream); - p.setProperty("pid", stringOf(getpid())); - p.setProperty("jid", KEYFILE_STRING("service", "jid")); + LogString pid, jid; + log4cxx::helpers::Transcoder::decode(stringOf(getpid()), pid); + log4cxx::helpers::Transcoder::decode(KEYFILE_STRING("service", "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); } diff --git a/cmake_modules/SwiftenConfig.cmake b/cmake_modules/SwiftenConfig.cmake index 278594aa..f693e1ed 100644 --- a/cmake_modules/SwiftenConfig.cmake +++ b/cmake_modules/SwiftenConfig.cmake @@ -16,8 +16,8 @@ if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR ) STRING(SUBSTRING ${f} 0 2 f_out) STRING(COMPARE EQUAL ${f_out} "/L" IS_PATH) if(${IS_PATH}) - message(${f}) - string(REGEX REPLACE "/LIBPATH:" "" f_replaced ${f}) + string(REGEX REPLACE "/LIBPATH:" "" f_replaced "${f}") + message("Added link directory: ${f_replaced}") link_directories(${f_replaced}) else() list(APPEND SWIFTEN_LIBRARY ${f}) diff --git a/cmake_modules/glibConfig.cmake b/cmake_modules/glibConfig.cmake index 0c3d791e..a160dc6d 100644 --- a/cmake_modules/glibConfig.cmake +++ b/cmake_modules/glibConfig.cmake @@ -22,13 +22,19 @@ find_library(GLIB2_LIBRARIES find_library(GLIB2_THREAD NAMES gthread-2.0 PATHS ${PKG_GLIB_LIBRARY_DIRS} ) +find_library(GLIB2_OBJECT + NAMES gobject-2.0 + PATHS ${PKG_GLIB_LIBRARY_DIRS} ) +find_library(GLIB2_MODULE + NAMES gmodule-2.0 + PATHS ${PKG_GLIB_LIBRARY_DIRS} ) find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h PATH_SUFFIXES glib-2.0/include PATHS ${PKG_GLIB_INCLUDE_DIRS} ${PKG_GLIB_LIBRARIES} ${CMAKE_SYSTEM_LIBRARY_PATH}) if(GLIB2_THREAD) - set(GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${GLIB2_THREAD}) + set(GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${GLIB2_THREAD} ${GLIB2_MODULE} ${GLIB2_OBJECT}) else(GLIB2_THREAD) message( STATUS "Could NOT find gthread-2.0" ) endif(GLIB2_THREAD) diff --git a/plugin/src/CMakeLists.txt b/plugin/src/CMakeLists.txt index 16a2a3ea..dde42f38 100644 --- a/plugin/src/CMakeLists.txt +++ b/plugin/src/CMakeLists.txt @@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 2.6) FILE(GLOB SRC *.cpp *.h) FILE(GLOB HEADERS ../include/transport/*.h) -ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc) +if (NOT WIN32) + ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc) +else() + ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc) +endif() ADD_DEPENDENCIES(transport-plugin pb) SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1) @@ -16,8 +20,6 @@ else() TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ws2_32.lib) endif() -TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES}) - SET_TARGET_PROPERTIES(transport-plugin PROPERTIES VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION} ) From 9b03ad3f309fde5fa32f480a425239cd056e96f0 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 23 Oct 2011 16:25:33 +0200 Subject: [PATCH 02/26] test --- src/tests/usermanager.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/usermanager.cpp b/src/tests/usermanager.cpp index d0084ddf..428892c7 100644 --- a/src/tests/usermanager.cpp +++ b/src/tests/usermanager.cpp @@ -169,7 +169,10 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPPars CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); - CPPUNIT_ASSERT(dynamic_cast(getStanza(received[1]))); + + Swift::Presence *presence = dynamic_cast(getStanza(received[1])); + CPPUNIT_ASSERT(presence); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType()); } Swift::Stanza *getStanza(boost::shared_ptr element) { From bc3971f7d258d48ec1efe3e11ae5cd17f9529524 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 23 Oct 2011 18:50:10 +0200 Subject: [PATCH 03/26] IRC backends work again --- CMakeLists.txt | 2 +- backends/libircclient-qt/ircnetworkplugin.cpp | 64 +++++++++++++++++++ backends/libircclient-qt/ircnetworkplugin.h | 38 +++++++++++ backends/libircclient-qt/main.cpp | 56 +--------------- include/transport/networkplugin.h | 1 - spectrum/src/sample.cfg | 4 +- src/networkpluginserver.cpp | 1 + 7 files changed, 108 insertions(+), 58 deletions(-) create mode 100644 backends/libircclient-qt/ircnetworkplugin.cpp create mode 100644 backends/libircclient-qt/ircnetworkplugin.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a3398e5..531b0591 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ find_package(event) find_package(Doxygen) INCLUDE(FindQt4) -FIND_PACKAGE(Qt4 COMPONENTS QtCore) +FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork) # ADD_DEFINITIONS(${SWIFTEN_CFLAGS}) ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS) diff --git a/backends/libircclient-qt/ircnetworkplugin.cpp b/backends/libircclient-qt/ircnetworkplugin.cpp new file mode 100644 index 00000000..70dc58d0 --- /dev/null +++ b/backends/libircclient-qt/ircnetworkplugin.cpp @@ -0,0 +1,64 @@ +#include "ircnetworkplugin.h" + +IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) { + this->config = config; + m_socket = new QTcpSocket(); + m_socket->connectToHost(QString::fromStdString(host), port); + connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData())); +} + +void IRCNetworkPlugin::readData() { + size_t availableBytes = m_socket->bytesAvailable(); + if (availableBytes == 0) + return; + + std::cout << "READ\n"; + std::string d = std::string(m_socket->readAll().data(), availableBytes); + handleDataRead(d); +} + +void IRCNetworkPlugin::sendData(const std::string &string) { + m_socket->write(string.c_str(), string.size()); +} + +void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { + MyIrcSession *session = new MyIrcSession(user, this); + std::string h = user.substr(0, user.find("@")); + session->setNick(QString::fromStdString(h.substr(0, h.find("%")))); + session->connectToServer(QString::fromStdString(h.substr(h.find("%") + 1)), 6667); + std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n"; + m_sessions[user] = session; +} + +void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) { + if (m_sessions[user] == NULL) + return; + m_sessions[user]->disconnectFromServer(); + m_sessions[user]->deleteLater(); +} + +void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { + std::cout << "MESSAGE " << user << " " << legacyName << "\n"; + if (m_sessions[user] == NULL) + return; + m_sessions[user]->message(QString::fromStdString(legacyName), QString::fromStdString(message)); + std::cout << "SENT\n"; +} + +void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { + std::cout << "JOIN\n"; + if (m_sessions[user] == NULL) + return; + m_sessions[user]->addAutoJoinChannel(QString::fromStdString(room)); + m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password)); + // update nickname, because we have nickname per session, no nickname per room. + handleRoomNicknameChanged(user, room, m_sessions[user]->nick().toStdString()); +} + +void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) { + std::cout << "PART\n"; + if (m_sessions[user] == NULL) + return; + m_sessions[user]->part(QString::fromStdString(room)); + m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(room)); +} diff --git a/backends/libircclient-qt/ircnetworkplugin.h b/backends/libircclient-qt/ircnetworkplugin.h new file mode 100644 index 00000000..c15dc9a1 --- /dev/null +++ b/backends/libircclient-qt/ircnetworkplugin.h @@ -0,0 +1,38 @@ + +#pragma once + +#include "transport/config.h" +#include "transport/networkplugin.h" +#include "session.h" +#include +#include +#include "Swiften/EventLoop/Qt/QtEventLoop.h" +#include "ircnetworkplugin.h" + + +class IRCNetworkPlugin : public QObject, public NetworkPlugin { + Q_OBJECT + + public: + IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port); + + void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password); + + void handleLogoutRequest(const std::string &user, const std::string &legacyName); + + void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/); + + void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password); + + void handleLeaveRoomRequest(const std::string &user, const std::string &room); + + std::map m_sessions; + + public slots: + void readData(); + void sendData(const std::string &string); + + private: + Config *config; + QTcpSocket *m_socket; +}; \ No newline at end of file diff --git a/backends/libircclient-qt/main.cpp b/backends/libircclient-qt/main.cpp index 7def0fbc..83723532 100644 --- a/backends/libircclient-qt/main.cpp +++ b/backends/libircclient-qt/main.cpp @@ -12,67 +12,15 @@ #include "transport/networkplugin.h" #include "session.h" #include +#include #include "Swiften/EventLoop/Qt/QtEventLoop.h" +#include "ircnetworkplugin.h" using namespace boost::program_options; using namespace Transport; -class IRCNetworkPlugin; IRCNetworkPlugin * np = NULL; -class IRCNetworkPlugin : public NetworkPlugin { - public: - IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { - this->config = config; - } - - void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { - MyIrcSession *session = new MyIrcSession(user, this); - session->setNick(QString::fromStdString(user.substr(0, user.find("@")))); - session->connectToServer(QString::fromStdString(user.substr(user.find("@") + 1)), 6667); -// std::cout << "CONNECTING IRC NETWORK " << jid.getNode() << " " << jid.getDomain() << "\n"; - m_sessions[user] = session; - } - - void handleLogoutRequest(const std::string &user, const std::string &legacyName) { - if (m_sessions[user] == NULL) - return; - m_sessions[user]->disconnectFromServer(); - m_sessions[user]->deleteLater(); - } - - void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { - std::cout << "MESSAGE " << user << " " << legacyName << "\n"; - if (m_sessions[user] == NULL) - return; - m_sessions[user]->message(QString::fromStdString(legacyName), QString::fromStdString(message)); - std::cout << "SENT\n"; - } - - void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { - std::cout << "JOIN\n"; - if (m_sessions[user] == NULL) - return; - m_sessions[user]->addAutoJoinChannel(QString::fromStdString(room)); - m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password)); - // update nickname, because we have nickname per session, no nickname per room. - handleRoomNicknameChanged(user, room, m_sessions[user]->nick().toStdString()); - } - - void handleLeaveRoomRequest(const std::string &user, const std::string &room) { - std::cout << "PART\n"; - if (m_sessions[user] == NULL) - return; - m_sessions[user]->part(QString::fromStdString(room)); - m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(room)); - } - - std::map m_sessions; - - private: - Config *config; -}; - int main (int argc, char* argv[]) { std::string host; int port; diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 691dc6e2..334fab8b 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -217,7 +217,6 @@ class NetworkPlugin { private: - void connect(); void handleLoginPayload(const std::string &payload); void handleLogoutPayload(const std::string &payload); void handleStatusChangedPayload(const std::string &payload); diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index 6efc9561..b3b18dd7 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -11,10 +11,10 @@ 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=/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=../../backends/libircclient-qt/spectrum2_libircclient-qt_backend +backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend #protocol=prpl-msn protocol=any #protocol=prpl-icq diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index e77bca35..c8507c03 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -355,6 +355,7 @@ void NetworkPluginServer::handleConnectedPayload(const std::string &data) { User *user = m_userManager->getUser(payload.user()); if (!user) { + LOG4CXX_ERROR(logger, "Connected payload received for unknown user " << payload.user()); return; } From fdc1a4199a2a1e6f9300fb520e6361b14f78aaa9 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Mon, 24 Oct 2011 22:33:15 +0200 Subject: [PATCH 04/26] IRC backend almost work in gateway mode --- backends/libircclient-qt/ircnetworkplugin.cpp | 63 ++++++++++++++----- backends/libircclient-qt/session.cpp | 40 +++++++----- backends/libircclient-qt/session.h | 7 ++- 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/backends/libircclient-qt/ircnetworkplugin.cpp b/backends/libircclient-qt/ircnetworkplugin.cpp index 70dc58d0..4f0c9e52 100644 --- a/backends/libircclient-qt/ircnetworkplugin.cpp +++ b/backends/libircclient-qt/ircnetworkplugin.cpp @@ -22,12 +22,18 @@ void IRCNetworkPlugin::sendData(const std::string &string) { } void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { - MyIrcSession *session = new MyIrcSession(user, this); - std::string h = user.substr(0, user.find("@")); - session->setNick(QString::fromStdString(h.substr(0, h.find("%")))); - session->connectToServer(QString::fromStdString(h.substr(h.find("%") + 1)), 6667); - std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n"; - m_sessions[user] = session; + // Server is in server-mode, so user is JID of server when we want to connect + if (CONFIG_BOOL(config, "service.server_mode")) { + MyIrcSession *session = new MyIrcSession(user, this); + std::string h = user.substr(0, user.find("@")); + session->setNick(QString::fromStdString(h.substr(0, h.find("%")))); + session->connectToServer(QString::fromStdString(h.substr(h.find("%") + 1)), 6667); + std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n"; + m_sessions[user] = session; + } + else { + handleConnected(user); + } } void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) { @@ -38,27 +44,54 @@ void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::s } void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { - std::cout << "MESSAGE " << user << " " << legacyName << "\n"; if (m_sessions[user] == NULL) return; - m_sessions[user]->message(QString::fromStdString(legacyName), QString::fromStdString(message)); + + std::string r = legacyName; + if (!CONFIG_BOOL(config, "service.server_mode")) { + r = legacyName.substr(0, r.find("@")); + } + std::cout << "MESSAGE " << user << " " << r << "\n"; + m_sessions[user]->message(QString::fromStdString(r), QString::fromStdString(message)); std::cout << "SENT\n"; } void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { std::cout << "JOIN\n"; - if (m_sessions[user] == NULL) - return; - m_sessions[user]->addAutoJoinChannel(QString::fromStdString(room)); - m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password)); + std::string r = room; + if (m_sessions[user] == NULL) { + // in gateway mode we want to login this user to network according to legacyName + if (room.find("%") != std::string::npos) { + // suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net + MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("%"))); + session->setNick(QString::fromStdString(nickname)); + session->connectToServer(QString::fromStdString(room.substr(room.find("%") + 1)), 6667); + std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("%") + 1) << "\n"; + std::cout << "SUFFIX " << room.substr(room.find("%")) << "\n"; + m_sessions[user] = session; + r = room.substr(0, room.find("%")); + std::cout << "room=" << r << "\n"; + } + else { + return; + } + } + m_sessions[user]->addAutoJoinChannel(QString::fromStdString(r)); + m_sessions[user]->join(QString::fromStdString(r), QString::fromStdString(password)); // update nickname, because we have nickname per session, no nickname per room. - handleRoomNicknameChanged(user, room, m_sessions[user]->nick().toStdString()); + handleRoomNicknameChanged(user, r, m_sessions[user]->nick().toStdString()); } void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) { std::cout << "PART\n"; if (m_sessions[user] == NULL) return; - m_sessions[user]->part(QString::fromStdString(room)); - m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(room)); + + std::string r = room; + if (!CONFIG_BOOL(config, "service.server_mode")) { + r = room.substr(0, room.find("%")); + } + + m_sessions[user]->part(QString::fromStdString(r)); + m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(r)); } diff --git a/backends/libircclient-qt/session.cpp b/backends/libircclient-qt/session.cpp index ed2b1674..ceb30ee5 100644 --- a/backends/libircclient-qt/session.cpp +++ b/backends/libircclient-qt/session.cpp @@ -13,10 +13,11 @@ #include #include "Swiften/Elements/StatusShow.h" -MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, QObject* parent) : Irc::Session(parent) +MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : Irc::Session(parent) { this->np = np; this->user = user; + this->suffix = suffix; connect(this, SIGNAL(disconnected()), SLOT(on_disconnected())); } @@ -26,8 +27,9 @@ void MyIrcSession::on_connected(){ void MyIrcSession::on_disconnected() { - std::cout << "disconnected:\n"; - np->handleDisconnected(user, 0, ""); + std::cout << "disconnected:\n"; + if (suffix.empty()) + np->handleDisconnected(user, 0, ""); } void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer) @@ -42,14 +44,15 @@ void MyIrcSession::on_bufferRemoved(Irc::Buffer* buffer) Irc::Buffer* MyIrcSession::createBuffer(const QString& receiver) { - return new MyIrcBuffer(receiver, user, np, this); + return new MyIrcBuffer(receiver, user, np, suffix, this); } -MyIrcBuffer::MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, Irc::Session* parent) +MyIrcBuffer::MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent) : Irc::Buffer(receiver, parent) { this->np = np; this->user = user; + this->suffix = suffix; p = (MyIrcSession *) parent; connect(this, SIGNAL(receiverChanged(QString)), SLOT(on_receiverChanged(QString))); connect(this, SIGNAL(joined(QString)), SLOT(on_joined(QString))); @@ -94,7 +97,7 @@ void MyIrcBuffer::on_joined(const QString& origin) { bool flags = 0; std::string nickname = origin.toStdString(); flags = correctNickname(nickname); - np->handleParticipantChanged(user, origin.toStdString(), receiver().toStdString(), (int) flags, pbnetwork::STATUS_ONLINE); + np->handleParticipantChanged(user, origin.toStdString(), receiver().toStdString() + suffix, (int) flags, pbnetwork::STATUS_ONLINE); } void MyIrcBuffer::on_parted(const QString& origin, const QString& message) { @@ -102,7 +105,7 @@ void MyIrcBuffer::on_parted(const QString& origin, const QString& message) { bool flags = 0; std::string nickname = origin.toStdString(); flags = correctNickname(nickname); - np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_NONE, message.toStdString()); + np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_NONE, message.toStdString()); } void MyIrcBuffer::on_quit(const QString& origin, const QString& message) @@ -116,7 +119,7 @@ void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) { std::string nickname = origin.toStdString(); bool flags = p->m_modes[receiver().toStdString() + nickname]; // std::cout << receiver().toStdString() + nickname << " " << flags << "\n"; - np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_ONLINE, "", nick.toStdString()); + np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", nick.toStdString()); } void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, const QString& args) { @@ -132,13 +135,13 @@ void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, con p->m_modes[receiver().toStdString() + nickname] = 0; } bool flags = p->m_modes[receiver().toStdString() + nickname]; - np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_ONLINE, ""); + np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, ""); } void MyIrcBuffer::on_topicChanged(const QString& origin, const QString& topic) { //topic changed: "#testik" "HanzZ" "test" qDebug() << "topic changed:" << receiver() << origin << topic; - np->handleSubject(user, receiver().toStdString(), topic.toStdString(), origin.toStdString()); + np->handleSubject(user, receiver().toStdString() + suffix, topic.toStdString(), origin.toStdString()); } void MyIrcBuffer::on_invited(const QString& origin, const QString& receiver, const QString& channel) @@ -155,7 +158,11 @@ void MyIrcBuffer::on_messageReceived(const QString& origin, const QString& messa qDebug() << "message received:" << receiver() << origin << message << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); if (!receiver().startsWith("#") && (flags & Irc::Buffer::EchoFlag)) return; - np->handleMessage(user, receiver().toStdString(), message.toStdString(), origin.toStdString()); + std::string r = receiver().toStdString(); +// if (!suffix.empty()) { +// r = receiver().replace('@', '%').toStdString(); +// } + np->handleMessage(user, r + suffix, message.toStdString(), origin.toStdString()); } void MyIrcBuffer::on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags) @@ -186,13 +193,14 @@ void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, co { switch (code) { case 251: - np->handleConnected(user); + if (suffix.empty()) + np->handleConnected(user); break; case 332: m_topicData = params.value(2).toStdString(); break; case 333: - np->handleSubject(user, params.value(1).toStdString(), m_topicData, params.value(2).toStdString()); + np->handleSubject(user, params.value(1).toStdString() + suffix, m_topicData, params.value(2).toStdString()); break; case 353: QString channel = params.value(2); @@ -203,12 +211,12 @@ void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, co std::string nickname = members.at(i).toStdString(); flags = correctNickname(nickname); p->m_modes[channel.toStdString() + nickname] = flags; -// std::cout << channel.toStdString() + nickname << " " << flags << "\n"; - np->handleParticipantChanged(user, nickname, channel.toStdString(),(int) flags, pbnetwork::STATUS_ONLINE); + std::cout << channel.toStdString() + suffix << " " << flags << "\n"; + np->handleParticipantChanged(user, nickname, channel.toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE); } break; } - qDebug() << "numeric message received:" << receiver() << origin << code << params; + qDebug() << "numeric message received:" << receiver() << origin << code << params; } void MyIrcBuffer::on_unknownMessageReceived(const QString& origin, const QStringList& params) diff --git a/backends/libircclient-qt/session.h b/backends/libircclient-qt/session.h index 1f9e021d..b782c7c5 100644 --- a/backends/libircclient-qt/session.h +++ b/backends/libircclient-qt/session.h @@ -22,8 +22,9 @@ class MyIrcSession : public Irc::Session Q_OBJECT public: - MyIrcSession(const std::string &user, NetworkPlugin *np, QObject* parent = 0); + MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0); std::map m_modes; + std::string suffix; protected Q_SLOTS: void on_connected(); @@ -35,6 +36,7 @@ protected Q_SLOTS: protected: NetworkPlugin *np; std::string user; + virtual Irc::Buffer* createBuffer(const QString& receiver); }; @@ -43,11 +45,12 @@ class MyIrcBuffer : public Irc::Buffer Q_OBJECT public: - MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, Irc::Session* parent); + MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent); NetworkPlugin *np; std::string user; MyIrcSession *p; std::string m_topicData; + std::string suffix; protected Q_SLOTS: void on_receiverChanged(const QString& receiver); From a560778c90e0a24d62894fa3de983716f1428b9f Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 25 Oct 2011 18:22:24 +0200 Subject: [PATCH 05/26] Added missing return; --- src/networkpluginserver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index c8507c03..4da583eb 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -1301,7 +1301,8 @@ void NetworkPluginServer::handleFTRejected(User *user, const std::string &buddyN void NetworkPluginServer::handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id) { User *user = m_userManager->getUser(userName); if (!user) { - // TODO: reject and remove filetransfer + // TODO: FIXME We have to remove filetransfer when use disconnects + return; } if (state.state == Swift::FileTransfer::State::Transferring) { handleFTAccepted(user, buddyName, fileName, size, id); From f7cd1346cc8a813d8b5176d2c5889b9a552afb73 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 25 Oct 2011 18:31:13 +0200 Subject: [PATCH 06/26] PURPLE_INPUT_WRITE works again --- backends/libpurple/main.cpp | 10 +++++++++- spectrum/src/sample.cfg | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 9e03792a..657a3799 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -45,6 +45,7 @@ using namespace log4cxx; static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple"); static LoggerPtr logger = log4cxx::Logger::getLogger("backend"); int m_sock; +static int writeInput; using namespace Transport; @@ -61,6 +62,8 @@ template std::string stringOf(T object) { return (os.str()); } +static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond); + class SpectrumNetworkPlugin; GKeyFile *keyfile; @@ -907,6 +910,8 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void sendData(const std::string &string) { write(m_sock, string.c_str(), string.size()); + if (writeInput == 0) + writeInput = purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL); } void readyForData() { @@ -1750,6 +1755,10 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi np->handleDataRead(d); } else { + if (writeInput != 0) { + purple_input_remove(writeInput); + writeInput = 0; + } np->readyForData(); } } @@ -1852,7 +1861,6 @@ int main(int argc, char **argv) { m_sock = create_socket(host, port); purple_input_add(m_sock, PURPLE_INPUT_READ, &transportDataReceived, NULL); -// purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL); np = new SpectrumNetworkPlugin(host, port); bool libev = KEYFILE_STRING("service", "eventloop") == "libev"; diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index b3b18dd7..c89c7871 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -11,10 +11,10 @@ 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=/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=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend #protocol=prpl-msn protocol=any #protocol=prpl-icq From 8d72e074c0d582828ebbe8cd2a60bffaddac3e3b Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 25 Oct 2011 19:24:14 +0200 Subject: [PATCH 07/26] IRC backend can connect more servers/rooms... PM still doesn't work correctly :) --- backends/libircclient-qt/ircnetworkplugin.cpp | 50 +++++++++++++------ backends/libircclient-qt/session.cpp | 1 + backends/libircclient-qt/session.h | 9 ++-- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/backends/libircclient-qt/ircnetworkplugin.cpp b/backends/libircclient-qt/ircnetworkplugin.cpp index 4f0c9e52..3899fa35 100644 --- a/backends/libircclient-qt/ircnetworkplugin.cpp +++ b/backends/libircclient-qt/ircnetworkplugin.cpp @@ -41,25 +41,35 @@ void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::s return; m_sessions[user]->disconnectFromServer(); m_sessions[user]->deleteLater(); + m_sessions.erase(user); } void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { - if (m_sessions[user] == NULL) + std::string u = user; + if (!CONFIG_BOOL(config, "service.server_mode")) { + u = user + legacyName.substr(legacyName.find("@") + 1); + } + if (m_sessions[u] == NULL) return; std::string r = legacyName; if (!CONFIG_BOOL(config, "service.server_mode")) { r = legacyName.substr(0, r.find("@")); } - std::cout << "MESSAGE " << user << " " << r << "\n"; - m_sessions[user]->message(QString::fromStdString(r), QString::fromStdString(message)); + std::cout << "MESSAGE " << u << " " << r << "\n"; + m_sessions[u]->message(QString::fromStdString(r), QString::fromStdString(message)); std::cout << "SENT\n"; } void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { std::cout << "JOIN\n"; std::string r = room; - if (m_sessions[user] == NULL) { + std::string u = user; + if (!CONFIG_BOOL(config, "service.server_mode")) { + u = user + room.substr(room.find("%") + 1); + r = room.substr(0, room.find("%")); + } + if (m_sessions[u] == NULL) { // in gateway mode we want to login this user to network according to legacyName if (room.find("%") != std::string::npos) { // suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net @@ -68,30 +78,38 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std: session->connectToServer(QString::fromStdString(room.substr(room.find("%") + 1)), 6667); std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("%") + 1) << "\n"; std::cout << "SUFFIX " << room.substr(room.find("%")) << "\n"; - m_sessions[user] = session; - r = room.substr(0, room.find("%")); - std::cout << "room=" << r << "\n"; + m_sessions[u] = session; } else { return; } } - m_sessions[user]->addAutoJoinChannel(QString::fromStdString(r)); - m_sessions[user]->join(QString::fromStdString(r), QString::fromStdString(password)); + std::cout << "JOINING " << r << "\n"; + m_sessions[u]->addAutoJoinChannel(QString::fromStdString(r)); + m_sessions[u]->join(QString::fromStdString(r), QString::fromStdString(password)); + m_sessions[u]->rooms += 1; // update nickname, because we have nickname per session, no nickname per room. - handleRoomNicknameChanged(user, r, m_sessions[user]->nick().toStdString()); + handleRoomNicknameChanged(user, r, m_sessions[u]->nick().toStdString()); } void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) { - std::cout << "PART\n"; - if (m_sessions[user] == NULL) - return; - std::string r = room; + std::string u = user; if (!CONFIG_BOOL(config, "service.server_mode")) { r = room.substr(0, room.find("%")); + u = user + room.substr(room.find("%") + 1); } - m_sessions[user]->part(QString::fromStdString(r)); - m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(r)); + if (m_sessions[u] == NULL) + return; + + m_sessions[u]->part(QString::fromStdString(r)); + m_sessions[u]->removeAutoJoinChannel(QString::fromStdString(r)); + m_sessions[u]->rooms -= 1; + + if (m_sessions[u]->rooms <= 0) { + m_sessions[u]->disconnectFromServer(); + m_sessions[u]->deleteLater(); + m_sessions.erase(u); + } } diff --git a/backends/libircclient-qt/session.cpp b/backends/libircclient-qt/session.cpp index ceb30ee5..508ab7f4 100644 --- a/backends/libircclient-qt/session.cpp +++ b/backends/libircclient-qt/session.cpp @@ -18,6 +18,7 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std this->np = np; this->user = user; this->suffix = suffix; + rooms = 0; connect(this, SIGNAL(disconnected()), SLOT(on_disconnected())); } diff --git a/backends/libircclient-qt/session.h b/backends/libircclient-qt/session.h index b782c7c5..326ba4b4 100644 --- a/backends/libircclient-qt/session.h +++ b/backends/libircclient-qt/session.h @@ -22,9 +22,10 @@ class MyIrcSession : public Irc::Session Q_OBJECT public: - MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0); + MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0); std::map m_modes; - std::string suffix; + std::string suffix; + int rooms; protected Q_SLOTS: void on_connected(); @@ -45,12 +46,12 @@ class MyIrcBuffer : public Irc::Buffer Q_OBJECT public: - MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent); + MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent); NetworkPlugin *np; std::string user; MyIrcSession *p; std::string m_topicData; - std::string suffix; + std::string suffix; protected Q_SLOTS: void on_receiverChanged(const QString& receiver); From 8c529dbabbbc337e0d97240a1070cd7e7abfb86d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 25 Oct 2011 20:29:58 +0200 Subject: [PATCH 08/26] semi-working PMs in muc --- backends/libircclient-qt/ircnetworkplugin.cpp | 33 ++++++++++++------- include/transport/conversation.h | 4 +-- src/conversation.cpp | 19 +++++++++-- src/user.cpp | 6 ++-- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/backends/libircclient-qt/ircnetworkplugin.cpp b/backends/libircclient-qt/ircnetworkplugin.cpp index 3899fa35..2ebe91d9 100644 --- a/backends/libircclient-qt/ircnetworkplugin.cpp +++ b/backends/libircclient-qt/ircnetworkplugin.cpp @@ -46,15 +46,26 @@ void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::s void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { std::string u = user; + std::cout << "AAAAA " << legacyName << "\n"; if (!CONFIG_BOOL(config, "service.server_mode")) { u = user + legacyName.substr(legacyName.find("@") + 1); + if (u.find("/") != std::string::npos) { + u = u.substr(0, u.find("/")); + } } - if (m_sessions[u] == NULL) + if (m_sessions[u] == NULL) { + std::cout << "No session for " << u << "\n"; return; + } std::string r = legacyName; if (!CONFIG_BOOL(config, "service.server_mode")) { - r = legacyName.substr(0, r.find("@")); + if (legacyName.find("/") == std::string::npos) { + r = legacyName.substr(0, r.find("@")); + } + else { + r = legacyName.substr(legacyName.find("/") + 1); + } } std::cout << "MESSAGE " << u << " " << r << "\n"; m_sessions[u]->message(QString::fromStdString(r), QString::fromStdString(message)); @@ -66,18 +77,18 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std: std::string r = room; std::string u = user; if (!CONFIG_BOOL(config, "service.server_mode")) { - u = user + room.substr(room.find("%") + 1); - r = room.substr(0, room.find("%")); + u = user + room.substr(room.find("@") + 1); + r = room.substr(0, room.find("@")); } if (m_sessions[u] == NULL) { // in gateway mode we want to login this user to network according to legacyName - if (room.find("%") != std::string::npos) { + if (room.find("@") != std::string::npos) { // suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net - MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("%"))); + MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("@"))); session->setNick(QString::fromStdString(nickname)); - session->connectToServer(QString::fromStdString(room.substr(room.find("%") + 1)), 6667); - std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("%") + 1) << "\n"; - std::cout << "SUFFIX " << room.substr(room.find("%")) << "\n"; + session->connectToServer(QString::fromStdString(room.substr(room.find("@") + 1)), 6667); + std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("@") + 1) << "\n"; + std::cout << "SUFFIX " << room.substr(room.find("@")) << "\n"; m_sessions[u] = session; } else { @@ -96,8 +107,8 @@ void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std std::string r = room; std::string u = user; if (!CONFIG_BOOL(config, "service.server_mode")) { - r = room.substr(0, room.find("%")); - u = user + room.substr(room.find("%") + 1); + r = room.substr(0, room.find("@")); + u = user + room.substr(room.find("@") + 1); } if (m_sessions[u] == NULL) diff --git a/include/transport/conversation.h b/include/transport/conversation.h index 82a35b0c..8af86993 100644 --- a/include/transport/conversation.h +++ b/include/transport/conversation.h @@ -97,9 +97,7 @@ class Conversation { /// This is used to detect Private messages associated with particular room. /// \param room room name associated with this Conversation. - void setRoom(const std::string &room) { - m_room = room; - } + void setRoom(const std::string &room); /// Returns room name associated with this Conversation. diff --git a/src/conversation.cpp b/src/conversation.cpp index 238fe4c8..81b1654d 100644 --- a/src/conversation.cpp +++ b/src/conversation.cpp @@ -42,6 +42,11 @@ Conversation::Conversation(ConversationManager *conversationManager, const std:: Conversation::~Conversation() { } +void Conversation::setRoom(const std::string &room) { + m_room = room; + m_legacyName = m_room + "/" + m_legacyName; +} + void Conversation::handleMessage(boost::shared_ptr &message, const std::string &nickname) { if (m_muc) { message->setType(Swift::Message::Groupchat); @@ -74,8 +79,12 @@ void Conversation::handleMessage(boost::shared_ptr &message, con m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message); } else { + std::string legacyName = m_legacyName; + if (legacyName.find_last_of("@") != std::string::npos) { + legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK + } message->setTo(m_conversationManager->getUser()->getJID().toString()); - message->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname)); + message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname)); m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message); } } @@ -83,7 +92,13 @@ void Conversation::handleMessage(boost::shared_ptr &message, con void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) { std::string nickname = nick; Swift::Presence::ref presence = Swift::Presence::create(); - presence->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname)); + std::string legacyName = m_legacyName; + if (m_muc) { + if (legacyName.find_last_of("@") != std::string::npos) { + legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK + } + } + presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname)); presence->setTo(m_conversationManager->getUser()->getJID().toString()); presence->setType(Swift::Presence::Available); diff --git a/src/user.cpp b/src/user.cpp index bd4c2726..53056d40 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -194,7 +194,8 @@ void User::handlePresence(Swift::Presence::ref presence) { if (isMUC) { if (presence->getType() == Swift::Presence::Unavailable) { LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << presence->getTo().getNode()); - onRoomLeft(presence->getTo().getNode()); + std::string room = Buddy::JIDToLegacyName(presence->getTo()); + onRoomLeft(room); } else { // force connection to legacy network to let backend to handle auto-join on connect. @@ -204,7 +205,8 @@ void User::handlePresence(Swift::Presence::ref presence) { onReadyToConnect(); } LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << presence->getTo().getNode() << " as " << presence->getTo().getResource()); - onRoomJoined(presence->getTo().getNode(), presence->getTo().getResource(), ""); + std::string room = Buddy::JIDToLegacyName(presence->getTo()); + onRoomJoined(room, presence->getTo().getResource(), ""); } return; } From ca227ccd26388b6bc8a06f0febbc9079461462b0 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Tue, 25 Oct 2011 23:47:56 +0200 Subject: [PATCH 09/26] Better PM --- backends/libircclient-qt/session.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backends/libircclient-qt/session.cpp b/backends/libircclient-qt/session.cpp index 508ab7f4..792bceed 100644 --- a/backends/libircclient-qt/session.cpp +++ b/backends/libircclient-qt/session.cpp @@ -163,7 +163,13 @@ void MyIrcBuffer::on_messageReceived(const QString& origin, const QString& messa // if (!suffix.empty()) { // r = receiver().replace('@', '%').toStdString(); // } - np->handleMessage(user, r + suffix, message.toStdString(), origin.toStdString()); + + if (r.find("#") == 0) { + np->handleMessage(user, r + suffix, message.toStdString(), origin.toStdString()); + } + else { + np->handleMessage(user, r + suffix, message.toStdString()); + } } void MyIrcBuffer::on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags) From 848f672b07e5e951a984448d8a3587c4499d6d5a Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 00:16:03 +0200 Subject: [PATCH 10/26] Use BasicTest in tests --- src/tests/basictest.cpp | 90 +++++++++++++++++++++++++++++ src/tests/basictest.h | 117 +++++++++++++++++++++++++++++++++++++ src/tests/component.cpp | 112 ++---------------------------------- src/tests/usermanager.cpp | 118 ++------------------------------------ 4 files changed, 216 insertions(+), 221 deletions(-) create mode 100644 src/tests/basictest.cpp create mode 100644 src/tests/basictest.h diff --git a/src/tests/basictest.cpp b/src/tests/basictest.cpp new file mode 100644 index 00000000..9de4b33a --- /dev/null +++ b/src/tests/basictest.cpp @@ -0,0 +1,90 @@ +#include "basictest.h" +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" +#include +#include +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" + +using namespace Transport; + +void BasicTest::setMeUp (void) { + streamEnded = false; + std::istringstream ifs("service.server_mode = 1\n"); + cfg = new Config(); + cfg->load(ifs); + + factory = new TestingFactory(); + + loop = new Swift::DummyEventLoop(); + factories = new Swift::DummyNetworkFactories(loop); + + userRegistry = new UserRegistry(cfg, factories); + + component = new Component(loop, factories, cfg, factory, userRegistry); + component->start(); + + userManager = new UserManager(component, userRegistry); + + payloadSerializers = new Swift::FullPayloadSerializerCollection(); + payloadParserFactories = new Swift::FullPayloadParserFactoryCollection(); + parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory()); + + serverFromClientSession = boost::shared_ptr(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(), + payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource"))); + serverFromClientSession->startSession(); + + serverFromClientSession->onDataWritten.connect(boost::bind(&BasicTest::handleDataReceived, this, _1)); + + dynamic_cast(component->getStanzaChannel())->addSession(serverFromClientSession); + parser->parse(""); + received.clear(); + loop->processEvents(); +} + +void BasicTest::tearMeDown (void) { + dynamic_cast(component->getStanzaChannel())->removeSession(serverFromClientSession); + delete component; + delete userRegistry; + delete factories; + delete factory; + delete loop; + delete cfg; + delete parser; + received.clear(); +} + +void BasicTest::handleDataReceived(const Swift::SafeByteArray &data) { +parser->parse(safeByteArrayToString(data)); +} + +void BasicTest::handleStreamStart(const Swift::ProtocolHeader&) { + +} + +void BasicTest::handleElement(boost::shared_ptr element) { +received.push_back(element); +} + +void BasicTest::handleStreamEnd() { + streamEnded = true; +} + +Swift::Stanza *BasicTest::getStanza(boost::shared_ptr element) { + Swift::Stanza *stanza = dynamic_cast(element.get()); + CPPUNIT_ASSERT(stanza); + return stanza; +} + diff --git a/src/tests/basictest.h b/src/tests/basictest.h new file mode 100644 index 00000000..6e093e33 --- /dev/null +++ b/src/tests/basictest.h @@ -0,0 +1,117 @@ +/** + * 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 "Swiften/Swiften.h" +#include "Swiften/Queries/SetResponder.h" +#include "transport/conversation.h" +#include "transport/conversationmanager.h" +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" + +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" + +using namespace Transport; + +class TestingConversation : public Conversation { + public: + TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) { + } + + // Called when there's new message to legacy network from XMPP network + void sendMessage(boost::shared_ptr &message) { + + } +}; + +class TestingFactory : public Factory { + public: + TestingFactory() { + } + + // Creates new conversation (NetworkConversation in this case) + Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) { + Conversation *nc = new TestingConversation(conversationManager, legacyName); + return nc; + } + + // Creates new LocalBuddy + Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) { + LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id); + buddy->setAlias(buddyInfo.alias); + buddy->setName(buddyInfo.legacyName); + buddy->setSubscription(buddyInfo.subscription); + buddy->setGroups(buddyInfo.groups); + buddy->setFlags((BuddyFlag) buddyInfo.flags); + if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) + buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s); + return buddy; + } +}; + +class BasicTest : public Swift::XMPPParserClient { + + public: + void setMeUp (void); + + void tearMeDown (void); + + void handleDataReceived(const Swift::SafeByteArray &data); + + void handleStreamStart(const Swift::ProtocolHeader&); + + void handleElement(boost::shared_ptr element); + + void handleStreamEnd(); + + Swift::Stanza *getStanza(boost::shared_ptr element); + + protected: + bool streamEnded; + UserManager *userManager; + boost::shared_ptr serverFromClientSession; + Swift::FullPayloadSerializerCollection* payloadSerializers; + Swift::FullPayloadParserFactoryCollection* payloadParserFactories; + Swift::XMPPParser *parser; + UserRegistry *userRegistry; + Config *cfg; + Swift::Server *server; + Swift::DummyNetworkFactories *factories; + Swift::DummyEventLoop *loop; + TestingFactory *factory; + Component *component; + std::vector > received; +}; + diff --git a/src/tests/component.cpp b/src/tests/component.cpp index 8d4b3be9..a3f709b5 100644 --- a/src/tests/component.cpp +++ b/src/tests/component.cpp @@ -14,45 +14,11 @@ #include "Swiften/Server/ServerFromClientSession.h" #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" + using namespace Transport; -class TestingConversation : public Conversation { - public: - TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) { - } - - // Called when there's new message to legacy network from XMPP network - void sendMessage(boost::shared_ptr &message) { - - } -}; - -class TestingFactory : public Factory { - public: - TestingFactory() { - } - - // Creates new conversation (NetworkConversation in this case) - Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) { - Conversation *nc = new TestingConversation(conversationManager, legacyName); - return nc; - } - - // Creates new LocalBuddy - Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) { - LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id); - buddy->setAlias(buddyInfo.alias); - buddy->setName(buddyInfo.legacyName); - buddy->setSubscription(buddyInfo.subscription); - buddy->setGroups(buddyInfo.groups); - buddy->setFlags((BuddyFlag) buddyInfo.flags); - if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) - buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s); - return buddy; - } -}; - -class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParserClient { +class ComponentTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(ComponentTest); CPPUNIT_TEST(handlePresenceWithNode); CPPUNIT_TEST(handlePresenceWithoutNode); @@ -62,48 +28,14 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser void setUp (void) { onUserPresenceReceived = false; onUserDiscoInfoReceived = false; - std::istringstream ifs("service.server_mode = 1\n"); - cfg = new Config(); - cfg->load(ifs); - factory = new TestingFactory(); - - loop = new Swift::DummyEventLoop(); - factories = new Swift::DummyNetworkFactories(loop); - - userRegistry = new UserRegistry(cfg, factories); - - component = new Component(loop, factories, cfg, factory, userRegistry); + setMeUp(); component->onUserPresenceReceived.connect(boost::bind(&ComponentTest::handleUserPresenceReceived, this, _1)); component->onUserDiscoInfoReceived.connect(boost::bind(&ComponentTest::handleUserDiscoInfoReceived, this, _1, _2)); - component->start(); - - payloadSerializers = new Swift::FullPayloadSerializerCollection(); - payloadParserFactories = new Swift::FullPayloadParserFactoryCollection(); - parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory()); - - serverFromClientSession = boost::shared_ptr(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(), - payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource"))); - serverFromClientSession->startSession(); - - serverFromClientSession->onDataWritten.connect(boost::bind(&ComponentTest::handleDataReceived, this, _1)); - - dynamic_cast(component->getStanzaChannel())->addSession(serverFromClientSession); - parser->parse(""); - received.clear(); - loop->processEvents(); } void tearDown (void) { - dynamic_cast(component->getStanzaChannel())->removeSession(serverFromClientSession); - delete component; - delete userRegistry; - delete factories; - delete factory; - delete loop; - delete cfg; - delete parser; - received.clear(); + tearMeDown(); } void handleUserDiscoInfoReceived(const Swift::JID& jid, boost::shared_ptr info) { @@ -114,22 +46,6 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser onUserPresenceReceived = true; } - void handleDataReceived(const Swift::SafeByteArray &data) { - parser->parse(safeByteArrayToString(data)); - } - - void handleStreamStart(const Swift::ProtocolHeader&) { - - } - - void handleElement(boost::shared_ptr element) { - received.push_back(element); - } - - void handleStreamEnd() { - - } - void handlePresenceWithNode() { Swift::Presence::ref response = Swift::Presence::create(); response->setTo("somebody@localhost"); @@ -151,27 +67,9 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser CPPUNIT_ASSERT(onUserPresenceReceived); } - Swift::Stanza *getStanza(boost::shared_ptr element) { - Swift::Stanza *stanza = dynamic_cast(element.get()); - CPPUNIT_ASSERT(stanza); - return stanza; - } - private: bool onUserPresenceReceived; bool onUserDiscoInfoReceived; - boost::shared_ptr serverFromClientSession; - Swift::FullPayloadSerializerCollection* payloadSerializers; - Swift::FullPayloadParserFactoryCollection* payloadParserFactories; - Swift::XMPPParser *parser; - UserRegistry *userRegistry; - Config *cfg; - Swift::Server *server; - Swift::DummyNetworkFactories *factories; - Swift::DummyEventLoop *loop; - TestingFactory *factory; - Component *component; - std::vector > received; }; CPPUNIT_TEST_SUITE_REGISTRATION (ComponentTest); diff --git a/src/tests/usermanager.cpp b/src/tests/usermanager.cpp index 428892c7..b67c8e88 100644 --- a/src/tests/usermanager.cpp +++ b/src/tests/usermanager.cpp @@ -16,46 +16,11 @@ #include "Swiften/Server/ServerStanzaChannel.h" #include "Swiften/Server/ServerFromClientSession.h" #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" using namespace Transport; -class TestingConversation : public Conversation { - public: - TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) { - } - - // Called when there's new message to legacy network from XMPP network - void sendMessage(boost::shared_ptr &message) { - - } -}; - -class TestingFactory : public Factory { - public: - TestingFactory() { - } - - // Creates new conversation (NetworkConversation in this case) - Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) { - Conversation *nc = new TestingConversation(conversationManager, legacyName); - return nc; - } - - // Creates new LocalBuddy - Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) { - LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id); - buddy->setAlias(buddyInfo.alias); - buddy->setName(buddyInfo.legacyName); - buddy->setSubscription(buddyInfo.subscription); - buddy->setGroups(buddyInfo.groups); - buddy->setFlags((BuddyFlag) buddyInfo.flags); - if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) - buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s); - return buddy; - } -}; - -class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParserClient { +class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(UserManagerTest); CPPUNIT_TEST(connectUser); CPPUNIT_TEST(handleProbePresence); @@ -64,67 +29,13 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPPars public: void setUp (void) { - streamEnded = false; - std::istringstream ifs("service.server_mode = 1\n"); - cfg = new Config(); - cfg->load(ifs); - - factory = new TestingFactory(); - - loop = new Swift::DummyEventLoop(); - factories = new Swift::DummyNetworkFactories(loop); - - userRegistry = new UserRegistry(cfg, factories); - - component = new Component(loop, factories, cfg, factory, userRegistry); - component->start(); - - userManager = new UserManager(component, userRegistry); - - payloadSerializers = new Swift::FullPayloadSerializerCollection(); - payloadParserFactories = new Swift::FullPayloadParserFactoryCollection(); - parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory()); - - serverFromClientSession = boost::shared_ptr(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(), - payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource"))); - serverFromClientSession->startSession(); - - serverFromClientSession->onDataWritten.connect(boost::bind(&UserManagerTest::handleDataReceived, this, _1)); - - dynamic_cast(component->getStanzaChannel())->addSession(serverFromClientSession); - parser->parse(""); - received.clear(); - loop->processEvents(); + setMeUp(); } void tearDown (void) { - dynamic_cast(component->getStanzaChannel())->removeSession(serverFromClientSession); - delete component; - delete userRegistry; - delete factories; - delete factory; - delete loop; - delete cfg; - delete parser; - received.clear(); + tearMeDown(); } - void handleDataReceived(const Swift::SafeByteArray &data) { - parser->parse(safeByteArrayToString(data)); - } - - void handleStreamStart(const Swift::ProtocolHeader&) { - - } - - void handleElement(boost::shared_ptr element) { - received.push_back(element); - } - - void handleStreamEnd() { - streamEnded = true; - } - void connectUser() { CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); @@ -175,27 +86,6 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPPars CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType()); } - Swift::Stanza *getStanza(boost::shared_ptr element) { - Swift::Stanza *stanza = dynamic_cast(element.get()); - CPPUNIT_ASSERT(stanza); - return stanza; - } - - private: - bool streamEnded; - UserManager *userManager; - boost::shared_ptr serverFromClientSession; - Swift::FullPayloadSerializerCollection* payloadSerializers; - Swift::FullPayloadParserFactoryCollection* payloadParserFactories; - Swift::XMPPParser *parser; - UserRegistry *userRegistry; - Config *cfg; - Swift::Server *server; - Swift::DummyNetworkFactories *factories; - Swift::DummyEventLoop *loop; - TestingFactory *factory; - Component *component; - std::vector > received; }; CPPUNIT_TEST_SUITE_REGISTRATION (UserManagerTest); From 8aff527f6d669e612bd91637790e17ea44fefc1d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 00:32:15 +0200 Subject: [PATCH 11/26] Dummy user.cpp test --- src/tests/user.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/tests/user.cpp diff --git a/src/tests/user.cpp b/src/tests/user.cpp new file mode 100644 index 00000000..864cbeba --- /dev/null +++ b/src/tests/user.cpp @@ -0,0 +1,81 @@ +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" +#include +#include +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" + +using namespace Transport; + +class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { + CPPUNIT_TEST_SUITE(UserTest); + CPPUNIT_TEST(sendCurrentPresence); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp (void) { + setMeUp(); + connectUser(); + received.clear(); + } + + void tearDown (void) { + disconnectUser(); + tearMeDown(); + } + + void connectUser() { + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); + loop->processEvents(); + CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount()); + + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + UserInfo userInfo = user->getUserInfo(); + CPPUNIT_ASSERT_EQUAL(std::string("password"), userInfo.password); + CPPUNIT_ASSERT(user->isReadyToConnect() == true); + CPPUNIT_ASSERT(user->isConnected() == false); + + user->setConnected(true); + CPPUNIT_ASSERT(user->isConnected() == true); + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + } + + void sendCurrentPresence() { + User *user = userManager->getUser("user@localhost"); + user->sendCurrentPresence(); + + // We're not forwarding current presence in server-mode + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); + } + + void disconnectUser() { + userManager->disconnectUser("user@localhost"); + dynamic_cast(factories->getTimerFactory())->setTime(10); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION (UserTest); From 8e7146a496614fc4770788f661a341d9285845e2 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 12:29:06 +0200 Subject: [PATCH 12/26] Include QtNetwork directory --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 531b0591..75aca2ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ find_package(event) find_package(Doxygen) INCLUDE(FindQt4) -FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork) +FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork REQUIRED) # ADD_DEFINITIONS(${SWIFTEN_CFLAGS}) ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS) @@ -104,6 +104,7 @@ if (PROTOBUF_FOUND) if(IRC_FOUND) ADD_DEFINITIONS(-DIRC_SHARED) message("IRC plugin : yes") + include_directories(${QT_QTNETWORK_INCLUDE_DIR}) include_directories(${IRC_INCLUDE_DIR}) include(${QT_USE_FILE}) else() From 04cbb3a90713d06e05a197d54d8f4698d0822942 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 16:06:24 +0200 Subject: [PATCH 13/26] More UserTest tests + fixes of some bugs found by tests --- .../Swiften/Server/ServerStanzaChannel.cpp | 2 +- src/tests/basictest.cpp | 9 +- src/tests/basictest.h | 2 + src/tests/user.cpp | 125 ++++++++++++++++++ src/user.cpp | 8 +- 5 files changed, 141 insertions(+), 5 deletions(-) diff --git a/include/Swiften/Server/ServerStanzaChannel.cpp b/include/Swiften/Server/ServerStanzaChannel.cpp index a0f56543..bb3fbf6e 100644 --- a/include/Swiften/Server/ServerStanzaChannel.cpp +++ b/include/Swiften/Server/ServerStanzaChannel.cpp @@ -73,7 +73,7 @@ void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptrfinishSession(); - std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n"; +// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n"; if (last) { break; } diff --git a/src/tests/basictest.cpp b/src/tests/basictest.cpp index 9de4b33a..73524063 100644 --- a/src/tests/basictest.cpp +++ b/src/tests/basictest.cpp @@ -22,7 +22,7 @@ using namespace Transport; void BasicTest::setMeUp (void) { streamEnded = false; - std::istringstream ifs("service.server_mode = 1\n"); + std::istringstream ifs("service.server_mode = 1\nservice.jid=localhost"); cfg = new Config(); cfg->load(ifs); @@ -67,7 +67,8 @@ void BasicTest::tearMeDown (void) { } void BasicTest::handleDataReceived(const Swift::SafeByteArray &data) { -parser->parse(safeByteArrayToString(data)); +// std::cout << safeByteArrayToString(data) << "\n"; + parser->parse(safeByteArrayToString(data)); } void BasicTest::handleStreamStart(const Swift::ProtocolHeader&) { @@ -82,6 +83,10 @@ void BasicTest::handleStreamEnd() { streamEnded = true; } +void BasicTest::injectPresence(boost::shared_ptr &response) { + dynamic_cast(component->getStanzaChannel())->onPresenceReceived(response); +} + Swift::Stanza *BasicTest::getStanza(boost::shared_ptr element) { Swift::Stanza *stanza = dynamic_cast(element.get()); CPPUNIT_ASSERT(stanza); diff --git a/src/tests/basictest.h b/src/tests/basictest.h index 6e093e33..525592ec 100644 --- a/src/tests/basictest.h +++ b/src/tests/basictest.h @@ -96,6 +96,8 @@ class BasicTest : public Swift::XMPPParserClient { void handleStreamEnd(); + void injectPresence(boost::shared_ptr &response); + Swift::Stanza *getStanza(boost::shared_ptr element); protected: diff --git a/src/tests/user.cpp b/src/tests/user.cpp index 864cbeba..a35ac423 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -23,20 +23,65 @@ using namespace Transport; class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(UserTest); CPPUNIT_TEST(sendCurrentPresence); + CPPUNIT_TEST(handlePresence); + CPPUNIT_TEST(handlePresenceJoinRoom); + CPPUNIT_TEST(handlePresenceLeaveRoom); + CPPUNIT_TEST(handleDisconnected); CPPUNIT_TEST_SUITE_END(); public: + std::string room; + std::string roomNickname; + std::string roomPassword; + bool readyToConnect; + bool disconnected; + Swift::Presence::ref changedPresence; + void setUp (void) { + disconnected = false; + readyToConnect = false; + changedPresence = Swift::Presence::ref(); + room = ""; + roomNickname = ""; + roomPassword = ""; + setMeUp(); + userManager->onUserCreated.connect(boost::bind(&UserTest::handleUserCreated, this, _1)); connectUser(); received.clear(); } void tearDown (void) { + received.clear(); disconnectUser(); tearMeDown(); } + void handleUserCreated(User *user) { + user->onReadyToConnect.connect(boost::bind(&UserTest::handleUserReadyToConnect, this, user)); + user->onPresenceChanged.connect(boost::bind(&UserTest::handleUserPresenceChanged, this, user, _1)); + user->onRoomJoined.connect(boost::bind(&UserTest::handleRoomJoined, this, user, _1, _2, _3)); + user->onRoomLeft.connect(boost::bind(&UserTest::handleRoomLeft, this, user, _1)); + } + + void handleUserReadyToConnect(User *user) { + readyToConnect = true; + } + + void handleUserPresenceChanged(User *user, Swift::Presence::ref presence) { + changedPresence = presence; + } + + void handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) { + room = r; + roomNickname = nickname; + roomPassword = password; + } + + void handleRoomLeft(User *user, const std::string &r) { + room = r; + } + void connectUser() { CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); @@ -51,11 +96,14 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT(user->isReadyToConnect() == true); CPPUNIT_ASSERT(user->isConnected() == false); + CPPUNIT_ASSERT_EQUAL(true, readyToConnect); + user->setConnected(true); CPPUNIT_ASSERT(user->isConnected() == true); CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + received.clear(); } void sendCurrentPresence() { @@ -66,7 +114,84 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); } + void handlePresence() { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("localhost"); + response->setFrom("user@localhost/resource"); + response->setShow(Swift::StatusShow::Away); + + injectPresence(response); + loop->processEvents(); + + // no presence received in server mode, just disco#info + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + + CPPUNIT_ASSERT(changedPresence); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, changedPresence->getShow()); + } + + void handlePresenceJoinRoom() { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("#room@localhost/hanzz"); + response->setFrom("user@localhost/resource"); + + Swift::MUCPayload *payload = new Swift::MUCPayload(); + payload->setPassword("password"); + response->addPayload(boost::shared_ptr(payload)); + injectPresence(response); + loop->processEvents(); + + // no presence received in server mode, just disco#info + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + + CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); + } + + void handlePresenceLeaveRoom() { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("#room@localhost/hanzz"); + response->setFrom("user@localhost/resource"); + response->setType(Swift::Presence::Unavailable); + + Swift::MUCPayload *payload = new Swift::MUCPayload(); + payload->setPassword("password"); + response->addPayload(boost::shared_ptr(payload)); + injectPresence(response); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); + + CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); + } + + void handleDisconnected() { + User *user = userManager->getUser("user@localhost"); + user->handleDisconnected("Connection error"); + loop->processEvents(); + + CPPUNIT_ASSERT(streamEnded); + user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(!user); + + CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); + Swift::Message *m = dynamic_cast(getStanza(received[0])); + CPPUNIT_ASSERT_EQUAL(std::string("Connection error"), m->getBody()); + + CPPUNIT_ASSERT(dynamic_cast(received[1].get())); + CPPUNIT_ASSERT_EQUAL(std::string("Connection error"), dynamic_cast(received[1].get())->getText()); + + disconnected = true; + } + void disconnectUser() { + if (disconnected) + return; userManager->disconnectUser("user@localhost"); dynamic_cast(factories->getTimerFactory())->setTime(10); loop->processEvents(); diff --git a/src/user.cpp b/src/user.cpp index 53056d40..c66da595 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -206,7 +206,11 @@ void User::handlePresence(Swift::Presence::ref presence) { } LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << presence->getTo().getNode() << " as " << presence->getTo().getResource()); std::string room = Buddy::JIDToLegacyName(presence->getTo()); - onRoomJoined(room, presence->getTo().getResource(), ""); + std::string password = ""; + if (presence->getPayload() != NULL) { + password = presence->getPayload()->getPassword() ? *presence->getPayload()->getPassword() : ""; + } + onRoomJoined(room, presence->getTo().getResource(), password); } return; } @@ -300,7 +304,7 @@ void User::handleDisconnected(const std::string &error) { // We can't be sure finishSession sends unavailable presence everytime, so check if user gets removed // in finishSession(...) call and if not, remove it here. std::string jid = m_jid.toBare().toString(); - dynamic_cast(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr(new Swift::StreamError(Swift::StreamError::UndefinedCondition, "test"))); + dynamic_cast(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr(new Swift::StreamError(Swift::StreamError::UndefinedCondition, error))); if (m_userManager->getUser(jid) != NULL) { m_userManager->removeUser(this); } From c82202f16bdad4a0aeab37912a5db0ba510415b6 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 16:53:41 +0200 Subject: [PATCH 14/26] initial RosterManagerTest --- include/transport/localbuddy.h | 1 + src/localbuddy.cpp | 6 ++ src/tests/rostermanager.cpp | 126 +++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 src/tests/rostermanager.cpp diff --git a/include/transport/localbuddy.h b/include/transport/localbuddy.h index 26b61983..c8f81174 100644 --- a/include/transport/localbuddy.h +++ b/include/transport/localbuddy.h @@ -63,6 +63,7 @@ class LocalBuddy : public Buddy { std::string m_statusMessage; std::string m_iconHash; Swift::StatusShow m_status; + bool m_firstSet; }; } diff --git a/src/localbuddy.cpp b/src/localbuddy.cpp index ce64ad87..a12b9ee9 100644 --- a/src/localbuddy.cpp +++ b/src/localbuddy.cpp @@ -25,12 +25,18 @@ namespace Transport { LocalBuddy::LocalBuddy(RosterManager *rosterManager, long id) : Buddy(rosterManager, id) { m_status = Swift::StatusShow::None; + m_firstSet = true; } LocalBuddy::~LocalBuddy() { } void LocalBuddy::setAlias(const std::string &alias) { + if (m_firstSet) { + m_firstSet = false; + m_alias = alias; + return; + } bool changed = m_alias != alias; m_alias = alias; diff --git a/src/tests/rostermanager.cpp b/src/tests/rostermanager.cpp new file mode 100644 index 00000000..860308e0 --- /dev/null +++ b/src/tests/rostermanager.cpp @@ -0,0 +1,126 @@ +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" +#include +#include +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" + +using namespace Transport; + +class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { + CPPUNIT_TEST_SUITE(RosterManagerTest); + CPPUNIT_TEST(setBuddy); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp (void) { + setMeUp(); + userManager->onUserCreated.connect(boost::bind(&RosterManagerTest::handleUserCreated, this, _1)); + connectUser(); + received.clear(); + } + + void tearDown (void) { + received.clear(); + disconnectUser(); + tearMeDown(); + } + + void handleUserCreated(User *user) { + + } + + void connectUser() { + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); + loop->processEvents(); + CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount()); + + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + UserInfo userInfo = user->getUserInfo(); + CPPUNIT_ASSERT_EQUAL(std::string("password"), userInfo.password); + CPPUNIT_ASSERT(user->isReadyToConnect() == true); + CPPUNIT_ASSERT(user->isConnected() == false); + + user->setConnected(true); + CPPUNIT_ASSERT(user->isConnected() == true); + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + received.clear(); + } + + void add2Buddies() { + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + LocalBuddy *buddy = new LocalBuddy(user->getRosterManager(), -1); + buddy->setFlags(BUDDY_JID_ESCAPING); + buddy->setName("buddy1"); + buddy->setAlias("Buddy 1"); + std::vector grp; + grp.push_back("group1"); + buddy->setGroups(grp); + buddy->setStatus(Swift::StatusShow(Swift::StatusShow::Away), "status1"); + user->getRosterManager()->setBuddy(buddy); + + buddy = new LocalBuddy(user->getRosterManager(), -1); + buddy->setFlags(BUDDY_JID_ESCAPING); + buddy->setName("buddy2"); + buddy->setAlias("Buddy 2"); + std::vector grp2; + grp2.push_back("group2"); + buddy->setGroups(grp2); + buddy->setStatus(Swift::StatusShow(Swift::StatusShow::Away), "status2"); + user->getRosterManager()->setBuddy(buddy); + } + + void setBuddy() { + add2Buddies(); + CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); + + Swift::RosterPayload::ref payload = getStanza(received[0])->getPayload(); + CPPUNIT_ASSERT(payload); + CPPUNIT_ASSERT_EQUAL(1, (int) payload->getItems().size()); + Swift::RosterItemPayload item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), Buddy::JIDToLegacyName(item.getJID())); + CPPUNIT_ASSERT_EQUAL(std::string("Buddy 1"), item.getName()); + + payload = getStanza(received[1])->getPayload(); + CPPUNIT_ASSERT(payload); + CPPUNIT_ASSERT_EQUAL(1, (int) payload->getItems().size()); + item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(std::string("buddy2"), Buddy::JIDToLegacyName(item.getJID())); + CPPUNIT_ASSERT_EQUAL(std::string("Buddy 2"), item.getName()); + + // TODO send response and check for presence + } + + void disconnectUser() { + userManager->disconnectUser("user@localhost"); + dynamic_cast(factories->getTimerFactory())->setTime(10); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION (RosterManagerTest); From 9e05a8dffbe8862312795b82d6e130e808f440c3 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 17:24:33 +0200 Subject: [PATCH 15/26] more tests --- src/tests/basictest.cpp | 4 ++++ src/tests/basictest.h | 1 + src/tests/rostermanager.cpp | 23 ++++++++++++++--------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/tests/basictest.cpp b/src/tests/basictest.cpp index 73524063..7a4568c9 100644 --- a/src/tests/basictest.cpp +++ b/src/tests/basictest.cpp @@ -87,6 +87,10 @@ void BasicTest::injectPresence(boost::shared_ptr &response) { dynamic_cast(component->getStanzaChannel())->onPresenceReceived(response); } +void BasicTest::injectIQ(boost::shared_ptr iq) { + dynamic_cast(component->getStanzaChannel())->onIQReceived(iq); +} + Swift::Stanza *BasicTest::getStanza(boost::shared_ptr element) { Swift::Stanza *stanza = dynamic_cast(element.get()); CPPUNIT_ASSERT(stanza); diff --git a/src/tests/basictest.h b/src/tests/basictest.h index 525592ec..c67691b3 100644 --- a/src/tests/basictest.h +++ b/src/tests/basictest.h @@ -97,6 +97,7 @@ class BasicTest : public Swift::XMPPParserClient { void handleStreamEnd(); void injectPresence(boost::shared_ptr &response); + void injectIQ(boost::shared_ptr iq); Swift::Stanza *getStanza(boost::shared_ptr element); diff --git a/src/tests/rostermanager.cpp b/src/tests/rostermanager.cpp index 860308e0..d29cb5bb 100644 --- a/src/tests/rostermanager.cpp +++ b/src/tests/rostermanager.cpp @@ -94,21 +94,26 @@ class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { add2Buddies(); CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); - Swift::RosterPayload::ref payload = getStanza(received[0])->getPayload(); - CPPUNIT_ASSERT(payload); - CPPUNIT_ASSERT_EQUAL(1, (int) payload->getItems().size()); - Swift::RosterItemPayload item = payload->getItems()[0]; + Swift::RosterPayload::ref payload1 = getStanza(received[0])->getPayload(); + CPPUNIT_ASSERT(payload1); + CPPUNIT_ASSERT_EQUAL(1, (int) payload1->getItems().size()); + Swift::RosterItemPayload item = payload1->getItems()[0]; CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), Buddy::JIDToLegacyName(item.getJID())); CPPUNIT_ASSERT_EQUAL(std::string("Buddy 1"), item.getName()); - payload = getStanza(received[1])->getPayload(); - CPPUNIT_ASSERT(payload); - CPPUNIT_ASSERT_EQUAL(1, (int) payload->getItems().size()); - item = payload->getItems()[0]; + Swift::RosterPayload::ref payload2 = getStanza(received[1])->getPayload(); + CPPUNIT_ASSERT(payload2); + CPPUNIT_ASSERT_EQUAL(1, (int) payload2->getItems().size()); + item = payload2->getItems()[0]; CPPUNIT_ASSERT_EQUAL(std::string("buddy2"), Buddy::JIDToLegacyName(item.getJID())); CPPUNIT_ASSERT_EQUAL(std::string("Buddy 2"), item.getName()); - // TODO send response and check for presence + // send responses back + injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID())); + injectIQ(Swift::IQ::createResult(getStanza(received[1])->getFrom(), getStanza(received[1])->getTo(), getStanza(received[1])->getID())); + + // we should get presences + CPPUNIT_ASSERT_EQUAL(4, (int) received.size()); } void disconnectUser() { From 2faaeff76d3eb99f190c9ff06a991fad100e4b84 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 17:49:05 +0200 Subject: [PATCH 16/26] Reconnect mysql connection when it's lost.. NOT TESTED, I will test it after hour :) --- include/transport/mysqlbackend.h | 5 ++- src/mysqlbackend.cpp | 56 ++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/include/transport/mysqlbackend.h b/include/transport/mysqlbackend.h index 04c00b7a..625491d3 100644 --- a/include/transport/mysqlbackend.h +++ b/include/transport/mysqlbackend.h @@ -48,6 +48,7 @@ class MySQLBackend : public StorageBackend /// automatically. /// \return true if database is opened successfully. bool connect(); + void disconnect(); /// Creates database structure. /// \see connect() @@ -100,7 +101,7 @@ class MySQLBackend : public StorageBackend Statement(MYSQL *conn, const std::string &format, const std::string &statement); ~Statement(); - bool execute(); + int execute(); int fetch(); @@ -126,6 +127,8 @@ class MySQLBackend : public StorageBackend std::string m_string; }; + bool exec(Statement *stmt); + MYSQL m_conn; Config *m_config; std::string m_prefix; diff --git a/src/mysqlbackend.cpp b/src/mysqlbackend.cpp index 0bad7c63..5631eff2 100644 --- a/src/mysqlbackend.cpp +++ b/src/mysqlbackend.cpp @@ -184,7 +184,7 @@ MySQLBackend::Statement::~Statement() { FINALIZE_STMT(m_stmt); } -bool MySQLBackend::Statement::execute() { +int MySQLBackend::Statement::execute() { // If statement has some input and doesn't have any output, we have // to clear the offset now, because operator>> will not be called. m_offset = 0; @@ -193,9 +193,9 @@ bool MySQLBackend::Statement::execute() { if ((ret = mysql_stmt_execute(m_stmt)) != 0) { LOG4CXX_ERROR(logger, m_string << " " << mysql_stmt_error(m_stmt) << "; " << mysql_error(m_conn)); - return false; + return mysql_stmt_errno(m_stmt); } - return true; + return 0; } int MySQLBackend::Statement::fetch() { @@ -263,6 +263,10 @@ MySQLBackend::MySQLBackend(Config *config) { } MySQLBackend::~MySQLBackend(){ + disconnect(); +} + +void MySQLBackend::disconnect() { delete m_setUser; delete m_getUser; delete m_removeUser; @@ -387,14 +391,30 @@ bool MySQLBackend::exec(const std::string &query) { return true; } +bool MySQLBackend::exec(Statement *stmt) { + for (int i = 20; i > 0; i--) { + int ret = stmt->execute(); + if (ret == 0) + return true; + if (ret == 2013) { + disconnect(); + connect(); + } + if (i != 20) { + sleep(1); + } + } + return false; +} + void MySQLBackend::setUser(const UserInfo &user) { *m_setUser << user.jid << user.uin << user.password << user.language << user.encoding << user.vip << user.password; - m_setUser->execute(); + exec(m_setUser); } bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) { *m_getUser << barejid; - if (!m_getUser->execute()) + if (!exec(m_getUser)) return false; int ret = false; @@ -408,7 +428,7 @@ bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) { void MySQLBackend::setUserOnline(long id, bool online) { *m_setUserOnline << online << id; - m_setUserOnline->execute(); + exec(m_setUserOnline); } long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) { @@ -417,14 +437,14 @@ long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) { *m_addBuddy << (buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); *m_addBuddy << buddyInfo.alias << buddyInfo.flags; - m_addBuddy->execute(); + exec(m_addBuddy); long id = (long) mysql_insert_id(&m_conn); // INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) if (!buddyInfo.settings.find("icon_hash")->second.s.empty()) { *m_updateBuddySetting << userId << id << buddyInfo.settings.find("icon_hash")->first << (int) TYPE_STRING << buddyInfo.settings.find("icon_hash")->second.s << buddyInfo.settings.find("icon_hash")->second.s; - m_updateBuddySetting->execute(); + exec(m_updateBuddySetting); } return id; @@ -436,7 +456,7 @@ void MySQLBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) { *m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription; *m_updateBuddy << userId << buddyInfo.legacyName; - m_updateBuddy->execute(); + exec(m_updateBuddy); } bool MySQLBackend::getBuddies(long id, std::list &roster) { @@ -450,7 +470,7 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { long buddy_id = -1; std::string key; - if (!m_getBuddies->execute()) + if (!exec(m_getBuddies)) return false; while (m_getBuddies->fetch() == 0) { @@ -465,7 +485,7 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { roster.push_back(b); } - if (!m_getBuddiesSettings->execute()) + if (!exec(m_getBuddiesSettings)) return false; BOOST_FOREACH(BuddyInfo &b, roster) { @@ -511,19 +531,19 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { bool MySQLBackend::removeUser(long id) { *m_removeUser << (int) id; - if (!m_removeUser->execute()) + if (!exec(m_removeUser)) return false; *m_removeUserSettings << (int) id; - if (!m_removeUserSettings->execute()) + if (!exec(m_removeUserSettings)) return false; *m_removeUserBuddies << (int) id; - if (!m_removeUserBuddies->execute()) + if (!exec(m_removeUserBuddies)) return false; *m_removeUserBuddiesSettings << (int) id; - if (!m_removeUserBuddiesSettings->execute()) + if (!exec(m_removeUserBuddiesSettings)) return false; return true; @@ -532,11 +552,11 @@ bool MySQLBackend::removeUser(long id) { void MySQLBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) { // "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?" *m_getUserSetting << id << variable; - m_getUserSetting->execute(); + exec(m_getUserSetting); if (m_getUserSetting->fetch() != 0) { // "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)" *m_setUserSetting << id << variable << type << value; - m_setUserSetting->execute(); + exec(m_setUserSetting); } else { *m_getUserSetting >> type >> value; @@ -546,7 +566,7 @@ void MySQLBackend::getUserSetting(long id, const std::string &variable, int &typ void MySQLBackend::updateUserSetting(long id, const std::string &variable, const std::string &value) { // "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?" *m_updateUserSetting << value << id << variable; - m_updateUserSetting->execute(); + exec(m_updateUserSetting); } void MySQLBackend::beginTransaction() { From 1a4b25835e7d7102891da7fdcf9ce5f4afe98ff7 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 17:58:13 +0200 Subject: [PATCH 17/26] RosterManagerTest: check received presences --- src/tests/rostermanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/rostermanager.cpp b/src/tests/rostermanager.cpp index d29cb5bb..b2803a12 100644 --- a/src/tests/rostermanager.cpp +++ b/src/tests/rostermanager.cpp @@ -114,6 +114,13 @@ class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // we should get presences CPPUNIT_ASSERT_EQUAL(4, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[2]))); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received[2]))->getShow()); + CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast(getStanza(received[2]))->getStatus()); + + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[3]))); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received[3]))->getShow()); + CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast(getStanza(received[3]))->getStatus()); } void disconnectUser() { From f57929c659c09e889881e474d0236de747b40e66 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 26 Oct 2011 18:03:35 +0200 Subject: [PATCH 18/26] RosterManagerTest: sendCurrentPresences --- src/tests/rostermanager.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/tests/rostermanager.cpp b/src/tests/rostermanager.cpp index b2803a12..85238a97 100644 --- a/src/tests/rostermanager.cpp +++ b/src/tests/rostermanager.cpp @@ -23,6 +23,7 @@ using namespace Transport; class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(RosterManagerTest); CPPUNIT_TEST(setBuddy); + CPPUNIT_TEST(sendCurrentPresences); CPPUNIT_TEST_SUITE_END(); public: @@ -123,6 +124,23 @@ class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast(getStanza(received[3]))->getStatus()); } + void sendCurrentPresences() { + setBuddy(); + received.clear(); + + User *user = userManager->getUser("user@localhost"); + user->getRosterManager()->sendCurrentPresences("user@localhost/resource"); + + CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); +// CPPUNIT_ASSERT(dynamic_cast(getStanza(received[2]))); +// CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received[2]))->getShow()); +// CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast(getStanza(received[2]))->getStatus()); +// +// CPPUNIT_ASSERT(dynamic_cast(getStanza(received[3]))); +// CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received[3]))->getShow()); +// CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast(getStanza(received[3]))->getStatus()); + } + void disconnectUser() { userManager->disconnectUser("user@localhost"); dynamic_cast(factories->getTimerFactory())->setTime(10); From 343349cea6f274ad8e4d2ff26f5c95fee8030081 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 22:28:05 +0200 Subject: [PATCH 19/26] Working MySQL reconnecting --- include/transport/mysqlbackend.h | 2 - src/mysqlbackend.cpp | 75 +++++++++++++++++--------------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/include/transport/mysqlbackend.h b/include/transport/mysqlbackend.h index 625491d3..b35a345d 100644 --- a/include/transport/mysqlbackend.h +++ b/include/transport/mysqlbackend.h @@ -127,8 +127,6 @@ class MySQLBackend : public StorageBackend std::string m_string; }; - bool exec(Statement *stmt); - MYSQL m_conn; Config *m_config; std::string m_prefix; diff --git a/src/mysqlbackend.cpp b/src/mysqlbackend.cpp index 5631eff2..97549724 100644 --- a/src/mysqlbackend.cpp +++ b/src/mysqlbackend.cpp @@ -29,7 +29,7 @@ using namespace log4cxx; #define MYSQL_DB_VERSION 2 #define CHECK_DB_RESPONSE(stmt) \ if(stmt) { \ - sqlite3_exec(m_db, "ROLLBACK;", NULL, NULL, NULL); \ + sqlite3_EXEC(m_db, "ROLLBACK;", NULL, NULL, NULL); \ return 0; \ } @@ -72,11 +72,26 @@ using namespace log4cxx; LOG4CXX_ERROR(logger, NAME << " " << mysql_error(&m_conn)); \ } +#define EXEC(STMT, METHOD) \ + {\ + int ret = STMT->execute(); \ + if (ret == 0) \ + exec_ok = true; \ + else if (ret == 2013) { \ + disconnect(); \ + connect(); \ + return METHOD; \ + } \ + else \ + exec_ok = false; \ + } + using namespace boost; namespace Transport { static LoggerPtr logger = Logger::getLogger("MySQLBackend"); +static bool exec_ok; MySQLBackend::Statement::Statement(MYSQL *conn, const std::string &format, const std::string &statement) { m_resultOffset = -1; @@ -256,10 +271,10 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator >> (std::string& t) { MySQLBackend::MySQLBackend(Config *config) { m_config = config; + m_prefix = CONFIG_STRING(m_config, "database.prefix"); mysql_init(&m_conn); my_bool my_true = 1; mysql_options(&m_conn, MYSQL_OPT_RECONNECT, &my_true); - m_prefix = CONFIG_STRING(m_config, "database.prefix"); } MySQLBackend::~MySQLBackend(){ @@ -267,6 +282,7 @@ MySQLBackend::~MySQLBackend(){ } void MySQLBackend::disconnect() { + LOG4CXX_INFO(logger, "Disconnecting"); delete m_setUser; delete m_getUser; delete m_removeUser; @@ -290,7 +306,7 @@ bool MySQLBackend::connect() { CONFIG_STRING(m_config, "database.user") << ", database " << CONFIG_STRING(m_config, "database.database") << ", port " << CONFIG_INT(m_config, "database.port") ); - + if (!mysql_real_connect(&m_conn, CONFIG_STRING(m_config, "database.server").c_str(), CONFIG_STRING(m_config, "database.user").c_str(), CONFIG_STRING(m_config, "database.password").c_str(), @@ -391,30 +407,15 @@ bool MySQLBackend::exec(const std::string &query) { return true; } -bool MySQLBackend::exec(Statement *stmt) { - for (int i = 20; i > 0; i--) { - int ret = stmt->execute(); - if (ret == 0) - return true; - if (ret == 2013) { - disconnect(); - connect(); - } - if (i != 20) { - sleep(1); - } - } - return false; -} - void MySQLBackend::setUser(const UserInfo &user) { *m_setUser << user.jid << user.uin << user.password << user.language << user.encoding << user.vip << user.password; - exec(m_setUser); + EXEC(m_setUser, setUser(user)); } bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) { *m_getUser << barejid; - if (!exec(m_getUser)) + EXEC(m_getUser, getUser(barejid, user)); + if (!exec_ok) return false; int ret = false; @@ -428,7 +429,7 @@ bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) { void MySQLBackend::setUserOnline(long id, bool online) { *m_setUserOnline << online << id; - exec(m_setUserOnline); + EXEC(m_setUserOnline, setUserOnline(id, online)); } long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) { @@ -437,14 +438,14 @@ long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) { *m_addBuddy << (buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); *m_addBuddy << buddyInfo.alias << buddyInfo.flags; - exec(m_addBuddy); + EXEC(m_addBuddy, addBuddy(userId, buddyInfo)); long id = (long) mysql_insert_id(&m_conn); // INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) if (!buddyInfo.settings.find("icon_hash")->second.s.empty()) { *m_updateBuddySetting << userId << id << buddyInfo.settings.find("icon_hash")->first << (int) TYPE_STRING << buddyInfo.settings.find("icon_hash")->second.s << buddyInfo.settings.find("icon_hash")->second.s; - exec(m_updateBuddySetting); + EXEC(m_updateBuddySetting, addBuddy(userId, buddyInfo)); } return id; @@ -456,7 +457,7 @@ void MySQLBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) { *m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription; *m_updateBuddy << userId << buddyInfo.legacyName; - exec(m_updateBuddy); + EXEC(m_updateBuddy, updateBuddy(userId, buddyInfo)); } bool MySQLBackend::getBuddies(long id, std::list &roster) { @@ -470,7 +471,8 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { long buddy_id = -1; std::string key; - if (!exec(m_getBuddies)) + EXEC(m_getBuddies, getBuddies(id, roster)); + if (!exec_ok) return false; while (m_getBuddies->fetch() == 0) { @@ -485,7 +487,8 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { roster.push_back(b); } - if (!exec(m_getBuddiesSettings)) + EXEC(m_getBuddiesSettings, getBuddies(id, roster)); + if (!exec_ok) return false; BOOST_FOREACH(BuddyInfo &b, roster) { @@ -531,19 +534,23 @@ bool MySQLBackend::getBuddies(long id, std::list &roster) { bool MySQLBackend::removeUser(long id) { *m_removeUser << (int) id; - if (!exec(m_removeUser)) + EXEC(m_removeUser, removeUser(id)); + if (!exec_ok) return false; *m_removeUserSettings << (int) id; - if (!exec(m_removeUserSettings)) + EXEC(m_removeUserSettings, removeUser(id)); + if (!exec_ok) return false; *m_removeUserBuddies << (int) id; - if (!exec(m_removeUserBuddies)) + EXEC(m_removeUserBuddies, removeUser(id)); + if (!exec_ok) return false; *m_removeUserBuddiesSettings << (int) id; - if (!exec(m_removeUserBuddiesSettings)) + EXEC(m_removeUserBuddiesSettings, removeUser(id)); + if (!exec_ok) return false; return true; @@ -552,11 +559,11 @@ bool MySQLBackend::removeUser(long id) { void MySQLBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) { // "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?" *m_getUserSetting << id << variable; - exec(m_getUserSetting); + EXEC(m_getUserSetting, getUserSetting(id, variable, type, value)); if (m_getUserSetting->fetch() != 0) { // "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)" *m_setUserSetting << id << variable << type << value; - exec(m_setUserSetting); + EXEC(m_setUserSetting, getUserSetting(id, variable, type, value)); } else { *m_getUserSetting >> type >> value; @@ -566,7 +573,7 @@ void MySQLBackend::getUserSetting(long id, const std::string &variable, int &typ void MySQLBackend::updateUserSetting(long id, const std::string &variable, const std::string &value) { // "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?" *m_updateUserSetting << value << id << variable; - exec(m_updateUserSetting); + EXEC(m_updateUserSetting, updateUserSetting(id, variable, value)); } void MySQLBackend::beginTransaction() { From 0e1267255548898abc77cd288ac3a1b18328f6c8 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 22:29:55 +0200 Subject: [PATCH 20/26] Show message --- src/mysqlbackend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mysqlbackend.cpp b/src/mysqlbackend.cpp index 97549724..a10d89ec 100644 --- a/src/mysqlbackend.cpp +++ b/src/mysqlbackend.cpp @@ -78,6 +78,7 @@ using namespace log4cxx; if (ret == 0) \ exec_ok = true; \ else if (ret == 2013) { \ + LOG4CXX_INFO(logger, "MySQL connection lost. Reconnecting...");\ disconnect(); \ connect(); \ return METHOD; \ From b98962e80d77d412de1386a90d69b4ed207fea31 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 23:14:24 +0200 Subject: [PATCH 21/26] Added missing cmake modules --- cmake_modules/CMakeParseArguments.cmake | 138 ++++++++++++++++++++++++ cmake_modules/FindPackageMessage.cmake | 48 +++++++++ 2 files changed, 186 insertions(+) create mode 100644 cmake_modules/CMakeParseArguments.cmake create mode 100644 cmake_modules/FindPackageMessage.cmake diff --git a/cmake_modules/CMakeParseArguments.cmake b/cmake_modules/CMakeParseArguments.cmake new file mode 100644 index 00000000..7ce4c49a --- /dev/null +++ b/cmake_modules/CMakeParseArguments.cmake @@ -0,0 +1,138 @@ +# CMAKE_PARSE_ARGUMENTS( args...) +# +# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for +# parsing the arguments given to that macro or function. +# It processes the arguments and defines a set of variables which hold the +# values of the respective options. +# +# The argument contains all options for the respective macro, +# i.e. keywords which can be used when calling the macro without any value +# following, like e.g. the OPTIONAL keyword of the install() command. +# +# The argument contains all keywords for this macro +# which are followed by one value, like e.g. DESTINATION keyword of the +# install() command. +# +# The argument contains all keywords for this macro +# which can be followed by more than one value, like e.g. the TARGETS or +# FILES keywords of the install() command. +# +# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the +# keywords listed in , and +# a variable composed of the given +# followed by "_" and the name of the respective keyword. +# These variables will then hold the respective value from the argument list. +# For the keywords this will be TRUE or FALSE. +# +# All remaining arguments are collected in a variable +# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether +# your macro was called with unrecognized parameters. +# +# As an example here a my_install() macro, which takes similar arguments as the +# real install() command: +# +# function(MY_INSTALL) +# set(options OPTIONAL FAST) +# set(oneValueArgs DESTINATION RENAME) +# set(multiValueArgs TARGETS CONFIGURATIONS) +# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) +# ... +# +# Assume my_install() has been called like this: +# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) +# +# After the cmake_parse_arguments() call the macro will have set the following +# variables: +# MY_INSTALL_OPTIONAL = TRUE +# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() +# MY_INSTALL_DESTINATION = "bin" +# MY_INSTALL_RENAME = "" (was not used) +# MY_INSTALL_TARGETS = "foo;bar" +# MY_INSTALL_CONFIGURATIONS = "" (was not used) +# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" +# +# You can the continue and process these variables. +# +# Keywords terminate lists of values, e.g. if directly after a one_value_keyword +# another recognized keyword follows, this is interpreted as the beginning of +# the new option. +# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in +# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. + +#============================================================================= +# Copyright 2010 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) + return() +endif() +set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) + + +function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) + # first set all result variables to empty/FALSE + foreach(arg_name ${_singleArgNames} ${_multiArgNames}) + set(${prefix}_${arg_name}) + endforeach(arg_name) + + foreach(option ${_optionNames}) + set(${prefix}_${option} FALSE) + endforeach(option) + + set(${prefix}_UNPARSED_ARGUMENTS) + + set(insideValues FALSE) + set(currentArgName) + + # now iterate over all arguments and fill the result variables + foreach(currentArg ${ARGN}) + list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword + + if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) + if(insideValues) + if("${insideValues}" STREQUAL "SINGLE") + set(${prefix}_${currentArgName} ${currentArg}) + set(insideValues FALSE) + elseif("${insideValues}" STREQUAL "MULTI") + list(APPEND ${prefix}_${currentArgName} ${currentArg}) + endif() + else(insideValues) + list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) + endif(insideValues) + else() + if(NOT ${optionIndex} EQUAL -1) + set(${prefix}_${currentArg} TRUE) + set(insideValues FALSE) + elseif(NOT ${singleArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "SINGLE") + elseif(NOT ${multiArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "MULTI") + endif() + endif() + + endforeach(currentArg) + + # propagate the result variables to the caller: + foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) + set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) + endforeach(arg_name) + set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) + +endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) diff --git a/cmake_modules/FindPackageMessage.cmake b/cmake_modules/FindPackageMessage.cmake new file mode 100644 index 00000000..eb398b2a --- /dev/null +++ b/cmake_modules/FindPackageMessage.cmake @@ -0,0 +1,48 @@ +# FIND_PACKAGE_MESSAGE( "message for user" "find result details") +# +# This macro is intended to be used in FindXXX.cmake modules files. +# It will print a message once for each unique find result. +# This is useful for telling the user where a package was found. +# The first argument specifies the name (XXX) of the package. +# The second argument specifies the message to display. +# The third argument lists details about the find result so that +# if they change the message will be displayed again. +# The macro also obeys the QUIET argument to the find_package command. +# +# Example: +# +# IF(X11_FOUND) +# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" +# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") +# ELSE(X11_FOUND) +# ... +# ENDIF(X11_FOUND) + +#============================================================================= +# Copyright 2008-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FUNCTION(FIND_PACKAGE_MESSAGE pkg msg details) + # Avoid printing a message repeatedly for the same find result. + IF(NOT ${pkg}_FIND_QUIETLY) + SET(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) + IF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + # The message has not yet been printed. + MESSAGE(STATUS "${msg}") + + # Save the find details in the cache to avoid printing the same + # message again. + SET("${DETAILS_VAR}" "${details}" + CACHE INTERNAL "Details about finding ${pkg}") + ENDIF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + ENDIF(NOT ${pkg}_FIND_QUIETLY) +ENDFUNCTION(FIND_PACKAGE_MESSAGE) From 3d9453687889dee58798787e23663839f3450814 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 23:17:18 +0200 Subject: [PATCH 22/26] Don't bother with CURRENT_LIST_DIR --- cmake_modules/opensslConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_modules/opensslConfig.cmake b/cmake_modules/opensslConfig.cmake index bffd91eb..01c1b404 100644 --- a/cmake_modules/opensslConfig.cmake +++ b/cmake_modules/opensslConfig.cmake @@ -229,7 +229,7 @@ set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}") endif (OPENSSL_INCLUDE_DIR) - include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + include(FindPackageHandleStandardArgs.cmake) if (OPENSSL_VERSION) find_package_handle_standard_args(OpenSSL From 624662e4282e5fd42e9d3496478721b90a2ba788 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 23:25:48 +0200 Subject: [PATCH 23/26] remove .cmake --- cmake_modules/CMakeParseArguments.cmake | 138 ---------- .../FindPackageHandleStandardArgs.cmake | 260 ------------------ cmake_modules/FindPackageMessage.cmake | 48 ---- cmake_modules/opensslConfig.cmake | 2 +- 4 files changed, 1 insertion(+), 447 deletions(-) delete mode 100644 cmake_modules/CMakeParseArguments.cmake delete mode 100644 cmake_modules/FindPackageHandleStandardArgs.cmake delete mode 100644 cmake_modules/FindPackageMessage.cmake diff --git a/cmake_modules/CMakeParseArguments.cmake b/cmake_modules/CMakeParseArguments.cmake deleted file mode 100644 index 7ce4c49a..00000000 --- a/cmake_modules/CMakeParseArguments.cmake +++ /dev/null @@ -1,138 +0,0 @@ -# CMAKE_PARSE_ARGUMENTS( args...) -# -# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for -# parsing the arguments given to that macro or function. -# It processes the arguments and defines a set of variables which hold the -# values of the respective options. -# -# The argument contains all options for the respective macro, -# i.e. keywords which can be used when calling the macro without any value -# following, like e.g. the OPTIONAL keyword of the install() command. -# -# The argument contains all keywords for this macro -# which are followed by one value, like e.g. DESTINATION keyword of the -# install() command. -# -# The argument contains all keywords for this macro -# which can be followed by more than one value, like e.g. the TARGETS or -# FILES keywords of the install() command. -# -# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the -# keywords listed in , and -# a variable composed of the given -# followed by "_" and the name of the respective keyword. -# These variables will then hold the respective value from the argument list. -# For the keywords this will be TRUE or FALSE. -# -# All remaining arguments are collected in a variable -# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether -# your macro was called with unrecognized parameters. -# -# As an example here a my_install() macro, which takes similar arguments as the -# real install() command: -# -# function(MY_INSTALL) -# set(options OPTIONAL FAST) -# set(oneValueArgs DESTINATION RENAME) -# set(multiValueArgs TARGETS CONFIGURATIONS) -# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) -# ... -# -# Assume my_install() has been called like this: -# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) -# -# After the cmake_parse_arguments() call the macro will have set the following -# variables: -# MY_INSTALL_OPTIONAL = TRUE -# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() -# MY_INSTALL_DESTINATION = "bin" -# MY_INSTALL_RENAME = "" (was not used) -# MY_INSTALL_TARGETS = "foo;bar" -# MY_INSTALL_CONFIGURATIONS = "" (was not used) -# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" -# -# You can the continue and process these variables. -# -# Keywords terminate lists of values, e.g. if directly after a one_value_keyword -# another recognized keyword follows, this is interpreted as the beginning of -# the new option. -# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in -# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. - -#============================================================================= -# Copyright 2010 Alexander Neundorf -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - - -if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) - return() -endif() -set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) - - -function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) - # first set all result variables to empty/FALSE - foreach(arg_name ${_singleArgNames} ${_multiArgNames}) - set(${prefix}_${arg_name}) - endforeach(arg_name) - - foreach(option ${_optionNames}) - set(${prefix}_${option} FALSE) - endforeach(option) - - set(${prefix}_UNPARSED_ARGUMENTS) - - set(insideValues FALSE) - set(currentArgName) - - # now iterate over all arguments and fill the result variables - foreach(currentArg ${ARGN}) - list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword - list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword - list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword - - if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) - if(insideValues) - if("${insideValues}" STREQUAL "SINGLE") - set(${prefix}_${currentArgName} ${currentArg}) - set(insideValues FALSE) - elseif("${insideValues}" STREQUAL "MULTI") - list(APPEND ${prefix}_${currentArgName} ${currentArg}) - endif() - else(insideValues) - list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) - endif(insideValues) - else() - if(NOT ${optionIndex} EQUAL -1) - set(${prefix}_${currentArg} TRUE) - set(insideValues FALSE) - elseif(NOT ${singleArgIndex} EQUAL -1) - set(currentArgName ${currentArg}) - set(${prefix}_${currentArgName}) - set(insideValues "SINGLE") - elseif(NOT ${multiArgIndex} EQUAL -1) - set(currentArgName ${currentArg}) - set(${prefix}_${currentArgName}) - set(insideValues "MULTI") - endif() - endif() - - endforeach(currentArg) - - # propagate the result variables to the caller: - foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) - set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) - endforeach(arg_name) - set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) - -endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) diff --git a/cmake_modules/FindPackageHandleStandardArgs.cmake b/cmake_modules/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 1acb021e..00000000 --- a/cmake_modules/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,260 +0,0 @@ -# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) -# -# This function is intended to be used in FindXXX.cmake modules files. -# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE(). -# It also sets the _FOUND variable. -# The package is considered found if all variables ... listed contain -# valid results, e.g. valid filepaths. -# -# There are two modes of this function. The first argument in both modes is -# the name of the Find-module where it is called (in original casing). -# -# The first simple mode looks like this: -# FIND_PACKAGE_HANDLE_STANDARD_ARGS( (DEFAULT_MSG|"Custom failure message") ... ) -# If the variables to are all valid, then _FOUND -# will be set to TRUE. -# If DEFAULT_MSG is given as second argument, then the function will generate -# itself useful success and error messages. You can also supply a custom error message -# for the failure case. This is not recommended. -# -# The second mode is more powerful and also supports version checking: -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS ...] -# [VERSION_VAR -# [CONFIG_MODE] -# [FAIL_MESSAGE "Custom failure message"] ) -# -# As above, if through are all valid, _FOUND -# will be set to TRUE. -# After REQUIRED_VARS the variables which are required for this package are listed. -# Following VERSION_VAR the name of the variable can be specified which holds -# the version of the package which has been found. If this is done, this version -# will be checked against the (potentially) specified required version used -# in the find_package() call. The EXACT keyword is also handled. The default -# messages include information about the required version and the version -# which has been actually found, both if the version is ok or not. -# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for -# a find_package(... NO_MODULE) call, in this case all the information -# provided by the config-mode of find_package() will be evaluated -# automatically. -# Via FAIL_MESSAGE a custom failure message can be specified, if this is not -# used, the default message will be displayed. -# -# Example for mode 1: -# -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) -# -# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and -# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. -# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, -# independent whether QUIET was used or not. -# If it is found, success will be reported, including the content of . -# On repeated Cmake runs, the same message won't be printed again. -# -# Example for mode 2: -# -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE -# VERSION_VAR BISON_VERSION) -# In this case, BISON is considered to be found if the variable(s) listed -# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. -# Also the version of BISON will be checked by using the version contained -# in BISON_VERSION. -# Since no FAIL_MESSAGE is given, the default messages will be printed. -# -# Another example for mode 2: -# -# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) -# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE) -# and adds an additional search directory for automoc4. -# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper -# success/error message. - -#============================================================================= -# Copyright 2007-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -INCLUDE(FindPackageMessage) -INCLUDE(CMakeParseArguments) - -# internal helper macro -MACRO(_FPHSA_FAILURE_MESSAGE _msg) - IF (${_NAME}_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "${_msg}") - ELSE (${_NAME}_FIND_REQUIRED) - IF (NOT ${_NAME}_FIND_QUIETLY) - MESSAGE(STATUS "${_msg}") - ENDIF (NOT ${_NAME}_FIND_QUIETLY) - ENDIF (${_NAME}_FIND_REQUIRED) -ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg) - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - IF(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - ELSE(${_NAME}_CONFIG) - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - IF(${_NAME}_CONSIDERED_CONFIGS) - SET(configsText "") - LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - MATH(EXPR configsCount "${configsCount} - 1") - FOREACH(currentConfigIndex RANGE ${configsCount}) - LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - SET(configsText "${configsText} ${filename} (version ${version})\n") - ENDFOREACH(currentConfigIndex) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - ELSE(${_NAME}_CONSIDERED_CONFIGS) - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - ENDIF(${_NAME}_CONSIDERED_CONFIGS) - ENDIF(${_NAME}_CONFIG) -ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - - -FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in -# new extended or in the "old" mode: - SET(options CONFIG_MODE) - SET(oneValueArgs FAIL_MESSAGE VERSION_VAR) - SET(multiValueArgs REQUIRED_VARS) - SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - IF(${INDEX} EQUAL -1) - SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - SET(FPHSA_REQUIRED_VARS ${ARGN}) - SET(FPHSA_VERSION_VAR) - ELSE(${INDEX} EQUAL -1) - - CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - IF(FPHSA_UNPARSED_ARGUMENTS) - MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - ENDIF(FPHSA_UNPARSED_ARGUMENTS) - - IF(NOT FPHSA_FAIL_MESSAGE) - SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - ENDIF(NOT FPHSA_FAIL_MESSAGE) - ENDIF(${INDEX} EQUAL -1) - -# now that we collected all arguments, process them - - IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") - SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - IF(FPHSA_CONFIG_MODE) - LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - SET(FPHSA_VERSION_VAR ${_NAME}_VERSION) - ENDIF(FPHSA_CONFIG_MODE) - - IF(NOT FPHSA_REQUIRED_VARS) - MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - ENDIF(NOT FPHSA_REQUIRED_VARS) - - LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - STRING(TOUPPER ${_NAME} _NAME_UPPER) - STRING(TOLOWER ${_NAME} _NAME_LOWER) - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - SET(MISSING_VARS "") - SET(DETAILS "") - SET(${_NAME_UPPER}_FOUND TRUE) - # check if all passed variables are valid - FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - IF(NOT ${_CURRENT_VAR}) - SET(${_NAME_UPPER}_FOUND FALSE) - SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") - ELSE(NOT ${_CURRENT_VAR}) - SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") - ENDIF(NOT ${_CURRENT_VAR}) - ENDFOREACH(_CURRENT_VAR) - - - # version handling: - SET(VERSION_MSG "") - SET(VERSION_OK TRUE) - SET(VERSION ${${FPHSA_VERSION_VAR}} ) - IF (${_NAME}_FIND_VERSION) - - IF(VERSION) - - IF(${_NAME}_FIND_VERSION_EXACT) # exact version required - IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") - SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - SET(VERSION_OK FALSE) - ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") - SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")") - ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") - - ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified: - IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") - SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - SET(VERSION_OK FALSE) - ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") - SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")") - ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") - ENDIF(${_NAME}_FIND_VERSION_EXACT) - - ELSE(VERSION) - - # if the package was not found, but a version was given, add that to the output: - IF(${_NAME}_FIND_VERSION_EXACT) - SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - ELSE(${_NAME}_FIND_VERSION_EXACT) - SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - ENDIF(${_NAME}_FIND_VERSION_EXACT) - - ENDIF(VERSION) - ELSE (${_NAME}_FIND_VERSION) - IF(VERSION) - SET(VERSION_MSG "(found version \"${VERSION}\")") - ENDIF(VERSION) - ENDIF (${_NAME}_FIND_VERSION) - - IF(VERSION_OK) - SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") - ELSE(VERSION_OK) - SET(${_NAME_UPPER}_FOUND FALSE) - ENDIF(VERSION_OK) - - - # print the result: - IF (${_NAME_UPPER}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}") - ELSE (${_NAME_UPPER}_FOUND) - - IF(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - ELSE(FPHSA_CONFIG_MODE) - IF(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - ELSE(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") - ENDIF(NOT VERSION_OK) - ENDIF(FPHSA_CONFIG_MODE) - - ENDIF (${_NAME_UPPER}_FOUND) - - SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) - -ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG) diff --git a/cmake_modules/FindPackageMessage.cmake b/cmake_modules/FindPackageMessage.cmake deleted file mode 100644 index eb398b2a..00000000 --- a/cmake_modules/FindPackageMessage.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. -# It will print a message once for each unique find result. -# This is useful for telling the user where a package was found. -# The first argument specifies the name (XXX) of the package. -# The second argument specifies the message to display. -# The third argument lists details about the find result so that -# if they change the message will be displayed again. -# The macro also obeys the QUIET argument to the find_package command. -# -# Example: -# -# IF(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# ELSE(X11_FOUND) -# ... -# ENDIF(X11_FOUND) - -#============================================================================= -# Copyright 2008-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -FUNCTION(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - IF(NOT ${pkg}_FIND_QUIETLY) - SET(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - IF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - MESSAGE(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - SET("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - ENDIF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - ENDIF(NOT ${pkg}_FIND_QUIETLY) -ENDFUNCTION(FIND_PACKAGE_MESSAGE) diff --git a/cmake_modules/opensslConfig.cmake b/cmake_modules/opensslConfig.cmake index 01c1b404..b3f012c8 100644 --- a/cmake_modules/opensslConfig.cmake +++ b/cmake_modules/opensslConfig.cmake @@ -229,7 +229,7 @@ set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}") endif (OPENSSL_INCLUDE_DIR) - include(FindPackageHandleStandardArgs.cmake) + include(FindPackageHandleStandardArgs) if (OPENSSL_VERSION) find_package_handle_standard_args(OpenSSL From af39c58f687f09ad57fb3f68a889e011037ce15b Mon Sep 17 00:00:00 2001 From: HanzZ Date: Wed, 26 Oct 2011 23:56:50 +0200 Subject: [PATCH 24/26] Support for line-end comments --- backends/libpurple/main.cpp | 7 +++++++ spectrum/src/sample.cfg | 5 +++-- spectrum/src/sample2.cfg | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 657a3799..51943171 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -76,6 +76,13 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key } std::string ret(str); free(str); + + if (ret.find("#") != std::string::npos) { + ret = ret.substr(0, ret.find("#")); + while(*(ret.end() - 1) == ' ') { + ret.erase(ret.end() - 1); + } + } return ret; } diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index c89c7871..71b1d23b 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -4,7 +4,8 @@ password = secret server = 127.0.0.1 port = 5222 server_mode = 1 -backend_host=localhost # < this option doesn't work yet +backend_host=localhost +# < this option doesn't work yet backend_port=10001 admin_username=admin admin_password=test @@ -25,7 +26,7 @@ protocol=any [logging] #config=logging.cfg # log4cxx/log4j logging configuration file -#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends +#backend_config=/home/hanzz/code/libtransport/spectrum/src/backend-logging.cfg # log4cxx/log4j logging configuration file for backends [database] type = none # or "none" without database backend diff --git a/spectrum/src/sample2.cfg b/spectrum/src/sample2.cfg index 10347f9e..ca499f66 100644 --- a/spectrum/src/sample2.cfg +++ b/spectrum/src/sample2.cfg @@ -65,7 +65,7 @@ type=xmpp config = /etc/spectrum2/logging.cfg # log4cxx/log4j logging configuration file in ini format used for backends. -backend_config = /etc/spectrum2/backend_logging.cfg # log4cxx/log4j logging configuration file for backends +backend_config = /etc/spectrum2/backend-logging.cfg # log4cxx/log4j logging configuration file for backends [database] # Database backend type From 140278d70d9d105b85559813a9578c0ab52d0d47 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Thu, 27 Oct 2011 00:07:59 +0200 Subject: [PATCH 25/26] Proper default config file --- spectrum_manager/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spectrum_manager/src/main.cpp b/spectrum_manager/src/main.cpp index 6c74057a..3428f066 100644 --- a/spectrum_manager/src/main.cpp +++ b/spectrum_manager/src/main.cpp @@ -215,7 +215,7 @@ int main(int argc, char **argv) boost::program_options::options_description desc("Usage: spectrum [OPTIONS] \nAllowed options"); desc.add_options() ("help,h", "Show help output") - ("config,c", boost::program_options::value(&config_file)->default_value("/etc/spectrum2/spectrum-manager.cfg"), "Spectrum manager config file") + ("config,c", boost::program_options::value(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file") ("command", boost::program_options::value(&command)->default_value(""), "Command") ; try From 3932a5c77e9a64b3c3ff6243baf52ba9350ccdad Mon Sep 17 00:00:00 2001 From: HanzZ Date: Thu, 27 Oct 2011 09:33:28 +0200 Subject: [PATCH 26/26] Renamed admin_username to admin_jid --- spectrum_manager/src/main.cpp | 73 ++++++++++++++++++++++++++++------- src/admininterface.cpp | 4 +- src/config.cpp | 2 +- src/userregistry.cpp | 2 +- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/spectrum_manager/src/main.cpp b/spectrum_manager/src/main.cpp index 3428f066..8d2e3ed3 100644 --- a/spectrum_manager/src/main.cpp +++ b/spectrum_manager/src/main.cpp @@ -26,26 +26,26 @@ using namespace boost; static int finished; static std::string *m; -static void handleDisconnected(Swift::Client *client, const boost::optional &) { - std::cout << "[ DISCONNECTED ] " << client->getJID().getDomain() << "\n"; +static void handleDisconnected(Swift::Client *client, const boost::optional &, const std::string &server) { + std::cout << "[ DISCONNECTED ] " << server << "\n"; if (--finished == 0) { exit(0); } } -static void handleConnected(Swift::Client *client) { +static void handleConnected(Swift::Client *client, const std::string &server) { boost::shared_ptr message(new Swift::Message()); - message->setTo(client->getJID().getDomain()); + message->setTo(server); message->setFrom(client->getJID()); message->setBody(*m); client->sendMessage(message); } -static void handleMessageReceived(Swift::Client *client, Swift::Message::ref message) { +static void handleMessageReceived(Swift::Client *client, Swift::Message::ref message, const std::string &server) { std::string body = message->getBody(); - boost::replace_all(body, "\n", "\n[ OK ] " + client->getJID().getDomain() + ": "); - std::cout << "[ OK ] " << client->getJID().getDomain() << ": " << body << "\n"; + boost::replace_all(body, "\n", "\n[ OK ] " + server + ": "); + std::cout << "[ OK ] " << server << ": " << body << "\n"; if (--finished == 0) { exit(0); } @@ -205,6 +205,47 @@ static void stop_all_instances(ManagerConfig *config) { } } +void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) { + path p(CONFIG_STRING(config, "service.config_directory")); + + try { + if (!exists(p)) { + std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n"; + exit(6); + } + + if (!is_directory(p)) { + std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n"; + exit(7); + } + + directory_iterator end_itr; + for (directory_iterator itr(p); itr != end_itr; ++itr) { + if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") { + Config cfg; + if (cfg.load(itr->path().string()) == false) { + std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n"; + } + + finished++; + Swift::Client *client = new Swift::Client(CONFIG_STRING(&cfg, "service.admin_username"), CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories); + client->setAlwaysTrustCertificates(); + client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid"))); + client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid"))); + client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid"))); + Swift::ClientOptions opt; + opt.allowPLAINWithoutTLS = true; + client->connect(opt); + } + } + } + catch (const filesystem_error& ex) { + std::cerr << "boost filesystem error\n"; + exit(5); + } +} + + int main(int argc, char **argv) { ManagerConfig config; @@ -243,12 +284,16 @@ int main(int argc, char **argv) return 3; } - if (!config.load(config_file)) { std::cerr << "Can't load configuration file.\n"; return 4; } + if (command.empty()) { + std::cout << desc << "\n"; + return 1; + } + if (command == "start") { start_all_instances(&config); } @@ -259,17 +304,19 @@ int main(int argc, char **argv) Swift::SimpleEventLoop eventLoop; Swift::BoostNetworkFactories networkFactories(&eventLoop); - std::string message = argv[1]; + std::string message = command; m = &message; + ask_local_servers(&config, networkFactories, message); + std::vector servers = CONFIG_VECTOR(&config, "servers.server"); for (std::vector::const_iterator it = servers.begin(); it != servers.end(); it++) { finished++; - Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + (*it), CONFIG_STRING(&config, "service.admin_password"), &networkFactories); + Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + *it, CONFIG_STRING(&config, "service.admin_password"), &networkFactories); client->setAlwaysTrustCertificates(); - client->onConnected.connect(boost::bind(&handleConnected, client)); - client->onDisconnected.connect(bind(&handleDisconnected, client, _1)); - client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1)); + client->onConnected.connect(boost::bind(&handleConnected, client, *it)); + client->onDisconnected.connect(bind(&handleDisconnected, client, _1, *it)); + client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, *it)); Swift::ClientOptions opt; opt.allowPLAINWithoutTLS = true; client->connect(opt); diff --git a/src/admininterface.cpp b/src/admininterface.cpp index 44709d8f..3af032d4 100644 --- a/src/admininterface.cpp +++ b/src/admininterface.cpp @@ -61,8 +61,8 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { if (!message->getTo().getNode().empty()) return; - if (message->getFrom().getNode() != CONFIG_STRING(m_component->getConfig(), "service.admin_username")) { - LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().getNode()); + if (message->getFrom().toBare().toString() != CONFIG_STRING(m_component->getConfig(), "service.admin_jid")) { + LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().toBare().toString()); return; } diff --git a/src/config.cpp b/src/config.cpp index 9b3e55e7..05473249 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -69,7 +69,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description ("service.backend_port", value()->default_value("10000"), "Port to bind backend server to") ("service.cert", value()->default_value(""), "PKCS#12 Certificate.") ("service.cert_password", value()->default_value(""), "PKCS#12 Certificate password.") - ("service.admin_username", value()->default_value(""), "Administrator username.") + ("service.admin_jid", value()->default_value(""), "Administrator jid.") ("service.admin_password", value()->default_value(""), "Administrator password.") ("service.reuse_old_backends", value()->default_value(true), "True if Spectrum should use old backends which were full in the past.") ("service.idle_reconnect_time", value()->default_value(0), "Time in seconds after which idle users are reconnected to let their backend die.") diff --git a/src/userregistry.cpp b/src/userregistry.cpp index b044ed49..00b72135 100644 --- a/src/userregistry.cpp +++ b/src/userregistry.cpp @@ -40,7 +40,7 @@ UserRegistry::UserRegistry(Config *cfg, Swift::NetworkFactories *factories) { UserRegistry::~UserRegistry() { m_removeTimer->stop(); } void UserRegistry::isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) { - if (!CONFIG_STRING(config, "service.admin_username").empty() && user.getNode() == CONFIG_STRING(config, "service.admin_username")) { + if (!CONFIG_STRING(config, "service.admin_jid").empty() && user.toBare().toString() == CONFIG_STRING(config, "service.admin_jid")) { if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) { session->handlePasswordValid(); }