Changeset - 81522828685a
CMakeLists.txt
Show inline comments
 
@@ -145,7 +145,12 @@ else(WIN32)
 
		message(STATUS "Using non-multithreaded boost")
 
		set(Boost_USE_MULTITHREADED 0)
 
	endif(contains)
 
	find_package(Boost COMPONENTS program_options date_time system filesystem regex thread-mt signals REQUIRED)
 
	set(Boost_FIND_QUIETLY ON)
 
	find_package(Boost COMPONENTS program_options date_time system filesystem regex thread-mt signals)
 
	if (NOT Boost_FOUND)
 
		set(Boost_FIND_QUIETLY OFF)
 
		find_package(Boost COMPONENTS program_options date_time system filesystem regex thread signals REQUIRED)
 
	endif()
 
endif(WIN32)
 

	
 
message( STATUS "Found Boost: ${Boost_LIBRARIES}, ${Boost_INCLUDE_DIR}")
backends/libcommuni/ircnetworkplugin.cpp
Show inline comments
 
@@ -10,9 +10,37 @@ DEFINE_LOGGER(logger, "IRCNetworkPlugin");
 

	
 
IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
 
	this->config = config;
 
	m_currentServer = 0;
 
	m_socket = new QTcpSocket();
 
	m_socket->connectToHost(FROM_UTF8(host), port);
 
	connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
 

	
 
	std::string server = CONFIG_STRING_DEFAULTED(config, "service.irc_server", "");
 
	if (!server.empty()) {
 
		m_servers.push_back(server);
 
	}
 
	else {
 
		
 
		std::list<std::string> list;
 
		list = CONFIG_LIST_DEFAULTED(config, "service.irc_server", list);
 
		
 
		m_servers.insert(m_servers.begin(), list.begin(), list.end());
 
	}
 

	
 
	if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
 
		m_identify = CONFIG_STRING(config, "service.irc_identify");
 
	}
 
	else {
 
		m_identify = "NickServ identify $name $password";
 
	}
 
}
 

	
 
void IRCNetworkPlugin::tryNextServer() {
 
	if (!m_servers.empty()) {
 
		int nextServer = (m_currentServer + 1) % m_servers.size();
 
		LOG4CXX_INFO(logger, "Server " << m_servers[m_currentServer] << " disconnected user. Next server to try will be " << m_servers[nextServer]);
 
		m_currentServer = nextServer;
 
	}
 
}
 

	
 
void IRCNetworkPlugin::readData() {
 
@@ -28,114 +56,156 @@ void IRCNetworkPlugin::sendData(const std::string &string) {
 
	m_socket->write(string.c_str(), string.size());
 
}
 

	
 
MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std::string &hostname, const std::string &nickname, const std::string &password, const std::string &suffix) {
 
	MyIrcSession *session = new MyIrcSession(user, this, suffix);
 
	session->setUserName(FROM_UTF8(nickname));
 
	session->setNickName(FROM_UTF8(nickname));
 
	session->setRealName(FROM_UTF8(nickname));
 
	session->setHost(FROM_UTF8(hostname));
 
	session->setPort(6667);
 
	session->setEncoding( "utf-8" );
 

	
 
	if (!password.empty()) {
 
		std::string identify = m_identify;
 
		boost::replace_all(identify, "$password", password);
 
		boost::replace_all(identify, "$name", nickname);
 
		session->setIdentify(identify);
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << ": Connecting " << hostname << " as " << nickname << ", suffix=" << suffix);
 

	
 
	session->open();
 

	
 
	return session;
 
}
 

	
 
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
	// In server mode, hostname of the server we want to connect to is stored in "user" JID.
 
	// In component mode we will connect user to the IRC network once he joins the room.
 
	if (CONFIG_BOOL(config, "service.server_mode")) {
 
		MyIrcSession *session = new MyIrcSession(user, this);
 
		std::string h = user.substr(0, user.find("@"));
 
		session->setNickName(FROM_UTF8(h.substr(0, h.find("%"))));
 
		session->setHost(FROM_UTF8(h.substr(h.find("%") + 1)));
 
		session->setPort(6667);
 
		session->open();
 
		LOG4CXX_INFO(logger, user << ": Connecting IRC network " << h.substr(h.find("%") + 1));
 
		m_sessions[user] = session;
 
	if (!m_servers.empty()) {
 
		// legacy name is users nickname
 
		if (m_sessions[user] != NULL) {
 
			LOG4CXX_WARN(logger, user << ": Already logged in.");
 
			return;
 
		}
 

	
 
		m_sessions[user] = createSession(user, m_servers[m_currentServer], legacyName, password, "");
 
	}
 
	else {
 
		// We are waiting for first room join to connect user to IRC network, because we don't know which
 
		// network he choose...
 
		LOG4CXX_INFO(logger, user << ": Ready for connections");
 
		handleConnected(user);
 
	}
 
}
 

	
 
void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
	if (m_sessions[user] == NULL)
 
	if (m_sessions[user] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Already disconnected.");
 
		return;
 
	}
 
	LOG4CXX_INFO(logger, user << ": Disconnecting.");
 
	m_sessions[user]->close();
 
	m_sessions[user]->deleteLater();
 
	m_sessions.erase(user);
 
}
 

	
 
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
 
std::string IRCNetworkPlugin::getSessionName(const std::string &user, const std::string &legacyName) {
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
	if (!CONFIG_BOOL(config, "service.server_mode") && m_servers.empty()) {
 
		u = user + legacyName.substr(legacyName.find("@") + 1);
 
		if (u.find("/") != std::string::npos) {
 
			u = u.substr(0, u.find("/"));
 
		}
 
	}
 
	if (m_sessions[u] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << u << ", No session for user");
 
		return;
 
	}
 
	return u;
 
}
 

	
 
std::string IRCNetworkPlugin::getTargetName(const std::string &legacyName) {
 
	std::string r = legacyName;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
// 	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		if (legacyName.find("/") == std::string::npos) {
 
			r = legacyName.substr(0, r.find("@"));
 
		}
 
		else {
 
			r = legacyName.substr(legacyName.find("/") + 1);
 
		}
 
// 	}
 
	return r;
 
}
 

	
 
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
 
	std::string session = getSessionName(user, legacyName);
 
	if (m_sessions[session] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
 
		return;
 
	}
 

	
 
	std::string target = getTargetName(legacyName);
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", message to " << target);
 
	m_sessions[session]->sendCommand(IrcCommand::createMessage(FROM_UTF8(target), FROM_UTF8(message)));
 

	
 
	if (target.find("#") == 0) {
 
		handleMessage(user, legacyName, message, TO_UTF8(m_sessions[session]->nickName()));
 
	}
 
	LOG4CXX_INFO(logger, user << ": Session name: " << u << ", message to " << r);
 
	m_sessions[u]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message)));
 
}
 

	
 
void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
	std::string r = room;
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		u = user + room.substr(room.find("@") + 1);
 
		r = room.substr(0, room.find("@"));
 
void IRCNetworkPlugin::handleRoomSubjectChangedRequest(const std::string &user, const std::string &room, const std::string &message) {
 
	std::string session = getSessionName(user, room);
 
	if (m_sessions[session] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << u << ", Joining room " << r);
 
	if (m_sessions[u] == NULL) {
 
		// in gateway mode we want to login this user to network according to legacyName
 
		if (room.find("@") != std::string::npos) {
 
			// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
 
			MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("@")));
 
			session->setNickName(FROM_UTF8(nickname));
 
			session->setHost(FROM_UTF8(room.substr(room.find("@") + 1)));
 
			session->setPort(6667);
 
			session->open();
 
			LOG4CXX_INFO(logger, user << ": Connecting IRC network " << room.substr(room.find("@") + 1));
 
			m_sessions[u] = session;
 
	std::string target = getTargetName(room);
 
	m_sessions[session]->sendCommand(IrcCommand::createTopic(FROM_UTF8(target), FROM_UTF8(message)));
 
}
 

	
 
void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
	std::string session = getSessionName(user, room);
 
	std::string target = getTargetName(room);
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Joining room " << target);
 
	if (m_sessions[session] == NULL) {
 
		if (m_servers.empty()) {
 
			// in gateway mode we want to login this user to network according to legacyName
 
			if (room.find("@") != std::string::npos) {
 
				// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
 
				m_sessions[session] = createSession(user, room.substr(room.find("@") + 1), nickname, "", room.substr(room.find("@")));
 
			}
 
			else {
 
				LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room);
 
				return;
 
			}
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room);
 
			LOG4CXX_WARN(logger, user << ": Join room requested for unconnected user");
 
			return;
 
		}
 
	}
 

	
 
	m_sessions[u]->addAutoJoinChannel(r, password);
 
	m_sessions[u]->sendCommand(IrcCommand::createJoin(FROM_UTF8(r), FROM_UTF8(password)));
 
	m_sessions[u]->rooms += 1;
 
	m_sessions[session]->addAutoJoinChannel(target, password);
 
	m_sessions[session]->sendCommand(IrcCommand::createJoin(FROM_UTF8(target), FROM_UTF8(password)));
 
	m_sessions[session]->rooms += 1;
 
	// update nickname, because we have nickname per session, no nickname per room.
 
	handleRoomNicknameChanged(user, r, TO_UTF8(m_sessions[u]->nickName()));
 
	handleRoomNicknameChanged(user, target, TO_UTF8(m_sessions[session]->nickName()));
 
}
 

	
 
void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
	std::string r = room;
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		r = room.substr(0, room.find("@"));
 
		u = user + room.substr(room.find("@") + 1);
 
	}
 
	std::string session = getSessionName(user, room);
 
	std::string target = getTargetName(room);
 

	
 
	if (m_sessions[u] == NULL)
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Leaving room " << target);
 
	if (m_sessions[session] == NULL)
 
		return;
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << u << ", Leaving room " << r);
 

	
 
	m_sessions[u]->sendCommand(IrcCommand::createPart(FROM_UTF8(r)));
 
	m_sessions[u]->removeAutoJoinChannel(r);
 
	m_sessions[u]->rooms -= 1;
 
	m_sessions[session]->sendCommand(IrcCommand::createPart(FROM_UTF8(target)));
 
	m_sessions[session]->removeAutoJoinChannel(target);
 
	m_sessions[session]->rooms -= 1;
 

	
 
	if (m_sessions[u]->rooms <= 0) {
 
		LOG4CXX_INFO(logger, user << ": Session name: " << u << ", User is not in room, disconnecting from network");
 
		m_sessions[u]->close();
 
		m_sessions[u]->deleteLater();
 
		m_sessions.erase(u);
 
	if (m_sessions[session]->rooms <= 0 && m_servers.empty()) {
 
		LOG4CXX_INFO(logger, user << ": Session name: " << session << ", User is not in any room, disconnecting from network");
 
		m_sessions[session]->close();
 
		m_sessions[session]->deleteLater();
 
		m_sessions.erase(session);
 
	}
 
}
backends/libcommuni/ircnetworkplugin.h
Show inline comments
 
@@ -26,12 +26,24 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room);
 

	
 
		void handleRoomSubjectChangedRequest(const std::string &user, const std::string &room, const std::string &message);
 

	
 
		void tryNextServer();
 

	
 
	public slots:
 
		void readData();
 
		void sendData(const std::string &string);
 

	
 
	private:
 
		MyIrcSession *createSession(const std::string &user, const std::string &hostname, const std::string &nickname, const std::string &password, const std::string &suffix = "");
 
		std::string getSessionName(const std::string &user, const std::string &legacyName);
 
		std::string getTargetName(const std::string &legacyName);
 

	
 
	private:
 
		Config *config;
 
		QTcpSocket *m_socket;
 
		std::map<std::string, MyIrcSession *> m_sessions;
 
		std::vector<std::string> m_servers;
 
		int m_currentServer;
 
		std::string m_identify;
 
};
 
\ No newline at end of file
backends/libcommuni/main.cpp
Show inline comments
 
@@ -16,7 +16,6 @@
 
#include <QtNetwork>
 
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
 
#include "ircnetworkplugin.h"
 
#include "singleircnetworkplugin.h"
 

	
 
using namespace boost::program_options;
 
using namespace Transport;
 
@@ -40,12 +39,7 @@ int main (int argc, char* argv[]) {
 

	
 
	Swift::QtEventLoop eventLoop;
 

	
 
	if (!CONFIG_HAS_KEY(cfg, "service.irc_server")) {
 
		np = new IRCNetworkPlugin(cfg, &eventLoop, host, port);
 
	}
 
	else {
 
		np = new SingleIRCNetworkPlugin(cfg, &eventLoop, host, port);
 
	}
 

	
 
	np = new IRCNetworkPlugin(cfg, &eventLoop, host, port);
 
	return app.exec();
 
}
backends/libcommuni/session.cpp
Show inline comments
 
@@ -14,6 +14,8 @@
 
#include <IrcCommand>
 
#include <IrcMessage>
 

	
 
#include "ircnetworkplugin.h"
 

	
 
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
 
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
 

	
 
@@ -21,7 +23,7 @@
 

	
 
DEFINE_LOGGER(logger, "IRCSession");
 

	
 
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
 
MyIrcSession::MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
 
{
 
	this->np = np;
 
	this->user = user;
 
@@ -29,6 +31,7 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std
 
	m_connected = false;
 
	rooms = 0;
 
	connect(this, SIGNAL(disconnected()), SLOT(on_disconnected()));
 
	connect(this, SIGNAL(socketError(QAbstractSocket::SocketError)), SLOT(on_socketError(QAbstractSocket::SocketError)));
 
	connect(this, SIGNAL(connected()), SLOT(on_connected()));
 
	connect(this, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(onMessageReceived(IrcMessage*)));
 
}
 
@@ -50,9 +53,15 @@ void MyIrcSession::on_connected() {
 
	}
 
}
 

	
 
void MyIrcSession::on_socketError(QAbstractSocket::SocketError error) {
 
	on_disconnected();
 
}
 

	
 
void MyIrcSession::on_disconnected() {
 
	if (suffix.empty())
 
	if (suffix.empty()) {
 
		np->handleDisconnected(user, 0, "");
 
		np->tryNextServer();
 
	}
 
	m_connected = false;
 
}
 

	
 
@@ -161,7 +170,8 @@ void MyIrcSession::on_messageReceived(IrcMessage *message) {
 
		bool flags = 0;
 
		std::string nickname = TO_UTF8(m->sender().name());
 
		flags = correctNickname(nickname);
 
		np->handleMessage(user, nickname, TO_UTF8(m->message()));
 
		LOG4CXX_INFO(logger, nickname + suffix);
 
		np->handleMessage(user, nickname + suffix, TO_UTF8(m->message()));
 
	}
 
}
 

	
 
@@ -181,6 +191,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
 
			channel = m->parameters().value(2);
 
			members = m->parameters().value(3).split(" ");
 

	
 
			LOG4CXX_INFO(logger, user << ": Received members for " << TO_UTF8(channel) << suffix);
 
			for (int i = 0; i < members.size(); i++) {
 
				bool flags = 0;
 
				std::string nickname = TO_UTF8(members.at(i));
 
@@ -190,9 +201,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
 
			}
 
			break;
 
		case 432:
 
			if (m_connected) {
 
				np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
 
			}
 
			np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
 
			break;
 
		default:
 
			break;
backends/libcommuni/session.h
Show inline comments
 
@@ -18,6 +18,8 @@
 

	
 
using namespace Transport;
 

	
 
class IRCNetworkPlugin;
 

	
 
class MyIrcSession : public IrcSession
 
{
 
    Q_OBJECT
 
@@ -37,7 +39,7 @@ public:
 

	
 
	typedef std::map<std::string, boost::shared_ptr<AutoJoinChannel> > AutoJoinMap;
 

	
 
	MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
 
	MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
 
	std::map<std::string, bool> m_modes;
 
	std::string suffix;
 
	int rooms;
 
@@ -72,11 +74,12 @@ public:
 
protected Q_SLOTS:
 
	void on_connected();
 
	void on_disconnected();
 
	void on_socketError(QAbstractSocket::SocketError error);
 

	
 
	void onMessageReceived(IrcMessage* message);
 

	
 
protected:
 
	NetworkPlugin *np;
 
	IRCNetworkPlugin *np;
 
	std::string user;
 
	std::string m_identify;
 
	AutoJoinMap m_autoJoin;
backends/libcommuni/singleircnetworkplugin.cpp
Show inline comments
 
deleted file
backends/libcommuni/singleircnetworkplugin.h
Show inline comments
 
deleted file
backends/libpurple/main.cpp
Show inline comments
 
@@ -17,7 +17,9 @@
 
#include "geventloop.h"
 

	
 
// #include "valgrind/memcheck.h"
 
#ifndef __FreeBSD__
 
#include "malloc.h"
 
#endif
 
#include <algorithm>
 
#include "errno.h"
 
#include <boost/make_shared.hpp>
 
@@ -364,8 +366,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
				purple_accounts_delete_wrapped(account);
 
#ifndef WIN32
 
#ifndef __FreeBSD__
 
				malloc_trim(0);
 
#endif
 
#endif
 
// 				VALGRIND_DO_LEAK_CHECK;
 
			}
 
		}
 
