Changeset - 316a26474f03
CMakeLists.txt
Show inline comments
 
@@ -32,96 +32,109 @@ find_package(Swiften REQUIRED)
 
set(openssl_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(openssl REQUIRED)
 

	
 
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
if (WIN32)
 
set(Boost_USE_STATIC_LIBS        ON)
 
set(Boost_USE_MULTITHREADED      ON)
 
set(Boost_USE_STATIC_RUNTIME    OFF)
 
endif()
 
find_package(Boost COMPONENTS program_options date_time system filesystem regex thread signals REQUIRED)
 
message( STATUS "Found Boost: ${Boost_LIBRARIES}, ${Boost_INCLUDE_DIR}")
 

	
 
set(Protobuf_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Protobuf REQUIRED)
 

	
 
set(Communi_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Communi)
 

	
 
set(log4cxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(log4cxx)
 

	
 
set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(event)
 

	
 
set(pqxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(pqxx)
 

	
 
find_package(Doxygen)
 

	
 
INCLUDE(FindQt4)
 
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork)
 

	
 
# ADD_DEFINITIONS(${SWIFTEN_CFLAGS})
 
ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS)
 
ADD_DEFINITIONS(-DBOOST_FILESYSTEM_VERSION=2)
 

	
 
message("  Supported features")
 
message("-----------------------")
 

	
 
if (SPECTRUM_VERSION)
 
	ADD_DEFINITIONS(-DSPECTRUM_VERSION="${SPECTRUM_VERSION}")
 
else (SPECTRUM_VERSION)
 
	if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
 
		execute_process(COMMAND git "--git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git" rev-parse --short HEAD
 
						OUTPUT_VARIABLE GIT_REVISION
 
						OUTPUT_STRIP_TRAILING_WHITESPACE
 
		)
 
		set(SPECTRUM_VERSION 2.0.0-beta-git-${GIT_REVISION})
 
		ADD_DEFINITIONS(-DSPECTRUM_VERSION="${SPECTRUM_VERSION}")
 
	else (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
 
		set(SPECTRUM_VERSION 2.0.0-alpha)
 
		ADD_DEFINITIONS(-DSPECTRUM_VERSION="${SPECTRUM_VERSION}")
 
	endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
 
endif (SPECTRUM_VERSION)
 

	
 
message("Version           : " ${SPECTRUM_VERSION})
 

	
 
if (SQLITE3_FOUND)
 
	ADD_DEFINITIONS(-DWITH_SQLITE)
 
	include_directories(${SQLITE3_INCLUDE_DIR})
 
	message("SQLite3           : yes")
 
else (SQLITE3_FOUND)
 
	set(SQLITE3_LIBRARIES "")
 
	message("SQLite3           : no")
 
endif (SQLITE3_FOUND)
 

	
 
if (MYSQL_FOUND)
 
	ADD_DEFINITIONS(-DWITH_MYSQL)
 
	include_directories(${MYSQL_INCLUDE_DIR})
 
	message("MySQL             : yes")
 
else (MYSQL_FOUND)
 
	set(MYSQL_LIBRARIES "")
 
	message("MySQL             : no (install mysql-devel)")
 
endif (MYSQL_FOUND)
 

	
 
if (PQXX_FOUND)
 
	ADD_DEFINITIONS(-DWITH_PQXX)
 
	include_directories(${PQXX_INCLUDE_DIR})
 
	message("PostgreSQL        : yes")
 
else (PQXX_FOUND)
 
	set(PQXX_LIBRARY "")
 
	set(PQ_LIBRARY "")
 
	message("PostgreSQL        : no (install libpqxx-devel)")
 
endif (PQXX_FOUND)
 

	
 
if (PROTOBUF_FOUND)
 
	ADD_DEFINITIONS(-DWITH_PROTOBUF)
 
	include_directories(${PROTOBUF_INCLUDE_DIRS})
 
	message("Network plugins   : yes")
 

	
 
	if(PURPLE_LIBRARY AND PURPLE_INCLUDE_DIR)
 
		message("Libpurple plugin  : yes")
 
		include_directories(${PURPLE_INCLUDE_DIR})
 
		include_directories(${GLIB2_INCLUDE_DIR})
 
	else()
 
		message("Libpurple plugin  : no (install libpurple)")
 
	endif()
 

	
 
	if (HAVE_EVENT)
 
		ADD_DEFINITIONS(-DWITH_LIBEVENT)
 
		include_directories(${EVENT_INCLUDE_DIRS})
 
		message("  libev eventloop : yes")
 
	else()
 
		message("  libev eventloop : no (install libev-devel)")
 
	endif()
 

	
 
	if(IRC_FOUND)
 
		ADD_DEFINITIONS(-DCOMMUNI_SHARED)
 
		message("IRC plugin        : yes")
ChangeLog
Show inline comments
 
Version 2.0.0-beta  (X-X-X):
 
	General:
 
	* Fixed registration from Pidgin.
 
	* Unsubscribe presence sent to some buddy doesn't disconnect the account.
 
	* Remote Roster requests are not sent to resources, but to bare JID.
 
	* Added automatic reconnection in case of non-fatal error.
 
	* Added more error messages.
 

	
 
version 2.0.0 alpha (2011-12-06):
 
	General:
 
	* First Spectrum 2.0.0 alpha release, check more on
 
	  http://spectrum.im/projects/spectrum/wiki/Spectrum_200_alpha
backends/libcommuni/session.cpp
Show inline comments
 
@@ -5,73 +5,76 @@
 
 * restriction applied to their modification, redistribution, using and so on.
 
 * You can study them, modify them, use them in your own program - either
 
 * completely or partially. By using it you may give me some credits in your
 
 * program, but you don't have to.
 
 */
 

	
 
#include "session.h"
 
#include <QtCore>
 
#include <iostream>
 
#include "Swiften/Elements/StatusShow.h"
 
#include <IrcCommand>
 
#include <IrcMessage>
 

	
 
#include "log4cxx/logger.h"
 

	
 
using namespace log4cxx;
 

	
 
static LoggerPtr logger = log4cxx::Logger::getLogger("IRCSession");
 

	
 
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
 
{
 
	this->np = np;
 
	this->user = user;
 
	this->suffix = suffix;
 
	m_connected = false;
 
	rooms = 0;
 
	connect(this, SIGNAL(disconnected()), SLOT(on_disconnected()));
 
	connect(this, SIGNAL(connected()), SLOT(on_connected()));
 
	connect(this, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(onMessageReceived(IrcMessage*)));
 
}
 

	
 
void MyIrcSession::on_connected() {
 
	m_connected = true;
 
	if (suffix.empty()) {
 
		np->handleConnected(user);
 
	}
 

	
 
	for(std::list<std::string>::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
 
		sendCommand(IrcCommand::createJoin(QString::fromStdString(*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)));
 
	}
 
}
 

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

	
 
bool MyIrcSession::correctNickname(std::string &nickname) {
 
	bool flags = 0;
 
	switch(nickname.at(0)) {
 
		case '@': nickname = nickname.substr(1); flags = 1; break;
 
		case '+': nickname = nickname.substr(1); break;
 
		default: break;
 
	}
 
	return flags;
 
}
 

	
 
void MyIrcSession::on_joined(IrcMessage *message) {
 
	IrcJoinMessage *m = (IrcJoinMessage *) message;
 
	bool flags = 0;
 
	std::string nickname = m->sender().name().toStdString();
 
	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());
 
}
 

	
 

	
 
void MyIrcSession::on_parted(IrcMessage *message) {
 
	IrcPartMessage *m = (IrcPartMessage *) message;
 
@@ -135,78 +138,89 @@ void MyIrcSession::on_topicChanged(IrcMessage *message) {
 
	LOG4CXX_INFO(logger, user << ": " << nickname << " topic changed to " << m->topic().toStdString());
 
	np->handleSubject(user, m->channel().toStdString() + suffix, m->topic().toStdString(), nickname);
 
}
 

	
 
void MyIrcSession::on_messageReceived(IrcMessage *message) {
 
	IrcPrivateMessage *m = (IrcPrivateMessage *) message;
 

	
 
	std::string target = m->target().toStdString();
 
	LOG4CXX_INFO(logger, user << ": Message from " << target);
 
	if (target.find("#") == 0) {
 
		bool flags = 0;
 
		std::string nickname = m->sender().name().toStdString();
 
		flags = correctNickname(nickname);
 
		np->handleMessage(user, target + suffix, m->message().toStdString(), nickname);
 
	}
 
	else {
 
		bool flags = 0;
 
		std::string nickname = m->sender().name().toStdString();
 
		flags = correctNickname(nickname);
 
		np->handleMessage(user, nickname, m->message().toStdString());
 
	}
 
}
 

	
 
void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
 
	QString channel;
 
	QStringList members;
 

	
 
	IrcNumericMessage *m = (IrcNumericMessage *) message;
 
	switch (m->code()) {
 
		case 332:
 
			m_topicData = m->parameters().value(2).toStdString();
 
			break;
 
		case 333:
 
			 np->handleSubject(user, m->parameters().value(1).toStdString() + suffix, m_topicData, m->parameters().value(2).toStdString());
 
			break;
 
		case 353:
 
			QString channel = m->parameters().value(2);
 
			QStringList members = m->parameters().value(3).split(" ");
 
			channel = m->parameters().value(2);
 
			members = m->parameters().value(3).split(" ");
 

	
 
			for (int i = 0; i < members.size(); i++) {
 
				bool flags = 0;
 
				std::string nickname = members.at(i).toStdString();
 
				flags = correctNickname(nickname);
 
				m_modes[channel.toStdString() + nickname] = flags;
 
				np->handleParticipantChanged(user, nickname, channel.toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE);
 
			}
 
			break;
 
		case 432:
 
			if (m_connected) {
 
				np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
 
			}
 
			break;
 
		default:
 
			break;
 
	}
 

	
 
	//qDebug() << "numeric message received:" << receiver() << origin << code << params;
 
}
 

	
 
void MyIrcSession::onMessageReceived(IrcMessage *message) {
 
	LOG4CXX_INFO(logger, user << ": " << message->toString().toStdString());
 
	switch (message->type()) {
 
		case IrcMessage::Join:
 
			on_joined(message);
 
			break;
 
		case IrcMessage::Part:
 
			on_parted(message);
 
			break;
 
		case IrcMessage::Quit:
 
			on_quit(message);
 
			break;
 
		case IrcMessage::Nick:
 
			on_nickChanged(message);
 
			break;
 
		case IrcMessage::Mode:
 
			on_modeChanged(message);
 
			break;
 
		case IrcMessage::Topic:
 
			on_topicChanged(message);
 
			break;
 
		case IrcMessage::Private:
 
			on_messageReceived(message);
 
			break;
 
		case IrcMessage::Numeric:
 
			on_numericMessageReceived(message);
 
			break;
 
		default:break;
 
	}
 
}
backends/libcommuni/session.h
Show inline comments
 
@@ -44,48 +44,49 @@ public:
 

	
 
	bool correctNickname(std::string &nickname);
 

	
 
	void on_joined(IrcMessage *message);
 
	void on_parted(IrcMessage *message);
 
	void on_quit(IrcMessage *message);
 
	void on_nickChanged(IrcMessage *message);
 
	void on_modeChanged(IrcMessage *message);
 
	void on_topicChanged(IrcMessage *message);
 
	void on_messageReceived(IrcMessage *message);
 
	void on_numericMessageReceived(IrcMessage *message);
 

	
 
protected Q_SLOTS:
 
	void on_connected();
 
	void on_disconnected();
 

	
 
	void onMessageReceived(IrcMessage* message);
 

	
 
protected:
 
	NetworkPlugin *np;
 
	std::string user;
 
	std::string m_identify;
 
	std::list<std::string> m_autoJoin;
 
	std::string m_topicData;
 
	bool m_connected;
 
};
 

	
 
//class MyIrcBuffer : public Irc::Buffer
 
//{
 
//    Q_OBJECT
 

	
 
//public:
 
//	MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent);
 
//	NetworkPlugin *np;
 
//	std::string user;
 
//	MyIrcSession *p;
 
//	std::string m_topicData;
 
//		std::string suffix;
 

	
 
//protected Q_SLOTS:
 
//    void on_receiverChanged(const QString& receiver);
 
//    void on_joined(const QString& origin);
 
//    void on_parted(const QString& origin, const QString& message);
 
//    void on_quit(const QString& origin, const QString& message);
 
//    void on_nickChanged(const QString& origin, const QString& nick);
 
//    void on_modeChanged(const QString& origin, const QString& mode, const QString& args);
 
//    void on_topicChanged(const QString& origin, const QString& topic);
 
//    void on_invited(const QString& origin, const QString& receiver, const QString& channel);
 
//    void on_kicked(const QString& origin, const QString& nick, const QString& message);
backends/libpurple/main.cpp
Show inline comments
 
@@ -420,48 +420,58 @@ spectrum_markup_linkify(const char *text)
 
		ret = g_string_append_c(ret, *c);
 
		c++;
 

	
 
	}
 
	return g_string_free(ret, FALSE);
 
}
 

	
 
struct authRequest {
 
	PurpleAccountRequestAuthorizationCb authorize_cb;
 
	PurpleAccountRequestAuthorizationCb deny_cb;
 
	void *user_data;
 
	std::string who;
 
	PurpleAccount *account;
 
	std::string mainJID;	// JID of user connected with this request
 
};
 

	
 
static void * requestInput(const char *title, const char *primary,const char *secondary, const char *default_value, gboolean multiline, gboolean masked, gchar *hint,const char *ok_text, GCallback ok_cb,const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data) {
 
	if (primary) {
 
		std::string primaryString(primary);
 
		if (primaryString == "Authorization Request Message:") {
 
			LOG4CXX_INFO(logger, "Authorization Request Message: calling ok_cb(...)");
 
			((PurpleRequestInputCb) ok_cb)(user_data, "Please authorize me.");
 
			return NULL;
 
		}
 
		else if (primaryString == "Authorization Request Message:") {
 
			LOG4CXX_INFO(logger, "Authorization Request Message: calling ok_cb(...)");
 
			((PurpleRequestInputCb) ok_cb)(user_data, "Please authorize me.");
 
			return NULL;
 
		}
 
		else if (primaryString == "Authorization Denied Message:") {
 
			LOG4CXX_INFO(logger, "Authorization Deined Message: calling ok_cb(...)");
 
			((PurpleRequestInputCb) ok_cb)(user_data, "Authorization denied.");
 
			return NULL;
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, "Unhandled request input. primary=" << primaryString);
 
		}
 
	}
 
	else if (title) {
 
		std::string titleString(title);
 
		if (titleString == "Xfire Invitation Message") {
 
			LOG4CXX_INFO(logger, "Authorization Request Message: calling ok_cb(...)");
 
			((PurpleRequestInputCb) ok_cb)(user_data, "Please authorize me.");
 
			return NULL;
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, "Unhandled request input. title=" << titleString);
 
		}
 
	}
 
	else {
 
		LOG4CXX_WARN(logger, "Request input without primary string");
 
	}
 
	return NULL;
 
}
 

	
 
static void *requestAction(const char *title, const char *primary, const char *secondary, int default_action, PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data, size_t action_count, va_list actions){
 
	std::string t(title ? title : "NULL");
 
	if (t == "SSL Certificate Verification") {
 
@@ -583,53 +593,55 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
				i++;
 
			}
 
			g_strfreev (keys);
 
		}
 

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

	
 
			if (password.empty()) {
 
				LOG4CXX_INFO(logger,  name.c_str() << ": Empty password");
 
				np->handleDisconnected(user, 0, "Empty password.");
 
				return;
 
			}
 

	
 
			if (!purple_find_prpl(protocol.c_str())) {
 
				LOG4CXX_INFO(logger,  name.c_str() << ": Invalid protocol '" << protocol << "'");
 
				np->handleDisconnected(user, 0, "Invalid protocol " + protocol);
 
				return;
 
			}
 

	
 
			LOG4CXX_INFO(logger,  "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
			if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL){
 

	
 
			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());
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'");
 
				account = purple_account_new(name.c_str(), protocol.c_str());
 
				purple_accounts_add(account);
 
			}
 

	
 
			m_sessions[user] = account;
 
			m_accounts[account] = user;
 

	
 
			// Default avatar
 
			setDefaultAvatar(account, legacyName);
 

	
 
			purple_account_set_password(account, password.c_str());
 
			purple_account_set_bool(account, "custom_smileys", FALSE);
 
			purple_account_set_bool(account, "direct_connect", FALSE);
 

	
 
			setDefaultAccountOptions(account);
 

	
 
			purple_account_set_enabled(account, "spectrum", TRUE);
 
			if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
				purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
 
			}
 

	
 
			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);
 
@@ -1057,48 +1069,50 @@ static std::vector<std::string> getGroups(PurpleBuddy *m_buddy) {
 
		GSList *buddies = purple_find_buddies(purple_buddy_get_account(m_buddy), purple_buddy_get_name(m_buddy));
 
		while(buddies) {
 
			PurpleGroup *g = purple_buddy_get_group((PurpleBuddy *) buddies->data);
 
			buddies = g_slist_delete_link(buddies, buddies);
 

	
 
			if(g && purple_group_get_name(g)) {
 
				groups.push_back(purple_group_get_name(g));
 
			}
 
		}
 
	}
 

	
 
	if (groups.empty()) {
 
		groups.push_back("Buddies");
 
	}
 

	
 
	return groups;
 
}
 

	
 
static void buddyListNewNode(PurpleBlistNode *node) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
		return;
 
	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));
 

	
 
	// Status
 
	pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
 
	std::string message;
 
	getStatus(buddy, status, message);
 

	
 
	// Tooltip
 
	PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account));
 
	PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 

	
 
	bool blocked = false;
 
	if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
 
		if (prpl_info && prpl_info->tooltip_text) {
 
			PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
 
			prpl_info->tooltip_text(buddy, user_info, true);
 
			GList *entries = purple_notify_user_info_get_entries(user_info);
 

	
 
			while (entries) {
 
				PurpleNotifyUserInfoEntry *entry = (PurpleNotifyUserInfoEntry *)(entries->data);
 
				if (purple_notify_user_info_entry_get_label(entry) && purple_notify_user_info_entry_get_value(entry)) {
 
					std::string label = purple_notify_user_info_entry_get_label(entry);
 
					if (label == "Blocked" ) {
 
						if (std::string(purple_notify_user_info_entry_get_value(entry)) == "Yes") {
 
							blocked = true;
 
							break;
cmake_modules/pqxxConfig.cmake
Show inline comments
 
new file 100644
 
FIND_PATH(PQXX_INCLUDE_DIR pqxx/pqxx PATHS)
 
MARK_AS_ADVANCED(PQXX_INCLUDE_DIR)
 

	
 
FIND_LIBRARY(PQXX_LIBRARY pqxx )
 
MARK_AS_ADVANCED(PQXX_LIBRARY)
 

	
 
FIND_LIBRARY(PQ_LIBRARY pq )
 
MARK_AS_ADVANCED(PQ_LIBRARY)
 

	
 
if(PQXX_LIBRARY AND PQ_LIBRARY AND PQXX_INCLUDE_DIR)
 
	set( PQXX_FOUND 1 )
 
	message( STATUS "Found pqxx: ${PQXX_LIBRARY}, ${PQ_LIBRARY}, ${PQXX_INCLUDE_DIR}")
 
else()
 
	message(STATUS "Could NOT find pqxx and pq library")
 
endif()
 

	
include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp
Show inline comments
 
/*
 
 * Copyright (c) 2011 Tobias Markmann
 
 * Licensed under the simplified BSD license.
 
 * See Documentation/Licenses/BSD-simplified.txt for more information.
 
 */
 

	
 
#include "CombinedOutgoingFileTransferManager.h"
 

	
 
#include <boost/smart_ptr/make_shared.hpp>
 

	
 
#include <Swiften/JID/JID.h>
 
#include "Swiften/Disco/EntityCapsProvider.h"
 
#include <Swiften/Jingle/JingleSessionManager.h>
 
#include <Swiften/Jingle/JingleSessionImpl.h>
 
#include <Swiften/Jingle/JingleContentID.h>
 
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
 
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
 
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
 
#include <Swiften/Base/IDGenerator.h>
 
#include <Swiften/Elements/Presence.h>
 
#include <Swiften/Presence/PresenceOracle.h>
 
#include <Swiften/Base/foreach.h>
 

	
 

	
 
namespace Swift {
 

	
 
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
 
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
 
	idGenerator = new IDGenerator();
 
}
 

	
 
CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() {
 
	delete idGenerator;
 
}
 

	
 
boost::shared_ptr<OutgoingFileTransfer> CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) {
 
	// check if receipient support Jingle FT
 
	boost::optional<JID> fullJID = highestPriorityJIDSupportingJingle(receipient);
 
	if (!fullJID.is_initialized()) {
 
		fullJID = highestPriorityJIDSupportingSI(receipient);
 
	}
 
	else {
 
		JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter);
 

	
 
		//jsManager->getSession(receipient, idGenerator->generateID());
 
		assert(jingleSession);
 
		jsManager->registerOutgoingSession(from, jingleSession);
 
		boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT =  boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy));
 
		return jingleFT;
 
	}
 

	
 
	if (!fullJID.is_initialized()) {
include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h
Show inline comments
 
/*
 
 * Copyright (c) 2011 Tobias Markmann
 
 * Licensed under the simplified BSD license.
 
 * See Documentation/Licenses/BSD-simplified.txt for more information.
 
 */
 

	
 
#pragma once
 

	
 
#include <boost/shared_ptr.hpp>
 
#include <boost/optional.hpp>
 

	
 
#include <Swiften/JID/JID.h>
 

	
 
#include "transport/presenceoracle.h"
 

	
 
namespace Swift {
 

	
 
class JingleSessionManager;
 
class IQRouter;
 
class EntityCapsProvider;
 
class RemoteJingleTransportCandidateSelectorFactory;
 
class LocalJingleTransportCandidateGeneratorFactory;
 
class OutgoingFileTransfer;
 
class JID;
 
class IDGenerator;
 
class ReadBytestream;
 
class StreamInitiationFileInfo;
 
class SOCKS5BytestreamRegistry;
 
class SOCKS5BytestreamProxy;
 
class SOCKS5BytestreamServer;
 
class PresenceOracle;
 

	
 
class CombinedOutgoingFileTransferManager {
 
public:
 
	CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
 
	CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
 
	~CombinedOutgoingFileTransferManager();
 
	
 
	boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
 

	
 
private:
 
	boost::optional<JID> highestPriorityJIDSupportingJingle(const JID& bareJID);
 
	boost::optional<JID> highestPriorityJIDSupportingSI(const JID& bareJID);
 
	JingleSessionManager* jsManager;
 
	IQRouter* iqRouter;
 
	EntityCapsProvider* capsProvider;
 
	RemoteJingleTransportCandidateSelectorFactory* remoteFactory;
 
	LocalJingleTransportCandidateGeneratorFactory* localFactory;
 
	IDGenerator *idGenerator;
 
	SOCKS5BytestreamRegistry* bytestreamRegistry;
 
	SOCKS5BytestreamProxy* bytestreamProxy;
 
	PresenceOracle* presenceOracle;
 
	Transport::PresenceOracle* presenceOracle;
 
	SOCKS5BytestreamServer *bytestreamServer;
 
};
 

	
 
}
include/transport/pqxxbackend.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
 

	
 
#ifdef WITH_PQXX
 

	
 
#include <string>
 
#include <map>
 
#include "Swiften/Swiften.h"
 
#include "transport/storagebackend.h"
 
#include "transport/config.h"
 
#include <pqxx/pqxx>
 

	
 
namespace Transport {
 

	
 
/// Used to store transport data into SQLite3 database.
 
class PQXXBackend : public StorageBackend
 
{
 
	public:
 
		/// Creates new PQXXBackend instance.
 
		/// \param config cofiguration, this class uses following Config values:
 
		/// 	- database.database - path to SQLite3 database file, database file is created automatically
 
		/// 	- service.prefix - prefix for tables created by createDatabase method
 
		PQXXBackend(Config *config);
 

	
 
		/// Destructor.
 
		~PQXXBackend();
 

	
 
		/// Connects to the database and creates it if it's needed. This method call createDatabase() function
 
		/// automatically.
 
		/// \return true if database is opened successfully.
 
		bool connect();
 
		void disconnect();
 

	
 
		/// Creates database structure.
 
		/// \see connect()
 
		/// \return true if database structure has been created successfully. Note that it returns True also if database structure
 
		/// already exists.
 
		bool createDatabase();
 

	
 
		/// Stores user into database.
 
		/// \param user user struct containing all information about user which have to be stored
 
		void setUser(const UserInfo &user);
 

	
 
		/// Gets user data from database and stores them into user reference.
 
		/// \param barejid barejid of user
 
		/// \param user UserInfo object where user data will be stored
 
		/// \return true if user has been found in database
 
		bool getUser(const std::string &barejid, UserInfo &user);
 

	
 
		/// Changes users online state variable in database.
 
		/// \param id id of user - UserInfo.id
 
		/// \param online online state
 
		void setUserOnline(long id, bool online);
 

	
 
		/// Removes user and all connected data from database.
 
		/// \param id id of user - UserInfo.id
 
		/// \return true if user has been found in database and removed
 
		bool removeUser(long id);
 

	
 
		/// Returns JIDs of all buddies in user's roster.
 
		/// \param id id of user - UserInfo.id
 
		/// \param roster string list used to store user's roster
 
		/// \return true if user has been found in database and roster has been fetched
 
		bool getBuddies(long id, std::list<BuddyInfo> &roster);
 

	
 
		bool getOnlineUsers(std::vector<std::string> &users);
 

	
 
		long addBuddy(long userId, const BuddyInfo &buddyInfo);
 

	
 
		void updateBuddy(long userId, const BuddyInfo &buddyInfo);
 
		void removeBuddy(long id) {}
 

	
 
		void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
 
		void updateUserSetting(long userId, const std::string &variable, const std::string &value);
 

	
 
		void beginTransaction();
 
		void commitTransaction();
 

	
 
	private:
 
		bool exec(const std::string &query, bool show_error = true);
 
		bool exec(pqxx::work &txn, const std::string &query, bool show_error = true);
 
		Config *m_config;
 
		std::string m_prefix;
 

	
 
		pqxx::connection *m_conn;
 
};
 

	
 
}
 

	
 
#endif
include/transport/presenceoracle.h
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
 
 */
 

	
 
#pragma once
 

	
 
#include <map>
 

	
 
#include <string>
 
#include <Swiften/Elements/Presence.h>
 
#include <Swiften/Client/StanzaChannel.h>
 

	
 
#include <Swiften/Base/boost_bsignals.h>
 

	
 
namespace Transport {
 

	
 
class PresenceOracle {
 
	public:
 
		PresenceOracle(Swift::StanzaChannel* stanzaChannel);
 
		~PresenceOracle();
 

	
 
		Swift::Presence::ref getLastPresence(const Swift::JID&) const;
 
		Swift::Presence::ref getHighestPriorityPresence(const Swift::JID& bareJID) const;
 
		std::vector<Swift::Presence::ref> getAllPresence(const Swift::JID& bareJID) const;
 

	
 
	public:
 
		boost::signal<void (Swift::Presence::ref)> onPresenceChange;
 

	
 
	private:
 
		void handleIncomingPresence(Swift::Presence::ref presence);
 
		void handleStanzaChannelAvailableChanged(bool);
 

	
 
	private:
 
		typedef std::map<Swift::JID, Swift::Presence::ref> PresenceMap;
 
		typedef std::map<Swift::JID, PresenceMap> PresencesMap;
 
		PresencesMap entries_;
 
		Swift::StanzaChannel* stanzaChannel_;
 
};
 

	
 
}
 

	
include/transport/transport.h
Show inline comments
 
@@ -6,58 +6,58 @@
 
 * 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/Server/Server.h"
 
#include "Swiften/Disco/GetDiscoInfoRequest.h"
 
#include "Swiften/Disco/EntityCapsManager.h"
 
#include "Swiften/Disco/CapsManager.h"
 
#include "Swiften/Disco/CapsMemoryStorage.h"
 
#include "Swiften/Presence/PresenceOracle.h"
 
#include "Swiften/Network/BoostTimerFactory.h"
 
#include "Swiften/Network/BoostIOServiceThread.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include "Swiften/Base/SafeByteArray.h"
 
#include "Swiften/Jingle/JingleSessionManager.h"
 

	
 
#include <boost/bind.hpp>
 
#include "transport/config.h"
 
#include "transport/factory.h"
 
#include "transport/presenceoracle.h"
 

	
 
namespace Transport {
 
	// typedef enum { 	CLIENT_FEATURE_ROSTERX = 2,
 
	// 				CLIENT_FEATURE_XHTML_IM = 4,
 
	// 				CLIENT_FEATURE_FILETRANSFER = 8,
 
	// 				CLIENT_FEATURE_CHATSTATES = 16
 
	// 				} SpectrumImportantFeatures;
 
	// 
 
	class StorageBackend;
 
	class DiscoInfoResponder;
 
	class DiscoItemsResponder;
 
	class Factory;
 
	class UserRegistry;
 

	
 
	/// Represents one transport instance.
 

	
 
	/// It's used to connect the Jabber server and provides transaction layer
 
	/// between Jabber server and other classes.
 
	///
 
	/// In server mode it represents Jabber server to which users can connect and use
 
	/// it as transport.
 
	class Component {
 
		public:
 
			/// Creates new Component instance.
 
@@ -71,49 +71,49 @@ namespace Transport {
 
			/// 	- service.server_mode
 
			/// \param factory Transport Abstract factory used to create basic transport structures.
 
			Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry = NULL);
 

	
 
			/// Component destructor.
 
			~Component();
 

	
 
			/// Returns Swift::StanzaChannel associated with this Transport::Component.
 

	
 
			/// It can be used to send presences and other stanzas.
 
			/// \return Swift::StanzaChannel associated with this Transport::Component.
 
			Swift::StanzaChannel *getStanzaChannel();
 

	
 
			Swift::CapsInfo &getBuddyCapsInfo();
 

	
 
			/// Returns Swift::IQRouter associated with this Component.
 

	
 
			/// \return Swift::IQRouter associated with this Component.
 
			Swift::IQRouter *getIQRouter() { return m_iqRouter; }
 

	
 
			/// Returns Swift::PresenceOracle associated with this Transport::Component.
 

	
 
			/// You can use it to check current resource connected for particular user.
 
			/// \return Swift::PresenceOracle associated with this Transport::Component.
 
			Swift::PresenceOracle *getPresenceOracle();
 
			PresenceOracle *getPresenceOracle();
 

	
 
			/// Returns True if the component is in server mode.
 

	
 
			/// \return True if the component is in server mode.
 
			bool inServerMode() { return m_server != NULL; }
 

	
 
			/// Connects the Jabber server.
 

	
 
			void start();
 
			void stop();
 

	
 
			/// Sets disco#info features which are sent as answer to disco#info IQ-get.
 
			
 
			/// This sets features of transport contact (For example "j2j.domain.tld").
 
			/// \param features list of features as sent in disco#info response
 
			void setTransportFeatures(std::list<std::string> &features);
 

	
 
			/// Sets disco#info features which are sent as answer to disco#info IQ-get.
 
			
 
			/// This sets features of legacy network buddies (For example "me\40gmail.com@j2j.domain.tld").
 
			/// \param features list of features as sent in disco#info response
 
			void setBuddyFeatures(std::list<std::string> &features);
 

	
 
			/// Returns Jabber ID of this transport.
 
@@ -158,44 +158,44 @@ namespace Transport {
 
			/// \param presence presence data
 
			boost::signal<void (Swift::Presence::ref presence)> onUserPresenceReceived;
 

	
 
			boost::signal<void (const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info)> onUserDiscoInfoReceived;
 

	
 
// 			boost::signal<void (boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid)> onDiscoInfoResponse;
 

	
 
		private:
 
			void handleConnected();
 
			void handleConnectionError(const Swift::ComponentError &error);
 
			void handlePresence(Swift::Presence::ref presence);
 
			void handleDataRead(const Swift::SafeByteArray &data);
 
			void handleDataWritten(const Swift::SafeByteArray &data);
 

	
 
			void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
			void handleCapsChanged(const Swift::JID& jid);
 

	
 
			Swift::NetworkFactories *m_factories;
 
			Swift::Component *m_component;
 
			Swift::Server *m_server;
 
			Swift::Timer::ref m_reconnectTimer;
 
			Swift::EntityCapsManager *m_entityCapsManager;
 
			Swift::CapsManager *m_capsManager;
 
			Swift::CapsMemoryStorage *m_capsMemoryStorage;
 
			Swift::PresenceOracle *m_presenceOracle;
 
			PresenceOracle *m_presenceOracle;
 
			Swift::StanzaChannel *m_stanzaChannel;
 
			Swift::IQRouter *m_iqRouter;
 
			
 
			Transport::UserRegistry *m_userRegistry;
 
			StorageBackend *m_storageBackend;
 
 			DiscoInfoResponder *m_discoInfoResponder;
 
			DiscoItemsResponder *m_discoItemsResponder;
 
			int m_reconnectCount;
 
			Config* m_config;
 
			std::string m_protocol;
 
			Swift::JID m_jid;
 
			Factory *m_factory;
 
			Swift::EventLoop *m_loop;
 

	
 
		friend class User;
 
		friend class UserRegistration;
 
		friend class NetworkPluginServer;
 
	};
 
}
include/transport/user.h
Show inline comments
 
/**
 
 * 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 <time.h>
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Presence/PresenceOracle.h"
 
#include "Swiften/Disco/EntityCapsManager.h"
 
#include "Swiften/Disco/EntityCapsProvider.h"
 
#include "storagebackend.h"
 
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
 
#include "Swiften/Elements/SpectrumErrorPayload.h"
 

	
 
namespace Transport {
 

	
 
class Component;
 
class RosterManager;
 
class ConversationManager;
 
class UserManager;
 
class PresenceOracle;
 
struct UserInfo;
 

	
 
/// Represents online XMPP user.
 
class User : public Swift::EntityCapsProvider {
 
	public:
 
		/// Creates new User class.
 
		/// \param jid XMPP JID associated with this user
 
		/// \param userInfo UserInfo struct with informations needed to connect
 
		/// this user to legacy network
 
		/// \param component Component associated with this user
 
		User(const Swift::JID &jid, UserInfo &userInfo, Component * component, UserManager *userManager);
 

	
 
		/// Destroyes User.
 
		virtual ~User();
 

	
 
		/// Returns JID of XMPP user who is currently connected using this User class.
 
		/// \return full JID
 
		const Swift::JID &getJID();
 

	
 
		/// Returns full JID which supports particular feature or invalid JID.
 
		/// \param feature disco#info feature.
 
		/// \return full JID which supports particular feature or invalid JID.
 
		Swift::JID getJIDWithFeature(const std::string &feature);
 

	
 
@@ -104,40 +104,40 @@ class User : public Swift::EntityCapsProvider {
 

	
 
		void sendCurrentPresence();
 

	
 
		void setIgnoreDisconnect(bool ignoreDisconnect);
 

	
 
		bool isConnected() {
 
			return m_connected;
 
		}
 

	
 
		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;
 
		boost::signal<void (const std::string &room)> onRoomLeft;
 
		boost::signal<void ()> onDisconnected;
 

	
 
	private:
 
		void onConnectingTimeout();
 

	
 
		Swift::JID m_jid;
 
		Component *m_component;
 
		RosterManager *m_rosterManager;
 
		UserManager *m_userManager;
 
		ConversationManager *m_conversationManager;
 
		Swift::EntityCapsManager *m_entityCapsManager;
 
		Swift::PresenceOracle *m_presenceOracle;
 
		PresenceOracle *m_presenceOracle;
 
		UserInfo m_userInfo;
 
		void *m_data;
 
		bool m_connected;
 
		bool m_readyForConnect;
 
		bool m_ignoreDisconnect;
 
		Swift::Timer::ref m_reconnectTimer;
 
		boost::shared_ptr<Swift::Connection> connection;
 
		time_t m_lastActivity;
 
		std::map<Swift::JID, Swift::DiscoInfo::ref> m_legacyCaps;
 
		std::vector<boost::shared_ptr<Swift::OutgoingFileTransfer> > m_filetransfers;
 
		int m_resources;
 
		int m_reconnectCounter;
 
};
 

	
 
}
include/transport/util.h
Show inline comments
 
@@ -19,27 +19,29 @@
 
 */
 

	
 
#pragma once
 

	
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <vector>
 
#include <string>
 
#include "Swiften/StringCodecs/Base64.h"
 

	
 
namespace Transport {
 

	
 
namespace Util {
 

	
 
void removeEverythingOlderThan(const std::vector<std::string> &dirs, time_t t);
 

	
 
std::string encryptPassword(const std::string &password, const std::string &key);
 

	
 
std::string decryptPassword(std::string &encrypted, const std::string &key);
 

	
 
std::string serializeGroups(const std::vector<std::string> &groups);
 

	
 
std::vector<std::string> deserializeGroups(std::string &groups);
 

	
 
int getRandomPort(const std::string &s);
 

	
 
}
 

	
 
}
spectrum/src/main.cpp
Show inline comments
 
#include "transport/config.h"
 
#include "transport/transport.h"
 
#include "transport/filetransfermanager.h"
 
#include "transport/usermanager.h"
 
#include "transport/logger.h"
 
#include "transport/sqlite3backend.h"
 
#include "transport/mysqlbackend.h"
 
#include "transport/pqxxbackend.h"
 
#include "transport/userregistration.h"
 
#include "transport/networkpluginserver.h"
 
#include "transport/admininterface.h"
 
#include "transport/statsresponder.h"
 
#include "transport/usersreconnecter.h"
 
#include "transport/util.h"
 
#include "Swiften/EventLoop/SimpleEventLoop.h"
 
#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>
 
#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"
 
@@ -358,49 +359,65 @@ int main(int argc, char **argv)
 
		}
 
	}
 
#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
 

	
 
	if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3") {
 
#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;
 
	}
 

	
 
	UserManager userManager(&transport, &userRegistry, storageBackend);
 
	userManager_ = &userManager;
 

	
 
	UserRegistration *userRegistration = NULL;
 
	UsersReconnecter *usersReconnecter = NULL;
 
	if (storageBackend) {
 
		userRegistration = new UserRegistration(&transport, &userManager, storageBackend);
 
		userRegistration->start();
 

	
 
		usersReconnecter = new UsersReconnecter(&transport, storageBackend);
 
	}
 

	
 
	FileTransferManager ftManager(&transport, &userManager);
 

	
 
	NetworkPluginServer plugin(&transport, &config, &userManager, &ftManager);
 

	
 
	AdminInterface adminInterface(&transport, &userManager, &plugin, storageBackend);
 
	StatsResponder statsResponder(&transport, &userManager, &plugin, storageBackend);
 
	statsResponder.start();
 

	
spectrum/src/sample2.cfg
Show inline comments
 
@@ -3,49 +3,51 @@
 
server_mode = 1
 

	
 
# The name of user/group Spectrum runs as.
 
#user=spectrum
 
#group=spectrum
 

	
 
# JID of Spectrum instance.
 
jid = localhost
 

	
 
# Password used to connect the XMPP server in gateway mode.
 
# In server mode, this option is ignored.
 
password = secret
 

	
 
# XMPP server to which Spectrum connects in gateway mode.
 
# In server mode, this option is ignored.
 
server = 127.0.0.1
 

	
 
# XMPP server port.
 
port = 5222
 

	
 
# Interface on which Spectrum listens for backends.
 
backend_host = localhost
 

	
 
# Port on which Spectrum listens for backends.
 
backend_port=10001
 
# By default Spectrum chooses random backend port and there's
 
# no need to change it normally
 
#backend_port=10001
 

	
 
# Full path to PKCS#12 cetficiate used for TLS in server mode.
 
#cert=
 

	
 
# Certificate password if any.
 
#cert_password= 
 

	
 
# Number of users per one legacy network backend.
 
users_per_backend=10
 

	
 
# Full path to backend binary.
 
backend=/usr/bin/spectrum2_libpurple_backend
 
#backend=/usr/bin/spectrum2_libircclient-qt_backend
 

	
 
# Libpurple protocol-id for spectrum_libpurple_backend
 
protocol=prpl-jabber
 
#protocol=prpl-msn
 
#protocol=prpl-icq
 

	
 
# prpl-any means that user sets his protocol in his JID which has to be
 
# in following format: protocol.username@domain.tld
 
# So for example: prpl-jabber.hanzz.k%gmail.com@domain.tld
 
#protocol=prpl-any
 

	
spectrum_manager/src/CMakeLists.txt
Show inline comments
 
cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC *.cpp)
 
 
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp)
 
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp ../../src/util.cpp)
 
 
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY})
 
 
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
 
 
INSTALL(FILES
 
	spectrum_manager.cfg
 
	DESTINATION /etc/spectrum2
 
	)
src/CMakeLists.txt
Show inline comments
 
@@ -14,37 +14,37 @@ endif()
 
if (NOT WIN32)
 
include_directories(${POPT_INCLUDE_DIR})
 
endif()
 

	
 
# SOURCE_GROUP(headers FILES ${HEADERS})
 

	
 

	
 
if (PROTOBUF_FOUND)
 
	if (CMAKE_COMPILER_IS_GNUCXX)
 
		ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC} ${SWIFTEN_SRC} ${CMAKE_CURRENT_BINARY_DIR}/../include/transport/protocol.pb.cc)
 
	else(CMAKE_COMPILER_IS_GNUCXX)
 
		ADD_LIBRARY(transport STATIC ${HEADERS} ${SRC} ${SWIFTEN_SRC} ${CMAKE_CURRENT_BINARY_DIR}/../include/transport/protocol.pb.cc)    
 
	endif(CMAKE_COMPILER_IS_GNUCXX)
 
	SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
 
	ADD_DEPENDENCIES(transport pb) 
 
else(PROTOBUF_FOUND)
 
	ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC} ${SWIFTEN_SRC})
 
endif(PROTOBUF_FOUND)
 

	
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
	ADD_DEFINITIONS(-fPIC)
 
endif()
 

	
 
if (WIN32)
 
	TARGET_LINK_LIBRARIES(transport ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
 
	TARGET_LINK_LIBRARIES(transport ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
 
else (WIN32)
 
	TARGET_LINK_LIBRARIES(transport ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
 
	TARGET_LINK_LIBRARIES(transport ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${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)
 

	
 
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_BINARY_DIR}/transport.pc")
 
#INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/transport.pc" DESTINATION lib/pkgconfig)
src/config.cpp
Show inline comments
 
/**
 
 * 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/config.h"
 
#include "transport/util.h"
 
#include <fstream>
 
#ifdef _MSC_VER
 
#include <direct.h>
 
#define getcwd _getcwd
 
#include <windows.h>
 
#define PATH_MAX MAX_PATH
 
#endif
 

	
 
using namespace boost::program_options;
 

	
 
namespace Transport {
 

	
 
bool Config::load(const std::string &configfile, boost::program_options::options_description &opts, const std::string &jid) {
 
	std::ifstream ifs(configfile.c_str());
 
	if (!ifs.is_open())
 
		return false;
 

	
 
	m_file = configfile;
 
	bool ret = load(ifs, opts, jid);
 
	ifs.close();
 

	
 
	char path[PATH_MAX] = "";
 
	if (m_file.find_first_of("/") != 0) {
 
		getcwd(path, PATH_MAX);
 
@@ -99,84 +100,73 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 
		("backend.default_avatar", value<std::string>()->default_value(""), "Full path to default avatar")
 
		("backend.avatars_directory", value<std::string>()->default_value(""), "Path to directory with avatars")
 
		("backend.no_vcard_fetch", value<bool>()->default_value(false), "True if VCards for buddies should not be fetched. Only avatars will be forwarded.")
 
	;
 

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

	
 
	bool found_working = false;
 
	bool found_pidfile = false;
 
	bool found_backend_port = false;
 
	std::string jid = "";
 
	BOOST_FOREACH(option &opt, parsed.options) {
 
		if (opt.string_key == "service.jid") {
 
			if (_jid.empty()) {
 
				jid = opt.value[0];
 
			}
 
			else {
 
				opt.value[0] = _jid;
 
				jid = _jid;
 
			}
 
		}
 
		else if (opt.string_key == "service.backend_port") {
 
			found_backend_port = true;
 
			if (opt.value[0] == "0") {
 
				unsigned long r = 0;
 
				BOOST_FOREACH(char c, _jid) {
 
					r += (int) c;
 
				}
 
				srand(time(NULL) + r);
 
				int randomPort = 30000 + rand() % 10000;
 
				opt.value[0] = boost::lexical_cast<std::string>(randomPort);
 
				opt.value[0] = boost::lexical_cast<std::string>(Util::getRandomPort(_jid.empty() ? jid : _jid));
 
			}
 
		}
 
		else if (opt.string_key == "service.working_dir") {
 
			found_working = true;
 
		}
 
		else if (opt.string_key == "service.pidfile") {
 
			found_pidfile = true;
 
		}
 
	}
 

	
 
	if (!found_working) {
 
		std::vector<std::string> value;
 
		value.push_back("/var/lib/spectrum2/$jid");
 
		parsed.options.push_back(boost::program_options::basic_option<char>("service.working_dir", value));
 
	}
 
	if (!found_pidfile) {
 
		std::vector<std::string> value;
 
		value.push_back("/var/run/spectrum2/$jid.pid");
 
		parsed.options.push_back(boost::program_options::basic_option<char>("service.pidfile", value));
 
	}
 
	if (!found_backend_port) {
 
		unsigned long r = 0;
 
		BOOST_FOREACH(char c, _jid) {
 
			r += (int) c;
 
		}
 
		srand(time(NULL) + r);
 
		int randomPort = 30000 + rand() % 10000;
 
		std::vector<std::string> value;
 
		value.push_back(boost::lexical_cast<std::string>(randomPort));
 
		std::string p = boost::lexical_cast<std::string>(Util::getRandomPort(_jid.empty() ? jid : _jid));
 
		value.push_back(p);
 
		parsed.options.push_back(boost::program_options::basic_option<char>("service.backend_port", value));
 
	}
 

	
 
	BOOST_FOREACH(option &opt, parsed.options) {
 
		if (opt.unregistered) {
 
			m_unregistered[opt.string_key] = opt.value[0];
 
		}
 
		else if (opt.value[0].find("$jid") != std::string::npos) {
 
			boost::replace_all(opt.value[0], "$jid", jid);
 
		}
 
	}
 

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

	
 
	onConfigReloaded();
 

	
 
	return true;
 
}
 

	
 
bool Config::load(std::istream &ifs) {
 
	options_description opts("Transport options");
 
	return load(ifs, opts);
 
}
src/pqxxbackend.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
 
 */
 

	
 
#ifdef WITH_PQXX
 

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

	
 
using namespace log4cxx;
 
using namespace boost;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("PQXXBackend");
 

	
 
PQXXBackend::PQXXBackend(Config *config) {
 
	m_config = config;
 
	m_prefix = CONFIG_STRING(m_config, "database.prefix");
 
}
 

	
 
PQXXBackend::~PQXXBackend(){
 
	disconnect();
 
}
 

	
 
void PQXXBackend::disconnect() {
 
	LOG4CXX_INFO(logger, "Disconnecting");
 

	
 
	delete m_conn;
 
}
 

	
 
bool PQXXBackend::connect() {
 
	LOG4CXX_INFO(logger, "Connecting PostgreSQL server " << CONFIG_STRING(m_config, "database.server") << ", user " <<
 
		CONFIG_STRING(m_config, "database.user") << ", database " << CONFIG_STRING(m_config, "database.database") <<
 
		", port " << CONFIG_INT(m_config, "database.port")
 
	);
 
	
 
	std::string str = "dbname=";
 
	str += CONFIG_STRING(m_config, "database.database") + " ";
 

	
 
	str += "user=" + CONFIG_STRING(m_config, "database.user") + " ";
 
	m_conn = new pqxx::connection(str);
 

	
 
	createDatabase();
 

	
 
	return true;
 
}
 

	
 
bool PQXXBackend::createDatabase() {
 
	
 
	int exist = exec("SELECT * FROM " + m_prefix + "buddies_settings LIMIT 1;", false);
 

	
 
	if (!exist) {
 
		exec("CREATE TABLE " + m_prefix + "buddies_settings ("
 
				"user_id integer NOT NULL,"
 
				"buddy_id integer NOT NULL,"
 
				"var varchar(50) NOT NULL,"
 
				"type smallint NOT NULL,"
 
				"value varchar(255) NOT NULL,"
 
				"PRIMARY KEY (buddy_id,var)"
 
			");");
 
		
 
		exec("CREATE TYPE Subscription AS ENUM ('to','from','both','ask','none');");
 
		exec("CREATE TABLE " + m_prefix + "buddies ("
 
							"id SERIAL,"
 
							"user_id integer NOT NULL,"
 
							"uin varchar(255) NOT NULL,"
 
							"subscription Subscription NOT NULL,"
 
							"nickname varchar(255) NOT NULL,"
 
							"groups varchar(255) NOT NULL,"
 
							"flags smallint NOT NULL DEFAULT '0',"
 
							"PRIMARY KEY (id),"
 
							"UNIQUE (user_id,uin)"
 
						");");
 
 
 
		exec("CREATE TABLE " + m_prefix + "users ("
 
				"id SERIAL,"
 
				"jid varchar(255) NOT NULL,"
 
				"uin varchar(4095) NOT NULL,"
 
				"password varchar(255) NOT NULL,"
 
				"language varchar(25) NOT NULL,"
 
				"encoding varchar(50) NOT NULL default 'utf8',"
 
				"last_login timestamp,"
 
				"vip boolean NOT NULL  default '0',"
 
				"online boolean NOT NULL  default '0',"
 
				"PRIMARY KEY (id),"
 
				"UNIQUE (jid)"
 
			");");
 

	
 
		exec("CREATE TABLE " + m_prefix + "users_settings ("
 
				"user_id integer NOT NULL,"
 
				"var varchar(50) NOT NULL,"
 
				"type smallint NOT NULL,"
 
				"value varchar(255) NOT NULL,"
 
				"PRIMARY KEY (user_id,var)"
 
			");");
 

	
 
		exec("CREATE TABLE " + m_prefix + "db_version ("
 
				"ver integer NOT NULL default '1',"
 
				"UNIQUE (ver)"
 
			");");
 

	
 
// 		exec("INSERT INTO db_version (ver) VALUES ('2');");
 
	}
 

	
 
	return true;
 
}
 

	
 
bool PQXXBackend::exec(const std::string &query, bool show_error) {
 
	pqxx::work txn(*m_conn);
 
	return exec(txn, query, show_error);
 
}
 

	
 
bool PQXXBackend::exec(pqxx::work &txn, const std::string &query, bool show_error) {
 
	try {
 
		txn.exec(query);
 
		txn.commit();
 
	}
 
	catch (std::exception& e) {
 
		if (show_error)
 
			LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 
	return true;
 
}
 

	
 
void PQXXBackend::setUser(const UserInfo &user) {
 
	std::string encrypted = user.password;
 
	if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) {
 
		encrypted = Util::encryptPassword(encrypted, CONFIG_STRING(m_config, "database.encryption_key"));
 
	}
 
	pqxx::work txn(*m_conn);
 
	exec(txn, "UPDATE " + m_prefix + "users SET uin=" + txn.quote(user.uin) + ", password=" + txn.quote(encrypted) + ";"
 
		"INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES "
 
		 "(" + txn.quote(user.jid) + ","
 
		+ txn.quote(user.uin) + ","
 
		+ txn.quote(encrypted) + ","
 
		+ txn.quote(user.language) + ","
 
		+ txn.quote(user.encoding) + ","
 
		+ "NOW(),"
 
		+ txn.quote(user.vip) +")");
 
}
 

	
 
bool PQXXBackend::getUser(const std::string &barejid, UserInfo &user) {
 
	try {
 
		pqxx::work txn(*m_conn);
 

	
 
		pqxx::result r = txn.exec("SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid="
 
			+ txn.quote(barejid));
 

	
 
		if (r.size() == 0) {
 
			return false;
 
		}
 

	
 
		user.id = r[0][0].as<int>();
 
		user.jid = r[0][1].as<std::string>();
 
		user.uin = r[0][2].as<std::string>();
 
		user.password = r[0][3].as<std::string>();
 
		user.encoding = r[0][4].as<std::string>();
 
		user.language = r[0][5].as<std::string>();
 
		user.vip = r[0][6].as<bool>();
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
void PQXXBackend::setUserOnline(long id, bool online) {
 
	try {
 
		pqxx::work txn(*m_conn);
 
		exec(txn, "UPDATE " + m_prefix + "users SET online=" + txn.quote(online) + ", last_login=NOW() WHERE id=" + txn.quote(id));
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
	}
 
}
 

	
 
bool PQXXBackend::getOnlineUsers(std::vector<std::string> &users) {
 
	try {
 
		pqxx::work txn(*m_conn);
 
		pqxx::result r = txn.exec("SELECT jid FROM " + m_prefix + "users WHERE online=1");
 

	
 
		for (pqxx::result::const_iterator it = r.begin(); it != r.end(); it++)  {
 
			users.push_back((*it)[0].as<std::string>());
 
		}
 
	}
 
	catch (std::exception& e) {
 
		LOG4CXX_ERROR(logger, e.what());
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
long PQXXBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
 
// 	"INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)"
 
//	std::string groups = Util::serializeGroups(buddyInfo.groups);
 
//	*m_addBuddy << userId << buddyInfo.legacyName << buddyInfo.subscription;
 
//	*m_addBuddy << groups;
 
//	*m_addBuddy << buddyInfo.alias << buddyInfo.flags;
 

	
 
//	EXEC(m_addBuddy, addBuddy(userId, buddyInfo));
 

	
 
//	long id = (long) mysql_insert_id(&m_conn);
 

	
 
// 	INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)
 
//	if (!buddyInfo.settings.find("icon_hash")->second.s.empty()) {
 
//		*m_updateBuddySetting << userId << id << buddyInfo.settings.find("icon_hash")->first << (int) TYPE_STRING << buddyInfo.settings.find("icon_hash")->second.s << buddyInfo.settings.find("icon_hash")->second.s;
 
//		EXEC(m_updateBuddySetting, addBuddy(userId, buddyInfo));
 
//	}
 

	
 
	return 0;
 
}
 

	
 
void PQXXBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
 
// 	"UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?"
 
//	std::string groups = Util::serializeGroups(buddyInfo.groups);
 
//	*m_updateBuddy << groups;
 
//	*m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription;
 
//	*m_updateBuddy << userId << buddyInfo.legacyName;
 

	
 
//	EXEC(m_updateBuddy, updateBuddy(userId, buddyInfo));
 
}
 

	
 
bool PQXXBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
//	SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC
 
//	*m_getBuddies << id;
 

	
 
// 	"SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC"
 
//	*m_getBuddiesSettings << id;
 

	
 
//	SettingVariableInfo var;
 
//	long buddy_id = -1;
 
//	std::string key;
 

	
 
//	EXEC(m_getBuddies, getBuddies(id, roster));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	while (m_getBuddies->fetch() == 0) {
 
//		BuddyInfo b;
 

	
 
//		std::string group;
 
//		*m_getBuddies >> b.id >> b.legacyName >> b.subscription >> b.alias >> group >> b.flags;
 

	
 
//		if (!group.empty()) {
 
//			b.groups = Util::deserializeGroups(group);
 
//		}
 

	
 
//		roster.push_back(b);
 
//	}
 

	
 
//	EXEC(m_getBuddiesSettings, getBuddies(id, roster));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	BOOST_FOREACH(BuddyInfo &b, roster) {
 
//		if (buddy_id == b.id) {
 
//// 			std::cout << "Adding buddy info setting " << key << "\n";
 
//			b.settings[key] = var;
 
//			buddy_id = -1;
 
//		}
 

	
 
//		while(buddy_id == -1 && m_getBuddiesSettings->fetch() == 0) {
 
//			std::string val;
 
//			*m_getBuddiesSettings >> buddy_id >> var.type >> key >> val;
 

	
 
//			switch (var.type) {
 
//				case TYPE_BOOLEAN:
 
//					var.b = atoi(val.c_str());
 
//					break;
 
//				case TYPE_STRING:
 
//					var.s = val;
 
//					break;
 
//				default:
 
//					if (buddy_id == b.id) {
 
//						buddy_id = -1;
 
//					}
 
//					continue;
 
//					break;
 
//			}
 
//			if (buddy_id == b.id) {
 
//// 				std::cout << "Adding buddy info setting " << key << "=" << val << "\n";
 
//				b.settings[key] = var;
 
//				buddy_id = -1;
 
//			}
 
//		}
 
//	}
 

	
 
//	while(m_getBuddiesSettings->fetch() == 0) {
 
//		// TODO: probably remove those settings, because there's no buddy for them.
 
//		// It should not happend, but one never know...
 
//	}
 
	
 
	return true;
 
}
 

	
 
bool PQXXBackend::removeUser(long id) {
 
//	*m_removeUser << (int) id;
 
//	EXEC(m_removeUser, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserSettings << (int) id;
 
//	EXEC(m_removeUserSettings, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserBuddies << (int) id;
 
//	EXEC(m_removeUserBuddies, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
//	*m_removeUserBuddiesSettings << (int) id;
 
//	EXEC(m_removeUserBuddiesSettings, removeUser(id));
 
//	if (!exec_ok)
 
//		return false;
 

	
 
	return true;
 
}
 

	
 
void PQXXBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
 
//// 	"SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?"
 
//	*m_getUserSetting << id << variable;
 
//	EXEC(m_getUserSetting, getUserSetting(id, variable, type, value));
 
//	if (m_getUserSetting->fetch() != 0) {
 
//// 		"INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)"
 
//		*m_setUserSetting << id << variable << type << value;
 
//		EXEC(m_setUserSetting, getUserSetting(id, variable, type, value));
 
//	}
 
//	else {
 
//		*m_getUserSetting >> type >> value;
 
//	}
 
}
 

	
 
void PQXXBackend::updateUserSetting(long id, const std::string &variable, const std::string &value) {
 
//// 	"UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?"
 
//	*m_updateUserSetting << value << id << variable;
 
//	EXEC(m_updateUserSetting, updateUserSetting(id, variable, value));
 
}
 

	
 
void PQXXBackend::beginTransaction() {
 
//	exec("START TRANSACTION;");
 
}
 

	
 
void PQXXBackend::commitTransaction() {
 
//	exec("COMMIT;");
 
}
 

	
 
}
 

	
 
#endif
src/presenceoracle.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/presenceoracle.h"
 
#include "Swiften/Swiften.h"
 

	
 
#include <boost/bind.hpp>
 

	
 
using namespace Swift;
 

	
 
namespace Transport {
 

	
 
PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) {
 
	stanzaChannel_ = stanzaChannel;
 
	stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
 
	stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
 
}
 

	
 
PresenceOracle::~PresenceOracle() {
 
	stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
 
	stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
 
}
 

	
 
void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) {
 
	if (available) {
 
		entries_.clear();
 
	}
 
}
 

	
 

	
 
void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
 
	// ignore presences for some contact, we're checking only presences for the transport itself here.
 
	bool isMUC = presence->getPayload<MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
 
	// filter out login/logout presence spam
 
	if (!presence->getTo().getNode().empty() && isMUC == false)
 
		return;
 

	
 
	JID bareJID(presence->getFrom().toBare());
 
	if (presence->getType() == Presence::Subscribe || presence->getType() == Presence::Subscribed) {
 
	}
 
	else {
 
		Presence::ref passedPresence = presence;
 
		if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) {
 
			/* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
 
			passedPresence = Presence::ref(new Presence());
 
			passedPresence->setType(Presence::Unavailable);
 
			passedPresence->setFrom(bareJID);
 
			passedPresence->setStatus(presence->getStatus());
 
		}
 
		std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID];
 
		if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
 
			/* Have a bare-JID only presence of offline */
 
			jidMap.clear();
 
		} else if (passedPresence->getType() == Presence::Available) {
 
			/* Don't have a bare-JID only offline presence once there are available presences */
 
			jidMap.erase(bareJID);
 
		}
 
		if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) {
 
			jidMap.erase(passedPresence->getFrom());
 
		} else {
 
			jidMap[passedPresence->getFrom()] = passedPresence;
 
		}
 
		entries_[bareJID] = jidMap;
 
		onPresenceChange(passedPresence);
 
	}
 
}
 

	
 
Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
 
	PresencesMap::const_iterator i = entries_.find(jid.toBare());
 
	if (i == entries_.end()) {
 
		return Presence::ref();
 
	}
 
	PresenceMap presenceMap = i->second;
 
	PresenceMap::const_iterator j = presenceMap.find(jid);
 
	if (j != presenceMap.end()) {
 
		return j->second;
 
	}
 
	else {
 
		return Presence::ref();
 
	}
 
}
 

	
 
std::vector<Presence::ref> PresenceOracle::getAllPresence(const JID& bareJID) const {
 
	std::vector<Presence::ref> results;
 
	PresencesMap::const_iterator i = entries_.find(bareJID);
 
	if (i == entries_.end()) {
 
		return results;
 
	}
 
	PresenceMap presenceMap = i->second;
 
	PresenceMap::const_iterator j = presenceMap.begin();
 
	for (; j != presenceMap.end(); ++j) {
 
		Presence::ref current = j->second;
 
		results.push_back(current);
 
	}
 
	return results;
 
}
 

	
 
Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const {
 
	PresencesMap::const_iterator i = entries_.find(bareJID);
 
	if (i == entries_.end()) {
 
		return Presence::ref();
 
	}
 
	PresenceMap presenceMap = i->second;
 
	PresenceMap::const_iterator j = presenceMap.begin();
 
	Presence::ref highest;
 
	for (; j != presenceMap.end(); ++j) {
 
		Presence::ref current = j->second;
 
		if (!highest
 
				|| current->getPriority() > highest->getPriority()
 
				|| (current->getPriority() == highest->getPriority()
 
						&& StatusShow::typeToAvailabilityOrdering(current->getShow()) > StatusShow::typeToAvailabilityOrdering(highest->getShow()))) {
 
			highest = current;
 
		}
 

	
 
	}
 
	return highest;
 
}
 

	
 
}
src/storageresponder.cpp
Show inline comments
 
@@ -50,33 +50,41 @@ bool StorageResponder::handleGetRequest(const Swift::JID& from, const Swift::JID
 
	User *user = m_userManager->getUser(from.toBare().toString());
 
	if (!user) {
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in");
 
		sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel);
 
		return true;
 
	}
 

	
 
	int type = 0;
 
	std::string value = "";
 
	m_storageBackend->getUserSetting(user->getUserInfo().id, "storage", type, value);
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Sending jabber:iq:storage");
 

	
 
	sendResponse(from, id, boost::shared_ptr<PrivateStorage>(new PrivateStorage(boost::shared_ptr<RawXMLPayload>(new RawXMLPayload(value)))));
 
	return true;
 
}
 

	
 
bool StorageResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::PrivateStorage> payload) {
 
	User *user = m_userManager->getUser(from.toBare().toString());
 
	if (!user) {
 
		sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel);
 
		LOG4CXX_WARN(logger, from.toBare().toString() << ": User is not logged in");
 
		return true;
 
	}
 

	
 
	StorageSerializer serializer;
 
	std::string value = serializer.serializePayload(boost::dynamic_pointer_cast<Storage>(payload->getPayload()));
 
	m_storageBackend->updateUserSetting(user->getUserInfo().id, "storage", value);
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Storing jabber:iq:storage");
 
	sendResponse(from, id, boost::shared_ptr<PrivateStorage>());
 
	boost::shared_ptr<Storage> storage = boost::dynamic_pointer_cast<Storage>(payload->getPayload());
 

	
 
	if (storage) {
 
		StorageSerializer serializer;
 
		std::string value = serializer.serializePayload(boost::dynamic_pointer_cast<Storage>(payload->getPayload()));
 
		m_storageBackend->updateUserSetting(user->getUserInfo().id, "storage", value);
 
		LOG4CXX_INFO(logger, from.toBare().toString() << ": Storing jabber:iq:storage");
 
		sendResponse(from, id, boost::shared_ptr<PrivateStorage>());
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, from.toBare().toString() << ": Unknown element. Libtransport does not support serialization of this.");
 
		sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel);
 
	}
 
	return true;
 
}
 

	
 
}
src/transport.cpp
Show inline comments
 
