Changeset - e8b61aa9b6fd
[Not reviewed]
CMakeLists.txt
Show inline comments
 
@@ -82,6 +82,7 @@ ADD_SUBDIRECTORY(src)
 
ADD_SUBDIRECTORY(include)
 
ADD_SUBDIRECTORY(examples)
 
ADD_SUBDIRECTORY(spectrum)
 
ADD_SUBDIRECTORY(backends)
 

	
 
if(DOXYGEN_FOUND)
 
	message("Docs         : yes")
backends/libpurple/main.cpp
Show inline comments
 
@@ -222,7 +222,7 @@ static void buddyListNewNode(PurpleBlistNode *node) {
 
	std::string message;
 
	getStatus(buddy, status, message);
 

	
 
	np->handleBuddyCreated(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy));
 
	np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy));
 
}
 

	
 
static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status_, PurpleStatus *old_status) {
cmake_modules/ProtobufConfig.cmake
Show inline comments
 
@@ -81,6 +81,36 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
 
  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
 
endfunction()
 

	
 
function(PROTOBUF_GENERATE_PY SRCS HDRS)
 
  if(NOT ARGN)
 
    message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
 
    return()
 
  endif(NOT ARGN)
 

	
 
  set(${SRCS})
 
  set(${HDRS})
 
  foreach(FIL ${ARGN})
 
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
 
    get_filename_component(FIL_WE ${FIL} NAME_WE)
 
    
 
    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
 
    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
 

	
 
    add_custom_command(
 
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
 
             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
 
      COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
 
      ARGS --python_out  ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR} ${ABS_FIL}
 
      DEPENDS ${ABS_FIL}
 
      COMMENT "Running Py protocol buffer compiler on ${FIL}"
 
      VERBATIM )
 
  endforeach()
 

	
 
  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
 
  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
 
  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
 
endfunction()
 

	
 

	
 
find_path(PROTOBUF_INCLUDE_DIR google/protobuf/service.h)
 

	
examples/CMakeLists.txt
Show inline comments
 
ADD_SUBDIRECTORY(server_connect)
 
ADD_SUBDIRECTORY(usermanager)
 

	
 
if (PROTOBUF_FOUND)
 
	ADD_SUBDIRECTORY(external_network_plugin)
 
endif()
include/transport/config.h
Show inline comments
 
@@ -70,11 +70,14 @@ class Config {
 
			return m_variables[key];
 
		}
 

	
 
		const std::string &getConfigFile() { return m_file; }
 

	
 
		/// This signal is emitted when config is loaded/reloaded.
 
		boost::signal<void ()> onConfigReloaded;
 
	
 
	private:
 
		Variables m_variables;
 
		std::string m_file;
 
};
 

	
 
}
include/transport/networkplugin.h
Show inline comments
 
@@ -58,6 +58,7 @@ class NetworkPlugin {
 
		void handleDisconnected();
 

	
 
		void send(const std::string &data);
 
		void sendPong();
 

	
 
		std::string m_data;
 
		std::string m_host;
include/transport/networkpluginserver.h
Show inline comments
 
@@ -58,12 +58,17 @@ class NetworkPluginServer {
 

	
 
		void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
 

	
 
		void pingTimeout();
 
		void sendPing();
 

	
 
		std::string m_command;
 
		std::string m_data;
 
		UserManager *m_userManager;
 
		Config *m_config;
 
		boost::shared_ptr<Swift::ConnectionServer> m_server;
 
		boost::shared_ptr<Swift::Connection> m_client;
 
		bool m_pongReceived;
 
		Swift::Timer::ref m_pingTimer;
 
};
 

	
 
}
spectrum/src/main.cpp
Show inline comments
 
#include "glib.h"
 
#include "purple.h"
 
#include <iostream>
 

	
 
#include "transport/config.h"
 
#include "transport/transport.h"
 
#include "transport/usermanager.h"
 
#include "transport/logger.h"
 
#include "transport/sqlite3backend.h"
 
#include "transport/userregistration.h"
 
#include "transport/user.h"
 
#include "transport/storagebackend.h"
 
#include "transport/rostermanager.h"
 
#include "transport/conversation.h"
 
#include "spectrumeventloop.h"
 
#include "spectrumbuddy.h"
 
#include "spectrumconversation.h"
 
#include "geventloop.h"
 

	
 
#define Log(X, STRING) std::cout << "[SPECTRUM] " << X << " " << STRING << "\n";
 

	
 

	
 
using namespace Transport;
 

	
 
Logger *_logger;
 

	
 
static gboolean nodaemon = FALSE;
 
static gchar *logfile = NULL;
 
static gchar *lock_file = NULL;
 
static gboolean ver = FALSE;
 
static gboolean upgrade_db = FALSE;
 
static gboolean check_db_version = FALSE;
 
static gboolean list_purple_settings = FALSE;
 

	
 
static GOptionEntry options_entries[] = {
 
	{ "nodaemon", 'n', 0, G_OPTION_ARG_NONE, &nodaemon, "Disable background daemon mode", NULL },
 
	{ "logfile", 'l', 0, G_OPTION_ARG_STRING, &logfile, "Set file to log", NULL },
 
	{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &lock_file, "File where to write transport PID", NULL },
 
	{ "version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Shows Spectrum version", NULL },
 
	{ "list-purple-settings", 's', 0, G_OPTION_ARG_NONE, &list_purple_settings, "Lists purple settings which can be used in config file", NULL },
 
	{ "upgrade-db", 'u', 0, G_OPTION_ARG_NONE, &upgrade_db, "Upgrades Spectrum database", NULL },
 
	{ "check-db-GlooxMessageHandler::version", 'c', 0, G_OPTION_ARG_NONE, &check_db_version, "Checks Spectrum database version", NULL },
 
	{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
 
};
 

	
 
static void buddyListNewNode(PurpleBlistNode *node) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
		return;
 
	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user)
 
		return;
 

	
 
	SpectrumBuddy *s_buddy = NULL;
 
	GSList *list = purple_find_buddies(account, purple_buddy_get_name(buddy));
 
	while (list) {
 
		PurpleBuddy *b = (PurpleBuddy *) list->data;
 
		if (b->node.ui_data)
 
			s_buddy = (SpectrumBuddy *) b->node.ui_data;
 
		list = g_slist_delete_link(list, list);
 
	}
 

	
 
	if (s_buddy) {
 
		buddy->node.ui_data = s_buddy;
 
		s_buddy->addBuddy(buddy);
 
	}
 
	else {
 
		buddy->node.ui_data = (void *) new SpectrumBuddy(user->getRosterManager(), -1, buddy);
 
		SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
		s_buddy->setFlags(BUDDY_JID_ESCAPING);
 
	}
 
}
 

	
 
static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status, PurpleStatus *old_status) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void buddySignedOn(PurpleBuddy *buddy) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void buddySignedOff(PurpleBuddy *buddy) {
 
	SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user || !s_buddy)
 
		return;
 

	
 
	s_buddy->buddyChanged();
 
}
 

	
 
static void NodeRemoved(PurpleBlistNode *node, void *data) {
 
	if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
		return;
 
	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
	
 
// 	PurpleAccount *account = purple_buddy_get_account(buddy);
 
// 	User *user = (User *) account->ui_data;
 
	if (buddy->node.ui_data) {
 
		SpectrumBuddy *s_buddy = (SpectrumBuddy *) buddy->node.ui_data;
 
		s_buddy->removeBuddy(buddy);
 
		buddy->node.ui_data = NULL;
 
		if (s_buddy->getBuddiesCount() == 0) {
 
			delete s_buddy;
 
		}
 
	}
 
}
 

	
 
static PurpleBlistUiOps blistUiOps =
 
{
 
	NULL,
 
	buddyListNewNode,
 
	NULL,
 
	NULL, // buddyListUpdate,
 
	NULL, //NodeRemoved,
 
	NULL,
 
	NULL,
 
	NULL, // buddyListAddBuddy,
 
	NULL,
 
	NULL,
 
	NULL, //buddyListSaveNode,
 
	NULL, //buddyListRemoveNode,
 
	NULL, //buddyListSaveAccount,
 
	NULL
 
};
 

	
 
static void conv_new(PurpleConversation *conv) {
 
	PurpleAccount *account = purple_conversation_get_account(conv);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user)
 
		return;
 

	
 
	std::string name = purple_conversation_get_name(conv);
 
	size_t pos = name.find("/");
 
	if (pos != std::string::npos)
 
		name.erase((int) pos, name.length() - (int) pos);
 

	
 
	SpectrumConversation *s_conv = new SpectrumConversation(user->getConversationManager(), name, conv);
 
	conv->ui_data = s_conv;
 
}
 

	
 
static void conv_destroy(PurpleConversation *conv) {
 
	SpectrumConversation *s_conv = (SpectrumConversation *) conv->ui_data;
 
	if (s_conv) {
 
		delete s_conv;
 
	}
 
}
 

	
 
static void conv_write_im(PurpleConversation *conv, const char *who, const char *message, PurpleMessageFlags flags, time_t mtime) {
 
	// Don't forwards our own messages.
 
	if (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)
 
		return;
 
	SpectrumConversation *s_conv = (SpectrumConversation *) conv->ui_data;
 
	if (!s_conv)
 
		return;
 

	
 
	boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 

	
 
	char *striped = purple_markup_strip_html(message);
 
	msg->setBody(message);
 
	g_free(striped);
 

	
 
	s_conv->handleMessage(msg);
 
}
 

	
 
static PurpleConversationUiOps conversation_ui_ops =
 
{
 
	conv_new,
 
	conv_destroy,
 
	NULL,//conv_write_chat,                              /* write_chat           */
 
	conv_write_im,             /* write_im             */
 
	NULL,//conv_write_conv,           /* write_conv           */
 
	NULL,//conv_chat_add_users,       /* chat_add_users       */
 
	NULL,//conv_chat_rename_user,     /* chat_rename_user     */
 
	NULL,//conv_chat_remove_users,    /* chat_remove_users    */
 
	NULL,//pidgin_conv_chat_update_user,     /* chat_update_user     */
 
	NULL,//pidgin_conv_present_conversation, /* present              */
 
	NULL,//pidgin_conv_has_focus,            /* has_focus            */
 
	NULL,//pidgin_conv_custom_smiley_add,    /* custom_smiley_add    */
 
	NULL,//pidgin_conv_custom_smiley_write,  /* custom_smiley_write  */
 
	NULL,//pidgin_conv_custom_smiley_close,  /* custom_smiley_close  */
 
	NULL,//pidgin_conv_send_confirm,         /* send_confirm         */
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
static void connection_report_disconnect(PurpleConnection *gc, PurpleConnectionError reason, const char *text){
 
	PurpleAccount *account = purple_connection_get_account(gc);
 
	User *user = (User *) account->ui_data;
 

	
 
	if (!user)
 
		return;
 
	user->handleDisconnected(text);
 
}
 

	
 
static PurpleConnectionUiOps conn_ui_ops =
 
{
 
	NULL,
 
	NULL,
 
	NULL,//connection_disconnected,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL,
 
	connection_report_disconnect,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
static void transport_core_ui_init(void)
 
{
 
	purple_blist_set_ui_ops(&blistUiOps);
 
// 	purple_accounts_set_ui_ops(&accountUiOps);
 
// 	purple_notify_set_ui_ops(&notifyUiOps);
 
// 	purple_request_set_ui_ops(&requestUiOps);
 
// 	purple_xfers_set_ui_ops(getXferUiOps());
 
	purple_connections_set_ui_ops(&conn_ui_ops);
 
	purple_conversations_set_ui_ops(&conversation_ui_ops);
 
// #ifndef WIN32
 
// 	purple_dnsquery_set_ui_ops(getDNSUiOps());
 
// #endif
 
}
 

	
 
static PurpleCoreUiOps coreUiOps =
 
{
 
	NULL,
 
// 	debug_init,
 
	NULL,
 
	transport_core_ui_init,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
 
	std::string c("[LIBPURPLE");
 

	
 
	if (category) {
 
		c.push_back('/');
 
		c.append(category);
 
	}
 

	
 
	c.push_back(']');
 

	
 
	std::cout << c << " " << arg_s;
 
}
 

	
 
/*
 
 * Ops....
 
 */
 
static PurpleDebugUiOps debugUiOps =
 
{
 
	printDebug,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
static bool initPurple(Config &cfg) {
 
	bool ret;
 

	
 
	purple_util_set_user_dir("./");
 
	remove("./accounts.xml");
 
	remove("./blist.xml");
 

	
 
// 	if (m_configuration.logAreas & LOG_AREA_PURPLE)
 
		purple_debug_set_ui_ops(&debugUiOps);
 

	
 
	purple_core_set_ui_ops(&coreUiOps);
 
	purple_eventloop_set_ui_ops(getEventLoopUiOps());
 

	
 
	ret = purple_core_init("spectrum");
 
	if (ret) {
 
		static int conversation_handle;
 
		static int conn_handle;
 
		static int blist_handle;
 

	
 
		purple_set_blist(purple_blist_new());
 
		purple_blist_load();
 

	
 
		purple_prefs_load();
 

	
 
		/* Good default preferences */
 
		/* The combination of these two settings mean that libpurple will never
 
		 * (of its own accord) set all the user accounts idle.
 
		 */
 
		purple_prefs_set_bool("/purple/away/away_when_idle", false);
 
		/*
 
		 * This must be set to something not "none" for idle reporting to work
 
		 * for, e.g., the OSCAR prpl. We don't implement the UI ops, so this is
 
		 * okay for now.
 
		 */
 
		purple_prefs_set_string("/purple/away/idle_reporting", "system");
 

	
 
		/* Disable all logging */
 
		purple_prefs_set_bool("/purple/logging/log_ims", false);
 
		purple_prefs_set_bool("/purple/logging/log_chats", false);
 
		purple_prefs_set_bool("/purple/logging/log_system", false);
 

	
 

	
 
// 		purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", &conversation_handle, PURPLE_CALLBACK(newMessageReceived), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typed", &conversation_handle, PURPLE_CALLBACK(buddyTyped), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
 
// 		purple_signal_connect(purple_connections_get_handle(), "signed-on", &conn_handle,PURPLE_CALLBACK(signed_on), NULL);
 
// 		purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL);
 
		purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
 
// 		purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
 
// 
 
// 		purple_commands_init();
 

	
 
	}
 
	return ret;
 
}
 

	
 
static void handleUserReadyToConnect(User *user) {
 
	PurpleAccount *account = (PurpleAccount *) user->getData();
 
	purple_account_set_enabled(account, "spectrum", TRUE);
 
	
 
	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);
 
	}
 
}
 

	
 
static void handleUserCreated(User *user, UserManager *userManager, Config *config) {
 
	UserInfo userInfo = user->getUserInfo();
 
	PurpleAccount *account = NULL;
 
	const char *protocol = CONFIG_STRING(config, "service.protocol").c_str();
 
	if (purple_accounts_find(userInfo.uin.c_str(), protocol) != NULL){
 
		Log(userInfo.jid, "this account already exists");
 
		account = purple_accounts_find(userInfo.uin.c_str(), protocol);
 
		User *u = (User *) account->ui_data;
 
		if (u && u != user) {
 
			Log(userInfo.jid, "This account is already connected by another jid " << user->getJID());
 
			return;
 
		}
 
	}
 
	else {
 
		Log(userInfo.jid, "creating new account");
 
		account = purple_account_new(userInfo.uin.c_str(), protocol);
 

	
 
		purple_accounts_add(account);
 
	}
 
// 	Transport::instance()->collector()->stopCollecting(m_account);
 

	
 
// 	PurplePlugin *plugin = purple_find_prpl(protocol);
 
// 	PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
 
// 	for (GList *l = prpl_info->protocol_options; l != NULL; l = l->next) {
 
// 		PurpleAccountOption *option = (PurpleAccountOption *) l->data;
 
// 		purple_account_remove_setting(account, purple_account_option_get_setting(option));
 
// 	}
 
// 
 
// 	std::map <std::string, PurpleAccountSettingValue> &settings = Transport::instance()->getConfiguration().purple_account_settings;
 
// 	for (std::map <std::string, PurpleAccountSettingValue>::iterator it = settings.begin(); it != settings.end(); it++) {
 
// 		PurpleAccountSettingValue v = (*it).second;
 
// 		std::string key((*it).first);
 
// 		switch (v.type) {
 
// 			case PURPLE_PREF_BOOLEAN:
 
// 				purple_account_set_bool(m_account, key.c_str(), v.b);
 
// 				break;
 
// 
 
// 			case PURPLE_PREF_INT:
 
// 				purple_account_set_int(m_account, key.c_str(), v.i);
 
// 				break;
 
// 
 
// 			case PURPLE_PREF_STRING:
 
// 				if (v.str)
 
// 					purple_account_set_string(m_account, key.c_str(), v.str);
 
// 				else
 
// 					purple_account_remove_setting(m_account, key.c_str());
 
// 				break;
 
// 
 
// 			case PURPLE_PREF_STRING_LIST:
 
// 				// TODO:
 
// 				break;
 
// 
 
// 			default:
 
// 				continue;
 
// 		}
 
// 	}
 

	
 
	purple_account_set_string(account, "encoding", userInfo.encoding.empty() ? CONFIG_STRING(config, "registration.encoding").c_str() : userInfo.encoding.c_str());
 
	purple_account_set_bool(account, "use_clientlogin", false);
 
// 	purple_account_set_bool(account, "require_tls",  Transport::instance()->getConfiguration().require_tls);
 
// 	purple_account_set_bool(account, "use_ssl",  Transport::instance()->getConfiguration().require_tls);
 
	purple_account_set_bool(account, "direct_connect", false);
 
// 	purple_account_set_bool(account, "check-mail", purple_value_get_boolean(getSetting("enable_notify_email")));
 

	
 
	account->ui_data = user;
 
	user->setData(account);
 

	
 
	user->onReadyToConnect.connect(boost::bind(&handleUserReadyToConnect, user));
 
	_logger->setRosterManager(user->getRosterManager());
 
	
 
// 	Transport::instance()->protocol()->onPurpleAccountCreated(m_account);
 

	
 
// 	m_loadingBuddiesFromDB = true;
 
// 	loadRoster();
 
// 	m_loadingBuddiesFromDB = false;
 

	
 
// 	m_connectionStart = time(NULL);
 
// 	m_readyForConnect = false;
 
	purple_account_set_password(account, userInfo.password.c_str());
 
// 	Log(m_jid, "UIN:" << m_username << " USER_ID:" << m_userID);
 
}
 

	
 
static void handleUserDestroyed(User *user, UserManager *userManager, Config *config) {
 
	PurpleAccount *account = (PurpleAccount *) user->getData();
 
	if (account) {
 
		purple_account_set_enabled(account, "spectrum", FALSE);
 

	
 
		// Remove conversations.
 
		// This has to be called before m_account->ui_data = NULL;, because it uses
 
		// ui_data to call SpectrumMessageHandler::purpleConversationDestroyed() callback.
 
		GList *iter;
 
		for (iter = purple_get_conversations(); iter; ) {
 
			PurpleConversation *conv = (PurpleConversation*) iter->data;
 
			iter = iter->next;
 
			if (purple_conversation_get_account(conv) == account)
 
				purple_conversation_destroy(conv);
 
		}
 

	
 
		account->ui_data = NULL;
 
// 		Transport::instance()->collector()->collect(m_account);
 
	}
 
}
 

	
 
class SpectrumFactory : public Factory {
 
	public:
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			PurpleConversation *conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, (PurpleAccount *) conversationManager->getUser()->getData() , legacyName.c_str());
 
			return (Conversation *) conv->ui_data;
 
		}
 

	
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			PurpleAccount *account = (PurpleAccount *) rosterManager->getUser()->getData();
 
			std::string group = buddyInfo.groups[0];
 
			PurpleGroup *g = purple_find_group(group.c_str());
 
			if (!g) {
 
				g = purple_group_new(group.c_str());
 
				purple_blist_add_group(g, NULL);
 
			}
 

	
 
			PurpleBuddy *buddy = purple_find_buddy_in_group(account, buddyInfo.legacyName.c_str(), g);
 
			if (!buddy) {
 
				// create contact
 
				PurpleContact *contact = purple_contact_new();
 
				purple_blist_add_contact(contact, g, NULL);
 

	
 
				// create buddy
 
				buddy = purple_buddy_new(account, buddyInfo.legacyName.c_str(), buddyInfo.alias.c_str());
 
				purple_blist_add_buddy(buddy, contact, g, NULL);
 
				purple_blist_server_alias_buddy(buddy, buddyInfo.alias.c_str());
 
			}
 
			return (Buddy *) buddy->node.ui_data;
 
		}
 
};
 

	
 
int main(int argc, char **argv) {
 
	GError *error = NULL;
 
	GOptionContext *context;
 
	context = g_option_context_new("config_file_name or profile name");
 
	g_option_context_add_main_entries(context, options_entries, "");
 
	if (!g_option_context_parse (context, &argc, &argv, &error)) {
 
		std::cout << "option parsing failed: " << error->message << "\n";
 
		return -1;
 
	}
 

	
 
	if (ver) {
 
// 		std::cout << VERSION << "\n";
 
		std::cout << "verze\n";
 
		g_option_context_free(context);
 
		return 0;
 
	}
 

	
 
	if (argc != 2) {
 
#ifdef WIN32
 
		std::cout << "Usage: spectrum.exe <configuration_file.cfg>\n";
 
#else
 

	
 
#if GLIB_CHECK_VERSION(2,14,0)
 
	std::cout << g_option_context_get_help(context, FALSE, NULL);
 
#else
 
	std::cout << "Usage: spectrum <configuration_file.cfg>\n";
 
	std::cout << "See \"man spectrum\" for more info.\n";
 
#endif
 
		
 
#endif
 
	}
 
	else {
 
#ifndef WIN32
 
// 		signal(SIGPIPE, SIG_IGN);
 
// 
 
// 		if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
 
// 			std::cout << "SIGCHLD handler can't be set\n";
 
// 			g_option_context_free(context);
 
// 			return -1;
 
// 		}
 
// 
 
// 		if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) {
 
// 			std::cout << "SIGINT handler can't be set\n";
 
// 			g_option_context_free(context);
 
// 			return -1;
 
// 		}
 
// 
 
// 		if (signal(SIGTERM, spectrum_sigterm_handler) == SIG_ERR) {
 
// 			std::cout << "SIGTERM handler can't be set\n";
 
// 			g_option_context_free(context);
 
// 			return -1;
 
// 		}
 
// 
 
// 		struct sigaction sa;
 
// 		memset(&sa, 0, sizeof(sa)); 
 
// 		sa.sa_handler = spectrum_sighup_handler;
 
// 		if (sigaction(SIGHUP, &sa, NULL)) {
 
// 			std::cout << "SIGHUP handler can't be set\n";
 
// 			g_option_context_free(context);
 
// 			return -1;
 
//		}
 
#endif
 
		Config config;
 
		if (!config.load(argv[1])) {
 
			std::cout << "Can't open " << argv[1] << " configuration file.\n";
 
			return 1;
 
		}
 

	
 
		initPurple(config);
 

	
 
		SpectrumEventLoop eventLoop;
 
		SpectrumFactory factory;
 
		Component transport(&eventLoop, &config, &factory);
 
		Logger logger(&transport);
 
		_logger = &logger;
 

	
 
		SQLite3Backend sql(&config);
 
		logger.setStorageBackend(&sql);
 
		if (!sql.connect()) {
 
			std::cout << "Can't connect to database.\n";
 
		}
 

	
 
		UserManager userManager(&transport, &sql);
 
		userManager.onUserCreated.connect(boost::bind(&handleUserCreated, _1, &userManager, &config));
 
		userManager.onUserDestroyed.connect(boost::bind(&handleUserDestroyed, _1, &userManager, &config));
 

	
 
		UserRegistration userRegistration(&transport, &userManager, &sql);
 
		logger.setUserRegistration(&userRegistration);
 
		logger.setUserManager(&userManager);
 

	
 
		transport.connect();
 
		eventLoop.run();
 
	}
 

	
 
	g_option_context_free(context);
 
}
 