@@ -1459,8 +1463,10 @@ static void signed_on(PurpleConnection *gc, gpointer unused) {
 
	PurpleAccount *account = purple_connection_get_account_wrapped(gc);
 
	np->handleConnected(np->m_accounts[account]);
 
#ifndef WIN32
 
#ifndef __FreeBSD__
 
	// force returning of memory chunks allocated by libxml2 to kernel
 
	malloc_trim(0);
 
#endif
 
#endif
 

	
 
	// For prpl-gg
 
@@ -1648,8 +1654,10 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 

	
 
int main(int argc, char **argv) {
 
#ifndef WIN32
 
#ifndef __FreeBSD__
 
		mallopt(M_CHECK_ACTION, 2);
 
		mallopt(M_PERTURB, 0xb);
 
#endif
 

	
 
		signal(SIGPIPE, SIG_IGN);
 

	
backends/twitter/userdb.cpp
Show inline comments
 
deleted file
backends/twitter/userdb.h
Show inline comments
 
deleted file
include/transport/config.h
Show inline comments
 
@@ -28,6 +28,20 @@
 
#include <boost/bind.hpp>
 
#include <boost/signal.hpp>
 

	
 
namespace Transport {
 

	
 
template <class myType>
 
const myType &safeAs(const boost::program_options::variable_value &var, const myType &def) {
 
	try  {
 
		return var.as<myType>();
 
	}
 
	catch(...) {
 
		return def;
 
	}
 
}
 

	
 
}
 

	
 
#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>()
 
@@ -35,9 +49,9 @@
 
#define CONFIG_LIST(PTR, KEY) (*PTR)[KEY].as<std::list<std::string> >()
 
#define CONFIG_VECTOR(PTR, KEY) ((*PTR).hasKey(KEY) ? (*PTR)[KEY].as<std::vector<std::string> >() : std::vector<std::string>())
 

	
 
#define CONFIG_STRING_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? (*PTR)[KEY].as<std::string>() : DEF)
 
#define CONFIG_BOOL_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? (*PTR)[KEY].as<bool>() : DEF)
 

	
 
#define CONFIG_STRING_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? Transport::safeAs<std::string>((*PTR)[KEY], DEF) : DEF)
 
#define CONFIG_BOOL_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? Transport::safeAs<bool>((*PTR)[KEY], DEF) : DEF)
 
#define CONFIG_LIST_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? Transport::safeAs<std::list<std::string> >((*PTR)[KEY], DEF) : DEF)
 

	
 
namespace Transport {
 

	
include/transport/conversation.h
Show inline comments
 
@@ -34,6 +34,12 @@ class ConversationManager;
 
/// Represents one XMPP-Legacy network conversation.
 
class Conversation {
 
	public:
 
		typedef struct _Participant {
 
			int flag;
 
			int status;
 
			std::string statusMessage;
 
		} Participant;
 

	
 
		/// Type of participants in MUC rooms.
 
		enum ParticipantFlag {None, Moderator};
 

	
 
@@ -82,6 +88,18 @@ class Conversation {
 
			m_jid = jid;
 
		}
 

	
 
		void addJID(const Swift::JID &jid) {
 
			m_jids.push_back(jid);
 
		}
 

	
 
		void removeJID(const Swift::JID &jid) {
 
			m_jids.remove(jid);
 
		}
 

	
 
		const std::list<Swift::JID> &getJIDs() {
 
			return m_jids;
 
		}
 

	
 
		/// Sends message to Legacy network.
 

	
 
		/// \param message Message.
 
@@ -116,6 +134,11 @@ class Conversation {
 

	
 
		void destroyRoom();
 

	
 
		void sendParticipants(const Swift::JID &to);
 

	
 
	private:
 
		Swift::Presence::ref generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname = "");
 

	
 
	private:
 
		ConversationManager *m_conversationManager;
 
		std::string m_legacyName;
 
@@ -123,6 +146,8 @@ class Conversation {
 
		std::string m_room;
 
		bool m_muc;
 
		Swift::JID m_jid;
 
		std::list<Swift::JID> m_jids;
 
		std::map<std::string, Participant> m_participants;
 
};
 

	
 
}
include/transport/conversationmanager.h
Show inline comments
 
@@ -70,6 +70,7 @@ class ConversationManager {
 
		void removeConversation(Conversation *conv);
 

	
 
		void resetResources();
 
		void removeJID(const Swift::JID &jid);
 

	
 
	private:
 
		void handleMessageReceived(Swift::Message::ref message);
include/transport/networkplugin.h
Show inline comments
 
@@ -218,6 +218,7 @@ class NetworkPlugin {
 
		/// \param photo Raw photo data.
 
		virtual void handleVCardUpdatedRequest(const std::string &/*user*/, const std::string &/*photo*/, const std::string &nickname) {}
 

	
 
		virtual void handleRoomSubjectChangedRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*message*/) {}
 

	
 
		virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {}
 
		virtual void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/) {}
 
@@ -260,6 +261,7 @@ class NetworkPlugin {
 
		void handleFTFinishPayload(const std::string &payload);
 
		void handleFTPausePayload(const std::string &payload);
 
		void handleFTContinuePayload(const std::string &payload);
 
		void handleRoomSubjectChangedPayload(const std::string &payload);
 

	
 
		void send(const std::string &data);
 
		void sendPong();
include/transport/user.h
Show inline comments
 
@@ -110,6 +110,10 @@ class User : public Swift::EntityCapsProvider {
 
			return m_connected;
 
		}
 

	
 
		int getResourceCount() {
 
			return m_resources;
 
		}
 

	
 
		boost::signal<void ()> onReadyToConnect;
 
		boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
 
		boost::signal<void (const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
include/transport/vcardresponder.h
Show inline comments
 
@@ -59,4 +59,4 @@ class VCardResponder : public Swift::Responder<Swift::VCard> {
 
		Swift::Timer::ref m_collectTimer;
 
};
 

	
 
}
 
\ No newline at end of file
 
}
plugin/cpp/networkplugin.cpp
Show inline comments
 
@@ -374,6 +374,16 @@ void NetworkPlugin::handleConvMessagePayload(const std::string &data) {
 
	handleMessageSendRequest(payload.username(), payload.buddyname(), payload.message(), payload.xhtml());
 
}
 

	
 
void NetworkPlugin::handleRoomSubjectChangedPayload(const std::string &data) {
 
	pbnetwork::ConversationMessage payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	handleRoomSubjectChangedRequest(payload.username(), payload.buddyname(), payload.message());
 
}
 

	
 
void NetworkPlugin::handleAttentionPayload(const std::string &data) {
 
	pbnetwork::ConversationMessage payload;
 
	if (payload.ParseFromString(data) == false) {
 
@@ -550,6 +560,9 @@ void NetworkPlugin::handleDataRead(std::string &data) {
 
			case pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE:
 
				handleConvMessagePayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_ROOM_SUBJECT_CHANGED:
 
				handleRoomSubjectChangedPayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM:
 
				handleJoinRoomPayload(wrapper.payload());
 
				break;
spectrum_manager/src/methods.cpp
Show inline comments
 
@@ -195,7 +195,7 @@ int start_instances(ManagerConfig *config, const std::string &_jid) {
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		std::cerr << "Filesystem error: " << ex.what() << "\n";
 
		return 6;
 
	}
 
	return rv;
 
@@ -271,7 +271,7 @@ void stop_instances(ManagerConfig *config, const std::string &_jid) {
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		std::cerr << "Filesystem error: " << ex.what() << "\n";
 
		exit(5);
 
	}
 
}
 
@@ -324,7 +324,7 @@ int show_status(ManagerConfig *config) {
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		std::cerr << "Filesystem error: " << ex.what() << "\n";
 
		exit(5);
 
	}
 
	return ret;
 
@@ -460,7 +460,7 @@ void ask_local_server(ManagerConfig *config, Swift::BoostNetworkFactories &netwo
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		std::cerr << "Filesystem error: " << ex.what() << "\n";
 
		exit(5);
 
	}
 
}
 
@@ -498,7 +498,7 @@ std::vector<std::string> show_list(ManagerConfig *config, bool show) {
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		std::cerr << "Filesystem error: " << ex.what() << "\n";
 
	}
 
	return list;
 
}
src/CMakeLists.txt
Show inline comments
 
@@ -38,11 +38,11 @@ else(PROTOBUF_FOUND)
 
	ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC} ${SWIFTEN_SRC})
 
endif(PROTOBUF_FOUND)
 

	
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
# if (CMAKE_COMPILER_IS_GNUCXX)
 
	if (NOT WIN32)
 
		ADD_DEFINITIONS(-fPIC)
 
	endif()
 
endif()
 
# endif()
 

	
 
if (WIN32)
 
	TARGET_LINK_LIBRARIES(transport transport-plugin sqlite3 ${PQXX_LIBRARY} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
src/config.cpp
Show inline comments
 
@@ -135,18 +135,6 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 

	
 
	;
 

	
 
	// 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();
 
		BOOST_FOREACH(option &opt, parsed.options) {
 
			if (opt.unregistered && !opt.value.empty()) {
 
				m_unregistered[opt.string_key] = variable_value(opt.value[0], false);
 
			}
 
		}
 
		store(parsed, m_variables);
 
	}
 

	
 
	parsed_options parsed = parse_config_file(ifs, opts, true);
 

	
 
	bool found_working = false;
 
@@ -212,15 +200,43 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 
		parsed.options.push_back(boost::program_options::basic_option<char>("database.database", value));
 
	}
 

	
 
	std::list<std::string> has_key;
 
	BOOST_FOREACH(option &opt, parsed.options) {
 
		if (opt.unregistered) {
 
			m_unregistered[opt.string_key] = variable_value(opt.value[0], false);
 
			if (std::find(has_key.begin(), has_key.end(), opt.string_key) == has_key.end()) {
 
				has_key.push_back(opt.string_key);
 
				m_unregistered[opt.string_key] = variable_value(opt.value[0], false);
 
			}
 
			else {
 
				std::list<std::string> list;
 
				try {
 
					list = m_unregistered[opt.string_key].as<std::list<std::string> >();
 
				}
 
				catch(...) {
 
					list.push_back(m_unregistered[opt.string_key].as<std::string>());
 
				}
 
				
 
				list.push_back(opt.value[0]);
 
				m_unregistered[opt.string_key] = variable_value(list, false);
 
			}
 
		}
 
		else if (opt.value[0].find("$jid") != std::string::npos) {
 
			boost::replace_all(opt.value[0], "$jid", jid);
 
		}
 
	}
 

	
 
	// 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();
 
		BOOST_FOREACH(option &opt, parsed.options) {
 
			if (opt.unregistered && !opt.value.empty()) {
 
				m_unregistered[opt.string_key] = variable_value(opt.value[0], false);
 
			}
 
		}
 
		store(parsed, m_variables);
 
	}
 

	
 
	store(parsed, m_variables);
 
	notify(m_variables);
 

	
