diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 36e2df3f..1de35fbc 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -1101,7 +1101,7 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif else if (label=="Nickname" || label == "Nick") { nickname = purple_notify_user_info_entry_get_value_wrapped(vcardEntry); } - else if (label=="Full Name") { + else if (label=="Full Name" || label == "Display name") { fullName = purple_notify_user_info_entry_get_value_wrapped(vcardEntry); } else { diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 6e700132..5d603d36 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -22,6 +22,8 @@ #endif #include +#include "sqlite3.h" + DEFINE_LOGGER(logger, "backend"); @@ -39,6 +41,34 @@ class SpectrumNetworkPlugin; } + +// Prepare the SQL statement +#define PREP_STMT(sql, str) \ + if(sqlite3_prepare_v2(db, std::string(str).c_str(), -1, &sql, NULL)) { \ + LOG4CXX_ERROR(logger, str<< (sqlite3_errmsg(db) == NULL ? "" : sqlite3_errmsg(db))); \ + sql = NULL; \ + } + +// Finalize the prepared statement +#define FINALIZE_STMT(prep) \ + if(prep != NULL) { \ + sqlite3_finalize(prep); \ + } + +#define BEGIN(STATEMENT) sqlite3_reset(STATEMENT);\ + int STATEMENT##_id = 1;\ + int STATEMENT##_id_get = 0;\ + (void)STATEMENT##_id_get; + +#define BIND_INT(STATEMENT, VARIABLE) sqlite3_bind_int(STATEMENT, STATEMENT##_id++, VARIABLE) +#define BIND_STR(STATEMENT, VARIABLE) sqlite3_bind_text(STATEMENT, STATEMENT##_id++, VARIABLE.c_str(), -1, SQLITE_STATIC) +#define RESET_GET_COUNTER(STATEMENT) STATEMENT##_id_get = 0; +#define GET_INT(STATEMENT) sqlite3_column_int(STATEMENT, STATEMENT##_id_get++) +#define GET_STR(STATEMENT) (const char *) sqlite3_column_text(STATEMENT, STATEMENT##_id_get++) +#define GET_BLOB(STATEMENT) (const void *) sqlite3_column_blob(STATEMENT, STATEMENT##_id_get++) +#define EXECUTE_STATEMENT(STATEMENT, NAME) if(sqlite3_step(STATEMENT) != SQLITE_DONE) {\ + LOG4CXX_ERROR(logger, NAME<< (sqlite3_errmsg(db) == NULL ? "" : sqlite3_errmsg(db)));\ + } SpectrumNetworkPlugin *np; @@ -100,6 +130,7 @@ class Skype { int m_timer; int m_counter; int fd_output; + std::map m_groups; }; class SpectrumNetworkPlugin : public NetworkPlugin { @@ -276,7 +307,43 @@ class SpectrumNetworkPlugin : public NetworkPlugin { g_free(filename); } g_free(username); - + + if (photo.empty()) { + sqlite3 *db; + std::string db_path = std::string("/tmp/skype/") + skype->getUsername() + "/" + skype->getUsername() + "/main.db"; + LOG4CXX_INFO(logger, "Opening database " << db_path); + if (sqlite3_open(db_path.c_str(), &db)) { + sqlite3_close(db); + LOG4CXX_ERROR(logger, "Can't open database"); + } + else { + sqlite3_stmt *stmt; + PREP_STMT(stmt, "SELECT avatar_image FROM Contacts WHERE skypename=?"); + if (stmt) { + BEGIN(stmt); + BIND_STR(stmt, name); + if(sqlite3_step(stmt) == SQLITE_ROW) { + int size = sqlite3_column_bytes(stmt, 0); + const void *data = sqlite3_column_blob(stmt, 0); + photo = std::string((const char *)data + 1, size - 1); + } + else { + LOG4CXX_ERROR(logger, (sqlite3_errmsg(db) == NULL ? "" : sqlite3_errmsg(db))); + } + + int ret; + while((ret = sqlite3_step(stmt)) == SQLITE_ROW) { + } + FINALIZE_STMT(stmt); + } + else { + LOG4CXX_ERROR(logger, "Can't created prepared statement"); + LOG4CXX_ERROR(logger, (sqlite3_errmsg(db) == NULL ? "" : sqlite3_errmsg(db))); + } + sqlite3_close(db); + } + } + std::string alias = ""; std::cout << skype->getUsername() << " " << name << "\n"; if (skype->getUsername() == name) { @@ -702,6 +769,55 @@ static void handle_skype_message(std::string &message, Skype *sk) { np->handleAuthorization(sk->getUser(), cmd[1]); } } + else if (cmd[0] == "GROUP") { +// if (cmd[2] == "DISPLAYNAME") { +// //GROUP 810 DISPLAYNAME My Friends +// std::string grp = GET_RESPONSE_DATA(message, "DISPLAYNAME"); +// std::string users = sk->send_command("GET GROUP " + cmd[1] + " USERS"); +// try { +// users = GET_RESPONSE_DATA(users, "USERS"); +// } +// catch (std::out_of_range& oor) { +// return; +// } +// +// std::vector data; +// boost::split(data, users, boost::is_any_of(",")); +// BOOST_FOREACH(std::string u, data) { +// GET_PROPERTY(alias, "USER", u, "FULLNAME"); +// GET_PROPERTY(mood_text, "USER", u, "MOOD_TEXT"); +// GET_PROPERTY(st, "USER", u, "ONLINESTATUS"); +// pbnetwork::StatusType status = getStatus(st); +// +// std::vector groups; +// groups.push_back(grp); +// np->handleBuddyChanged(sk->getUser(), u, alias, groups, status, mood_text); +// } +// } + if (cmd[2] == "NROFUSERS" && cmd[3] != "0") { + GET_PROPERTY(grp, "GROUP", cmd[1], "DISPLAYNAME"); + std::string users = sk->send_command("GET GROUP " + cmd[1] + " USERS"); + try { + users = GET_RESPONSE_DATA(users, "USERS"); + } + catch (std::out_of_range& oor) { + return; + } + + std::vector data; + boost::split(data, users, boost::is_any_of(",")); + BOOST_FOREACH(std::string u, data) { + GET_PROPERTY(alias, "USER", u, "FULLNAME"); + GET_PROPERTY(mood_text, "USER", u, "MOOD_TEXT"); + GET_PROPERTY(st, "USER", u, "ONLINESTATUS"); + pbnetwork::StatusType status = getStatus(st); + + std::vector groups; + groups.push_back(grp); + np->handleBuddyChanged(sk->getUser(), u, alias, groups, status, mood_text); + } + } + } else if (cmd[0] == "CHATMESSAGE") { if (cmd[3] == "RECEIVED") { GET_PROPERTY(body, "CHATMESSAGE", cmd[1], "BODY"); diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp index b0ffba6f..fa777960 100644 --- a/backends/twitter/TwitterPlugin.cpp +++ b/backends/twitter/TwitterPlugin.cpp @@ -274,7 +274,7 @@ void TwitterPlugin::handleMessageSendRequest(const std::string &user, const std: } else { - std::string buddy; + std::string buddy = legacyName; if(userdb[user].twitterMode == CHATROOM) buddy = legacyName.substr(legacyName.find("/") + 1); if(legacyName != "twitter") { tp->runAsThread(new DirectMessageRequest(userdb[user].sessions, user, buddy, message, diff --git a/include/Swiften/Server/Server.cpp b/include/Swiften/Server/Server.cpp index 3cc63428..afd239de 100644 --- a/include/Swiften/Server/Server.cpp +++ b/include/Swiften/Server/Server.cpp @@ -38,6 +38,7 @@ Server::Server( NetworkFactories* networkFactories, UserRegistry *userRegistry, const JID& jid, + const std::string &address, int port) : userRegistry_(userRegistry), port_(port), @@ -45,7 +46,8 @@ Server::Server( networkFactories_(networkFactories), stopping(false), selfJID(jid), - stanzaChannel_(){ + stanzaChannel_(), + address_(address){ stanzaChannel_ = new ServerStanzaChannel(); iqRouter_ = new IQRouter(stanzaChannel_); tlsFactory = NULL; @@ -63,7 +65,12 @@ void Server::start() { if (serverFromClientConnectionServer) { return; } - serverFromClientConnectionServer = networkFactories_->getConnectionServerFactory()->createConnectionServer(port_); + if (address_ == "0.0.0.0") { + serverFromClientConnectionServer = networkFactories_->getConnectionServerFactory()->createConnectionServer(port_); + } + else { + serverFromClientConnectionServer = networkFactories_->getConnectionServerFactory()->createConnectionServer(Swift::HostAddress(address_), port_); + } serverFromClientConnectionServerSignalConnections.push_back( serverFromClientConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewClientConnection, this, _1))); diff --git a/include/Swiften/Server/Server.h b/include/Swiften/Server/Server.h index f3d70060..b32ae463 100644 --- a/include/Swiften/Server/Server.h +++ b/include/Swiften/Server/Server.h @@ -35,7 +35,7 @@ namespace Swift { class Server : public Entity { public: - Server(EventLoop* eventLoop, NetworkFactories* networkFactories, UserRegistry *userRegistry, const JID& jid, int port); + Server(EventLoop* eventLoop, NetworkFactories* networkFactories, UserRegistry *userRegistry, const JID& jid, const std::string &address, int port); ~Server(); void start(); @@ -86,5 +86,6 @@ namespace Swift { TLSServerContextFactory *tlsFactory; CertificateWithKey::ref cert; PlatformXMLParserFactory *parserFactory_; + std::string address_; }; } diff --git a/munin/spectrum2_ b/munin/spectrum2_ index d0dc7a36..df43dc86 100755 --- a/munin/spectrum2_ +++ b/munin/spectrum2_ @@ -21,10 +21,9 @@ # You have to configure the plugin to run as user and group "spectrum". # # By default, the plugin monitors all instances configured in a config-file -# in /etc/spectrum. If you use a different directory, you can specify the -# environment-variable "base". If you do not want to monitor all instances, -# you can give an explicit listing of the corresponding configuration files -# with the environment variable "cfgs". +# in /etc/spectrum2/transports. If you do not want to monitor all instances, +# you can give an explicit listing of the corresponding instances +# with the environment variable "jids". # # Here is an example of a configuration. Note again that you can ommit both # env.cfgs and env.base: @@ -32,8 +31,7 @@ # [spectrum_*] # user spectrum # group spectrum -# env.cfgs xmpp.example.com.cfg,irc.example.com.cfg -# env.base /etc/spectrum +# env.jids xmpp.example.com,irc.example.com # # Author: # Mathias Ertl @@ -94,9 +92,16 @@ def handle_field( string ): # get runtime variables suffix = sys.argv[0].partition('_')[2] verbose = os.environ.get( 'verbose' ) -proc = Popen(['spectrum2_manager', 'list'], stdout=PIPE, stderr=PIPE) -out, err = proc.communicate() -jids = out.split('\n')[:-1] + +jids = [] + +base = os.environ.get( 'base', '/etc/spectrum' ) +if 'jids' in os.environ.keys(): + jids = os.environ.get( 'jids' ).split(',') +else: + proc = Popen(['spectrum2_manager', 'list'], stdout=PIPE, stderr=PIPE) + out, err = proc.communicate() + jids = out.split('\n')[:-1] # set variables based on wildcard if suffix == 'uptime': diff --git a/spectrum/src/sample2.cfg b/spectrum/src/sample2.cfg index 6cad8d9d..5a91d5b8 100644 --- a/spectrum/src/sample2.cfg +++ b/spectrum/src/sample2.cfg @@ -14,7 +14,7 @@ jid = localhost password = secret # XMPP server to which Spectrum connects in gateway mode. -# In server mode, this option is ignored. +# To bind to all ipv4 interfaces, use server=0.0.0.0 server = 127.0.0.1 # XMPP server port. diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 85747b23..6f50b04f 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -352,6 +352,10 @@ void NetworkPluginServer::start() { } else { LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status) << ", possible error: " << strerror(WEXITSTATUS(status))); + if (WEXITSTATUS(status) == ENOENT) { + LOG4CXX_ERROR(logger, "This usually means the path to backend executable defined in config file as '[service] backend=\"...\"' is wrong or the executable does not exists."); + } + } LOG4CXX_ERROR(logger, "Check backend log for more details"); continue; diff --git a/src/sqlite3backend.cpp b/src/sqlite3backend.cpp index b7e839bb..4290d9cf 100644 --- a/src/sqlite3backend.cpp +++ b/src/sqlite3backend.cpp @@ -55,6 +55,7 @@ #define RESET_GET_COUNTER(STATEMENT) STATEMENT##_id_get = 0; #define GET_INT(STATEMENT) sqlite3_column_int(STATEMENT, STATEMENT##_id_get++) #define GET_STR(STATEMENT) (const char *) sqlite3_column_text(STATEMENT, STATEMENT##_id_get++) +#define GET_BLOB(STATEMENT) (const void *) sqlite3_column_blob(STATEMENT, STATEMENT##_id_get++) #define EXECUTE_STATEMENT(STATEMENT, NAME) if(sqlite3_step(STATEMENT) != SQLITE_DONE) {\ LOG4CXX_ERROR(logger, NAME<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));\ } diff --git a/src/tests/userregistry.cpp b/src/tests/userregistry.cpp index 7e567cfd..83fb21a1 100644 --- a/src/tests/userregistry.cpp +++ b/src/tests/userregistry.cpp @@ -36,7 +36,7 @@ class UserRegistryTest : public CPPUNIT_NS :: TestFixture { userRegistry->onConnectUser.connect(bind(&UserRegistryTest::handleConnectUser, this, _1)); userRegistry->onDisconnectUser.connect(bind(&UserRegistryTest::handleDisconnectUser, this, _1)); - server = new Swift::Server(loop, factories, userRegistry, "localhost", 5222); + server = new Swift::Server(loop, factories, userRegistry, "localhost", "0.0.0.0", 5222); server->start(); connectionServer = server->getConnectionServer(); diff --git a/src/transport.cpp b/src/transport.cpp index 9c7172be..a98f101a 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -80,7 +80,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, if (CONFIG_BOOL(m_config, "service.server_mode")) { LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port")); - m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_INT(m_config, "service.port")); + m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port")); if (!CONFIG_STRING(m_config, "service.cert").empty()) { #ifndef _WIN32 //TODO: fix