#include "transport/config.h"
 
#include "transport/transport.h"
 
#include "transport/usermanager.h"
 
#include "transport/logger.h"
 
#include "transport/sqlite3backend.h"
 
#include "transport/userregistration.h"
 
#include "transport/networkpluginserver.h"
 
#include "Swiften/EventLoop/SimpleEventLoop.h"
 
 
using namespace Transport;
 
 
int main(void)
 
{
 
	Config config;
 
	if (!config.load("sample.cfg")) {
 
		std::cout << "Can't open sample.cfg configuration file.\n";
 
		return 1;
 
	}
 
 
	Swift::SimpleEventLoop eventLoop;
 
	Component transport(&eventLoop, &config, NULL);
 
	Logger logger(&transport);
 
 
	SQLite3Backend sql(&config);
 
	logger.setStorageBackend(&sql);
 
	if (!sql.connect()) {
 
		std::cout << "Can't connect to database.\n";
 
	}
 
 
	UserManager userManager(&transport, &sql);
 
	UserRegistration userRegistration(&transport, &userManager, &sql);
 
	logger.setUserRegistration(&userRegistration);
 
	logger.setUserManager(&userManager);
 
 
	NetworkPluginServer plugin(&transport, &config, &userManager);
 
 
	transport.connect();
 
	eventLoop.run();
 
}
spectrum/src/sample.cfg
Show inline comments
 
