Changeset - 9331f56079ad
[Not reviewed]
Merge
4 60 58
Daniel Henninger - 13 years ago 2012-05-07 17:18:54
daniel@vorpalcloud.org
Merge remote-tracking branch 'upstream/master'
121 files changed with 4090 insertions and 2775 deletions:
ChangeLog
59
1
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
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)
ChangeLog
Show inline comments
 
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.
backends/CMakeLists.txt
Show inline comments
 
@@ -9,6 +9,8 @@ if (PROTOBUF_FOUND)
 

	
 
	ADD_SUBDIRECTORY(smstools3)
 

	
 
	ADD_SUBDIRECTORY(template)
 

	
 
if (NOT WIN32)
 
	ADD_SUBDIRECTORY(frotz)
 
	if (${LIBDBUSGLIB_FOUND})
backends/libcommuni/ircnetworkplugin.cpp
Show inline comments
 
@@ -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;
 

	
backends/libcommuni/main.cpp
Show inline comments
 
@@ -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;
 

	
backends/libcommuni/session.cpp
Show inline comments
 
@@ -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);
backends/libcommuni/singleircnetworkplugin.cpp
Show inline comments
 
#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;
 
}
backends/libpurple/gen_dynamic_purple.py
Show inline comments
 
new file 100644
 
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()
backends/libpurple/geventloop.cpp
Show inline comments
 
@@ -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;
backends/libpurple/main.cpp
Show inline comments
 
#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
 

	
 
#include "purple_defs.h"
 

	
 
DEFINE_LOGGER(logger_libpurple, "libpurple");
 
DEFINE_LOGGER(logger, "backend");
 

	
 
static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple");
 
static LoggerPtr logger = log4cxx::Logger::getLogger("backend");
 
int m_sock;
 
int main_socket;
 
static int writeInput;
 

	
 
using namespace Transport;
 
