Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
9331f56079
121 changed files with 4089 additions and 2774 deletions
|
@ -1,6 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(libtransport)
|
||||
|
||||
if(NOT LIB_INSTALL_DIR)
|
||||
set(LIB_INSTALL_DIR "lib")
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH "cmake_modules")
|
||||
|
||||
set(cppunit_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
|
@ -27,10 +31,10 @@ set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
|||
find_package(event)
|
||||
|
||||
set(Swiften_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(Swiften REQUIRED)
|
||||
find_package(Swiften)
|
||||
|
||||
set(openssl_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(openssl REQUIRED)
|
||||
find_package(openssl)
|
||||
|
||||
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
if (WIN32)
|
||||
|
@ -167,10 +171,12 @@ else()
|
|||
endif()
|
||||
|
||||
if (LOG4CXX_FOUND)
|
||||
message("Logging : yes")
|
||||
message("Log4cxx : yes")
|
||||
include_directories(${LOG4CXX_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DWITH_LOG4CXX)
|
||||
else()
|
||||
message(FATAL_ERROR "Logging : no (install log4cxx-devel)")
|
||||
set(LOG4CXX_LIBRARIES "")
|
||||
message("Log4cxx : no (install log4cxx-devel)")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
|
@ -218,6 +224,7 @@ ADD_SUBDIRECTORY(spectrum)
|
|||
ADD_SUBDIRECTORY(backends)
|
||||
if (NOT WIN32)
|
||||
ADD_SUBDIRECTORY(spectrum_manager)
|
||||
# ADD_SUBDIRECTORY(spectrum2_send_message)
|
||||
endif()
|
||||
|
||||
if (CPPUNIT_FOUND)
|
||||
|
|
60
ChangeLog
60
ChangeLog
|
@ -1,6 +1,64 @@
|
|||
Version 2.0.0-beta (X-X-X):
|
||||
Version 2.0.0-beta3 (2012-XX-XX):
|
||||
General:
|
||||
* Log errors related to backend spawning (Show proper log message for
|
||||
example when path to backend binary is not found).
|
||||
* Update buddies in database only when it's needed and do not execute
|
||||
useless database statements.
|
||||
* Send roster changes also when buddy's group change.
|
||||
* Fixed bug when transport contact we in all groups.
|
||||
* Answer to disco#info IQ with proper node (#206).
|
||||
* Set SQLite3 as default database backend.
|
||||
* Fixed disconnecting from server caused by sending VCard response
|
||||
with bad "from" attribute.
|
||||
* Added Munin plugin (Thanks to Askovpen).
|
||||
* Added support for more admin_jid JIDs (Thanks to Askovpen).
|
||||
* Fixed allowed_servers option.
|
||||
|
||||
Libpurple:
|
||||
* prpl-gg: Fetch the contact list properly (#252).
|
||||
|
||||
Skype:
|
||||
* Log more errors.
|
||||
|
||||
Backend API:
|
||||
* Added Python NetworkPlugin class, so it is now easier to write backends
|
||||
in Python (Thanks to Sarang).
|
||||
|
||||
Version 2.0.0-beta2 (2012-03-28):
|
||||
General:
|
||||
* Fixed bug when Roster Item Exchange and subscribe stanzas were sent
|
||||
repeatedly.
|
||||
* Backends related logs now contain the backend PID.
|
||||
* Fixed username_mask setting.
|
||||
* Added new fields into statistics (backends_crashed, messages related
|
||||
stats).
|
||||
* Chatstates are now not counted as incoming messages in stats.
|
||||
* Log4cxx is now optional dependency. Without Log4cxx, Spectrum 2 logs
|
||||
to standard output.
|
||||
* Fixed crash when Log4cxx configuration file didn't exist.
|
||||
* Admin can now see "Admin" contact in server-mode.
|
||||
|
||||
libpurple:
|
||||
* Added initial support for MUC for prpl-jabber protocol.
|
||||
|
||||
LibCommuni IRC backend:
|
||||
* Fixed sending/receiving UTF8 messages.
|
||||
* Using the [registration] auto_register=1 config option, users don't
|
||||
have to register manually when connecting IRC network.
|
||||
|
||||
Skype:
|
||||
* Memory usage statistic now includes the Skype client.
|
||||
* Fixed logging issue when the logs were not stored in the proper instance
|
||||
directory.
|
||||
* Skype backend includes also Skype client memory usage into the account.
|
||||
* Working buddies adding/removing.
|
||||
* Information about missed call is now forwarded to XMPP user.
|
||||
* Fixed bug when Skype client instance wasn't killed by backend.
|
||||
|
||||
Version 2.0.0-beta (2012-02-28):
|
||||
General:
|
||||
* Added PostreSQL support (thanks to Jadestorm).
|
||||
* Added XEP-0100 (Gateway interaction) support.
|
||||
* Send presences only "from" bare JID (fixed bug with buddies appearing
|
||||
twice in the roster and potential unregistering issues).
|
||||
* Fixed potential MySQL/SQLite3 deadlocks.
|
||||
|
|
|
@ -9,6 +9,8 @@ if (PROTOBUF_FOUND)
|
|||
|
||||
ADD_SUBDIRECTORY(smstools3)
|
||||
|
||||
ADD_SUBDIRECTORY(template)
|
||||
|
||||
if (NOT WIN32)
|
||||
ADD_SUBDIRECTORY(frotz)
|
||||
if (${LIBDBUSGLIB_FOUND})
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
|
||||
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
|
||||
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
|
||||
|
||||
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);
|
||||
m_socket->connectToHost(FROM_UTF8(host), port);
|
||||
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
}
|
||||
|
||||
|
@ -28,8 +31,8 @@ void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::st
|
|||
if (CONFIG_BOOL(config, "service.server_mode")) {
|
||||
MyIrcSession *session = new MyIrcSession(user, this);
|
||||
std::string h = user.substr(0, user.find("@"));
|
||||
session->setNickName(QString::fromStdString(h.substr(0, h.find("%"))));
|
||||
session->setHost(QString::fromStdString(h.substr(h.find("%") + 1)));
|
||||
session->setNickName(FROM_UTF8(h.substr(0, h.find("%"))));
|
||||
session->setHost(FROM_UTF8(h.substr(h.find("%") + 1)));
|
||||
session->setPort(6667);
|
||||
session->open();
|
||||
std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n";
|
||||
|
@ -72,7 +75,7 @@ void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const s
|
|||
}
|
||||
}
|
||||
std::cout << "MESSAGE " << u << " " << r << "\n";
|
||||
m_sessions[u]->sendCommand(IrcCommand::createMessage(QString::fromStdString(r), QString::fromStdString(message)));
|
||||
m_sessions[u]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message)));
|
||||
std::cout << "SENT\n";
|
||||
}
|
||||
|
||||
|
@ -89,8 +92,8 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std:
|
|||
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->setNickName(QString::fromStdString(nickname));
|
||||
session->setHost(QString::fromStdString(room.substr(room.find("@") + 1)));
|
||||
session->setNickName(FROM_UTF8(nickname));
|
||||
session->setHost(FROM_UTF8(room.substr(room.find("@") + 1)));
|
||||
session->setPort(6667);
|
||||
session->open();
|
||||
std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("@") + 1) << "\n";
|
||||
|
@ -103,10 +106,10 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std:
|
|||
}
|
||||
std::cout << "JOINING " << r << "\n";
|
||||
m_sessions[u]->addAutoJoinChannel(r);
|
||||
m_sessions[u]->sendCommand(IrcCommand::createJoin(QString::fromStdString(r), QString::fromStdString(password)));
|
||||
m_sessions[u]->sendCommand(IrcCommand::createJoin(FROM_UTF8(r), FROM_UTF8(password)));
|
||||
m_sessions[u]->rooms += 1;
|
||||
// update nickname, because we have nickname per session, no nickname per room.
|
||||
handleRoomNicknameChanged(user, r, m_sessions[u]->nickName().toStdString());
|
||||
handleRoomNicknameChanged(user, r, TO_UTF8(m_sessions[u]->nickName()));
|
||||
}
|
||||
|
||||
void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
|
||||
|
@ -120,7 +123,7 @@ void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std
|
|||
if (m_sessions[u] == NULL)
|
||||
return;
|
||||
|
||||
m_sessions[u]->sendCommand(IrcCommand::createPart(QString::fromStdString(r)));
|
||||
m_sessions[u]->sendCommand(IrcCommand::createPart(FROM_UTF8(r)));
|
||||
m_sessions[u]->removeAutoJoinChannel(r);
|
||||
m_sessions[u]->rooms -= 1;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
#include "session.h"
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
|
@ -17,19 +18,9 @@
|
|||
#include "ircnetworkplugin.h"
|
||||
#include "singleircnetworkplugin.h"
|
||||
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include "log4cxx/helpers/transcoder.h"
|
||||
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
NetworkPlugin * np = NULL;
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
|
@ -83,30 +74,7 @@ int main (int argc, char* argv[]) {
|
|||
}
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
if (CONFIG_STRING(&config, "logging.backend_config").empty()) {
|
||||
LoggerPtr root = log4cxx::Logger::getRootLogger();
|
||||
#ifndef _MSC_VER
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
|
||||
#else
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n")));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
log4cxx::helpers::Properties p;
|
||||
log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config"));
|
||||
p.load(istream);
|
||||
LogString pid, jid;
|
||||
log4cxx::helpers::Transcoder::decode(boost::lexical_cast<std::string>(getpid()), pid);
|
||||
log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid);
|
||||
#ifdef _MSC_VER
|
||||
p.setProperty(L"pid", pid);
|
||||
p.setProperty(L"jid", jid);
|
||||
#else
|
||||
p.setProperty("pid", pid);
|
||||
p.setProperty("jid", jid);
|
||||
#endif
|
||||
log4cxx::PropertyConfigurator::configure(p);
|
||||
}
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
Swift::QtEventLoop eventLoop;
|
||||
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
|
||||
#include "log4cxx/logger.h"
|
||||
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
|
||||
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
|
||||
|
||||
using namespace log4cxx;
|
||||
#include "transport/logging.h"
|
||||
|
||||
static LoggerPtr logger = log4cxx::Logger::getLogger("IRCSession");
|
||||
DEFINE_LOGGER(logger, "IRCSession");
|
||||
|
||||
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
|
||||
{
|
||||
|
@ -40,13 +41,13 @@ void MyIrcSession::on_connected() {
|
|||
}
|
||||
|
||||
for(std::list<std::string>::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
|
||||
sendCommand(IrcCommand::createJoin(QString::fromStdString(*it)));
|
||||
sendCommand(IrcCommand::createJoin(FROM_UTF8(*it)));
|
||||
}
|
||||
|
||||
if (getIdentify().find(" ") != std::string::npos) {
|
||||
std::string to = getIdentify().substr(0, getIdentify().find(" "));
|
||||
std::string what = getIdentify().substr(getIdentify().find(" ") + 1);
|
||||
sendCommand(IrcCommand::createMessage(QString::fromStdString(to), QString::fromStdString(what)));
|
||||
sendCommand(IrcCommand::createMessage(FROM_UTF8(to), FROM_UTF8(what)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,30 +70,30 @@ bool MyIrcSession::correctNickname(std::string &nickname) {
|
|||
void MyIrcSession::on_joined(IrcMessage *message) {
|
||||
IrcJoinMessage *m = (IrcJoinMessage *) message;
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
np->handleParticipantChanged(user, nickname, m->channel().toStdString() + suffix, (int) flags, pbnetwork::STATUS_ONLINE);
|
||||
LOG4CXX_INFO(logger, user << ": Joined " << m->parameters()[0].toStdString());
|
||||
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel()), (int) flags, pbnetwork::STATUS_ONLINE);
|
||||
LOG4CXX_INFO(logger, user << ": Joined " << TO_UTF8(m->parameters()[0]));
|
||||
}
|
||||
|
||||
|
||||
void MyIrcSession::on_parted(IrcMessage *message) {
|
||||
IrcPartMessage *m = (IrcPartMessage *) message;
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " parted " << m->channel().toStdString() + suffix);
|
||||
np->handleParticipantChanged(user, nickname, m->channel().toStdString() + suffix,(int) flags, pbnetwork::STATUS_NONE, m->reason().toStdString());
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " parted " << TO_UTF8(m->channel()) + suffix);
|
||||
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel()) + suffix,(int) flags, pbnetwork::STATUS_NONE, TO_UTF8(m->reason()));
|
||||
}
|
||||
|
||||
void MyIrcSession::on_quit(IrcMessage *message) {
|
||||
IrcQuitMessage *m = (IrcQuitMessage *) message;
|
||||
for(std::list<std::string>::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " quit " << (*it) + suffix);
|
||||
np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_NONE, m->reason().toStdString());
|
||||
np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_NONE, TO_UTF8(m->reason()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,10 +101,10 @@ void MyIrcSession::on_nickChanged(IrcMessage *message) {
|
|||
IrcNickMessage *m = (IrcNickMessage *) message;
|
||||
|
||||
for(std::list<std::string>::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
bool flags = m_modes[(*it) + nickname];
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " changed nickname to " << m->nick().toStdString());
|
||||
np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", m->nick().toStdString());
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " changed nickname to " << TO_UTF8(m->nick()));
|
||||
np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", TO_UTF8(m->nick()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,8 +112,8 @@ void MyIrcSession::on_modeChanged(IrcMessage *message) {
|
|||
IrcModeMessage *m = (IrcModeMessage *) message;
|
||||
|
||||
// mode changed: "#testik" "HanzZ" "+o" "hanzz_k"
|
||||
std::string nickname = m->argument().toStdString();
|
||||
std::string mode = m->mode().toStdString();
|
||||
std::string nickname = TO_UTF8(m->argument());
|
||||
std::string mode = TO_UTF8(m->mode());
|
||||
if (nickname.empty())
|
||||
return;
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " changed mode to " << mode);
|
||||
|
@ -132,29 +133,29 @@ void MyIrcSession::on_topicChanged(IrcMessage *message) {
|
|||
IrcTopicMessage *m = (IrcTopicMessage *) message;
|
||||
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " topic changed to " << m->topic().toStdString());
|
||||
np->handleSubject(user, m->channel().toStdString() + suffix, m->topic().toStdString(), nickname);
|
||||
LOG4CXX_INFO(logger, user << ": " << nickname << " topic changed to " << TO_UTF8(m->topic()));
|
||||
np->handleSubject(user, TO_UTF8(m->channel()) + suffix, TO_UTF8(m->topic()), nickname);
|
||||
}
|
||||
|
||||
void MyIrcSession::on_messageReceived(IrcMessage *message) {
|
||||
IrcPrivateMessage *m = (IrcPrivateMessage *) message;
|
||||
|
||||
std::string target = m->target().toStdString();
|
||||
std::string target = TO_UTF8(m->target());
|
||||
LOG4CXX_INFO(logger, user << ": Message from " << target);
|
||||
if (target.find("#") == 0) {
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
np->handleMessage(user, target + suffix, m->message().toStdString(), nickname);
|
||||
np->handleMessage(user, target + suffix, TO_UTF8(m->message()), nickname);
|
||||
}
|
||||
else {
|
||||
bool flags = 0;
|
||||
std::string nickname = m->sender().name().toStdString();
|
||||
std::string nickname = TO_UTF8(m->sender().name());
|
||||
flags = correctNickname(nickname);
|
||||
np->handleMessage(user, nickname, m->message().toStdString());
|
||||
np->handleMessage(user, nickname, TO_UTF8(m->message()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,10 +166,10 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
|
|||
IrcNumericMessage *m = (IrcNumericMessage *) message;
|
||||
switch (m->code()) {
|
||||
case 332:
|
||||
m_topicData = m->parameters().value(2).toStdString();
|
||||
m_topicData = TO_UTF8(m->parameters().value(2));
|
||||
break;
|
||||
case 333:
|
||||
np->handleSubject(user, m->parameters().value(1).toStdString() + suffix, m_topicData, m->parameters().value(2).toStdString());
|
||||
np->handleSubject(user, TO_UTF8(m->parameters().value(1)) + suffix, m_topicData, TO_UTF8(m->parameters().value(2)));
|
||||
break;
|
||||
case 353:
|
||||
channel = m->parameters().value(2);
|
||||
|
@ -176,10 +177,10 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
|
|||
|
||||
for (int i = 0; i < members.size(); i++) {
|
||||
bool flags = 0;
|
||||
std::string nickname = members.at(i).toStdString();
|
||||
std::string nickname = TO_UTF8(members.at(i));
|
||||
flags = correctNickname(nickname);
|
||||
m_modes[channel.toStdString() + nickname] = flags;
|
||||
np->handleParticipantChanged(user, nickname, channel.toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE);
|
||||
m_modes[TO_UTF8(channel) + nickname] = flags;
|
||||
np->handleParticipantChanged(user, nickname, TO_UTF8(channel) + suffix,(int) flags, pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
break;
|
||||
case 432:
|
||||
|
@ -195,7 +196,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
|
|||
}
|
||||
|
||||
void MyIrcSession::onMessageReceived(IrcMessage *message) {
|
||||
LOG4CXX_INFO(logger, user << ": " << message->toString().toStdString());
|
||||
LOG4CXX_INFO(logger, user << ": " << TO_UTF8(message->toString()));
|
||||
switch (message->type()) {
|
||||
case IrcMessage::Join:
|
||||
on_joined(message);
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
#include "singleircnetworkplugin.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include "transport/logging.h"
|
||||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
|
||||
using namespace log4cxx;
|
||||
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
|
||||
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
|
||||
|
||||
static LoggerPtr logger = log4cxx::Logger::getLogger("SingleIRCNetworkPlugin");
|
||||
DEFINE_LOGGER(logger, "SingleIRCNetworkPlugin");
|
||||
|
||||
SingleIRCNetworkPlugin::SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
|
||||
this->config = config;
|
||||
m_server = config->getUnregistered().find("service.irc_server")->second;
|
||||
m_socket = new QTcpSocket();
|
||||
m_socket->connectToHost(QString::fromStdString(host), port);
|
||||
m_socket->connectToHost(FROM_UTF8(host), port);
|
||||
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
|
||||
if (config->getUnregistered().find("service.irc_identify") != config->getUnregistered().end()) {
|
||||
|
@ -46,16 +47,18 @@ void SingleIRCNetworkPlugin::handleLoginRequest(const std::string &user, const s
|
|||
LOG4CXX_INFO(logger, user << ": Connecting " << m_server << " as " << legacyName);
|
||||
|
||||
MyIrcSession *session = new MyIrcSession(user, this);
|
||||
session->setUserName(QString::fromStdString(legacyName));
|
||||
session->setNickName(QString::fromStdString(legacyName));
|
||||
session->setRealName(QString::fromStdString(legacyName));
|
||||
session->setHost(QString::fromStdString(m_server));
|
||||
session->setUserName(FROM_UTF8(legacyName));
|
||||
session->setNickName(FROM_UTF8(legacyName));
|
||||
session->setRealName(FROM_UTF8(legacyName));
|
||||
session->setHost(FROM_UTF8(m_server));
|
||||
session->setPort(6667);
|
||||
|
||||
std::string identify = m_identify;
|
||||
boost::replace_all(identify, "$password", password);
|
||||
boost::replace_all(identify, "$name", legacyName);
|
||||
session->setIdentify(identify);
|
||||
if (!password.empty()) {
|
||||
std::string identify = m_identify;
|
||||
boost::replace_all(identify, "$password", password);
|
||||
boost::replace_all(identify, "$name", legacyName);
|
||||
session->setIdentify(identify);
|
||||
}
|
||||
|
||||
session->open();
|
||||
|
||||
|
@ -90,10 +93,10 @@ void SingleIRCNetworkPlugin::handleMessageSendRequest(const std::string &user, c
|
|||
}
|
||||
|
||||
LOG4CXX_INFO(logger, user << ": Forwarding message to " << r);
|
||||
m_sessions[user]->sendCommand(IrcCommand::createMessage(QString::fromStdString(r), QString::fromStdString(message)));
|
||||
m_sessions[user]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message)));
|
||||
|
||||
if (r.find("#") == 0) {
|
||||
handleMessage(user, legacyName, message, m_sessions[user]->nickName().toStdString());
|
||||
handleMessage(user, legacyName, message, TO_UTF8(m_sessions[user]->nickName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,11 +108,11 @@ void SingleIRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, cons
|
|||
|
||||
LOG4CXX_INFO(logger, user << ": Joining " << room);
|
||||
m_sessions[user]->addAutoJoinChannel(room);
|
||||
m_sessions[user]->sendCommand(IrcCommand::createJoin(QString::fromStdString(room), QString::fromStdString(password)));
|
||||
m_sessions[user]->sendCommand(IrcCommand::createJoin(FROM_UTF8(room), FROM_UTF8(password)));
|
||||
m_sessions[user]->rooms += 1;
|
||||
|
||||
// update nickname, because we have nickname per session, no nickname per room.
|
||||
handleRoomNicknameChanged(user, room, m_sessions[user]->userName().toStdString());
|
||||
handleRoomNicknameChanged(user, room, TO_UTF8(m_sessions[user]->userName()));
|
||||
}
|
||||
|
||||
void SingleIRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
|
||||
|
@ -122,7 +125,7 @@ void SingleIRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, con
|
|||
}
|
||||
|
||||
LOG4CXX_INFO(logger, user << ": Leaving " << room);
|
||||
m_sessions[u]->sendCommand(IrcCommand::createPart(QString::fromStdString(r)));
|
||||
m_sessions[u]->sendCommand(IrcCommand::createPart(FROM_UTF8(r)));
|
||||
m_sessions[u]->removeAutoJoinChannel(r);
|
||||
m_sessions[u]->rooms -= 1;
|
||||
}
|
||||
|
|
251
backends/libpurple/gen_dynamic_purple.py
Normal file
251
backends/libpurple/gen_dynamic_purple.py
Normal file
|
@ -0,0 +1,251 @@
|
|||
import sys
|
||||
import os
|
||||
|
||||
# intialize for methods used in libpurple macros
|
||||
methods = ["purple_connection_get_state(", "purple_conversation_get_im_data(",
|
||||
"purple_conversation_get_chat_data(", "purple_blist_node_get_type("]
|
||||
macros = ["PURPLE_CONV_IM", "PURPLE_CONV_CHAT", "PURPLE_BLIST_NODE_IS_BUDDY", "PURPLE_CONNECTION_IS_CONNECTED"]
|
||||
definitions = []
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print "Usage:", sys.argv[0], "<path_to_libpurple_dir_containing_libpurple_headers>"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def handle_file(cpp):
|
||||
global methods
|
||||
global macros
|
||||
sys.stdout.write("getting used methods in " + cpp + ": ")
|
||||
sys.stdout.flush()
|
||||
|
||||
counter = 0
|
||||
|
||||
new_file = ""
|
||||
f = open(cpp, "r")
|
||||
for line in f.readlines():
|
||||
new_line = ""
|
||||
index = 0
|
||||
while index < len(line):
|
||||
new_line += line[index]
|
||||
if line[index:].startswith("purple_") or line[index:].startswith("wpurple_") or line[index:].startswith("serv_"):
|
||||
if line[index:].find("=") != -1 and line[index:].find("=") < line[index:].find("("):
|
||||
index += 1
|
||||
continue
|
||||
if line[index-1] == "_" or line[index:].find("(") == -1 or line[index:].startswith("purple_commands_init") or line[index:].startswith("serv_addr"):
|
||||
index += 1
|
||||
continue
|
||||
m = line[index:line[index:].find("(")+index]
|
||||
index += len(m)
|
||||
if m.find("_wrapped") != -1:
|
||||
new_line += m[1:] + "("
|
||||
m = m.replace("_wrapped", "")
|
||||
else:
|
||||
new_line += m[1:] + "_wrapped("
|
||||
if not m + "(" in methods and len(m) != 0:
|
||||
methods += [m + "("]
|
||||
counter += 1
|
||||
index += 1
|
||||
|
||||
for x in macros:
|
||||
if new_line.find(x + "_WRAPPED") == -1:
|
||||
new_line = new_line.replace(x, x + "_WRAPPED")
|
||||
new_file += new_line
|
||||
f.close()
|
||||
|
||||
print counter, "new methods found"
|
||||
return new_file
|
||||
|
||||
def handle_header(header, method):
|
||||
global definitions
|
||||
|
||||
f = open(os.path.join(sys.argv[1], header), "r")
|
||||
|
||||
lines = f.readlines()
|
||||
for i in range(len(lines)):
|
||||
line = lines[i]
|
||||
if line.find(method) != -1:
|
||||
if line.startswith(method):
|
||||
line = lines[i-1][:-1] + line
|
||||
m = line[:-1]
|
||||
l = unicode(m).strip()
|
||||
if l.endswith(")"):
|
||||
continue
|
||||
|
||||
if m.find("/*") > m.find(";"):
|
||||
m = m[:m.find("/*")]
|
||||
m.rstrip()
|
||||
if len(m) != 0:
|
||||
while m[-1] == " ":
|
||||
m = m[:-1]
|
||||
|
||||
index = i;
|
||||
while not m.endswith(";"):
|
||||
index += 1
|
||||
m += " " + lines[index][:-1].lstrip()
|
||||
|
||||
l = unicode(m).strip()
|
||||
if (l.startswith("#") or l.startswith("*") or l.startswith("/*") or l.count("***") != 0 or l.count("&&") != 0
|
||||
or l.endswith(")")):
|
||||
continue;
|
||||
|
||||
m = m.replace("G_GNUC_NULL_TERMINATE", "")
|
||||
|
||||
if not m in definitions:
|
||||
print "found", method[:-1], "in", header
|
||||
definitions += [m]
|
||||
break
|
||||
f.close()
|
||||
|
||||
def get_raw_args(d):
|
||||
return d[d.find("(")+1:-2]
|
||||
|
||||
def get_args(d):
|
||||
x = d[d.find("(")+1:-2]
|
||||
x = x.split(",")
|
||||
|
||||
args = []
|
||||
for arg in x:
|
||||
y = arg.split(" ")
|
||||
if len(y) == 1:
|
||||
continue
|
||||
args += [y[-1].replace("*", "")]
|
||||
|
||||
return args
|
||||
|
||||
def get_name(d):
|
||||
x = d[:d.find("(")+1].lstrip()
|
||||
if x.find("wpurple_") != -1:
|
||||
return x[x.find("wpurple_"):]
|
||||
if x.find("serv_") != -1:
|
||||
return x[x.find("serv_"):]
|
||||
return x[x.find("purple_"):]
|
||||
|
||||
def get_rtype(d):
|
||||
if d.find("wpurple_") != -1:
|
||||
return d[:d.find("wpurple_")].lstrip()
|
||||
if d.find("serv_") != -1:
|
||||
return d[:d.find("serv_")].lstrip()
|
||||
return d[:d.find("purple_")].lstrip()
|
||||
|
||||
def output():
|
||||
global definitions
|
||||
|
||||
header = open("purple_defs.h", "w")
|
||||
print >> header, "#pragma once"
|
||||
print >> header, "#ifdef WIN32"
|
||||
|
||||
print >> header, """
|
||||
#include <Windows.h>
|
||||
#include <purple.h>
|
||||
|
||||
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CHAT_NODE)
|
||||
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_BUDDY_NODE)
|
||||
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CONTACT_NODE)
|
||||
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_GROUP_NODE)
|
||||
|
||||
#define PURPLE_CONV_IM_WRAPPED(c) (purple_conversation_get_im_data_wrapped(c))
|
||||
#define PURPLE_CONV_CHAT_WRAPPED(c) (purple_conversation_get_chat_data_wrapped(c))
|
||||
|
||||
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED(gc) \
|
||||
(purple_connection_get_state_wrapped(gc) == PURPLE_CONNECTED)
|
||||
"""
|
||||
|
||||
for d in definitions:
|
||||
#typedef void (_cdecl * purple_util_set_user_wrapped_func)(const char *dir);
|
||||
print >> header, "typedef", get_rtype(d), "(_cdecl *", get_name(d)[:-1] + "_wrapped_fnc)(" + get_raw_args(d) + ");"
|
||||
#extern purple_util_set_user_wrapped_func purple_util_set_user_wrapped;
|
||||
print >> header, "extern", get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped;"
|
||||
print >> header, ""
|
||||
|
||||
print >> header, ""
|
||||
print >> header, "#else"
|
||||
print >> header, ""
|
||||
|
||||
print >> header, """
|
||||
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED PURPLE_BLIST_NODE_IS_CHAT
|
||||
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED PURPLE_BLIST_NODE_IS_BUDDY
|
||||
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED PURPLE_BLIST_NODE_IS_CONTACT
|
||||
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED PURPLE_BLIST_NODE_IS_GROUP
|
||||
|
||||
#define PURPLE_CONV_IM_WRAPPED PURPLE_CONV_IM
|
||||
#define PURPLE_CONV_CHAT_WRAPPED PURPLE_CONV_CHAT
|
||||
|
||||
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED PURPLE_CONNECTION_IS_CONNECTED
|
||||
"""
|
||||
|
||||
for d in definitions:
|
||||
#define purple_util_set_user_wrapped purple_util_set_user
|
||||
print >> header, "#define", get_name(d)[:-1] + "_wrapped", get_name(d)[:-1]
|
||||
|
||||
print >> header, "#endif"
|
||||
print >> header, ""
|
||||
print >> header, "bool resolvePurpleFunctions();"
|
||||
print >> header, ""
|
||||
|
||||
|
||||
cpp = open("purple_defs.cpp", "w")
|
||||
print >> cpp, "#include \"purple_defs.h\""
|
||||
print >> cpp, ""
|
||||
print >> cpp, "#ifdef WIN32"
|
||||
print >> cpp, "static HMODULE f_hPurple = NULL;"
|
||||
for d in definitions:
|
||||
#purple_util_set_user_wrapped_fnc purple_util_set_user_wrapped = NULL;
|
||||
print >> cpp, get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped = NULL;"
|
||||
|
||||
print >> cpp, "#endif"
|
||||
|
||||
print >> cpp, "bool resolvePurpleFunctions() {"
|
||||
print >> cpp, "#ifdef WIN32"
|
||||
print >> cpp, "\tf_hPurple = LoadLibrary(\"libpurple.dll\");"
|
||||
print >> cpp, "\tif (!f_hPurple)"
|
||||
print >> cpp, "\t\t\treturn false;"
|
||||
for d in definitions:
|
||||
#purple_util_set_user_wrapped = (purple_util_set_user_wrapped_func)GetProcAddress(f_hPurple, "purple_util_set_user_dir");
|
||||
print >> cpp, "\t" + get_name(d)[:-1] + "_wrapped = (" + get_name(d)[:-1] + "_wrapped_fnc)GetProcAddress(f_hPurple, \"" + get_name(d)[:-1] + "\");"
|
||||
#if (!purple_util_set_user_wrapped)
|
||||
print >> cpp, "\tif (!" + get_name(d)[:-1] + "_wrapped)"
|
||||
print >> cpp, "\t\treturn false;"
|
||||
print >> cpp, ""
|
||||
print >> cpp, "#endif"
|
||||
|
||||
print >> cpp, "\treturn true;"
|
||||
print >> cpp, "}"
|
||||
print >> cpp, ""
|
||||
|
||||
cpp.close()
|
||||
header.close()
|
||||
|
||||
|
||||
for f in os.listdir("."):
|
||||
if not f.endswith(".cpp") or f.startswith("purple_defs"):
|
||||
continue
|
||||
new_file = handle_file(f)
|
||||
|
||||
print "updating", f
|
||||
fd = open(f, "w")
|
||||
fd.write(new_file)
|
||||
fd.close()
|
||||
|
||||
for f in os.listdir(sys.argv[1]):
|
||||
if not f.endswith(".h"):
|
||||
continue
|
||||
for m in methods:
|
||||
handle_header(f, m)
|
||||
|
||||
sys.argv[1] = sys.argv[1] + "/win32"
|
||||
for f in os.listdir(sys.argv[1]):
|
||||
if not f.endswith(".h"):
|
||||
continue
|
||||
for m in methods:
|
||||
handle_header(f, m)
|
||||
|
||||
for m in methods:
|
||||
found = False
|
||||
for d in definitions:
|
||||
if d.find(m[:-1]) != -1:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
print "NOT FOUND:", m
|
||||
|
||||
output()
|
|
@ -28,11 +28,11 @@
|
|||
#include "event.h"
|
||||
#endif
|
||||
|
||||
#include "log4cxx/logger.h"
|
||||
#include "purple_defs.h"
|
||||
|
||||
using namespace log4cxx;
|
||||
#include "transport/logging.h"
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("EventLoop");
|
||||
DEFINE_LOGGER(logger, "EventLoop");
|
||||
|
||||
typedef struct _PurpleIOClosure {
|
||||
PurpleInputFunction function;
|
||||
|
|
|
@ -1,36 +1,16 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "purple.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/logging.h"
|
||||
#include "geventloop.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include "log4cxx/helpers/transcoder.h"
|
||||
#ifndef WIN32
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ether.h>
|
||||
#include "sys/socket.h"
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#define ssize_t SSIZE_T
|
||||
#include "win32/win32dep.h"
|
||||
#endif
|
||||
|
||||
// #include "valgrind/memcheck.h"
|
||||
#include "malloc.h"
|
||||
#include <algorithm>
|
||||
|
@ -40,11 +20,19 @@
|
|||
#include <event.h>
|
||||
#endif
|
||||
|
||||
using namespace log4cxx;
|
||||
#ifdef WIN32
|
||||
#include "win32/win32dep.h"
|
||||
#define ssize_t SSIZE_T
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
|
||||
static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple");
|
||||
static LoggerPtr logger = log4cxx::Logger::getLogger("backend");
|
||||
int m_sock;
|
||||
#include "purple_defs.h"
|
||||
|
||||
DEFINE_LOGGER(logger_libpurple, "libpurple");
|
||||
DEFINE_LOGGER(logger, "backend");
|
||||
|
||||
int main_socket;
|
||||
static int writeInput;
|
||||
|
||||
using namespace Transport;
|
||||
|
@ -62,6 +50,21 @@ template <class T> std::string stringOf(T object) {
|
|||
return (os.str());
|
||||
}
|
||||
|
||||
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while(std::getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
static std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
return split(s, delim, elems);
|
||||
}
|
||||
|
||||
static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond);
|
||||
|
||||
class SpectrumNetworkPlugin;
|
||||
|
@ -89,7 +92,7 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key
|
|||
return def;
|
||||
}
|
||||
std::string ret(str);
|
||||
free(str);
|
||||
g_free(str);
|
||||
|
||||
if (ret.find("#") != std::string::npos) {
|
||||
ret = ret.substr(0, ret.find("#"));
|
||||
|
@ -107,13 +110,8 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key
|
|||
|
||||
#define KEYFILE_BOOL(CAT, KEY) g_key_file_get_boolean(keyfile, CAT, KEY, 0)
|
||||
|
||||
static gboolean nodaemon = FALSE;
|
||||
static gchar *logfile = NULL;
|
||||
static gchar *lock_file = NULL;
|
||||
static gchar *host = NULL;
|
||||
static int port = 10000;
|
||||
static gboolean ver = FALSE;
|
||||
static gboolean list_purple_settings = FALSE;
|
||||
|
||||
struct FTData {
|
||||
unsigned long id;
|
||||
|
@ -122,121 +120,12 @@ struct FTData {
|
|||
};
|
||||
|
||||
static GOptionEntry options_entries[] = {
|
||||
{ "nodaemon", 'n', 0, G_OPTION_ARG_NONE, &nodaemon, "Disable background daemon mode", NULL },
|
||||
{ "logfile", 'l', 0, G_OPTION_ARG_STRING, &logfile, "Set file to log", NULL },
|
||||
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &lock_file, "File where to write transport PID", NULL },
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Shows Spectrum version", NULL },
|
||||
{ "list-purple-settings", 's', 0, G_OPTION_ARG_NONE, &list_purple_settings, "Lists purple settings which can be used in config file", NULL },
|
||||
{ "host", 'h', 0, G_OPTION_ARG_STRING, &host, "Host to connect to", NULL },
|
||||
{ "port", 'p', 0, G_OPTION_ARG_INT, &port, "Port to connect to", NULL },
|
||||
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
|
||||
};
|
||||
|
||||
static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info);
|
||||
static GHashTable *ui_info = NULL;
|
||||
|
||||
static GHashTable *spectrum_ui_get_info(void)
|
||||
{
|
||||
if(NULL == ui_info) {
|
||||
ui_info = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert(ui_info, g_strdup("name"), g_strdup("Spectrum"));
|
||||
g_hash_table_insert(ui_info, g_strdup("version"), g_strdup("0.5"));
|
||||
g_hash_table_insert(ui_info, g_strdup("website"), g_strdup("http://spectrum.im"));
|
||||
g_hash_table_insert(ui_info, g_strdup("dev_website"), g_strdup("http://spectrum.im"));
|
||||
g_hash_table_insert(ui_info, g_strdup("client_type"), g_strdup("pc"));
|
||||
|
||||
/*
|
||||
* This is the client key for "Pidgin." It is owned by the AIM
|
||||
* account "markdoliner." Please don't use this key for other
|
||||
* applications. You can either not specify a client key, in
|
||||
* which case the default "libpurple" key will be used, or you
|
||||
* can register for your own client key at
|
||||
* http://developer.aim.com/manageKeys.jsp
|
||||
*/
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-aim-clientkey"), g_strdup("ma1cSASNCKFtrdv9"));
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-icq-clientkey"), g_strdup("ma1cSASNCKFtrdv9"));
|
||||
|
||||
/*
|
||||
* This is the distid for Pidgin, given to us by AOL. Please
|
||||
* don't use this for other applications. You can just not
|
||||
* specify a distid and libpurple will use a default.
|
||||
*/
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-aim-distid"), GINT_TO_POINTER(1550));
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-icq-distid"), GINT_TO_POINTER(1550));
|
||||
}
|
||||
|
||||
return ui_info;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
badchar(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case ',':
|
||||
case '\0':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '<':
|
||||
case '>':
|
||||
case '"':
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
badentity(const char *c)
|
||||
{
|
||||
if (!g_ascii_strncasecmp(c, "<", 4) ||
|
||||
!g_ascii_strncasecmp(c, ">", 4) ||
|
||||
!g_ascii_strncasecmp(c, """, 6)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
process_link(GString *ret,
|
||||
const char *start, const char *c,
|
||||
int matchlen,
|
||||
const char *urlprefix,
|
||||
int inside_paren)
|
||||
{
|
||||
char *url_buf;
|
||||
const char *t;
|
||||
|
||||
for (t = c;; t++) {
|
||||
if (!badchar(*t) && !badentity(t))
|
||||
continue;
|
||||
|
||||
if (t - c == matchlen)
|
||||
break;
|
||||
|
||||
if (*t == ',' && *(t + 1) != ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t > start && *(t - 1) == '.')
|
||||
t--;
|
||||
if (t > start && *(t - 1) == ')' && inside_paren > 0)
|
||||
t--;
|
||||
|
||||
url_buf = g_strndup(c, t - c);
|
||||
// tmpurlbuf = purple_unescape_html(url_buf);
|
||||
// std::cout << url_buf << "\n";
|
||||
g_string_append_printf(ret, "<A HREF=\"%s%s\">%s</A>",
|
||||
urlprefix,
|
||||
url_buf, url_buf);
|
||||
// g_free(tmpurlbuf);
|
||||
g_free(url_buf);
|
||||
return t;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static gboolean ft_ui_ready(void *data) {
|
||||
PurpleXfer *xfer = (PurpleXfer *) data;
|
||||
|
@ -246,184 +135,6 @@ static gboolean ft_ui_ready(void *data) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
spectrum_markup_linkify(const char *text)
|
||||
{
|
||||
const char *c, *t, *q = NULL;
|
||||
char *tmpurlbuf, *url_buf;
|
||||
gunichar g;
|
||||
gboolean inside_html = FALSE;
|
||||
int inside_paren = 0;
|
||||
GString *ret;
|
||||
|
||||
if (text == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = g_string_new("");
|
||||
|
||||
c = text;
|
||||
while (*c) {
|
||||
|
||||
if(*c == '(' && !inside_html) {
|
||||
inside_paren++;
|
||||
ret = g_string_append_c(ret, *c);
|
||||
c++;
|
||||
}
|
||||
|
||||
if(inside_html) {
|
||||
if(*c == '>') {
|
||||
inside_html = FALSE;
|
||||
} else if(!q && (*c == '\"' || *c == '\'')) {
|
||||
q = c;
|
||||
} else if(q) {
|
||||
if(*c == *q)
|
||||
q = NULL;
|
||||
}
|
||||
} else if(*c == '<') {
|
||||
inside_html = TRUE;
|
||||
if (!g_ascii_strncasecmp(c, "<A", 2)) {
|
||||
while (1) {
|
||||
if (!g_ascii_strncasecmp(c, "/A>", 3)) {
|
||||
inside_html = FALSE;
|
||||
break;
|
||||
}
|
||||
ret = g_string_append_c(ret, *c);
|
||||
c++;
|
||||
if (!(*c))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!g_ascii_strncasecmp(c, "http://", 7)) {
|
||||
c = process_link(ret, text, c, 7, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "https://", 8)) {
|
||||
c = process_link(ret, text, c, 8, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "ftp://", 6)) {
|
||||
c = process_link(ret, text, c, 6, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "sftp://", 7)) {
|
||||
c = process_link(ret, text, c, 7, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "file://", 7)) {
|
||||
c = process_link(ret, text, c, 7, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "www.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
|
||||
c = process_link(ret, text, c, 4, "http://", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "ftp.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
|
||||
c = process_link(ret, text, c, 4, "ftp://", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "xmpp:", 5) && (c == text || badchar(c[-1]) || badentity(c-1))) {
|
||||
c = process_link(ret, text, c, 5, "", inside_paren);
|
||||
} else if (!g_ascii_strncasecmp(c, "mailto:", 7)) {
|
||||
t = c;
|
||||
while (1) {
|
||||
if (badchar(*t) || badentity(t)) {
|
||||
const char *d;
|
||||
if (t - c == 7) {
|
||||
break;
|
||||
}
|
||||
if (t > text && *(t - 1) == '.')
|
||||
t--;
|
||||
if ((d = strstr(c + 7, "?")) != NULL && d < t)
|
||||
url_buf = g_strndup(c + 7, d - c - 7);
|
||||
else
|
||||
url_buf = g_strndup(c + 7, t - c - 7);
|
||||
if (!purple_email_is_valid(url_buf)) {
|
||||
g_free(url_buf);
|
||||
break;
|
||||
}
|
||||
g_free(url_buf);
|
||||
url_buf = g_strndup(c, t - c);
|
||||
// tmpurlbuf = purple_unescape_html(url_buf);
|
||||
g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
|
||||
url_buf, url_buf);
|
||||
g_free(url_buf);
|
||||
// g_free(tmpurlbuf);
|
||||
c = t;
|
||||
break;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
} else if (c != text && (*c == '@')) {
|
||||
int flag;
|
||||
GString *gurl_buf = NULL;
|
||||
const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0";
|
||||
|
||||
if (strchr(illegal_chars,*(c - 1)) || strchr(illegal_chars, *(c + 1)))
|
||||
flag = 0;
|
||||
else {
|
||||
flag = 1;
|
||||
gurl_buf = g_string_new("");
|
||||
}
|
||||
|
||||
t = c;
|
||||
while (flag) {
|
||||
/* iterate backwards grabbing the local part of an email address */
|
||||
g = g_utf8_get_char(t);
|
||||
if (badchar(*t) || (g >= 127) || (*t == '(') ||
|
||||
((*t == ';') && ((t > (text+2) && (!g_ascii_strncasecmp(t - 3, "<", 4) ||
|
||||
!g_ascii_strncasecmp(t - 3, ">", 4))) ||
|
||||
(t > (text+4) && (!g_ascii_strncasecmp(t - 5, """, 6)))))) {
|
||||
/* local part will already be part of ret, strip it out */
|
||||
ret = g_string_truncate(ret, ret->len - (c - t));
|
||||
ret = g_string_append_unichar(ret, g);
|
||||
break;
|
||||
} else {
|
||||
g_string_prepend_unichar(gurl_buf, g);
|
||||
t = g_utf8_find_prev_char(text, t);
|
||||
if (t < text) {
|
||||
ret = g_string_assign(ret, "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t = g_utf8_find_next_char(c, NULL);
|
||||
|
||||
while (flag) {
|
||||
/* iterate forwards grabbing the domain part of an email address */
|
||||
g = g_utf8_get_char(t);
|
||||
if (badchar(*t) || (g >= 127) || (*t == ')') || badentity(t)) {
|
||||
char *d;
|
||||
|
||||
url_buf = g_string_free(gurl_buf, FALSE);
|
||||
|
||||
/* strip off trailing periods */
|
||||
if (strlen(url_buf) > 0) {
|
||||
for (d = url_buf + strlen(url_buf) - 1; *d == '.'; d--, t--)
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
tmpurlbuf = purple_unescape_html(url_buf);
|
||||
if (purple_email_is_valid(tmpurlbuf)) {
|
||||
g_string_append_printf(ret, "<A HREF=\"mailto:%s\">%s</A>",
|
||||
url_buf, url_buf);
|
||||
} else {
|
||||
g_string_append(ret, url_buf);
|
||||
}
|
||||
g_free(url_buf);
|
||||
g_free(tmpurlbuf);
|
||||
c = t;
|
||||
|
||||
break;
|
||||
} else {
|
||||
g_string_append_unichar(gurl_buf, g);
|
||||
t = g_utf8_find_next_char(t, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*c == ')' && !inside_html) {
|
||||
inside_paren--;
|
||||
ret = g_string_append_c(ret, *c);
|
||||
c++;
|
||||
}
|
||||
|
||||
if (*c == 0)
|
||||
break;
|
||||
|
||||
ret = g_string_append_c(ret, *c);
|
||||
c++;
|
||||
|
||||
}
|
||||
return g_string_free(ret, FALSE);
|
||||
}
|
||||
|
||||
struct authRequest {
|
||||
PurpleAccountRequestAuthorizationCb authorize_cb;
|
||||
PurpleAccountRequestAuthorizationCb deny_cb;
|
||||
|
@ -509,13 +220,13 @@ static std::string getAlias(PurpleBuddy *m_buddy) {
|
|||
|
||||
class SpectrumNetworkPlugin : public NetworkPlugin {
|
||||
public:
|
||||
SpectrumNetworkPlugin(const std::string &host, int port) : NetworkPlugin() {
|
||||
SpectrumNetworkPlugin() : NetworkPlugin() {
|
||||
|
||||
}
|
||||
|
||||
void handleExitRequest() {
|
||||
LOG4CXX_INFO(logger, "Exiting...");
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void getProtocolAndName(const std::string &legacyName, std::string &name, std::string &protocol) {
|
||||
|
@ -593,11 +304,29 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
i++;
|
||||
}
|
||||
g_strfreev (keys);
|
||||
|
||||
char* contents;
|
||||
gsize length;
|
||||
gboolean ret = g_file_get_contents ("gfire.cfg", &contents, &length, NULL);
|
||||
if (ret) {
|
||||
purple_account_set_int(account, "version", fromString<int>(std::string(contents, length)));
|
||||
}
|
||||
|
||||
|
||||
if (KEYFILE_STRING("service", "protocol") == "prpl-novell") {
|
||||
std::string username(purple_account_get_username(account));
|
||||
std::vector <std::string> u = split(username, '@');
|
||||
purple_account_set_username(account, (const char*) u.front().c_str());
|
||||
std::vector <std::string> s = split(u.back(), ':');
|
||||
purple_account_set_string(account, "server", s.front().c_str());
|
||||
purple_account_set_int(account, "port", atoi(s.back().c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
PurpleAccount *account = NULL;
|
||||
|
||||
|
||||
std::string name;
|
||||
std::string protocol;
|
||||
getProtocolAndName(legacyName, name, protocol);
|
||||
|
@ -614,7 +343,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL) {
|
||||
LOG4CXX_INFO(logger, "Using previously created account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
|
||||
account = purple_accounts_find(name.c_str(), protocol.c_str());
|
||||
|
@ -637,11 +365,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
|
||||
setDefaultAccountOptions(account);
|
||||
|
||||
// Enable account + privacy lists
|
||||
purple_account_set_enabled(account, "spectrum", TRUE);
|
||||
if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
|
||||
purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
|
||||
}
|
||||
|
||||
// Set the status
|
||||
const PurpleStatusType *status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE);
|
||||
if (status_type != NULL) {
|
||||
purple_account_set_status(account, purple_status_type_get_id(status_type), TRUE, NULL);
|
||||
|
@ -651,6 +381,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
PurpleAccount *account = m_sessions[user];
|
||||
if (account) {
|
||||
if (purple_account_get_int(account, "version", 0) != 0) {
|
||||
std::string data = stringOf(purple_account_get_int(account, "version", 0));
|
||||
g_file_set_contents ("gfire.cfg", data.c_str(), data.size(), NULL);
|
||||
}
|
||||
// VALGRIND_DO_LEAK_CHECK;
|
||||
m_sessions.erase(user);
|
||||
purple_account_disconnect(account);
|
||||
|
@ -661,50 +395,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
m_accounts.erase(account);
|
||||
|
||||
purple_accounts_delete(account);
|
||||
//
|
||||
// // Remove conversations.
|
||||
// // This has to be called before m_account->ui_data = NULL;, because it uses
|
||||
// // ui_data to call SpectrumMessageHandler::purpleConversationDestroyed() callback.
|
||||
// GList *iter;
|
||||
// for (iter = purple_get_conversations(); iter; ) {
|
||||
// PurpleConversation *conv = (PurpleConversation*) iter->data;
|
||||
// iter = iter->next;
|
||||
// if (purple_conversation_get_account(conv) == account)
|
||||
// purple_conversation_destroy(conv);
|
||||
// }
|
||||
//
|
||||
// g_free(account->ui_data);
|
||||
// account->ui_data = NULL;
|
||||
// m_accounts.erase(account);
|
||||
//
|
||||
// purple_notify_close_with_handle(account);
|
||||
// purple_request_close_with_handle(account);
|
||||
//
|
||||
// purple_accounts_remove(account);
|
||||
//
|
||||
// GSList *buddies = purple_find_buddies(account, NULL);
|
||||
// while(buddies) {
|
||||
// PurpleBuddy *b = (PurpleBuddy *) buddies->data;
|
||||
// purple_blist_remove_buddy(b);
|
||||
// buddies = g_slist_delete_link(buddies, buddies);
|
||||
// }
|
||||
//
|
||||
// /* Remove any open conversation for this account */
|
||||
// for (GList *it = purple_get_conversations(); it; ) {
|
||||
// PurpleConversation *conv = (PurpleConversation *) it->data;
|
||||
// it = it->next;
|
||||
// if (purple_conversation_get_account(conv) == account)
|
||||
// purple_conversation_destroy(conv);
|
||||
// }
|
||||
//
|
||||
// /* Remove this account's pounces */
|
||||
// // purple_pounce_destroy_all_by_account(account);
|
||||
//
|
||||
// /* This will cause the deletion of an old buddy icon. */
|
||||
// purple_buddy_icons_set_account_icon(account, NULL, 0);
|
||||
//
|
||||
// purple_account_destroy(account);
|
||||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
#ifndef WIN32
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
|
@ -768,17 +458,30 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) {
|
||||
PurpleAccount *account = m_sessions[user];
|
||||
if (account) {
|
||||
PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account);
|
||||
PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, legacyName.c_str(), account);
|
||||
if (!conv) {
|
||||
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str());
|
||||
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account);
|
||||
if (!conv) {
|
||||
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, legacyName.c_str());
|
||||
}
|
||||
}
|
||||
if (xhtml.empty()) {
|
||||
gchar *_markup = purple_markup_escape_text(message.c_str(), -1);
|
||||
purple_conv_im_send(PURPLE_CONV_IM(conv), _markup);
|
||||
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
|
||||
purple_conv_im_send(PURPLE_CONV_IM(conv), _markup);
|
||||
}
|
||||
else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
|
||||
purple_conv_chat_send(PURPLE_CONV_CHAT(conv), _markup);
|
||||
}
|
||||
g_free(_markup);
|
||||
}
|
||||
else {
|
||||
purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str());
|
||||
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
|
||||
purple_conv_im_send(PURPLE_CONV_IM(conv), xhtml.c_str());
|
||||
}
|
||||
else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
|
||||
purple_conv_chat_send(PURPLE_CONV_CHAT(conv), xhtml.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -915,6 +618,41 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &pasword) {
|
||||
PurpleAccount *account = m_sessions[user];
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
PurpleConnection *gc = purple_account_get_connection(account);
|
||||
GHashTable *comps = NULL;
|
||||
|
||||
// Check if the PurpleChat is not stored in buddy list
|
||||
PurpleChat *chat = purple_blist_find_chat(account, room.c_str());
|
||||
if (chat) {
|
||||
comps = purple_chat_get_components(chat);
|
||||
}
|
||||
else if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) {
|
||||
comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, room.c_str());
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, user << ": Joining the room " << room);
|
||||
if (comps) {
|
||||
serv_join_chat(gc, comps);
|
||||
g_hash_table_destroy(comps);
|
||||
}
|
||||
}
|
||||
|
||||
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
|
||||
PurpleAccount *account = m_sessions[user];
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, room.c_str(), account);
|
||||
purple_conversation_destroy(conv);
|
||||
}
|
||||
|
||||
void handleFTStartRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) {
|
||||
PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName];
|
||||
if (xfer) {
|
||||
|
@ -954,9 +692,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
}
|
||||
|
||||
void sendData(const std::string &string) {
|
||||
write(m_sock, string.c_str(), string.size());
|
||||
#ifdef WIN32
|
||||
::send(main_socket, string.c_str(), string.size(), 0);
|
||||
#else
|
||||
write(main_socket, string.c_str(), string.size());
|
||||
#endif
|
||||
if (writeInput == 0)
|
||||
writeInput = purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
|
||||
writeInput = purple_input_add(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
|
||||
}
|
||||
|
||||
void readyForData() {
|
||||
|
@ -1090,7 +832,8 @@ static void buddyListNewNode(PurpleBlistNode *node) {
|
|||
PurpleBuddy *buddy = (PurpleBuddy *) node;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
|
||||
LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy));
|
||||
std::vector<std::string> groups = getGroups(buddy);
|
||||
LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy) << " group (" << groups.size() << ")=" << groups[0]);
|
||||
|
||||
// Status
|
||||
pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
|
||||
|
@ -1178,8 +921,9 @@ static PurpleBlistUiOps blistUiOps =
|
|||
|
||||
static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) {
|
||||
// Don't forwards our own messages.
|
||||
if (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)
|
||||
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)) {
|
||||
return;
|
||||
}
|
||||
PurpleAccount *account = purple_conversation_get_account(conv);
|
||||
|
||||
// char *striped = purple_markup_strip_html(message);
|
||||
|
@ -1218,19 +962,67 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
|
|||
|
||||
// LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "'");
|
||||
|
||||
np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_);
|
||||
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
|
||||
np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_);
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name(conv) << "' " << w);
|
||||
np->handleMessage(np->m_accounts[account], purple_conversation_get_name(conv), message_, w, xhtml_);
|
||||
}
|
||||
}
|
||||
|
||||
static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
|
||||
PurpleAccount *account = purple_conversation_get_account(conv);
|
||||
|
||||
GList *l = cbuddies;
|
||||
while (l != NULL) {
|
||||
PurpleConvChatBuddy *cb = (PurpleConvChatBuddy *)l->data;
|
||||
std::string name(cb->name);
|
||||
int flags = GPOINTER_TO_INT(cb->flags);
|
||||
if (flags & PURPLE_CBFLAGS_OP || flags & PURPLE_CBFLAGS_HALFOP) {
|
||||
// item->addAttribute("affiliation", "admin");
|
||||
// item->addAttribute("role", "moderator");
|
||||
flags = 1;
|
||||
}
|
||||
else if (flags & PURPLE_CBFLAGS_FOUNDER) {
|
||||
// item->addAttribute("affiliation", "owner");
|
||||
// item->addAttribute("role", "moderator");
|
||||
flags = 1;
|
||||
}
|
||||
else {
|
||||
flags = 0;
|
||||
// item->addAttribute("affiliation", "member");
|
||||
// item->addAttribute("role", "participant");
|
||||
}
|
||||
|
||||
np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), (int) flags, pbnetwork::STATUS_ONLINE);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void conv_chat_remove_users(PurpleConversation *conv, GList *users) {
|
||||
PurpleAccount *account = purple_conversation_get_account(conv);
|
||||
|
||||
GList *l = users;
|
||||
while (l != NULL) {
|
||||
std::string name((char *) l->data);
|
||||
np->handleParticipantChanged(np->m_accounts[account], name, purple_conversation_get_name(conv), 0, pbnetwork::STATUS_NONE);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
static PurpleConversationUiOps conversation_ui_ops =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,//conv_write_chat, /* write_chat */
|
||||
conv_write_im,//conv_write_chat, /* write_chat */
|
||||
conv_write_im, /* write_im */
|
||||
NULL,//conv_write_conv, /* write_conv */
|
||||
NULL,//conv_chat_add_users, /* chat_add_users */
|
||||
conv_chat_add_users, /* chat_add_users */
|
||||
NULL,//conv_chat_rename_user, /* chat_rename_user */
|
||||
NULL,//conv_chat_remove_users, /* chat_remove_users */
|
||||
conv_chat_remove_users, /* chat_remove_users */
|
||||
NULL,//pidgin_conv_chat_update_user, /* chat_update_user */
|
||||
NULL,//pidgin_conv_present_conversation, /* present */
|
||||
NULL,//pidgin_conv_has_focus, /* has_focus */
|
||||
|
@ -1372,11 +1164,13 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif
|
|||
if (true) {
|
||||
gchar *data;
|
||||
gchar *path = purple_buddy_icon_get_full_path(icon);
|
||||
if (g_file_get_contents (path, &data, &len, NULL)) {
|
||||
photo = std::string(data, len);
|
||||
free(data);
|
||||
if (path) {
|
||||
if (g_file_get_contents(path, &data, &len, NULL)) {
|
||||
photo = std::string(data, len);
|
||||
g_free(data);
|
||||
}
|
||||
g_free(path);
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
else {
|
||||
const gchar * data = (gchar*)purple_buddy_icon_get_data(icon, &len);
|
||||
|
@ -1674,6 +1468,8 @@ debug_init(void)
|
|||
REGISTER_G_LOG_HANDLER("GModule");
|
||||
REGISTER_G_LOG_HANDLER("GLib-GObject");
|
||||
REGISTER_G_LOG_HANDLER("GThread");
|
||||
REGISTER_G_LOG_HANDLER("GConf");
|
||||
|
||||
|
||||
#undef REGISTER_G_LOD_HANDLER
|
||||
}
|
||||
|
@ -1697,6 +1493,9 @@ static void signed_on(PurpleConnection *gc, gpointer unused) {
|
|||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
|
||||
// For prpl-gg
|
||||
execute_purple_plugin_action(gc, "Download buddylist from Server");
|
||||
}
|
||||
|
||||
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
|
||||
|
@ -1761,13 +1560,19 @@ static void gotAttention(PurpleAccount *account, const char *who, PurpleConversa
|
|||
static bool initPurple() {
|
||||
bool ret;
|
||||
|
||||
if (!resolvePurpleFunctions()) {
|
||||
LOG4CXX_ERROR(logger, "Unable to load libpurple.dll or some of the needed methods");
|
||||
return false;
|
||||
}
|
||||
|
||||
purple_plugins_add_search_path("./plugins");
|
||||
|
||||
purple_util_set_user_dir("./");
|
||||
remove("./accounts.xml");
|
||||
remove("./blist.xml");
|
||||
|
||||
// if (m_configuration.logAreas & LOG_AREA_PURPLE)
|
||||
purple_debug_set_ui_ops(&debugUiOps);
|
||||
purple_debug_set_verbose(true);
|
||||
purple_debug_set_ui_ops(&debugUiOps);
|
||||
purple_debug_set_verbose(true);
|
||||
|
||||
purple_core_set_ui_ops(&coreUiOps);
|
||||
if (KEYFILE_STRING("service", "eventloop") == "libev") {
|
||||
|
@ -1831,56 +1636,17 @@ static bool initPurple() {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#ifndef WIN32
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int create_socket(char *host, int portno) {
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
int m_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
hostent *hos; // Resolve name
|
||||
if ((hos = gethostbyname(host)) == NULL) {
|
||||
// strerror() will not work for gethostbyname() and hstrerror()
|
||||
// is supposedly obsolete
|
||||
exit(1);
|
||||
}
|
||||
serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
|
||||
|
||||
if (connect(m_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
close(m_sock);
|
||||
m_sock = 0;
|
||||
}
|
||||
|
||||
int flags = fcntl(m_sock, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(m_sock, F_SETFL, flags);
|
||||
return m_sock;
|
||||
}
|
||||
|
||||
static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond) {
|
||||
if (cond & PURPLE_INPUT_READ) {
|
||||
char buffer[65535];
|
||||
char *ptr = buffer;
|
||||
#ifdef WIN32
|
||||
ssize_t n = recv(source, ptr, sizeof(buffer), 0);
|
||||
#else
|
||||
ssize_t n = read(source, ptr, sizeof(buffer));
|
||||
#endif
|
||||
if (n <= 0) {
|
||||
LOG4CXX_INFO(logger, "Diconnecting from spectrum2 server");
|
||||
exit(errno);
|
||||
|
@ -1903,17 +1669,10 @@ int main(int argc, char **argv) {
|
|||
context = g_option_context_new("config_file_name or profile name");
|
||||
g_option_context_add_main_entries(context, options_entries, "");
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
std::cout << "option parsing failed: " << error->message << "\n";
|
||||
std::cerr << "option parsing failed: " << error->message << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver) {
|
||||
// std::cout << VERSION << "\n";
|
||||
std::cout << "verze\n";
|
||||
g_option_context_free(context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
#ifdef WIN32
|
||||
std::cout << "Usage: spectrum.exe <configuration_file.cfg>\n";
|
||||
|
@ -1937,27 +1696,6 @@ int main(int argc, char **argv) {
|
|||
g_option_context_free(context);
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
// if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) {
|
||||
// std::cout << "SIGINT handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if (signal(SIGTERM, spectrum_sigterm_handler) == SIG_ERR) {
|
||||
// std::cout << "SIGTERM handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// struct sigaction sa;
|
||||
// memset(&sa, 0, sizeof(sa));
|
||||
// sa.sa_handler = spectrum_sighup_handler;
|
||||
// if (sigaction(SIGHUP, &sa, NULL)) {
|
||||
// std::cout << "SIGHUP handler can't be set\n";
|
||||
// g_option_context_free(context);
|
||||
// return -1;
|
||||
// }
|
||||
#endif
|
||||
keyfile = g_key_file_new ();
|
||||
if (!g_key_file_load_from_file (keyfile, argv[1], (GKeyFileFlags) 0, 0)) {
|
||||
|
@ -1965,39 +1703,20 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
LogString pid, jid;
|
||||
log4cxx::helpers::Transcoder::decode(stringOf(getpid()), pid);
|
||||
log4cxx::helpers::Transcoder::decode(KEYFILE_STRING("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);
|
||||
Config config;
|
||||
if (!config.load(argv[1])) {
|
||||
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
initPurple();
|
||||
|
||||
m_sock = create_socket(host, port);
|
||||
|
||||
purple_input_add(m_sock, PURPLE_INPUT_READ, &transportDataReceived, NULL);
|
||||
main_socket = create_socket(host, port);
|
||||
purple_input_add(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL);
|
||||
purple_timeout_add_seconds(30, pingTimeout, NULL);
|
||||
|
||||
np = new SpectrumNetworkPlugin(host, port);
|
||||
np = new SpectrumNetworkPlugin();
|
||||
bool libev = KEYFILE_STRING("service", "eventloop") == "libev";
|
||||
|
||||
GMainLoop *m_loop;
|
||||
|
|
5
backends/libpurple/purple_defs.cpp
Normal file
5
backends/libpurple/purple_defs.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "purple_defs.h"
|
||||
bool resolvePurpleFunctions() {
|
||||
return true;
|
||||
}
|
||||
|
3
backends/libpurple/purple_defs.h
Normal file
3
backends/libpurple/purple_defs.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
bool resolvePurpleFunctions();
|
153
backends/libpurple/utils.cpp
Normal file
153
backends/libpurple/utils.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "purple.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "errno.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ether.h>
|
||||
#include "sys/socket.h"
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#define ssize_t SSIZE_T
|
||||
#include "win32/win32dep.h"
|
||||
#endif
|
||||
|
||||
#include "purple_defs.h"
|
||||
|
||||
static GHashTable *ui_info = NULL;
|
||||
|
||||
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name) {
|
||||
PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
|
||||
if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
|
||||
PurplePluginAction *action = NULL;
|
||||
GList *actions, *l;
|
||||
|
||||
actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
|
||||
|
||||
for (l = actions; l != NULL; l = l->next) {
|
||||
if (l->data) {
|
||||
action = (PurplePluginAction *) l->data;
|
||||
action->plugin = plugin;
|
||||
action->context = gc;
|
||||
if ((std::string) action->label == name) {
|
||||
action->callback(action);
|
||||
}
|
||||
purple_plugin_action_free(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GHashTable *spectrum_ui_get_info(void)
|
||||
{
|
||||
if(NULL == ui_info) {
|
||||
ui_info = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert(ui_info, g_strdup("name"), g_strdup("Spectrum"));
|
||||
g_hash_table_insert(ui_info, g_strdup("version"), g_strdup("0.5"));
|
||||
g_hash_table_insert(ui_info, g_strdup("website"), g_strdup("http://spectrum.im"));
|
||||
g_hash_table_insert(ui_info, g_strdup("dev_website"), g_strdup("http://spectrum.im"));
|
||||
g_hash_table_insert(ui_info, g_strdup("client_type"), g_strdup("pc"));
|
||||
|
||||
/*
|
||||
* This is the client key for "Pidgin." It is owned by the AIM
|
||||
* account "markdoliner." Please don't use this key for other
|
||||
* applications. You can either not specify a client key, in
|
||||
* which case the default "libpurple" key will be used, or you
|
||||
* can register for your own client key at
|
||||
* http://developer.aim.com/manageKeys.jsp
|
||||
*/
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-aim-clientkey"), g_strdup("ma1cSASNCKFtrdv9"));
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-icq-clientkey"), g_strdup("ma1cSASNCKFtrdv9"));
|
||||
|
||||
/*
|
||||
* This is the distid for Pidgin, given to us by AOL. Please
|
||||
* don't use this for other applications. You can just not
|
||||
* specify a distid and libpurple will use a default.
|
||||
*/
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-aim-distid"), GINT_TO_POINTER(1550));
|
||||
g_hash_table_insert(ui_info, g_strdup("prpl-icq-distid"), GINT_TO_POINTER(1550));
|
||||
}
|
||||
|
||||
return ui_info;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int create_socket(char *host, int portno) {
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
int main_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
hostent *hos; // Resolve name
|
||||
if ((hos = gethostbyname(host)) == NULL) {
|
||||
// strerror() will not work for gethostbyname() and hstrerror()
|
||||
// is supposedly obsolete
|
||||
exit(1);
|
||||
}
|
||||
serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
|
||||
|
||||
if (connect(main_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
close(main_socket);
|
||||
main_socket = 0;
|
||||
}
|
||||
|
||||
// int flags = fcntl(main_socket, F_GETFL);
|
||||
// flags |= O_NONBLOCK;
|
||||
// fcntl(main_socket, F_SETFL, flags);
|
||||
return main_socket;
|
||||
}
|
33
backends/libpurple/utils.h
Normal file
33
backends/libpurple/utils.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "purple.h"
|
||||
#include <string>
|
||||
|
||||
#ifndef WIN32
|
||||
void spectrum_sigchld_handler(int sig);
|
||||
#endif
|
||||
|
||||
int create_socket(char *host, int portno);
|
||||
GHashTable *spectrum_ui_get_info(void);
|
||||
|
||||
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name);
|
|
@ -2,8 +2,10 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/memoryusage.h"
|
||||
#include "transport/logger.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/userregistration.h"
|
||||
|
@ -12,13 +14,8 @@
|
|||
#include "transport/rostermanager.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logger.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
// #include "valgrind/memcheck.h"
|
||||
|
@ -26,14 +23,22 @@
|
|||
#include <dbus-1.0/dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("backend");
|
||||
DEFINE_LOGGER(logger, "backend");
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
class SpectrumNetworkPlugin;
|
||||
|
||||
#define GET_RESPONSE_DATA(RESP, DATA) ((RESP.find(std::string(DATA) + " ") != std::string::npos) ? RESP.substr(RESP.find(DATA) + strlen(DATA) + 1) : "");
|
||||
#define GET_PROPERTY(VAR, OBJ, WHICH, PROP) std::string VAR = sk->send_command(std::string("GET ") + OBJ + " " + WHICH + " " + PROP); \
|
||||
try {\
|
||||
VAR = GET_RESPONSE_DATA(VAR, PROP);\
|
||||
}\
|
||||
catch (std::out_of_range& oor) {\
|
||||
VAR="";\
|
||||
}
|
||||
|
||||
|
||||
|
||||
SpectrumNetworkPlugin *np;
|
||||
|
||||
|
@ -81,7 +86,7 @@ static pbnetwork::StatusType getStatus(const std::string &st) {
|
|||
class Skype {
|
||||
public:
|
||||
Skype(const std::string &user, const std::string &username, const std::string &password);
|
||||
~Skype() { logout(); }
|
||||
~Skype() { LOG4CXX_INFO(logger, "Skype instance desctuctor"); logout(); }
|
||||
void login();
|
||||
void logout();
|
||||
std::string send_command(const std::string &message);
|
||||
|
@ -97,6 +102,10 @@ class Skype {
|
|||
bool createDBusProxy();
|
||||
bool loadSkypeBuddies();
|
||||
|
||||
int getPid() {
|
||||
return (int) m_pid;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_username;
|
||||
std::string m_password;
|
||||
|
@ -124,7 +133,9 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
std::string name = legacyName;
|
||||
name = name.substr(name.find(".") + 1);
|
||||
if (name.find("skype.") == 0 || name.find("prpl-skype.") == 0) {
|
||||
name = name.substr(name.find(".") + 1);
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Creating account with name '" << name << "'");
|
||||
|
||||
Skype *skype = new Skype(user, name, password);
|
||||
|
@ -134,10 +145,27 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
skype->login();
|
||||
}
|
||||
|
||||
void handleMemoryUsage(double &res, double &shared) {
|
||||
res = 0;
|
||||
shared = 0;
|
||||
for(std::map<std::string, Skype *>::const_iterator it = m_sessions.begin(); it != m_sessions.end(); it++) {
|
||||
Skype *skype = it->second;
|
||||
if (skype) {
|
||||
double r;
|
||||
double s;
|
||||
process_mem_usage(s, r, skype->getPid());
|
||||
res += r;
|
||||
shared += s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
Skype *skype = m_sessions[user];
|
||||
if (skype) {
|
||||
LOG4CXX_INFO(logger, "User wants to logout, logging out");
|
||||
skype->logout();
|
||||
Logging::shutdownLogging();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +206,21 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
Skype *skype = m_sessions[user];
|
||||
if (skype) {
|
||||
skype->send_command("SET USER " + buddyName + " BUDDYSTATUS 2 Please authorize me");
|
||||
skype->send_command("SET USER " + buddyName + " ISAUTHORIZED TRUE");
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
Skype *skype = m_sessions[user];
|
||||
if (skype) {
|
||||
skype->send_command("SET USER " + buddyName + " BUDDYSTATUS 1");
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml) {
|
||||
Skype *skype = m_sessions[user];
|
||||
if (skype) {
|
||||
|
@ -253,7 +296,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
std::cout << skype->getUsername() << " " << name << "\n";
|
||||
if (skype->getUsername() == name) {
|
||||
alias = skype->send_command("GET PROFILE FULLNAME");
|
||||
alias = alias.substr(17);
|
||||
alias = GET_RESPONSE_DATA(alias, "FULLNAME")
|
||||
}
|
||||
handleVCard(user, id, legacyName, "", alias, photo);
|
||||
}
|
||||
|
@ -268,13 +311,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
void handleVCardUpdatedRequest(const std::string &user, const std::string &p, const std::string &nickname) {
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
|
||||
}
|
||||
|
||||
void handleBuddyBlockToggled(const std::string &user, const std::string &buddyName, bool blocked) {
|
||||
|
||||
}
|
||||
|
@ -331,7 +367,8 @@ bool Skype::createDBusProxy() {
|
|||
LOG4CXX_INFO(logger, m_username << ":" << error->message);
|
||||
|
||||
if (m_counter == 15) {
|
||||
np->handleDisconnected(m_user, 0, error->message);
|
||||
LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created: " << error->message);
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, error->message);
|
||||
logout();
|
||||
g_error_free(error);
|
||||
return FALSE;
|
||||
|
@ -360,6 +397,12 @@ static gboolean create_dbus_proxy(gpointer data) {
|
|||
}
|
||||
|
||||
void Skype::login() {
|
||||
if (m_username.find("..") == 0 || m_username.find("/") != std::string::npos) {
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Invalid username");
|
||||
return;
|
||||
}
|
||||
boost::filesystem::remove_all(std::string("/tmp/skype/") + m_username);
|
||||
|
||||
boost::filesystem::path path(std::string("/tmp/skype/") + m_username);
|
||||
if (!boost::filesystem::exists(path)) {
|
||||
boost::filesystem::create_directories(path);
|
||||
|
@ -394,6 +437,7 @@ void Skype::login() {
|
|||
"</config>\n";
|
||||
g_file_set_contents(std::string(std::string("/tmp/skype/") + m_username + "/" + m_username +"/config.xml").c_str(), config_xml.c_str(), -1, NULL);
|
||||
|
||||
sleep(1);
|
||||
std::string db_path = std::string("/tmp/skype/") + m_username;
|
||||
char *db = (char *) malloc(db_path.size() + 1);
|
||||
strcpy(db, db_path.c_str());
|
||||
|
@ -401,7 +445,8 @@ void Skype::login() {
|
|||
gchar* argv[6] = {"skype", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0};
|
||||
|
||||
int fd;
|
||||
g_spawn_async_with_pipes(NULL,
|
||||
GError *error = NULL;
|
||||
bool spawned = g_spawn_async_with_pipes(NULL,
|
||||
argv,
|
||||
NULL /*envp*/,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
|
@ -411,9 +456,16 @@ void Skype::login() {
|
|||
&fd,
|
||||
NULL,
|
||||
&fd_output,
|
||||
NULL /*error*/);
|
||||
&error);
|
||||
|
||||
if (!spawned) {
|
||||
LOG4CXX_ERROR(logger, "Error spawning the Skype instance: " << error->message)
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Error spawning the Skype instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string login_data = std::string(m_username + " " + m_password + "\n");
|
||||
LOG4CXX_INFO(logger, m_username << ": Login data=" << login_data);
|
||||
LOG4CXX_INFO(logger, m_username << ": Login data=" << m_username);
|
||||
write(fd, login_data.c_str(), login_data.size());
|
||||
close(fd);
|
||||
|
||||
|
@ -426,17 +478,18 @@ void Skype::login() {
|
|||
|
||||
if (m_connection == NULL)
|
||||
{
|
||||
LOG4CXX_INFO(logger, "Creating DBus connection.");
|
||||
LOG4CXX_INFO(logger, "Creating DBUS connection.");
|
||||
GError *error = NULL;
|
||||
m_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
|
||||
if (m_connection == NULL && error != NULL)
|
||||
{
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS Error: " << error->message);
|
||||
LOG4CXX_INFO(logger, m_username << ": Creating DBUS Connection error: " << error->message);
|
||||
g_error_free(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
m_timer = g_timeout_add_seconds(1, create_dbus_proxy, this);
|
||||
}
|
||||
|
||||
|
@ -449,28 +502,35 @@ bool Skype::loadSkypeBuddies() {
|
|||
int bytes_read = read(fd_output, buffer, 1023);
|
||||
if (bytes_read > 0) {
|
||||
buffer[bytes_read] = 0;
|
||||
np->handleDisconnected(m_user, 0, buffer);
|
||||
close(fd_output);
|
||||
logout();
|
||||
return FALSE;
|
||||
std::string b(buffer);
|
||||
LOG4CXX_WARN(logger, "Skype wrote this on stdout '" << b << "'");
|
||||
if (b.find("Incorrect Password") != std::string::npos) {
|
||||
LOG4CXX_INFO(logger, "Incorrect password, logging out")
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_FAILED, "Incorrect password");
|
||||
close(fd_output);
|
||||
logout();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
std::string re = send_command("NAME Spectrum");
|
||||
if (m_counter++ > 15) {
|
||||
np->handleDisconnected(m_user, 0, "");
|
||||
LOG4CXX_ERROR(logger, "Logging out, because we tried to connect the Skype over DBUS 15 times without success");
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon.");
|
||||
close(fd_output);
|
||||
logout();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (re.empty() || re == "CONNSTATUS OFFLINE") {
|
||||
if (re.empty() || re == "CONNSTATUS OFFLINE" || re == "ERROR 68") {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
close(fd_output);
|
||||
|
||||
if (send_command("PROTOCOL 7") != "PROTOCOL 7") {
|
||||
np->handleDisconnected(m_user, 0, "Skype is not ready");
|
||||
LOG4CXX_ERROR(logger, "PROTOCOL 7 failed, logging out");
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon.");
|
||||
logout();
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -479,20 +539,32 @@ bool Skype::loadSkypeBuddies() {
|
|||
|
||||
std::map<std::string, std::string> group_map;
|
||||
std::string groups = send_command("SEARCH GROUPS CUSTOM");
|
||||
groups = groups.substr(groups.find(' ') + 1);
|
||||
std::vector<std::string> grps;
|
||||
boost::split(grps, groups, boost::is_any_of(","));
|
||||
BOOST_FOREACH(std::string grp, grps) {
|
||||
std::vector<std::string> data;
|
||||
std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME");
|
||||
boost::split(data, name, boost::is_any_of(" "));
|
||||
name = name.substr(name.find("DISPLAYNAME") + 12);
|
||||
if (groups.find(' ') != std::string::npos) {
|
||||
groups = groups.substr(groups.find(' ') + 1);
|
||||
std::vector<std::string> grps;
|
||||
boost::split(grps, groups, boost::is_any_of(","));
|
||||
BOOST_FOREACH(std::string grp, grps) {
|
||||
std::vector<std::string> data;
|
||||
std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME");
|
||||
|
||||
std::string users = send_command("GET GROUP " + data[1] + " USERS");
|
||||
users = name.substr(name.find("USERS") + 6);
|
||||
boost::split(data, users, boost::is_any_of(","));
|
||||
BOOST_FOREACH(std::string u, data) {
|
||||
group_map[u] = grp;
|
||||
if (name.find("ERROR") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::split(data, name, boost::is_any_of(" "));
|
||||
name = GET_RESPONSE_DATA(name, "DISPLAYNAME");
|
||||
|
||||
std::string users = send_command("GET GROUP " + data[1] + " USERS");
|
||||
try {
|
||||
users = GET_RESPONSE_DATA(users, "USERS");
|
||||
}
|
||||
catch (std::out_of_range& oor) {
|
||||
continue;
|
||||
}
|
||||
boost::split(data, users, boost::is_any_of(","));
|
||||
BOOST_FOREACH(std::string u, data) {
|
||||
group_map[u] = grp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,7 +577,7 @@ bool Skype::loadSkypeBuddies() {
|
|||
// online status;friendly name;voicemail;mood
|
||||
// (comma-seperated lines, usernames can have comma's)
|
||||
|
||||
for (int i=0; full_friends_list[i] && *full_friends_list[i] != '\0'; i+=8)
|
||||
for (int i=0; full_friends_list[i] && full_friends_list[i+1] && *full_friends_list[i] != '\0'; i+=8)
|
||||
{
|
||||
std::string buddy = full_friends_list[i];
|
||||
|
||||
|
@ -553,8 +625,12 @@ void Skype::logout() {
|
|||
send_command("SET USERSTATUS OFFLINE");
|
||||
sleep(2);
|
||||
g_object_unref(m_proxy);
|
||||
LOG4CXX_INFO(logger, m_username << ": Killing Skype instance");
|
||||
LOG4CXX_INFO(logger, m_username << ": Terminating Skype instance (SIGTERM)");
|
||||
kill((int) m_pid, SIGTERM);
|
||||
// Give skype a chance
|
||||
sleep(2);
|
||||
LOG4CXX_INFO(logger, m_username << ": Killing Skype instance (SIGKILL)");
|
||||
kill((int) m_pid, SIGKILL);
|
||||
m_pid = 0;
|
||||
}
|
||||
}
|
||||
|
@ -565,6 +641,7 @@ std::string Skype::send_command(const std::string &message) {
|
|||
// int message_num;
|
||||
// gchar error_return[30];
|
||||
|
||||
LOG4CXX_INFO(logger, "Sending: '" << message << "'");
|
||||
if (!dbus_g_proxy_call (m_proxy, "Invoke", &error, G_TYPE_STRING, message.c_str(), G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &str, G_TYPE_INVALID))
|
||||
{
|
||||
|
@ -572,14 +649,16 @@ std::string Skype::send_command(const std::string &message) {
|
|||
{
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS Error: " << error->message);
|
||||
g_error_free(error);
|
||||
return "";
|
||||
} else {
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS no response");
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
if (str != NULL)
|
||||
{
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS:" << str);
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS:'" << str << "'");
|
||||
}
|
||||
return str ? std::string(str) : std::string();
|
||||
}
|
||||
|
@ -599,57 +678,73 @@ static void handle_skype_message(std::string &message, Skype *sk) {
|
|||
}
|
||||
else {
|
||||
pbnetwork::StatusType status = getStatus(cmd[3]);
|
||||
std::string mood_text = sk->send_command("GET USER " + cmd[1] + " MOOD_TEXT");
|
||||
mood_text = mood_text.substr(mood_text.find("MOOD_TEXT") + 10);
|
||||
|
||||
std::string alias = sk->send_command("GET USER " + cmd[1] + " FULLNAME");
|
||||
alias = alias.substr(alias.find("FULLNAME") + 9);
|
||||
GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT");
|
||||
GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME");
|
||||
|
||||
std::vector<std::string> groups;
|
||||
np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text);
|
||||
}
|
||||
}
|
||||
else if (cmd[2] == "MOOD_TEXT") {
|
||||
std::string st = sk->send_command("GET USER " + cmd[1] + " ONLINESTATUS");
|
||||
st = st.substr(st.find("ONLINESTATUS") + 13);
|
||||
GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS");
|
||||
pbnetwork::StatusType status = getStatus(st);
|
||||
|
||||
std::string mood_text = message.substr(message.find("MOOD_TEXT") + 10);
|
||||
std::string mood_text = GET_RESPONSE_DATA(message, "MOOD_TEXT");
|
||||
|
||||
std::vector<std::string> groups;
|
||||
np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text);
|
||||
}
|
||||
else if (cmd[2] == "BUDDYSTATUS" && cmd[3] == "3") {
|
||||
std::string st = sk->send_command("GET USER " + cmd[1] + " ONLINESTATUS");
|
||||
st = st.substr(st.find("ONLINESTATUS") + 13);
|
||||
GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT");
|
||||
GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS");
|
||||
pbnetwork::StatusType status = getStatus(st);
|
||||
|
||||
std::string mood_text = message.substr(message.find("MOOD_TEXT") + 10);
|
||||
|
||||
std::vector<std::string> groups;
|
||||
np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text);
|
||||
}
|
||||
else if (cmd[2] == "FULLNAME") {
|
||||
GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME");
|
||||
GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT");
|
||||
GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS");
|
||||
pbnetwork::StatusType status = getStatus(st);
|
||||
|
||||
std::vector<std::string> groups;
|
||||
np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text);
|
||||
}
|
||||
}
|
||||
else if (cmd[0] == "CHATMESSAGE") {
|
||||
if (cmd[3] == "RECEIVED") {
|
||||
std::string body = sk->send_command("GET CHATMESSAGE " + cmd[1] + " BODY");
|
||||
body = body.substr(body.find("BODY") + 5);
|
||||
GET_PROPERTY(body, "CHATMESSAGE", cmd[1], "BODY");
|
||||
GET_PROPERTY(from_handle, "CHATMESSAGE", cmd[1], "FROM_HANDLE");
|
||||
|
||||
std::string chatname = sk->send_command("GET CHATMESSAGE " + cmd[1] + " CHATNAME");
|
||||
size_t start = chatname.find("$") + 1;
|
||||
size_t len = chatname.find(";") - start;
|
||||
std::string from = chatname.substr(start, len);
|
||||
|
||||
std::string from_handle = sk->send_command("GET CHATMESSAGE " + cmd[1] + " FROM_HANDLE");
|
||||
from_handle = from_handle.substr(from_handle.find("FROM_HANDLE") + 12);
|
||||
|
||||
// if (from_handle != sk->getUsername()) {
|
||||
from = from_handle;
|
||||
// }
|
||||
if (from_handle == sk->getUsername())
|
||||
return;
|
||||
|
||||
np->handleMessage(sk->getUser(), from, body);
|
||||
np->handleMessage(sk->getUser(), from_handle, body);
|
||||
|
||||
sk->send_command("SET CHATMESSAGE " + cmd[1] + " SEEN");
|
||||
}
|
||||
}
|
||||
else if (cmd[0] == "CALL") {
|
||||
// CALL 884 STATUS RINGING
|
||||
if (cmd[2] == "STATUS") {
|
||||
if (cmd[3] == "RINGING" || cmd[3] == "MISSED") {
|
||||
// handle only incoming calls
|
||||
GET_PROPERTY(type, "CALL", cmd[1], "TYPE");
|
||||
if (type.find("INCOMING") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
GET_PROPERTY(from, "CALL", cmd[1], "PARTNER_HANDLE");
|
||||
GET_PROPERTY(dispname, "CALL", cmd[1], "PARTNER_DISPNAME");
|
||||
|
||||
if (cmd[3] == "RINGING") {
|
||||
np->handleMessage(sk->getUser(), from, "User " + dispname + " is calling you.");
|
||||
}
|
||||
else {
|
||||
np->handleMessage(sk->getUser(), from, "You have missed call from user " + dispname + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -707,6 +802,7 @@ static int create_socket(char *host, int portno) {
|
|||
if ((hos = gethostbyname(host)) == NULL) {
|
||||
// strerror() will not work for gethostbyname() and hstrerror()
|
||||
// is supposedly obsolete
|
||||
Logging::shutdownLogging();
|
||||
exit(1);
|
||||
}
|
||||
serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
|
||||
|
@ -729,6 +825,7 @@ static gboolean transportDataReceived(GIOChannel *source, GIOCondition condition
|
|||
ssize_t n = read(m_sock, ptr, sizeof(buffer));
|
||||
if (n <= 0) {
|
||||
LOG4CXX_INFO(logger, "Diconnecting from spectrum2 server");
|
||||
Logging::shutdownLogging();
|
||||
exit(errno);
|
||||
}
|
||||
std::string d = std::string(buffer, n);
|
||||
|
@ -737,6 +834,7 @@ static gboolean transportDataReceived(GIOChannel *source, GIOCondition condition
|
|||
}
|
||||
|
||||
static void io_destroy(gpointer data) {
|
||||
Logging::shutdownLogging();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -812,18 +910,7 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (CONFIG_STRING(&config, "logging.backend_config").empty()) {
|
||||
LoggerPtr root = log4cxx::Logger::getRootLogger();
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
|
||||
}
|
||||
else {
|
||||
log4cxx::helpers::Properties p;
|
||||
log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config"));
|
||||
|
||||
p.load(istream);
|
||||
p.setProperty("pid", boost::lexical_cast<std::string>(getpid()));
|
||||
log4cxx::PropertyConfigurator::configure(p);
|
||||
}
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
// initPurple(config);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/mysqlbackend.h"
|
||||
|
@ -25,13 +26,6 @@
|
|||
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include "log4cxx/helpers/transcoder.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
@ -40,9 +34,7 @@ using namespace boost::filesystem;
|
|||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
static LoggerPtr logger = log4cxx::Logger::getLogger("SMSNetworkPlugin");
|
||||
DEFINE_LOGGER(logger, "SMSNetworkPlugin");
|
||||
|
||||
#define INTERNAL_USER "/sms@backend@internal@user"
|
||||
|
||||
|
@ -312,80 +304,19 @@ int main (int argc, char* argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (CONFIG_STRING(&config, "logging.backend_config").empty()) {
|
||||
LoggerPtr root = log4cxx::Logger::getRootLogger();
|
||||
#ifndef _MSC_VER
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
|
||||
#else
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n")));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
log4cxx::helpers::Properties p;
|
||||
log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config"));
|
||||
p.load(istream);
|
||||
LogString pid, jid;
|
||||
log4cxx::helpers::Transcoder::decode(boost::lexical_cast<std::string>(getpid()), pid);
|
||||
log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid);
|
||||
#ifdef _MSC_VER
|
||||
p.setProperty(L"pid", pid);
|
||||
p.setProperty(L"jid", jid);
|
||||
#else
|
||||
p.setProperty("pid", pid);
|
||||
p.setProperty("jid", jid);
|
||||
#endif
|
||||
log4cxx::PropertyConfigurator::configure(p);
|
||||
}
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
#ifdef WITH_SQLITE
|
||||
if (CONFIG_STRING(&config, "database.type") == "sqlite3") {
|
||||
storageBackend = new SQLite3Backend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
std::string error;
|
||||
StorageBackend *storageBackend = StorageBackend::createBackend(&config, error);
|
||||
if (storageBackend == NULL) {
|
||||
if (!error.empty()) {
|
||||
std::cerr << error << "\n";
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "sqlite3") {
|
||||
std::cerr << "Spectrum2 is not compiled with mysql backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MYSQL
|
||||
if (CONFIG_STRING(&config, "database.type") == "mysql") {
|
||||
storageBackend = new MySQLBackend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "mysql") {
|
||||
std::cerr << "Spectrum2 is not compiled with mysql backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PQXX
|
||||
if (CONFIG_STRING(&config, "database.type") == "pqxx") {
|
||||
storageBackend = new PQXXBackend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "pqxx") {
|
||||
std::cerr << "Spectrum2 is not compiled with pqxx backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3"
|
||||
&& CONFIG_STRING(&config, "database.type") != "pqxx" && CONFIG_STRING(&config, "database.type") != "none") {
|
||||
std::cerr << "Unknown storage backend " << CONFIG_STRING(&config, "database.type") << "\n";
|
||||
return -2;
|
||||
else if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
|
|
10
backends/template/CMakeLists.txt
Normal file
10
backends/template/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_template_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
#INSTALL(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin)
|
||||
|
1
backends/template/README
Normal file
1
backends/template/README
Normal file
|
@ -0,0 +1 @@
|
|||
This is just template for creating new generic spectrum2 backends. It does not do anything!
|
153
backends/template/main.cpp
Normal file
153
backends/template/main.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
DEFINE_LOGGER(logger, "Backend Template");
|
||||
|
||||
// eventloop
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
// Plugin
|
||||
class TemplatePlugin;
|
||||
TemplatePlugin * np = NULL;
|
||||
|
||||
class TemplatePlugin : public NetworkPlugin {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
|
||||
TemplatePlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
|
||||
this->config = config;
|
||||
m_factories = new Swift::BoostNetworkFactories(loop);
|
||||
m_conn = m_factories->getConnectionFactory()->createConnection();
|
||||
m_conn->onDataRead.connect(boost::bind(&TemplatePlugin::_handleDataRead, this, _1));
|
||||
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting the plugin.");
|
||||
}
|
||||
|
||||
// NetworkPlugin uses this method to send the data to networkplugin server
|
||||
void sendData(const std::string &string) {
|
||||
m_conn->write(Swift::createSafeByteArray(string));
|
||||
}
|
||||
|
||||
// This method has to call handleDataRead with all received data from network plugin server
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
handleDataRead(d);
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
handleConnected(user);
|
||||
LOG4CXX_INFO(logger, user << ": Added buddy - Echo.");
|
||||
handleBuddyChanged(user, "echo", "Echo", std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
|
||||
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 = "") {
|
||||
LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ".");
|
||||
if (legacyName == "echo") {
|
||||
handleMessage(user, legacyName, message);
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << ".");
|
||||
handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
Config *config;
|
||||
};
|
||||
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
std::cout << "SIGCHLD handler can't be set\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
|
||||
desc.add_options()
|
||||
("host,h", value<std::string>(&host), "host")
|
||||
("port,p", value<int>(&port), "port")
|
||||
;
|
||||
try
|
||||
{
|
||||
boost::program_options::variables_map vm;
|
||||
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
|
||||
boost::program_options::notify(vm);
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (argc < 5) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Config config;
|
||||
if (!config.load(argv[5])) {
|
||||
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
loop_ = &eventLoop;
|
||||
np = new TemplatePlugin(&config, &eventLoop, host, port);
|
||||
loop_->run();
|
||||
|
||||
return 0;
|
||||
}
|
103
backends/template/template_backend.py
Executable file
103
backends/template/template_backend.py
Executable file
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import asyncore, argparse, protocol_pb2, socket, logging
|
||||
from NetworkPlugin import NetworkPlugin
|
||||
|
||||
np = None
|
||||
|
||||
|
||||
logger = logging.getLogger('Template Backend')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
ch.setFormatter(formatter)
|
||||
logger.addHandler(ch)
|
||||
|
||||
|
||||
def handleTransportData(data):
|
||||
"""
|
||||
This function is called when data is received from the NetworkPlugin server
|
||||
"""
|
||||
np.handleDataRead(data)
|
||||
|
||||
|
||||
class SpectrumPlugin(NetworkPlugin):
|
||||
global logger
|
||||
def __init__(self, iochannel):
|
||||
NetworkPlugin.__init__(self)
|
||||
self.iochannel = iochannel
|
||||
logger.info("Starting plugin.")
|
||||
|
||||
def sendData(self, string):
|
||||
"""
|
||||
NetworkPlugin uses this method to send the data to networkplugin server
|
||||
"""
|
||||
self.iochannel.sendData(string)
|
||||
logger.info("Starting plugin.")
|
||||
|
||||
def handleLoginRequest(self, user, legacyName, password):
|
||||
self.handleConnected(user)
|
||||
logger.info("Added Echo Buddy")
|
||||
self.handleBuddyChanged(user, "echo", "Echo", [], protocol_pb2.STATUS_ONLINE)
|
||||
|
||||
def handleLogoutRequest(self, user, legacyName):
|
||||
pass
|
||||
|
||||
def handleMessageSendRequest(self, user, legacyName, message, xhtml = ""):
|
||||
logger.info("Message sent from " + user + ' to ' + legacyName)
|
||||
if(legacyName == "echo"):
|
||||
logger.info("Message Echoed: " + message)
|
||||
self.handleMessage(user, legacyName, message)
|
||||
|
||||
def handleBuddyUpdatedRequest(self, user, buddyName, alias, groups):
|
||||
logger.info("Added Buddy " + buddyName)
|
||||
self.handleBuddyChanged(user, buddyName, alias, groups, protocol_pb2.STATUS_ONLINE)
|
||||
|
||||
def handleBuddyRemovedRequest(self, user, buddyName, groups):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class IOChannel(asyncore.dispatcher):
|
||||
def __init__(self, host, port, readCallBack):
|
||||
asyncore.dispatcher.__init__(self)
|
||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.connect((host, port))
|
||||
self.handleReceivedData = readCallBack
|
||||
self.send_buffer = ""
|
||||
|
||||
def sendData(self, data):
|
||||
self.send_buffer += data
|
||||
|
||||
def handle_connect(self):
|
||||
pass
|
||||
|
||||
def handle_close(self):
|
||||
self.close()
|
||||
|
||||
def handle_read(self):
|
||||
data = self.recv(65536)
|
||||
self.handleReceivedData(data)
|
||||
|
||||
def handle_write(self):
|
||||
sent = self.send(self.send_buffer)
|
||||
self.send_buffer = self.send_buffer[sent:]
|
||||
|
||||
def writable(self):
|
||||
return (len(self.send_buffer) > 0)
|
||||
|
||||
def readable(self):
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--host', type=str, required=True)
|
||||
parser.add_argument('--port', type=int, required=True)
|
||||
parser.add_argument('config_file', type=str)
|
||||
|
||||
args = parser.parse_args()
|
||||
io = IOChannel(args.host, args.port, handleTransportData)
|
||||
np = SpectrumPlugin(io)
|
||||
asyncore.loop()
|
|
@ -1,5 +1,8 @@
|
|||
FIND_LIBRARY(IRC_LIBRARY NAMES Communi)
|
||||
FIND_PATH(IRC_INCLUDE_DIR NAMES "ircglobal.h" PATH_SUFFIXES Communi qt4/Communi )
|
||||
find_package(Qt4 REQUIRED)
|
||||
include( ${QT_USE_FILE} )
|
||||
|
||||
FIND_LIBRARY(IRC_LIBRARY NAMES Communi PATHS ${QT_LIBRARY_DIR})
|
||||
FIND_PATH(IRC_INCLUDE_DIR NAMES "ircglobal.h" PATHS ${QT_INCLUDE_DIR} PATH_SUFFIXES Communi)
|
||||
|
||||
# message( STATUS ${IRC_LIBRARY})
|
||||
if( IRC_LIBRARY AND IRC_INCLUDE_DIR )
|
||||
|
|
1510
docs/Doxyfile
1510
docs/Doxyfile
File diff suppressed because it is too large
Load diff
16
include/Swiften/Elements/GatewayPayload.cpp
Normal file
16
include/Swiften/Elements/GatewayPayload.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/GatewayPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
GatewayPayload::GatewayPayload(const JID &jid, const std::string &desc, const std::string &prompt) :
|
||||
jid(jid), desc(desc), prompt(prompt) {
|
||||
|
||||
}
|
||||
|
||||
}
|
49
include/Swiften/Elements/GatewayPayload.h
Normal file
49
include/Swiften/Elements/GatewayPayload.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
namespace Swift {
|
||||
class GatewayPayload : public Payload {
|
||||
public:
|
||||
GatewayPayload(const JID &jid = JID(), const std::string &desc = "", const std::string &prompt = "");
|
||||
|
||||
void setJID(const JID &jid) {
|
||||
this->jid = jid;
|
||||
}
|
||||
|
||||
const JID &getJID() const {
|
||||
return jid;
|
||||
}
|
||||
|
||||
void setDesc(const std::string &desc) {
|
||||
this->desc = desc;
|
||||
}
|
||||
|
||||
const std::string &getDesc() const {
|
||||
return desc;
|
||||
}
|
||||
|
||||
void setPrompt(const std::string &prompt) {
|
||||
this->prompt = prompt;
|
||||
}
|
||||
|
||||
const std::string &getPrompt() const {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
private:
|
||||
JID jid;
|
||||
std::string desc;
|
||||
std::string prompt;
|
||||
};
|
||||
}
|
14
include/Swiften/Elements/PubSubItem.cpp
Normal file
14
include/Swiften/Elements/PubSubItem.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/PubSubItem.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubItem::PubSubItem() {
|
||||
}
|
||||
|
||||
}
|
64
include/Swiften/Elements/PubSubItem.h
Normal file
64
include/Swiften/Elements/PubSubItem.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubItem : public Payload {
|
||||
public:
|
||||
PubSubItem();
|
||||
|
||||
void addPayload(boost::shared_ptr<Payload> payload) {
|
||||
payloads.push_back(payload);
|
||||
}
|
||||
|
||||
const std::vector<boost::shared_ptr<Payload> > getPayloads() const {
|
||||
return payloads;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const std::vector<boost::shared_ptr<T> > getPayloads() const {
|
||||
std::vector<boost::shared_ptr<T> > matched_payloads;
|
||||
for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) {
|
||||
boost::shared_ptr<T> result = boost::dynamic_pointer_cast<T>(*i);
|
||||
if (result) {
|
||||
matched_payloads.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
return matched_payloads;
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const boost::shared_ptr<T> getPayload() const {
|
||||
boost::shared_ptr<T> result;
|
||||
for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) {
|
||||
result = boost::dynamic_pointer_cast<T>(*i);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::string& getId() const { return id; }
|
||||
|
||||
void setId(const std::string& id) {
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<boost::shared_ptr<Payload> > payloads;
|
||||
std::string id;
|
||||
};
|
||||
}
|
14
include/Swiften/Elements/PubSubPayload.cpp
Normal file
14
include/Swiften/Elements/PubSubPayload.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/PubSubPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubPayload::PubSubPayload() {
|
||||
}
|
||||
|
||||
}
|
57
include/Swiften/Elements/PubSubPayload.h
Normal file
57
include/Swiften/Elements/PubSubPayload.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubPayload : public Payload {
|
||||
public:
|
||||
PubSubPayload();
|
||||
|
||||
void addPayload(boost::shared_ptr<Payload> payload) {
|
||||
payloads.push_back(payload);
|
||||
}
|
||||
|
||||
const std::vector<boost::shared_ptr<Payload> > getPayloads() const {
|
||||
return payloads;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const std::vector<boost::shared_ptr<T> > getPayloads() const {
|
||||
std::vector<boost::shared_ptr<T> > matched_payloads;
|
||||
for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) {
|
||||
boost::shared_ptr<T> result = boost::dynamic_pointer_cast<T>(*i);
|
||||
if (result) {
|
||||
matched_payloads.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
return matched_payloads;
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const boost::shared_ptr<T> getPayload() const {
|
||||
boost::shared_ptr<T> result;
|
||||
for (std::vector<boost::shared_ptr<Payload> >::const_iterator i = payloads.begin(); i != payloads.end(); ++i) {
|
||||
result = boost::dynamic_pointer_cast<T>(*i);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<boost::shared_ptr<Payload> > payloads;
|
||||
};
|
||||
}
|
16
include/Swiften/Elements/PubSubPublishPayload.cpp
Normal file
16
include/Swiften/Elements/PubSubPublishPayload.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/PubSubPublishPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubPublishPayload::PubSubPublishPayload(const std::string &node) :
|
||||
node(node) {
|
||||
|
||||
}
|
||||
|
||||
}
|
43
include/Swiften/Elements/PubSubPublishPayload.h
Normal file
43
include/Swiften/Elements/PubSubPublishPayload.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
#include <Swiften/Elements/PubSubItem.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubPublishPayload : public Payload {
|
||||
public:
|
||||
enum Type { None, Pending, Subscribed, Unconfigured };
|
||||
|
||||
PubSubPublishPayload(const std::string &node = "");
|
||||
|
||||
void setNode(const std::string &node) {
|
||||
this->node = node;
|
||||
}
|
||||
|
||||
const std::string &getNode() const {
|
||||
return node;
|
||||
}
|
||||
|
||||
void addItem(const boost::shared_ptr<Payload> &item) {
|
||||
items.push_back(item);
|
||||
}
|
||||
|
||||
const std::vector<boost::shared_ptr<Payload> > &getItems() const {
|
||||
return items;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string node;
|
||||
std::vector<boost::shared_ptr<Payload> > items;
|
||||
};
|
||||
}
|
16
include/Swiften/Elements/PubSubSubscribePayload.cpp
Normal file
16
include/Swiften/Elements/PubSubSubscribePayload.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/PubSubSubscribePayload.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubSubscribePayload::PubSubSubscribePayload(const JID &jid, const std::string &node) :
|
||||
jid(jid), node(node) {
|
||||
|
||||
}
|
||||
|
||||
}
|
40
include/Swiften/Elements/PubSubSubscribePayload.h
Normal file
40
include/Swiften/Elements/PubSubSubscribePayload.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubSubscribePayload : public Payload {
|
||||
public:
|
||||
PubSubSubscribePayload(const JID &jid = JID(), const std::string &node = "");
|
||||
|
||||
void setJID(const JID &jid) {
|
||||
this->jid = jid;
|
||||
}
|
||||
|
||||
const JID &getJID() const {
|
||||
return jid;
|
||||
}
|
||||
|
||||
void setNode(const std::string &node) {
|
||||
this->node = node;
|
||||
}
|
||||
|
||||
const std::string &getNode() const {
|
||||
return node;
|
||||
}
|
||||
|
||||
private:
|
||||
JID jid;
|
||||
std::string node;
|
||||
};
|
||||
}
|
16
include/Swiften/Elements/PubSubSubscriptionPayload.cpp
Normal file
16
include/Swiften/Elements/PubSubSubscriptionPayload.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Elements/PubSubSubscriptionPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubSubscriptionPayload::PubSubSubscriptionPayload(const JID &jid, const std::string &node) :
|
||||
jid(jid), node(node), type(None) {
|
||||
|
||||
}
|
||||
|
||||
}
|
60
include/Swiften/Elements/PubSubSubscriptionPayload.h
Normal file
60
include/Swiften/Elements/PubSubSubscriptionPayload.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Payload.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubSubscriptionPayload : public Payload {
|
||||
public:
|
||||
enum Type { None, Pending, Subscribed, Unconfigured };
|
||||
|
||||
PubSubSubscriptionPayload(const JID &jid = JID(), const std::string &node = "");
|
||||
|
||||
void setJID(const JID &jid) {
|
||||
this->jid = jid;
|
||||
}
|
||||
|
||||
const JID &getJID() const {
|
||||
return jid;
|
||||
}
|
||||
|
||||
void setNode(const std::string &node) {
|
||||
this->node = node;
|
||||
}
|
||||
|
||||
const std::string &getNode() const {
|
||||
return node;
|
||||
}
|
||||
|
||||
void setId(const std::string &id) {
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
const std::string &getId() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setType(const Type &type) {
|
||||
this->type = type;
|
||||
}
|
||||
|
||||
const Type &getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
JID jid;
|
||||
std::string node;
|
||||
std::string id;
|
||||
Type type;
|
||||
};
|
||||
}
|
|
@ -18,6 +18,7 @@ DummyNetworkFactories::DummyNetworkFactories(EventLoop* eventLoop) {
|
|||
domainNameResolver = new PlatformDomainNameResolver(eventLoop);
|
||||
connectionServerFactory = new DummyConnectionServerFactory(eventLoop);
|
||||
m_platformXMLParserFactory = new PlatformXMLParserFactory();
|
||||
this->eventLoop = eventLoop;
|
||||
}
|
||||
|
||||
DummyNetworkFactories::~DummyNetworkFactories() {
|
||||
|
|
|
@ -41,6 +41,10 @@ namespace Swift {
|
|||
return m_platformXMLParserFactory;
|
||||
}
|
||||
|
||||
EventLoop *getEventLoop() const {
|
||||
return eventLoop;
|
||||
}
|
||||
|
||||
Swift::TLSContextFactory* getTLSContextFactory() const {
|
||||
return 0;
|
||||
}
|
||||
|
@ -55,5 +59,6 @@ namespace Swift {
|
|||
ConnectionFactory* connectionFactory;
|
||||
DomainNameResolver* domainNameResolver;
|
||||
ConnectionServerFactory* connectionServerFactory;
|
||||
EventLoop *eventLoop;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/GatewayPayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void GatewayPayloadParser::handleTree(ParserElement::ref root) {
|
||||
foreach (ParserElement::ref child, root->getAllChildren()) {
|
||||
if (child->getName() == "desc") {
|
||||
getPayloadInternal()->setDesc(child->getText());
|
||||
}
|
||||
else if (child->getName() == "prompt") {
|
||||
getPayloadInternal()->setPrompt(child->getText());
|
||||
}
|
||||
else if (child->getName() == "jid") {
|
||||
getPayloadInternal()->setJID(child->getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
21
include/Swiften/Parser/PayloadParsers/GatewayPayloadParser.h
Normal file
21
include/Swiften/Parser/PayloadParsers/GatewayPayloadParser.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/GatewayPayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class GatewayPayloadParser : public GenericPayloadTreeParser<GatewayPayload> {
|
||||
public:
|
||||
GatewayPayloadParser() {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
};
|
||||
}
|
27
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.cpp
Normal file
27
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Kevin Smith
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/MUCPayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void MUCPayloadParser::handleTree(ParserElement::ref root) {
|
||||
foreach (ParserElement::ref child, root->getAllChildren()) {
|
||||
if (child->getName() == "password" && child->getNamespace() == root->getNamespace()) {
|
||||
getPayloadInternal()->setPassword(child->getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
22
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.h
Normal file
22
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Kevin Smith
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/MUCPayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class MUCPayloadParser : public GenericPayloadTreeParser<MUCPayload> {
|
||||
public:
|
||||
MUCPayloadParser(){}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
};
|
||||
}
|
30
include/Swiften/Parser/PayloadParsers/PubSubItemParser.cpp
Normal file
30
include/Swiften/Parser/PayloadParsers/PubSubItemParser.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/PubSubItemParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void PubSubItemParser::handleTree(ParserElement::ref root) {
|
||||
std::string id = root->getAttributes().getAttribute("id");
|
||||
if (!id.empty()) {
|
||||
getPayloadInternal()->setId(id);
|
||||
}
|
||||
|
||||
foreach (ParserElement::ref child, root->getAllChildren()) {
|
||||
getPayloadInternal()->addPayload(TreeReparser::parseTree(child, factories));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
24
include/Swiften/Parser/PayloadParsers/PubSubItemParser.h
Normal file
24
include/Swiften/Parser/PayloadParsers/PubSubItemParser.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/PubSubItem.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class PubSubItemParser : public GenericPayloadTreeParser<PubSubItem> {
|
||||
public:
|
||||
PubSubItemParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
private:
|
||||
PayloadParserFactoryCollection* factories;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/PubSubPayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void PubSubPayloadParser::handleTree(ParserElement::ref root) {
|
||||
foreach (ParserElement::ref child, root->getAllChildren()) {
|
||||
getPayloadInternal()->addPayload(TreeReparser::parseTree(child, factories));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
24
include/Swiften/Parser/PayloadParsers/PubSubPayloadParser.h
Normal file
24
include/Swiften/Parser/PayloadParsers/PubSubPayloadParser.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/PubSubPayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class PubSubPayloadParser : public GenericPayloadTreeParser<PubSubPayload> {
|
||||
public:
|
||||
PubSubPayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
private:
|
||||
PayloadParserFactoryCollection* factories;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/PubSubPublishPayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void PubSubPublishPayloadParser::handleTree(ParserElement::ref root) {
|
||||
std::string node = root->getAttributes().getAttribute("node");
|
||||
if (!node.empty()) {
|
||||
getPayloadInternal()->setNode(node);
|
||||
}
|
||||
|
||||
foreach (ParserElement::ref child, root->getAllChildren()) {
|
||||
getPayloadInternal()->addItem(TreeReparser::parseTree(child, factories));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/PubSubPublishPayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class PubSubPublishPayloadParser : public GenericPayloadTreeParser<PubSubPublishPayload> {
|
||||
public:
|
||||
PubSubPublishPayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
private:
|
||||
PayloadParserFactoryCollection* factories;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/PubSubSubscribePayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void PubSubSubscribePayloadParser::handleTree(ParserElement::ref root) {
|
||||
std::string node = root->getAttributes().getAttribute("node");
|
||||
if (!node.empty()) {
|
||||
getPayloadInternal()->setNode(node);
|
||||
}
|
||||
|
||||
std::string jid = root->getAttributes().getAttribute("jid");
|
||||
if (!jid.empty()) {
|
||||
getPayloadInternal()->setJID(jid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/PubSubSubscribePayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class PubSubSubscribePayloadParser : public GenericPayloadTreeParser<PubSubSubscribePayload> {
|
||||
public:
|
||||
PubSubSubscribePayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
private:
|
||||
PayloadParserFactoryCollection* factories;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/PayloadParsers/PubSubSubscriptionPayloadParser.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <Swiften/Parser/PayloadParserFactoryCollection.h>
|
||||
#include <Swiften/Parser/PayloadParserFactory.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Elements/MUCOccupant.h>
|
||||
#include <Swiften/Parser/Tree/TreeReparser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
void PubSubSubscriptionPayloadParser::handleTree(ParserElement::ref root) {
|
||||
std::string node = root->getAttributes().getAttribute("node");
|
||||
if (!node.empty()) {
|
||||
getPayloadInternal()->setNode(node);
|
||||
}
|
||||
|
||||
std::string jid = root->getAttributes().getAttribute("jid");
|
||||
if (!jid.empty()) {
|
||||
getPayloadInternal()->setJID(jid);
|
||||
}
|
||||
|
||||
std::string id = root->getAttributes().getAttribute("subid");
|
||||
if (!id.empty()) {
|
||||
getPayloadInternal()->setId(id);
|
||||
}
|
||||
|
||||
std::string type = root->getAttributes().getAttribute("subscription");
|
||||
if (type == "none") {
|
||||
getPayloadInternal()->setType(PubSubSubscriptionPayload::None);
|
||||
}
|
||||
else if (type == "subscribed") {
|
||||
getPayloadInternal()->setType(PubSubSubscriptionPayload::Subscribed);
|
||||
}
|
||||
else if (type == "pending") {
|
||||
getPayloadInternal()->setType(PubSubSubscriptionPayload::Pending);
|
||||
}
|
||||
else if (type == "unconfigured") {
|
||||
getPayloadInternal()->setType(PubSubSubscriptionPayload::Unconfigured);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/Elements/PubSubSubscriptionPayload.h>
|
||||
#include <Swiften/Parser/GenericPayloadTreeParser.h>
|
||||
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadParserFactoryCollection;
|
||||
class PubSubSubscriptionPayloadParser : public GenericPayloadTreeParser<PubSubSubscriptionPayload> {
|
||||
public:
|
||||
PubSubSubscriptionPayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
|
||||
virtual void handleTree(ParserElement::ref root);
|
||||
private:
|
||||
PayloadParserFactoryCollection* factories;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
GatewayPayloadSerializer::GatewayPayloadSerializer()
|
||||
: GenericPayloadSerializer<GatewayPayload>() {
|
||||
}
|
||||
|
||||
std::string GatewayPayloadSerializer::serializePayload(boost::shared_ptr<GatewayPayload> payload) const {
|
||||
XMLElement query("query", "jabber:iq:gateway");
|
||||
|
||||
if (payload->getJID().isValid()) {
|
||||
boost::shared_ptr<XMLElement> jid(new XMLElement("jid", "", payload->getJID().toBare().toString()));
|
||||
query.addNode(jid);
|
||||
}
|
||||
|
||||
if (!payload->getDesc().empty()) {
|
||||
boost::shared_ptr<XMLElement> desc(new XMLElement("desc", "", payload->getDesc()));
|
||||
query.addNode(desc);
|
||||
}
|
||||
|
||||
if (!payload->getPrompt().empty()) {
|
||||
boost::shared_ptr<XMLElement> prompt(new XMLElement("prompt", "", payload->getPrompt()));
|
||||
query.addNode(prompt);
|
||||
}
|
||||
|
||||
return query.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/GatewayPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
class GatewayPayloadSerializer : public GenericPayloadSerializer<GatewayPayload> {
|
||||
public:
|
||||
GatewayPayloadSerializer();
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<GatewayPayload> item) const;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/PubSubItemSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubItemSerializer::PubSubItemSerializer(PayloadSerializerCollection *serializers) :
|
||||
GenericPayloadSerializer<PubSubItem>(), serializers(serializers) {
|
||||
}
|
||||
|
||||
std::string PubSubItemSerializer::serializePayload(boost::shared_ptr<PubSubItem> payload) const {
|
||||
XMLElement item("item");
|
||||
if (!payload->getId().empty()) {
|
||||
item.setAttribute("id", payload->getId());
|
||||
}
|
||||
|
||||
if (!payload->getPayloads().empty()) {
|
||||
foreach(boost::shared_ptr<Payload> subPayload, payload->getPayloads()) {
|
||||
PayloadSerializer* serializer = serializers->getPayloadSerializer(subPayload);
|
||||
if (serializer) {
|
||||
item.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(subPayload))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/PubSubItem.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadSerializerCollection;
|
||||
class PubSubItemSerializer : public GenericPayloadSerializer<PubSubItem> {
|
||||
public:
|
||||
PubSubItemSerializer(PayloadSerializerCollection *serializers);
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<PubSubItem> item) const;
|
||||
private:
|
||||
PayloadSerializerCollection *serializers;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/PubSubPayloadSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubPayloadSerializer::PubSubPayloadSerializer(PayloadSerializerCollection *serializers)
|
||||
: GenericPayloadSerializer<PubSubPayload>(),
|
||||
serializers(serializers) {
|
||||
}
|
||||
|
||||
std::string PubSubPayloadSerializer::serializePayload(boost::shared_ptr<PubSubPayload> payload) const {
|
||||
XMLElement pubsub("pubsub", "http://jabber.org/protocol/pubsub");
|
||||
|
||||
if (!payload->getPayloads().empty()) {
|
||||
foreach(boost::shared_ptr<Payload> subPayload, payload->getPayloads()) {
|
||||
PayloadSerializer* serializer = serializers->getPayloadSerializer(subPayload);
|
||||
if (serializer) {
|
||||
pubsub.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(subPayload))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pubsub.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/PubSubPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadSerializerCollection;
|
||||
|
||||
class PubSubPayloadSerializer : public GenericPayloadSerializer<PubSubPayload> {
|
||||
public:
|
||||
PubSubPayloadSerializer(PayloadSerializerCollection *serializers);
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<PubSubPayload> item) const;
|
||||
private:
|
||||
PayloadSerializerCollection *serializers;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/PubSubPublishPayloadSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubPublishPayloadSerializer::PubSubPublishPayloadSerializer(PayloadSerializerCollection *serializers)
|
||||
: GenericPayloadSerializer<PubSubPublishPayload>(),
|
||||
serializers(serializers) {
|
||||
}
|
||||
|
||||
std::string PubSubPublishPayloadSerializer::serializePayload(boost::shared_ptr<PubSubPublishPayload> payload) const {
|
||||
XMLElement publish("publish");
|
||||
|
||||
if (!payload->getNode().empty()) {
|
||||
publish.setAttribute("node", payload->getNode());
|
||||
}
|
||||
|
||||
if (!payload->getItems().empty()) {
|
||||
foreach(boost::shared_ptr<Payload> subPayload, payload->getItems()) {
|
||||
PayloadSerializer* serializer = serializers->getPayloadSerializer(subPayload);
|
||||
if (serializer) {
|
||||
publish.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(subPayload))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return publish.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/PubSubPublishPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PayloadSerializerCollection;
|
||||
|
||||
class PubSubPublishPayloadSerializer : public GenericPayloadSerializer<PubSubPublishPayload> {
|
||||
public:
|
||||
PubSubPublishPayloadSerializer(PayloadSerializerCollection *serializers);
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<PubSubPublishPayload> item) const;
|
||||
private:
|
||||
PayloadSerializerCollection *serializers;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/PubSubSubscribePayloadSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubSubscribePayloadSerializer::PubSubSubscribePayloadSerializer()
|
||||
: GenericPayloadSerializer<PubSubSubscribePayload>() {
|
||||
}
|
||||
|
||||
std::string PubSubSubscribePayloadSerializer::serializePayload(boost::shared_ptr<PubSubSubscribePayload> payload) const {
|
||||
XMLElement subscribe("subscribe");
|
||||
|
||||
if (!payload->getJID().isValid()) {
|
||||
subscribe.setAttribute("jid", payload->getJID().toBare().toString());
|
||||
}
|
||||
|
||||
if (!payload->getNode().empty()) {
|
||||
subscribe.setAttribute("node", payload->getNode());
|
||||
}
|
||||
|
||||
return subscribe.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/PubSubSubscribePayload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubSubscribePayloadSerializer : public GenericPayloadSerializer<PubSubSubscribePayload> {
|
||||
public:
|
||||
PubSubSubscribePayloadSerializer();
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<PubSubSubscribePayload> item) const;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Serializer/PayloadSerializers/PubSubSubscriptionPayloadSerializer.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLTextNode.h>
|
||||
#include <Swiften/Serializer/XML/XMLElement.h>
|
||||
#include <Swiften/Serializer/PayloadSerializerCollection.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
PubSubSubscriptionPayloadSerializer::PubSubSubscriptionPayloadSerializer()
|
||||
: GenericPayloadSerializer<PubSubSubscriptionPayload>() {
|
||||
}
|
||||
|
||||
std::string PubSubSubscriptionPayloadSerializer::serializePayload(boost::shared_ptr<PubSubSubscriptionPayload> payload) const {
|
||||
XMLElement subscription("subscription");
|
||||
|
||||
if (!payload->getJID().isValid()) {
|
||||
subscription.setAttribute("jid", payload->getJID().toBare().toString());
|
||||
}
|
||||
|
||||
if (!payload->getNode().empty()) {
|
||||
subscription.setAttribute("node", payload->getNode());
|
||||
}
|
||||
|
||||
switch (payload->getType()) {
|
||||
case PubSubSubscriptionPayload::None:
|
||||
subscription.setAttribute("subscription", "none");
|
||||
break;
|
||||
case PubSubSubscriptionPayload::Subscribed:
|
||||
subscription.setAttribute("subscription", "subscribed");
|
||||
break;
|
||||
case PubSubSubscriptionPayload::Unconfigured:
|
||||
subscription.setAttribute("subscription", "unconfigured");
|
||||
break;
|
||||
case PubSubSubscriptionPayload::Pending:
|
||||
subscription.setAttribute("subscription", "pending");
|
||||
break;
|
||||
}
|
||||
|
||||
return subscription.serialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Serializer/GenericPayloadSerializer.h>
|
||||
#include <Swiften/Elements/PubSubSubscriptionPayload.h>
|
||||
|
||||
namespace Swift {
|
||||
class PubSubSubscriptionPayloadSerializer : public GenericPayloadSerializer<PubSubSubscriptionPayload> {
|
||||
public:
|
||||
PubSubSubscriptionPayloadSerializer();
|
||||
|
||||
virtual std::string serializePayload(boost::shared_ptr<PubSubSubscriptionPayload> item) const;
|
||||
};
|
||||
}
|
|
@ -14,12 +14,8 @@
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
using namespace log4cxx;
|
||||
static LoggerPtr logger = Logger::getLogger("OpenSSLServerContext");
|
||||
#include "transport/logging.h"
|
||||
DEFINE_LOGGER(logger, "OpenSSLServerContext");
|
||||
|
||||
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
if (PROTOBUF_FOUND)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/protocol.pb.cc ${CMAKE_CURRENT_BINARY_DIR}/protocol.pb.h
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --cpp_out ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/protocol.proto
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol.pb.cc ${CMAKE_CURRENT_SOURCE_DIR}/protocol.pb.h
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --cpp_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/protocol.proto
|
||||
COMMENT "Running C++ protocol buffer compiler on protocol.proto"
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/protocol.proto
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol.proto
|
||||
)
|
||||
ADD_CUSTOM_TARGET(pb DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/protocol.pb.cc)
|
||||
ADD_CUSTOM_TARGET(pb DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol.pb.cc)
|
||||
endif()
|
||||
|
||||
FILE(GLOB HEADERS *.h protocol.h)
|
||||
|
|
|
@ -39,6 +39,9 @@ typedef enum { BUDDY_NO_FLAG = 0,
|
|||
/// Represents one legacy network Buddy.
|
||||
class Buddy {
|
||||
public:
|
||||
typedef enum { Ask,
|
||||
Both,
|
||||
} Subscription;
|
||||
/// Constructor.
|
||||
|
||||
/// \param rosterManager RosterManager associated with this buddy.
|
||||
|
@ -93,12 +96,12 @@ class Buddy {
|
|||
/// Sets current subscription.
|
||||
|
||||
/// \param subscription "to", "from", "both", "ask"
|
||||
void setSubscription(const std::string &subscription);
|
||||
void setSubscription(Subscription subscription);
|
||||
|
||||
/// Returns current subscription
|
||||
|
||||
/// \return subscription "to", "from", "both", "ask"
|
||||
const std::string getSubscription();
|
||||
Subscription getSubscription();
|
||||
|
||||
/// Sets this buddy's flags.
|
||||
|
||||
|
@ -172,6 +175,7 @@ class Buddy {
|
|||
Swift::JID m_jid;
|
||||
BuddyFlag m_flags;
|
||||
RosterManager *m_rosterManager;
|
||||
Subscription m_subscription;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include <boost/signal.hpp>
|
||||
|
||||
|
||||
#define CONFIG_HAS_KEY(PTR, KEY) (*PTR).hasKey(KEY)
|
||||
#define CONFIG_STRING(PTR, KEY) (*PTR)[KEY].as<std::string>()
|
||||
#define CONFIG_INT(PTR, KEY) (*PTR)[KEY].as<int>()
|
||||
#define CONFIG_BOOL(PTR, KEY) (*PTR)[KEY].as<bool>()
|
||||
#define CONFIG_LIST(PTR, KEY) (*PTR)[KEY].as<std::list<std::string> >()
|
||||
#define CONFIG_VECTOR(PTR, KEY) (*PTR)[KEY].as<std::vector<std::string> >()
|
||||
#define CONFIG_HAS_KEY(PTR, KEY) (*PTR).hasKey(KEY)
|
||||
#define CONFIG_VECTOR(PTR, KEY) ((*PTR).hasKey(KEY) ? (*PTR)[KEY].as<std::vector<std::string> >() : std::vector<std::string>())
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
|
@ -50,7 +50,7 @@ typedef boost::program_options::variables_map Variables;
|
|||
class Config {
|
||||
public:
|
||||
/// Constructor.
|
||||
Config() {}
|
||||
Config(int argc = 0, char **argv = NULL) : m_argc(argc), m_argv(argv) {}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Config() {}
|
||||
|
@ -99,6 +99,8 @@ class Config {
|
|||
boost::signal<void ()> onConfigReloaded;
|
||||
|
||||
private:
|
||||
int m_argc;
|
||||
char **m_argv;
|
||||
Variables m_variables;
|
||||
std::map<std::string, std::string> m_unregistered;
|
||||
std::string m_file;
|
||||
|
|
43
include/transport/gatewayresponder.h
Normal file
43
include/transport/gatewayresponder.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* 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 <vector>
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/Queries/Responder.h"
|
||||
#include "Swiften/Elements/GatewayPayload.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class UserManager;
|
||||
|
||||
class GatewayResponder : public Swift::Responder<Swift::GatewayPayload> {
|
||||
public:
|
||||
GatewayResponder(Swift::IQRouter *router, UserManager *userManager);
|
||||
~GatewayResponder();
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload);
|
||||
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload);
|
||||
UserManager *m_userManager;
|
||||
};
|
||||
|
||||
}
|
|
@ -51,10 +51,15 @@ class LocalBuddy : public Buddy {
|
|||
}
|
||||
|
||||
std::string getIconHash() { return m_iconHash; }
|
||||
void setIconHash(const std::string &iconHash) { m_iconHash = iconHash; }
|
||||
void setIconHash(const std::string &iconHash) {
|
||||
bool changed = m_iconHash != iconHash;
|
||||
m_iconHash = iconHash;
|
||||
if (changed)
|
||||
getRosterManager()->storeBuddy(this);
|
||||
}
|
||||
|
||||
std::vector<std::string> getGroups() { return m_groups; }
|
||||
void setGroups(const std::vector<std::string> &groups) { m_groups = groups; }
|
||||
void setGroups(const std::vector<std::string> &groups);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
|
63
include/transport/logging.h
Normal file
63
include/transport/logging.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef WITH_LOG4CXX
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include "log4cxx/helpers/transcoder.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/logmanager.h"
|
||||
|
||||
#define DEFINE_LOGGER(VAR, NAME) static log4cxx::LoggerPtr VAR = log4cxx::Logger::getLogger(NAME);
|
||||
|
||||
using namespace log4cxx;
|
||||
#else
|
||||
#define DEFINE_LOGGER(VARIABLE, NAME) static const char *VARIABLE = NAME;
|
||||
|
||||
#define LOG4CXX_ERROR(LOGGER, DATA) std::cerr << "E: <" << LOGGER << "> " << DATA << "\n";
|
||||
#define LOG4CXX_WARN(LOGGER, DATA) std::cout << "W: <" << LOGGER << "> " << DATA << "\n";
|
||||
#define LOG4CXX_INFO(LOGGER, DATA) std::cout << "I: <" << LOGGER << "> " << DATA << "\n";
|
||||
#endif
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Config;
|
||||
|
||||
namespace Logging {
|
||||
|
||||
void initBackendLogging(Config *config);
|
||||
void initMainLogging(Config *config);
|
||||
void shutdownLogging();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -22,10 +22,14 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#ifndef WIN32
|
||||
#include "signal.h"
|
||||
#endif
|
||||
|
||||
namespace Transport {
|
||||
|
||||
#ifndef WIN32
|
||||
void process_mem_usage(double& shared, double& resident_set);
|
||||
void process_mem_usage(double& shared, double& resident_set, pid_t pid = 0);
|
||||
#endif
|
||||
|
||||
}
|
|
@ -34,6 +34,22 @@ namespace Transport {
|
|||
/// development.
|
||||
class NetworkPlugin {
|
||||
public:
|
||||
|
||||
class PluginConfig {
|
||||
public:
|
||||
PluginConfig() : m_needPassword(true) {}
|
||||
virtual ~PluginConfig() {}
|
||||
|
||||
void setNeedPassword(bool needPassword = true) { m_needPassword = needPassword; }
|
||||
void setExtraFields(const std::vector<std::string> &fields) { m_extraFields = fields; }
|
||||
|
||||
private:
|
||||
bool m_needPassword;
|
||||
std::vector<std::string> m_extraFields;
|
||||
|
||||
friend class NetworkPlugin;
|
||||
};
|
||||
|
||||
/// Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer.
|
||||
/// \param loop Event loop.
|
||||
/// \param host Host where Spectrum2 NetworkPluginServer runs.
|
||||
|
@ -43,6 +59,8 @@ class NetworkPlugin {
|
|||
/// Destructor.
|
||||
virtual ~NetworkPlugin();
|
||||
|
||||
void sendConfig(const PluginConfig &cfg);
|
||||
|
||||
/// Call this function when legacy network buddy changed.
|
||||
/// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld")
|
||||
/// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com")
|
||||
|
@ -211,6 +229,8 @@ class NetworkPlugin {
|
|||
virtual void handleFTPauseRequest(unsigned long ftID) {}
|
||||
virtual void handleFTContinueRequest(unsigned long ftID) {}
|
||||
|
||||
virtual void handleMemoryUsage(double &res, double &shared) {res = 0; shared = 0;}
|
||||
|
||||
virtual void handleExitRequest() { exit(1); }
|
||||
void handleDataRead(std::string &data);
|
||||
virtual void sendData(const std::string &string) {}
|
||||
|
|
|
@ -56,6 +56,7 @@ class NetworkPluginServer {
|
|||
bool acceptUsers;
|
||||
bool longRun;
|
||||
bool willDie;
|
||||
std::string id;
|
||||
};
|
||||
|
||||
NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager);
|
||||
|
@ -70,6 +71,10 @@ class NetworkPluginServer {
|
|||
return m_clients;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getCrashedBackends() {
|
||||
return m_crashedBackends;
|
||||
}
|
||||
|
||||
void collectBackend();
|
||||
|
||||
bool moveToLongRunBackend(User *user);
|
||||
|
@ -137,6 +142,7 @@ class NetworkPluginServer {
|
|||
bool m_isNextLongRun;
|
||||
std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
|
||||
FileTransferManager *m_ftManager;
|
||||
std::vector<std::string> m_crashedBackends;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ message Login {
|
|||
required string user = 1;
|
||||
required string legacyName = 2;
|
||||
required string password = 3;
|
||||
repeated string extraFields = 4;
|
||||
}
|
||||
|
||||
message Logout {
|
||||
|
@ -106,6 +107,7 @@ message Stats {
|
|||
required int32 res = 1;
|
||||
required int32 init_res = 2;
|
||||
required int32 shared = 3;
|
||||
required string id = 4;
|
||||
}
|
||||
|
||||
message File {
|
||||
|
@ -121,6 +123,10 @@ message FileTransferData {
|
|||
required bytes data = 2;
|
||||
}
|
||||
|
||||
message BackendConfig {
|
||||
required string config = 1;
|
||||
}
|
||||
|
||||
message WrapperMessage {
|
||||
enum Type {
|
||||
TYPE_CONNECTED = 1;
|
||||
|
@ -151,6 +157,7 @@ message WrapperMessage {
|
|||
TYPE_FT_PAUSE = 27;
|
||||
TYPE_FT_CONTINUE = 28;
|
||||
TYPE_EXIT = 29;
|
||||
TYPE_BACKEND_CONFIG = 30;
|
||||
}
|
||||
required Type type = 1;
|
||||
optional bytes payload = 2;
|
||||
|
|
|
@ -80,6 +80,8 @@ struct BuddyInfo {
|
|||
int flags;
|
||||
};
|
||||
|
||||
class Config;
|
||||
|
||||
/// Abstract class defining storage backends.
|
||||
class StorageBackend
|
||||
{
|
||||
|
@ -87,6 +89,8 @@ class StorageBackend
|
|||
/// Virtual desctructor.
|
||||
virtual ~StorageBackend() {}
|
||||
|
||||
static StorageBackend *createBackend(Config *config, std::string &error);
|
||||
|
||||
/// connect
|
||||
virtual bool connect() = 0;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "transport/config.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/presenceoracle.h"
|
||||
#include <Swiften/Network/BoostConnectionServer.h>
|
||||
|
||||
namespace Transport {
|
||||
// typedef enum { CLIENT_FEATURE_ROSTERX = 2,
|
||||
|
@ -165,6 +166,7 @@ namespace Transport {
|
|||
private:
|
||||
void handleConnected();
|
||||
void handleConnectionError(const Swift::ComponentError &error);
|
||||
void handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e);
|
||||
void handlePresence(Swift::Presence::ref presence);
|
||||
void handleDataRead(const Swift::SafeByteArray &data);
|
||||
void handleDataWritten(const Swift::SafeByteArray &data);
|
||||
|
|
|
@ -104,6 +104,10 @@ class UserManager : public Swift::EntityCapsProvider {
|
|||
return m_userRegistry;
|
||||
}
|
||||
|
||||
Component *getComponent() {
|
||||
return m_component;
|
||||
}
|
||||
|
||||
/// Connects user manually.
|
||||
/// \param user JID of user.
|
||||
void connectUser(const Swift::JID &user);
|
||||
|
@ -112,6 +116,13 @@ class UserManager : public Swift::EntityCapsProvider {
|
|||
/// \param user JID of user.
|
||||
void disconnectUser(const Swift::JID &user);
|
||||
|
||||
void messageToXMPPSent() { m_sentToXMPP++; }
|
||||
void messageToBackendSent() { m_sentToBackend++; }
|
||||
|
||||
unsigned long getMessagesToXMPP() { return m_sentToXMPP; }
|
||||
unsigned long getMessagesToBackend() { return m_sentToBackend; }
|
||||
|
||||
|
||||
private:
|
||||
void handlePresence(Swift::Presence::ref presence);
|
||||
void handleMessageReceived(Swift::Message::ref message);
|
||||
|
@ -130,6 +141,8 @@ class UserManager : public Swift::EntityCapsProvider {
|
|||
StorageResponder *m_storageResponder;
|
||||
UserRegistry *m_userRegistry;
|
||||
Swift::Timer::ref m_removeTimer;
|
||||
unsigned long m_sentToXMPP;
|
||||
unsigned long m_sentToBackend;
|
||||
friend class RosterResponder;
|
||||
};
|
||||
|
||||
|
|
166
munin/spectrum2_
Executable file
166
munin/spectrum2_
Executable file
|
@ -0,0 +1,166 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# config:
|
||||
# [spectrum2_*]
|
||||
# env.admin_jid tradmin@host.org
|
||||
# env.password jid_password
|
||||
# env.transports icq.host.org xmpp.host.org
|
||||
#
|
||||
# symlinks:
|
||||
# spectrum2_backends spectrum2_memory spectrum2_users spectrum2_messages spectrum2_messages_sec
|
||||
#
|
||||
#
|
||||
use AnyEvent;
|
||||
use AnyEvent::XMPP::Client;
|
||||
use AnyEvent::XMPP::Component;
|
||||
use AnyEvent::XMPP::Ext::Disco;
|
||||
use AnyEvent::XMPP::Ext::Version;
|
||||
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
|
||||
use AnyEvent::XMPP::Util qw/simxml/;
|
||||
use XML::Simple;
|
||||
use Time::HiRes qw ( setitimer ITIMER_REAL time );
|
||||
use strict;
|
||||
$|=1;
|
||||
|
||||
$SIG{ALRM} = sub { exit; };
|
||||
setitimer(ITIMER_REAL, 30, 1);
|
||||
|
||||
|
||||
my %config=(
|
||||
users => {
|
||||
title=>'Buddies online',
|
||||
vlabel=>'users',
|
||||
info=>'Number of users that currently use the spectrum transports.',
|
||||
command=>'online_users_count',
|
||||
base=>'--base 1000',
|
||||
x=>'1',
|
||||
},
|
||||
backends => {
|
||||
title=>'Backends running',
|
||||
vlabel=>'backends',
|
||||
info=>'Number of backends that currently running.',
|
||||
command=>'backends_count',
|
||||
base=>'--base 1000',
|
||||
x=>'1',
|
||||
},
|
||||
memory => {
|
||||
title=>'Memory usage of transports',
|
||||
vlabel=>'megabytes',
|
||||
info=>'Memory usage of spectrum transports.',
|
||||
command=>'used_memory',
|
||||
base=>'--base 1024',
|
||||
x=>'1024',
|
||||
},
|
||||
messages => {
|
||||
title=>'Messages send over transport',
|
||||
vlabel=>'messages',
|
||||
info=>'Messages send over spectrum transports.',
|
||||
command=>'',
|
||||
base=>'--base 1000',
|
||||
x=>'1',
|
||||
},
|
||||
messages_sec => {
|
||||
title=>'Messages send over transport',
|
||||
vlabel=>'messages/sec',
|
||||
info=>'Messages send per second over spectrum transports.',
|
||||
command=>'',
|
||||
base=>'--base 1000',
|
||||
x=>'1',
|
||||
},
|
||||
);
|
||||
my @queue=('_out','_in');
|
||||
$0 =~ /spectrum2_(.+)*$/;
|
||||
my $func = $1;
|
||||
exit 2 unless defined $func;
|
||||
my %tr;
|
||||
my $count=0;
|
||||
foreach (split(' ',$ENV{'transports'})){
|
||||
if ($func=~/messages/)
|
||||
{
|
||||
$tr{$_."_in"}=$count;
|
||||
$count++;
|
||||
$tr{$_."_out"}=$count;
|
||||
$count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tr{$_}=$count;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $ARGV[0] and $ARGV[0] eq "config")
|
||||
{
|
||||
print "graph_title ".$config{$func}->{'title'}."\n";
|
||||
print "graph_vlabel ".$config{$func}->{'vlabel'}."\n";
|
||||
print "graph_category spectrum2\n";
|
||||
foreach (keys (%tr)){
|
||||
print "r".$tr{$_}.".label ".$_."\n";
|
||||
if ($func eq 'messages_sec')
|
||||
{
|
||||
print "r".$tr{$_}.".type DERIVE\n";
|
||||
print "r".$tr{$_}.".min 0\n";
|
||||
}
|
||||
}
|
||||
print "graph_args ".$config{$func}->{'base'}."\n";
|
||||
print "graph_info ".$config{$func}->{'info'}."\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
binmode( STDOUT);
|
||||
my $xs=new XML::Simple;
|
||||
my $cl=AnyEvent::XMPP::Client->new(debug=>0);
|
||||
my $j=AnyEvent->condvar;
|
||||
$cl->add_account($ENV{'admin_jid'}.'/'.time,$ENV{'password'});
|
||||
$cl->reg_cb(
|
||||
session_ready => \&cl_sess,
|
||||
disconnect => \&cl_disc,
|
||||
message => \&cl_msg,
|
||||
);
|
||||
$cl->start;
|
||||
$j->wait;
|
||||
|
||||
|
||||
sub cl_disc
|
||||
{
|
||||
my ($cl,$acc,$h,$p,$reas)=@_;
|
||||
print "disc ($h:$p) $reas\n";
|
||||
}
|
||||
sub cl_sess
|
||||
{
|
||||
my($cl,$acc)=@_;
|
||||
foreach (keys (%tr)){
|
||||
if ($func=~/messages/)
|
||||
{
|
||||
if (s/_in$//)
|
||||
{
|
||||
$cl->send_message("messages_from_xmpp",$_,undef,'chat');
|
||||
};
|
||||
if (s/_out$//)
|
||||
{
|
||||
$cl->send_message("messages_to_xmpp",$_,undef,'chat');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$cl->send_message($config{$func}->{'command'},$_,undef,'chat');
|
||||
}
|
||||
}
|
||||
}
|
||||
sub cl_msg
|
||||
{
|
||||
my ($cl,$acc,$msg)=@_;
|
||||
if ($func=~/messages/)
|
||||
{
|
||||
print "r".$tr{$msg->from.$queue[-1]}.".value ".int($msg->any_body/$config{$func}->{'x'})."\n";
|
||||
delete( $tr{$msg->from.$queue[-1]});
|
||||
pop(@queue);
|
||||
if ($#queue==-1){@queue=("_out","_in");}
|
||||
}
|
||||
else
|
||||
{
|
||||
print "r".$tr{$msg->from}.".value ".int($msg->any_body/$config{$func}->{'x'})."\n";
|
||||
delete( $tr{$msg->from});
|
||||
}
|
||||
exit if (scalar(keys %tr)==0);
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
ADD_SUBDIRECTORY(src)
|
||||
ADD_SUBDIRECTORY(cpp)
|
||||
ADD_SUBDIRECTORY(python)
|
||||
|
|
35
plugin/cpp/CMakeLists.txt
Normal file
35
plugin/cpp/CMakeLists.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB HEADERS ../include/transport/*.h)
|
||||
|
||||
set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/memoryusage.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/logging.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/config.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
|
||||
|
||||
if (NOT WIN32)
|
||||
ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
|
||||
else()
|
||||
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
|
||||
endif()
|
||||
ADD_DEPENDENCIES(transport-plugin pb)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib)
|
||||
endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
|
||||
|
||||
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc")
|
||||
#INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc" DESTINATION lib/pkgconfig)
|
|
@ -19,19 +19,21 @@
|
|||
*/
|
||||
|
||||
#include "transport/networkplugin.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/basicconfigurator.h"
|
||||
#include "transport/memoryusage.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <stdint.h>
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("NetworkPlugin");
|
||||
DEFINE_LOGGER(logger, "NetworkPlugin");
|
||||
|
||||
namespace Transport {
|
||||
|
||||
|
@ -40,6 +42,12 @@ namespace Transport {
|
|||
wrap.set_payload(MESSAGE); \
|
||||
wrap.SerializeToString(&MESSAGE);
|
||||
|
||||
template <class T> std::string stringOf(T object) {
|
||||
std::ostringstream os;
|
||||
os << object;
|
||||
return (os.str());
|
||||
}
|
||||
|
||||
NetworkPlugin::NetworkPlugin() {
|
||||
m_pingReceived = false;
|
||||
|
||||
|
@ -52,6 +60,25 @@ NetworkPlugin::NetworkPlugin() {
|
|||
NetworkPlugin::~NetworkPlugin() {
|
||||
}
|
||||
|
||||
void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
|
||||
std::string data = "[registration]";
|
||||
data += std::string("needPassword=") + (cfg.m_needPassword ? "1" : "0") + "\n";
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = cfg.m_extraFields.begin(); it != cfg.m_extraFields.end(); it++) {
|
||||
data += std::string("extraField=") + (*it) + "\n";
|
||||
}
|
||||
|
||||
pbnetwork::BackendConfig m;
|
||||
m.set_config(data);
|
||||
|
||||
std::string message;
|
||||
m.SerializeToString(&message);
|
||||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BACKEND_CONFIG);
|
||||
|
||||
send(message);
|
||||
}
|
||||
|
||||
void NetworkPlugin::handleMessage(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname, const std::string &xhtml) {
|
||||
pbnetwork::ConversationMessage m;
|
||||
m.set_username(user);
|
||||
|
@ -559,8 +586,8 @@ void NetworkPlugin::handleDataRead(std::string &data) {
|
|||
}
|
||||
|
||||
void NetworkPlugin::send(const std::string &data) {
|
||||
char header[4];
|
||||
*((int*)(header)) = htonl(data.size());
|
||||
uint32_t size = htonl(data.size());
|
||||
char *header = (char *) &size;
|
||||
sendData(std::string(header, 4) + data);
|
||||
}
|
||||
|
||||
|
@ -586,13 +613,19 @@ void NetworkPlugin::sendMemoryUsage() {
|
|||
pbnetwork::Stats stats;
|
||||
|
||||
stats.set_init_res(m_init_res);
|
||||
double res;
|
||||
double shared;
|
||||
double res = 0;
|
||||
double shared = 0;
|
||||
#ifndef WIN32
|
||||
process_mem_usage(shared, res);
|
||||
#endif
|
||||
stats.set_res(res);
|
||||
stats.set_shared(shared);
|
||||
|
||||
double e_res;
|
||||
double e_shared;
|
||||
handleMemoryUsage(e_res, e_shared);
|
||||
|
||||
stats.set_res(res + e_res);
|
||||
stats.set_shared(shared + e_shared);
|
||||
stats.set_id(stringOf(getpid()));
|
||||
|
||||
std::string message;
|
||||
stats.SerializeToString(&message);
|
15
plugin/python/CMakeLists.txt
Normal file
15
plugin/python/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
if (PROTOBUF_FOUND)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
COMMENT "Running Python protocol buffer compiler on protocol.proto"
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
)
|
||||
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
524
plugin/python/NetworkPlugin.py
Normal file
524
plugin/python/NetworkPlugin.py
Normal file
|
@ -0,0 +1,524 @@
|
|||
import protocol_pb2, socket, struct, sys, os
|
||||
|
||||
def WRAP(MESSAGE, TYPE):
|
||||
wrap = protocol_pb2.WrapperMessage()
|
||||
wrap.type = TYPE
|
||||
wrap.payload = MESSAGE
|
||||
return wrap.SerializeToString()
|
||||
|
||||
class NetworkPlugin:
|
||||
"""
|
||||
Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer.
|
||||
@param loop: Event loop.
|
||||
@param host: Host where Spectrum2 NetworkPluginServer runs.
|
||||
@param port: Port.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.m_pingReceived = False
|
||||
self.m_data = ""
|
||||
self.m_init_res = 0
|
||||
|
||||
def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = ""):
|
||||
m = protocol_pb2.ConversationMessage()
|
||||
m.userName = user
|
||||
m.buddyName = legacyName
|
||||
m.message = msg
|
||||
m.nickname = nickname
|
||||
m.xhtml = xhtml
|
||||
|
||||
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE)
|
||||
self.send(message)
|
||||
|
||||
def handleAttention(self, user, buddyName, msg):
|
||||
m = protocol_pb2.ConversationMessage()
|
||||
m.userName = user
|
||||
m.buddyName = buddyName
|
||||
m.message = msg
|
||||
|
||||
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ATTENTION)
|
||||
self.send(message)
|
||||
|
||||
def handleVCard(self, user, ID, legacyName, fullName, nickname, photo):
|
||||
vcard = protocol_pb2.VCard()
|
||||
vcard.userName = user
|
||||
vcard.buddyName = legacyName
|
||||
vcard.id = ID
|
||||
vcard.fullname = fullName
|
||||
vcard.nickname = nickname
|
||||
vcard.photo = photo
|
||||
|
||||
message = WRAP(vcard.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_VCARD)
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleSubject(self, user, legacyName, msg, nickname = ""):
|
||||
m = protocol_pb2.ConversationMessage()
|
||||
m.userName = user
|
||||
m.buddyName = legacyName
|
||||
m.message = msg
|
||||
m.nickname = nickname
|
||||
|
||||
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ROOM_SUBJECT_CHANGED)
|
||||
#print "SENDING MESSAGE"
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleBuddyChanged(self, user, buddyName, alias, groups, status, statusMessage = "", iconHash = "", blocked = False):
|
||||
buddy = protocol_pb2.Buddy()
|
||||
buddy.userName = user
|
||||
buddy.buddyName = buddyName
|
||||
buddy.alias = alias
|
||||
buddy.group.extend(groups)
|
||||
buddy.status = status
|
||||
buddy.statusMessage = statusMessage
|
||||
buddy.iconHash = iconHash
|
||||
buddy.blocked = blocked
|
||||
|
||||
message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_CHANGED)
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleBuddyTyping(self, user, buddyName):
|
||||
buddy = protocol_pb2.Buddy()
|
||||
buddy.userName = user
|
||||
buddy.buddyName = buddyName
|
||||
|
||||
message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING)
|
||||
self.send(message);
|
||||
|
||||
def handleBuddyTyped(self, user, buddyName):
|
||||
buddy = protocol_pb2.Buddy()
|
||||
buddy.userName = user
|
||||
buddy.buddyName = buddyName
|
||||
|
||||
message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED)
|
||||
self.send(message);
|
||||
|
||||
def handleBuddyStoppedTyping(self, user, buddyName):
|
||||
buddy = protocol_pb2.Buddy()
|
||||
buddy.userName = user
|
||||
buddy.buddyName = buddyName
|
||||
|
||||
message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING)
|
||||
self.send(message)
|
||||
|
||||
def handleAuthorization(self, user, buddyName):
|
||||
buddy = protocol_pb2.Buddy()
|
||||
buddy.userName = user
|
||||
buddy.buddyName = buddyName
|
||||
|
||||
message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_AUTH_REQUEST)
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleConnected(self, user):
|
||||
d = protocol_pb2.Connected()
|
||||
d.user = user
|
||||
|
||||
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONNECTED)
|
||||
self.send(message);
|
||||
|
||||
|
||||
def handleDisconnected(self, user, error = 0, msg = ""):
|
||||
d = protocol_pb2.Disconnected()
|
||||
d.user = user
|
||||
d.error = error
|
||||
d.message = msg
|
||||
|
||||
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_DISCONNECTED)
|
||||
self.send(message);
|
||||
|
||||
|
||||
def handleParticipantChanged(self, user, nickname, room, flags, status, statusMessage = "", newname = ""):
|
||||
d = protocol_pb2.Participant()
|
||||
d.userName = user
|
||||
d.nickname = nickname
|
||||
d.room = room
|
||||
d.flag = flags
|
||||
d.newname = newname
|
||||
d.status = status
|
||||
d.statusMessage = statusMessage
|
||||
|
||||
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_PARTICIPANT_CHANGED)
|
||||
self.send(message);
|
||||
|
||||
|
||||
def handleRoomNicknameChanged(self, user, r, nickname):
|
||||
room = protocol_pb2.Room()
|
||||
room.userName = user
|
||||
room.nickname = nickname
|
||||
room.room = r
|
||||
room.password = ""
|
||||
|
||||
message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ROOM_NICKNAME_CHANGED)
|
||||
self.send(message);
|
||||
|
||||
|
||||
def handleFTStart(self, user, buddyName, fileName, size):
|
||||
room = protocol_pb2.File()
|
||||
room.userName = user
|
||||
room.buddyName = buddyName
|
||||
room.fileName = fileName
|
||||
room.size = size
|
||||
|
||||
message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_START)
|
||||
self.send(message);
|
||||
|
||||
def handleFTFinish(self, user, buddyName, fileName, size, ftid):
|
||||
room = protocol_pb2.File()
|
||||
room.userName = user
|
||||
room.buddyName = buddyName
|
||||
room.fileName = fileName
|
||||
room.size = size
|
||||
|
||||
# Check later
|
||||
if ftid != 0:
|
||||
room.ftID = ftid
|
||||
|
||||
message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_FINISH)
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleFTData(self, ftID, data):
|
||||
d = protocol_pb2.FileTransferData()
|
||||
d.ftid = ftID
|
||||
d.data = data
|
||||
|
||||
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA);
|
||||
self.send(message)
|
||||
|
||||
def handleLoginPayload(self, data):
|
||||
payload = protocol_pb2.Login()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleLoginRequest(payload.user, payload.legacyName, payload.password)
|
||||
|
||||
def handleLogoutPayload(self, data):
|
||||
payload = protocol_pb2.Logout()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleLogoutRequest(self, payload.user, payload.legacyName)
|
||||
|
||||
def handleStatusChangedPayload(data):
|
||||
payload = protocol_pb2.Status()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleStatusChangeRequest(payload.userName, payload.status, payload.statusMessage)
|
||||
|
||||
def handleConvMessagePayload(self, data):
|
||||
payload = protocol_pb2.ConversationMessage()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleMessageSendRequest(payload.userName, payload.buddyName, payload.message, payload.xhtml)
|
||||
|
||||
def handleAttentionPayload(self, data):
|
||||
payload = protocol_pb2.ConversationMessage()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleAttentionRequest(payload.userName, payload.buddyName, payload.message)
|
||||
|
||||
def handleFTStartPayload(self, data):
|
||||
payload = protocol_pb2.File()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleFTStartRequest(payload.userName, payload.buddyName, payload.fileName, payload.size, payload.ftID);
|
||||
|
||||
def handleFTFinishPayload(self, data):
|
||||
payload = protocol_pb2.File()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleFTFinishRequest(payload.userName, payload.buddyName, payload.fileName, payload.size, payload.ftID)
|
||||
|
||||
def handleFTPausePayload(self, data):
|
||||
payload = protocol_pb2.FileTransferData()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleFTPauseRequest(payload.ftID)
|
||||
|
||||
def handleFTContinuePayload(self, data):
|
||||
payload = protocol_pb2.FileTransferData()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleFTContinueRequest(payload.ftID)
|
||||
|
||||
def handleJoinRoomPayload(self, data):
|
||||
payload = protocol_pb2.Room()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleJoinRoomRequest(payload.userName, payload.room, payload.nickname, payload.password)
|
||||
|
||||
def handleLeaveRoomPayload(self, data):
|
||||
payload = protocol_pb2.Room()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
self.handleLeaveRoomRequest(payload.userName, payload.room)
|
||||
|
||||
def handleVCardPayload(self, data):
|
||||
payload = protocol_pb2.VCard()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
if payload.HasField('photo'):
|
||||
self.handleVCardUpdatedRequest(payload.userName, payload.photo, payload.nickname)
|
||||
elif len(payload.buddyName) > 0:
|
||||
self.handleVCardRequest(payload.userName, payload.buddyName, payload.id)
|
||||
|
||||
def handleBuddyChangedPayload(self, data):
|
||||
payload = protocol_pb2.Buddy()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
if payload.HasField('blocked'):
|
||||
self.handleBuddyBlockToggled(payload.userName, payload.buddyName, payload.blocked)
|
||||
else:
|
||||
groups = [g for g in payload.group]
|
||||
self.handleBuddyUpdatedRequest(payload.userName, payload.buddyName, payload.alias, groups);
|
||||
|
||||
def handleBuddyRemovedPayload(self, data):
|
||||
payload = protocol_pb2.Buddy()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
groups = [g for g in payload.group]
|
||||
self.handleBuddyRemovedRequest(payload.userName, payload.buddyName, groups);
|
||||
|
||||
def handleChatStatePayload(self, data, msgType):
|
||||
payload = protocol_pb2.Buddy()
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
if msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING:
|
||||
self.handleTypingRequest(payload.userName, payload.buddyName)
|
||||
elif msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED:
|
||||
self.handleTypedRequest(payload.userName, payload.buddyName)
|
||||
elif msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING:
|
||||
self.handleStoppedTypingRequest(payload.userName, payload.buddyName)
|
||||
|
||||
|
||||
def handleDataRead(self, data):
|
||||
self.m_data += data
|
||||
while len(self.m_data) != 0:
|
||||
expected_size = 0
|
||||
if (len(self.m_data) >= 4):
|
||||
expected_size = struct.unpack('!I', self.m_data[0:4])[0]
|
||||
if (len(self.m_data) - 4 < expected_size):
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
||||
wrapper = protocol_pb2.WrapperMessage()
|
||||
if (wrapper.ParseFromString(self.m_data[4:]) == False):
|
||||
self.m_data = self.m_data[expected_size+4:]
|
||||
return
|
||||
|
||||
self.m_data = self.m_data[4+expected_size:]
|
||||
|
||||
if wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGIN:
|
||||
self.handleLoginPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGOUT:
|
||||
self.handleLogoutPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_PING:
|
||||
self.sendPong()
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE:
|
||||
self.handleConvMessagePayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_JOIN_ROOM:
|
||||
self.handleJoinRoomPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_LEAVE_ROOM:
|
||||
self.handleLeaveRoomPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_VCARD:
|
||||
self.handleVCardPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_CHANGED:
|
||||
self.handleBuddyChangedPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_REMOVED:
|
||||
self.handleBuddyRemovedPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_STATUS_CHANGED:
|
||||
self.handleStatusChangedPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING:
|
||||
self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED:
|
||||
self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING:
|
||||
self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_ATTENTION:
|
||||
self.handleAttentionPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_START:
|
||||
self.handleFTStartPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_FINISH:
|
||||
self.handleFTFinishPayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_PAUSE:
|
||||
self.handleFTPausePayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_CONTINUE:
|
||||
self.handleFTContinuePayload(wrapper.payload)
|
||||
elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_EXIT:
|
||||
self.handleExitRequest()
|
||||
|
||||
|
||||
def send(self, data):
|
||||
header = struct.pack('!I',len(data))
|
||||
self.sendData(header + data)
|
||||
|
||||
def checkPing(self):
|
||||
if (self.m_pingReceived == False):
|
||||
self.handleExitRequest()
|
||||
self.m_pingReceived = False
|
||||
|
||||
|
||||
def sendPong(self):
|
||||
self.m_pingReceived = True
|
||||
wrap = protocol_pb2.WrapperMessage()
|
||||
wrap.type = protocol_pb2.WrapperMessage.TYPE_PONG
|
||||
message = wrap.SerializeToString()
|
||||
self.send(message)
|
||||
self.sendMemoryUsage()
|
||||
|
||||
|
||||
def sendMemoryUsage(self):
|
||||
stats = protocol_pb2.Stats()
|
||||
|
||||
stats.init_res = self.m_init_res
|
||||
res = 0
|
||||
shared = 0
|
||||
|
||||
e_res, e_shared = self.handleMemoryUsage()
|
||||
|
||||
stats.res = res + e_res
|
||||
stats.shared = shared + e_shared
|
||||
stats.id = str(os.getpid())
|
||||
|
||||
message = WRAP(stats.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_STATS)
|
||||
self.send(message)
|
||||
|
||||
|
||||
def handleLoginRequest(self, user, legacyName, password):
|
||||
"""
|
||||
Called when XMPP user wants to connect legacy network.
|
||||
You should connect him to legacy network and call handleConnected or handleDisconnected function later.
|
||||
@param user: XMPP JID of user for which this event occurs.
|
||||
@param legacyName: Legacy network name of this user used for login.
|
||||
@param password: Legacy network password of this user.
|
||||
"""
|
||||
|
||||
#\msc
|
||||
#NetworkPlugin,YourNetworkPlugin,LegacyNetwork;
|
||||
#NetworkPlugin->YourNetworkPlugin [label="handleLoginRequest(...)", URL="\ref NetworkPlugin::handleLoginRequest()"];
|
||||
#YourNetworkPlugin->LegacyNetwork [label="connect the legacy network"];
|
||||
#--- [label="If password was valid and user is connected and logged in"];
|
||||
#YourNetworkPlugin<-LegacyNetwork [label="connected"];
|
||||
#YourNetworkPlugin->NetworkPlugin [label="handleConnected()", URL="\ref NetworkPlugin::handleConnected()"];
|
||||
#--- [label="else"];
|
||||
#YourNetworkPlugin<-LegacyNetwork [label="disconnected"];
|
||||
#YourNetworkPlugin->NetworkPlugin [label="handleDisconnected()", URL="\ref NetworkPlugin::handleDisconnected()"];
|
||||
#\endmsc
|
||||
|
||||
raise NotImplementedError, "Implement me"
|
||||
|
||||
def handleLogoutRequest(self, user, legacyName):
|
||||
"""
|
||||
Called when XMPP user wants to disconnect legacy network.
|
||||
You should disconnect him from legacy network.
|
||||
@param user: XMPP JID of user for which this event occurs.
|
||||
@param legacyName: Legacy network name of this user used for login.
|
||||
"""
|
||||
|
||||
raise NotImplementedError, "Implement me"
|
||||
|
||||
def handleMessageSendRequest(self, user, legacyName, message, xhtml = ""):
|
||||
"""
|
||||
Called when XMPP user sends message to legacy network.
|
||||
@param user: XMPP JID of user for which this event occurs.
|
||||
@param legacyName: Legacy network name of buddy or room.
|
||||
@param message: Plain text message.
|
||||
@param xhtml: XHTML message.
|
||||
"""
|
||||
|
||||
raise NotImplementedError, "Implement me"
|
||||
|
||||
def handleVCardRequest(self, user, legacyName, ID):
|
||||
""" Called when XMPP user requests VCard of buddy.
|
||||
@param user: XMPP JID of user for which this event occurs.
|
||||
@param legacyName: Legacy network name of buddy whose VCard is requested.
|
||||
@param ID: ID which is associated with this request. You have to pass it to handleVCard function when you receive VCard."""
|
||||
|
||||
#\msc
|
||||
#NetworkPlugin,YourNetworkPlugin,LegacyNetwork;
|
||||
#NetworkPlugin->YourNetworkPlugin [label="handleVCardRequest(...)", URL="\ref NetworkPlugin::handleVCardRequest()"];
|
||||
#YourNetworkPlugin->LegacyNetwork [label="start VCard fetching"];
|
||||
#YourNetworkPlugin<-LegacyNetwork [label="VCard fetched"];
|
||||
#YourNetworkPlugin->NetworkPlugin [label="handleVCard()", URL="\ref NetworkPlugin::handleVCard()"];
|
||||
#\endmsc
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def handleVCardUpdatedRequest(self, user, photo, nickname):
|
||||
"""
|
||||
Called when XMPP user updates his own VCard.
|
||||
You should update the VCard in legacy network too.
|
||||
@param user: XMPP JID of user for which this event occurs.
|
||||
@param photo: Raw photo data.
|
||||
"""
|
||||
pass
|
||||
|
||||
def handleJoinRoomRequest(self, user, room, nickname, pasword):
|
||||
pass
|
||||
|
||||
def handleLeaveRoomRequest(self, user, room):
|
||||
pass
|
||||
|
||||
def handleStatusChangeRequest(self, user, status, statusMessage):
|
||||
pass
|
||||
|
||||
def handleBuddyUpdatedRequest(self, user, buddyName, alias, groups):
|
||||
pass
|
||||
|
||||
def handleBuddyRemovedRequest(self, user, buddyName, groups):
|
||||
pass
|
||||
|
||||
def handleBuddyBlockToggled(self, user, buddyName, blocked):
|
||||
pass
|
||||
|
||||
def handleTypingRequest(self, user, buddyName):
|
||||
pass
|
||||
|
||||
def handleTypedRequest(self, user, buddyName):
|
||||
pass
|
||||
|
||||
def handleStoppedTypingRequest(self, user, buddyName):
|
||||
pass
|
||||
|
||||
def handleAttentionRequest(self, user, buddyName, message):
|
||||
pass
|
||||
|
||||
def handleFTStartRequest(self, user, buddyName, fileName, size, ftID):
|
||||
pass
|
||||
|
||||
def handleFTFinishRequest(self, user, buddyName, fileName, size, ftID):
|
||||
pass
|
||||
|
||||
def handleFTPauseRequest(self, ftID):
|
||||
pass
|
||||
|
||||
def handleFTContinueRequest(self, ftID):
|
||||
pass
|
||||
|
||||
def handleMemoryUsage(self):
|
||||
return (0,0)
|
||||
|
||||
def handleExitRequest(self):
|
||||
sys.exit(1)
|
||||
|
||||
def sendData(self, data):
|
||||
pass
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB HEADERS ../include/transport/*.h)
|
||||
|
||||
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)
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ws2_32.lib)
|
||||
endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)
|
||||
|
||||
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_BINARY_DIR}/transport.pc")
|
||||
#INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/transport.pc" DESTINATION lib/pkgconfig)
|
|
@ -1,137 +0,0 @@
|
|||
package pbnetwork;
|
||||
|
||||
enum StatusType {
|
||||
STATUS_ONLINE = 0;
|
||||
STATUS_AWAY = 1;
|
||||
STATUS_FFC = 2;
|
||||
STATUS_XA = 3;
|
||||
STATUS_DND = 4;
|
||||
STATUS_NONE = 5;
|
||||
STATUS_INVISIBLE = 6;
|
||||
}
|
||||
|
||||
message Connected {
|
||||
required string user = 1;
|
||||
}
|
||||
|
||||
message Disconnected {
|
||||
required string user = 1;
|
||||
required int32 error = 2;
|
||||
optional string message = 3;
|
||||
}
|
||||
|
||||
message Login {
|
||||
required string user = 1;
|
||||
required string legacyName = 2;
|
||||
required string password = 3;
|
||||
}
|
||||
|
||||
message Logout {
|
||||
required string user = 1;
|
||||
required string legacyName = 2;
|
||||
}
|
||||
|
||||
message Buddy {
|
||||
required string userName = 1;
|
||||
required string buddyName = 2;
|
||||
optional string alias = 3;
|
||||
optional string groups = 4;
|
||||
optional StatusType status = 5;
|
||||
optional string statusMessage = 6;
|
||||
optional string iconHash = 7;
|
||||
optional bool blocked = 8;
|
||||
}
|
||||
|
||||
message ConversationMessage {
|
||||
required string userName = 1;
|
||||
required string buddyName = 2;
|
||||
required string message = 3;
|
||||
optional string nickname = 4;
|
||||
optional string xhtml = 5;
|
||||
}
|
||||
|
||||
message Room {
|
||||
required string userName = 1;
|
||||
required string nickname = 2;
|
||||
required string room = 3;
|
||||
optional string password = 4;
|
||||
}
|
||||
|
||||
message Participant {
|
||||
required string userName = 1;
|
||||
required string room = 2;
|
||||
required string nickname = 3;
|
||||
required int32 flag = 4;
|
||||
required StatusType status = 5;
|
||||
optional string statusMessage = 6;
|
||||
optional string newname = 7;
|
||||
}
|
||||
|
||||
message VCard {
|
||||
required string userName = 1;
|
||||
required string buddyName = 2;
|
||||
required int32 id = 3;
|
||||
optional string fullname = 4;
|
||||
optional string nickname = 5;
|
||||
optional bytes photo = 6;
|
||||
}
|
||||
|
||||
message Status {
|
||||
required string userName = 1;
|
||||
required StatusType status = 3;
|
||||
optional string statusMessage = 4;
|
||||
}
|
||||
|
||||
message Stats {
|
||||
required int32 res = 1;
|
||||
required int32 init_res = 2;
|
||||
required int32 shared = 3;
|
||||
}
|
||||
|
||||
message File {
|
||||
required string userName = 1;
|
||||
required string buddyName = 2;
|
||||
required string fileName = 3;
|
||||
required int32 size = 4;
|
||||
optional int32 ftID = 5;
|
||||
}
|
||||
|
||||
message FileTransferData {
|
||||
required int32 ftID = 1;
|
||||
required bytes data = 2;
|
||||
}
|
||||
|
||||
message WrapperMessage {
|
||||
enum Type {
|
||||
TYPE_CONNECTED = 1;
|
||||
TYPE_DISCONNECTED = 2;
|
||||
TYPE_LOGIN = 3;
|
||||
TYPE_LOGOUT = 4;
|
||||
TYPE_BUDDY_CHANGED = 6;
|
||||
TYPE_BUDDY_REMOVED = 7;
|
||||
TYPE_CONV_MESSAGE = 8;
|
||||
TYPE_PING = 9;
|
||||
TYPE_PONG = 10;
|
||||
TYPE_JOIN_ROOM = 11;
|
||||
TYPE_LEAVE_ROOM = 12;
|
||||
TYPE_PARTICIPANT_CHANGED = 13;
|
||||
TYPE_ROOM_NICKNAME_CHANGED = 14;
|
||||
TYPE_ROOM_SUBJECT_CHANGED = 15;
|
||||
TYPE_VCARD = 16;
|
||||
TYPE_STATUS_CHANGED = 17;
|
||||
TYPE_BUDDY_TYPING = 18;
|
||||
TYPE_BUDDY_STOPPED_TYPING = 19;
|
||||
TYPE_BUDDY_TYPED = 20;
|
||||
TYPE_AUTH_REQUEST = 21;
|
||||
TYPE_ATTENTION = 22;
|
||||
TYPE_STATS = 23;
|
||||
TYPE_FT_START = 24;
|
||||
TYPE_FT_FINISH = 25;
|
||||
TYPE_FT_DATA = 26;
|
||||
TYPE_FT_PAUSE = 27;
|
||||
TYPE_FT_CONTINUE = 28;
|
||||
}
|
||||
required Type type = 1;
|
||||
optional bytes payload = 2;
|
||||
}
|
||||
;
|
|
@ -12,6 +12,8 @@
|
|||
#include "transport/statsresponder.h"
|
||||
#include "transport/usersreconnecter.h"
|
||||
#include "transport/util.h"
|
||||
#include "transport/gatewayresponder.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -24,20 +26,11 @@
|
|||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "log4cxx/logger.h"
|
||||
#include "log4cxx/consoleappender.h"
|
||||
#include "log4cxx/patternlayout.h"
|
||||
#include "log4cxx/propertyconfigurator.h"
|
||||
#include "log4cxx/helpers/properties.h"
|
||||
#include "log4cxx/helpers/transcoder.h"
|
||||
#include "log4cxx/helpers/fileinputstream.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
static LoggerPtr logger = log4cxx::Logger::getLogger("Spectrum");
|
||||
DEFINE_LOGGER(logger, "Spectrum");
|
||||
|
||||
Swift::SimpleEventLoop *eventLoop_ = NULL;
|
||||
Component *component_ = NULL;
|
||||
|
@ -121,7 +114,7 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Config config;
|
||||
Config config(argc, argv);
|
||||
|
||||
boost::program_options::variables_map vm;
|
||||
bool no_daemon = false;
|
||||
|
@ -154,7 +147,7 @@ int main(int argc, char **argv)
|
|||
boost::program_options::positional_options_description p;
|
||||
p.add("config", -1);
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run(), vm);
|
||||
options(desc).positional(p).allow_unregistered().run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
if (vm.count("version")) {
|
||||
|
@ -234,71 +227,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (CONFIG_STRING(&config, "logging.config").empty()) {
|
||||
LoggerPtr root = log4cxx::Logger::getRootLogger();
|
||||
#ifdef WIN32
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n")));
|
||||
#else
|
||||
root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
log4cxx::helpers::Properties p;
|
||||
log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.config"));
|
||||
|
||||
p.load(istream);
|
||||
LogString pid, jid;
|
||||
log4cxx::helpers::Transcoder::decode(boost::lexical_cast<std::string>(getpid()), pid);
|
||||
log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid);
|
||||
#ifdef WIN32
|
||||
p.setProperty(L"pid", pid);
|
||||
p.setProperty(L"jid", jid);
|
||||
#else
|
||||
p.setProperty("pid", pid);
|
||||
p.setProperty("jid", jid);
|
||||
#endif
|
||||
|
||||
std::string dir;
|
||||
BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) {
|
||||
if (boost::ends_with(prop, ".File")) {
|
||||
log4cxx::helpers::Transcoder::encode(p.get(prop), dir);
|
||||
boost::replace_all(dir, "${jid}", jid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dir.empty()) {
|
||||
// create directories
|
||||
try {
|
||||
boost::filesystem::create_directories(
|
||||
boost::filesystem::path(dir).parent_path().string()
|
||||
);
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (!CONFIG_STRING(&config, "service.group").empty() && !CONFIG_STRING(&config, "service.user").empty()) {
|
||||
struct group *gr;
|
||||
if ((gr = getgrnam(CONFIG_STRING(&config, "service.group").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.group name " << CONFIG_STRING(&config, "service.group") << "\n";
|
||||
return 1;
|
||||
}
|
||||
struct passwd *pw;
|
||||
if ((pw = getpwnam(CONFIG_STRING(&config, "service.user").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.user name " << CONFIG_STRING(&config, "service.user") << "\n";
|
||||
return 1;
|
||||
}
|
||||
chown(dir.c_str(), pw->pw_uid, gr->gr_gid);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
log4cxx::PropertyConfigurator::configure(p);
|
||||
}
|
||||
Logging::initMainLogging(&config);
|
||||
|
||||
#ifndef WIN32
|
||||
if (!CONFIG_STRING(&config, "service.group").empty() ||!CONFIG_STRING(&config, "service.user").empty() ) {
|
||||
|
@ -348,57 +277,17 @@ int main(int argc, char **argv)
|
|||
component_ = &transport;
|
||||
// Logger logger(&transport);
|
||||
|
||||
StorageBackend *storageBackend = NULL;
|
||||
|
||||
#ifdef WITH_SQLITE
|
||||
if (CONFIG_STRING(&config, "database.type") == "sqlite3") {
|
||||
storageBackend = new SQLite3Backend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
std::string error;
|
||||
StorageBackend *storageBackend = StorageBackend::createBackend(&config, error);
|
||||
if (storageBackend == NULL) {
|
||||
if (!error.empty()) {
|
||||
std::cerr << error << "\n";
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "sqlite3") {
|
||||
std::cerr << "Spectrum2 is not compiled with mysql backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MYSQL
|
||||
if (CONFIG_STRING(&config, "database.type") == "mysql") {
|
||||
storageBackend = new MySQLBackend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "mysql") {
|
||||
std::cerr << "Spectrum2 is not compiled with mysql backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PQXX
|
||||
if (CONFIG_STRING(&config, "database.type") == "pqxx") {
|
||||
storageBackend = new PQXXBackend(&config);
|
||||
if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (CONFIG_STRING(&config, "database.type") == "pqxx") {
|
||||
std::cerr << "Spectrum2 is not compiled with pqxx backend.\n";
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3"
|
||||
&& CONFIG_STRING(&config, "database.type") != "pqxx" && CONFIG_STRING(&config, "database.type") != "none") {
|
||||
std::cerr << "Unknown storage backend " << CONFIG_STRING(&config, "database.type") << "\n";
|
||||
return -2;
|
||||
else if (!storageBackend->connect()) {
|
||||
std::cerr << "Can't connect to database. Check the log to find out the reason.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
UserManager userManager(&transport, &userRegistry, storageBackend);
|
||||
|
@ -421,6 +310,9 @@ int main(int argc, char **argv)
|
|||
StatsResponder statsResponder(&transport, &userManager, &plugin, storageBackend);
|
||||
statsResponder.start();
|
||||
|
||||
GatewayResponder gatewayResponder(transport.getIQRouter(), &userManager);
|
||||
gatewayResponder.start();
|
||||
|
||||
eventLoop_ = &eventLoop;
|
||||
|
||||
eventLoop.run();
|
||||
|
@ -436,4 +328,5 @@ int main(int argc, char **argv)
|
|||
|
||||
delete storageBackend;
|
||||
delete factories;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,38 +7,35 @@ server_mode = 1
|
|||
backend_host=localhost
|
||||
pidfile=./test.pid
|
||||
# < this option doesn't work yet
|
||||
backend_port=10001
|
||||
admin_username=admin
|
||||
#backend_port=10001
|
||||
#admin_jid=admin@localhost
|
||||
admin_password=test
|
||||
#cert=server.pfx #patch to PKCS#12 certificate
|
||||
#cert_password=test #password to that certificate if any
|
||||
users_per_backend=10
|
||||
#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
|
||||
backend=/home/hanzz/code/libtransport/backends/smstools3/spectrum2_smstools3_backend
|
||||
#backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe
|
||||
#backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend
|
||||
#backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
|
||||
backend=../..//backends/libpurple/spectrum2_libpurple_backend
|
||||
#backend=../../backends/template/template_backend.py
|
||||
protocol=prpl-jabber
|
||||
#protocol=prpl-msn
|
||||
protocol=any
|
||||
#protocol=any
|
||||
#protocol=prpl-icq
|
||||
irc_server=irc.freenode.org
|
||||
working_dir=./
|
||||
|
||||
[backend]
|
||||
#default_avatar=catmelonhead.jpg
|
||||
#no_vcard_fetch=true
|
||||
incoming_dir=/var/spool/sms/incoming
|
||||
|
||||
[logging]
|
||||
#config=logging.cfg # log4cxx/log4j logging configuration file
|
||||
#backend_config=/home/hanzz/code/libtransport/spectrum/src/backend-logging.cfg # log4cxx/log4j logging configuration file for backends
|
||||
|
||||
[database]
|
||||
#type = sqlite3 # or "none" without database backend
|
||||
#database = test.sql
|
||||
#prefix=icq
|
||||
type = mysql # or "none" without database backend.......................................................................................................................
|
||||
database = test
|
||||
prefix=
|
||||
user=root
|
||||
password=yourrootsqlpassword
|
||||
type = none # or "none" without database backend
|
||||
database = test.sql
|
||||
prefix=icq
|
||||
#type = mysql # or "none" without database backend.......................................................................................................................
|
||||
#database = test
|
||||
#prefix=
|
||||
#user=root
|
||||
#password=yourrootsqlpassword
|
||||
#encryption_key=hanzzik
|
||||
|
|
BIN
spectrum/src/server.p12
Normal file
BIN
spectrum/src/server.p12
Normal file
Binary file not shown.
|
@ -310,12 +310,12 @@ static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactorie
|
|||
std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
}
|
||||
|
||||
if (CONFIG_STRING(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
|
||||
if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
|
||||
std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
|
||||
}
|
||||
|
||||
finished++;
|
||||
Swift::Client *client = new Swift::Client(CONFIG_STRING(&cfg, "service.admin_jid"), CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
|
||||
Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], 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")));
|
||||
|
|
|
@ -68,6 +68,10 @@ class ManagerConfig {
|
|||
return m_variables[key];
|
||||
}
|
||||
|
||||
bool hasKey(const std::string &key) {
|
||||
return m_variables.find(key) != m_variables.end();
|
||||
}
|
||||
|
||||
/// Returns path to config file from which data were loaded.
|
||||
const std::string &getManagerConfigFile() { return m_file; }
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB_RECURSE SWIFTEN_SRC ../include/Swiften/*.cpp)
|
||||
|
||||
# Build without openssl on windows
|
||||
if (WIN32)
|
||||
string(REGEX REPLACE "[^;]+;?/OpenSSL/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}")
|
||||
endif()
|
||||
|
||||
FILE(GLOB HEADERS ../include/transport/*.h)
|
||||
|
||||
if (CPPUNIT_FOUND)
|
||||
|
@ -35,16 +41,16 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
|||
endif()
|
||||
|
||||
if (WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else (WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
|
||||
endif(WIN32)
|
||||
|
||||
SET_TARGET_PROPERTIES(transport PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS transport LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)
|
||||
INSTALL(TARGETS transport LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
|
||||
|
||||
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_BINARY_DIR}/transport.pc")
|
||||
#INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/transport.pc" DESTINATION lib/pkgconfig)
|
||||
|
|
|
@ -26,16 +26,14 @@
|
|||
#include "transport/rostermanager.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/networkpluginserver.h"
|
||||
#include "transport/logging.h"
|
||||
#include "storageresponder.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include "transport/memoryusage.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("AdminInterface");
|
||||
DEFINE_LOGGER(logger, "AdminInterface");
|
||||
|
||||
static std::string getArg(const std::string &body) {
|
||||
std::string ret;
|
||||
|
@ -61,11 +59,13 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
if (!message->getTo().getNode().empty())
|
||||
return;
|
||||
|
||||
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;
|
||||
std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid");
|
||||
if (std::find(x.begin(), x.end(), message->getFrom().toBare().toString()) == x.end()) {
|
||||
LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().toBare().toString());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Ignore empty messages
|
||||
if (message->getBody().empty()) {
|
||||
return;
|
||||
|
@ -112,7 +112,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
for (std::list <NetworkPluginServer::Backend *>::const_iterator b = backends.begin(); b != backends.end(); b++) {
|
||||
NetworkPluginServer::Backend *backend = *b;
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id);
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + ")";
|
||||
lst += backend->acceptUsers ? "" : " - not-accepting";
|
||||
lst += backend->longRun ? " - long-running" : "";
|
||||
lst += ":\n";
|
||||
|
@ -204,7 +204,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
int id = 1;
|
||||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) {
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ": " + boost::lexical_cast<std::string>(backend->res) + "\n";
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + "): " + boost::lexical_cast<std::string>(backend->res) + "\n";
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
int id = 1;
|
||||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) {
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ": " + boost::lexical_cast<std::string>(backend->shared) + "\n";
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + "): " + boost::lexical_cast<std::string>(backend->shared) + "\n";
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
int id = 1;
|
||||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) {
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ": " + boost::lexical_cast<std::string>(backend->res - backend->shared) + "\n";
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + "): " + boost::lexical_cast<std::string>(backend->res - backend->shared) + "\n";
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -238,10 +238,10 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
const std::list <NetworkPluginServer::Backend *> &backends = m_server->getBackends();
|
||||
BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) {
|
||||
if (backend->users.size() == 0) {
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ": 0\n";
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + "): 0\n";
|
||||
}
|
||||
else {
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + ": " + boost::lexical_cast<std::string>((backend->res - backend->init_res) / backend->users.size()) + "\n";
|
||||
lst += "Backend " + boost::lexical_cast<std::string>(id) + " (ID=" + backend->id + "): " + boost::lexical_cast<std::string>((backend->res - backend->init_res) / backend->users.size()) + "\n";
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
@ -251,6 +251,22 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
else if (message->getBody() == "collect_backend") {
|
||||
m_server->collectBackend();
|
||||
}
|
||||
else if (message->getBody() == "crashed_backends") {
|
||||
std::string lst;
|
||||
const std::vector<std::string> &backends = m_server->getCrashedBackends();
|
||||
BOOST_FOREACH(const std::string &backend, backends) {
|
||||
lst += backend + "\n";
|
||||
}
|
||||
message->setBody(lst);
|
||||
}
|
||||
else if (message->getBody() == "messages_from_xmpp") {
|
||||
int msgCount = m_userManager->getMessagesToBackend();
|
||||
message->setBody(boost::lexical_cast<std::string>(msgCount));
|
||||
}
|
||||
else if (message->getBody() == "messages_to_xmpp") {
|
||||
int msgCount = m_userManager->getMessagesToXMPP();
|
||||
message->setBody(boost::lexical_cast<std::string>(msgCount));
|
||||
}
|
||||
else if (message->getBody().find("help") == 0) {
|
||||
std::string help;
|
||||
help += "General:\n";
|
||||
|
@ -261,8 +277,12 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
|
|||
help += " online_users_count - number of online users\n";
|
||||
help += " online_users_per_backend - shows online users per backends\n";
|
||||
help += " has_online_user <bare_JID> - returns 1 if user is online\n";
|
||||
help += "Messages:\n";
|
||||
help += " messages_from_xmpp - get number of messages received from XMPP users\n";
|
||||
help += " messages_to_xmpp - get number of messages sent to XMPP users\n";
|
||||
help += "Backends:\n";
|
||||
help += " backends_count - number of active backends\n";
|
||||
help += " crashed_backends - returns IDs of crashed backends\n";
|
||||
help += "Memory:\n";
|
||||
help += " res_memory - Total RESident memory spectrum2 and its backends use in KB\n";
|
||||
help += " shr_memory - Total SHaRed memory spectrum2 backends share together in KB\n";
|
||||
|
|
|
@ -29,16 +29,14 @@
|
|||
#include "transport/user.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/rostermanager.h"
|
||||
#include "log4cxx/logger.h"
|
||||
|
||||
using namespace log4cxx;
|
||||
#include "transport/logging.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("BlockResponder");
|
||||
DEFINE_LOGGER(logger, "BlockResponder");
|
||||
|
||||
BlockResponder::BlockResponder(Swift::IQRouter *router, UserManager *userManager) : Swift::SetResponder<BlockPayload>(router) {
|
||||
m_userManager = userManager;
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
namespace Transport {
|
||||
|
||||
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
|
||||
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager),
|
||||
m_subscription(Ask) {
|
||||
// m_rosterManager->setBuddy(this);
|
||||
}
|
||||
|
||||
|
@ -64,12 +65,12 @@ const Swift::JID &Buddy::getJID() {
|
|||
return m_jid;
|
||||
}
|
||||
|
||||
void Buddy::setSubscription(const std::string &subscription) {
|
||||
// m_subscription = subscription;
|
||||
void Buddy::setSubscription(Subscription subscription) {
|
||||
m_subscription = subscription;
|
||||
}
|
||||
|
||||
const std::string Buddy::getSubscription() {
|
||||
return "ask";
|
||||
Buddy::Subscription Buddy::getSubscription() {
|
||||
return m_subscription;
|
||||
}
|
||||
|
||||
Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) {
|
||||
|
@ -147,7 +148,6 @@ void Buddy::handleBuddyChanged() {
|
|||
if (presence) {
|
||||
m_rosterManager->getUser()->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
m_rosterManager->handleBuddyChanged(this);
|
||||
}
|
||||
|
||||
void Buddy::handleVCardReceived(const std::string &id, Swift::VCard::ref vcard) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/util.h"
|
||||
#include <fstream>
|
||||
#ifdef _MSC_VER
|
||||
#include <direct.h>
|
||||
|
@ -28,9 +27,23 @@
|
|||
#define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
|
||||
#include "iostream"
|
||||
#include "boost/version.hpp"
|
||||
|
||||
#define BOOST_MAJOR_VERSION BOOST_VERSION / 100000
|
||||
#define BOOST_MINOR_VERSION BOOST_VERSION / 100 % 1000
|
||||
|
||||
using namespace boost::program_options;
|
||||
|
||||
namespace Transport {
|
||||
static int getRandomPort(const std::string &s) {
|
||||
unsigned long r = 0;
|
||||
BOOST_FOREACH(char c, s) {
|
||||
r += (int) c;
|
||||
}
|
||||
srand(time(NULL) + r);
|
||||
return 30000 + rand() % 10000;
|
||||
}
|
||||
|
||||
bool Config::load(const std::string &configfile, boost::program_options::options_description &opts, const std::string &jid) {
|
||||
std::ifstream ifs(configfile.c_str());
|
||||
|
@ -63,14 +76,14 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("service.protocol", value<std::string>()->default_value(""), "Protocol")
|
||||
("service.pidfile", value<std::string>()->default_value("/var/run/spectrum2/$jid.pid"), "Full path to pid file")
|
||||
("service.working_dir", value<std::string>()->default_value("/var/lib/spectrum2/$jid"), "Working dir")
|
||||
("service.allowed_servers", value<std::string>()->default_value(""), "Only users from these servers can connect")
|
||||
("service.allowed_servers", value<std::vector<std::string> >()->multitoken(), "Only users from these servers can connect")
|
||||
("service.server_mode", value<bool>()->default_value(false), "True if Spectrum should behave as server")
|
||||
("service.users_per_backend", value<int>()->default_value(100), "Number of users per one legacy network backend")
|
||||
("service.backend_host", value<std::string>()->default_value("localhost"), "Host to bind backend server to")
|
||||
("service.backend_port", value<std::string>()->default_value("0"), "Port to bind backend server to")
|
||||
("service.cert", value<std::string>()->default_value(""), "PKCS#12 Certificate.")
|
||||
("service.cert_password", value<std::string>()->default_value(""), "PKCS#12 Certificate password.")
|
||||
("service.admin_jid", value<std::string>()->default_value(""), "Administrator jid.")
|
||||
("service.admin_jid", value<std::vector<std::string> >()->multitoken(), "Administrator jid.")
|
||||
("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
|
||||
("service.reuse_old_backends", value<bool>()->default_value(true), "True if Spectrum should use old backends which were full in the past.")
|
||||
("service.idle_reconnect_time", value<int>()->default_value(0), "Time in seconds after which idle users are reconnected to let their backend die.")
|
||||
|
@ -86,11 +99,14 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("registration.instructions", value<std::string>()->default_value("Enter your legacy network username and password."), "Instructions showed to user in registration form")
|
||||
("registration.username_label", value<std::string>()->default_value("Legacy network username:"), "Label for username field")
|
||||
("registration.username_mask", value<std::string>()->default_value(""), "Username mask")
|
||||
("registration.auto_register", value<bool>()->default_value(false), "Register new user automatically when the presence arrives.")
|
||||
("registration.encoding", value<std::string>()->default_value("utf8"), "Default encoding in registration form")
|
||||
("registration.require_local_account", value<bool>()->default_value(false), "True if users have to have a local account to register to this transport from remote servers.")
|
||||
("registration.local_username_label", value<std::string>()->default_value("Local username:"), "Label for local usernme field")
|
||||
("registration.local_account_server", value<std::string>()->default_value("localhost"), "The server on which the local accounts will be checked for validity")
|
||||
("registration.local_account_server_timeout", value<int>()->default_value(10000), "Timeout when checking local user on local_account_server (msecs)")
|
||||
("gateway_responder.prompt", value<std::string>()->default_value("Contact ID"), "Value of <prompt> </promt> field")
|
||||
("gateway_responder.label", value<std::string>()->default_value("Enter legacy network contact ID."), "Label for add contact ID field")
|
||||
("database.type", value<std::string>()->default_value("none"), "Database type.")
|
||||
("database.database", value<std::string>()->default_value("/var/lib/spectrum2/$jid/database.sql"), "Database used to store data")
|
||||
("database.server", value<std::string>()->default_value("localhost"), "Database server.")
|
||||
|
@ -106,6 +122,13 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("backend.no_vcard_fetch", value<bool>()->default_value(false), "True if VCards for buddies should not be fetched. Only avatars will be forwarded.")
|
||||
;
|
||||
|
||||
// Load configs passed by command line
|
||||
if (m_argc != 0 && m_argv) {
|
||||
basic_command_line_parser<char> parser = command_line_parser(m_argc, m_argv).options(opts).allow_unregistered();
|
||||
parsed_options parsed = parser.run();
|
||||
store(parsed, m_variables);
|
||||
}
|
||||
|
||||
parsed_options parsed = parse_config_file(ifs, opts, true);
|
||||
|
||||
bool found_working = false;
|
||||
|
@ -126,7 +149,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
else if (opt.string_key == "service.backend_port") {
|
||||
found_backend_port = true;
|
||||
if (opt.value[0] == "0") {
|
||||
opt.value[0] = boost::lexical_cast<std::string>(Util::getRandomPort(_jid.empty() ? jid : _jid));
|
||||
opt.value[0] = boost::lexical_cast<std::string>(getRandomPort(_jid.empty() ? jid : _jid));
|
||||
}
|
||||
}
|
||||
else if (opt.string_key == "service.working_dir") {
|
||||
|
@ -152,7 +175,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
}
|
||||
if (!found_backend_port) {
|
||||
std::vector<std::string> value;
|
||||
std::string p = boost::lexical_cast<std::string>(Util::getRandomPort(_jid.empty() ? jid : _jid));
|
||||
std::string p = boost::lexical_cast<std::string>(getRandomPort(_jid.empty() ? jid : _jid));
|
||||
value.push_back(p);
|
||||
parsed.options.push_back(boost::program_options::basic_option<char>("service.backend_port", value));
|
||||
}
|
||||
|
@ -185,8 +208,17 @@ bool Config::load(std::istream &ifs) {
|
|||
}
|
||||
|
||||
bool Config::load(const std::string &configfile, const std::string &jid) {
|
||||
options_description opts("Transport options");
|
||||
return load(configfile, opts, jid);
|
||||
try {
|
||||
options_description opts("Transport options");
|
||||
return load(configfile, opts, jid);
|
||||
} catch ( const boost::program_options::multiple_occurrences& e ) {
|
||||
#if (BOOST_MAJOR_VERSION >= 1 && BOOST_MINOR_VERSION >= 42)
|
||||
std::cerr << configfile << " parsing error: " << e.what() << " from option: " << e.get_option_name() << std::endl;
|
||||
#else
|
||||
std::cerr << configfile << " parsing error: " << e.what() << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Config::reload() {
|
||||
|
|
|
@ -25,14 +25,9 @@
|
|||
#include "transport/transport.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/rostermanager.h"
|
||||
#include "log4cxx/logger.h"
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
// static LoggerPtr logger = Logger::getLogger("Conversation");
|
||||
|
||||
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
|
||||
m_legacyName = legacyName;
|
||||
m_conversationManager->addConversation(this);
|
||||
|
|
|
@ -24,16 +24,14 @@
|
|||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/Roster/SetRosterRequest.h"
|
||||
#include "Swiften/Elements/RosterPayload.h"
|
||||
#include "Swiften/Elements/RosterItemPayload.h"
|
||||
#include "log4cxx/logger.h"
|
||||
|
||||
using namespace log4cxx;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("ConversationManager");
|
||||
DEFINE_LOGGER(logger, "ConversationManager");
|
||||
|
||||
ConversationManager::ConversationManager(User *user, Component *component){
|
||||
m_user = user;
|
||||
|
|
|
@ -88,11 +88,15 @@ bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::J
|
|||
|
||||
// presence for transport
|
||||
if (to.getNode().empty()) {
|
||||
sendResponse(from, id, boost::shared_ptr<DiscoInfo>(new DiscoInfo(m_transportInfo)));
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, id, res);
|
||||
}
|
||||
// presence for buddy
|
||||
else {
|
||||
sendResponse(from, to, id, boost::shared_ptr<DiscoInfo>(new DiscoInfo(m_buddyInfo)));
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_buddyInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,11 @@
|
|||
#include "transport/usermanager.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "log4cxx/logger.h"
|
||||
|
||||
using namespace log4cxx;
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
static LoggerPtr logger = Logger::getLogger("FileTransferManager");
|
||||
DEFINE_LOGGER(logger, "FileTransferManager");
|
||||
|
||||
FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) {
|
||||
m_component = component;
|
||||
|
|
63
src/gatewayresponder.cpp
Normal file
63
src/gatewayresponder.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/gatewayresponder.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/bind.hpp>
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/RawXMLPayload.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "GatewayResponder");
|
||||
|
||||
GatewayResponder::GatewayResponder(Swift::IQRouter *router, UserManager *userManager) : Swift::Responder<GatewayPayload>(router) {
|
||||
m_userManager = userManager;
|
||||
}
|
||||
|
||||
GatewayResponder::~GatewayResponder() {
|
||||
}
|
||||
|
||||
bool GatewayResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload) {
|
||||
std::string prompt = CONFIG_STRING(m_userManager->getComponent()->getConfig(), "gateway_responder.prompt");
|
||||
std::string label = CONFIG_STRING(m_userManager->getComponent()->getConfig(), "gateway_responder.label");
|
||||
sendResponse(from, id, boost::shared_ptr<GatewayPayload>(new GatewayPayload(Swift::JID(), label, prompt)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GatewayResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload) {
|
||||
std::string prompt = payload->getPrompt();
|
||||
std::string escaped = Swift::JID::getEscapedNode(prompt);
|
||||
std::string jid = escaped + "@" + m_userManager->getComponent()->getJID().toBare().toString();
|
||||
|
||||
sendResponse(from, id, boost::shared_ptr<GatewayPayload>(new GatewayPayload(jid)));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,11 +32,11 @@ LocalBuddy::~LocalBuddy() {
|
|||
}
|
||||
|
||||
void LocalBuddy::setAlias(const std::string &alias) {
|
||||
if (m_firstSet) {
|
||||
m_firstSet = false;
|
||||
m_alias = alias;
|
||||
return;
|
||||
}
|
||||
// if (m_firstSet) {
|
||||
// m_firstSet = false;
|
||||
// m_alias = alias;
|
||||
// return;
|
||||
// }
|
||||
bool changed = m_alias != alias;
|
||||
m_alias = alias;
|
||||
|
||||
|
@ -48,4 +48,24 @@ void LocalBuddy::setAlias(const std::string &alias) {
|
|||
}
|
||||
}
|
||||
|
||||
void LocalBuddy::setGroups(const std::vector<std::string> &groups) {
|
||||
bool changed = m_groups.size() != groups.size();
|
||||
if (!changed) {
|
||||
for (int i = 0; i != m_groups.size(); i++) {
|
||||
if (m_groups[i] != groups[i]) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_groups = groups;
|
||||
if (changed) {
|
||||
if (getRosterManager()->getUser()->getComponent()->inServerMode() || getRosterManager()->isRemoteRosterSupported()) {
|
||||
getRosterManager()->sendBuddyRosterPush(this);
|
||||
}
|
||||
getRosterManager()->storeBuddy(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue