Changeset - f1d9579afa73
CMakeLists.txt
Show inline comments
 
@@ -43,12 +43,11 @@ set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(event)
 

	
 
set(Swiften_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Swiften REQUIRED)
 
find_package(Swiften)
 

	
 
if (CMAKE_COMPILER_IS_GNUCXX)
 
set(openssl_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(openssl REQUIRED)
 
endif()
 
find_package(openssl)
 

	
 
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
if (WIN32)
ChangeLog
Show inline comments
 
Version 2.0.0-beta3 (2012-XX-XX):
 
	General:
 
	* Log errors related to backend spawning (Show proper log message for
 
	  example when path to backend binary is not found).
 
	* Update buddies in database only when it's needed and do not execute
 
	  useless database statements.
 
	* Send roster changes also when buddy's group change.
 
	* Fixed bug when transport contact we in all groups.
 
	* Answer to disco#info IQ with proper node (#206).
 
	* Set SQLite3 as default database backend.
 
	* Fixed disconnecting from server caused by sending VCard response
 
	  with bad "from" attribute.
 
	* Added Munin plugin (Thanks to Askovpen).
 
	* Added support for more admin_jid JIDs (Thanks to Askovpen).
 
	* Fixed allowed_servers option.
 

	
 
	Libpurple:
 
	* prpl-gg: Fetch the contact list properly (#252).
 

	
 
	Skype:
 
	* Log more errors.
 

	
 
	Backend API:
 
	* Added Python NetworkPlugin class, so it is now easier to write backends
 
	  in Python (Thanks to Sarang).
 

	
 
Version 2.0.0-beta2 (2012-03-28):
 
	General:
 
	* Fixed bug when Roster Item Exchange and subscribe stanzas were sent
backends/libpurple/gen_dynamic_purple.py
Show inline comments
 
new file 100644
 
import sys
 
import os
 

	
 
# intialize for methods used in libpurple macros
 
methods = ["purple_connection_get_state(", "purple_conversation_get_im_data(",
 
			"purple_conversation_get_chat_data(", "purple_blist_node_get_type("]
 
macros = ["PURPLE_CONV_IM", "PURPLE_CONV_CHAT", "PURPLE_BLIST_NODE_IS_BUDDY", "PURPLE_CONNECTION_IS_CONNECTED"]
 
definitions = []
 

	
 
if len(sys.argv) != 2:
 
	print "Usage:", sys.argv[0], "<path_to_libpurple_dir_containing_libpurple_headers>"
 
	sys.exit(1)
 

	
 

	
 
def handle_file(cpp):
 
	global methods
 
	global macros
 
	sys.stdout.write("getting used methods in " + cpp + ": ")
 
	sys.stdout.flush()
 

	
 
	counter = 0
 

	
 
	new_file = ""
 
	f = open(cpp, "r")
 
	for line in f.readlines():
 
		new_line = ""
 
		index = 0
 
		while index < len(line):
 
			new_line += line[index]
 
			if line[index:].startswith("purple_") or line[index:].startswith("wpurple_") or line[index:].startswith("serv_"):
 
				if line[index:].find("=") != -1 and line[index:].find("=") < line[index:].find("("):
 
					index += 1
 
					continue
 
				if line[index-1] == "_" or line[index:].find("(") == -1 or line[index:].startswith("purple_commands_init") or line[index:].startswith("serv_addr"):
 
					index += 1
 
					continue
 
				m = line[index:line[index:].find("(")+index]
 
				index += len(m)
 
				if m.find("_wrapped") != -1:
 
					new_line += m[1:] + "("
 
					m = m.replace("_wrapped", "")
 
				else:
 
					new_line += m[1:] + "_wrapped("
 
				if not m + "(" in methods and len(m) != 0:
 
					methods += [m + "("]
 
					counter += 1
 
			index += 1
 

	
 
		for x in macros:
 
			if new_line.find(x + "_WRAPPED") == -1:
 
				new_line = new_line.replace(x, x + "_WRAPPED")
 
		new_file += new_line
 
	f.close()
 

	
 
	print counter, "new methods found"
 
	return new_file
 

	
 
def handle_header(header, method):
 
	global definitions
 

	
 
	f = open(os.path.join(sys.argv[1], header), "r")
 

	
 
	lines = f.readlines()
 
	for i in range(len(lines)):
 
		line = lines[i]
 
		if line.find(method) != -1:
 
			if line.startswith(method):
 
				line = lines[i-1][:-1] + line
 
			m = line[:-1]
 
			l = unicode(m).strip()
 
			if l.endswith(")"):
 
				continue
 

	
 
			if m.find("/*") > m.find(";"):
 
				m = m[:m.find("/*")]
 
				m.rstrip()
 
				if len(m) != 0:
 
					while m[-1] == " ":
 
						m = m[:-1]
 

	
 
			index = i;
 
			while not m.endswith(";"):
 
				index += 1
 
				m += " " + lines[index][:-1].lstrip()
 

	
 
			l = unicode(m).strip()
 
			if (l.startswith("#") or l.startswith("*") or l.startswith("/*") or l.count("***") != 0 or l.count("&&") != 0
 
				or l.endswith(")")):
 
				continue;
 

	
 
			m = m.replace("G_GNUC_NULL_TERMINATE", "")
 

	
 
			if not m in definitions:
 
				print "found", method[:-1], "in", header
 
				definitions += [m]
 
			break
 
	f.close()
 

	
 
def get_raw_args(d):
 
	return d[d.find("(")+1:-2]
 

	
 
def get_args(d):
 
	x = d[d.find("(")+1:-2]
 
	x = x.split(",")
 

	
 
	args = []
 
	for arg in x:
 
		y = arg.split(" ")
 
		if len(y) == 1:
 
			continue
 
		args += [y[-1].replace("*", "")]
 

	
 
	return args
 

	
 
def get_name(d):
 
	x = d[:d.find("(")+1].lstrip()
 
	if x.find("wpurple_") != -1:
 
		return x[x.find("wpurple_"):]
 
	if x.find("serv_") != -1:
 
		return x[x.find("serv_"):]
 
	return x[x.find("purple_"):]
 

	
 
def get_rtype(d):
 
	if d.find("wpurple_") != -1:
 
		return d[:d.find("wpurple_")].lstrip()
 
	if d.find("serv_") != -1:
 
		return d[:d.find("serv_")].lstrip()
 
	return d[:d.find("purple_")].lstrip()
 

	
 
def output():
 
	global definitions
 

	
 
	header = open("purple_defs.h", "w")
 
	print >> header, "#pragma once"
 
	print >> header, "#ifdef WIN32"
 

	
 
	print >> header, """
 
#include <Windows.h>
 
#include <purple.h>
 

	
 
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED(n)    (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CHAT_NODE)
 
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_BUDDY_NODE)
 
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CONTACT_NODE)
 
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_GROUP_NODE)
 

	
 
#define PURPLE_CONV_IM_WRAPPED(c) (purple_conversation_get_im_data_wrapped(c))
 
#define PURPLE_CONV_CHAT_WRAPPED(c) (purple_conversation_get_chat_data_wrapped(c))
 

	
 
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED(gc) \
 
	(purple_connection_get_state_wrapped(gc) == PURPLE_CONNECTED)
 
"""
 

	
 
	for d in definitions:
 
		#typedef void (_cdecl * purple_util_set_user_wrapped_func)(const char *dir);
 
		print >> header, "typedef", get_rtype(d), "(_cdecl *", get_name(d)[:-1] + "_wrapped_fnc)(" + get_raw_args(d) + ");"
 
		#extern purple_util_set_user_wrapped_func purple_util_set_user_wrapped;
 
		print >> header, "extern", get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped;"
 
		print >> header, ""
 

	
 
	print >> header, ""
 
	print >> header, "#else"
 
	print >> header, ""
 

	
 
	print >> header, """
 
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED PURPLE_BLIST_NODE_IS_CHAT
 
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED PURPLE_BLIST_NODE_IS_BUDDY
 
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED PURPLE_BLIST_NODE_IS_CONTACT
 
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED PURPLE_BLIST_NODE_IS_GROUP
 

	
 
#define PURPLE_CONV_IM_WRAPPED PURPLE_CONV_IM
 
#define PURPLE_CONV_CHAT_WRAPPED PURPLE_CONV_CHAT
 

	
 
#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED PURPLE_CONNECTION_IS_CONNECTED	
 
"""
 

	
 
	for d in definitions:
 
		#define purple_util_set_user_wrapped purple_util_set_user
 
		print >> header, "#define", get_name(d)[:-1] + "_wrapped", get_name(d)[:-1]
 
			
 
	print >> header, "#endif"
 
	print >> header, ""
 
	print >> header, "bool resolvePurpleFunctions();"
 
	print >> header, ""
 

	
 

	
 
	cpp = open("purple_defs.cpp", "w")
 
	print >> cpp, "#include \"purple_defs.h\""
 
	print >> cpp, ""
 
	print >> cpp, "#ifdef WIN32"
 
	print >> cpp, "static HMODULE f_hPurple = NULL;"
 
	for d in definitions:
 
		#purple_util_set_user_wrapped_fnc purple_util_set_user_wrapped = NULL;
 
		print >> cpp, get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped = NULL;"
 

	
 
	print >> cpp, "#endif"
 

	
 
	print >> cpp, "bool resolvePurpleFunctions() {"
 
	print >> cpp, "#ifdef WIN32"
 
	print >> cpp, "\tf_hPurple = LoadLibrary(\"libpurple.dll\");"
 
	print >> cpp, "\tif (!f_hPurple)"
 
	print >> cpp, "\t\t\treturn false;"
 
	for d in definitions:
 
		#purple_util_set_user_wrapped = (purple_util_set_user_wrapped_func)GetProcAddress(f_hPurple, "purple_util_set_user_dir");
 
		print >> cpp, "\t" + get_name(d)[:-1] + "_wrapped = (" + get_name(d)[:-1] + "_wrapped_fnc)GetProcAddress(f_hPurple, \"" + get_name(d)[:-1] + "\");"
 
		#if (!purple_util_set_user_wrapped)
 
		print >> cpp, "\tif (!" + get_name(d)[:-1] + "_wrapped)"
 
		print >> cpp, "\t\treturn false;"
 
		print >> cpp, ""
 
	print >> cpp, "#endif"
 

	
 
	print >> cpp, "\treturn true;"
 
	print >> cpp, "}"
 
	print >> cpp, ""
 

	
 
	cpp.close()
 
	header.close()
 
		
 

	
 
for f in os.listdir("."):
 
	if not f.endswith(".cpp") or f.startswith("purple_defs"):
 
		continue
 
	new_file = handle_file(f)
 

	
 
	print "updating", f
 
	fd = open(f, "w")
 
	fd.write(new_file)
 
	fd.close()
 

	
 
for f in os.listdir(sys.argv[1]):
 
	if not f.endswith(".h"):
 
		continue
 
	for m in methods:
 
		handle_header(f, m)
 

	
 
sys.argv[1] = sys.argv[1] + "/win32"
 
for f in os.listdir(sys.argv[1]):
 
	if not f.endswith(".h"):
 
		continue
 
	for m in methods:
 
		handle_header(f, m)
 

	
 
for m in methods:
 
	found = False
 
	for d in definitions:
 
		if d.find(m[:-1]) != -1:
 
			found = True
 
			break
 
	if not found:
 
		print "NOT FOUND:", m
 

	
 
output()
backends/libpurple/geventloop.cpp
Show inline comments
 
@@ -28,6 +28,8 @@
 
#include "event.h"
 
#endif
 

	
 
#include "purple_defs.h"
 

	
 
#include "transport/logging.h"
 

	
 
DEFINE_LOGGER(logger, "EventLoop");
backends/libpurple/main.cpp
Show inline comments
 
@@ -27,6 +27,8 @@
 
#define getpid _getpid
 
#endif
 

	
 
#include "purple_defs.h"
 

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

	
 
@@ -653,7 +655,11 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
		}
 

	
 
		void sendData(const std::string &string) {
 
#ifdef WIN32
 
			::send(main_socket, string.c_str(), string.size(), 0);
 
#else
 
			write(main_socket, string.c_str(), string.size());
 
#endif
 
			if (writeInput == 0)
 
				writeInput = purple_input_add(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
 
		}
 
@@ -789,7 +795,8 @@ static void buddyListNewNode(PurpleBlistNode *node) {
 
	PurpleBuddy *buddy = (PurpleBuddy *) node;
 
	PurpleAccount *account = purple_buddy_get_account(buddy);
 

	
 
	LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy));
 
	std::vector<std::string> groups = getGroups(buddy);
 
	LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy) << " group (" << groups.size() << ")=" << groups[0]);
 

	
 
	// Status
 
	pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
 
@@ -1424,6 +1431,8 @@ debug_init(void)
 
	REGISTER_G_LOG_HANDLER("GModule");
 
	REGISTER_G_LOG_HANDLER("GLib-GObject");
 
	REGISTER_G_LOG_HANDLER("GThread");
 
	REGISTER_G_LOG_HANDLER("GConf");
 
	
 

	
 
#undef REGISTER_G_LOD_HANDLER
 
}
 
@@ -1447,6 +1456,9 @@ static void signed_on(PurpleConnection *gc, gpointer unused) {
 
	// force returning of memory chunks allocated by libxml2 to kernel
 
	malloc_trim(0);
 
#endif
 

	
 
	// For prpl-gg
 
	execute_purple_plugin_action(gc, "Download buddylist from Server");
 
}
 

	
 
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
 
@@ -1511,6 +1523,13 @@ static void gotAttention(PurpleAccount *account, const char *who, PurpleConversa
 
static bool initPurple() {
 
	bool ret;
 

	
 
	if (!resolvePurpleFunctions()) {
 
		LOG4CXX_ERROR(logger, "Unable to load libpurple.dll or some of the needed methods");
 
		return false;
 
	}
 

	
 
	purple_plugins_add_search_path("./plugins");
 

	
 
	purple_util_set_user_dir("./");
 
	remove("./accounts.xml");
 
	remove("./blist.xml");
 
@@ -1586,7 +1605,11 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 
	if (cond & PURPLE_INPUT_READ) {
 
		char buffer[65535];
 
		char *ptr = buffer;
 
#ifdef WIN32
 
		ssize_t n = recv(source, ptr, sizeof(buffer), 0);
 
#else
 
		ssize_t n = read(source, ptr, sizeof(buffer));
 
#endif
 
		if (n <= 0) {
 
			LOG4CXX_INFO(logger, "Diconnecting from spectrum2 server");
 
			exit(errno);
backends/libpurple/purple_defs.cpp
Show inline comments
 
new file 100644
 
#include "purple_defs.h"
 
bool resolvePurpleFunctions() {
 
	return true;
 
}
 

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

	
 
bool resolvePurpleFunctions();
backends/libpurple/utils.cpp
Show inline comments
 
@@ -47,8 +47,32 @@
 
#include "win32/win32dep.h"
 
#endif
 

	
 
#include "purple_defs.h"
 

	
 
static GHashTable *ui_info = NULL;
 

	
 
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name) {
 
	PurplePlugin *plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
 
	if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
 
		PurplePluginAction *action = NULL;
 
		GList *actions, *l;
 

	
 
		actions = PURPLE_PLUGIN_ACTIONS(plugin, gc);
 

	
 
		for (l = actions; l != NULL; l = l->next) {
 
			if (l->data) {
 
				action = (PurplePluginAction *) l->data;
 
				action->plugin = plugin;
 
				action->context = gc;
 
				if ((std::string) action->label == name) {
 
					action->callback(action);
 
				}
 
				purple_plugin_action_free(action);
 
			}
 
		}
 
	}
 
}
 

	
 
GHashTable *spectrum_ui_get_info(void)
 
{
 
	if(NULL == ui_info) {
 
@@ -122,8 +146,8 @@ int create_socket(char *host, int portno) {
 
		main_socket = 0;
 
	}
 

	
 
	int flags = fcntl(main_socket, F_GETFL);
 
	flags |= O_NONBLOCK;
 
	fcntl(main_socket, F_SETFL, flags);
 
// 	int flags = fcntl(main_socket, F_GETFL);
 
// 	flags |= O_NONBLOCK;
 
// 	fcntl(main_socket, F_SETFL, flags);
 
	return main_socket;
 
}
backends/libpurple/utils.h
Show inline comments
 
@@ -21,10 +21,13 @@
 
#pragma once
 

	
 
#include "purple.h"
 
#include <string>
 

	
 
#ifndef WIN32
 
void spectrum_sigchld_handler(int sig);
 
#endif
 

	
 
int create_socket(char *host, int portno);
 
GHashTable *spectrum_ui_get_info(void);
 
\ No newline at end of file
 
GHashTable *spectrum_ui_get_info(void);
 

	
 
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name);
backends/skype/main.cpp
Show inline comments
 
@@ -165,6 +165,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			if (skype) {
 
				LOG4CXX_INFO(logger, "User wants to logout, logging out");
 
				skype->logout();
 
				Logging::shutdownLogging();
 
				exit(1);
 
			}
 
		}
 
@@ -801,6 +802,7 @@ static int create_socket(char *host, int portno) {
 
	if ((hos = gethostbyname(host)) == NULL) {
 
		// strerror() will not work for gethostbyname() and hstrerror() 
 
		// is supposedly obsolete
 
		Logging::shutdownLogging();
 
		exit(1);
 
	}
 
	serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
 
@@ -823,6 +825,7 @@ static gboolean transportDataReceived(GIOChannel *source, GIOCondition condition
 
	ssize_t n = read(m_sock, ptr, sizeof(buffer));
 
	if (n <= 0) {
 
		LOG4CXX_INFO(logger, "Diconnecting from spectrum2 server");
 
		Logging::shutdownLogging();
 
		exit(errno);
 
	}
 
	std::string d = std::string(buffer, n);
 
@@ -831,6 +834,7 @@ static gboolean transportDataReceived(GIOChannel *source, GIOCondition condition
 
}
 

	
 
static void io_destroy(gpointer data) {
 
	Logging::shutdownLogging();
 
	exit(1);
 
}
 

	
backends/template/main.cpp
Show inline comments
 
@@ -57,6 +57,8 @@ class TemplatePlugin : public NetworkPlugin {
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			handleConnected(user);
 
			LOG4CXX_INFO(logger, user << ": Added buddy - Echo.");
 
			handleBuddyChanged(user, "echo", "Echo", std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
@@ -64,6 +66,9 @@ class TemplatePlugin : public NetworkPlugin {
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "") {
 
			LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ".");
 
			if (legacyName == "echo") {
 
				handleMessage(user, legacyName, message);
 
			}
 
		}
 

	
 
		void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
backends/template/template_backend.py
Show inline comments
 
new file 100755
 
#!/usr/bin/python
 

	
 
import asyncore, argparse, protocol_pb2, socket, logging
 
from NetworkPlugin import NetworkPlugin
 

	
 
np = None
 

	
 

	
 
logger = logging.getLogger('Template Backend')
 
logger.setLevel(logging.DEBUG)
 
ch = logging.StreamHandler()
 
ch.setLevel(logging.DEBUG)
 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
ch.setFormatter(formatter)
 
logger.addHandler(ch)
 

	
 

	
 
def handleTransportData(data):
 
	"""
 
	This function is called when data is received from the NetworkPlugin server
 
	"""
 
	np.handleDataRead(data)
 
	
 
    
 
class SpectrumPlugin(NetworkPlugin):
 
	global logger
 
	def __init__(self, iochannel):
 
		NetworkPlugin.__init__(self)
 
		self.iochannel = iochannel
 
		logger.info("Starting plugin.")
 

	
 
	def sendData(self, string):
 
		"""
 
		NetworkPlugin uses this method to send the data to networkplugin server
 
		"""
 
		self.iochannel.sendData(string)
 
		logger.info("Starting plugin.")
 

	
 
	def handleLoginRequest(self, user, legacyName, password):
 
		self.handleConnected(user)
 
		logger.info("Added Echo Buddy")
 
		self.handleBuddyChanged(user, "echo", "Echo", [], protocol_pb2.STATUS_ONLINE)
 

	
 
	def handleLogoutRequest(self, user, legacyName):
 
		pass
 

	
 
	def handleMessageSendRequest(self, user, legacyName, message, xhtml = ""):
 
		logger.info("Message sent from "  + user + ' to ' + legacyName)
 
		if(legacyName == "echo"):
 
			logger.info("Message Echoed: " + message)
 
			self.handleMessage(user, legacyName, message)
 

	
 
	def handleBuddyUpdatedRequest(self, user, buddyName, alias, groups):
 
		logger.info("Added Buddy " + buddyName)
 
		self.handleBuddyChanged(user, buddyName, alias, groups, protocol_pb2.STATUS_ONLINE)
 
		
 
	def handleBuddyRemovedRequest(self, user, buddyName, groups):
 
		pass
 

	
 

	
 

	
 
class IOChannel(asyncore.dispatcher):
 
	def __init__(self, host, port, readCallBack):
 
		asyncore.dispatcher.__init__(self)
 
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
 
		self.connect((host, port))
 
		self.handleReceivedData = readCallBack
 
		self.send_buffer = ""
 

	
 
	def sendData(self, data):
 
		self.send_buffer += data
 

	
 
	def handle_connect(self):
 
		pass
 

	
 
	def handle_close(self):
 
		self.close()
 

	
 
	def handle_read(self):
 
		data = self.recv(65536)
 
		self.handleReceivedData(data)
 

	
 
	def handle_write(self):
 
		sent = self.send(self.send_buffer)
 
		self.send_buffer = self.send_buffer[sent:]
 

	
 
	def writable(self):
 
		return (len(self.send_buffer) > 0)
 

	
 
	def readable(self):
 
		return True
 

	
 

	
 
if __name__ == "__main__":
 
	parser = argparse.ArgumentParser()
 
	parser.add_argument('--host', type=str, required=True)
 
	parser.add_argument('--port', type=int, required=True)
 
	parser.add_argument('config_file', type=str)
 

	
 
	args = parser.parse_args()
 
	io = IOChannel(args.host, args.port, handleTransportData)
 
	np = SpectrumPlugin(io)
 
	asyncore.loop()
cmake_modules/CommuniConfig.cmake
Show inline comments
 
FIND_LIBRARY(IRC_LIBRARY NAMES Communi)
 
FIND_PATH(IRC_INCLUDE_DIR NAMES "ircglobal.h" PATH_SUFFIXES Communi qt4/Communi )
 
find_package(Qt4 REQUIRED)
 
include( ${QT_USE_FILE} )
 

	
 
FIND_LIBRARY(IRC_LIBRARY NAMES Communi PATHS ${QT_LIBRARY_DIR})
 
FIND_PATH(IRC_INCLUDE_DIR NAMES "ircglobal.h" PATHS ${QT_INCLUDE_DIR} PATH_SUFFIXES Communi)
 

	
 
# message( STATUS ${IRC_LIBRARY})
 
if( IRC_LIBRARY AND IRC_INCLUDE_DIR )
docs/Doxyfile
Show inline comments
 
deleted file
include/transport/localbuddy.h
Show inline comments
 
@@ -59,12 +59,7 @@ class LocalBuddy : public Buddy {
 
		}
 

	
 
		std::vector<std::string> getGroups() { return m_groups; }
 
		void setGroups(const std::vector<std::string> &groups) {
 
			bool changed = m_groups.size() != groups.size();
 
			m_groups = groups;
 
			if (changed)
 
				getRosterManager()->storeBuddy(this);
 
		}
 
		void setGroups(const std::vector<std::string> &groups);
 

	
 
	private:
 
		std::string m_name;
include/transport/logging.h
Show inline comments
 
@@ -35,6 +35,7 @@
 
#include "log4cxx/helpers/fileinputstream.h"
 
#include "log4cxx/helpers/transcoder.h"
 
#include "log4cxx/logger.h"
 
#include "log4cxx/logmanager.h"
 

	
 
#define DEFINE_LOGGER(VAR, NAME) static log4cxx::LoggerPtr VAR = log4cxx::Logger::getLogger(NAME);
 

	
 
@@ -55,6 +56,7 @@ namespace Logging {
 

	
 
void initBackendLogging(Config *config);
 
void initMainLogging(Config *config);
 
void shutdownLogging();
 

	
 
}
 

	
include/transport/networkplugin.h
Show inline comments
 
@@ -34,6 +34,22 @@ namespace Transport {
 
/// development.
 
class NetworkPlugin {
 
	public:
 

	
 
		class PluginConfig {
 
			public:
 
				PluginConfig() : m_needPassword(true) {}
 
				virtual ~PluginConfig() {}
 

	
 
				void setNeedPassword(bool needPassword = true) { m_needPassword = needPassword; }
 
				void setExtraFields(const std::vector<std::string> &fields) { m_extraFields = fields; }
 

	
 
			private:
 
				bool m_needPassword;
 
				std::vector<std::string> m_extraFields;
 

	
 
				friend class NetworkPlugin;
 
		};
 

	
 
		/// Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer.
 
		/// \param loop Event loop.
 
		/// \param host Host where Spectrum2 NetworkPluginServer runs.
 
@@ -43,6 +59,8 @@ class NetworkPlugin {
 
		/// Destructor.
 
		virtual ~NetworkPlugin();
 

	
 
		void sendConfig(const PluginConfig &cfg);
 

	
 
		/// Call this function when legacy network buddy changed.
 
		/// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld")
 
		/// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com")
include/transport/protocol.proto
Show inline comments
 
@@ -44,6 +44,7 @@ message Login {
 
	required string user = 1;
 
	required string legacyName = 2;
 
	required string password = 3;
 
	repeated string extraFields = 4;
 
}
 

	
 
message Logout {
 
@@ -122,6 +123,10 @@ message FileTransferData {
 
	required bytes data = 2;
 
}
 

	
 
message BackendConfig {
 
	required string config = 1;
 
}
 

	
 
message WrapperMessage {
 
	enum Type { 
 
		TYPE_CONNECTED 				= 1;
 
@@ -152,6 +157,7 @@ message WrapperMessage {
 
		TYPE_FT_PAUSE				= 27;
 
		TYPE_FT_CONTINUE			= 28;
 
		TYPE_EXIT					= 29;
 
		TYPE_BACKEND_CONFIG			= 30;
 
	}
 
	required Type type = 1;
 
	optional bytes payload = 2;
include/transport/transport.h
Show inline comments
 
@@ -37,6 +37,7 @@
 
#include "transport/config.h"
 
#include "transport/factory.h"
 
#include "transport/presenceoracle.h"
 
#include <Swiften/Network/BoostConnectionServer.h>
 

	
 
namespace Transport {
 
	// typedef enum { 	CLIENT_FEATURE_ROSTERX = 2,
 
@@ -165,6 +166,7 @@ namespace Transport {
 
		private:
 
			void handleConnected();
 
			void handleConnectionError(const Swift::ComponentError &error);
 
			void handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e);
 
			void handlePresence(Swift::Presence::ref presence);
 
			void handleDataRead(const Swift::SafeByteArray &data);
 
			void handleDataWritten(const Swift::SafeByteArray &data);
munin/spectrum2_
Show inline comments
 
new file 100755
 
#!/usr/bin/perl
 

	
 
# config:
 
# [spectrum2_*]
 
# env.admin_jid tradmin@host.org
 
# env.password jid_password
 
# env.transports icq.host.org xmpp.host.org
 
#
 
# symlinks: 
 
#    spectrum2_backends  spectrum2_memory  spectrum2_users spectrum2_messages spectrum2_messages_sec
 
#
 
#
 
use AnyEvent;
 
use AnyEvent::XMPP::Client;
 
use AnyEvent::XMPP::Component;
 
use AnyEvent::XMPP::Ext::Disco;
 
use AnyEvent::XMPP::Ext::Version;
 
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;
 
use AnyEvent::XMPP::Util qw/simxml/;
 
use XML::Simple;
 
use Time::HiRes qw ( setitimer ITIMER_REAL time );
 
use strict;
 
$|=1;
 

	
 
$SIG{ALRM} = sub { exit; };
 
setitimer(ITIMER_REAL, 30, 1);
 

	
 

	
 
my %config=(
 
    users => {
 
	title=>'Buddies online',
 
	vlabel=>'users',
 
	info=>'Number of users that currently use the spectrum transports.',
 
	command=>'online_users_count',
 
	base=>'--base 1000',
 
	x=>'1',
 
    },
 
    backends => {
 
	title=>'Backends running',
 
	vlabel=>'backends',
 
	info=>'Number of backends that currently running.',
 
	command=>'backends_count',
 
	base=>'--base 1000',
 
	x=>'1',
 
    },
 
    memory => {
 
	title=>'Memory usage of transports',
 
	vlabel=>'megabytes',
 
	info=>'Memory usage of spectrum transports.',
 
	command=>'used_memory',
 
	base=>'--base 1024',
 
	x=>'1024',
 
    },
 
    messages => {
 
	title=>'Messages send over transport',
 
	vlabel=>'messages',
 
	info=>'Messages send over spectrum transports.',
 
	command=>'',
 
	base=>'--base 1000',
 
	x=>'1',
 
    },
 
    messages_sec => {
 
	title=>'Messages send over transport',
 
	vlabel=>'messages/sec',
 
	info=>'Messages send per second over spectrum transports.',
 
	command=>'',
 
	base=>'--base 1000',
 
	x=>'1',
 
    },
 
);
 
my @queue=('_out','_in');
 
$0 =~ /spectrum2_(.+)*$/;
 
my $func = $1;
 
exit 2 unless defined $func;
 
my %tr;
 
my $count=0;
 
    foreach (split(' ',$ENV{'transports'})){
 
        if ($func=~/messages/)
 
	{
 
	    $tr{$_."_in"}=$count;
 
	    $count++;
 
	    $tr{$_."_out"}=$count;
 
	    $count++;
 
	}
 
	else
 
	{
 
	$tr{$_}=$count;
 
	$count++;
 
	}
 
    }
 

	
 
if (exists $ARGV[0] and $ARGV[0] eq "config") 
 
{
 
    print "graph_title ".$config{$func}->{'title'}."\n";
 
    print "graph_vlabel ".$config{$func}->{'vlabel'}."\n";
 
    print "graph_category spectrum2\n";
 
    foreach (keys (%tr)){
 
	print "r".$tr{$_}.".label ".$_."\n";
 
	if ($func eq 'messages_sec')
 
	{
 
	    print "r".$tr{$_}.".type DERIVE\n";
 
	    print "r".$tr{$_}.".min 0\n";
 
	}
 
    }
 
    print "graph_args ".$config{$func}->{'base'}."\n";
 
    print "graph_info ".$config{$func}->{'info'}."\n";
 
    exit 0;
 
}
 

	
 
binmode( STDOUT);
 
my $xs=new XML::Simple;
 
my $cl=AnyEvent::XMPP::Client->new(debug=>0);
 
my $j=AnyEvent->condvar;
 
$cl->add_account($ENV{'admin_jid'}.'/'.time,$ENV{'password'});
 
$cl->reg_cb(
 
    session_ready => \&cl_sess,
 
    disconnect => \&cl_disc,
 
    message => \&cl_msg,
 
);
 
$cl->start;
 
$j->wait;
 

	
 

	
 
sub cl_disc
 
{
 
my ($cl,$acc,$h,$p,$reas)=@_;
 
    print "disc ($h:$p) $reas\n";
 
}
 
sub cl_sess
 
{
 
    my($cl,$acc)=@_;
 
    foreach (keys (%tr)){
 
        if ($func=~/messages/)
 
	{
 
	    if (s/_in$//)
 
	    {
 
		$cl->send_message("messages_from_xmpp",$_,undef,'chat');
 
	    };
 
	    if (s/_out$//)
 
	    {
 
		$cl->send_message("messages_to_xmpp",$_,undef,'chat');
 
	    }
 
	}
 
	else
 
	{
 
	    $cl->send_message($config{$func}->{'command'},$_,undef,'chat');
 
	}
 
    }
 
}
 
sub cl_msg
 
{
 
    my ($cl,$acc,$msg)=@_;
 
    if ($func=~/messages/)
 
    {
 
	print "r".$tr{$msg->from.$queue[-1]}.".value ".int($msg->any_body/$config{$func}->{'x'})."\n";
 
	delete( $tr{$msg->from.$queue[-1]});
 
	pop(@queue);
 
	if ($#queue==-1){@queue=("_out","_in");}
 
    }
 
    else
 
    {
 
	print "r".$tr{$msg->from}.".value ".int($msg->any_body/$config{$func}->{'x'})."\n";
 
	delete( $tr{$msg->from});
 
    }
 
    exit if (scalar(keys %tr)==0);
 
}
plugin/cpp/networkplugin.cpp
Show inline comments
 
@@ -60,6 +60,25 @@ NetworkPlugin::NetworkPlugin() {
 
NetworkPlugin::~NetworkPlugin() {
 
}
 

	
 
void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
 
	std::string data = "[registration]";
 
	data += std::string("needPassword=") + (cfg.m_needPassword ? "1" : "0") + "\n";
 

	
 
	for (std::vector<std::string>::const_iterator it = cfg.m_extraFields.begin(); it != cfg.m_extraFields.end(); it++) {
 
		data += std::string("extraField=") + (*it) + "\n";
 
	}
 

	
 
	pbnetwork::BackendConfig m;
 
	m.set_config(data);
 

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

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BACKEND_CONFIG);
 

	
 
	send(message);
 
}
 

	
 
void NetworkPlugin::handleMessage(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname, const std::string &xhtml) {
 
	pbnetwork::ConversationMessage m;
 
	m.set_username(user);
plugin/python/CMakeLists.txt
Show inline comments
 
@@ -5,12 +5,12 @@ if (PROTOBUF_FOUND)
 
	set (PROTOBUF_PROTOC_EXECUTABLE protoc)
 
    endif()
 
    ADD_CUSTOM_COMMAND(
 
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/protocol_pb2.py
 
        COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out  ${CMAKE_CURRENT_BINARY_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
 
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
 
        COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out  ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
 
        COMMENT "Running Python protocol buffer compiler on protocol.proto"
 
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
 
    )
 
    ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/protocol_pb2.py)
 
    ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
 
endif()
 
 
plugin/python/NetworkPlugin.py
Show inline comments
 
new file 100644
 
import protocol_pb2, socket, struct, sys, os
 

	
 
def WRAP(MESSAGE, TYPE):
 
 	wrap = protocol_pb2.WrapperMessage()
 
	wrap.type = TYPE
 
	wrap.payload = MESSAGE
 
	return wrap.SerializeToString()
 
	
 
class NetworkPlugin:
 
	"""
 
	Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer.
 
	@param loop: Event loop.
 
	@param host: Host where Spectrum2 NetworkPluginServer runs.
 
	@param port: Port. 
 
	"""
 
	
 
	def __init__(self):
 
		self.m_pingReceived = False
 
		self.m_data = ""
 
		self.m_init_res = 0
 

	
 
	def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = ""):
 
		m = protocol_pb2.ConversationMessage()
 
		m.userName = user
 
		m.buddyName = legacyName
 
		m.message = msg
 
		m.nickname = nickname
 
		m.xhtml = xhtml
 

	
 
		message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE)
 
		self.send(message)
 

	
 
	def handleAttention(self, user, buddyName, msg):
 
		m = protocol_pb2.ConversationMessage()
 
		m.userName = user
 
		m.buddyName = buddyName
 
		m.message = msg
 

	
 
		message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ATTENTION)
 
		self.send(message)
 

	
 
	def handleVCard(self, user, ID, legacyName, fullName, nickname, photo):
 
		vcard = protocol_pb2.VCard()
 
		vcard.userName = user
 
		vcard.buddyName = legacyName
 
		vcard.id = ID
 
		vcard.fullname = fullName
 
		vcard.nickname = nickname
 
		vcard.photo = photo 
 

	
 
		message = WRAP(vcard.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_VCARD)
 
		self.send(message)
 

	
 

	
 
	def handleSubject(self, user, legacyName, msg, nickname = ""):
 
		m = protocol_pb2.ConversationMessage()
 
		m.userName = user
 
		m.buddyName = legacyName
 
		m.message = msg 
 
		m.nickname = nickname
 

	
 
		message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ROOM_SUBJECT_CHANGED)
 
		#print "SENDING MESSAGE"
 
		self.send(message)
 

	
 

	
 
	def handleBuddyChanged(self, user, buddyName, alias, groups, status, statusMessage = "", iconHash = "", blocked = False):
 
		buddy = protocol_pb2.Buddy()
 
		buddy.userName = user
 
		buddy.buddyName = buddyName
 
		buddy.alias = alias
 
		buddy.group.extend(groups)
 
		buddy.status = status
 
		buddy.statusMessage = statusMessage
 
		buddy.iconHash = iconHash
 
		buddy.blocked = blocked
 

	
 
		message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_CHANGED)
 
		self.send(message)
 

	
 

	
 
	def handleBuddyTyping(self, user, buddyName):
 
		buddy = protocol_pb2.Buddy()
 
		buddy.userName = user
 
		buddy.buddyName = buddyName
 

	
 
		message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING)
 
		self.send(message);
 

	
 
	def handleBuddyTyped(self, user, buddyName):
 
		buddy = protocol_pb2.Buddy()
 
		buddy.userName  = user
 
		buddy.buddyName = buddyName
 

	
 
		message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED)
 
		self.send(message);
 

	
 
	def handleBuddyStoppedTyping(self, user, buddyName):
 
		buddy = protocol_pb2.Buddy()
 
		buddy.userName = user
 
		buddy.buddyName = buddyName
 

	
 
		message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING)
 
		self.send(message)
 

	
 
	def handleAuthorization(self, user, buddyName):
 
		buddy = protocol_pb2.Buddy()
 
		buddy.userName = user
 
		buddy.buddyName = buddyName
 

	
 
		message = WRAP(buddy.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_AUTH_REQUEST)
 
		self.send(message)
 

	
 

	
 
	def handleConnected(self, user):
 
		d = protocol_pb2.Connected()
 
		d.user = user
 

	
 
		message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONNECTED)
 
		self.send(message);	
 

	
 

	
 
	def handleDisconnected(self, user, error = 0, msg = ""):
 
		d = protocol_pb2.Disconnected()
 
		d.user = user
 
		d.error = error
 
		d.message = msg
 

	
 
		message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_DISCONNECTED)
 
		self.send(message);
 

	
 

	
 
	def handleParticipantChanged(self, user, nickname, room, flags, status, statusMessage = "", newname = ""):
 
		d = protocol_pb2.Participant()
 
		d.userName = user
 
		d.nickname = nickname
 
		d.room = room
 
		d.flag = flags
 
		d.newname = newname
 
		d.status = status
 
		d.statusMessage = statusMessage
 

	
 
		message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_PARTICIPANT_CHANGED)
 
		self.send(message);
 

	
 

	
 
	def handleRoomNicknameChanged(self, user, r, nickname):
 
		room = protocol_pb2.Room()
 
		room.userName = user
 
		room.nickname = nickname
 
		room.room = r
 
		room.password = ""
 

	
 
		message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_ROOM_NICKNAME_CHANGED)
 
		self.send(message);
 

	
 

	
 
	def handleFTStart(self, user, buddyName, fileName, size):
 
		room = protocol_pb2.File()
 
		room.userName = user
 
		room.buddyName = buddyName
 
		room.fileName = fileName
 
		room.size = size
 

	
 
		message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_START)
 
		self.send(message);
 

	
 
	def handleFTFinish(self, user, buddyName, fileName, size, ftid):
 
		room = protocol_pb2.File()
 
		room.userName = user
 
		room.buddyName = buddyName
 
		room.fileName = fileName
 
		room.size = size
 

	
 
		# Check later
 
		if ftid != 0:
 
			room.ftID = ftid 
 
			
 
		message = WRAP(room.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_FINISH)
 
		self.send(message)
 

	
 

	
 
	def handleFTData(self, ftID, data):
 
		d = protocol_pb2.FileTransferData()
 
		d.ftid = ftID
 
		d.data = data
 

	
 
		message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA);
 
		self.send(message)
 

	
 
	def handleLoginPayload(self, data):
 
		payload = protocol_pb2.Login()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleLoginRequest(payload.user, payload.legacyName, payload.password)
 

	
 
	def handleLogoutPayload(self, data):
 
		payload = protocol_pb2.Logout()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleLogoutRequest(self, payload.user, payload.legacyName)
 
	
 
	def handleStatusChangedPayload(data):
 
		payload = protocol_pb2.Status()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleStatusChangeRequest(payload.userName, payload.status, payload.statusMessage)
 

	
 
	def handleConvMessagePayload(self, data):
 
		payload = protocol_pb2.ConversationMessage()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleMessageSendRequest(payload.userName, payload.buddyName, payload.message, payload.xhtml)
 

	
 
	def handleAttentionPayload(self, data):
 
		payload = protocol_pb2.ConversationMessage()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleAttentionRequest(payload.userName, payload.buddyName, payload.message)
 
	
 
	def handleFTStartPayload(self, data):
 
		payload = protocol_pb2.File()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleFTStartRequest(payload.userName, payload.buddyName, payload.fileName, payload.size, payload.ftID);
 

	
 
	def handleFTFinishPayload(self, data):
 
		payload = protocol_pb2.File()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleFTFinishRequest(payload.userName, payload.buddyName, payload.fileName, payload.size, payload.ftID)
 

	
 
	def handleFTPausePayload(self, data):
 
		payload = protocol_pb2.FileTransferData()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleFTPauseRequest(payload.ftID)
 

	
 
	def handleFTContinuePayload(self, data):
 
		payload = protocol_pb2.FileTransferData()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleFTContinueRequest(payload.ftID)
 

	
 
	def handleJoinRoomPayload(self, data):
 
		payload = protocol_pb2.Room()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleJoinRoomRequest(payload.userName, payload.room, payload.nickname, payload.password)
 

	
 
	def handleLeaveRoomPayload(self, data):
 
		payload = protocol_pb2.Room()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		self.handleLeaveRoomRequest(payload.userName, payload.room)
 

	
 
	def handleVCardPayload(self, data):
 
		payload = protocol_pb2.VCard()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		if payload.HasField('photo'):
 
			self.handleVCardUpdatedRequest(payload.userName, payload.photo, payload.nickname)
 
		elif len(payload.buddyName)  > 0:
 
			self.handleVCardRequest(payload.userName, payload.buddyName, payload.id)
 

	
 
	def handleBuddyChangedPayload(self, data):
 
		payload = protocol_pb2.Buddy()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		if payload.HasField('blocked'):
 
			self.handleBuddyBlockToggled(payload.userName, payload.buddyName, payload.blocked)
 
		else:
 
			groups = [g for g in payload.group]
 
			self.handleBuddyUpdatedRequest(payload.userName, payload.buddyName, payload.alias, groups);
 

	
 
	def handleBuddyRemovedPayload(self, data):
 
		payload = protocol_pb2.Buddy()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		groups = [g for g in payload.group]
 
		self.handleBuddyRemovedRequest(payload.userName, payload.buddyName, groups);
 

	
 
	def handleChatStatePayload(self, data, msgType):
 
		payload = protocol_pb2.Buddy()
 
		if (payload.ParseFromString(data) == False):
 
			#TODO: ERROR
 
			return
 
		if msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING:
 
				self.handleTypingRequest(payload.userName, payload.buddyName)
 
		elif  msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED:
 
				self.handleTypedRequest(payload.userName, payload.buddyName)
 
		elif msgType == protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING:
 
				self.handleStoppedTypingRequest(payload.userName, payload.buddyName)
 

	
 

	
 
	def handleDataRead(self, data):
 
		self.m_data += data
 
		while len(self.m_data) != 0:
 
			expected_size = 0
 
			if (len(self.m_data) >= 4):
 
				expected_size = struct.unpack('!I', self.m_data[0:4])[0]
 
				if (len(self.m_data) - 4 < expected_size):
 
					return
 
			else:
 
				return
 

	
 
			wrapper = protocol_pb2.WrapperMessage()
 
			if (wrapper.ParseFromString(self.m_data[4:]) == False):
 
				self.m_data = self.m_data[expected_size+4:]
 
				return
 

	
 
			self.m_data = self.m_data[4+expected_size:]
 

	
 
			if wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGIN:
 
					self.handleLoginPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGOUT:
 
					self.handleLogoutPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_PING:
 
					self.sendPong()
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE:
 
					self.handleConvMessagePayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_JOIN_ROOM:
 
					self.handleJoinRoomPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_LEAVE_ROOM:
 
					self.handleLeaveRoomPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_VCARD:
 
					self.handleVCardPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_CHANGED:
 
					self.handleBuddyChangedPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_REMOVED:
 
					self.handleBuddyRemovedPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_STATUS_CHANGED:
 
					self.handleStatusChangedPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING:
 
					self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPING)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED:
 
					self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_TYPED)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING:
 
					self.handleChatStatePayload(wrapper.payload, protocol_pb2.WrapperMessage.TYPE_BUDDY_STOPPED_TYPING)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_ATTENTION:
 
					self.handleAttentionPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_START:
 
					self.handleFTStartPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_FINISH:
 
					self.handleFTFinishPayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_PAUSE:
 
					self.handleFTPausePayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_FT_CONTINUE:
 
					self.handleFTContinuePayload(wrapper.payload)
 
			elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_EXIT:
 
					self.handleExitRequest()
 

	
 

	
 
	def send(self, data):
 
		header = struct.pack('!I',len(data))
 
		self.sendData(header + data)
 

	
 
	def checkPing(self):
 
		if (self.m_pingReceived == False):
 
			self.handleExitRequest()
 
		self.m_pingReceived = False
 

	
 

	
 
	def sendPong(self):
 
		self.m_pingReceived = True
 
		wrap = protocol_pb2.WrapperMessage()
 
		wrap.type = protocol_pb2.WrapperMessage.TYPE_PONG
 
		message = wrap.SerializeToString()
 
		self.send(message)
 
		self.sendMemoryUsage()
 
	
 

	
 
	def sendMemoryUsage(self):
 
		stats = protocol_pb2.Stats()
 

	
 
		stats.init_res = self.m_init_res
 
		res = 0
 
		shared = 0
 

	
 
		e_res, e_shared = self.handleMemoryUsage()
 

	
 
		stats.res = res + e_res
 
		stats.shared = shared + e_shared
 
		stats.id = str(os.getpid())
 

	
 
		message = WRAP(stats.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_STATS)
 
		self.send(message)
 

	
 

	
 
	def handleLoginRequest(self, user, legacyName, password):
 
		""" 
 
		Called when XMPP user wants to connect legacy network.
 
		You should connect him to legacy network and call handleConnected or handleDisconnected function later.
 
		@param user: XMPP JID of user for which this event occurs.
 
		@param legacyName: Legacy network name of this user used for login.
 
		@param password: Legacy network password of this user.
 
		"""
 

	
 
		#\msc
 
		#NetworkPlugin,YourNetworkPlugin,LegacyNetwork;
 
		#NetworkPlugin->YourNetworkPlugin [label="handleLoginRequest(...)", URL="\ref NetworkPlugin::handleLoginRequest()"];
 
		#YourNetworkPlugin->LegacyNetwork [label="connect the legacy network"];
 
		#--- [label="If password was valid and user is connected and logged in"];
 
		#YourNetworkPlugin<-LegacyNetwork [label="connected"];
 
		#YourNetworkPlugin->NetworkPlugin [label="handleConnected()", URL="\ref NetworkPlugin::handleConnected()"];
 
		#--- [label="else"];
 
		#YourNetworkPlugin<-LegacyNetwork [label="disconnected"];
 
		#YourNetworkPlugin->NetworkPlugin [label="handleDisconnected()", URL="\ref NetworkPlugin::handleDisconnected()"];
 
		#\endmsc
 

	
 
		raise NotImplementedError, "Implement me"
 

	
 
	def handleLogoutRequest(self, user, legacyName):
 
		"""
 
		Called when XMPP user wants to disconnect legacy network.
 
		You should disconnect him from legacy network.
 
		@param user: XMPP JID of user for which this event occurs.
 
		@param legacyName: Legacy network name of this user used for login.
 
		"""
 

	
 
		raise NotImplementedError, "Implement me"
 

	
 
	def handleMessageSendRequest(self, user, legacyName, message, xhtml = ""):
 
		"""
 
		Called when XMPP user sends message to legacy network.
 
		@param user: XMPP JID of user for which this event occurs.
 
		@param legacyName: Legacy network name of buddy or room.
 
		@param message: Plain text message.
 
		@param xhtml: XHTML message.
 
		"""
 

	
 
		raise NotImplementedError, "Implement me"
 

	
 
	def handleVCardRequest(self, user, legacyName, ID):
 
		""" Called when XMPP user requests VCard of buddy.
 
		@param user: XMPP JID of user for which this event occurs.
 
		@param legacyName: Legacy network name of buddy whose VCard is requested.
 
		@param ID: ID which is associated with this request. You have to pass it to handleVCard function when you receive VCard."""
 
			
 
		#\msc
 
		#NetworkPlugin,YourNetworkPlugin,LegacyNetwork;
 
		#NetworkPlugin->YourNetworkPlugin [label="handleVCardRequest(...)", URL="\ref NetworkPlugin::handleVCardRequest()"];
 
		#YourNetworkPlugin->LegacyNetwork [label="start VCard fetching"];
 
		#YourNetworkPlugin<-LegacyNetwork [label="VCard fetched"];
 
		#YourNetworkPlugin->NetworkPlugin [label="handleVCard()", URL="\ref NetworkPlugin::handleVCard()"];
 
		#\endmsc
 
	
 
		pass
 
			
 

	
 
	def handleVCardUpdatedRequest(self, user, photo, nickname):
 
		"""
 
		Called when XMPP user updates his own VCard.
 
		You should update the VCard in legacy network too.
 
		@param user: XMPP JID of user for which this event occurs.
 
		@param photo: Raw photo data.
 
		"""
 
		pass
 

	
 
	def handleJoinRoomRequest(self, user, room, nickname, pasword):
 
		pass
 
		
 
	def handleLeaveRoomRequest(self, user, room):
 
		pass
 
		
 
	def handleStatusChangeRequest(self, user, status, statusMessage):
 
		pass
 

	
 
	def handleBuddyUpdatedRequest(self, user,  buddyName, alias, groups):
 
		pass
 
		
 
	def handleBuddyRemovedRequest(self, user, buddyName, groups):
 
		pass
 
		
 
	def handleBuddyBlockToggled(self, user, buddyName, blocked):
 
		pass
 

	
 
	def handleTypingRequest(self, user, buddyName):
 
		pass
 
		
 
	def handleTypedRequest(self, user, buddyName):
 
		pass
 
		
 
	def handleStoppedTypingRequest(self, user, buddyName):
 
		pass
 
		
 
	def handleAttentionRequest(self, user, buddyName, message):
 
		pass
 

	
 
	def handleFTStartRequest(self, user, buddyName, fileName, size, ftID):
 
		pass
 
		
 
	def handleFTFinishRequest(self, user, buddyName, fileName, size, ftID):
 
		pass
 
		
 
	def handleFTPauseRequest(self, ftID):
 
		pass
 

	
 
	def handleFTContinueRequest(self, ftID):
 
		pass
 

	
 
	def handleMemoryUsage(self):
 
		return (0,0)
 

	
 
	def handleExitRequest(self):
 
		sys.exit(1)
 

	
 
	def sendData(self, data):
 
		pass
 

	