@@ -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, "&lt;", 4) ||
 
		!g_ascii_strncasecmp(c, "&gt;", 4) ||
 
		!g_ascii_strncasecmp(c, "&quot;", 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, "&lt;", 4) ||
 
				                                       !g_ascii_strncasecmp(t - 3, "&gt;", 4))) ||
 
				                     (t > (text+4) && (!g_ascii_strncasecmp(t - 5, "&quot;", 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;
backends/libpurple/purple_defs.cpp
Show inline comments
 
new file 100644
 
#include "purple_defs.h"
 
bool resolvePurpleFunctions() {
 
	return true;
 
}
 

	
backends/libpurple/purple_defs.h
Show inline comments
 
new file 100644
 
#pragma once
 

	
 
bool resolvePurpleFunctions();
backends/libpurple/utils.cpp
Show inline comments
 
new file 100644
 
/**
 
 * 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;
 
}
backends/libpurple/utils.h
Show inline comments
 
new file 100644
 
/**
 
 * 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);
backends/skype/main.cpp
Show inline comments
 
@@ -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);
 

	
 
		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 (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");
 

	
 
			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);
 

	
 
			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);
 
			GET_PROPERTY(body, "CHATMESSAGE", cmd[1], "BODY");
 
			GET_PROPERTY(from_handle, "CHATMESSAGE", cmd[1], "FROM_HANDLE");
 

	
 
// 			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);
 

	
backends/smstools3/main.cpp
Show inline comments
 
@@ -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;
 
		}
 
	}
 
#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;
 
	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") == "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;
backends/template/CMakeLists.txt
Show inline comments
 
new file 100644
 
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)
 
backends/template/README
Show inline comments
 
new file 100644
 
This is just template for creating new generic spectrum2 backends. It does not do anything!
 
\ No newline at end of file
backends/template/main.cpp
Show inline comments
 
new file 100644
 
// 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;
 
}
backends/template/template_backend.py
Show inline comments
 
new file 100755
 
#!/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()
cmake_modules/CommuniConfig.cmake
Show inline comments
 
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 )
docs/Doxyfile
Show inline comments
 
deleted file
include/Swiften/Elements/GatewayPayload.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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) {
 
		
 
	}
 

	
 
}
include/Swiften/Elements/GatewayPayload.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Elements/PubSubItem.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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() {
 
}
 

	
 
}
include/Swiften/Elements/PubSubItem.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Elements/PubSubPayload.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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() {
 
}
 

	
 
}
include/Swiften/Elements/PubSubPayload.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Elements/PubSubPublishPayload.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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) {
 
		
 
	}
 

	
 
}
include/Swiften/Elements/PubSubPublishPayload.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Elements/PubSubSubscribePayload.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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) {
 
		
 
	}
 

	
 
}
include/Swiften/Elements/PubSubSubscribePayload.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Elements/PubSubSubscriptionPayload.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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) {
 
		
 
	}
 

	
 
}
include/Swiften/Elements/PubSubSubscriptionPayload.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Network/DummyNetworkFactories.cpp
Show inline comments
 
@@ -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() {
include/Swiften/Network/DummyNetworkFactories.h
Show inline comments
 
@@ -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;
 
	};
 
}
include/Swiften/Parser/PayloadParsers/GatewayPayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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());
 
		}
 
	}
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/GatewayPayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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);
 
	};
 
}
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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());
 
		}
 
	}
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/MUCPayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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);
 
	};
 
}
include/Swiften/Parser/PayloadParsers/PubSubItemParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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));
 
	}
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/PubSubItemParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Parser/PayloadParsers/PubSubPayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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));
 
	}
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/PubSubPayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Parser/PayloadParsers/PubSubPublishPayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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));
 
	}
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/PubSubPublishPayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Parser/PayloadParsers/PubSubSubscribePayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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);
 
	}
 

	
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/PubSubSubscribePayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Parser/PayloadParsers/PubSubSubscriptionPayloadParser.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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);
 
	}
 

	
 
}
 

	
 
}
include/Swiften/Parser/PayloadParsers/PubSubSubscriptionPayloadParser.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubItemSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubItemSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubPayloadSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubPayloadSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubPublishPayloadSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubPublishPayloadSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubSubscribePayloadSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubSubscribePayloadSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubSubscriptionPayloadSerializer.cpp
Show inline comments
 
new file 100644
 
/*
 
 * 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();
 
}
 

	
 
}
include/Swiften/Serializer/PayloadSerializers/PubSubSubscriptionPayloadSerializer.h
Show inline comments
 
new file 100644
 
/*
 
 * 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;
 
	};
 
}
include/Swiften/TLS/OpenSSL/OpenSSLServerContext.cpp
Show inline comments
 
@@ -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"
include/transport/CMakeLists.txt
Show inline comments
 
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)
include/transport/buddy.h
Show inline comments
 
@@ -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;
 
};
 

	
 
}
include/transport/config.h
Show inline comments
 
@@ -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;
include/transport/gatewayresponder.h
Show inline comments
 
new file 100644
 
/**
 
 * 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;
 
};
 

	
 
}
 
\ No newline at end of file
include/transport/localbuddy.h
Show inline comments
 
@@ -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;
include/transport/logging.h
Show inline comments
 
new file 100644
 
/**
 
 * 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();
 

	
 
}
 

	
 
}
include/transport/memoryusage.h
Show inline comments
 
@@ -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
 

	
 
}
 
\ No newline at end of file
include/transport/networkplugin.h
Show inline comments
 
@@ -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) {}
include/transport/networkpluginserver.h
Show inline comments
 
@@ -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;
 
};
 

	
 
}
include/transport/protocol.proto
Show inline comments
 
@@ -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;
include/transport/storagebackend.h
Show inline comments
 
@@ -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;
 

	
include/transport/transport.h
Show inline comments
 
@@ -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);
include/transport/usermanager.h
Show inline comments
 
@@ -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;
 
};
 

	
munin/spectrum2_
Show inline comments
 
new file 100755
 
#!/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);
 
}
plugin/CMakeLists.txt
Show inline comments
 
ADD_SUBDIRECTORY(src)
 
ADD_SUBDIRECTORY(cpp)
 
ADD_SUBDIRECTORY(python)
plugin/cpp/CMakeLists.txt
Show inline comments
 
new file 100644
 
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)
plugin/cpp/networkplugin.cpp
Show inline comments
 
file renamed from plugin/src/networkplugin.cpp to plugin/cpp/networkplugin.cpp
 
@@ -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);
plugin/python/CMakeLists.txt
Show inline comments
 
new file 100644
 
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()
 
 
 
 
plugin/python/NetworkPlugin.py
Show inline comments
 
new file 100644
 
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
 

	
plugin/src/CMakeLists.txt
Show inline comments
 
deleted file
plugin/src/pbnetwork.proto
Show inline comments
 
deleted file
spectrum/src/main.cpp
Show inline comments
 
@@ -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;
 
		}
 
	}
 
#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;
 
	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") == "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;
 
}
spectrum/src/sample.cfg
Show inline comments
 
@@ -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
spectrum/src/server.p12
Show inline comments
 
new file 100644
 
binary diff not shown
spectrum_manager/src/main.cpp
Show inline comments
 
@@ -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")));
spectrum_manager/src/managerconfig.h
Show inline comments
 
@@ -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; }
 

	
src/CMakeLists.txt
Show inline comments
 
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)
src/admininterface.cpp
Show inline comments
 
@@ -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";
src/blockresponder.cpp
Show inline comments
 
@@ -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;
src/buddy.cpp
Show inline comments
 
@@ -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) {
src/config.cpp
Show inline comments
 
@@ -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() {
src/conversation.cpp
Show inline comments
 
@@ -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);
src/conversationmanager.cpp
Show inline comments
 
@@ -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;
src/discoinforesponder.cpp
Show inline comments
 
@@ -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;
 
}
src/filetransfermanager.cpp
Show inline comments
 
@@ -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;
src/gatewayresponder.cpp
Show inline comments
 
new file 100644
 
/**
 
 * 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;
 
}
 

	
 
}
src/localbuddy.cpp
Show inline comments
 
@@ -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);
 
	}
 
}
 

	
 
}
src/logging.cpp
Show inline comments
 
new file 100644
 
/**
 
 * 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 "transport/logging.h"
 
#include "transport/config.h"
 
#include <boost/foreach.hpp>
 
#include <iostream>
 
#include <iterator>
 
#include <algorithm>
 

	
 

	
 
#include <boost/filesystem.hpp>
 
#include <boost/algorithm/string.hpp>
 

	
 
#ifndef WIN32
 
#include "sys/signal.h"
 
#include <pwd.h>
 
#include <grp.h>
 
#include <sys/resource.h>
 
#include "libgen.h"
 
#else
 
#include <windows.h>
 
#include <process.h>
 
#define getpid _getpid
 
#endif
 

	
 
using namespace boost::filesystem;
 

	
 

	
 
namespace Transport {
 

	
 
namespace Logging {
 

	
 
#ifdef WITH_LOG4CXX
 
using namespace log4cxx;
 
static LoggerPtr root;
 

	
 
static void initLogging(Config *config, std::string key) {
 
	if (CONFIG_STRING(config, key).empty()) {
 
		root = log4cxx::Logger::getRootLogger();
 
#ifdef WIN32
 
		root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n")));
 
#else
 
		root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
 
#endif
 
	}
 
	else {
 
		log4cxx::helpers::Properties p;
 

	
 
		log4cxx::helpers::FileInputStream *istream = NULL;
 
		try {
 
			istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(config, key));
 
		}
 
		catch(log4cxx::helpers::IOException &ex) {
 
			std::cerr << "Can't create FileInputStream logger instance: " << ex.what() << "\n";
 
		}
 
		catch (...) {
 
			std::cerr << "Can't create FileInputStream logger instance\n";
 
		}
 

	
 
		if (!istream) {
 
			return;
 
		}
 

	
 
		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";
 
			}
 

	
 
#ifndef WIN32
 
			if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) {
 
				struct group *gr;
 
				if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) {
 
					std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n";
 
				}
 
				struct passwd *pw;
 
				if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) {
 
					std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n";
 
				}
 
				chown(dir.c_str(), pw->pw_uid, gr->gr_gid);
 
			}
 

	
 
#endif
 
		}
 

	
 
		log4cxx::PropertyConfigurator::configure(p);
 
	}
 
}
 

	
 
void initBackendLogging(Config *config) {
 
	initLogging(config, "logging.backend_config");
 
}
 

	
 
void initMainLogging(Config *config) {
 
	initLogging(config, "logging.config");
 
}
 

	
 
void shutdownLogging() {
 
	log4cxx::LogManager::shutdown();
 
}
 

	
 
#else /* WITH_LOG4CXX */
 
void initBackendLogging(Config */*config*/) {
 
}
 

	
 
void initMainLogging(Config */*config*/) {
 
}
 

	
 
void shutdownLogging() {
 
	
 
}
 
#endif /* WITH_LOG4CXX */
 

	
 
}
 

	
 
}
src/memoryreadbytestream.cpp
Show inline comments
 
@@ -19,11 +19,8 @@
 
 */
 

	
 
#include "transport/memoryreadbytestream.h"
 
#include "log4cxx/logger.h"
 
#include <boost/foreach.hpp>
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 
	
 
MemoryReadBytestream::MemoryReadBytestream(unsigned long size) {
src/memoryusage.cpp
Show inline comments
 
@@ -25,6 +25,7 @@
 
#include <sstream>
 
#include <fstream>
 
#include <algorithm>
 
#include <boost/lexical_cast.hpp>
 
#ifndef WIN32
 
#include <sys/param.h>
 
#endif
 
@@ -41,13 +42,18 @@ namespace Transport {
 

	
 
#ifndef WIN32
 
#ifdef BSD
 
void process_mem_usage(double& vm_usage, double& resident_set) {
 
void process_mem_usage(double& vm_usage, double& resident_set, pid_t pid) {
 
	int mib[4];
 
	size_t size;
 
	mib[0] = CTL_KERN;
 
	mib[1] = KERN_PROC;
 
	mib[2] = KERN_PROC_PID;
 
	mib[3] = getpid();
 
	if (pid == 0) {
 
		mib[3] = getpid();
 
	}
 
	else {
 
		mib[3] = pid;
 
	}
 
	struct kinfo_proc proc;
 

	
 
	size = sizeof(struct kinfo_proc);
 
@@ -75,7 +81,7 @@ void process_mem_usage(double& vm_usage, double& resident_set) {
 
	vm_usage = (double) proc.ki_size;
 
}
 
#else /* BSD */
 
void process_mem_usage(double& shared, double& resident_set) {
 
void process_mem_usage(double& shared, double& resident_set, pid_t pid) {
 
	using std::ios_base;
 
	using std::ifstream;
 
	using std::string;
 
@@ -84,8 +90,11 @@ void process_mem_usage(double& shared, double& resident_set) {
 
	resident_set = 0.0;
 

	
 
	// 'file' stat seems to give the most reliable results
 
	//
 
	ifstream stat_stream("/proc/self/statm",ios_base::in);
 
	std::string f = "/proc/self/statm";
 
	if (pid != 0) {
 
		f = "/proc/" + boost::lexical_cast<std::string>(pid) + "/statm";
 
	}
 
	ifstream stat_stream(f.c_str(), ios_base::in);
 
	if (!stat_stream.is_open()) {
 
		shared = 0;
 
		resident_set = 0;
 
@@ -94,7 +103,7 @@ void process_mem_usage(double& shared, double& resident_set) {
 

	
 
	// dummy vars for leading entries in stat that we don't care about
 
	//
 
	string pid, comm, state, ppid, pgrp, session, tty_nr;
 
	string pid1, comm, state, ppid, pgrp, session, tty_nr;
 
	string tpgid, flags, minflt, cminflt, majflt, cmajflt;
 
	string utime, stime, cutime, cstime, priority, nice;
 
	string O, itrealvalue, starttime;
src/mysqlbackend.cpp
Show inline comments
 
@@ -22,10 +22,8 @@
 

	
 
#include "transport/mysqlbackend.h"
 
#include "transport/util.h"
 
#include "transport/logging.h"
 
#include <boost/bind.hpp>
 
#include "log4cxx/logger.h"
 

	
 
using namespace log4cxx;
 

	
 
#define MYSQL_DB_VERSION 2
 
#define CHECK_DB_RESPONSE(stmt) \
 
@@ -92,7 +90,7 @@ using namespace boost;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("MySQLBackend");
 
DEFINE_LOGGER(logger, "MySQLBackend");
 
static bool exec_ok;
 

	
 
MySQLBackend::Statement::Statement(MYSQL *conn, const std::string &format, const std::string &statement) {
src/networkpluginserver.cpp
Show inline comments
 
@@ -31,6 +31,7 @@
 
#include "transport/vcardresponder.h"
 
#include "transport/rosterresponder.h"
 
#include "transport/memoryreadbytestream.h"
 
#include "transport/logging.h"
 
#include "blockresponder.h"
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
@@ -41,27 +42,25 @@
 
#include "Swiften/Elements/InvisiblePayload.h"
 
#include "Swiften/Elements/SpectrumErrorPayload.h"
 
#include "transport/protocol.pb.h"
 
#include "log4cxx/logger.h"
 

	
 
#include <Swiften/FileTransfer/ReadBytestream.h>
 
#include <Swiften/Elements/StreamInitiationFileInfo.h>
 

	
 
#ifdef _WIN32
 
#include "windows.h"
 
#include <stdint.h>
 
#else
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#include "popt.h"
 
#endif
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static unsigned long backend_id;
 
static unsigned long bytestream_id;
 

	
 
static LoggerPtr logger = Logger::getLogger("NetworkPluginServer");
 
DEFINE_LOGGER(logger, "NetworkPluginServer");
 

	
 
class NetworkConversation : public Conversation {
 
	public:
 
@@ -94,7 +93,12 @@ class NetworkFactory : public Factory {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			if (buddyInfo.subscription == "both") {
 
				buddy->setSubscription(Buddy::Both);
 
			}
 
			else {
 
				buddy->setSubscription(Buddy::Ask);
 
			}
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) (buddyInfo.flags));
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
@@ -159,9 +163,14 @@ static unsigned long exec_(std::string path, const char *host, const char *port,
 
	if ( pid == 0 ) {
 
		setsid();
 
		// child process
 
		exit(execv(argv[0], argv));
 
		errno = 0;
 
		int ret = execv(argv[0], argv);
 
		if (ret == -1) {
 
			exit(errno);
 
		}
 
		exit(0);
 
	} else if ( pid < 0 ) {
 
		// fork failed
 
		LOG4CXX_ERROR(logger, "Fork failed");
 
	}
 
	free(p);
 

	
 
@@ -195,6 +204,7 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
 
	// Set alias only if it's not empty. Backends are allowed to send empty alias if it has
 
	// not changed.
 
	if (!payload.alias().empty()) {
 
		LOG4CXX_INFO(logger, "Setting alias to " << payload.alias() << " " << buddy->getAlias());
 
		buddy->setAlias(payload.alias());
 
	}
 

	
 
@@ -253,12 +263,29 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
 

	
 
	LOG4CXX_INFO(logger, "Listening on host " << CONFIG_STRING(m_config, "service.backend_host") << " port " << CONFIG_STRING(m_config, "service.backend_port"));
 

	
 
	unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
 
	LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
 

	
 
#ifndef _WIN32
 
	// wait if the backend process will still be alive after 1 second
 
	sleep(1);
 
	pid_t result;
 
	int status;
 
	result = waitpid(-1, &status, WNOHANG);
 
	if (result != 0) {
 
		if (WIFEXITED(status)) {
 
			if (WEXITSTATUS(status) != 0) {
 
				LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status) << ", possible error: " << strerror(WEXITSTATUS(status)));
 
			}
 
		}
 
		else {
 
			LOG4CXX_ERROR(logger, "Backend can not be started");
 
		}
 
	}
 

	
 
	signal(SIGCHLD, SigCatcher);
 
#endif
 

	
 
	exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
 
	LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
 
}
 

	
 
NetworkPluginServer::~NetworkPluginServer() {
 
@@ -337,15 +364,19 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
 
}
 

	
 
void NetworkPluginServer::handleSessionFinished(Backend *c) {
 
	LOG4CXX_INFO(logger, "Backend " << c << " disconnected. Current backend count=" << (m_clients.size() - 1));
 
	LOG4CXX_INFO(logger, "Backend " << c << " (ID=" << c->id << ") disconnected. Current backend count=" << (m_clients.size() - 1));
 

	
 
	// This backend will do, so we can't reconnect users to it in User::handleDisconnected call
 
	c->willDie = true;
 

	
 
	// If there are users associated with this backend, it must have crashed, so print error output
 
	// and disconnect users
 
	if (!c->users.empty()) {
 
		m_crashedBackends.push_back(c->id);
 
	}
 

	
 
	for (std::list<User *>::const_iterator it = c->users.begin(); it != c->users.end(); it++) {
 
		LOG4CXX_ERROR(logger, "Backend " << c << " disconnected (probably crashed) with active user " << (*it)->getJID().toString());
 
		LOG4CXX_ERROR(logger, "Backend " << c << " (ID=" << c->id << ") disconnected (probably crashed) with active user " << (*it)->getJID().toString());
 
		(*it)->setData(NULL);
 
		(*it)->handleDisconnected("Internal Server Error, please reconnect.");
 
	}
 
@@ -478,6 +509,8 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) {
 
	if (!user)
 
		return;
 

	
 
	LOG4CXX_INFO(logger, "HANDLE BUDDY CHANGED " << payload.buddyname() << "-" << payload.alias());
 

	
 
	LocalBuddy *buddy = (LocalBuddy *) user->getRosterManager()->getBuddy(payload.buddyname());
 
	if (buddy) {
 
		handleBuddyPayload(buddy, payload);
 
@@ -566,6 +599,7 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool
 

	
 
	// Forward it
 
	conv->handleMessage(msg, payload.nickname());
 
	m_userManager->messageToXMPPSent();
 
}
 

	
 
void NetworkPluginServer::handleAttentionPayload(const std::string &data) {
 
@@ -603,6 +637,7 @@ void NetworkPluginServer::handleStatsPayload(Backend *c, const std::string &data
 
	c->res = payload.res();
 
	c->init_res = payload.init_res();
 
	c->shared = payload.shared();
 
	c->id = payload.id();
 
}
 

	
 
void NetworkPluginServer::handleFTStartPayload(const std::string &data) {
 
@@ -801,8 +836,8 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::Sa
 

	
 
void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const std::string &data) {
 
	// generate header - size of wrapper message
 
	char header[4];
 
	*((int*)(header)) = htonl(data.size());
 
	uint32_t size = htonl(data.size());
 
	char *header = (char *) &size;
 

	
 
	// send header together with wrapper message
 
	c->write(Swift::createSafeByteArray(std::string(header, 4) + data));
 
@@ -849,12 +884,12 @@ void NetworkPluginServer::pingTimeout() {
 
			sendPing((*it));
 
		}
 
		else {
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". PING response not received.");
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << " (ID=" << (*it)->id << "). PING response not received.");
 
			toRemove.push_back(*it);
 
		}
 

	
 
		if ((*it)->users.size() == 0) {
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << ". There are no users.");
 
			LOG4CXX_INFO(logger, "Disconnecting backend " << (*it) << " (ID=" << (*it)->id << "). There are no users.");
 
			toRemove.push_back(*it);
 
		}
 
	}
 
@@ -883,7 +918,7 @@ void NetworkPluginServer::collectBackend() {
 
		if (m_collectTimer) {
 
			m_collectTimer->start();
 
		}
 
		LOG4CXX_INFO(logger, "Backend " << backend << "is set to die");
 
		LOG4CXX_INFO(logger, "Backend " << backend << " (ID=" << backend->id << ") is set to die");
 
		backend->acceptUsers = false;
 
	}
 
}
 
@@ -1080,12 +1115,13 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
 
	}
 
	send(c->connection, message);
 
	c->users.remove(user);
 
// 	if (c->users.size() == 0) {
 
// 		LOG4CXX_INFO(logger, "Disconnecting backend " << c << ". There are no users.");
 

	
 
// 		handleSessionFinished(c);
 
// 		m_clients.erase(user->connection);
 
// 	}
 
	// If backend should handle only one user, it must not accept another one before 
 
	// we kill it, so set up willDie to true
 
	if (c->users.size() == 0 && CONFIG_INT(m_config, "service.users_per_backend") == 1) {
 
		LOG4CXX_INFO(logger, "Backend " << c->id << " will die, because the last user disconnected");
 
		c->willDie = true;
 
	}
 
}
 

	
 
void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &msg) {
 
@@ -1351,7 +1387,7 @@ void NetworkPluginServer::sendPing(Backend *c) {
 
	wrap.SerializeToString(&message);
 

	
 
	if (c->connection) {
 
		LOG4CXX_INFO(logger, "PING to " << c);
 
		LOG4CXX_INFO(logger, "PING to " << c << " (ID=" << c->id << ")");
 
		send(c->connection, message);
 
		c->pongReceived = false;
 
	}
src/rostermanager.cpp
Show inline comments
 
@@ -25,21 +25,19 @@
 
#include "transport/usermanager.h"
 
#include "transport/buddy.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 "Swiften/Elements/RosterItemExchangePayload.h"
 
#include "log4cxx/logger.h"
 
#include <boost/foreach.hpp>
 

	
 
#include <map>
 
#include <iterator>
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("RosterManager");
 
DEFINE_LOGGER(logger, "RosterManager");
 

	
 
RosterManager::RosterManager(User *user, Component *component){
 
	m_rosterStorage = NULL;
 
@@ -110,7 +108,12 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
 
	Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
	Swift::RosterItemPayload item;
 
	item.setJID(buddy->getJID().toBare());
 
	item.setName(buddy->getAlias());
 
	if (buddy->getAlias().empty()) {
 
		item.setName(buddy->getJID().toBare().toString());
 
	}
 
	else {
 
		item.setName(buddy->getAlias());
 
	}
 
	item.setGroups(buddy->getGroups());
 
	item.setSubscription(Swift::RosterItemPayload::Both);
 

	
 
@@ -132,6 +135,11 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
 
		request->send();
 
		m_requests.push_back(request);
 
	}
 

	
 
	if (buddy->getSubscription() != Buddy::Both) {
 
		buddy->setSubscription(Buddy::Both);
 
		handleBuddyChanged(buddy);
 
	}
 
}
 

	
 
void RosterManager::sendBuddySubscribePresence(Buddy *buddy) {
 
@@ -144,9 +152,6 @@ void RosterManager::sendBuddySubscribePresence(Buddy *buddy) {
 
}
 

	
 
void RosterManager::handleBuddyChanged(Buddy *buddy) {
 
	if (m_rosterStorage) {
 
		m_rosterStorage->storeBuddy(buddy);
 
	}
 
}
 

	
 
void RosterManager::setBuddyCallback(Buddy *buddy) {
 
@@ -160,6 +165,11 @@ void RosterManager::setBuddyCallback(Buddy *buddy) {
 
		sendBuddyRosterPush(buddy);
 
	}
 
	else {
 
		if (buddy->getSubscription() == Buddy::Both) {
 
			LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Not forwarding this buddy, because subscription=both");
 
			return;
 
		}
 

	
 
		if (m_supportRemoteRoster) {
 
			sendBuddyRosterPush(buddy);
 
		}
 
@@ -222,7 +232,10 @@ void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPa
 
		if (m_buddies.find(legacyName) != m_buddies.end()) {
 
			continue;
 
		}
 
		std::cout << "LEGACYNAME " << legacyName << "\n";
 

	
 
		if (legacyName.empty()) {
 
			continue;
 
		}
 

	
 
		BuddyInfo buddyInfo;
 
		buddyInfo.id = -1;
 
@@ -230,6 +243,7 @@ void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPa
 
		buddyInfo.legacyName = legacyName;
 
		buddyInfo.subscription = "both";
 
		buddyInfo.flags = Buddy::buddFlagsFromJID(item.getJID());
 
		buddyInfo.groups = item.getGroups();
 

	
 
		Buddy *buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
 
		setBuddy(buddy);
 
@@ -281,6 +295,10 @@ void RosterManager::sendRIE() {
 

	
 
void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
	std::string legacyName = Buddy::JIDToLegacyName(presence->getTo());
 
	if (legacyName.empty()) {
 
		return;
 
	}
 
	
 
	// For server mode the subscription changes are handler in rosterresponder.cpp
 
	// using roster pushes.
 
	if (m_component->inServerMode()) {
 
@@ -326,8 +344,8 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
					response->setType(Swift::Presence::Subscribed);
 
					break;
 
				case Swift::Presence::Subscribed:
 
					onBuddyAdded(buddy);
 
					break;
 
// 					onBuddyAdded(buddy);
 
					return;
 
				// buddy is already there, so nothing to do, just answer
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
@@ -356,6 +374,10 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
						currentPresence->setTo(presence->getFrom());
 
						m_component->getStanzaChannel()->sendPresence(currentPresence);
 
					}
 
					if (buddy->getSubscription() != Buddy::Both) {
 
						buddy->setSubscription(Buddy::Both);
 
						handleBuddyChanged(buddy);
 
					}
 
					break;
 
				// remove buddy
 
				case Swift::Presence::Unsubscribe:
 
@@ -365,7 +387,20 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
				// just send response
 
				case Swift::Presence::Unsubscribed:
 
					response->setType(Swift::Presence::Unsubscribe);
 
					// We set both here, because this Unsubscribed can be response to
 
					// subscribe presence and we don't want that unsubscribe presence
 
					// to be send later again
 
					if (buddy->getSubscription() != Buddy::Both) {
 
						buddy->setSubscription(Buddy::Both);
 
						handleBuddyChanged(buddy);
 
					}
 
					break;
 
				case Swift::Presence::Subscribed:
 
					if (buddy->getSubscription() != Buddy::Both) {
 
						buddy->setSubscription(Buddy::Both);
 
						handleBuddyChanged(buddy);
 
					}
 
					return;
 
				default:
 
					return;
 
			}
 
@@ -389,7 +424,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
				// buddy is already there, so nothing to do, just answer
 
				case Swift::Presence::Unsubscribe:
 
					response->setType(Swift::Presence::Unsubscribed);
 
					onBuddyRemoved(buddy);
 
// 					onBuddyRemoved(buddy);
 
					break;
 
				// just send response
 
				case Swift::Presence::Unsubscribed:
src/rosterresponder.cpp
Show inline comments
 
@@ -28,16 +28,14 @@
 
#include "transport/usermanager.h"
 
#include "transport/rostermanager.h"
 
#include "transport/buddy.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("RosterResponder");
 
DEFINE_LOGGER(logger, "RosterResponder");
 

	
 
RosterResponder::RosterResponder(Swift::IQRouter *router, UserManager *userManager) : Swift::Responder<RosterPayload>(router) {
 
	m_userManager = userManager;
src/rosterstorage.cpp
Show inline comments
 
@@ -103,7 +103,7 @@ bool RosterStorage::storeBuddies() {
 
		buddyInfo.alias = buddy->getAlias();
 
		buddyInfo.legacyName = buddy->getName();
 
		buddyInfo.groups = buddy->getGroups();
 
		buddyInfo.subscription = buddy->getSubscription();
 
		buddyInfo.subscription = buddy->getSubscription() == Buddy::Ask ? "ask" : "both";
 
		buddyInfo.id = buddy->getID();
 
		buddyInfo.flags = buddy->getFlags();
 
		buddyInfo.settings["icon_hash"].s = buddy->getIconHash();
src/sqlite3backend.cpp
Show inline comments
 
@@ -22,10 +22,8 @@
 

	
 
#include "transport/sqlite3backend.h"
 
#include "transport/util.h"
 
#include "transport/logging.h"
 
#include <boost/bind.hpp>
 
#include "log4cxx/logger.h"
 

	
 
using namespace log4cxx;
 

	
 
#define SQLITE_DB_VERSION 3
 
#define CHECK_DB_RESPONSE(stmt) \
 
@@ -65,7 +63,7 @@ using namespace boost;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("SQLite3Backend");
 
DEFINE_LOGGER(logger, "SQLite3Backend");
 

	
 
SQLite3Backend::SQLite3Backend(Config *config) {
 
	m_config = config;
src/statsresponder.cpp
Show inline comments
 
@@ -34,16 +34,14 @@
 
#include "transport/rostermanager.h"
 
#include "transport/usermanager.h"
 
#include "transport/networkpluginserver.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("StatsResponder");
 
DEFINE_LOGGER(logger, "StatsResponder");
 

	
 
StatsResponder::StatsResponder(Component *component, UserManager *userManager, NetworkPluginServer *server, StorageBackend *storageBackend) : Swift::Responder<StatsPayload>(component->getIQRouter()) {
 
	m_component = component;
 
@@ -81,7 +79,10 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
 
		response->addItem(StatsPayload::Item("users/online"));
 
		response->addItem(StatsPayload::Item("contacts/online"));
 
		response->addItem(StatsPayload::Item("contacts/total"));
 
		response->addItem(StatsPayload::Item("backends"));
 
		response->addItem(StatsPayload::Item("messages/from-xmpp"));
 
		response->addItem(StatsPayload::Item("messages/to-xmpp"));
 
		response->addItem(StatsPayload::Item("backends/running"));
 
		response->addItem(StatsPayload::Item("backends/crashed"));
 
		response->addItem(StatsPayload::Item("memory-usage"));
 
	}
 
	else {
 
@@ -115,8 +116,11 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
 
			else if (item.getName() == "users/online") {
 
				response->addItem(StatsPayload::Item("users/online", "users", boost::lexical_cast<std::string>(m_userManager->getUserCount())));
 
			}
 
			else if (item.getName() == "backends") {
 
				response->addItem(StatsPayload::Item("backends", "backends", boost::lexical_cast<std::string>(m_server->getBackendCount())));
 
			else if (item.getName() == "backends/running") {
 
				response->addItem(StatsPayload::Item("backends/running", "backends", boost::lexical_cast<std::string>(m_server->getBackendCount())));
 
			}
 
			else if (item.getName() == "backends/crashed") {
 
				response->addItem(StatsPayload::Item("backends/crashed", "backends", boost::lexical_cast<std::string>(m_server->getCrashedBackends().size())));
 
			}
 
			else if (item.getName() == "memory-usage") {
 
				response->addItem(StatsPayload::Item("memory-usage", "KB", boost::lexical_cast<std::string>(usedMemory())));
 
@@ -127,6 +131,12 @@ bool StatsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
 
			else if (item.getName() == "contacts/total") {
 
				response->addItem(StatsPayload::Item("contacts/total", "contacts", boost::lexical_cast<std::string>(contactsTotal)));
 
			}
 
			else if (item.getName() == "messages/from-xmpp") {
 
				response->addItem(StatsPayload::Item("messages/from-xmpp", "messages", boost::lexical_cast<std::string>(m_userManager->getMessagesToBackend())));
 
			}
 
			else if (item.getName() == "messages/to-xmpp") {
 
				response->addItem(StatsPayload::Item("messages/to-xmpp", "messages", boost::lexical_cast<std::string>(m_userManager->getMessagesToXMPP())));
 
			}
 
		}
 
	}
 

	
src/storagebackend.cpp
Show inline comments
 
new file 100644
 
#include "transport/storagebackend.h"
 
#include "transport/config.h"
 

	
 
#include "transport/sqlite3backend.h"
 
#include "transport/mysqlbackend.h"
 
#include "transport/pqxxbackend.h"
 

	
 
namespace Transport {
 

	
 
StorageBackend *StorageBackend::createBackend(Config *config, std::string &error) {
 
	StorageBackend *storageBackend = NULL;
 
#ifdef WITH_SQLITE
 
	if (CONFIG_STRING(config, "database.type") == "sqlite3" ||
 
		(CONFIG_STRING(config, "database.type") == "none" && !CONFIG_BOOL(config, "service.server_mode"))) {
 
		storageBackend = new SQLite3Backend(config);
 
	}
 
#else
 
	if (CONFIG_STRING(config, "database.type") == "sqlite3") {
 
		error = "Libtransport is not compiled with sqlite3 backend support.";
 
	}
 
#endif
 

	
 
#ifdef WITH_MYSQL
 
	if (CONFIG_STRING(config, "database.type") == "mysql") {
 
		storageBackend = new MySQLBackend(config);
 
	}
 
#else
 
	if (CONFIG_STRING(config, "database.type") == "mysql") {
 
		error = "Spectrum2 is not compiled with mysql backend support.";
 
	}
 
#endif
 

	
 
#ifdef WITH_PQXX
 
	if (CONFIG_STRING(config, "database.type") == "pqxx") {
 
		storageBackend = new PQXXBackend(config);
 
	}
 
#else
 
	if (CONFIG_STRING(config, "database.type") == "pqxx") {
 
		error = "Spectrum2 is not compiled with pqxx backend support.";
 
	}
 
#endif
 

	
 
	if (CONFIG_STRING(config, "database.type") != "mysql" && CONFIG_STRING(config, "database.type") != "sqlite3"
 
		&& CONFIG_STRING(config, "database.type") != "pqxx" && CONFIG_STRING(config, "database.type") != "none") {
 
		error = "Unknown storage backend " + CONFIG_STRING(config, "database.type");
 
	}
 

	
 
	return storageBackend;
 
}
 

	
 
}
src/storageresponder.cpp
Show inline comments
 
@@ -27,16 +27,14 @@
 
#include "Swiften/Swiften.h"
 
#include "transport/usermanager.h"
 
#include "transport/user.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("StorageResponder");
 
DEFINE_LOGGER(logger, "StorageResponder");
 

	
 
StorageResponder::StorageResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager) : Swift::Responder<PrivateStorage>(router) {
 
	m_storageBackend = storageBackend;
src/tests/basictest.h
Show inline comments
 
@@ -72,7 +72,7 @@ class TestingFactory : public Factory {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setSubscription(Buddy::Ask);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
src/tests/main.cpp
Show inline comments
 
@@ -5,18 +5,22 @@
 
#include <cppunit/TestResultCollector.h>
 
#include <cppunit/TestRunner.h>
 
#include <cppunit/BriefTestProgressListener.h>
 
#ifdef WITH_LOG4CXX
 
#include "log4cxx/logger.h"
 
#include "log4cxx/fileappender.h"
 
#include "log4cxx/patternlayout.h"
 
#include "log4cxx/propertyconfigurator.h"
 

	
 
using namespace log4cxx;
 
#endif
 

	
 

	
 
int main (int argc, char* argv[])
 
{
 
#ifdef WITH_LOG4CXX
 
	LoggerPtr root = Logger::getRootLogger();
 
	root->addAppender(new FileAppender(new PatternLayout("%d %-5p %c: %m%n"), "libtransport_test.log", false));
 
#endif
 

	
 
	// informs test-listener about testresults
 
	CPPUNIT_NS :: TestResult testresult;
src/transport.cpp
Show inline comments
 
@@ -24,6 +24,7 @@
 
#include "transport/storagebackend.h"
 
#include "transport/factory.h"
 
#include "transport/userregistry.h"
 
#include "transport/logging.h"
 
#include "discoinforesponder.h"
 
#include "discoitemsresponder.h"
 
#include "storageparser.h"
 
@@ -36,25 +37,23 @@
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
 
#include "transport/BlockParser.h"
 
#include "transport/BlockSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
 
#include "log4cxx/logger.h"
 
#include "log4cxx/consoleappender.h"
 
#include "log4cxx/patternlayout.h"
 
#include "log4cxx/propertyconfigurator.h"
 
#include "Swiften/Swiften.h"
 

	
 
using namespace Swift;
 
using namespace boost;
 
using namespace log4cxx;
 

	
 
namespace Transport {
 
	
 
static LoggerPtr logger = Logger::getLogger("Component");
 
static LoggerPtr logger_xml = Logger::getLogger("Component.XML");
 
DEFINE_LOGGER(logger, "Component");
 
DEFINE_LOGGER(logger_xml, "Component.XML");
 

	
 
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
 
	m_component = NULL;
 
@@ -95,6 +94,8 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_server->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
@@ -102,6 +103,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
 
		m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_server->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 

	
 
		m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
 
		m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
 
@@ -121,6 +123,8 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_component->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
@@ -128,6 +132,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
 
		m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_component->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 

	
 
		m_stanzaChannel = m_component->getStanzaChannel();
 
		m_iqRouter = m_component->getIQRouter();
 
@@ -198,6 +203,11 @@ void Component::start() {
 
	else if (m_server) {
 
		LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server->start();
 

	
 
		//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
 
		//Ideally, onStopped must be defined in ConnectionServer
 
		boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&Component::handleServerStopped, this, _1));
 
		
 
		// We're connected right here, because we're in server mode...
 
		handleConnected();
 
	}
 
@@ -221,6 +231,17 @@ void Component::handleConnected() {
 
	m_reconnectCount = 0;
 
}
 

	
 
void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
 
	if(e != NULL ) {
 
		if(*e == Swift::BoostConnectionServer::Conflict)
 
			LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
 
		if(*e == Swift::BoostConnectionServer::UnknownError)
 
			LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
 
		exit(1);
 
	}
 
}
 

	
 

	
 
void Component::handleConnectionError(const ComponentError &error) {
 
	onConnectionError(error);
 
// 	if (m_reconnectCount == 2)
src/user.cpp
Show inline comments
 
@@ -25,24 +25,23 @@
 
#include "transport/usermanager.h"
 
#include "transport/conversationmanager.h"
 
#include "transport/presenceoracle.h"
 
#include "transport/logging.h"
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Elements/StreamError.h"
 
#include "Swiften/Elements/MUCPayload.h"
 
#include "Swiften/Elements/SpectrumErrorPayload.h"
 
#include "log4cxx/logger.h"
 
#include <boost/foreach.hpp>
 
#include <stdio.h>
 
#include <stdlib.h>
 

	
 
using namespace log4cxx;
 
using namespace boost;
 

	
 
#define foreach         BOOST_FOREACH
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("User");
 
DEFINE_LOGGER(logger, "User");
 

	
 
User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) {
 
	m_jid = jid.toBare();
 
@@ -210,11 +209,12 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
			}
 
		}
 
	}
 

	
 
	bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
 
	if (isMUC) {
 
		if (presence->getType() == Swift::Presence::Unavailable) {
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << presence->getTo().getNode());
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
 
			onRoomLeft(room);
 
		}
 
		else {
 
@@ -224,8 +224,8 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
				m_readyForConnect = true;
 
				onReadyToConnect();
 
			}
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << presence->getTo().getNode() << " as " << presence->getTo().getResource());
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << room << " as " << presence->getTo().getResource());
 
			std::string password = "";
 
			if (presence->getPayload<Swift::MUCPayload>() != NULL) {
 
				password = presence->getPayload<Swift::MUCPayload>()->getPassword() ? *presence->getPayload<Swift::MUCPayload>()->getPassword() : "";
 
@@ -328,7 +328,7 @@ void User::handleDisconnected(const std::string &error, Swift::SpectrumErrorPayl
 
	if (e == Swift::SpectrumErrorPayload::CONNECTION_ERROR_OTHER_ERROR || e == Swift::SpectrumErrorPayload::CONNECTION_ERROR_NETWORK_ERROR) {
 
		if (m_reconnectCounter < 3) {
 
			m_reconnectCounter++;
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network for, trying to reconnect automatically.");
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network " << error << ", trying to reconnect automatically.");
 
			// Simulate destruction/resurrection :)
 
			// TODO: If this stops working, create onReconnect signal
 
			m_userManager->onUserDestroyed(this);
src/usermanager.cpp
Show inline comments
 
@@ -25,23 +25,24 @@
 
#include "transport/conversationmanager.h"
 
#include "transport/rostermanager.h"
 
#include "transport/userregistry.h"
 
#include "transport/logging.h"
 
#include "storageresponder.h"
 
#include "log4cxx/logger.h"
 

	
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Elements/StreamError.h"
 
#include "malloc.h"
 
// #include "valgrind/memcheck.h"
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("UserManager");
 
DEFINE_LOGGER(logger, "UserManager");
 

	
 
UserManager::UserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) {
 
	m_cachedUser = NULL;
 
	m_onlineBuddies = 0;
 
	m_sentToXMPP = 0;
 
	m_sentToBackend = 0;
 
	m_component = component;
 
	m_storageBackend = storageBackend;
 
	m_storageResponder = NULL;
 
@@ -149,8 +150,27 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
	// Create user class if it's not there
 
	if (!user) {
 
		// Admin user is not legacy network user, so do not create User class instance for him
 
		if (m_component->inServerMode() && CONFIG_STRING(m_component->getConfig(), "service.admin_jid") == presence->getFrom().toBare().toString()) {
 
		if (m_component->inServerMode()) {
 
		    std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid");
 
		    if (std::find(x.begin(), x.end(), presence->getFrom().toBare().toString()) != x.end()) {
 
		
 
			// Send admin contact to the user.
 
			Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
			Swift::RosterItemPayload item;
 
			item.setJID(m_component->getJID());
 
			item.setName("Admin");
 
			item.setSubscription(Swift::RosterItemPayload::Both);
 
			payload->addItem(item);
 

	
 
			Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, presence->getFrom(), m_component->getIQRouter());
 
			request->send();
 

	
 
			Swift::Presence::ref response = Swift::Presence::create();
 
			response->setTo(presence->getFrom());
 
			response->setFrom(m_component->getJID());
 
			m_component->getStanzaChannel()->sendPresence(response);
 
			return;
 
		    }
 
		}
 

	
 
		// No user and unavailable presence -> answer with unavailable
 
@@ -198,6 +218,34 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
			res.password = m_userRegistry->getUserPassword(userkey);
 
		}
 

	
 
		// We allow auto_register feature in gateway-mode. This allows IRC user to register
 
		// the transport just by joining the room.
 
		if (!m_component->inServerMode()) {
 
			if (!registered && CONFIG_BOOL(m_component->getConfig(), "registration.auto_register")) {
 
				res.password = "";
 
				res.jid = userkey;
 

	
 
				bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
 
				if (isMUC) {
 
					res.uin = presence->getTo().getResource();
 
				}
 
				else {
 
					res.uin = presence->getFrom().toString();
 
				}
 
				LOG4CXX_INFO(logger, "Auto-registering user " << userkey << " with uin=" << res.uin);
 

	
 
				if (m_storageBackend) {
 
					// store user and getUser again to get user ID.
 
					m_storageBackend->setUser(res);
 
					registered = m_storageBackend->getUser(userkey, res);
 
				}
 
				else {
 
					registered = false;
 
				}
 
			}
 
		}
 

	
 

	
 
		// Unregistered users are not able to login
 
		if (!registered) {
 
			LOG4CXX_WARN(logger, "Unregistered user " << userkey << " tried to login");
 
@@ -266,6 +314,12 @@ void UserManager::handleMessageReceived(Swift::Message::ref message) {
 
	}
 

	
 
	user->getConversationManager()->handleMessageReceived(message);
 

	
 
	// Do not count chatstate notification...
 
	boost::shared_ptr<Swift::ChatState> statePayload = message->getPayload<Swift::ChatState>();
 
	if (!statePayload) {
 
		messageToBackendSent();
 
	}
 
}
 

	
 
void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) {
src/userregistration.cpp
Show inline comments
 
@@ -24,18 +24,17 @@
 
#include "transport/transport.h"
 
#include "transport/rostermanager.h"
 
#include "transport/user.h"
 
#include "transport/logging.h"
 
#include "Swiften/Elements/ErrorPayload.h"
 
#include <boost/shared_ptr.hpp>
 
#include <boost/thread.hpp>
 
#include <boost/date_time/posix_time/posix_time.hpp>
 
#include "log4cxx/logger.h"
 

	
 
using namespace Swift;
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("UserRegistration");
 
DEFINE_LOGGER(logger, "UserRegistration");
 

	
 
UserRegistration::UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend) : Swift::Responder<Swift::InBandRegistrationPayload>(component->m_iqRouter) {
 
	m_component = component;
 
@@ -169,7 +168,7 @@ bool UserRegistration::handleGetRequest(const Swift::JID& from, const Swift::JID
 
	std::string barejid = from.toBare().toString();
 

	
 
	if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) {
 
		std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers");
 
		std::vector<std::string> const &x = CONFIG_VECTOR(m_config,"service.allowed_servers");
 
		if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) {
 
			LOG4CXX_INFO(logger, barejid << ": This user has no permissions to register an account")
 
			sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
 
@@ -276,7 +275,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
 
	std::string barejid = from.toBare().toString();
 

	
 
	if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) {
 
		std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers");
 
		std::vector<std::string> const &x = CONFIG_VECTOR(m_config,"service.allowed_servers");
 
		if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) {
 
			LOG4CXX_INFO(logger, barejid << ": This user has no permissions to register an account")
 
			sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
 
@@ -453,7 +452,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
 
// #endif
 
	if (!registered) {
 
		res.jid = barejid;
 
		res.uin = username;
 
		res.uin = newUsername;
 
		res.password = *payload->getPassword();
 
		res.language = language;
 
		res.encoding = encoding;
 
@@ -462,7 +461,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
 
	}
 
	else {
 
		res.jid = barejid;
 
		res.uin = username;
 
		res.uin = newUsername;
 
		res.password = *payload->getPassword();
 
		res.language = language;
 
		res.encoding = encoding;
src/userregistry.cpp
Show inline comments
 
@@ -23,13 +23,11 @@
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include "transport/userregistry.h"
 
#include "log4cxx/logger.h"
 

	
 
using namespace log4cxx;
 
#include "transport/logging.h"
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("UserRegistry");
 
DEFINE_LOGGER(logger, "UserRegistry");
 

	
 
UserRegistry::UserRegistry(Config *cfg, Swift::NetworkFactories *factories) {
 
	config = cfg;
 
@@ -40,7 +38,8 @@ UserRegistry::UserRegistry(Config *cfg, Swift::NetworkFactories *factories) {
 
UserRegistry::~UserRegistry() { m_removeTimer->stop(); }
 

	
 
void UserRegistry::isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) {
 
	if (!CONFIG_STRING(config, "service.admin_jid").empty() && user.toBare().toString() == CONFIG_STRING(config, "service.admin_jid")) {
 
	std::vector<std::string> const &x = CONFIG_VECTOR(config,"service.admin_jid");
 
	if (std::find(x.begin(), x.end(), user.toBare().toString()) != x.end()) {
 
		if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) {
 
			session->handlePasswordValid();
 
		}
 
@@ -49,7 +48,6 @@ void UserRegistry::isValidUserPassword(const Swift::JID& user, Swift::ServerFrom
 
		}
 
		return;
 
	}
 

	
 
	std::string key = user.toBare().toString();
 

	
 
	// Users try to connect twice
src/usersreconnecter.cpp
Show inline comments
 
@@ -26,16 +26,14 @@
 
#include "Swiften/Swiften.h"
 
#include "transport/storagebackend.h"
 
#include "transport/transport.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("UserReconnecter");
 
DEFINE_LOGGER(logger, "UserReconnecter");
 

	
 
UsersReconnecter::UsersReconnecter(Component *component, StorageBackend *storageBackend) {
 
	m_component = component;
src/vcardresponder.cpp
Show inline comments
 
@@ -28,16 +28,14 @@
 
#include "transport/usermanager.h"
 
#include "transport/rostermanager.h"
 
#include "transport/transport.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("VCardResponder");
 
DEFINE_LOGGER(logger, "VCardResponder");
 

	
 
VCardResponder::VCardResponder(Swift::IQRouter *router, Swift::NetworkFactories *factories, UserManager *userManager) : Swift::Responder<VCard>(router) {
 
	m_id = 0;
 
@@ -103,7 +101,7 @@ bool VCardResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Requested VCard of " << name);
 

	
 
	m_queries[m_id].from = from;
 
	m_queries[m_id].to = to_;
 
	m_queries[m_id].to = to;
 
	m_queries[m_id].id = id; 
 
	m_queries[m_id].received = time(NULL);
 
	onVCardRequired(user, name, m_id++);
0 comments (0 inline, 0 general)