@@ -24,48 +24,49 @@
 
#include "transport/storagebackend.h"
 
#include "transport/factory.h"
 
#include "transport/userregistry.h"
 
#include "discoinforesponder.h"
 
#include "discoitemsresponder.h"
 
#include "storageparser.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
 
#include "Swiften/TLS/PKCS12Certificate.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
 
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.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");
 

	
 
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
 
	m_component = NULL;
 
	m_userRegistry = NULL;
 
	m_server = NULL;
 
	m_reconnectCount = 0;
 
	m_config = config;
 
	m_factory = factory;
 
	m_loop = loop;
 
	m_userRegistry = userRegistry;
 

	
 
	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
 

	
 
	m_factories = factories;
 

	
 
@@ -116,82 +117,82 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
 

	
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
		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->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
		m_component->addPayloadSerializer(new Transport::BlockSerializer());
 
		m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_component->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 

	
 
		m_stanzaChannel = m_component->getStanzaChannel();
 
		m_iqRouter = m_component->getIQRouter();
 
	}
 

	
 
	m_capsMemoryStorage = new CapsMemoryStorage();
 
	m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
 
	m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
 
 	m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
 
	
 
	m_presenceOracle = new PresenceOracle(m_stanzaChannel);
 
	m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
 
	m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
 

	
 
	m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter, m_config);
 
	m_discoInfoResponder->start();
 

	
 
	m_discoItemsResponder = new DiscoItemsResponder(m_iqRouter);
 
	m_discoItemsResponder->start();
 

	
 