spectrum/src/sample.cfg
Show inline comments
 
@@ -14,8 +14,8 @@ admin_password=test
 
#cert_password=test #password to that certificate if any
 
users_per_backend=10
 
#backend=../..//backends/libpurple/spectrum2_libpurple_backend
 
backend=../../backends/template/spectrum2_template_backend
 
protocol=prpl-xmpp
 
backend=../../backends/template/template_backend.py
 
protocol=prpl-jabber
 
#protocol=prpl-msn
 
#protocol=any
 
#protocol=prpl-icq
spectrum_manager/src/main.cpp
Show inline comments
 
@@ -310,12 +310,12 @@ static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactorie
 
					std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
 
				}
 
 
				if (CONFIG_STRING(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
 
				if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
 
					std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
 
				}
 
 
				finished++;
 
				Swift::Client *client = new Swift::Client(CONFIG_STRING(&cfg, "service.admin_jid"), CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
 
				Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
 
				client->setAlwaysTrustCertificates();
 
				client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
 
				client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
src/CMakeLists.txt
Show inline comments
 
@@ -44,16 +44,11 @@ if (CMAKE_COMPILER_IS_GNUCXX)
 
	endif()
 
endif()
 

	
 
if (NOT CMAKE_COMPILER_IS_GNUCXX)
 
	include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/protobuf/libprotobuf")
 
	TARGET_LINK_LIBRARIES(transport transport-plugin sqlite3 libprotobuf ${PQXX_LIBRARY} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
 
else ()
 
	if (WIN32)
 
		TARGET_LINK_LIBRARIES(transport transport-plugin sqlite3 ${PQXX_LIBRARY} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARIES})
 
	else()
 
		TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
 
	endif()
 
endif()
 
if (WIN32)
 
	TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
 
else (WIN32)
 
	TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
 
endif(WIN32)
 

	
 
SET_TARGET_PROPERTIES(transport PROPERTIES
 
      VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
src/admininterface.cpp
Show inline comments
 
@@ -59,11 +59,13 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
 
	if (!message->getTo().getNode().empty())
 
		return;
 

	
 
	if (message->getFrom().toBare().toString() != CONFIG_STRING(m_component->getConfig(), "service.admin_jid")) {
 
		LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().toBare().toString());
 
		return;
 
	std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid");
 
	if (std::find(x.begin(), x.end(), message->getFrom().toBare().toString()) == x.end()) {
 
	    LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().toBare().toString());
 
	    return;
 
	
 
	}
 

	
 
	
 
	// Ignore empty messages
 
	if (message->getBody().empty()) {
 
		return;
 
@@ -257,6 +259,14 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
 
		}
 
		message->setBody(lst);
 
	}
 
	else if (message->getBody() == "messages_from_xmpp") {
 
		int msgCount = m_userManager->getMessagesToBackend();
 
		message->setBody(boost::lexical_cast<std::string>(msgCount));
 
	}
 
	else if (message->getBody() == "messages_to_xmpp") {
 
		int msgCount = m_userManager->getMessagesToXMPP();
 
		message->setBody(boost::lexical_cast<std::string>(msgCount));
 
	}
 
	else if (message->getBody().find("help") == 0) {
 
		std::string help;
 
		help += "General:\n";
 
@@ -267,6 +277,9 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
 
		help += "    online_users_count - number of online users\n";
 
		help += "    online_users_per_backend - shows online users per backends\n";
 
		help += "    has_online_user <bare_JID> - returns 1 if user is online\n";
 
		help += "Messages:\n";
 
		help += "    messages_from_xmpp - get number of messages received from XMPP users\n";
 
		help += "    messages_to_xmpp - get number of messages sent to XMPP users\n";
 
		help += "Backends:\n";
 
		help += "    backends_count - number of active backends\n";
 
		help += "    crashed_backends - returns IDs of crashed backends\n";
src/config.cpp
Show inline comments
 
@@ -29,10 +29,16 @@
 
#endif
 
#endif
 

	
 
#include "iostream"
 
#include "boost/version.hpp"
 

	
 
#define BOOST_MAJOR_VERSION BOOST_VERSION / 100000
 
#define BOOST_MINOR_VERSION BOOST_VERSION / 100 % 1000
 

	
 
using namespace boost::program_options;
 

	
 
namespace Transport {
 
int getRandomPort(const std::string &s) {
 
static int getRandomPort(const std::string &s) {
 
	unsigned long r = 0;
 
	BOOST_FOREACH(char c, s) {
 
		r += (int) c;
 
@@ -72,14 +78,14 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 
		("service.protocol", value<std::string>()->default_value(""), "Protocol")
 
		("service.pidfile", value<std::string>()->default_value("/var/run/spectrum2/$jid.pid"), "Full path to pid file")
 
		("service.working_dir", value<std::string>()->default_value("/var/lib/spectrum2/$jid"), "Working dir")
 
		("service.allowed_servers", value<std::string>()->default_value(""), "Only users from these servers can connect")
 
		("service.allowed_servers", value<std::vector<std::string> >()->multitoken(), "Only users from these servers can connect")
 
		("service.server_mode", value<bool>()->default_value(false), "True if Spectrum should behave as server")
 
		("service.users_per_backend", value<int>()->default_value(100), "Number of users per one legacy network backend")
 
		("service.backend_host", value<std::string>()->default_value("localhost"), "Host to bind backend server to")
 
		("service.backend_port", value<std::string>()->default_value("0"), "Port to bind backend server to")
 
		("service.cert", value<std::string>()->default_value(""), "PKCS#12 Certificate.")
 
		("service.cert_password", value<std::string>()->default_value(""), "PKCS#12 Certificate password.")
 
		("service.admin_jid", value<std::string>()->default_value(""), "Administrator jid.")
 
		("service.admin_jid", value<std::vector<std::string> >()->multitoken(), "Administrator jid.")
 
		("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
 
		("service.reuse_old_backends", value<bool>()->default_value(true), "True if Spectrum should use old backends which were full in the past.")
 
		("service.idle_reconnect_time", value<int>()->default_value(0), "Time in seconds after which idle users are reconnected to let their backend die.")
 
@@ -101,6 +107,8 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 
		("registration.local_username_label", value<std::string>()->default_value("Local username:"), "Label for local usernme field")
 
		("registration.local_account_server", value<std::string>()->default_value("localhost"), "The server on which the local accounts will be checked for validity")
 
		("registration.local_account_server_timeout", value<int>()->default_value(10000), "Timeout when checking local user on local_account_server (msecs)")
 
		("gateway_responder.prompt", value<std::string>()->default_value("Contact ID"), "Value of <prompt> </promt> field")
 
		("gateway_responder.label", value<std::string>()->default_value("Enter legacy network contact ID."), "Label for add contact ID field")
 
		("database.type", value<std::string>()->default_value("none"), "Database type.")
 
		("database.database", value<std::string>()->default_value("/var/lib/spectrum2/$jid/database.sql"), "Database used to store data")
 
		("database.server", value<std::string>()->default_value("localhost"), "Database server.")
 
@@ -195,8 +203,17 @@ bool Config::load(std::istream &ifs) {
 
}
 

	
 
bool Config::load(const std::string &configfile, const std::string &jid) {
 
	options_description opts("Transport options");
 
	return load(configfile, opts, jid);
 
	try {
 
		options_description opts("Transport options");
 
		return load(configfile, opts, jid);
 
	} catch ( const boost::program_options::multiple_occurrences& e ) {
 
#if (BOOST_MAJOR_VERSION >= 1 && BOOST_MINOR_VERSION >= 42)
 
		std::cerr << configfile << " parsing error: " << e.what() << " from option: " << e.get_option_name() << std::endl;
 
#else
 
		std::cerr << configfile << " parsing error: " << e.what() << std::endl;
 
#endif
 
		return false;
 
	}
 
}
 

	
 
bool Config::reload() {
src/discoinforesponder.cpp
Show inline comments
 
@@ -88,11 +88,15 @@ bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::J
 

	
 
	// presence for transport
 
	if (to.getNode().empty()) {
 
		sendResponse(from, id, boost::shared_ptr<DiscoInfo>(new DiscoInfo(m_transportInfo)));
 
		boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
 
		res->setNode(info->getNode());
 
		sendResponse(from, id, res);
 
	}
 
	// presence for buddy
 
	else {
 
		sendResponse(from, to, id, boost::shared_ptr<DiscoInfo>(new DiscoInfo(m_buddyInfo)));
 
		boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_buddyInfo));
 
		res->setNode(info->getNode());
 
		sendResponse(from, to, id, res);
 
	}
 
	return true;
 
}
src/gatewayresponder.cpp
Show inline comments
 
@@ -45,7 +45,9 @@ GatewayResponder::~GatewayResponder() {
 
}
 

	
 
bool GatewayResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload) {
 
	sendResponse(from, id, boost::shared_ptr<GatewayPayload>(new GatewayPayload(Swift::JID(), "Enter legacy network contact ID.", "Contact ID")));
 
	std::string prompt = CONFIG_STRING(m_userManager->getComponent()->getConfig(), "gateway_responder.prompt");
 
	std::string label = CONFIG_STRING(m_userManager->getComponent()->getConfig(), "gateway_responder.label");
 
	sendResponse(from, id, boost::shared_ptr<GatewayPayload>(new GatewayPayload(Swift::JID(), label, prompt)));
 
	return true;
 
}
 

	
src/localbuddy.cpp
Show inline comments
 
@@ -48,4 +48,24 @@ void LocalBuddy::setAlias(const std::string &alias) {
 
	}
 
}
 

	
 
void LocalBuddy::setGroups(const std::vector<std::string> &groups) {
 
	bool changed = m_groups.size() != groups.size();
 
	if (!changed) {
 
		for (int i = 0; i != m_groups.size(); i++) {
 
			if (m_groups[i] != groups[i]) {
 
				changed = true;
 
				break;
 
			}
 
		}
 
	}
 

	
 
	m_groups = groups;
 
	if (changed) {
 
		if (getRosterManager()->getUser()->getComponent()->inServerMode() || getRosterManager()->isRemoteRosterSupported()) {
 
			getRosterManager()->sendBuddyRosterPush(this);
 
		}
 
		getRosterManager()->storeBuddy(this);
 
	}
 
}
 

	
 
}
src/logging.cpp
Show inline comments
 
@@ -139,11 +139,19 @@ void initMainLogging(Config *config) {
 
	initLogging(config, "logging.config");
 
}
 

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

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

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

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

	
src/rostermanager.cpp
Show inline comments
 
@@ -232,7 +232,10 @@ void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPa
 
		if (m_buddies.find(legacyName) != m_buddies.end()) {
 
			continue;
 
		}
 
		std::cout << "LEGACYNAME " << legacyName << "\n";
 

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

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

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

	
 
void RosterManager::handleSubscription(Swift::Presence::ref presence) {
 
	std::string legacyName = Buddy::JIDToLegacyName(presence->getTo());
 
	if (legacyName.empty()) {
 
		return;
 
	}
 
	
 
	// For server mode the subscription changes are handler in rosterresponder.cpp
 
	// using roster pushes.
 
	if (m_component->inServerMode()) {
src/storagebackend.cpp
Show inline comments
 
@@ -10,7 +10,8 @@ namespace Transport {
 
StorageBackend *StorageBackend::createBackend(Config *config, std::string &error) {
 
	StorageBackend *storageBackend = NULL;
 
#ifdef WITH_SQLITE
 
	if (CONFIG_STRING(config, "database.type") == "sqlite3") {
 
	if (CONFIG_STRING(config, "database.type") == "sqlite3" ||
 
		(CONFIG_STRING(config, "database.type") == "none" && !CONFIG_BOOL(config, "service.server_mode"))) {
 
		storageBackend = new SQLite3Backend(config);
 
	}
 
#else
 
@@ -43,6 +44,7 @@ StorageBackend *StorageBackend::createBackend(Config *config, std::string &error
 
		&& CONFIG_STRING(config, "database.type") != "pqxx" && CONFIG_STRING(config, "database.type") != "none") {
 
		error = "Unknown storage backend " + CONFIG_STRING(config, "database.type");
 
	}
 

	
 
	return storageBackend;
 
}
 

	
src/transport.cpp
Show inline comments
 
@@ -216,6 +216,11 @@ void Component::start() {
 
	else if (m_server) {
 
		LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server->start();
 

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

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

	
 

	
 
void Component::handleConnectionError(const ComponentError &error) {
 
	onConnectionError(error);
 
// 	if (m_reconnectCount == 2)
src/usermanager.cpp
Show inline comments
 
@@ -150,7 +150,10 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
	// Create user class if it's not there
 
	if (!user) {
 
		// Admin user is not legacy network user, so do not create User class instance for him
 
		if (m_component->inServerMode() && CONFIG_STRING(m_component->getConfig(), "service.admin_jid") == presence->getFrom().toBare().toString()) {
 
		if (m_component->inServerMode()) {
 
		    std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid");
 
		    if (std::find(x.begin(), x.end(), presence->getFrom().toBare().toString()) != x.end()) {
 
		
 
			// Send admin contact to the user.
 
			Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
			Swift::RosterItemPayload item;
 
@@ -167,6 +170,7 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
 
			response->setFrom(m_component->getJID());
 
			m_component->getStanzaChannel()->sendPresence(response);
 
			return;
 
		    }
 
		}
 

	
 
		// No user and unavailable presence -> answer with unavailable
src/userregistration.cpp
Show inline comments
 
@@ -168,7 +168,7 @@ bool UserRegistration::handleGetRequest(const Swift::JID& from, const Swift::JID
 
	std::string barejid = from.toBare().toString();
 

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

	
 
	if (!CONFIG_BOOL(m_config,"registration.enable_public_registration")) {
 
		std::list<std::string> const &x = CONFIG_LIST(m_config,"service.allowed_servers");
 
		std::vector<std::string> const &x = CONFIG_VECTOR(m_config,"service.allowed_servers");
 
		if (std::find(x.begin(), x.end(), from.getDomain()) == x.end()) {
 
			LOG4CXX_INFO(logger, barejid << ": This user has no permissions to register an account")
 
			sendError(from, id, ErrorPayload::BadRequest, ErrorPayload::Modify);
src/userregistry.cpp
Show inline comments
 
@@ -38,7 +38,8 @@ UserRegistry::UserRegistry(Config *cfg, Swift::NetworkFactories *factories) {
 
UserRegistry::~UserRegistry() { m_removeTimer->stop(); }
 

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

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

	
 
	// Users try to connect twice
src/vcardresponder.cpp
Show inline comments
 
@@ -101,7 +101,7 @@ bool VCardResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
 
	LOG4CXX_INFO(logger, from.toBare().toString() << ": Requested VCard of " << name);
 

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