src/conversation.cpp
Show inline comments
 
@@ -55,6 +55,10 @@ void Conversation::destroyRoom() {
 
		Swift::MUCUserPayload *p = new Swift::MUCUserPayload ();
 
		p->addItem(item);
 

	
 
		Swift::MUCUserPayload::StatusCode c;
 
		c.code = 332;
 
		p->addStatusCode(c);
 

	
 
		presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
@@ -111,13 +115,23 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
		if (n.empty()) {
 
			n = " ";
 
		}
 
		message->setTo(m_jid);
 
		message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
		BOOST_FOREACH(const Swift::JID &jid, m_jids) {
 
			message->setTo(jid);
 
			message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
 
			m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
		}
 
	}
 
}
 

	
 
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
void Conversation::sendParticipants(const Swift::JID &to) {
 
	for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
 
		Swift::Presence::ref presence = generatePresence(it->first, it->second.flag, it->second.status, it->second.statusMessage, "");
 
		presence->setTo(to);
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
}
 

	
 
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
	std::string nickname = nick;
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
	std::string legacyName = m_legacyName;
 
@@ -127,7 +141,6 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i
 
		}
 
	}
 
	presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
	presence->setTo(m_jid);
 
	presence->setType(Swift::Presence::Available);
 

	
 
	if (!statusMessage.empty())
 
@@ -168,9 +181,29 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i
 
	}
 

	
 
	p->addItem(item);
 

	
 
	presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
 
	m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	return presence;
 
}
 

	
 
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
	Swift::Presence::ref presence = generatePresence(nick, flag, status, statusMessage, newname);
 

	
 
	if (presence->getType() == Swift::Presence::Unavailable) {
 
		m_participants.erase(nick);
 
	}
 
	else {
 
		Participant p;
 
		p.flag = flag;
 
		p.status = status;
 
		p.statusMessage = statusMessage;
 
		m_participants[nick] = p;
 
	}
 

	
 

	
 
	BOOST_FOREACH(const Swift::JID &jid, m_jids) {
 
		presence->setTo(jid);
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
	if (!newname.empty()) {
 
		handleParticipantChanged(newname, flag, status, statusMessage);
 
	}
src/conversationmanager.cpp
Show inline comments
 
@@ -89,6 +89,12 @@ void ConversationManager::resetResources() {
 
	}
 
}
 

	
 
void ConversationManager::removeJID(const Swift::JID &jid) {
 
	for (std::map<std::string, Conversation *>::const_iterator it = m_convs.begin(); it != m_convs.end(); it++) {
 
		(*it).second->removeJID(jid);
 
	}
 
}
 

	
 
void ConversationManager::handleMessageReceived(Swift::Message::ref message) {
 
// 	std::string name = message->getTo().getUnescapedNode();
 
// 	if (name.find_last_of("%") != std::string::npos) { // OK when commented
src/networkpluginserver.cpp
Show inline comments
 
@@ -56,6 +56,8 @@
 
#else
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
#include <sys/types.h>
 
#include <signal.h>
 
#include "popt.h"
 
#endif
 

	
 
@@ -1192,7 +1194,7 @@ void NetworkPluginServer::handleRoomJoined(User *user, const Swift::JID &who, co
 
	user->getConversationManager()->addConversation(conv);
 
	conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2));
 
	conv->setNickname(nickname);
 
	conv->setJID(who);
 
	conv->addJID(who);
 
}
 

	
 
void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
 
@@ -1301,6 +1303,22 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
 
		send(c->connection, message);
 
		return;
 
	}
 

	
 
	if (!msg->getSubject().empty()) {
 
		pbnetwork::ConversationMessage m;
 
		m.set_username(conv->getConversationManager()->getUser()->getJID().toBare());
 
		m.set_buddyname(conv->getLegacyName());
 
		m.set_message(msg->getSubject());
 

	
 
		std::string message;
 
		m.SerializeToString(&message);
 

	
 
		WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_ROOM_SUBJECT_CHANGED);
 

	
 
		Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
 
		send(c->connection, message);
 
		return;
 
	}
 
	
 

	
 
	std::string xhtml;
src/tests/basictest.cpp
Show inline comments
 
@@ -41,7 +41,7 @@ using namespace Transport;
 

	
 
void BasicTest::setMeUp (void) {
 
	streamEnded = false;
 
	std::istringstream ifs("service.server_mode = 1\nservice.jid=localhost");
 
	std::istringstream ifs("service.server_mode = 1\nservice.jid=localhost\nservice.more_resources=1\n");
 
	cfg = new Config();
 
	cfg->load(ifs);
 

	
 
@@ -86,6 +86,7 @@ void BasicTest::setMeUp (void) {
 
	payloadSerializers->addSerializer(new Swift::GatewayPayloadSerializer());
 

	
 
	parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
 
	parser2 = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
 

	
 
	serverFromClientSession = boost::shared_ptr<Swift::ServerFromClientSession>(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(),
 
			payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource")));
 
@@ -95,13 +96,19 @@ void BasicTest::setMeUp (void) {
 

	
 
	dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->addSession(serverFromClientSession);
 
	parser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
	parser2->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
	received.clear();
 
	received2.clear();
 
	receivedData.clear();
 
	loop->processEvents();
 
}
 

	
 
void BasicTest::tearMeDown (void) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->removeSession(serverFromClientSession);
 
	if (serverFromClientSession2) {
 
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->removeSession(serverFromClientSession2);
 
		serverFromClientSession2.reset();
 
	}
 
	delete component;
 
	delete userRegistry;
 
	delete factories;
 
@@ -109,29 +116,48 @@ void BasicTest::tearMeDown (void) {
 
	delete loop;
 
	delete cfg;
 
	delete parser;
 
	delete parser2;
 
	delete storage;
 
	delete userRegistration;
 
	delete itemsResponder;
 
	received.clear();
 
	received2.clear();
 
	receivedData.clear();
 
	receivedData2.clear();
 
}
 

	
 
void BasicTest::handleDataReceived(const Swift::SafeByteArray &data) {
 
// 	std::cout << safeByteArrayToString(data) << "\n";
 
	stream1_active = true;
 
	receivedData += safeByteArrayToString(data) + "\n";
 
	parser->parse(safeByteArrayToString(data));
 
}
 

	
 
void BasicTest::handleDataReceived2(const Swift::SafeByteArray &data) {
 
// 	std::cout << safeByteArrayToString(data) << "\n";
 
	stream1_active = false;
 
	receivedData2 += safeByteArrayToString(data) + "\n";
 
	parser2->parse(safeByteArrayToString(data));
 
}
 

	
 
void BasicTest::handleStreamStart(const Swift::ProtocolHeader&) {
 

	
 
}
 

	
 
void BasicTest::dumpReceived() {
 
	std::cout << "\nStream1:\n";
 
	std::cout << receivedData << "\n";
 
	std::cout << "Stream2:\n";
 
	std::cout << receivedData2 << "\n";
 
}
 

	
 
void BasicTest::handleElement(boost::shared_ptr<Swift::Element> element) {
 
	received.push_back(element);
 
	if (stream1_active) {
 
		received.push_back(element);
 
	}
 
	else {
 
		received2.push_back(element);
 
	}
 
}
 

	
 
void BasicTest::handleStreamEnd() {
 
@@ -159,6 +185,7 @@ Swift::Stanza *BasicTest::getStanza(boost::shared_ptr<Swift::Element> element) {
 
void BasicTest::connectUser() {
 
	CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
	userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
	userRegistry->onPasswordValid(Swift::JID("user@localhost/resource"));
 
	loop->processEvents();
 
	CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount());
 

	
 
@@ -173,9 +200,39 @@ void BasicTest::connectUser() {
 
	user->setConnected(true);
 
	CPPUNIT_ASSERT(user->isConnected() == true);
 

	
 
	CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
	CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
	CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
 
	received.clear();
 
	receivedData.clear();
 
}
 

	
 
void BasicTest::connectSecondResource() {
 
	serverFromClientSession2 = boost::shared_ptr<Swift::ServerFromClientSession>(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(),
 
			payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource2")));
 
	serverFromClientSession2->startSession();
 

	
 
	serverFromClientSession2->onDataWritten.connect(boost::bind(&BasicTest::handleDataReceived2, this, _1));
 

	
 
	dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->addSession(serverFromClientSession2);
 

	
 
	userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource2"), serverFromClientSession2.get(), Swift::createSafeByteArray("password"));
 
	userRegistry->onPasswordValid(Swift::JID("user@localhost/resource2"));
 

	
 
	loop->processEvents();
 

	
 
	Swift::Presence::ref response = Swift::Presence::create();
 
	response->setTo("localhost");
 
	response->setFrom("user@localhost/resource2");
 
	injectPresence(response);
 
	loop->processEvents();
 

	
 
	CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount());
 

	
 
	User *user = userManager->getUser("user@localhost");
 
	CPPUNIT_ASSERT(user);
 
	CPPUNIT_ASSERT_EQUAL(2, user->getResourceCount());
 

	
 
	CPPUNIT_ASSERT(getStanza(received2[1])->getPayload<Swift::DiscoInfo>());
 
}
 

	
 
void BasicTest::disconnectUser() {
src/tests/basictest.h
Show inline comments
 
@@ -205,6 +205,7 @@ class BasicTest : public Swift::XMPPParserClient {
 
		void tearMeDown (void);
 

	
 
	void handleDataReceived(const Swift::SafeByteArray &data);
 
	void handleDataReceived2(const Swift::SafeByteArray &data);
 

	
 
	void handleStreamStart(const Swift::ProtocolHeader&);
 

	
 
@@ -228,6 +229,7 @@ class BasicTest : public Swift::XMPPParserClient {
 
	}
 

	
 
	void connectUser();
 
	void connectSecondResource();
 
	void disconnectUser();
 
	void add2Buddies();
 

	
 
@@ -237,9 +239,11 @@ class BasicTest : public Swift::XMPPParserClient {
 
		bool streamEnded;
 
		UserManager *userManager;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession2;
 
		Swift::FullPayloadSerializerCollection* payloadSerializers;
 
		Swift::FullPayloadParserFactoryCollection* payloadParserFactories;
 
		Swift::XMPPParser *parser;
 
		Swift::XMPPParser *parser2;
 
		UserRegistry *userRegistry;
 
		Config *cfg;
 
		Swift::Server *server;
 
@@ -248,9 +252,12 @@ class BasicTest : public Swift::XMPPParserClient {
 
		TestingFactory *factory;
 
		Component *component;
 
		std::vector<boost::shared_ptr<Swift::Element> > received;
 
		std::vector<boost::shared_ptr<Swift::Element> > received2;
 
		std::string receivedData;
 
		std::string receivedData2;
 
		StorageBackend *storage;
 
		UserRegistration *userRegistration;
 
		DiscoItemsResponder *itemsResponder;
 
		bool stream1_active;
 
};
 

	
src/tests/config.cpp
Show inline comments
 
@@ -24,7 +24,12 @@ using namespace Transport;
 

	
 
class ConfigTest : public CPPUNIT_NS :: TestFixture{
 
	CPPUNIT_TEST_SUITE(ConfigTest);
 
	CPPUNIT_TEST(setStringTwice);
 
	CPPUNIT_TEST(updateBackendConfig);
 
	CPPUNIT_TEST(unregisteredList);
 
	CPPUNIT_TEST(unregisteredString);
 
	CPPUNIT_TEST(unregisteredListAsString);
 
	CPPUNIT_TEST(unregisteredStringAsList);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
@@ -35,6 +40,14 @@ class ConfigTest : public CPPUNIT_NS :: TestFixture{
 

	
 
		}
 

	
 
	void setStringTwice() {
 
		char *argv[3] = {"binary", "--service.jids=localhost", NULL};
 
		Config cfg(2, argv);
 
		std::istringstream ifs("service.jids = irc.freenode.org\n");
 
		cfg.load(ifs);
 
		CPPUNIT_ASSERT_EQUAL(std::string("localhost"), CONFIG_STRING(&cfg, "service.jids"));
 
	}
 

	
 
	void updateBackendConfig() {
 
		Config cfg;
 
		CPPUNIT_ASSERT(!cfg.hasKey("registration.needPassword"));
 
@@ -44,6 +57,35 @@ class ConfigTest : public CPPUNIT_NS :: TestFixture{
 
		CPPUNIT_ASSERT_EQUAL(false, CONFIG_BOOL(&cfg, "registration.needPassword"));
 
	}
 

	
 
	void unregisteredList() {
 
		Config cfg;
 
		std::istringstream ifs("service.irc_server = irc.freenode.org\nservice.irc_server=localhost\n");
 
		cfg.load(ifs);
 
		CPPUNIT_ASSERT_EQUAL(2, (int) CONFIG_LIST(&cfg, "service.irc_server").size());
 
	}
 

	
 
	void unregisteredString() {
 
		Config cfg;
 
		std::istringstream ifs("service.irc_server = irc.freenode.org");
 
		cfg.load(ifs);
 
		CPPUNIT_ASSERT_EQUAL(std::string("irc.freenode.org"), CONFIG_STRING(&cfg, "service.irc_server"));
 
	}
 

	
 
	void unregisteredListAsString() {
 
		Config cfg;
 
		std::istringstream ifs("service.irc_server = irc.freenode.orgn\nservice.irc_server = irc2.freenode.org");
 
		cfg.load(ifs);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), CONFIG_STRING_DEFAULTED(&cfg, "service.irc_server", ""));
 
	}
 

	
 
	void unregisteredStringAsList() {
 
		Config cfg;
 
		std::istringstream ifs("service.irc_server = irc.freenode.org");
 
		cfg.load(ifs);
 
		std::list<std::string> list;
 
		CPPUNIT_ASSERT_EQUAL(0, (int) CONFIG_LIST_DEFAULTED(&cfg, "service.irc_server", list).size());
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (ConfigTest);
src/tests/conversationmanager.cpp
Show inline comments
 
@@ -25,8 +25,11 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
	CPPUNIT_TEST_SUITE(ConversationManagerTest);
 
	CPPUNIT_TEST(handleNormalMessages);
 
	CPPUNIT_TEST(handleGroupchatMessages);
 
	CPPUNIT_TEST(handleGroupchatMessagesTwoResources);
 
	CPPUNIT_TEST(handleChatstateMessages);
 
	CPPUNIT_TEST(handleSubjectMessages);
 
	CPPUNIT_TEST(handleParticipantChanged);
 
	CPPUNIT_TEST(handleParticipantChangedTwoResources);
 
	CPPUNIT_TEST(handlePMFromXMPP);
 
	CPPUNIT_TEST(handleGroupchatRemoved);
 
	CPPUNIT_TEST_SUITE_END();
 
@@ -89,6 +92,38 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		received.clear();
 
	}
 

	
 
	void handleSubjectMessages() {
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "buddy1");
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setSubject("subject");
 

	
 
		// Forward it
 
		conv->handleMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getSubject());
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("buddy1@localhost/bot");
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("subject"), m_msg->getSubject());
 

	
 
		received.clear();
 
	}
 

	
 
	void handleNormalMessages() {
 
		User *user = userManager->getUser("user@localhost");
 

	
 
@@ -158,7 +193,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->setJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// reset resources should not touch this resource
 
		user->getConversationManager()->resetResources();
 
@@ -191,13 +226,55 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
 
	}
 

	
 
	void handleGroupchatMessagesTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource2");
 

	
 
		// reset resources should not touch this resource
 
		user->getConversationManager()->resetResources();
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setBody("hi there!");
 

	
 
		// Forward it
 
		conv->handleMessage(msg, "anotheruser");
 

	
 
		loop->processEvents();
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received2[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getBody());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getFrom().toString());
 

	
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource2");
 
		msg->setTo("#room@localhost");
 
		msg->setBody("response!");
 
		msg->setType(Swift::Message::Groupchat);
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
 
	}
 

	
 
	void handleParticipantChanged() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->setJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
 
@@ -246,6 +323,31 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		CPPUNIT_ASSERT_EQUAL(303, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 
	}
 

	
 
	void handleParticipantChangedTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource2");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received2[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
	}
 

	
 
	void handlePMFromXMPP() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
@@ -293,6 +395,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::None, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/nickname"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT_EQUAL(332, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 
	}
 

	
 
};
src/tests/user.cpp
Show inline comments
 
@@ -25,7 +25,10 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST(sendCurrentPresence);
 
    CPPUNIT_TEST(handlePresence);
 
	CPPUNIT_TEST(handlePresenceJoinRoom);
 
	CPPUNIT_TEST(handlePresenceJoinRoomTwoResources);
 
	CPPUNIT_TEST(handlePresenceLeaveRoom);
 
	CPPUNIT_TEST(handlePresenceLeaveRoomTwoResources);
 
	CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesOneDisconnects);
 
	CPPUNIT_TEST(leaveJoinedRoom);
 
	CPPUNIT_TEST(handleDisconnected);
 
	CPPUNIT_TEST(handleDisconnectedReconnect);
 
@@ -139,6 +142,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 

	
 
		// simulate that backend joined the room
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		conv->addJID("user@localhost/resource");
 
		user->getConversationManager()->addConversation(conv);
 

	
 
		received.clear();
 
@@ -154,6 +158,41 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 
	}
 

	
 
	void handlePresenceJoinRoomTwoResources() {
 
		handlePresenceJoinRoom();
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		// Add 1 participant
 
		Conversation *conv = user->getConversationManager()->getConversation("#room");
 
		conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
 

	
 
		// Connect 2nd resource
 
		connectSecondResource();
 
		received2.clear();
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource2");
 

	
 
		Swift::MUCPayload *payload = new Swift::MUCPayload();
 
		payload->setPassword("password");
 
		response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
 
		injectPresence(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[1])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received2[1])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
	}
 

	
 
	void handlePresenceLeaveRoom() {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
@@ -173,6 +212,71 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 
	}
 

	
 
	void handlePresenceLeaveRoomTwoResources() {
 
		handlePresenceJoinRoomTwoResources();
 
		received.clear();
 

	
 
		// User is still connected from resource2, so he should not leave the room
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource");
 
		response->setType(Swift::Presence::Unavailable);
 

	
 
		Swift::MUCPayload *payload = new Swift::MUCPayload();
 
		payload->setPassword("password");
 
		response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
 
		injectPresence(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 

	
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 

	
 
		// disconnect also from resource
 
		// User is still connected from resource2, so he should not leave the room
 
		response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource2");
 
		response->setType(Swift::Presence::Unavailable);
 

	
 
		payload = new Swift::MUCPayload();
 
		payload->setPassword("password");
 
		response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
 
		injectPresence(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 

	
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 
	}
 

	
 
	void handlePresenceLeaveRoomTwoResourcesOneDisconnects() {
 
		handlePresenceJoinRoomTwoResources();
 
		received.clear();
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		// User is still connected from resource2, so he should not leave the room
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("localhost/hanzz");
 
		response->setFrom("user@localhost/resource");
 
		response->setType(Swift::Presence::Unavailable);
 
		injectPresence(response);
 
		loop->processEvents();
 

	
 

	
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 

	
 
		Conversation *conv = user->getConversationManager()->getConversation("#room");
 
		CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size());
 
		CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front());
 
	}
 

	
 
	void leaveJoinedRoom() {
 
		User *user = userManager->getUser("user@localhost");
 
		handlePresenceJoinRoom();
src/tests/usermanager.cpp
Show inline comments
 
@@ -23,6 +23,7 @@ using namespace Transport;
 
class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(UserManagerTest);
 
	CPPUNIT_TEST(connectUser);
 
	CPPUNIT_TEST(connectTwoResources);
 
	CPPUNIT_TEST(connectUserTransportDisabled);
 
	CPPUNIT_TEST(connectUserRegistrationNeeded);
 
	CPPUNIT_TEST(connectUserRegistrationNeededRegistered);
 
@@ -86,6 +87,22 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType());
 
	}
 

	
 
	void connectTwoResources() {
 
		connectUser();
 
		add2Buddies();
 
		connectSecondResource();
 

	
 
		// we should get presences
 
		CPPUNIT_ASSERT_EQUAL(4, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[2])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[2]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast<Swift::Presence *>(getStanza(received2[2]))->getStatus());
 

	
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[3])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[3]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast<Swift::Presence *>(getStanza(received2[3]))->getStatus());
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (UserManagerTest);
src/user.cpp
Show inline comments
 
@@ -218,10 +218,17 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
	if (isMUC) {
 
		if (presence->getType() == Swift::Presence::Unavailable) {
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			Conversation *conv = m_conversationManager->getConversation(room);
 
			if (conv) {
 
				conv->removeJID(presence->getFrom());
 
				if (!conv->getJIDs().empty()) {
 
					return;
 
				}
 
			}
 

	
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
 
			onRoomLeft(room);
 

	
 
			Conversation *conv = m_conversationManager->getConversation(room);
 
			if (conv) {
 
				m_conversationManager->removeConversation(conv);
 
				delete conv;
 
@@ -235,8 +242,15 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
				onReadyToConnect();
 
			}
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			if (m_conversationManager->getConversation(room) != NULL) {
 
				LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource());
 
			Conversation *conv = m_conversationManager->getConversation(room);
 
			if (conv != NULL) {
 
				if (std::find(conv->getJIDs().begin(), conv->getJIDs().end(), presence->getFrom()) != conv->getJIDs().end()) {
 
					LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource());
 
				}
 
				else {
 
					conv->addJID(presence->getFrom());
 
					conv->sendParticipants(presence->getFrom());
 
				}
 
				return;
 
			}
 

	
 
@@ -249,6 +263,10 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
		}
 
		return;
 
	}
 
	
 
	if (presence->getType() == Swift::Presence::Unavailable) {
 
		m_conversationManager->removeJID(presence->getFrom());
 
	}
 

	
 

	
 
	// User wants to disconnect this resource
 
@@ -266,13 +284,14 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
		}
 
		else {
 
			sendCurrentPresence();
 
			// This resource is new, so we have to send buddies presences
 
			if (currentResourcesCount != m_resources) {
 
				m_rosterManager->sendCurrentPresences(presence->getFrom());
 
			}
 
		}
 
	}
 

	
 
	// This resource is new, so we have to send buddies presences
 
	if (presence->getType() != Swift::Presence::Unavailable && currentResourcesCount != m_resources) {
 
		m_rosterManager->sendCurrentPresences(presence->getFrom());
 
	}
 

	
 
	m_resources = currentResourcesCount;
 

	
 

	
src/usermanager.cpp
Show inline comments
 
@@ -31,7 +31,9 @@
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Elements/StreamError.h"
 
#ifndef __FreeBSD__
 
#include "malloc.h"
 
#endif
 
// #include "valgrind/memcheck.h"
 

	
 
namespace Transport {
 
@@ -124,8 +126,10 @@ void UserManager::removeUser(User *user, bool onUserBehalf) {
 
	onUserDestroyed(user);
 
	delete user;
 
#ifndef WIN32
 
#ifndef __FreeBSD__
 
	malloc_trim(0);
 
#endif
 
#endif
 
// 	VALGRIND_DO_LEAK_CHECK;
 
}
 

	
 
@@ -340,7 +344,7 @@ void UserManager::handleMessageReceived(Swift::Message::ref message) {
 
		messageToBackendSent();
 
	}
 

	
 
	if (message->getBody().empty() && !statePayload) {
 
	if (message->getBody().empty() && !statePayload && message->getSubject().empty()) {
 
		return;
 
	}
 

	
0 comments (0 inline, 0 general)