// 
 
// 	m_registerHandler = new SpectrumRegisterHandler(m_component);
 
// 	m_registerHandler->start();
 
}
 

	
 
Component::~Component() {
 
	delete m_presenceOracle;
 
	delete m_entityCapsManager;
 
	delete m_capsManager;
 
	delete m_capsMemoryStorage;
 
	delete m_discoInfoResponder;
 
	delete m_discoItemsResponder;
 
	if (m_component)
 
		delete m_component;
 
	if (m_server) {
 
		m_server->stop();
 
		delete m_server;
 
	}
 
}
 

	
 
Swift::StanzaChannel *Component::getStanzaChannel() {
 
	return m_stanzaChannel;
 
}
 

	
 
Swift::PresenceOracle *Component::getPresenceOracle() {
 
Transport::PresenceOracle *Component::getPresenceOracle() {
 
	return m_presenceOracle;
 
}
 

	
 
void Component::setTransportFeatures(std::list<std::string> &features) {
 
	m_discoInfoResponder->setTransportFeatures(features);
 
}
 

	
 
Swift::CapsInfo &Component::getBuddyCapsInfo() {
 
		return m_discoInfoResponder->getBuddyCapsInfo();
 
}
 

	
 
void Component::setBuddyFeatures(std::list<std::string> &features) {
 
	// TODO: handle caps change
 
	m_discoInfoResponder->setBuddyFeatures(features);
 
}
 

	
 
void Component::start() {
 
	if (m_component && !m_component->isAvailable()) {
 
		LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
 
		m_reconnectCount++;
 
		m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
		m_reconnectTimer->stop();
 
	}
 
	else if (m_server) {
src/user.cpp
Show inline comments
 
@@ -3,48 +3,49 @@
 
 *
 
 * 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/user.h"
 
#include "transport/transport.h"
 
#include "transport/storagebackend.h"
 
#include "transport/rostermanager.h"
 
#include "transport/usermanager.h"
 
#include "transport/conversationmanager.h"
 
#include "transport/presenceoracle.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");
 

	
 
User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) {
 
	m_jid = jid.toBare();
 
	m_data = NULL;
 

	
 
	m_component = component;
src/userregistration.cpp
Show inline comments
 
@@ -265,48 +265,52 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
 
			LOG4CXX_INFO(logger, barejid << ": This user has no permissions to register an account")
 
			sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
 
			return true;
 
		}
 
	}
 

	
 
	UserInfo res;
 
	bool registered = m_storageBackend->getUser(barejid, res);
 

	
 
	std::string encoding;
 
	std::string language;
 

	
 
	Form::ref form = payload->getForm();
 
	if (form) {
 
		const std::vector<FormField::ref> fields = form->getFields();
 
		for (std::vector<FormField::ref>::const_iterator it = fields.begin(); it != fields.end(); it++) {
 
			TextSingleFormField::ref textSingle = boost::dynamic_pointer_cast<TextSingleFormField>(*it);
 
			if (textSingle) {
 
				if (textSingle->getName() == "username") {
 
					payload->setUsername(textSingle->getValue());
 
				}
 
				else if (textSingle->getName() == "encoding") {
 
					encoding = textSingle->getValue();
 
				}
 
				// Pidgin sends it as textSingle, not sure why...
 
				else if (textSingle->getName() == "password") {
 
					payload->setPassword(textSingle->getValue());
 
				}
 
				continue;
 
			}
 

	
 
			TextPrivateFormField::ref textPrivate = boost::dynamic_pointer_cast<TextPrivateFormField>(*it);
 
			if (textPrivate) {
 
				if (textPrivate->getName() == "password") {
 
					payload->setPassword(textPrivate->getValue());
 
				}
 
				continue;
 
			}
 

	
 
			ListSingleFormField::ref listSingle = boost::dynamic_pointer_cast<ListSingleFormField>(*it);
 
			if (listSingle) {
 
				if (listSingle->getName() == "language") {
 
					language = listSingle->getValue();
 
				}
 
				continue;
 
			}
 

	
 
			BooleanFormField::ref boolean = boost::dynamic_pointer_cast<BooleanFormField>(*it);
 
			if (boolean) {
 
				if (boolean->getName() == "unregister") {
 
					if (boolean->getValue()) {
 
						payload->setRemove(true);
src/util.cpp
Show inline comments
 
@@ -107,27 +107,36 @@ std::string decryptPassword(std::string &encrypted, const std::string &key) {
 
std::string serializeGroups(const std::vector<std::string> &groups) {
 
	std::string ret;
 
	BOOST_FOREACH(const std::string &group, groups) {
 
		ret += group + "\n";
 
	}
 
	if (!ret.empty()) {
 
		ret.erase(ret.end() - 1);
 
	}
 
	return ret;
 
}
 

	
 
std::vector<std::string> deserializeGroups(std::string &groups) {
 
	std::vector<std::string> ret;
 
	if (groups.empty()) {
 
		return ret;
 
	}
 

	
 
	boost::split(ret, groups, boost::is_any_of("\n"));
 
	if (ret.back().empty()) {
 
		ret.erase(ret.end() - 1);
 
	}
 
	return ret;
 
}
 

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

	
 
}
 

	
 
}
0 comments (0 inline, 0 general)