@@ -3,8 +3,9 @@ jid = icq.localhost
 
password = secret
 
server = 127.0.0.1
 
port = 5222
 
server_mode = 1
 
backend=../../backends/libpurple/libpurple_backend
 
protocol=prpl-jabber
 
server_mode=1
 

	
 
[database]
 
database = test.sql
src/CMakeLists.txt
Show inline comments
 
@@ -2,12 +2,16 @@ cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC *.cpp *.h)
 
FILE(GLOB HEADERS ../../include/transport/*.h)
 
 
if (PROTOBUF_FOUND)
 
	PROTOBUF_GENERATE_CPP(PROTOBUF_SRC PROTOBUF_HDRS "pbnetwork.proto")
 
endif()
 
 
# SOURCE_GROUP(headers FILES ${HEADERS})
 
 
ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC})
 
ADD_LIBRARY(transport SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS})
 
ADD_DEFINITIONS(-fPIC)
 
 
TARGET_LINK_LIBRARIES(transport -lresolv -lidn -lz -lpthread -lexpat -lidn -lz -lssl -lcrypto -lexpat -lresolv -lc -lxml2 ${Boost_LIBRARIES} ${SQLITE3_LIBRARIES} ${SWIFTEN_LIBRARY})
 
TARGET_LINK_LIBRARIES(transport -lresolv -lidn -lz -lpthread -lexpat -lidn -lz -lssl -lcrypto -lexpat -lresolv -lc -lxml2 ${Boost_LIBRARIES} ${SQLITE3_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
 
 
SET_TARGET_PROPERTIES(transport PROPERTIES
 
      VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
src/buddy.cpp
Show inline comments
 
@@ -26,7 +26,7 @@
 
namespace Transport {
 

	
 
Buddy::Buddy(RosterManager *rosterManager, long id) : m_id(id), m_online(false), m_subscription("ask"), m_flags(BUDDY_NO_FLAG), m_rosterManager(rosterManager){
 
	m_rosterManager->setBuddy(this);
 
// 	m_rosterManager->setBuddy(this);
 
}
 

	
 
Buddy::~Buddy() {
src/config.cpp
Show inline comments
 
@@ -35,6 +35,7 @@ bool Config::load(const std::string &configfile, boost::program_options::options
 
		("service.server", value<std::string>()->default_value(""), "Server to connect to")
 
		("service.password", value<std::string>()->default_value(""), "Password used to auth the server")
 
		("service.port", value<int>()->default_value(0), "Port the server is listening on")
 
		("service.backend", value<std::string>()->default_value("libpurple_backend"), "Backend")
 
		("service.protocol", value<std::string>()->default_value(""), "Protocol")
 
		("service.allowed_servers", value<std::string>()->default_value(""), "Only users from these servers can connect")
 
		("service.server_mode", value<bool>()->default_value(false), "True if Spectrum should behave as server")
 
@@ -51,6 +52,8 @@ bool Config::load(const std::string &configfile, boost::program_options::options
 
    store(parse_config_file(ifs, opts), m_variables);
 
	notify(m_variables);
 

	
 
	m_file = configfile;
 

	
 
	onConfigReloaded();
 

	
 
	return true;
src/networkplugin.cpp
Show inline comments
 
@@ -160,6 +160,9 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) {
 
			case pbnetwork::WrapperMessage_Type_TYPE_LOGOUT:
 
				handleLogoutPayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_PING:
 
				sendPong();
 
				break;
 
			default:
 
				return;
 
		}
 
@@ -178,4 +181,14 @@ void NetworkPlugin::send(const std::string &data) {
 
	m_conn->write(Swift::ByteArray(header + data));
 
}
 

	
 
void NetworkPlugin::sendPong() {
 
	std::string message;
 
	pbnetwork::WrapperMessage wrap;
 
	wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PONG);
 
	wrap.SerializeToString(&message);
 

	
 
	send(message);
 
	std::cout << "SENDING PONG\n";
 
}
 

	
 
}
src/networkpluginserver.cpp
Show inline comments
 
@@ -73,9 +73,13 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
 
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager) {
 
	m_userManager = userManager;
 
	m_config = config;
 
	m_pongReceived = false;
 
	m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1));
 
	m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1));
 

	
 
	m_pingTimer = component->getFactories()->getTimerFactory()->createTimer(10000);
 
	m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this)); 
 

	
 
	m_server = component->getFactories()->getConnectionFactory()->createConnectionServer(10000);
 
	m_server->onNewConnection.connect(boost::bind(&NetworkPluginServer::handleNewClientConnection, this, _1));
 
	m_server->start();
 
@@ -86,7 +90,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
 
}
 

	
 
NetworkPluginServer::~NetworkPluginServer() {
 
	></i>
 
	m_pingTimer->stop();
 
}
 

	
 
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
 
@@ -94,15 +98,21 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Con
 
		c->disconnect();
 
	}
 
	m_client = c;
 
	m_pongReceived = false;
 
	
 

	
 
	c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, c));
 
	c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, c, _1));
 
	sendPing();
 
	m_pingTimer->start();
 
}
 

	
 
void NetworkPluginServer::handleSessionFinished(boost::shared_ptr<Swift::Connection> c) {
 
	if (c == m_client) {
 
		m_client.reset();
 
	}
 
	m_pingTimer->stop();
 
	exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str());
 
}
 

	
 
void NetworkPluginServer::handleConnectedPayload(const std::string &data) {
 
@@ -187,6 +197,9 @@ void NetworkPluginServer::handleDataRead(boost::shared_ptr<Swift::Connection> c,
 
			case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED:
 
				handleBuddyChangedPayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_PONG:
 
				m_pongReceived = true;
 
				break;
 
			default:
 
				return;
 
		}
 
@@ -201,6 +214,17 @@ void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const st
 
	c->write(Swift::ByteArray(header + data));
 
}
 

	
 
void NetworkPluginServer::pingTimeout() {
 
	std::cout << "pingtimeout\n";
 
	if (m_pongReceived) {
 
		sendPing();
 
		m_pingTimer->start();
 
	}
 
	else {
 
		exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str());
 
	}
 
}
 

	
 
void NetworkPluginServer::handleUserCreated(User *user) {
 
// 	UserInfo userInfo = user->getUserInfo();
 
	user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
 
@@ -233,8 +257,20 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
 
	logout.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT);
 
 
 
	send(m_client, message);
 
}
 

	
 
void NetworkPluginServer::sendPing() {
 

	
 
	std::string message;
 
	pbnetwork::WrapperMessage wrap;
 
	wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PING);
 
	wrap.SerializeToString(&message);
 

	
 
	send(m_client, message);
 
	m_pongReceived = false;
 
	std::cout << "SENDING PING\n";
 
}
 

	
 
}
src/pbnetwork.proto
Show inline comments
 
@@ -55,8 +55,10 @@ message WrapperMessage {
 
		TYPE_CONV_CREATED	= 8;
 
		TYPE_CONV_WRITE		= 9;
 
		TYPE_CONV_REMOVED	= 10;
 
		TYPE_PING			= 11;
 
		TYPE_PONG			= 12;
 
	}
 
	required Type type = 1;
 
	required bytes payload = 2;
 
	optional bytes payload = 2;
 
}
 
;
 
\ No newline at end of file
src/rostermanager.cpp
Show inline comments
 
@@ -37,20 +37,25 @@ RosterManager::RosterManager(User *user, Component *component){
 
	m_user = user;
 
	m_component = component;
 
	m_setBuddyTimer = m_component->getFactories()->getTimerFactory()->createTimer(1000);
 
	m_RIETimer = m_component->getFactories()->getTimerFactory()->createTimer(3000);
 
	m_RIETimer = m_component->getFactories()->getTimerFactory()->createTimer(5000);
 
	m_RIETimer->onTick.connect(boost::bind(&RosterManager::sendRIE, this));
 
}
 

	
 
RosterManager::~RosterManager() {
 
	m_setBuddyTimer->stop();
 
	m_RIETimer->stop();
 
	for (std::map<std::string, Buddy *>::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) {
 
		Buddy *buddy = (*it).second;
 
		delete buddy;
 
	}
 
	if (m_rosterStorage)
 
		delete m_rosterStorage;
 
}
 

	
 
void RosterManager::setBuddy(Buddy *buddy) {
 
	m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 
	m_setBuddyTimer->start();
 
// 	m_setBuddyTimer->onTick.connect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 
// 	m_setBuddyTimer->start();
 
	setBuddyCallback(buddy);
 
}
 

	
 
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
 
@@ -70,6 +75,7 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
 
void RosterManager::setBuddyCallback(Buddy *buddy) {
 
	m_setBuddyTimer->onTick.disconnect(boost::bind(&RosterManager::setBuddyCallback, this, buddy));
 

	
 
	std::cout << "ADDING " << buddy->getName() << "\n";
 
	m_buddies[buddy->getName()] = buddy;
 
	onBuddySet(buddy);
 

	
 
@@ -79,13 +85,11 @@ void RosterManager::setBuddyCallback(Buddy *buddy) {
 
		sendBuddyRosterPush(buddy);
 
	}
 
	else {
 
		
 
	}
 

	
 
	if (m_setBuddyTimer->onTick.empty()) {
 
		m_setBuddyTimer->stop();
 
		if (true /*&& rie_is_supported*/) {
 
			m_RIETimer->start();
 
		if (m_setBuddyTimer->onTick.empty()) {
 
			m_setBuddyTimer->stop();
 
			if (true /*&& rie_is_supported*/) {
 
				m_RIETimer->start();
 
			}
 
		}
 
	}
 

	
src/sqlite3backend.cpp
Show inline comments
 
@@ -76,6 +76,15 @@ SQLite3Backend::~SQLite3Backend(){
 
		// But requires SQLite3 >= 3.6.0 beta
 
	
 
		FINALIZE_STMT(m_setUser);
 
		FINALIZE_STMT(m_getUser);
 
		FINALIZE_STMT(m_removeUser);
 
		FINALIZE_STMT(m_removeUserBuddies);
 
		FINALIZE_STMT(m_removeUserSettings);
 
		FINALIZE_STMT(m_removeUserBuddiesSettings);
 
		FINALIZE_STMT(m_addBuddy);
 
		FINALIZE_STMT(m_updateBuddy);
 
		FINALIZE_STMT(m_getBuddies);
 
		FINALIZE_STMT(m_getBuddiesSettings);
 
		sqlite3_close(m_db);
 
	}
 
}
0 comments (0 inline, 0 general)