Merge branch 'master' of git://github.com/hanzz/libtransport
This commit is contained in:
commit
6a4849f0a9
93 changed files with 19898 additions and 1608 deletions
|
@ -31,10 +31,10 @@ set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
|||
find_package(event)
|
||||
|
||||
set(Swiften_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(Swiften REQUIRED)
|
||||
find_package(Swiften)
|
||||
|
||||
set(openssl_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(openssl REQUIRED)
|
||||
find_package(openssl)
|
||||
|
||||
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
if (WIN32)
|
||||
|
@ -63,6 +63,9 @@ find_package(pqxx)
|
|||
set(dbus_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(dbus)
|
||||
|
||||
set(yahoo2_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
|
||||
find_package(yahoo2)
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
INCLUDE(FindQt4)
|
||||
|
@ -162,6 +165,14 @@ if (PROTOBUF_FOUND)
|
|||
message("Skype plugin : no (install dbus-glib-devel)")
|
||||
endif()
|
||||
|
||||
# We have our own copy now...
|
||||
# if(YAHOO2_FOUND)
|
||||
message("Libyahoo2 plugin : yes")
|
||||
# include_directories(${YAHOO2_INCLUDE_DIR})
|
||||
# else()
|
||||
# message("Libyahoo2 plugin : no (install libyahoo2-devel)")
|
||||
# endif()
|
||||
|
||||
else()
|
||||
message("Network plugins : no (install libprotobuf-dev)")
|
||||
message("Libpurple plugin : no (install libpurple and libprotobuf-dev)")
|
||||
|
|
49
ChangeLog
49
ChangeLog
|
@ -1,4 +1,42 @@
|
|||
Version 2.0.0-beta2 (2012-XX-XX):
|
||||
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.
|
||||
* Show error in server-mode when server port is already used.
|
||||
* Fixed bug when backend could freeze on exit.
|
||||
* Options from config file can now be set also using command line like
|
||||
--service.jid=domain.tld .
|
||||
* Do not send password in IQ-get registration response.
|
||||
|
||||
Libpurple:
|
||||
* prpl-gg: Fetch the contact list properly (#252).
|
||||
* Added support for prpl-novell as it was in spectrum1.
|
||||
|
||||
Skype:
|
||||
* Log more errors.
|
||||
|
||||
Libyahoo2:
|
||||
* Added new Yahoo backend based on libyahoo2.
|
||||
|
||||
Swiften:
|
||||
* Added new XMPP backend based on Swiften library.
|
||||
|
||||
Backend API:
|
||||
* Added Python NetworkPlugin class, so it is now easier to write backends
|
||||
in Python (Thanks to Sarang).
|
||||
|
||||
Version 2.0.0-beta2 (2012-03-28):
|
||||
General:
|
||||
* Fixed bug when Roster Item Exchange and subscribe stanzas were sent
|
||||
repeatedly.
|
||||
|
@ -6,13 +44,19 @@ Version 2.0.0-beta2 (2012-XX-XX):
|
|||
* Fixed username_mask setting.
|
||||
* Added new fields into statistics (backends_crashed, messages related
|
||||
stats).
|
||||
* Chatstates are now not counted as incoming messages in stats.
|
||||
* Log4cxx is now optional dependency. Without Log4cxx, Spectrum 2 logs
|
||||
to standard output.
|
||||
* Fixed crash when Log4cxx configuration file didn't exist.
|
||||
* Admin can now see "Admin" contact in server-mode.
|
||||
|
||||
libpurple:
|
||||
* Added support for MUC for prpl-jabber protocol.
|
||||
* Added initial support for MUC for prpl-jabber protocol.
|
||||
|
||||
LibCommuni IRC backend:
|
||||
* Fixed sending/receiving UTF8 messages.
|
||||
* Using the [registration] auto_register=1 config option, users don't
|
||||
have to register manually when connecting IRC network.
|
||||
|
||||
Skype:
|
||||
* Memory usage statistic now includes the Skype client.
|
||||
|
@ -21,6 +65,7 @@ Version 2.0.0-beta2 (2012-XX-XX):
|
|||
* Skype backend includes also Skype client memory usage into the account.
|
||||
* Working buddies adding/removing.
|
||||
* Information about missed call is now forwarded to XMPP user.
|
||||
* Fixed bug when Skype client instance wasn't killed by backend.
|
||||
|
||||
Version 2.0.0-beta (2012-02-28):
|
||||
General:
|
||||
|
|
|
@ -9,6 +9,12 @@ if (PROTOBUF_FOUND)
|
|||
|
||||
ADD_SUBDIRECTORY(smstools3)
|
||||
|
||||
ADD_SUBDIRECTORY(swiften)
|
||||
|
||||
# if(YAHOO2_FOUND)
|
||||
ADD_SUBDIRECTORY(libyahoo2)
|
||||
# endif()
|
||||
|
||||
ADD_SUBDIRECTORY(template)
|
||||
|
||||
if (NOT WIN32)
|
||||
|
|
|
@ -78,7 +78,7 @@ int main (int argc, char* argv[]) {
|
|||
|
||||
Swift::QtEventLoop eventLoop;
|
||||
|
||||
if (config.getUnregistered().find("service.irc_server") == config.getUnregistered().end()) {
|
||||
if (!CONFIG_HAS_KEY(&config, "service.irc_server")) {
|
||||
np = new IRCNetworkPlugin(&config, &eventLoop, host, port);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -10,13 +10,19 @@ DEFINE_LOGGER(logger, "SingleIRCNetworkPlugin");
|
|||
|
||||
SingleIRCNetworkPlugin::SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
|
||||
this->config = config;
|
||||
m_server = config->getUnregistered().find("service.irc_server")->second;
|
||||
if (CONFIG_HAS_KEY(config, "service.irc_server")) {
|
||||
m_server = CONFIG_STRING(config, "service.irc_server");
|
||||
}
|
||||
else {
|
||||
LOG4CXX_ERROR(logger, "No [service] irc_server defined, exiting...");
|
||||
exit(-1);
|
||||
}
|
||||
m_socket = new QTcpSocket();
|
||||
m_socket->connectToHost(FROM_UTF8(host), port);
|
||||
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
|
||||
if (config->getUnregistered().find("service.irc_identify") != config->getUnregistered().end()) {
|
||||
m_identify = config->getUnregistered().find("service.irc_identify")->second;
|
||||
if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
|
||||
m_identify = CONFIG_STRING(config, "service.irc_identify");
|
||||
}
|
||||
else {
|
||||
m_identify = "NickServ identify $name $password";
|
||||
|
|
251
backends/libpurple/gen_dynamic_purple.py
Normal file
251
backends/libpurple/gen_dynamic_purple.py
Normal file
|
@ -0,0 +1,251 @@
|
|||
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()
|
|
@ -28,6 +28,8 @@
|
|||
#include "event.h"
|
||||
#endif
|
||||
|
||||
#include "purple_defs.h"
|
||||
|
||||
#include "transport/logging.h"
|
||||
|
||||
DEFINE_LOGGER(logger, "EventLoop");
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#define getpid _getpid
|
||||
#endif
|
||||
|
||||
#include "purple_defs.h"
|
||||
|
||||
DEFINE_LOGGER(logger_libpurple, "libpurple");
|
||||
DEFINE_LOGGER(logger, "backend");
|
||||
|
||||
|
@ -48,6 +50,21 @@ template <class T> std::string stringOf(T object) {
|
|||
return (os.str());
|
||||
}
|
||||
|
||||
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while(std::getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
static std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
return split(s, delim, elems);
|
||||
}
|
||||
|
||||
static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond);
|
||||
|
||||
class SpectrumNetworkPlugin;
|
||||
|
@ -287,6 +304,24 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
i++;
|
||||
}
|
||||
g_strfreev (keys);
|
||||
|
||||
char* contents;
|
||||
gsize length;
|
||||
gboolean ret = g_file_get_contents ("gfire.cfg", &contents, &length, NULL);
|
||||
if (ret) {
|
||||
purple_account_set_int(account, "version", fromString<int>(std::string(contents, length)));
|
||||
}
|
||||
|
||||
|
||||
if (KEYFILE_STRING("service", "protocol") == "prpl-novell") {
|
||||
std::string username(purple_account_get_username(account));
|
||||
std::vector <std::string> u = split(username, '@');
|
||||
purple_account_set_username(account, (const char*) u.front().c_str());
|
||||
std::vector <std::string> s = split(u.back(), ':');
|
||||
purple_account_set_string(account, "server", s.front().c_str());
|
||||
purple_account_set_int(account, "port", atoi(s.back().c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
|
@ -346,6 +381,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
|
|||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
PurpleAccount *account = m_sessions[user];
|
||||
if (account) {
|
||||
if (purple_account_get_int(account, "version", 0) != 0) {
|
||||
std::string data = stringOf(purple_account_get_int(account, "version", 0));
|
||||
g_file_set_contents ("gfire.cfg", data.c_str(), data.size(), NULL);
|
||||
}
|
||||
// VALGRIND_DO_LEAK_CHECK;
|
||||
m_sessions.erase(user);
|
||||
purple_account_disconnect(account);
|
||||
|
@ -653,7 +692,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 +832,8 @@ static void buddyListNewNode(PurpleBlistNode *node) {
|
|||
PurpleBuddy *buddy = (PurpleBuddy *) node;
|
||||
PurpleAccount *account = purple_buddy_get_account(buddy);
|
||||
|
||||
LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy));
|
||||
std::vector<std::string> groups = getGroups(buddy);
|
||||
LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy) << " group (" << groups.size() << ")=" << groups[0]);
|
||||
|
||||
// Status
|
||||
pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
|
||||
|
@ -1424,6 +1468,8 @@ debug_init(void)
|
|||
REGISTER_G_LOG_HANDLER("GModule");
|
||||
REGISTER_G_LOG_HANDLER("GLib-GObject");
|
||||
REGISTER_G_LOG_HANDLER("GThread");
|
||||
REGISTER_G_LOG_HANDLER("GConf");
|
||||
|
||||
|
||||
#undef REGISTER_G_LOD_HANDLER
|
||||
}
|
||||
|
@ -1447,6 +1493,9 @@ static void signed_on(PurpleConnection *gc, gpointer unused) {
|
|||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
|
||||
// For prpl-gg
|
||||
execute_purple_plugin_action(gc, "Download buddylist from Server");
|
||||
}
|
||||
|
||||
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
|
||||
|
@ -1511,6 +1560,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 +1642,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);
|
||||
|
|
5
backends/libpurple/purple_defs.cpp
Normal file
5
backends/libpurple/purple_defs.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "purple_defs.h"
|
||||
bool resolvePurpleFunctions() {
|
||||
return true;
|
||||
}
|
||||
|
3
backends/libpurple/purple_defs.h
Normal file
3
backends/libpurple/purple_defs.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
bool resolvePurpleFunctions();
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
GHashTable *spectrum_ui_get_info(void);
|
||||
|
||||
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name);
|
||||
|
|
14
backends/libyahoo2/CMakeLists.txt
Normal file
14
backends/libyahoo2/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB_RECURSE SRC *.c *.cpp)
|
||||
|
||||
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)
|
||||
|
159
backends/libyahoo2/httpfetch.cpp
Normal file
159
backends/libyahoo2/httpfetch.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
|
||||
#include "httpfetch.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
DEFINE_LOGGER(logger, "HTTPFetch");
|
||||
|
||||
static int url_to_host_port_path(const char *url,
|
||||
char *host, int *port, char *path, int *ssl)
|
||||
{
|
||||
char *urlcopy = NULL;
|
||||
char *slash = NULL;
|
||||
char *colon = NULL;
|
||||
|
||||
/*
|
||||
* http://hostname
|
||||
* http://hostname/
|
||||
* http://hostname/path
|
||||
* http://hostname/path:foo
|
||||
* http://hostname:port
|
||||
* http://hostname:port/
|
||||
* http://hostname:port/path
|
||||
* http://hostname:port/path:foo
|
||||
* and https:// variants of the above
|
||||
*/
|
||||
|
||||
if (strstr(url, "http://") == url) {
|
||||
urlcopy = strdup(url + 7);
|
||||
} else if (strstr(url, "https://") == url) {
|
||||
urlcopy = strdup(url + 8);
|
||||
*ssl = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
slash = strchr(urlcopy, '/');
|
||||
colon = strchr(urlcopy, ':');
|
||||
|
||||
if (!colon || (slash && slash < colon)) {
|
||||
if (*ssl)
|
||||
*port = 443;
|
||||
else
|
||||
*port = 80;
|
||||
} else {
|
||||
*colon = 0;
|
||||
*port = atoi(colon + 1);
|
||||
}
|
||||
|
||||
if (!slash) {
|
||||
strcpy(path, "/");
|
||||
} else {
|
||||
strcpy(path, slash);
|
||||
*slash = 0;
|
||||
}
|
||||
|
||||
strcpy(host, urlcopy);
|
||||
|
||||
free(urlcopy);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
HTTPFetch::HTTPFetch(Swift::BoostIOServiceThread *ioService, Swift::ConnectionFactory *factory) : m_ioService(ioService), m_factory(factory) {
|
||||
m_afterHeader = false;
|
||||
}
|
||||
|
||||
HTTPFetch::~HTTPFetch() {
|
||||
}
|
||||
|
||||
void HTTPFetch::_connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error) {
|
||||
if (error) {
|
||||
_disconnected(conn);
|
||||
}
|
||||
else {
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
int ssl = 0;
|
||||
if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl))
|
||||
return;
|
||||
|
||||
static char buff[2048];
|
||||
snprintf(buff, sizeof(buff),
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"User-Agent: Mozilla/4.5 [en] (1/1)\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"%s" "\r\n", path, host,
|
||||
"Connection: close\r\n");
|
||||
LOG4CXX_INFO(logger, "Sending " << buff << "\n");
|
||||
conn->write(Swift::createSafeByteArray(buff));
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPFetch::_disconnected(boost::shared_ptr<Swift::Connection> conn) {
|
||||
conn->onConnectFinished.disconnect_all_slots();
|
||||
conn->onDisconnected.disconnect_all_slots();
|
||||
conn->onDataRead.disconnect_all_slots();
|
||||
|
||||
if (m_buffer.size() == 0) {
|
||||
onURLFetched("");
|
||||
}
|
||||
else {
|
||||
std::string img = m_buffer.substr(m_buffer.find("\r\n\r\n") + 4);
|
||||
onURLFetched(img);
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPFetch::_read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
// std::cout << d << "\n";
|
||||
std::string img = d.substr(d.find("\r\n\r\n") + 4);
|
||||
if (d.find("Location: ") == std::string::npos) {
|
||||
m_buffer += d;
|
||||
}
|
||||
else {
|
||||
d = d.substr(d.find("Location: ") + 10);
|
||||
if (d.find("\r") == std::string::npos) {
|
||||
d = d.substr(0, d.find("\n"));
|
||||
}
|
||||
else {
|
||||
d = d.substr(0, d.find("\r"));
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Next url is '" << d << "'");
|
||||
fetchURL(d);
|
||||
conn->onConnectFinished.disconnect_all_slots();
|
||||
conn->onDisconnected.disconnect_all_slots();
|
||||
conn->onDataRead.disconnect_all_slots();
|
||||
}
|
||||
}
|
||||
|
||||
bool HTTPFetch::fetchURL(const std::string &url) {
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
char buff[1024];
|
||||
int ssl = 0;
|
||||
if (!url_to_host_port_path(url.c_str(), host, &port, path, &ssl)) {
|
||||
LOG4CXX_ERROR(logger, "Invalid URL " << url);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, "Connecting to " << host << ":" << port);
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(*m_ioService->getIOService());
|
||||
boost::asio::ip::tcp::resolver::query query(host, "");
|
||||
boost::asio::ip::address address;
|
||||
for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
|
||||
boost::asio::ip::tcp::endpoint end = *i;
|
||||
address = end.address();
|
||||
break;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Connection> conn = m_factory->createConnection();
|
||||
conn->onConnectFinished.connect(boost::bind(&HTTPFetch::_connected, this, conn, url, _1));
|
||||
conn->onDisconnected.connect(boost::bind(&HTTPFetch::_disconnected, this, conn));
|
||||
conn->onDataRead.connect(boost::bind(&HTTPFetch::_read, this, conn, _1));
|
||||
conn->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
|
||||
return true;
|
||||
}
|
43
backends/libyahoo2/httpfetch.h
Normal file
43
backends/libyahoo2/httpfetch.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
class HTTPFetch {
|
||||
public:
|
||||
HTTPFetch(Swift::BoostIOServiceThread *ioSerice, Swift::ConnectionFactory *factory);
|
||||
virtual ~HTTPFetch();
|
||||
|
||||
bool fetchURL(const std::string &url);
|
||||
|
||||
boost::signal<void (const std::string &data)> onURLFetched;
|
||||
|
||||
private:
|
||||
void _connected(boost::shared_ptr<Swift::Connection> conn, const std::string url, bool error);
|
||||
void _disconnected(boost::shared_ptr<Swift::Connection> conn);
|
||||
void _read(boost::shared_ptr<Swift::Connection> conn, boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
Swift::BoostIOServiceThread *m_ioService;
|
||||
Swift::ConnectionFactory *m_factory;
|
||||
std::string m_buffer;
|
||||
bool m_afterHeader;
|
||||
};
|
783
backends/libyahoo2/main.cpp
Normal file
783
backends/libyahoo2/main.cpp
Normal file
|
@ -0,0 +1,783 @@
|
|||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Yahoo2
|
||||
#include <yahoo2.h>
|
||||
#include <yahoo2_callbacks.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "yahoohandler.h"
|
||||
#include "yahoolocalaccount.h"
|
||||
#include "httpfetch.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
class YahooHandler;
|
||||
class YahooLocalAccount;
|
||||
|
||||
static std::string *currently_read_data;
|
||||
static YahooLocalAccount *currently_writting_account;
|
||||
|
||||
YahooHandler::YahooHandler(YahooLocalAccount *account, int conn_tag, int handler_tag, void *data, yahoo_input_condition cond) :
|
||||
handler_tag(handler_tag), conn_tag(conn_tag), data(data), cond(cond), remove_later(false), account(account) {}
|
||||
|
||||
YahooHandler::~YahooHandler() {}
|
||||
|
||||
void YahooHandler::ready(std::string *buffer) {
|
||||
if (cond == YAHOO_INPUT_WRITE) {
|
||||
YahooLocalAccount *old = currently_writting_account;
|
||||
currently_writting_account = account;
|
||||
yahoo_write_ready(account->id, (void *) conn_tag, data);
|
||||
currently_writting_account = old;
|
||||
}
|
||||
else {
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
// yahoo_read_ready calls ext_yahoo_read(...) in a loop, so we just have to choose proper buffer from which will
|
||||
// that method read. We do that by static currently_read_data pointer.
|
||||
currently_read_data = buffer;
|
||||
// libyahoo2 reads data per 1024 bytes, so if we still have some data after the first ext_yahoo_read call,
|
||||
// we have to call yahoo_read_ready again...
|
||||
do {
|
||||
yahoo_read_ready(account->id, (void *) conn_tag, data);
|
||||
} while (currently_read_data->size() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
std::string yahoo_id;
|
||||
std::string name;
|
||||
int status;
|
||||
int away;
|
||||
std::string msg;
|
||||
std::string group;
|
||||
} yahoo_account;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
char *label;
|
||||
} yahoo_idlabel;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
char *who;
|
||||
} yahoo_authorize_data;
|
||||
|
||||
DEFINE_LOGGER(logger, "Yahoo2");
|
||||
|
||||
// eventloop
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
// Plugin
|
||||
class YahooPlugin;
|
||||
YahooPlugin * np = NULL;
|
||||
|
||||
class YahooPlugin : public NetworkPlugin {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::OpenSSLContextFactory *m_sslFactory;
|
||||
Swift::TLSConnectionFactory *m_tlsFactory;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
|
||||
YahooPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
|
||||
this->config = config;
|
||||
m_factories = new Swift::BoostNetworkFactories(loop);
|
||||
m_sslFactory = new Swift::OpenSSLContextFactory();
|
||||
m_tlsFactory = new Swift::TLSConnectionFactory(m_sslFactory, m_factories->getConnectionFactory());
|
||||
m_conn = m_factories->getConnectionFactory()->createConnection();
|
||||
m_conn->onDataRead.connect(boost::bind(&YahooPlugin::_handleDataRead, this, _1));
|
||||
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting the plugin.");
|
||||
}
|
||||
|
||||
// NetworkPlugin uses this method to send the data to networkplugin server
|
||||
void sendData(const std::string &string) {
|
||||
m_conn->write(Swift::createSafeByteArray(string));
|
||||
}
|
||||
|
||||
// This method has to call handleDataRead with all received data from network plugin server
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
handleDataRead(d);
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
YahooLocalAccount *account = new YahooLocalAccount(user, legacyName, password);
|
||||
m_users[user] = account;
|
||||
m_ids[account->id] = user;
|
||||
|
||||
LOG4CXX_INFO(logger, user << ": Logging in the user as " << legacyName << " with id=" << account->id);
|
||||
account->login();
|
||||
}
|
||||
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
YahooLocalAccount *account = m_users[user];
|
||||
if (account) {
|
||||
yahoo_logoff(account->id);
|
||||
m_ids.erase(account->id);
|
||||
m_users.erase(user);
|
||||
delete account;
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "") {
|
||||
YahooLocalAccount *account = m_users[user];
|
||||
if (account) {
|
||||
LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ": " << message << ".");
|
||||
yahoo_send_im(account->id, NULL, legacyName.c_str(), message.c_str(), 0, 0);
|
||||
_yahoo_write_ready(account);
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << ".");
|
||||
handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
|
||||
void _avatar_fetched(HTTPFetch *fetch, int account_id, unsigned int id, const std::string &img) {
|
||||
handleVCard(m_ids[account_id], id, "", "", "", img);
|
||||
delete fetch;
|
||||
}
|
||||
|
||||
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
|
||||
YahooLocalAccount *account = m_users[user];
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account->urls.find(legacyName) == account->urls.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPFetch *fetch = new HTTPFetch(&m_boostIOServiceThread, m_factories->getConnectionFactory());
|
||||
fetch->onURLFetched.connect(boost::bind(&YahooPlugin::_avatar_fetched, this, fetch, account->id, id, _1));
|
||||
fetch->fetchURL(account->urls[legacyName]);
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
|
||||
}
|
||||
|
||||
YahooLocalAccount *getAccount(int id) {
|
||||
return m_users[m_ids[id]];
|
||||
}
|
||||
|
||||
void _yahoo_remove_account(YahooLocalAccount *account) {
|
||||
m_ids.erase(account->id);
|
||||
m_users.erase(account->user);
|
||||
delete account;
|
||||
}
|
||||
|
||||
void _yahoo_connect_finished(YahooLocalAccount *account, yahoo_connect_callback callback, void *data, int conn_tag, bool error) {
|
||||
currently_writting_account = account;
|
||||
if (error) {
|
||||
LOG4CXX_ERROR(logger, account->user << ": Connection error!");
|
||||
callback(NULL, 0, data);
|
||||
// np->handleDisconnected(user, 0, "Connection error.");
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, account->user << ": Connected");
|
||||
// We will have dangling pointer here, but we can't pass boost::shared_ptr here...
|
||||
callback((void *) conn_tag, 0, data);
|
||||
}
|
||||
}
|
||||
|
||||
void _yahoo_write_ready(YahooLocalAccount *account) {
|
||||
// Find all WRITE handlers and inform that they really can write.
|
||||
for (std::map<int, YahooHandler *>::iterator it = account->handlers.begin(); it != account->handlers.end(); it++) {
|
||||
if (it->second->cond == YAHOO_INPUT_WRITE && !it->second->remove_later) {
|
||||
it->second->ready();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _yahoo_data_read(YahooLocalAccount *account, int conn_tag, boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
|
||||
// Find the handler that handles READing for this conn_tag
|
||||
for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
|
||||
if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
|
||||
std::string cpy(d);
|
||||
it->second->ready(&cpy);
|
||||
|
||||
// Look like libyahoo2 needs to be informed it can write to socket after the read
|
||||
// even we have informed it before...
|
||||
_yahoo_write_ready(account);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
account->removeOldHandlers();
|
||||
}
|
||||
|
||||
void _yahoo_data_written(YahooLocalAccount *account, int conn_tag) {
|
||||
LOG4CXX_INFO(logger, "data written");
|
||||
for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
|
||||
if (it->second->cond == YAHOO_INPUT_WRITE) {
|
||||
it->second->ready();
|
||||
}
|
||||
}
|
||||
|
||||
account->removeOldHandlers();
|
||||
}
|
||||
|
||||
void _yahoo_disconnected(YahooLocalAccount *account, int conn_tag, const boost::optional<Swift::Connection::Error> &error) {
|
||||
for (std::map<int, YahooHandler *>::iterator it = account->handlers_per_conn[conn_tag].begin(); it != account->handlers_per_conn[conn_tag].end(); it++) {
|
||||
if (it->second->cond == YAHOO_INPUT_READ && !it->second->remove_later) {
|
||||
std::string cpy;
|
||||
it->second->ready(&cpy);
|
||||
_yahoo_write_ready(account);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
account->removeConn(conn_tag);
|
||||
}
|
||||
|
||||
int _yahoo_connect_async(int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl) {
|
||||
YahooLocalAccount *account = getAccount(id);
|
||||
if (!account) {
|
||||
LOG4CXX_ERROR(logger, "Unknown account id=" << id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(*m_boostIOServiceThread.getIOService());
|
||||
boost::asio::ip::tcp::resolver::query query(host, "");
|
||||
boost::asio::ip::address address;
|
||||
for(boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); i != boost::asio::ip::tcp::resolver::iterator(); ++i) {
|
||||
boost::asio::ip::tcp::endpoint end = *i;
|
||||
address = end.address();
|
||||
break;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, m_ids[id] << ": Connecting " << host << ":" << port);
|
||||
int tag = account->conn_tag++;
|
||||
if (use_ssl) {
|
||||
account->conns[tag] = m_tlsFactory->createConnection();
|
||||
}
|
||||
else {
|
||||
account->conns[tag] = m_factories->getConnectionFactory()->createConnection();
|
||||
}
|
||||
account->conns[tag]->onConnectFinished.connect(boost::bind(&YahooPlugin::_yahoo_connect_finished, this, account, callback, data, tag, _1));
|
||||
account->conns[tag]->onDisconnected.connect(boost::bind(&YahooPlugin::_yahoo_disconnected, this, account, tag, _1));
|
||||
account->conns[tag]->onDataRead.connect(boost::bind(&YahooPlugin::_yahoo_data_read, this, account, tag, _1));
|
||||
account->conns[tag]->onDataWritten.connect(boost::bind(&YahooPlugin::_yahoo_data_written, this, account, tag));
|
||||
account->conns[tag]->connect(Swift::HostAddressPort(Swift::HostAddress(address), port));
|
||||
return tag;
|
||||
}
|
||||
|
||||
private:
|
||||
Config *config;
|
||||
std::map<std::string, YahooLocalAccount *> m_users;
|
||||
std::map<int, std::string> m_ids;
|
||||
};
|
||||
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_conf_invite(int id, const char *me, const char *who, const char *room, const char *msg, YList *members) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_conf_userdecline(int id, const char *me, const char *who, const char *room, const char *msg) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_conf_userjoin(int id, const char *me, const char *who, const char *room) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_conf_userleave(int id, const char *me, const char *who, const char *room) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_conf_message(int id, const char *me, const char *who, const char *room, const char *msg, int utf8) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_cat_xml(int id, const char *xml) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_join(int id, const char *me, const char *room, const char * topic, YList *members, void *fd) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_userjoin(int id, const char *me, const char *room, struct yahoo_chat_member *who) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_userleave(int id, const char *me, const char *room, const char *who) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_message(int id, const char *me, const char *who, const char *room, const char *msg, int msgtype, int utf8) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_status_changed(int id, const char *who, int stat, const char *msg, int away, int idle, int mobile) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, account->user << ": " << who << " status changed");
|
||||
|
||||
pbnetwork::StatusType status = pbnetwork::STATUS_NONE;
|
||||
switch (stat) {
|
||||
case YAHOO_STATUS_AVAILABLE:
|
||||
status = pbnetwork::STATUS_ONLINE;
|
||||
break;
|
||||
case YAHOO_STATUS_NOTATHOME:
|
||||
case YAHOO_STATUS_NOTATDESK:
|
||||
case YAHOO_STATUS_NOTINOFFICE:
|
||||
case YAHOO_STATUS_ONPHONE:
|
||||
case YAHOO_STATUS_ONVACATION:
|
||||
case YAHOO_STATUS_OUTTOLUNCH:
|
||||
case YAHOO_STATUS_STEPPEDOUT:
|
||||
status = pbnetwork::STATUS_AWAY;
|
||||
break;
|
||||
case YAHOO_STATUS_BRB:
|
||||
status = pbnetwork::STATUS_XA;
|
||||
break;
|
||||
case YAHOO_STATUS_BUSY:
|
||||
status = pbnetwork::STATUS_DND;
|
||||
break;
|
||||
case YAHOO_STATUS_OFFLINE:
|
||||
status = pbnetwork::STATUS_NONE;
|
||||
break;
|
||||
default:
|
||||
status = pbnetwork::STATUS_ONLINE;
|
||||
break;
|
||||
}
|
||||
|
||||
yahoo_buddyicon_request(id, who);
|
||||
np->_yahoo_write_ready(account);
|
||||
|
||||
np->handleBuddyChanged(account->user, who, "", std::vector<std::string>(), status, msg ? msg : "");
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddies(int id, YList * buds) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, account->user << ": Got buddy list");
|
||||
for(; buds; buds = buds->next) {
|
||||
struct yahoo_buddy *bud = (struct yahoo_buddy *) buds->data;
|
||||
|
||||
std::vector<std::string> groups;
|
||||
groups.push_back(bud->group);
|
||||
np->handleBuddyChanged(account->user, bud->id, bud->real_name ? bud->real_name : "", groups, pbnetwork::STATUS_NONE);
|
||||
}
|
||||
|
||||
// yahoo_set_away(id, YAHOO_STATUS_AVAILABLE, "", 1);
|
||||
np->_yahoo_write_ready(account);
|
||||
np->handleConnected(account->user);
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_ignore(int id, YList * igns)
|
||||
{
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buzz(int id, const char *me, const char *who, long tm) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_im(int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
np->handleMessage(account->user, who, msg);
|
||||
}
|
||||
|
||||
static void ext_yahoo_rejected(int id, const char *who, const char *msg) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_contact_added(int id, const char *myid, const char *who, const char *msg) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_typing_notify(int id, const char* me, const char *who, int stat) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_game_notify(int id, const char *me, const char *who, int stat, const char *msg)
|
||||
{
|
||||
}
|
||||
|
||||
static void ext_yahoo_mail_notify(int id, const char *from, const char *subj, int cnt) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_webcam_image(int id, const char *who, const unsigned char *image, unsigned int image_size, unsigned int real_size, unsigned int timestamp) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_webcam_viewer(int id, const char *who, int connect) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_webcam_closed(int id, const char *who, int reason) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_webcam_data_request(int id, int send) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_webcam_invite(int id, const char *me, const char *from) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_webcam_invite_reply(int id, const char *me, const char *from, int accept) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_system_message(int id, const char *me, const char *who, const char *msg) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_cookies(int id) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_login_response(int id, int succ, const char *url) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (succ == YAHOO_LOGIN_OK) {
|
||||
account->status = yahoo_current_status(id);
|
||||
// We will fire handleConnected in Got Buddy List.
|
||||
return;
|
||||
}
|
||||
else if (succ == YAHOO_LOGIN_UNAME) {
|
||||
np->handleDisconnected(account->user, 0, "Could not log into Yahoo service - username not recognised. Please verify that your username is correctly typed.");
|
||||
}
|
||||
else if (succ == YAHOO_LOGIN_PASSWD) {
|
||||
np->handleDisconnected(account->user, 0, "Could not log into Yahoo service - password incorrect. Please verify that your password is correctly typed.");
|
||||
}
|
||||
else if (succ == YAHOO_LOGIN_LOCK) {
|
||||
np->handleDisconnected(account->user, 0, std::string("Could not log into Yahoo service. Your account has been locked. Visit ") + url + " to reactivate it.");
|
||||
}
|
||||
else if (succ == YAHOO_LOGIN_DUPL) {
|
||||
np->handleDisconnected(account->user, 0, "You have been logged out of the yahoo service, possibly due to a duplicate login.");
|
||||
}
|
||||
else if (succ == YAHOO_LOGIN_SOCK) {
|
||||
np->handleDisconnected(account->user, 0, "The server closed the socket.");
|
||||
}
|
||||
else {
|
||||
np->handleDisconnected(account->user, 0, "Could not log in, unknown reason.");
|
||||
}
|
||||
|
||||
np->handleLogoutRequest(account->user, "");
|
||||
}
|
||||
|
||||
static void ext_yahoo_error(int id, const char *_err, int fatal, int num) {
|
||||
std::string err(_err);
|
||||
std::string msg("Yahoo Error: ");
|
||||
msg += err + " - ";
|
||||
switch(num) {
|
||||
case E_UNKNOWN:
|
||||
msg += "unknown error " + err;
|
||||
break;
|
||||
case E_CUSTOM:
|
||||
msg += "custom error " + err;
|
||||
break;
|
||||
case E_CONFNOTAVAIL:
|
||||
msg += err + " is not available for the conference";
|
||||
break;
|
||||
case E_IGNOREDUP:
|
||||
msg += err + " is already ignored";
|
||||
break;
|
||||
case E_IGNORENONE:
|
||||
msg += err +" is not in the ignore list";
|
||||
break;
|
||||
case E_IGNORECONF:
|
||||
msg += err + " is in buddy list - cannot ignore ";
|
||||
break;
|
||||
case E_SYSTEM:
|
||||
msg += "system error " + err;
|
||||
break;
|
||||
case E_CONNECTION:
|
||||
msg += err + "server connection error %s";
|
||||
break;
|
||||
}
|
||||
LOG4CXX_ERROR(logger, msg);
|
||||
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(fatal) {
|
||||
np->handleDisconnected(account->user, 0, msg);
|
||||
np->handleLogoutRequest(account->user, "");
|
||||
}
|
||||
}
|
||||
|
||||
static int ext_yahoo_connect(const char *host, int port) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ext_yahoo_add_handler(int id, void *fd, yahoo_input_condition cond, void *data) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int conn_tag = (unsigned long) fd;
|
||||
YahooHandler *handler = new YahooHandler(account, conn_tag, account->handler_tag++, data, cond);
|
||||
account->addHandler(handler);
|
||||
|
||||
// We are ready to write right now, so why not...
|
||||
handler->ready();
|
||||
|
||||
return handler->handler_tag;
|
||||
}
|
||||
|
||||
static void ext_yahoo_remove_handler(int id, int tag) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account->handlers.find(tag) == account->handlers.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
YahooHandler *handler = account->handlers[tag];
|
||||
handler->remove_later = true;
|
||||
}
|
||||
|
||||
static int ext_yahoo_write(void *fd, char *buf, int len) {
|
||||
int conn_tag = (unsigned long) fd;
|
||||
YahooLocalAccount *account = currently_writting_account;
|
||||
|
||||
std::string string(buf, len);
|
||||
account->conns[conn_tag]->write(Swift::createSafeByteArray(string));
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int ext_yahoo_read(void *fd, char *buf, int len) {
|
||||
if (currently_read_data->size() < len) {
|
||||
len = currently_read_data->size();
|
||||
}
|
||||
memcpy(buf, currently_read_data->c_str(), len);
|
||||
currently_read_data->erase(0, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static void ext_yahoo_close(void *fd) {
|
||||
// No need to do anything here. We close it properly in _yahoo_disconnected(...);
|
||||
}
|
||||
|
||||
static int ext_yahoo_connect_async(int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl) {
|
||||
return np->_yahoo_connect_async(id, host, port, callback, data, use_ssl);
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_file(int id, const char *me, const char *who, const char *msg, const char *fname, unsigned long fesize, char *trid) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_file_transfer_done(int id, int response, void *data) {
|
||||
}
|
||||
|
||||
static char *ext_yahoo_get_ip_addr(const char *domain) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_ft_data(int id, const unsigned char *in, int count, void *data) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_identities(int id, YList * ids) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_yahoologout(int id, const char *me) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_chat_yahooerror(int id, const char *me) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_ping(int id, const char *errormsg){
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_search_result(int id, int found, int start, int total, YList *contacts) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon_checksum(int id, const char *a, const char *b, int checksum) {
|
||||
LOG4CXX_INFO(logger, "got buddyicon_checksum");
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddy_change_group(int id, const char *me, const char *who, const char *old_group, const char *new_group) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon(int id, const char *me, const char *who, const char *url, int checksum) {
|
||||
YahooLocalAccount *account = np->getAccount(id);
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, account->user << ": got buddyicon of " << who);
|
||||
account->urls[who] = url;
|
||||
}
|
||||
|
||||
static void ext_yahoo_buddyicon_uploaded(int id, const char *url) {
|
||||
}
|
||||
|
||||
static void ext_yahoo_got_buddyicon_request(int id, const char *me, const char *who) {
|
||||
LOG4CXX_INFO(logger, "got buddyicon_request");
|
||||
}
|
||||
|
||||
static int ext_yahoo_log(const char *fmt,...)
|
||||
{
|
||||
static char log[8192];
|
||||
static std::string buffered;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
vsnprintf(log, 8191, fmt, ap);
|
||||
buffered += log;
|
||||
if (buffered.find('\n') != std::string::npos) {
|
||||
buffered.erase(buffered.find('\n'), 1);
|
||||
LOG4CXX_INFO(logger, buffered);
|
||||
buffered.clear();
|
||||
}
|
||||
fflush(stderr);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void register_callbacks()
|
||||
{
|
||||
static struct yahoo_callbacks yc;
|
||||
|
||||
yc.ext_yahoo_login_response = ext_yahoo_login_response;
|
||||
yc.ext_yahoo_got_buddies = ext_yahoo_got_buddies;
|
||||
yc.ext_yahoo_got_ignore = ext_yahoo_got_ignore;
|
||||
yc.ext_yahoo_got_identities = ext_yahoo_got_identities;
|
||||
yc.ext_yahoo_got_cookies = ext_yahoo_got_cookies;
|
||||
yc.ext_yahoo_status_changed = ext_yahoo_status_changed;
|
||||
yc.ext_yahoo_got_im = ext_yahoo_got_im;
|
||||
yc.ext_yahoo_got_buzz = ext_yahoo_got_buzz;
|
||||
yc.ext_yahoo_got_conf_invite = ext_yahoo_got_conf_invite;
|
||||
yc.ext_yahoo_conf_userdecline = ext_yahoo_conf_userdecline;
|
||||
yc.ext_yahoo_conf_userjoin = ext_yahoo_conf_userjoin;
|
||||
yc.ext_yahoo_conf_userleave = ext_yahoo_conf_userleave;
|
||||
yc.ext_yahoo_conf_message = ext_yahoo_conf_message;
|
||||
yc.ext_yahoo_chat_cat_xml = ext_yahoo_chat_cat_xml;
|
||||
yc.ext_yahoo_chat_join = ext_yahoo_chat_join;
|
||||
yc.ext_yahoo_chat_userjoin = ext_yahoo_chat_userjoin;
|
||||
yc.ext_yahoo_chat_userleave = ext_yahoo_chat_userleave;
|
||||
yc.ext_yahoo_chat_message = ext_yahoo_chat_message;
|
||||
yc.ext_yahoo_chat_yahoologout = ext_yahoo_chat_yahoologout;
|
||||
yc.ext_yahoo_chat_yahooerror = ext_yahoo_chat_yahooerror;
|
||||
yc.ext_yahoo_got_webcam_image = ext_yahoo_got_webcam_image;
|
||||
yc.ext_yahoo_webcam_invite = ext_yahoo_webcam_invite;
|
||||
yc.ext_yahoo_webcam_invite_reply = ext_yahoo_webcam_invite_reply;
|
||||
yc.ext_yahoo_webcam_closed = ext_yahoo_webcam_closed;
|
||||
yc.ext_yahoo_webcam_viewer = ext_yahoo_webcam_viewer;
|
||||
yc.ext_yahoo_webcam_data_request = ext_yahoo_webcam_data_request;
|
||||
yc.ext_yahoo_got_file = ext_yahoo_got_file;
|
||||
yc.ext_yahoo_got_ft_data = ext_yahoo_got_ft_data;
|
||||
yc.ext_yahoo_get_ip_addr = ext_yahoo_get_ip_addr;
|
||||
yc.ext_yahoo_file_transfer_done = ext_yahoo_file_transfer_done;
|
||||
yc.ext_yahoo_contact_added = ext_yahoo_contact_added;
|
||||
yc.ext_yahoo_rejected = ext_yahoo_rejected;
|
||||
yc.ext_yahoo_typing_notify = ext_yahoo_typing_notify;
|
||||
yc.ext_yahoo_game_notify = ext_yahoo_game_notify;
|
||||
yc.ext_yahoo_mail_notify = ext_yahoo_mail_notify;
|
||||
yc.ext_yahoo_got_search_result = ext_yahoo_got_search_result;
|
||||
yc.ext_yahoo_system_message = ext_yahoo_system_message;
|
||||
yc.ext_yahoo_error = ext_yahoo_error;
|
||||
yc.ext_yahoo_log = ext_yahoo_log;
|
||||
yc.ext_yahoo_add_handler = ext_yahoo_add_handler;
|
||||
yc.ext_yahoo_remove_handler = ext_yahoo_remove_handler;
|
||||
yc.ext_yahoo_connect = ext_yahoo_connect;
|
||||
yc.ext_yahoo_connect_async = ext_yahoo_connect_async;
|
||||
yc.ext_yahoo_read = ext_yahoo_read;
|
||||
yc.ext_yahoo_write = ext_yahoo_write;
|
||||
yc.ext_yahoo_close = ext_yahoo_close;
|
||||
yc.ext_yahoo_got_buddyicon = ext_yahoo_got_buddyicon;
|
||||
yc.ext_yahoo_got_buddyicon_checksum = ext_yahoo_got_buddyicon_checksum;
|
||||
yc.ext_yahoo_buddyicon_uploaded = ext_yahoo_buddyicon_uploaded;
|
||||
yc.ext_yahoo_got_buddyicon_request = ext_yahoo_got_buddyicon_request;
|
||||
yc.ext_yahoo_got_ping = ext_yahoo_got_ping;
|
||||
yc.ext_yahoo_got_buddy_change_group = ext_yahoo_got_buddy_change_group;
|
||||
|
||||
yahoo_register_callbacks(&yc);
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
std::cout << "SIGCHLD handler can't be set\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
|
||||
desc.add_options()
|
||||
("host,h", value<std::string>(&host), "host")
|
||||
("port,p", value<int>(&port), "port")
|
||||
;
|
||||
try
|
||||
{
|
||||
boost::program_options::variables_map vm;
|
||||
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
|
||||
boost::program_options::notify(vm);
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (argc < 5) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Config config;
|
||||
if (!config.load(argv[5])) {
|
||||
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
register_callbacks();
|
||||
yahoo_set_log_level(YAHOO_LOG_DEBUG);
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
loop_ = &eventLoop;
|
||||
np = new YahooPlugin(&config, &eventLoop, host, port);
|
||||
loop_->run();
|
||||
|
||||
return 0;
|
||||
}
|
1898
backends/libyahoo2/sample_client.example
Normal file
1898
backends/libyahoo2/sample_client.example
Normal file
File diff suppressed because it is too large
Load diff
208
backends/libyahoo2/yahoo/crypt.c
Normal file
208
backends/libyahoo2/yahoo/crypt.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* One way encryption based on MD5 sum.
|
||||
Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* warmenhoven took this file and made it work with the md5.[ch] we
|
||||
* already had. isn't that lovely. people should just use linux or
|
||||
* freebsd, crypt works properly on those systems. i hate solaris */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#elif HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "yahoo_util.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/* Define our magic string to mark salt for MD5 "encryption"
|
||||
replacement. This is meant to be the same as for other MD5 based
|
||||
encryption implementations. */
|
||||
static const char md5_salt_prefix[] = "$1$";
|
||||
|
||||
/* Table with characters for base64 transformation. */
|
||||
static const char b64t[64] =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
char *yahoo_crypt(char *key, char *salt)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
int buflen = 0;
|
||||
int needed = 3 + strlen(salt) + 1 + 26 + 1;
|
||||
|
||||
md5_byte_t alt_result[16];
|
||||
md5_state_t ctx;
|
||||
md5_state_t alt_ctx;
|
||||
size_t salt_len;
|
||||
size_t key_len;
|
||||
size_t cnt;
|
||||
char *cp;
|
||||
|
||||
if (buflen < needed) {
|
||||
buflen = needed;
|
||||
if ((buffer = realloc(buffer, buflen)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find beginning of salt string. The prefix should normally always
|
||||
be present. Just in case it is not. */
|
||||
if (strncmp(md5_salt_prefix, salt, sizeof(md5_salt_prefix) - 1) == 0)
|
||||
/* Skip salt prefix. */
|
||||
salt += sizeof(md5_salt_prefix) - 1;
|
||||
|
||||
salt_len = MIN(strcspn(salt, "$"), 8);
|
||||
key_len = strlen(key);
|
||||
|
||||
/* Prepare for the real work. */
|
||||
md5_init(&ctx);
|
||||
|
||||
/* Add the key string. */
|
||||
md5_append(&ctx, (md5_byte_t *)key, key_len);
|
||||
|
||||
/* Because the SALT argument need not always have the salt prefix we
|
||||
add it separately. */
|
||||
md5_append(&ctx, (md5_byte_t *)md5_salt_prefix,
|
||||
sizeof(md5_salt_prefix) - 1);
|
||||
|
||||
/* The last part is the salt string. This must be at most 8
|
||||
characters and it ends at the first `$' character (for
|
||||
compatibility which existing solutions). */
|
||||
md5_append(&ctx, (md5_byte_t *)salt, salt_len);
|
||||
|
||||
/* Compute alternate MD5 sum with input KEY, SALT, and KEY. The
|
||||
final result will be added to the first context. */
|
||||
md5_init(&alt_ctx);
|
||||
|
||||
/* Add key. */
|
||||
md5_append(&alt_ctx, (md5_byte_t *)key, key_len);
|
||||
|
||||
/* Add salt. */
|
||||
md5_append(&alt_ctx, (md5_byte_t *)salt, salt_len);
|
||||
|
||||
/* Add key again. */
|
||||
md5_append(&alt_ctx, (md5_byte_t *)key, key_len);
|
||||
|
||||
/* Now get result of this (16 bytes) and add it to the other
|
||||
context. */
|
||||
md5_finish(&alt_ctx, alt_result);
|
||||
|
||||
/* Add for any character in the key one byte of the alternate sum. */
|
||||
for (cnt = key_len; cnt > 16; cnt -= 16)
|
||||
md5_append(&ctx, alt_result, 16);
|
||||
md5_append(&ctx, alt_result, cnt);
|
||||
|
||||
/* For the following code we need a NUL byte. */
|
||||
alt_result[0] = '\0';
|
||||
|
||||
/* The original implementation now does something weird: for every 1
|
||||
bit in the key the first 0 is added to the buffer, for every 0
|
||||
bit the first character of the key. This does not seem to be
|
||||
what was intended but we have to follow this to be compatible. */
|
||||
for (cnt = key_len; cnt > 0; cnt >>= 1)
|
||||
md5_append(&ctx,
|
||||
(cnt & 1) != 0 ? alt_result : (md5_byte_t *)key, 1);
|
||||
|
||||
/* Create intermediate result. */
|
||||
md5_finish(&ctx, alt_result);
|
||||
|
||||
/* Now comes another weirdness. In fear of password crackers here
|
||||
comes a quite long loop which just processes the output of the
|
||||
previous round again. We cannot ignore this here. */
|
||||
for (cnt = 0; cnt < 1000; ++cnt) {
|
||||
/* New context. */
|
||||
md5_init(&ctx);
|
||||
|
||||
/* Add key or last result. */
|
||||
if ((cnt & 1) != 0)
|
||||
md5_append(&ctx, (md5_byte_t *)key, key_len);
|
||||
else
|
||||
md5_append(&ctx, alt_result, 16);
|
||||
|
||||
/* Add salt for numbers not divisible by 3. */
|
||||
if (cnt % 3 != 0)
|
||||
md5_append(&ctx, (md5_byte_t *)salt, salt_len);
|
||||
|
||||
/* Add key for numbers not divisible by 7. */
|
||||
if (cnt % 7 != 0)
|
||||
md5_append(&ctx, (md5_byte_t *)key, key_len);
|
||||
|
||||
/* Add key or last result. */
|
||||
if ((cnt & 1) != 0)
|
||||
md5_append(&ctx, alt_result, 16);
|
||||
else
|
||||
md5_append(&ctx, (md5_byte_t *)key, key_len);
|
||||
|
||||
/* Create intermediate result. */
|
||||
md5_finish(&ctx, alt_result);
|
||||
}
|
||||
|
||||
/* Now we can construct the result string. It consists of three
|
||||
parts. */
|
||||
|
||||
strncpy(buffer, md5_salt_prefix, MAX(0, buflen));
|
||||
cp = buffer + strlen(buffer);
|
||||
buflen -= sizeof(md5_salt_prefix);
|
||||
|
||||
strncpy(cp, salt, MIN((size_t) buflen, salt_len));
|
||||
cp = cp + strlen(cp);
|
||||
buflen -= MIN((size_t) buflen, salt_len);
|
||||
|
||||
if (buflen > 0) {
|
||||
*cp++ = '$';
|
||||
--buflen;
|
||||
}
|
||||
#define b64_from_24bit(B2, B1, B0, N) \
|
||||
do { \
|
||||
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
|
||||
int n = (N); \
|
||||
while (n-- > 0 && buflen > 0) { \
|
||||
*cp++ = b64t[w & 0x3f]; \
|
||||
--buflen; \
|
||||
w >>= 6; \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
b64_from_24bit(alt_result[0], alt_result[6], alt_result[12], 4);
|
||||
b64_from_24bit(alt_result[1], alt_result[7], alt_result[13], 4);
|
||||
b64_from_24bit(alt_result[2], alt_result[8], alt_result[14], 4);
|
||||
b64_from_24bit(alt_result[3], alt_result[9], alt_result[15], 4);
|
||||
b64_from_24bit(alt_result[4], alt_result[10], alt_result[5], 4);
|
||||
b64_from_24bit(0, 0, alt_result[11], 2);
|
||||
if (buflen <= 0) {
|
||||
FREE(buffer);
|
||||
} else
|
||||
*cp = '\0'; /* Terminate the string. */
|
||||
|
||||
/* Clear the buffer for the intermediate result so that people
|
||||
attaching to processes or reading core dumps cannot get any
|
||||
information. We do it in this way to clear correct_words[]
|
||||
inside the MD5 implementation as well. */
|
||||
md5_init(&ctx);
|
||||
md5_finish(&ctx, alt_result);
|
||||
memset(&ctx, '\0', sizeof(ctx));
|
||||
memset(&alt_ctx, '\0', sizeof(alt_ctx));
|
||||
|
||||
return buffer;
|
||||
}
|
5520
backends/libyahoo2/yahoo/libyahoo2.c
Normal file
5520
backends/libyahoo2/yahoo/libyahoo2.c
Normal file
File diff suppressed because it is too large
Load diff
405
backends/libyahoo2/yahoo/md5.c
Normal file
405
backends/libyahoo2/yahoo/md5.c
Normal file
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321.
|
||||
It is derived directly from the text of the RFC and not from the
|
||||
reference implementation.
|
||||
|
||||
The original and principal author of md5.c is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <string.h>
|
||||
#else
|
||||
# if !HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr(), *strrchr();
|
||||
# if !HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# define memmove(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
/*
|
||||
* Compile with -DTEST to create a self-contained executable test program.
|
||||
* The test program should print out the same values as given in section
|
||||
* A.5 of RFC 1321, reproduced below.
|
||||
*/
|
||||
main()
|
||||
{
|
||||
static const char *const test[7] = {
|
||||
"", /*d41d8cd98f00b204e9800998ecf8427e */
|
||||
"945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661 */
|
||||
"abc", /*900150983cd24fb0d6963f7d28e17f72 */
|
||||
"message digest", /*f96b697d7cb7938d525a2f31aaf161d0 */
|
||||
"abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b */
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
/*d174ab98d277d9f5a5611c2c9f419d9f */
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a */
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 7; ++i) {
|
||||
md5_state_t state;
|
||||
md5_byte_t digest[16];
|
||||
int di;
|
||||
|
||||
md5_init(&state);
|
||||
md5_append(&state, (const md5_byte_t *)test[i],
|
||||
strlen(test[i]));
|
||||
md5_finish(&state, digest);
|
||||
printf("MD5 (\"%s\") = ", test[i]);
|
||||
for (di = 0; di < 16; ++di)
|
||||
printf("%02x", digest[di]);
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST */
|
||||
|
||||
/*
|
||||
* For reference, here is the program that computed the T values.
|
||||
*/
|
||||
#if 0
|
||||
#include <math.h>
|
||||
main()
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i <= 64; ++i) {
|
||||
unsigned long v =
|
||||
(unsigned long)(4294967296.0 * fabs(sin((double)i)));
|
||||
printf("#define T%d 0x%08lx\n", i, v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* End of T computation program.
|
||||
*/
|
||||
#define T1 0xd76aa478
|
||||
#define T2 0xe8c7b756
|
||||
#define T3 0x242070db
|
||||
#define T4 0xc1bdceee
|
||||
#define T5 0xf57c0faf
|
||||
#define T6 0x4787c62a
|
||||
#define T7 0xa8304613
|
||||
#define T8 0xfd469501
|
||||
#define T9 0x698098d8
|
||||
#define T10 0x8b44f7af
|
||||
#define T11 0xffff5bb1
|
||||
#define T12 0x895cd7be
|
||||
#define T13 0x6b901122
|
||||
#define T14 0xfd987193
|
||||
#define T15 0xa679438e
|
||||
#define T16 0x49b40821
|
||||
#define T17 0xf61e2562
|
||||
#define T18 0xc040b340
|
||||
#define T19 0x265e5a51
|
||||
#define T20 0xe9b6c7aa
|
||||
#define T21 0xd62f105d
|
||||
#define T22 0x02441453
|
||||
#define T23 0xd8a1e681
|
||||
#define T24 0xe7d3fbc8
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 0xc33707d6
|
||||
#define T27 0xf4d50d87
|
||||
#define T28 0x455a14ed
|
||||
#define T29 0xa9e3e905
|
||||
#define T30 0xfcefa3f8
|
||||
#define T31 0x676f02d9
|
||||
#define T32 0x8d2a4c8a
|
||||
#define T33 0xfffa3942
|
||||
#define T34 0x8771f681
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 0xfde5380c
|
||||
#define T37 0xa4beea44
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 0xf6bb4b60
|
||||
#define T40 0xbebfbc70
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 0xeaa127fa
|
||||
#define T43 0xd4ef3085
|
||||
#define T44 0x04881d05
|
||||
#define T45 0xd9d4d039
|
||||
#define T46 0xe6db99e5
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 0xc4ac5665
|
||||
#define T49 0xf4292244
|
||||
#define T50 0x432aff97
|
||||
#define T51 0xab9423a7
|
||||
#define T52 0xfc93a039
|
||||
#define T53 0x655b59c3
|
||||
#define T54 0x8f0ccc92
|
||||
#define T55 0xffeff47d
|
||||
#define T56 0x85845dd1
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 0xfe2ce6e0
|
||||
#define T59 0xa3014314
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 0xf7537e82
|
||||
#define T62 0xbd3af235
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 0xeb86d391
|
||||
|
||||
static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64] */ )
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
|
||||
#ifndef ARCH_IS_BIG_ENDIAN
|
||||
# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */
|
||||
#endif
|
||||
#if ARCH_IS_BIG_ENDIAN
|
||||
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the right
|
||||
* order. (This also works on machines of unknown byte order.)
|
||||
*/
|
||||
md5_word_t X[16];
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
|
||||
#else /* !ARCH_IS_BIG_ENDIAN */
|
||||
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned data
|
||||
* without copying it.
|
||||
*/
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t *X;
|
||||
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + F(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + G(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + H(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + I(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
void md5_init(md5_state_t *pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = 0xefcdab89;
|
||||
pms->abcd[2] = 0x98badcfe;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
|
||||
{
|
||||
const md5_byte_t *p = data;
|
||||
int left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t) (nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t) (pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
92
backends/libyahoo2/yahoo/md5.h
Normal file
92
backends/libyahoo2/yahoo/md5.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321.
|
||||
It is derived directly from the text of the RFC and not from the
|
||||
reference implementation.
|
||||
|
||||
The original and principal author of md5.h is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#ifndef md5_INCLUDED
|
||||
# define md5_INCLUDED
|
||||
|
||||
/*
|
||||
* This code has some adaptations for the Ghostscript environment, but it
|
||||
* will compile and run correctly in any environment with 8-bit chars and
|
||||
* 32-bit ints. Specifically, it assumes that if the following are
|
||||
* defined, they have the same meaning as in Ghostscript: P1, P2, P3,
|
||||
* ARCH_IS_BIG_ENDIAN.
|
||||
*/
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
#ifdef P1
|
||||
void md5_init(P1(md5_state_t *pms));
|
||||
#else
|
||||
void md5_init(md5_state_t *pms);
|
||||
#endif
|
||||
|
||||
/* Append a string to the message. */
|
||||
#ifdef P3
|
||||
void md5_append(P3(md5_state_t *pms, const md5_byte_t *data,
|
||||
int nbytes));
|
||||
#else
|
||||
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
|
||||
#endif
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
#ifdef P2
|
||||
void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
|
||||
#else
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
#endif /* md5_INCLUDED */
|
613
backends/libyahoo2/yahoo/sha1.c
Normal file
613
backends/libyahoo2/yahoo/sha1.c
Normal file
|
@ -0,0 +1,613 @@
|
|||
/*-
|
||||
* Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
|
||||
*
|
||||
* Define SHA1_TEST to test the implementation using the NIST's
|
||||
* sample messages. The output should be:
|
||||
*
|
||||
* a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
|
||||
* 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
|
||||
* 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#else
|
||||
# if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
|
||||
|
||||
#define F_0_19(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define F_20_39(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define F_40_59(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
|
||||
#define F_60_79(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
#define DO_ROUND(F, K) { \
|
||||
temp = ROTL(a, 5) + F(b, c, d) + e + *(W++) + K; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = ROTL(b, 30); \
|
||||
b = a; \
|
||||
a = temp; \
|
||||
}
|
||||
|
||||
#define K_0_19 0x5a827999L
|
||||
#define K_20_39 0x6ed9eba1L
|
||||
#define K_40_59 0x8f1bbcdcL
|
||||
#define K_60_79 0xca62c1d6L
|
||||
|
||||
#ifndef RUNTIME_ENDIAN
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define BYTESWAP(x) (x)
|
||||
#define BYTESWAP64(x) (x)
|
||||
|
||||
#else /* WORDS_BIGENDIAN */
|
||||
|
||||
#define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | (ROTL((x), 8) & 0x00ff00ffL))
|
||||
|
||||
static uint64_t _byteswap64(uint64_t x)
|
||||
{
|
||||
uint32_t a = x >> 32;
|
||||
uint32_t b = (uint32_t) x;
|
||||
return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
|
||||
}
|
||||
|
||||
#define BYTESWAP64(x) _byteswap64(x)
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
#else /* !RUNTIME_ENDIAN */
|
||||
|
||||
#define BYTESWAP(x) _byteswap(sc->littleEndian, x)
|
||||
#define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
|
||||
|
||||
#define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
|
||||
(ROTL((x), 8) & 0x00ff00ffL))
|
||||
#define _BYTESWAP64(x) __byteswap64(x)
|
||||
|
||||
static uint64_t __byteswap64(uint64_t x)
|
||||
{
|
||||
uint32_t a = x >> 32;
|
||||
uint32_t b = (uint32_t) x;
|
||||
return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
|
||||
}
|
||||
|
||||
static uint32_t _byteswap(int littleEndian, uint32_t x)
|
||||
{
|
||||
if (!littleEndian)
|
||||
return x;
|
||||
else
|
||||
return _BYTESWAP(x);
|
||||
}
|
||||
|
||||
static uint64_t _byteswap64(int littleEndian, uint64_t x)
|
||||
{
|
||||
if (!littleEndian)
|
||||
return x;
|
||||
else
|
||||
return _BYTESWAP64(x);
|
||||
}
|
||||
|
||||
static void setEndian(int *littleEndianp)
|
||||
{
|
||||
union {
|
||||
uint32_t w;
|
||||
uint8_t b[4];
|
||||
} endian;
|
||||
|
||||
endian.w = 1L;
|
||||
*littleEndianp = endian.b[0] != 0;
|
||||
}
|
||||
|
||||
#endif /* !RUNTIME_ENDIAN */
|
||||
|
||||
static const uint8_t padding[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void SHA1Init(SHA1Context *sc)
|
||||
{
|
||||
#ifdef RUNTIME_ENDIAN
|
||||
setEndian(&sc->littleEndian);
|
||||
#endif /* RUNTIME_ENDIAN */
|
||||
|
||||
sc->totalLength = 0LL;
|
||||
sc->hash[0] = 0x67452301L;
|
||||
sc->hash[1] = 0xefcdab89L;
|
||||
sc->hash[2] = 0x98badcfeL;
|
||||
sc->hash[3] = 0x10325476L;
|
||||
sc->hash[4] = 0xc3d2e1f0L;
|
||||
sc->bufferLength = 0L;
|
||||
}
|
||||
|
||||
static void burnStack(int size)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
size -= sizeof(buf);
|
||||
if (size > 0)
|
||||
burnStack(size);
|
||||
}
|
||||
|
||||
static void SHA1Guts(SHA1Context *sc, const uint32_t *cbuf)
|
||||
{
|
||||
uint32_t buf[80];
|
||||
uint32_t *W, *W3, *W8, *W14, *W16;
|
||||
uint32_t a, b, c, d, e, temp;
|
||||
int i;
|
||||
|
||||
W = buf;
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
*(W++) = BYTESWAP(*cbuf);
|
||||
cbuf++;
|
||||
}
|
||||
|
||||
W16 = &buf[0];
|
||||
W14 = &buf[2];
|
||||
W8 = &buf[8];
|
||||
W3 = &buf[13];
|
||||
|
||||
for (i = 63; i >= 0; i--) {
|
||||
*W = *(W3++) ^ *(W8++) ^ *(W14++) ^ *(W16++);
|
||||
*W = ROTL(*W, 1);
|
||||
W++;
|
||||
}
|
||||
|
||||
a = sc->hash[0];
|
||||
b = sc->hash[1];
|
||||
c = sc->hash[2];
|
||||
d = sc->hash[3];
|
||||
e = sc->hash[4];
|
||||
|
||||
W = buf;
|
||||
|
||||
#ifndef SHA1_UNROLL
|
||||
#define SHA1_UNROLL 20
|
||||
#endif /* !SHA1_UNROLL */
|
||||
|
||||
#if SHA1_UNROLL == 1
|
||||
for (i = 19; i >= 0; i--)
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
|
||||
for (i = 19; i >= 0; i--)
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
|
||||
for (i = 19; i >= 0; i--)
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
|
||||
for (i = 19; i >= 0; i--)
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
#elif SHA1_UNROLL == 2
|
||||
for (i = 9; i >= 0; i--) {
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
}
|
||||
|
||||
for (i = 9; i >= 0; i--) {
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
}
|
||||
|
||||
for (i = 9; i >= 0; i--) {
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
}
|
||||
|
||||
for (i = 9; i >= 0; i--) {
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
}
|
||||
#elif SHA1_UNROLL == 4
|
||||
for (i = 4; i >= 0; i--) {
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
}
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
}
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
}
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
}
|
||||
#elif SHA1_UNROLL == 5
|
||||
for (i = 3; i >= 0; i--) {
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
}
|
||||
|
||||
for (i = 3; i >= 0; i--) {
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
}
|
||||
|
||||
for (i = 3; i >= 0; i--) {
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
}
|
||||
|
||||
for (i = 3; i >= 0; i--) {
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
}
|
||||
#elif SHA1_UNROLL == 10
|
||||
for (i = 1; i >= 0; i--) {
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
}
|
||||
|
||||
for (i = 1; i >= 0; i--) {
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
}
|
||||
|
||||
for (i = 1; i >= 0; i--) {
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
}
|
||||
|
||||
for (i = 1; i >= 0; i--) {
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
}
|
||||
#elif SHA1_UNROLL == 20
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
DO_ROUND(F_0_19, K_0_19);
|
||||
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
DO_ROUND(F_20_39, K_20_39);
|
||||
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
DO_ROUND(F_40_59, K_40_59);
|
||||
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
DO_ROUND(F_60_79, K_60_79);
|
||||
#else /* SHA1_UNROLL */
|
||||
#error SHA1_UNROLL must be 1, 2, 4, 5, 10 or 20!
|
||||
#endif
|
||||
|
||||
sc->hash[0] += a;
|
||||
sc->hash[1] += b;
|
||||
sc->hash[2] += c;
|
||||
sc->hash[3] += d;
|
||||
sc->hash[4] += e;
|
||||
}
|
||||
|
||||
void SHA1Update(SHA1Context *sc, const void *vdata, uint32_t len)
|
||||
{
|
||||
const uint8_t *data = vdata;
|
||||
uint32_t bufferBytesLeft;
|
||||
uint32_t bytesToCopy;
|
||||
int needBurn = 0;
|
||||
|
||||
#ifdef SHA1_FAST_COPY
|
||||
if (sc->bufferLength) {
|
||||
bufferBytesLeft = 64L - sc->bufferLength;
|
||||
|
||||
bytesToCopy = bufferBytesLeft;
|
||||
if (bytesToCopy > len)
|
||||
bytesToCopy = len;
|
||||
|
||||
memcpy(&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
|
||||
|
||||
sc->totalLength += bytesToCopy * 8L;
|
||||
|
||||
sc->bufferLength += bytesToCopy;
|
||||
data += bytesToCopy;
|
||||
len -= bytesToCopy;
|
||||
|
||||
if (sc->bufferLength == 64L) {
|
||||
SHA1Guts(sc, sc->buffer.words);
|
||||
needBurn = 1;
|
||||
sc->bufferLength = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 63) {
|
||||
sc->totalLength += 512L;
|
||||
|
||||
SHA1Guts(sc, data);
|
||||
needBurn = 1;
|
||||
|
||||
data += 64L;
|
||||
len -= 64L;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(&sc->buffer.bytes[sc->bufferLength], data, len);
|
||||
|
||||
sc->totalLength += len * 8L;
|
||||
|
||||
sc->bufferLength += len;
|
||||
}
|
||||
#else /* SHA1_FAST_COPY */
|
||||
while (len) {
|
||||
bufferBytesLeft = 64L - sc->bufferLength;
|
||||
|
||||
bytesToCopy = bufferBytesLeft;
|
||||
if (bytesToCopy > len)
|
||||
bytesToCopy = len;
|
||||
|
||||
memcpy(&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
|
||||
|
||||
sc->totalLength += bytesToCopy * 8L;
|
||||
|
||||
sc->bufferLength += bytesToCopy;
|
||||
data += bytesToCopy;
|
||||
len -= bytesToCopy;
|
||||
|
||||
if (sc->bufferLength == 64L) {
|
||||
SHA1Guts(sc, sc->buffer.words);
|
||||
needBurn = 1;
|
||||
sc->bufferLength = 0L;
|
||||
}
|
||||
}
|
||||
#endif /* SHA1_FAST_COPY */
|
||||
|
||||
if (needBurn)
|
||||
burnStack(sizeof(uint32_t[86]) + sizeof(uint32_t *[5]) +
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
void SHA1Final(SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE])
|
||||
{
|
||||
uint32_t bytesToPad;
|
||||
uint64_t lengthPad;
|
||||
int i;
|
||||
|
||||
bytesToPad = 120L - sc->bufferLength;
|
||||
if (bytesToPad > 64L)
|
||||
bytesToPad -= 64L;
|
||||
|
||||
lengthPad = BYTESWAP64(sc->totalLength);
|
||||
|
||||
SHA1Update(sc, padding, bytesToPad);
|
||||
SHA1Update(sc, &lengthPad, 8L);
|
||||
|
||||
if (hash) {
|
||||
for (i = 0; i < SHA1_HASH_WORDS; i++) {
|
||||
#ifdef SHA1_FAST_COPY
|
||||
*((uint32_t *)hash) = BYTESWAP(sc->hash[i]);
|
||||
#else /* SHA1_FAST_COPY */
|
||||
hash[0] = (uint8_t) (sc->hash[i] >> 24);
|
||||
hash[1] = (uint8_t) (sc->hash[i] >> 16);
|
||||
hash[2] = (uint8_t) (sc->hash[i] >> 8);
|
||||
hash[3] = (uint8_t) sc->hash[i];
|
||||
#endif /* SHA1_FAST_COPY */
|
||||
hash += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SHA1_TEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SHA1Context foo;
|
||||
uint8_t hash[SHA1_HASH_SIZE];
|
||||
char buf[1000];
|
||||
int i;
|
||||
|
||||
SHA1Init(&foo);
|
||||
SHA1Update(&foo, "abc", 3);
|
||||
SHA1Final(&foo, hash);
|
||||
|
||||
for (i = 0; i < SHA1_HASH_SIZE;) {
|
||||
printf("%02x", hash[i++]);
|
||||
if (!(i % 4))
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
SHA1Init(&foo);
|
||||
SHA1Update(&foo,
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
|
||||
SHA1Final(&foo, hash);
|
||||
|
||||
for (i = 0; i < SHA1_HASH_SIZE;) {
|
||||
printf("%02x", hash[i++]);
|
||||
if (!(i % 4))
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
SHA1Init(&foo);
|
||||
memset(buf, 'a', sizeof(buf));
|
||||
for (i = 0; i < 1000; i++)
|
||||
SHA1Update(&foo, buf, sizeof(buf));
|
||||
SHA1Final(&foo, hash);
|
||||
|
||||
for (i = 0; i < SHA1_HASH_SIZE;) {
|
||||
printf("%02x", hash[i++]);
|
||||
if (!(i % 4))
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif /* SHA1_TEST */
|
69
backends/libyahoo2/yahoo/sha1.h
Normal file
69
backends/libyahoo2/yahoo/sha1.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-
|
||||
* Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SHA1_H
|
||||
#define _SHA1_H
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#else
|
||||
# if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define SHA1_HASH_SIZE 20
|
||||
|
||||
/* Hash size in 32-bit words */
|
||||
#define SHA1_HASH_WORDS 5
|
||||
|
||||
struct _SHA1Context {
|
||||
uint64_t totalLength;
|
||||
uint32_t hash[SHA1_HASH_WORDS];
|
||||
uint32_t bufferLength;
|
||||
union {
|
||||
uint32_t words[16];
|
||||
uint8_t bytes[64];
|
||||
} buffer;
|
||||
#ifdef RUNTIME_ENDIAN
|
||||
int littleEndian;
|
||||
#endif /* RUNTIME_ENDIAN */
|
||||
};
|
||||
|
||||
typedef struct _SHA1Context SHA1Context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void SHA1Init(SHA1Context *sc);
|
||||
void SHA1Update(SHA1Context *sc, const void *data, uint32_t len);
|
||||
void SHA1Final(SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _SHA1_H */
|
225
backends/libyahoo2/yahoo/yahoo2.h
Normal file
225
backends/libyahoo2/yahoo/yahoo2.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* libyahoo2: yahoo2.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef YAHOO2_H
|
||||
#define YAHOO2_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "yahoo2_types.h"
|
||||
|
||||
/* returns the socket descriptor object for a given pager connection. shouldn't be needed */
|
||||
void *yahoo_get_fd(int id);
|
||||
|
||||
/* says how much logging to do */
|
||||
/* see yahoo2_types.h for the different values */
|
||||
int yahoo_set_log_level(enum yahoo_log_level level);
|
||||
enum yahoo_log_level yahoo_get_log_level(void);
|
||||
|
||||
/* these functions should be self explanatory */
|
||||
/* who always means the buddy you're acting on */
|
||||
/* id is the successful value returned by yahoo_init */
|
||||
|
||||
/* init returns a connection id used to identify the connection hereon */
|
||||
/* or 0 on failure */
|
||||
/* you must call init before calling any other function */
|
||||
/*
|
||||
* The optional parameters to init are key/value pairs that specify
|
||||
* server settings to use. This list must be NULL terminated - even
|
||||
* if the list is empty. If a parameter isn't set, a default value
|
||||
* will be used. Parameter keys are strings, parameter values are
|
||||
* either strings or ints, depending on the key. Values passed in
|
||||
* are copied, so you can use const/auto/static/pointers/whatever
|
||||
* you want. Parameters are:
|
||||
* NAME TYPE DEFAULT
|
||||
* pager_host char * scs.msg.yahoo.com
|
||||
* pager_port int 5050
|
||||
* filetransfer_host char * filetransfer.msg.yahoo.com
|
||||
* filetransfer_port int 80
|
||||
* webcam_host char * webcam.yahoo.com
|
||||
* webcam_port int 5100
|
||||
* webcam_description char * ""
|
||||
* local_host char * ""
|
||||
* conn_type int Y_WCM_DSL
|
||||
*
|
||||
* You should set at least local_host if you intend to use webcams
|
||||
*/
|
||||
int yahoo_init_with_attributes(const char *username,
|
||||
const char *password, ...);
|
||||
|
||||
/* yahoo_init does the same as yahoo_init_with_attributes, assuming defaults
|
||||
* for all attributes */
|
||||
int yahoo_init(const char *username, const char *password);
|
||||
|
||||
/* release all resources held by this session */
|
||||
/* you need to call yahoo_close for a session only if
|
||||
* yahoo_logoff is never called for it (ie, it was never logged in) */
|
||||
void yahoo_close(int id);
|
||||
/* login logs in to the server */
|
||||
/* initial is of type enum yahoo_status. see yahoo2_types.h */
|
||||
void yahoo_login(int id, int initial);
|
||||
void yahoo_logoff(int id);
|
||||
/* reloads status of all buddies */
|
||||
void yahoo_refresh(int id);
|
||||
/* activates/deactivates an identity */
|
||||
void yahoo_set_identity_status(int id, const char *identity,
|
||||
int active);
|
||||
/* regets the entire buddy list from the server */
|
||||
void yahoo_get_list(int id);
|
||||
/* download buddy contact information from your yahoo addressbook */
|
||||
void yahoo_get_yab(int id);
|
||||
/* add/modify an address book entry. if yab->dbid is set, it will */
|
||||
/* modify that entry else it creates a new entry */
|
||||
void yahoo_set_yab(int id, struct yab *yab);
|
||||
void yahoo_keepalive(int id);
|
||||
void yahoo_chat_keepalive(int id);
|
||||
|
||||
/* from is the identity you're sending from. if NULL, the default is used */
|
||||
/* utf8 is whether msg is a utf8 string or not. */
|
||||
void yahoo_send_im(int id, const char *from, const char *who,
|
||||
const char *msg, int utf8, int picture);
|
||||
void yahoo_send_buzz(int id, const char *from, const char *who);
|
||||
/* if type is true, send typing notice, else send stopped typing notice */
|
||||
void yahoo_send_typing(int id, const char *from, const char *who,
|
||||
int typ);
|
||||
|
||||
/* used to set away/back status. */
|
||||
/* away says whether the custom message is an away message or a sig */
|
||||
void yahoo_set_away(int id, enum yahoo_status state, const char *msg,
|
||||
int away);
|
||||
|
||||
void yahoo_add_buddy(int id, const char *who, const char *group,
|
||||
const char *msg);
|
||||
void yahoo_remove_buddy(int id, const char *who, const char *group);
|
||||
void yahoo_confirm_buddy(int id, const char *who, int reject,
|
||||
const char *msg);
|
||||
void yahoo_stealth_buddy(int id, const char *who, int unstealth);
|
||||
/* if unignore is true, unignore, else ignore */
|
||||
void yahoo_ignore_buddy(int id, const char *who, int unignore);
|
||||
void yahoo_change_buddy_group(int id, const char *who,
|
||||
const char *old_group, const char *new_group);
|
||||
void yahoo_group_rename(int id, const char *old_group,
|
||||
const char *new_group);
|
||||
|
||||
void yahoo_conference_invite(int id, const char *from, YList *who,
|
||||
const char *room, const char *msg);
|
||||
void yahoo_conference_addinvite(int id, const char *from,
|
||||
const char *who, const char *room, const YList *members,
|
||||
const char *msg);
|
||||
void yahoo_conference_decline(int id, const char *from, YList *who,
|
||||
const char *room, const char *msg);
|
||||
void yahoo_conference_message(int id, const char *from, YList *who,
|
||||
const char *room, const char *msg, int utf8);
|
||||
void yahoo_conference_logon(int id, const char *from, YList *who,
|
||||
const char *room);
|
||||
void yahoo_conference_logoff(int id, const char *from, YList *who,
|
||||
const char *room);
|
||||
|
||||
/* Get a list of chatrooms */
|
||||
void yahoo_get_chatrooms(int id, int chatroomid);
|
||||
/* join room with specified roomname and roomid */
|
||||
void yahoo_chat_logon(int id, const char *from, const char *room,
|
||||
const char *roomid);
|
||||
/* Send message "msg" to room with specified roomname, msgtype is 1-normal message or 2-/me mesage */
|
||||
void yahoo_chat_message(int id, const char *from, const char *room,
|
||||
const char *msg, const int msgtype, const int utf8);
|
||||
/* Log off chat */
|
||||
void yahoo_chat_logoff(int id, const char *from);
|
||||
|
||||
/* requests a webcam feed */
|
||||
/* who is the person who's webcam you would like to view */
|
||||
/* if who is null, then you're the broadcaster */
|
||||
void yahoo_webcam_get_feed(int id, const char *who);
|
||||
void yahoo_webcam_close_feed(int id, const char *who);
|
||||
|
||||
/* sends an image when uploading */
|
||||
/* image points to a JPEG-2000 image, length is the length of the image */
|
||||
/* in bytes. The timestamp is the time in milliseconds since we started the */
|
||||
/* webcam. */
|
||||
void yahoo_webcam_send_image(int id, unsigned char *image,
|
||||
unsigned int length, unsigned int timestamp);
|
||||
|
||||
/* this function should be called if we want to allow a user to watch the */
|
||||
/* webcam. Who is the user we want to accept. */
|
||||
/* Accept user (accept = 1), decline user (accept = 0) */
|
||||
void yahoo_webcam_accept_viewer(int id, const char *who, int accept);
|
||||
|
||||
/* send an invitation to a user to view your webcam */
|
||||
void yahoo_webcam_invite(int id, const char *who);
|
||||
|
||||
/* will set up a connection and initiate file transfer.
|
||||
* callback will be called with the fd that you should write
|
||||
* the file data to
|
||||
*/
|
||||
void yahoo_send_file(int id, const char *who, const char *msg,
|
||||
const char *name, unsigned long size,
|
||||
yahoo_get_fd_callback callback, void *data);
|
||||
|
||||
/*
|
||||
* Respond to a file transfer request. Be sure to provide the callback data
|
||||
* since that is your only chance to recognize future callbacks
|
||||
*/
|
||||
void yahoo_send_file_transfer_response(int client_id, int response,
|
||||
char *id, void *data);
|
||||
|
||||
|
||||
/* send a search request
|
||||
*/
|
||||
void yahoo_search(int id, enum yahoo_search_type t, const char *text,
|
||||
enum yahoo_search_gender g, enum yahoo_search_agerange ar,
|
||||
int photo, int yahoo_only);
|
||||
|
||||
/* continue last search
|
||||
* should be called if only (start+found >= total)
|
||||
*
|
||||
* where the above three are passed to ext_yahoo_got_search_result
|
||||
*/
|
||||
void yahoo_search_again(int id, int start);
|
||||
|
||||
/* these should be called when input is available on a fd */
|
||||
/* registered by ext_yahoo_add_handler */
|
||||
/* if these return negative values, errno may be set */
|
||||
int yahoo_read_ready(int id, void *fd, void *data);
|
||||
int yahoo_write_ready(int id, void *fd, void *data);
|
||||
|
||||
/* utility functions. these do not hit the server */
|
||||
enum yahoo_status yahoo_current_status(int id);
|
||||
const YList *yahoo_get_buddylist(int id);
|
||||
const YList *yahoo_get_ignorelist(int id);
|
||||
const YList *yahoo_get_identities(int id);
|
||||
/* 'which' could be y, t, c or login. This may change in later versions. */
|
||||
const char *yahoo_get_cookie(int id, const char *which);
|
||||
|
||||
/* returns the url used to get user profiles - you must append the user id */
|
||||
/* as of now this is http://profiles.yahoo.com/ */
|
||||
/* You'll have to do urlencoding yourself, but see yahoo_httplib.h first */
|
||||
const char *yahoo_get_profile_url(void);
|
||||
|
||||
void yahoo_buddyicon_request(int id, const char *who);
|
||||
|
||||
#include "yahoo_httplib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
776
backends/libyahoo2/yahoo/yahoo2_callbacks.h
Normal file
776
backends/libyahoo2/yahoo/yahoo2_callbacks.h
Normal file
|
@ -0,0 +1,776 @@
|
|||
/*
|
||||
* libyahoo2: yahoo2_callbacks.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The functions in this file *must* be defined in your client program
|
||||
* If you want to use a callback structure instead of direct functions,
|
||||
* then you must define USE_STRUCT_CALLBACKS in all files that #include
|
||||
* this one.
|
||||
*
|
||||
* Register the callback structure by calling yahoo_register_callbacks -
|
||||
* declared in this file and defined in libyahoo2.c
|
||||
*/
|
||||
|
||||
#ifndef YAHOO2_CALLBACKS_H
|
||||
#define YAHOO2_CALLBACKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "yahoo2_types.h"
|
||||
|
||||
/*
|
||||
* yahoo2_callbacks.h
|
||||
*
|
||||
* Callback interface for libyahoo2
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
YAHOO_INPUT_READ = 1 << 0,
|
||||
YAHOO_INPUT_WRITE = 1 << 1,
|
||||
YAHOO_INPUT_EXCEPTION = 1 << 2
|
||||
} yahoo_input_condition;
|
||||
|
||||
/*
|
||||
* A callback function called when an asynchronous connect completes.
|
||||
*
|
||||
* Params:
|
||||
* fd - The file descriptor object that has been connected, or NULL on
|
||||
* error
|
||||
* error - The value of errno set by the call to connect or 0 if no error
|
||||
* Set both fd and error to 0 if the connect was cancelled by the
|
||||
* user
|
||||
* callback_data - the callback_data passed to the ext_yahoo_connect_async
|
||||
* function
|
||||
*/
|
||||
typedef void (*yahoo_connect_callback) (void *fd, int error,
|
||||
void *callback_data);
|
||||
|
||||
/*
|
||||
* The following functions need to be implemented in the client
|
||||
* interface. They will be called by the library when each
|
||||
* event occurs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* should we use a callback structure or directly call functions
|
||||
* if you want the structure, you *must* define USE_STRUCT_CALLBACKS
|
||||
* both when you compile the library, and when you compile your code
|
||||
* that uses the library
|
||||
*/
|
||||
|
||||
#define YAHOO_CALLBACK_TYPE(x) (*x)
|
||||
struct yahoo_callbacks {
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_login_response
|
||||
* Called when the login process is complete
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* succ - enum yahoo_login_status
|
||||
* url - url to reactivate account if locked
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_login_response) (int id, int succ,
|
||||
const char *url);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddies
|
||||
* Called when the contact list is got from the server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* buds - the buddy list
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddies) (int id, YList *buds);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_ignore
|
||||
* Called when the ignore list is got from the server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* igns - the ignore list
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_ignore) (int id, YList *igns);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_identities
|
||||
* Called when the contact list is got from the server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* ids - the identity list
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_identities) (int id, YList *ids);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_cookies
|
||||
* Called when the cookie list is got from the server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_cookies) (int id);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_ping
|
||||
* Called when the ping packet is received from the server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* errormsg - optional error message
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_ping) (int id,
|
||||
const char *errormsg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_status_changed
|
||||
* Called when remote user's status changes.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* who - the handle of the remote user
|
||||
* stat - status code (enum yahoo_status)
|
||||
* msg - the message if stat == YAHOO_STATUS_CUSTOM
|
||||
* away - whether the contact is away or not (YAHOO_STATUS_CUSTOM)
|
||||
* idle - this is the number of seconds he is idle [if he is idle]
|
||||
* mobile - this is set for mobile users/buddies
|
||||
* TODO: add support for pager, chat, and game states
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_status_changed) (int id,
|
||||
const char *who, int stat, const char *msg, int away, int idle,
|
||||
int mobile);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buzz
|
||||
* Called when remote user sends you a buzz.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity the message was sent to
|
||||
* who - the handle of the remote user
|
||||
* tm - timestamp of message if offline
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buzz) (int id, const char *me,
|
||||
const char *who, long tm);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_im
|
||||
* Called when remote user sends you a message.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity the message was sent to
|
||||
* who - the handle of the remote user
|
||||
* msg - the message - NULL if stat == 2
|
||||
* tm - timestamp of message if offline
|
||||
* stat - message status - 0
|
||||
* 1
|
||||
* 2 == error sending message
|
||||
* 5
|
||||
* utf8 - whether the message is encoded as utf8 or not
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_im) (int id, const char *me,
|
||||
const char *who, const char *msg, long tm, int stat, int utf8);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_conf_invite
|
||||
* Called when remote user sends you a conference invitation.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity the invitation was sent to
|
||||
* who - the user inviting you
|
||||
* room - the room to join
|
||||
* msg - the message
|
||||
* members - the initial members of the conference (null terminated list)
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_conf_invite) (int id,
|
||||
const char *me, const char *who, const char *room,
|
||||
const char *msg, YList *members);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_conf_userdecline
|
||||
* Called when someone declines to join the conference.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the conference
|
||||
* who - the user who has declined
|
||||
* room - the room
|
||||
* msg - the declining message
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userdecline) (int id,
|
||||
const char *me, const char *who, const char *room,
|
||||
const char *msg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_conf_userjoin
|
||||
* Called when someone joins the conference.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the conference
|
||||
* who - the user who has joined
|
||||
* room - the room joined
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userjoin) (int id,
|
||||
const char *me, const char *who, const char *room);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_conf_userleave
|
||||
* Called when someone leaves the conference.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the conference
|
||||
* who - the user who has left
|
||||
* room - the room left
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_userleave) (int id,
|
||||
const char *me, const char *who, const char *room);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_chat_cat_xml
|
||||
* Called when ?
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* xml - ?
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_cat_xml) (int id,
|
||||
const char *xml);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_chat_join
|
||||
* Called when joining the chatroom.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the chatroom
|
||||
* room - the room joined, used in all other chat calls, freed by
|
||||
* library after call
|
||||
* topic - the topic of the room, freed by library after call
|
||||
* members - the initial members of the chatroom (null terminated YList
|
||||
* of yahoo_chat_member's) Must be freed by the client
|
||||
* fd - the object where the connection is coming from (for tracking)
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_join) (int id, const char *me,
|
||||
const char *room, const char *topic, YList *members, void *fd);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_chat_userjoin
|
||||
* Called when someone joins the chatroom.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the chatroom
|
||||
* room - the room joined
|
||||
* who - the user who has joined, Must be freed by the client
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userjoin) (int id,
|
||||
const char *me, const char *room,
|
||||
struct yahoo_chat_member *who);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_chat_userleave
|
||||
* Called when someone leaves the chatroom.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the chatroom
|
||||
* room - the room left
|
||||
* who - the user who has left (Just the User ID)
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_userleave) (int id,
|
||||
const char *me, const char *room, const char *who);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_chat_message
|
||||
* Called when someone messages in the chatroom.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity in the chatroom
|
||||
* room - the room
|
||||
* who - the user who messaged (Just the user id)
|
||||
* msg - the message
|
||||
* msgtype - 1 = Normal message
|
||||
* 2 = /me type message
|
||||
* utf8 - whether the message is utf8 encoded or not
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_message) (int id,
|
||||
const char *me, const char *who, const char *room,
|
||||
const char *msg, int msgtype, int utf8);
|
||||
|
||||
/*
|
||||
*
|
||||
* Name: ext_yahoo_chat_yahoologout
|
||||
* called when yahoo disconnects your chat session
|
||||
* Note this is called whenver a disconnect happens, client or server
|
||||
* requested. Care should be taken to make sure you know the origin
|
||||
* of the disconnect request before doing anything here (auto-join's etc)
|
||||
* Params:
|
||||
* id - the id that identifies this connection
|
||||
* me - the identity in the chatroom
|
||||
* Returns:
|
||||
* nothing.
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahoologout) (int id,
|
||||
const char *me);
|
||||
|
||||
/*
|
||||
*
|
||||
* Name: ext_yahoo_chat_yahooerror
|
||||
* called when yahoo sends back an error to you
|
||||
* Note this is called whenver chat message is sent into a room
|
||||
* in error (fd not connected, room doesn't exists etc)
|
||||
* Care should be taken to make sure you know the origin
|
||||
* of the error before doing anything about it.
|
||||
* Params:
|
||||
* id - the id that identifies this connection
|
||||
* me - the identity in the chatroom
|
||||
* Returns:
|
||||
* nothing.
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_yahooerror) (int id,
|
||||
const char *me);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_conf_message
|
||||
* Called when someone messages in the conference.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity the conf message was sent to
|
||||
* who - the user who messaged
|
||||
* room - the room
|
||||
* msg - the message
|
||||
* utf8 - whether the message is utf8 encoded or not
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_message) (int id,
|
||||
const char *me, const char *who, const char *room,
|
||||
const char *msg, int utf8);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_file
|
||||
* Called when someone sends you a file
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the identity the file was sent to
|
||||
* who - the user who sent the file
|
||||
* msg - the message
|
||||
* fname- the file name if direct transfer
|
||||
* fsize- the file size if direct transfer
|
||||
* trid - transfer id. Unique for this transfer
|
||||
*
|
||||
* NOTE: Subsequent callbacks for file transfer do not send all of this
|
||||
* information again since it is wasteful. Implementations are expected to
|
||||
* save this information and supply it as callback data when the file or
|
||||
* confirmation is sent
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file) (int id, const char *me,
|
||||
const char *who, const char *msg, const char *fname,
|
||||
unsigned long fesize, char *trid);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_ft_data
|
||||
* Called multiple times when parts of the file are received
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* in - The data
|
||||
* len - Length of the data
|
||||
* data - callback data
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_ft_data) (int id,
|
||||
const unsigned char *in, int len, void *data);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_file_transfer_done
|
||||
* File transfer is done
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* result - To notify if it finished successfully or with a failure
|
||||
* data - callback data
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_file_transfer_done) (int id,
|
||||
int result, void *data);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_contact_added
|
||||
* Called when a contact is added to your list
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* myid - the identity he was added to
|
||||
* who - who was added
|
||||
* msg - any message sent
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_added) (int id,
|
||||
const char *myid, const char *who, const char *msg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_rejected
|
||||
* Called when a contact rejects your add
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* who - who rejected you
|
||||
* msg - any message sent
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_rejected) (int id, const char *who,
|
||||
const char *msg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_typing_notify
|
||||
* Called when remote user starts or stops typing.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the handle of the remote user
|
||||
* stat - 1 if typing, 0 if stopped typing
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_typing_notify) (int id,
|
||||
const char *me, const char *who, int stat);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_game_notify
|
||||
* Called when remote user starts or stops a game.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the handle of the remote user
|
||||
* stat - 1 if game, 0 if stopped gaming
|
||||
* msg - game description and/or other text
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify) (int id, const char *me,
|
||||
const char *who, int stat, const char *msg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_mail_notify
|
||||
* Called when you receive mail, or with number of messages
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* from - who the mail is from - NULL if only mail count
|
||||
* subj - the subject of the mail - NULL if only mail count
|
||||
* cnt - mail count - 0 if new mail notification
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_mail_notify) (int id,
|
||||
const char *from, const char *subj, int cnt);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_system_message
|
||||
* System message
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the source of the system message (there are different types)
|
||||
* msg - the message
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message) (int id,
|
||||
const char *me, const char *who, const char *msg);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddyicon
|
||||
* Buddy icon received
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the person the buddy icon is for
|
||||
* url - the url to use to load the icon
|
||||
* checksum - the checksum of the icon content
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon) (int id,
|
||||
const char *me, const char *who, const char *url, int checksum);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddyicon_checksum
|
||||
* Buddy icon checksum received
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the yahoo id of the buddy icon checksum is for
|
||||
* checksum - the checksum of the icon content
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon_checksum) (int id,
|
||||
const char *me, const char *who, int checksum);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddyicon_request
|
||||
* Buddy icon request received
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - the handle of the identity the notification is sent to
|
||||
* who - the yahoo id of the buddy that requested the buddy icon
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddyicon_request) (int id,
|
||||
const char *me, const char *who);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddyicon_request
|
||||
* Buddy icon request received
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* url - remote url, the uploaded buddy icon can be fetched from
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_buddyicon_uploaded) (int id,
|
||||
const char *url);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_webcam_image
|
||||
* Called when you get a webcam update
|
||||
* An update can either be receiving an image, a part of an image or
|
||||
* just an update with a timestamp
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* who - the user who's webcam we're viewing
|
||||
* image - image data
|
||||
* image_size - length of the image in bytes
|
||||
* real_size - actual length of image data
|
||||
* timestamp - milliseconds since the webcam started
|
||||
*
|
||||
* If the real_size is smaller then the image_size then only part of
|
||||
* the image has been read. This function will keep being called till
|
||||
* the total amount of bytes in image_size has been read. The image
|
||||
* received is in JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1).
|
||||
* The size of the image will be either 160x120 or 320x240.
|
||||
* Each webcam image contains a timestamp. This timestamp should be
|
||||
* used to keep the image in sync since some images can take longer
|
||||
* to transport then others. When image_size is 0 we can still receive
|
||||
* a timestamp to stay in sync
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_webcam_image) (int id,
|
||||
const char *who, const unsigned char *image,
|
||||
unsigned int image_size, unsigned int real_size,
|
||||
unsigned int timestamp);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_webcam_invite
|
||||
* Called when you get a webcam invitation
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - identity the invitation is to
|
||||
* from - who the invitation is from
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite) (int id,
|
||||
const char *me, const char *from);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_webcam_invite_reply
|
||||
* Called when you get a response to a webcam invitation
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* me - identity the invitation response is to
|
||||
* from - who the invitation response is from
|
||||
* accept - 0 (decline), 1 (accept)
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_invite_reply) (int id,
|
||||
const char *me, const char *from, int accept);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_webcam_closed
|
||||
* Called when the webcam connection closed
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* who - the user who we where connected to
|
||||
* reason - reason why the connection closed
|
||||
* 1 = user stopped broadcasting
|
||||
* 2 = user cancelled viewing permission
|
||||
* 3 = user declines permission
|
||||
* 4 = user does not have webcam online
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_closed) (int id,
|
||||
const char *who, int reason);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_search_result
|
||||
* Called when the search result received from server
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* found - total number of results returned in the current result set
|
||||
* start - offset from where the current result set starts
|
||||
* total - total number of results available (start + found <= total)
|
||||
* contacts - the list of results as a YList of yahoo_found_contact
|
||||
* these will be freed after this function returns, so
|
||||
* if you need to use the information, make a copy
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_search_result) (int id,
|
||||
int found, int start, int total, YList *contacts);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_error
|
||||
* Called on error.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* err - the error message
|
||||
* fatal- whether this error is fatal to the connection or not
|
||||
* num - Which error is this
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_error) (int id, const char *err,
|
||||
int fatal, int num);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_webcam_viewer
|
||||
* Called when a viewer disconnects/connects/requests to connect
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* who - the viewer
|
||||
* connect - 0=disconnect 1=connect 2=request
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_viewer) (int id,
|
||||
const char *who, int connect);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_webcam_data_request
|
||||
* Called when you get a request for webcam images
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* send - whether to send images or not
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_webcam_data_request) (int id,
|
||||
int send);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_log
|
||||
* Called to log a message.
|
||||
* Params:
|
||||
* fmt - the printf formatted message
|
||||
* Returns:
|
||||
* 0
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_log) (const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_add_handler
|
||||
* Add a listener for the fd. Must call yahoo_read_ready
|
||||
* when a YAHOO_INPUT_READ fd is ready and yahoo_write_ready
|
||||
* when a YAHOO_INPUT_WRITE fd is ready.
|
||||
* Params:
|
||||
* id - the id that identifies the server connection
|
||||
* fd - the fd object on which to listen
|
||||
* cond - the condition on which to call the callback
|
||||
* data - callback data to pass to yahoo_*_ready
|
||||
*
|
||||
* Returns: a tag to be used when removing the handler
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_add_handler) (int id, void *fd,
|
||||
yahoo_input_condition cond, void *data);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_remove_handler
|
||||
* Remove the listener for the fd.
|
||||
* Params:
|
||||
* id - the id that identifies the connection
|
||||
* tag - the handler tag to remove
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_remove_handler) (int id, int tag);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_connect
|
||||
* Connect to a host:port
|
||||
* Params:
|
||||
* host - the host to connect to
|
||||
* port - the port to connect on
|
||||
* Returns:
|
||||
* a unix file descriptor to the socket
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_connect) (const char *host, int port);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_connect_async
|
||||
* Connect to a host:port asynchronously. This function should return
|
||||
* immediately returing a tag used to identify the connection handler,
|
||||
* or a pre-connect error (eg: host name lookup failure).
|
||||
* Once the connect completes (successfully or unsuccessfully), callback
|
||||
* should be called (see the signature for yahoo_connect_callback).
|
||||
* The callback may safely be called before this function returns, but
|
||||
* it should not be called twice.
|
||||
* Params:
|
||||
* id - the id that identifies this connection
|
||||
* host - the host to connect to
|
||||
* port - the port to connect on
|
||||
* callback - function to call when connect completes
|
||||
* callback_data - data to pass to the callback function
|
||||
* use_ssl - Whether we need an SSL connection
|
||||
* Returns:
|
||||
* a tag signifying the connection attempt
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_connect_async) (int id,
|
||||
const char *host, int port, yahoo_connect_callback callback,
|
||||
void *callback_data, int use_ssl);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_get_ip_addr
|
||||
* get IP Address for a domain name
|
||||
* Params:
|
||||
* domain - Domain name
|
||||
* Returns:
|
||||
* Newly allocated string containing the IP Address in IPv4 notation
|
||||
*/
|
||||
char *YAHOO_CALLBACK_TYPE(ext_yahoo_get_ip_addr) (const char *domain);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_write
|
||||
* Write data from the buffer into the socket for the specified connection
|
||||
* Params:
|
||||
* fd - the file descriptor object that identifies this connection
|
||||
* buf - Buffer to write the data from
|
||||
* len - Length of the data
|
||||
* Returns:
|
||||
* Number of bytes written or -1 for error
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_write) (void *fd, char *buf, int len);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_read
|
||||
* Read data into a buffer from socket for the specified connection
|
||||
* Params:
|
||||
* fd - the file descriptor object that identifies this connection
|
||||
* buf - Buffer to read the data into
|
||||
* len - Max length to read
|
||||
* Returns:
|
||||
* Number of bytes read or -1 for error
|
||||
*/
|
||||
int YAHOO_CALLBACK_TYPE(ext_yahoo_read) (void *fd, char *buf, int len);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_close
|
||||
* Close the file descriptor object and free its resources. Libyahoo2 will not
|
||||
* use this object again.
|
||||
* Params:
|
||||
* fd - the file descriptor object that identifies this connection
|
||||
* Returns:
|
||||
* Nothing
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_close) (void *fd);
|
||||
|
||||
/*
|
||||
* Name: ext_yahoo_got_buddy_change_group
|
||||
* Acknowledgement of buddy changing group
|
||||
* Params:
|
||||
* id: client id
|
||||
* me: The user
|
||||
* who: Buddy name
|
||||
* old_group: Old group name
|
||||
* new_group: New group name
|
||||
* Returns:
|
||||
* Nothing
|
||||
*/
|
||||
void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddy_change_group) (int id,
|
||||
const char *me, const char *who, const char *old_group,
|
||||
const char *new_group);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* if using a callback structure, call yahoo_register_callbacks
|
||||
* before doing anything else
|
||||
*/
|
||||
void yahoo_register_callbacks(struct yahoo_callbacks *tyc);
|
||||
|
||||
#undef YAHOO_CALLBACK_TYPE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
396
backends/libyahoo2/yahoo/yahoo2_types.h
Normal file
396
backends/libyahoo2/yahoo/yahoo2_types.h
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* libyahoo2: yahoo2_types.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef YAHOO2_TYPES_H
|
||||
#define YAHOO2_TYPES_H
|
||||
|
||||
#include "yahoo_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum yahoo_service { /* these are easier to see in hex */
|
||||
YAHOO_SERVICE_LOGON = 1,
|
||||
YAHOO_SERVICE_LOGOFF,
|
||||
YAHOO_SERVICE_ISAWAY,
|
||||
YAHOO_SERVICE_ISBACK,
|
||||
YAHOO_SERVICE_IDLE, /* 5 (placemarker) */
|
||||
YAHOO_SERVICE_MESSAGE,
|
||||
YAHOO_SERVICE_IDACT,
|
||||
YAHOO_SERVICE_IDDEACT,
|
||||
YAHOO_SERVICE_MAILSTAT,
|
||||
YAHOO_SERVICE_USERSTAT, /* 0xa */
|
||||
YAHOO_SERVICE_NEWMAIL,
|
||||
YAHOO_SERVICE_CHATINVITE,
|
||||
YAHOO_SERVICE_CALENDAR,
|
||||
YAHOO_SERVICE_NEWPERSONALMAIL,
|
||||
YAHOO_SERVICE_NEWCONTACT,
|
||||
YAHOO_SERVICE_ADDIDENT, /* 0x10 */
|
||||
YAHOO_SERVICE_ADDIGNORE,
|
||||
YAHOO_SERVICE_PING,
|
||||
YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */
|
||||
YAHOO_SERVICE_SYSMESSAGE = 0x14,
|
||||
YAHOO_SERVICE_SKINNAME = 0x15,
|
||||
YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
|
||||
YAHOO_SERVICE_CONFINVITE = 0x18,
|
||||
YAHOO_SERVICE_CONFLOGON,
|
||||
YAHOO_SERVICE_CONFDECLINE,
|
||||
YAHOO_SERVICE_CONFLOGOFF,
|
||||
YAHOO_SERVICE_CONFADDINVITE,
|
||||
YAHOO_SERVICE_CONFMSG,
|
||||
YAHOO_SERVICE_CHATLOGON,
|
||||
YAHOO_SERVICE_CHATLOGOFF,
|
||||
YAHOO_SERVICE_CHATMSG = 0x20,
|
||||
YAHOO_SERVICE_GAMELOGON = 0x28,
|
||||
YAHOO_SERVICE_GAMELOGOFF,
|
||||
YAHOO_SERVICE_GAMEMSG = 0x2a,
|
||||
YAHOO_SERVICE_FILETRANSFER = 0x46,
|
||||
YAHOO_SERVICE_VOICECHAT = 0x4A,
|
||||
YAHOO_SERVICE_NOTIFY,
|
||||
YAHOO_SERVICE_VERIFY,
|
||||
YAHOO_SERVICE_P2PFILEXFER,
|
||||
YAHOO_SERVICE_PEERTOPEER = 0x4F, /* Checks if P2P possible */
|
||||
YAHOO_SERVICE_WEBCAM,
|
||||
YAHOO_SERVICE_AUTHRESP = 0x54,
|
||||
YAHOO_SERVICE_LIST,
|
||||
YAHOO_SERVICE_AUTH = 0x57,
|
||||
YAHOO_SERVICE_AUTHBUDDY = 0x6d,
|
||||
YAHOO_SERVICE_ADDBUDDY = 0x83,
|
||||
YAHOO_SERVICE_REMBUDDY,
|
||||
YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0 */
|
||||
YAHOO_SERVICE_REJECTCONTACT,
|
||||
YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */
|
||||
YAHOO_SERVICE_Y7_PING = 0x8A,
|
||||
YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1 */
|
||||
YAHOO_SERVICE_CHATGOTO,
|
||||
YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */
|
||||
YAHOO_SERVICE_CHATLEAVE,
|
||||
YAHOO_SERVICE_CHATEXIT = 0x9b,
|
||||
YAHOO_SERVICE_CHATADDINVITE = 0x9d,
|
||||
YAHOO_SERVICE_CHATLOGOUT = 0xa0,
|
||||
YAHOO_SERVICE_CHATPING,
|
||||
YAHOO_SERVICE_COMMENT = 0xa8,
|
||||
YAHOO_SERVICE_GAME_INVITE = 0xb7,
|
||||
YAHOO_SERVICE_STEALTH_PERM = 0xb9,
|
||||
YAHOO_SERVICE_STEALTH_SESSION = 0xba,
|
||||
YAHOO_SERVICE_AVATAR = 0xbc,
|
||||
YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
|
||||
YAHOO_SERVICE_PICTURE = 0xbe,
|
||||
YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
|
||||
YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2,
|
||||
YAHOO_SERVICE_YAB_UPDATE = 0xc4,
|
||||
YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */
|
||||
YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, /* YMSG13 */
|
||||
YAHOO_SERVICE_PICTURE_STATUS = 0xc7, /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */
|
||||
YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8,
|
||||
YAHOO_SERVICE_AUDIBLE = 0xd0,
|
||||
YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2,
|
||||
YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4,
|
||||
YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_FILETRANSFERINFO, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */
|
||||
YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */
|
||||
YAHOO_SERVICE_MYSTERY = 0xef, /* Don't know what this is for */
|
||||
YAHOO_SERVICE_Y8_STATUS = 0xf0, /* YMSG15 */
|
||||
YAHOO_SERVICE_Y8_LIST = 0Xf1, /* YMSG15 */
|
||||
YAHOO_SERVICE_MESSAGE_CONFIRM = 0xfb,
|
||||
YAHOO_SERVICE_WEBLOGIN = 0x0226,
|
||||
YAHOO_SERVICE_SMS_MSG = 0x02ea
|
||||
};
|
||||
|
||||
enum yahoo_status {
|
||||
YAHOO_STATUS_AVAILABLE = 0,
|
||||
YAHOO_STATUS_BRB,
|
||||
YAHOO_STATUS_BUSY,
|
||||
YAHOO_STATUS_NOTATHOME,
|
||||
YAHOO_STATUS_NOTATDESK,
|
||||
YAHOO_STATUS_NOTINOFFICE,
|
||||
YAHOO_STATUS_ONPHONE,
|
||||
YAHOO_STATUS_ONVACATION,
|
||||
YAHOO_STATUS_OUTTOLUNCH,
|
||||
YAHOO_STATUS_STEPPEDOUT,
|
||||
YAHOO_STATUS_INVISIBLE = 12,
|
||||
YAHOO_STATUS_CUSTOM = 99,
|
||||
YAHOO_STATUS_IDLE = 999,
|
||||
YAHOO_STATUS_OFFLINE = 0x5a55aa56 /* don't ask */
|
||||
};
|
||||
|
||||
enum ypacket_status {
|
||||
YPACKET_STATUS_DISCONNECTED = -1,
|
||||
YPACKET_STATUS_DEFAULT = 0,
|
||||
YPACKET_STATUS_SERVERACK = 1,
|
||||
YPACKET_STATUS_GAME = 0x2,
|
||||
YPACKET_STATUS_AWAY = 0x4,
|
||||
YPACKET_STATUS_CONTINUED = 0x5,
|
||||
YPACKET_STATUS_INVISIBLE = 12,
|
||||
YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */
|
||||
YPACKET_STATUS_WEBLOGIN = 0x5a55aa55,
|
||||
YPACKET_STATUS_OFFLINE = 0x5a55aa56
|
||||
};
|
||||
|
||||
#define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */
|
||||
|
||||
enum yahoo_login_status {
|
||||
YAHOO_LOGIN_OK = 0,
|
||||
YAHOO_LOGIN_LOGOFF = 1,
|
||||
YAHOO_LOGIN_UNAME = 3,
|
||||
YAHOO_LOGIN_PASSWD = 13,
|
||||
YAHOO_LOGIN_LOCK = 14,
|
||||
YAHOO_LOGIN_DUPL = 99,
|
||||
YAHOO_LOGIN_SOCK = -1,
|
||||
YAHOO_LOGIN_UNKNOWN = 999
|
||||
};
|
||||
|
||||
enum yahoo_error {
|
||||
E_UNKNOWN = -1,
|
||||
E_CONNECTION = -2,
|
||||
E_SYSTEM = -3,
|
||||
E_CUSTOM = 0,
|
||||
|
||||
/* responses from ignore buddy */
|
||||
E_IGNOREDUP = 2,
|
||||
E_IGNORENONE = 3,
|
||||
E_IGNORECONF = 12,
|
||||
|
||||
/* conference */
|
||||
E_CONFNOTAVAIL = 20
|
||||
};
|
||||
|
||||
enum yahoo_log_level {
|
||||
YAHOO_LOG_NONE = 0,
|
||||
YAHOO_LOG_FATAL,
|
||||
YAHOO_LOG_ERR,
|
||||
YAHOO_LOG_WARNING,
|
||||
YAHOO_LOG_NOTICE,
|
||||
YAHOO_LOG_INFO,
|
||||
YAHOO_LOG_DEBUG
|
||||
};
|
||||
|
||||
enum yahoo_file_transfer {
|
||||
YAHOO_FILE_TRANSFER_INIT = 1,
|
||||
YAHOO_FILE_TRANSFER_ACCEPT = 3,
|
||||
YAHOO_FILE_TRANSFER_REJECT = 4,
|
||||
YAHOO_FILE_TRANSFER_DONE = 5,
|
||||
YAHOO_FILE_TRANSFER_RELAY,
|
||||
YAHOO_FILE_TRANSFER_FAILED,
|
||||
YAHOO_FILE_TRANSFER_UNKNOWN
|
||||
};
|
||||
|
||||
#define YAHOO_PROTO_VER 0x0010
|
||||
|
||||
/* Yahoo style/color directives */
|
||||
#define YAHOO_COLOR_BLACK "\033[30m"
|
||||
#define YAHOO_COLOR_BLUE "\033[31m"
|
||||
#define YAHOO_COLOR_LIGHTBLUE "\033[32m"
|
||||
#define YAHOO_COLOR_GRAY "\033[33m"
|
||||
#define YAHOO_COLOR_GREEN "\033[34m"
|
||||
#define YAHOO_COLOR_PINK "\033[35m"
|
||||
#define YAHOO_COLOR_PURPLE "\033[36m"
|
||||
#define YAHOO_COLOR_ORANGE "\033[37m"
|
||||
#define YAHOO_COLOR_RED "\033[38m"
|
||||
#define YAHOO_COLOR_OLIVE "\033[39m"
|
||||
#define YAHOO_COLOR_ANY "\033[#"
|
||||
#define YAHOO_STYLE_ITALICON "\033[2m"
|
||||
#define YAHOO_STYLE_ITALICOFF "\033[x2m"
|
||||
#define YAHOO_STYLE_BOLDON "\033[1m"
|
||||
#define YAHOO_STYLE_BOLDOFF "\033[x1m"
|
||||
#define YAHOO_STYLE_UNDERLINEON "\033[4m"
|
||||
#define YAHOO_STYLE_UNDERLINEOFF "\033[x4m"
|
||||
#define YAHOO_STYLE_URLON "\033[lm"
|
||||
#define YAHOO_STYLE_URLOFF "\033[xlm"
|
||||
|
||||
enum yahoo_connection_type {
|
||||
YAHOO_CONNECTION_PAGER = 0,
|
||||
YAHOO_CONNECTION_FT,
|
||||
YAHOO_CONNECTION_YAB,
|
||||
YAHOO_CONNECTION_WEBCAM_MASTER,
|
||||
YAHOO_CONNECTION_WEBCAM,
|
||||
YAHOO_CONNECTION_CHATCAT,
|
||||
YAHOO_CONNECTION_SEARCH,
|
||||
YAHOO_CONNECTION_AUTH
|
||||
};
|
||||
|
||||
enum yahoo_webcam_direction_type {
|
||||
YAHOO_WEBCAM_DOWNLOAD = 0,
|
||||
YAHOO_WEBCAM_UPLOAD
|
||||
};
|
||||
|
||||
enum yahoo_stealth_visibility_type {
|
||||
YAHOO_STEALTH_DEFAULT = 0,
|
||||
YAHOO_STEALTH_ONLINE,
|
||||
YAHOO_STEALTH_PERM_OFFLINE
|
||||
};
|
||||
|
||||
/* chat member attribs */
|
||||
#define YAHOO_CHAT_MALE 0x8000
|
||||
#define YAHOO_CHAT_FEMALE 0x10000
|
||||
#define YAHOO_CHAT_FEMALE 0x10000
|
||||
#define YAHOO_CHAT_DUNNO 0x400
|
||||
#define YAHOO_CHAT_WEBCAM 0x10
|
||||
|
||||
enum yahoo_webcam_conn_type { Y_WCM_DIALUP, Y_WCM_DSL, Y_WCM_T1 };
|
||||
|
||||
struct yahoo_webcam {
|
||||
int direction; /* Uploading or downloading */
|
||||
int conn_type; /* 0=Dialup, 1=DSL/Cable, 2=T1/Lan */
|
||||
|
||||
char *user; /* user we are viewing */
|
||||
char *server; /* webcam server to connect to */
|
||||
int port; /* webcam port to connect on */
|
||||
char *key; /* key to connect to the server with */
|
||||
char *description; /* webcam description */
|
||||
char *my_ip; /* own ip number */
|
||||
};
|
||||
|
||||
struct yahoo_webcam_data {
|
||||
unsigned int data_size;
|
||||
unsigned int to_read;
|
||||
unsigned int timestamp;
|
||||
unsigned char packet_type;
|
||||
};
|
||||
|
||||
struct yahoo_data {
|
||||
char *user;
|
||||
char *password;
|
||||
|
||||
char *cookie_y;
|
||||
char *cookie_t;
|
||||
char *cookie_c;
|
||||
char *cookie_b;
|
||||
char *login_cookie;
|
||||
char *crumb;
|
||||
char *seed;
|
||||
|
||||
YList *buddies;
|
||||
YList *ignore;
|
||||
YList *identities;
|
||||
char *login_id;
|
||||
|
||||
int current_status;
|
||||
int initial_status;
|
||||
int logged_in;
|
||||
|
||||
int session_id;
|
||||
|
||||
int client_id;
|
||||
|
||||
char *rawbuddylist;
|
||||
char *ignorelist;
|
||||
|
||||
void *server_settings;
|
||||
|
||||
struct yahoo_process_status_entry *half_user;
|
||||
};
|
||||
|
||||
struct yab {
|
||||
int yid;
|
||||
char *id;
|
||||
char *fname;
|
||||
char *lname;
|
||||
char *nname;
|
||||
char *email;
|
||||
char *hphone;
|
||||
char *wphone;
|
||||
char *mphone;
|
||||
int dbid;
|
||||
};
|
||||
|
||||
struct yahoo_buddy {
|
||||
char *group;
|
||||
char *id;
|
||||
char *real_name;
|
||||
struct yab *yab_entry;
|
||||
};
|
||||
|
||||
enum yahoo_search_type {
|
||||
YAHOO_SEARCH_KEYWORD = 0,
|
||||
YAHOO_SEARCH_YID,
|
||||
YAHOO_SEARCH_NAME
|
||||
};
|
||||
|
||||
enum yahoo_search_gender {
|
||||
YAHOO_GENDER_NONE = 0,
|
||||
YAHOO_GENDER_MALE,
|
||||
YAHOO_GENDER_FEMALE
|
||||
};
|
||||
|
||||
enum yahoo_search_agerange {
|
||||
YAHOO_AGERANGE_NONE = 0
|
||||
};
|
||||
|
||||
struct yahoo_found_contact {
|
||||
char *id;
|
||||
char *gender;
|
||||
char *location;
|
||||
int age;
|
||||
int online;
|
||||
};
|
||||
|
||||
/*
|
||||
* Function pointer to be passed to http get/post and send file
|
||||
*/
|
||||
typedef void (*yahoo_get_fd_callback) (int id, void *fd, int error,
|
||||
void *data);
|
||||
|
||||
/*
|
||||
* Function pointer to be passed to yahoo_get_url_handle
|
||||
*/
|
||||
typedef void (*yahoo_get_url_handle_callback) (int id, void *fd,
|
||||
int error, const char *filename, unsigned long size,
|
||||
void *data);
|
||||
|
||||
struct yahoo_chat_member {
|
||||
char *id;
|
||||
int age;
|
||||
int attribs;
|
||||
char *alias;
|
||||
char *location;
|
||||
};
|
||||
|
||||
struct yahoo_process_status_entry {
|
||||
char *name; /* 7 name */
|
||||
int state; /* 10 state */
|
||||
int flags; /* 13 flags, bit 0 = pager, bit 1 = chat, bit 2 = game */
|
||||
int mobile; /* 60 mobile */
|
||||
char *msg; /* 19 custom status message */
|
||||
int away; /* 47 away (or invisible) */
|
||||
int buddy_session; /* 11 state */
|
||||
int f17; /* 17 in chat? then what about flags? */
|
||||
int idle; /* 137 seconds idle */
|
||||
int f138; /* 138 state */
|
||||
char *f184; /* 184 state */
|
||||
int f192; /* 192 state */
|
||||
int f10001; /* 10001 state */
|
||||
int f10002; /* 10002 state */
|
||||
int f198; /* 198 state */
|
||||
char *f197; /* 197 state */
|
||||
char *f205; /* 205 state */
|
||||
int f213; /* 213 state */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
36
backends/libyahoo2/yahoo/yahoo_debug.h
Normal file
36
backends/libyahoo2/yahoo/yahoo_debug.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* libyahoo2: yahoo_debug.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
extern int yahoo_log_message(char *fmt, ...);
|
||||
|
||||
#define NOTICE(x) if(yahoo_get_log_level() >= YAHOO_LOG_NOTICE) { yahoo_log_message x; yahoo_log_message("\n"); }
|
||||
|
||||
#define LOG(x) if(yahoo_get_log_level() >= YAHOO_LOG_INFO) { yahoo_log_message("%s:%d: ", __FILE__, __LINE__); \
|
||||
yahoo_log_message x; \
|
||||
yahoo_log_message("\n"); }
|
||||
|
||||
#define WARNING(x) if(yahoo_get_log_level() >= YAHOO_LOG_WARNING) { yahoo_log_message("%s:%d: warning: ", __FILE__, __LINE__); \
|
||||
yahoo_log_message x; \
|
||||
yahoo_log_message("\n"); }
|
||||
|
||||
#define DEBUG_MSG(x) if(yahoo_get_log_level() >= YAHOO_LOG_DEBUG) { yahoo_log_message("%s:%d: debug: ", __FILE__, __LINE__); \
|
||||
yahoo_log_message x; \
|
||||
yahoo_log_message("\n"); }
|
4810
backends/libyahoo2/yahoo/yahoo_fn.c
Normal file
4810
backends/libyahoo2/yahoo/yahoo_fn.c
Normal file
File diff suppressed because it is too large
Load diff
32
backends/libyahoo2/yahoo/yahoo_fn.h
Normal file
32
backends/libyahoo2/yahoo/yahoo_fn.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* libyahoo2 - originally from gaim patches by Amatus
|
||||
*
|
||||
* Copyright (C) 2003-2004
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define IDENT 1 /* identify function */
|
||||
#define XOR 2 /* xor with arg1 */
|
||||
#define MULADD 3 /* multipy by arg1 then add arg2 */
|
||||
#define LOOKUP 4 /* lookup each byte in the table pointed to by arg1 */
|
||||
#define BITFLD 5 /* reorder bits according to table pointed to by arg1 */
|
||||
|
||||
struct yahoo_fn {
|
||||
int type;
|
||||
long arg1, arg2;
|
||||
};
|
||||
|
||||
int yahoo_xfrm(int table, int depth, int seed);
|
404
backends/libyahoo2/yahoo/yahoo_httplib.c
Normal file
404
backends/libyahoo2/yahoo/yahoo_httplib.c
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* libyahoo2: yahoo_httplib.c
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <string.h>
|
||||
#else
|
||||
# if !HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr(), *strrchr();
|
||||
# if !HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# define memmove(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "yahoo2.h"
|
||||
#include "yahoo2_callbacks.h"
|
||||
#include "yahoo_httplib.h"
|
||||
#include "yahoo_util.h"
|
||||
|
||||
#include "yahoo_debug.h"
|
||||
#ifdef __MINGW32__
|
||||
# include <winsock2.h>
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
extern struct yahoo_callbacks *yc;
|
||||
#define YAHOO_CALLBACK(x) yc->x
|
||||
|
||||
extern enum yahoo_log_level log_level;
|
||||
|
||||
int yahoo_tcp_readline(char *ptr, int maxlen, void *fd)
|
||||
{
|
||||
int n, rc;
|
||||
char c;
|
||||
|
||||
for (n = 1; n < maxlen; n++) {
|
||||
|
||||
do {
|
||||
rc = YAHOO_CALLBACK(ext_yahoo_read) (fd, &c, 1);
|
||||
} while (rc == -1 && (errno == EINTR || errno == EAGAIN)); /* this is bad - it should be done asynchronously */
|
||||
|
||||
if (rc == 1) {
|
||||
if (c == '\r') /* get rid of \r */
|
||||
continue;
|
||||
*ptr = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
ptr++;
|
||||
} else if (rc == 0) {
|
||||
if (n == 1)
|
||||
return (0); /* EOF, no data */
|
||||
else
|
||||
break; /* EOF, w/ data */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = 0;
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int url_to_host_port_path(const char *url,
|
||||
char *host, int *port, char *path, int *ssl)
|
||||
{
|
||||
char *urlcopy = NULL;
|
||||
char *slash = NULL;
|
||||
char *colon = NULL;
|
||||
|
||||
/*
|
||||
* http://hostname
|
||||
* http://hostname/
|
||||
* http://hostname/path
|
||||
* http://hostname/path:foo
|
||||
* http://hostname:port
|
||||
* http://hostname:port/
|
||||
* http://hostname:port/path
|
||||
* http://hostname:port/path:foo
|
||||
* and https:// variants of the above
|
||||
*/
|
||||
|
||||
if (strstr(url, "http://") == url) {
|
||||
urlcopy = strdup(url + 7);
|
||||
} else if (strstr(url, "https://") == url) {
|
||||
urlcopy = strdup(url + 8);
|
||||
*ssl = 1;
|
||||
} else {
|
||||
WARNING(("Weird url - unknown protocol: %s", url));
|
||||
return 0;
|
||||
}
|
||||
|
||||
slash = strchr(urlcopy, '/');
|
||||
colon = strchr(urlcopy, ':');
|
||||
|
||||
if (!colon || (slash && slash < colon)) {
|
||||
if (*ssl)
|
||||
*port = 443;
|
||||
else
|
||||
*port = 80;
|
||||
} else {
|
||||
*colon = 0;
|
||||
*port = atoi(colon + 1);
|
||||
}
|
||||
|
||||
if (!slash) {
|
||||
strcpy(path, "/");
|
||||
} else {
|
||||
strcpy(path, slash);
|
||||
*slash = 0;
|
||||
}
|
||||
|
||||
strcpy(host, urlcopy);
|
||||
|
||||
FREE(urlcopy);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int isurlchar(unsigned char c)
|
||||
{
|
||||
return (isalnum(c));
|
||||
}
|
||||
|
||||
char *yahoo_urlencode(const char *instr)
|
||||
{
|
||||
int ipos = 0, bpos = 0;
|
||||
char *str = NULL;
|
||||
int len = strlen(instr);
|
||||
|
||||
if (!(str = y_new(char, 3 *len + 1)))
|
||||
return "";
|
||||
|
||||
while (instr[ipos]) {
|
||||
while (isurlchar(instr[ipos]))
|
||||
str[bpos++] = instr[ipos++];
|
||||
if (!instr[ipos])
|
||||
break;
|
||||
|
||||
snprintf(&str[bpos], 4, "%%%02x", instr[ipos] & 0xff);
|
||||
bpos += 3;
|
||||
ipos++;
|
||||
}
|
||||
str[bpos] = '\0';
|
||||
|
||||
/* free extra alloc'ed mem. */
|
||||
len = strlen(str);
|
||||
str = y_renew(char, str, len + 1);
|
||||
|
||||
return (str);
|
||||
}
|
||||
|
||||
char *yahoo_urldecode(const char *instr)
|
||||
{
|
||||
int ipos = 0, bpos = 0;
|
||||
char *str = NULL;
|
||||
char entity[3] = { 0, 0, 0 };
|
||||
unsigned dec;
|
||||
int len = strlen(instr);
|
||||
|
||||
if (!(str = y_new(char, len + 1)))
|
||||
return "";
|
||||
|
||||
while (instr[ipos]) {
|
||||
while (instr[ipos] && instr[ipos] != '%')
|
||||
if (instr[ipos] == '+') {
|
||||
str[bpos++] = ' ';
|
||||
ipos++;
|
||||
} else
|
||||
str[bpos++] = instr[ipos++];
|
||||
if (!instr[ipos])
|
||||
break;
|
||||
|
||||
if (instr[ipos + 1] && instr[ipos + 2]) {
|
||||
ipos++;
|
||||
entity[0] = instr[ipos++];
|
||||
entity[1] = instr[ipos++];
|
||||
sscanf(entity, "%2x", &dec);
|
||||
str[bpos++] = (char)dec;
|
||||
} else {
|
||||
str[bpos++] = instr[ipos++];
|
||||
}
|
||||
}
|
||||
str[bpos] = '\0';
|
||||
|
||||
/* free extra alloc'ed mem. */
|
||||
len = strlen(str);
|
||||
str = y_renew(char, str, len + 1);
|
||||
|
||||
return (str);
|
||||
}
|
||||
|
||||
char *yahoo_xmldecode(const char *instr)
|
||||
{
|
||||
int ipos = 0, bpos = 0, epos = 0;
|
||||
char *str = NULL;
|
||||
char entity[4] = { 0, 0, 0, 0 };
|
||||
char *entitymap[5][2] = {
|
||||
{"amp;", "&"},
|
||||
{"quot;", "\""},
|
||||
{"lt;", "<"},
|
||||
{"gt;", "<"},
|
||||
{"nbsp;", " "}
|
||||
};
|
||||
unsigned dec;
|
||||
int len = strlen(instr);
|
||||
|
||||
if (!(str = y_new(char, len + 1)))
|
||||
return "";
|
||||
|
||||
while (instr[ipos]) {
|
||||
while (instr[ipos] && instr[ipos] != '&')
|
||||
if (instr[ipos] == '+') {
|
||||
str[bpos++] = ' ';
|
||||
ipos++;
|
||||
} else
|
||||
str[bpos++] = instr[ipos++];
|
||||
if (!instr[ipos] || !instr[ipos + 1])
|
||||
break;
|
||||
ipos++;
|
||||
|
||||
if (instr[ipos] == '#') {
|
||||
ipos++;
|
||||
epos = 0;
|
||||
while (instr[ipos] != ';')
|
||||
entity[epos++] = instr[ipos++];
|
||||
sscanf(entity, "%u", &dec);
|
||||
str[bpos++] = (char)dec;
|
||||
ipos++;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (!strncmp(instr + ipos, entitymap[i][0],
|
||||
strlen(entitymap[i][0]))) {
|
||||
str[bpos++] = entitymap[i][1][0];
|
||||
ipos += strlen(entitymap[i][0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
str[bpos] = '\0';
|
||||
|
||||
/* free extra alloc'ed mem. */
|
||||
len = strlen(str);
|
||||
str = y_renew(char, str, len + 1);
|
||||
|
||||
return (str);
|
||||
}
|
||||
|
||||
typedef void (*http_connected) (int id, void *fd, int error);
|
||||
|
||||
struct callback_data {
|
||||
int id;
|
||||
yahoo_get_fd_callback callback;
|
||||
char *request;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
static void connect_complete(void *fd, int error, void *data)
|
||||
{
|
||||
struct callback_data *ccd = data;
|
||||
if (error == 0)
|
||||
YAHOO_CALLBACK(ext_yahoo_write) (fd, ccd->request,
|
||||
strlen(ccd->request));
|
||||
free(ccd->request);
|
||||
ccd->callback(ccd->id, fd, error, ccd->user_data);
|
||||
FREE(ccd);
|
||||
}
|
||||
|
||||
static void yahoo_send_http_request(int id, char *host, int port, char *request,
|
||||
yahoo_get_fd_callback callback, void *data, int use_ssl)
|
||||
{
|
||||
struct callback_data *ccd = y_new0(struct callback_data, 1);
|
||||
ccd->callback = callback;
|
||||
ccd->id = id;
|
||||
ccd->request = strdup(request);
|
||||
ccd->user_data = data;
|
||||
|
||||
YAHOO_CALLBACK(ext_yahoo_connect_async) (id, host, port,
|
||||
connect_complete, ccd, use_ssl);
|
||||
}
|
||||
|
||||
void yahoo_http_post(int id, const char *url, const char *cookies,
|
||||
long content_length, yahoo_get_fd_callback callback, void *data)
|
||||
{
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
char buff[1024];
|
||||
int ssl = 0;
|
||||
|
||||
if (!url_to_host_port_path(url, host, &port, path, &ssl))
|
||||
return;
|
||||
|
||||
/* thanks to kopete dumpcap */
|
||||
snprintf(buff, sizeof(buff),
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Cookie: %s\r\n"
|
||||
"User-Agent: Mozilla/5.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
"Content-Length: %ld\r\n"
|
||||
"Cache-Control: no-cache\r\n"
|
||||
"\r\n", path, cookies, host, content_length);
|
||||
|
||||
yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
|
||||
}
|
||||
|
||||
void yahoo_http_get(int id, const char *url, const char *cookies, int http11,
|
||||
int keepalive, yahoo_get_fd_callback callback, void *data)
|
||||
{
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
char buff[2048];
|
||||
char cookiebuff[1024];
|
||||
int ssl = 0;
|
||||
|
||||
if (!url_to_host_port_path(url, host, &port, path, &ssl))
|
||||
return;
|
||||
|
||||
/* Allow cases when we don't need to send a cookie */
|
||||
if (cookies)
|
||||
snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n",
|
||||
cookies);
|
||||
else
|
||||
cookiebuff[0] = '\0';
|
||||
|
||||
snprintf(buff, sizeof(buff),
|
||||
"GET %s HTTP/1.%s\r\n"
|
||||
"%sHost: %s\r\n"
|
||||
"User-Agent: Mozilla/4.5 [en] (" "1" "/" "1" ")\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"%s" "\r\n", path, http11?"1":"0", cookiebuff, host,
|
||||
keepalive? "Connection: Keep-Alive\r\n":"Connection: close\r\n");
|
||||
|
||||
yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
|
||||
}
|
||||
|
||||
void yahoo_http_head(int id, const char *url, const char *cookies, int len,
|
||||
char *payload, yahoo_get_fd_callback callback, void *data)
|
||||
{
|
||||
char host[255];
|
||||
int port = 80;
|
||||
char path[255];
|
||||
char buff[2048];
|
||||
char cookiebuff[1024];
|
||||
int ssl = 0;
|
||||
|
||||
if (!url_to_host_port_path(url, host, &port, path, &ssl))
|
||||
return;
|
||||
|
||||
/* Allow cases when we don't need to send a cookie */
|
||||
if (cookies)
|
||||
snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n",
|
||||
cookies);
|
||||
else
|
||||
cookiebuff[0] = '\0';
|
||||
|
||||
snprintf(buff, sizeof(buff),
|
||||
"HEAD %s HTTP/1.0\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"Host: %s:%d\r\n"
|
||||
"User-Agent: Mozilla/4.5 [en] (" "1" "/" "1" ")\r\n"
|
||||
"%s"
|
||||
"Content-Length: %d\r\n"
|
||||
"Cache-Control: no-cache\r\n"
|
||||
"\r\n%s", path, host, port, cookiebuff, len,
|
||||
payload?payload:"");
|
||||
|
||||
yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
|
||||
}
|
||||
|
48
backends/libyahoo2/yahoo/yahoo_httplib.h
Normal file
48
backends/libyahoo2/yahoo/yahoo_httplib.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* libyahoo2: yahoo_httplib.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef YAHOO_HTTPLIB_H
|
||||
#define YAHOO_HTTPLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "yahoo2_types.h"
|
||||
|
||||
char *yahoo_urlencode(const char *instr);
|
||||
char *yahoo_urldecode(const char *instr);
|
||||
char *yahoo_xmldecode(const char *instr);
|
||||
|
||||
int yahoo_tcp_readline(char *ptr, int maxlen, void *fd);
|
||||
void yahoo_http_post(int id, const char *url, const char *cookies,
|
||||
long size, yahoo_get_fd_callback callback, void *data);
|
||||
void yahoo_http_get(int id, const char *url, const char *cookies,
|
||||
int http11, int keepalive, yahoo_get_fd_callback callback,
|
||||
void *data);
|
||||
void yahoo_http_head(int id, const char *url, const char *cookies,
|
||||
int size, char *payload, yahoo_get_fd_callback callback,
|
||||
void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
233
backends/libyahoo2/yahoo/yahoo_list.c
Normal file
233
backends/libyahoo2/yahoo/yahoo_list.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* yahoo_list.c: linked list routines
|
||||
*
|
||||
* Some code copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
* Other code copyright Meredydd Luff <meredydd AT everybuddy.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Some of this code was borrowed from elist.c in the eb-lite sources
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "yahoo_list.h"
|
||||
|
||||
YList *y_list_append(YList *list, void *data)
|
||||
{
|
||||
YList *n;
|
||||
YList *new_list = malloc(sizeof(YList));
|
||||
YList *attach_to = NULL;
|
||||
|
||||
new_list->next = NULL;
|
||||
new_list->data = data;
|
||||
|
||||
for (n = list; n != NULL; n = n->next) {
|
||||
attach_to = n;
|
||||
}
|
||||
|
||||
if (attach_to == NULL) {
|
||||
new_list->prev = NULL;
|
||||
return new_list;
|
||||
} else {
|
||||
new_list->prev = attach_to;
|
||||
attach_to->next = new_list;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
YList *y_list_prepend(YList *list, void *data)
|
||||
{
|
||||
YList *n = malloc(sizeof(YList));
|
||||
|
||||
n->next = list;
|
||||
n->prev = NULL;
|
||||
n->data = data;
|
||||
if (list)
|
||||
list->prev = n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
YList *y_list_concat(YList *list, YList *add)
|
||||
{
|
||||
YList *l;
|
||||
|
||||
if (!list)
|
||||
return add;
|
||||
|
||||
if (!add)
|
||||
return list;
|
||||
|
||||
for (l = list; l->next; l = l->next) ;
|
||||
|
||||
l->next = add;
|
||||
add->prev = l;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
YList *y_list_remove(YList *list, void *data)
|
||||
{
|
||||
YList *n;
|
||||
|
||||
for (n = list; n != NULL; n = n->next) {
|
||||
if (n->data == data) {
|
||||
list = y_list_remove_link(list, n);
|
||||
y_list_free_1(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
/* link MUST be part of list */
|
||||
/* caller must free link using y_list_free_1 */
|
||||
YList *y_list_remove_link(YList *list, const YList *link)
|
||||
{
|
||||
if (!link)
|
||||
return list;
|
||||
|
||||
if (link->next)
|
||||
link->next->prev = link->prev;
|
||||
if (link->prev)
|
||||
link->prev->next = link->next;
|
||||
|
||||
if (link == list)
|
||||
list = link->next;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int y_list_length(const YList *list)
|
||||
{
|
||||
int retval = 0;
|
||||
const YList *n = list;
|
||||
|
||||
for (n = list; n != NULL; n = n->next) {
|
||||
retval++;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* well, you could just check for list == NULL, but that would be
|
||||
* implementation dependent
|
||||
*/
|
||||
int y_list_empty(const YList *list)
|
||||
{
|
||||
if (!list)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int y_list_singleton(const YList *list)
|
||||
{
|
||||
if (!list || list->next)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
YList *y_list_copy(YList *list)
|
||||
{
|
||||
YList *n;
|
||||
YList *copy = NULL;
|
||||
|
||||
for (n = list; n != NULL; n = n->next) {
|
||||
copy = y_list_append(copy, n->data);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void y_list_free_1(YList *list)
|
||||
{
|
||||
free(list);
|
||||
}
|
||||
|
||||
void y_list_free(YList *list)
|
||||
{
|
||||
YList *n = list;
|
||||
|
||||
while (n != NULL) {
|
||||
YList *next = n->next;
|
||||
free(n);
|
||||
n = next;
|
||||
}
|
||||
}
|
||||
|
||||
YList *y_list_find(YList *list, const void *data)
|
||||
{
|
||||
YList *l;
|
||||
for (l = list; l && l->data != data; l = l->next) ;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void y_list_foreach(YList *list, YListFunc fn, void *user_data)
|
||||
{
|
||||
for (; list; list = list->next)
|
||||
fn(list->data, user_data);
|
||||
}
|
||||
|
||||
YList *y_list_find_custom(YList *list, const void *data, YListCompFunc comp)
|
||||
{
|
||||
YList *l;
|
||||
for (l = list; l; l = l->next)
|
||||
if (comp(l->data, data) == 0)
|
||||
return l;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
YList *y_list_nth(YList *list, int n)
|
||||
{
|
||||
int i = n;
|
||||
for (; list && i; list = list->next, i--) ;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
YList *y_list_insert_sorted(YList *list, void *data, YListCompFunc comp)
|
||||
{
|
||||
YList *l, *n, *prev = NULL;
|
||||
if (!list)
|
||||
return y_list_append(list, data);
|
||||
|
||||
n = malloc(sizeof(YList));
|
||||
n->data = data;
|
||||
for (l = list; l && comp(l->data, n->data) <= 0; l = l->next)
|
||||
prev = l;
|
||||
|
||||
if (l) {
|
||||
n->prev = l->prev;
|
||||
l->prev = n;
|
||||
} else
|
||||
n->prev = prev;
|
||||
|
||||
n->next = l;
|
||||
|
||||
if (n->prev) {
|
||||
n->prev->next = n;
|
||||
return list;
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
76
backends/libyahoo2/yahoo/yahoo_list.h
Normal file
76
backends/libyahoo2/yahoo/yahoo_list.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* yahoo_list.h: linked list routines
|
||||
*
|
||||
* Some code copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
* Other code copyright Meredydd Luff <meredydd AT everybuddy.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a replacement for the GList. It only provides functions that
|
||||
* we use in Ayttm. Thanks to Meredyyd from everybuddy dev for doing
|
||||
* most of it.
|
||||
*/
|
||||
|
||||
#ifndef __YLIST_H__
|
||||
#define __YLIST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _YList {
|
||||
struct _YList *next;
|
||||
struct _YList *prev;
|
||||
void *data;
|
||||
} YList;
|
||||
|
||||
typedef int (*YListCompFunc) (const void *, const void *);
|
||||
typedef void (*YListFunc) (void *, void *);
|
||||
|
||||
YList *y_list_append(YList *list, void *data);
|
||||
YList *y_list_prepend(YList *list, void *data);
|
||||
YList *y_list_remove_link(YList *list, const YList *link);
|
||||
YList *y_list_remove(YList *list, void *data);
|
||||
|
||||
YList *y_list_insert_sorted(YList *list, void *data,
|
||||
YListCompFunc comp);
|
||||
|
||||
YList *y_list_copy(YList *list);
|
||||
|
||||
YList *y_list_concat(YList *list, YList *add);
|
||||
|
||||
YList *y_list_find(YList *list, const void *data);
|
||||
YList *y_list_find_custom(YList *list, const void *data,
|
||||
YListCompFunc comp);
|
||||
|
||||
YList *y_list_nth(YList *list, int n);
|
||||
|
||||
void y_list_foreach(YList *list, YListFunc fn, void *user_data);
|
||||
|
||||
void y_list_free_1(YList *list);
|
||||
void y_list_free(YList *list);
|
||||
int y_list_length(const YList *list);
|
||||
int y_list_empty(const YList *list);
|
||||
int y_list_singleton(const YList *list);
|
||||
|
||||
#define y_list_next(list) list->next
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
162
backends/libyahoo2/yahoo/yahoo_util.c
Normal file
162
backends/libyahoo2/yahoo/yahoo_util.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* libyahoo2: yahoo_util.c
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <string.h>
|
||||
#else
|
||||
# if !HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr(), *strrchr();
|
||||
# if !HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# define memmove(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "yahoo_util.h"
|
||||
|
||||
char *y_string_append(char *string, char *append)
|
||||
{
|
||||
int size = strlen(string) + strlen(append) + 1;
|
||||
char *new_string = y_renew(char, string, size);
|
||||
|
||||
if (new_string == NULL) {
|
||||
new_string = y_new(char, size);
|
||||
strcpy(new_string, string);
|
||||
FREE(string);
|
||||
}
|
||||
|
||||
strcat(new_string, append);
|
||||
|
||||
return new_string;
|
||||
}
|
||||
|
||||
char *y_str_to_utf8(const char *in)
|
||||
{
|
||||
unsigned int n, i = 0;
|
||||
char *result = NULL;
|
||||
|
||||
if (in == NULL || *in == '\0')
|
||||
return strdup("");
|
||||
|
||||
result = y_new(char, strlen(in) * 2 + 1);
|
||||
|
||||
/* convert a string to UTF-8 Format */
|
||||
for (n = 0; n < strlen(in); n++) {
|
||||
unsigned char c = (unsigned char)in[n];
|
||||
|
||||
if (c < 128) {
|
||||
result[i++] = (char)c;
|
||||
} else {
|
||||
result[i++] = (char)((c >> 6) | 192);
|
||||
result[i++] = (char)((c & 63) | 128);
|
||||
}
|
||||
}
|
||||
result[i] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
char *y_utf8_to_str(const char *in)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int n;
|
||||
char *result = NULL;
|
||||
|
||||
if (in == NULL || *in == '\0')
|
||||
return strdup("");
|
||||
|
||||
result = y_new(char, strlen(in) + 1);
|
||||
|
||||
/* convert a string from UTF-8 Format */
|
||||
for (n = 0; n < strlen(in); n++) {
|
||||
unsigned char c = in[n];
|
||||
|
||||
if (c < 128) {
|
||||
result[i++] = (char)c;
|
||||
} else {
|
||||
result[i++] = (c << 6) | (in[++n] & 63);
|
||||
}
|
||||
}
|
||||
result[i] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !HAVE_GLIB
|
||||
|
||||
void y_strfreev(char **vector)
|
||||
{
|
||||
char **v;
|
||||
for (v = vector; *v; v++) {
|
||||
FREE(*v);
|
||||
}
|
||||
FREE(vector);
|
||||
}
|
||||
|
||||
char **y_strsplit(char *str, char *sep, int nelem)
|
||||
{
|
||||
char **vector;
|
||||
char *s, *p;
|
||||
int i = 0;
|
||||
int l = strlen(sep);
|
||||
if (nelem <= 0) {
|
||||
char *s;
|
||||
nelem = 0;
|
||||
if (*str) {
|
||||
for (s = strstr(str, sep); s;
|
||||
s = strstr(s + l, sep), nelem++) ;
|
||||
if (strcmp(str + strlen(str) - l, sep))
|
||||
nelem++;
|
||||
}
|
||||
}
|
||||
|
||||
vector = y_new(char *, nelem + 1);
|
||||
|
||||
for (p = str, s = strstr(p, sep); i < nelem && s;
|
||||
p = s + l, s = strstr(p, sep), i++) {
|
||||
int len = s - p;
|
||||
vector[i] = y_new(char, len + 1);
|
||||
strncpy(vector[i], p, len);
|
||||
vector[i][len] = '\0';
|
||||
}
|
||||
|
||||
if (i < nelem && *str) /* str didn't end with sep, and str isn't empty */
|
||||
vector[i++] = strdup(p);
|
||||
|
||||
vector[i] = NULL;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void *y_memdup(const void *addr, int n)
|
||||
{
|
||||
void *new_chunk = malloc(n);
|
||||
if (new_chunk)
|
||||
memcpy(new_chunk, addr, n);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
#endif
|
103
backends/libyahoo2/yahoo/yahoo_util.h
Normal file
103
backends/libyahoo2/yahoo/yahoo_util.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* libyahoo2: yahoo_util.h
|
||||
*
|
||||
* Copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __YAHOO_UTIL_H__
|
||||
#define __YAHOO_UTIL_H__
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_GLIB
|
||||
# include <glib.h>
|
||||
|
||||
# define FREE(x) if(x) {g_free(x); x=NULL;}
|
||||
|
||||
# define y_new g_new
|
||||
# define y_new0 g_new0
|
||||
# define y_renew g_renew
|
||||
|
||||
# define y_memdup g_memdup
|
||||
# define y_strsplit g_strsplit
|
||||
# define y_strfreev g_strfreev
|
||||
# ifndef strdup
|
||||
# define strdup g_strdup
|
||||
# endif
|
||||
# ifndef strncasecmp
|
||||
# define strncasecmp g_strncasecmp
|
||||
# define strcasecmp g_strcasecmp
|
||||
# endif
|
||||
|
||||
# define snprintf g_snprintf
|
||||
# define vsnprintf g_vsnprintf
|
||||
|
||||
#else
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <stdarg.h>
|
||||
|
||||
# define FREE(x) if(x) {free(x); x=NULL;}
|
||||
|
||||
# define y_new(type, n) (type *)malloc(sizeof(type) * (n))
|
||||
# define y_new0(type, n) (type *)calloc((n), sizeof(type))
|
||||
# define y_renew(type, mem, n) (type *)realloc(mem, n)
|
||||
|
||||
void *y_memdup(const void *addr, int n);
|
||||
char **y_strsplit(char *str, char *sep, int nelem);
|
||||
void y_strfreev(char **vector);
|
||||
|
||||
#ifndef _WIN32
|
||||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
char *strdup(const char *s);
|
||||
|
||||
int snprintf(char *str, size_t size, const char *format, ...);
|
||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following three functions return newly allocated memory.
|
||||
* You must free it yourself
|
||||
*/
|
||||
char *y_string_append(char *str, char *append);
|
||||
char *y_str_to_utf8(const char *in);
|
||||
char *y_utf8_to_str(const char *in);
|
||||
|
||||
#endif
|
48
backends/libyahoo2/yahoohandler.h
Normal file
48
backends/libyahoo2/yahoohandler.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Yahoo2
|
||||
#include <yahoo2.h>
|
||||
#include <yahoo2_callbacks.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
class YahooLocalAccount;
|
||||
|
||||
class YahooHandler {
|
||||
public:
|
||||
YahooHandler(YahooLocalAccount *account, int conn_tag, int handler_tag, void *data, yahoo_input_condition cond);
|
||||
virtual ~YahooHandler();
|
||||
|
||||
void ready(std::string *buffer = NULL);
|
||||
|
||||
int handler_tag;
|
||||
int conn_tag;
|
||||
void *data;
|
||||
yahoo_input_condition cond;
|
||||
bool remove_later;
|
||||
YahooLocalAccount *account;
|
||||
};
|
||||
|
60
backends/libyahoo2/yahoolocalaccount.cpp
Normal file
60
backends/libyahoo2/yahoolocalaccount.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include "yahoolocalaccount.h"
|
||||
#include "yahoohandler.h"
|
||||
|
||||
YahooLocalAccount::YahooLocalAccount(const std::string &user, const std::string &legacyName, const std::string &password) : user(user), id(0), conn_tag(1), handler_tag(1), status(YAHOO_STATUS_OFFLINE), msg(""), buffer("") {
|
||||
id = yahoo_init_with_attributes(legacyName.c_str(), password.c_str(),
|
||||
"local_host", "",
|
||||
"pager_port", 5050,
|
||||
NULL);
|
||||
}
|
||||
|
||||
YahooLocalAccount::~YahooLocalAccount() {
|
||||
// remove handlers
|
||||
for (std::map<int, YahooHandler *>::iterator it = handlers.begin(); it != handlers.end(); it++) {
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
// remove conns
|
||||
for (std::map<int, boost::shared_ptr<Swift::Connection> >::iterator it = conns.begin(); it != conns.end(); it++) {
|
||||
it->second->onConnectFinished.disconnect_all_slots();
|
||||
it->second->onDisconnected.disconnect_all_slots();
|
||||
it->second->onDataRead.disconnect_all_slots();
|
||||
it->second->onDataWritten.disconnect_all_slots();
|
||||
}
|
||||
}
|
||||
|
||||
void YahooLocalAccount::login() {
|
||||
yahoo_login(id, YAHOO_STATUS_AVAILABLE);
|
||||
}
|
||||
|
||||
void YahooLocalAccount::addHandler(YahooHandler *handler) {
|
||||
handlers[handler->handler_tag] = handler;
|
||||
handlers_per_conn[handler->conn_tag][handler->handler_tag] = handler;
|
||||
}
|
||||
|
||||
void YahooLocalAccount::removeOldHandlers() {
|
||||
std::vector<int> handlers_to_remove;
|
||||
for (std::map<int, YahooHandler *>::iterator it = handlers.begin(); it != handlers.end(); it++) {
|
||||
if (it->second->remove_later) {
|
||||
handlers_to_remove.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(int tag, handlers_to_remove) {
|
||||
YahooHandler *handler = handlers[tag];
|
||||
handlers.erase(tag);
|
||||
handlers_per_conn[handler->conn_tag].erase(tag);
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
|
||||
void YahooLocalAccount::removeConn(int conn_tag) {
|
||||
for (std::map<int, YahooHandler *>::iterator it = handlers_per_conn[conn_tag].begin(); it != handlers_per_conn[conn_tag].end(); it++) {
|
||||
it->second->remove_later = true;
|
||||
}
|
||||
|
||||
removeOldHandlers();
|
||||
|
||||
conns.erase(conn_tag);
|
||||
}
|
56
backends/libyahoo2/yahoolocalaccount.h
Normal file
56
backends/libyahoo2/yahoolocalaccount.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Yahoo2
|
||||
#include <yahoo2.h>
|
||||
#include <yahoo2_callbacks.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLContextFactory.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
class YahooHandler;
|
||||
|
||||
class YahooLocalAccount {
|
||||
public:
|
||||
YahooLocalAccount(const std::string &user, const std::string &legacyName, const std::string &password);
|
||||
virtual ~YahooLocalAccount();
|
||||
|
||||
void login();
|
||||
|
||||
void addHandler(YahooHandler *handler);
|
||||
void removeOldHandlers();
|
||||
void removeConn(int conn_tag);
|
||||
|
||||
std::string user;
|
||||
int id;
|
||||
std::map<int, boost::shared_ptr<Swift::Connection> > conns;
|
||||
int conn_tag;
|
||||
std::map<int, YahooHandler *> handlers;
|
||||
std::map<int, std::map<int, YahooHandler *> > handlers_per_conn;
|
||||
std::map<std::string, std::string> urls;
|
||||
int handler_tag;
|
||||
int status;
|
||||
std::string msg;
|
||||
std::string buffer;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +367,7 @@ bool Skype::createDBusProxy() {
|
|||
LOG4CXX_INFO(logger, m_username << ":" << error->message);
|
||||
|
||||
if (m_counter == 15) {
|
||||
LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created");
|
||||
LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created: " << error->message);
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, error->message);
|
||||
logout();
|
||||
g_error_free(error);
|
||||
|
@ -444,7 +445,8 @@ void Skype::login() {
|
|||
gchar* argv[6] = {"skype", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0};
|
||||
|
||||
int fd;
|
||||
g_spawn_async_with_pipes(NULL,
|
||||
GError *error = NULL;
|
||||
bool spawned = g_spawn_async_with_pipes(NULL,
|
||||
argv,
|
||||
NULL /*envp*/,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
|
@ -454,9 +456,16 @@ void Skype::login() {
|
|||
&fd,
|
||||
NULL,
|
||||
&fd_output,
|
||||
NULL /*error*/);
|
||||
&error);
|
||||
|
||||
if (!spawned) {
|
||||
LOG4CXX_ERROR(logger, "Error spawning the Skype instance: " << error->message)
|
||||
np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Error spawning the Skype instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string login_data = std::string(m_username + " " + m_password + "\n");
|
||||
LOG4CXX_INFO(logger, m_username << ": Login data=" << login_data);
|
||||
LOG4CXX_INFO(logger, m_username << ": Login data=" << m_username);
|
||||
write(fd, login_data.c_str(), login_data.size());
|
||||
close(fd);
|
||||
|
||||
|
@ -469,12 +478,12 @@ void Skype::login() {
|
|||
|
||||
if (m_connection == NULL)
|
||||
{
|
||||
LOG4CXX_INFO(logger, "Creating DBus connection.");
|
||||
LOG4CXX_INFO(logger, "Creating DBUS connection.");
|
||||
GError *error = NULL;
|
||||
m_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
|
||||
if (m_connection == NULL && error != NULL)
|
||||
{
|
||||
LOG4CXX_INFO(logger, m_username << ": DBUS Error: " << error->message);
|
||||
LOG4CXX_INFO(logger, m_username << ": Creating DBUS Connection error: " << error->message);
|
||||
g_error_free(error);
|
||||
return;
|
||||
}
|
||||
|
@ -793,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]);
|
||||
|
@ -815,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);
|
||||
|
@ -823,6 +834,7 @@ static gboolean transportDataReceived(GIOChannel *source, GIOCondition condition
|
|||
}
|
||||
|
||||
static void io_destroy(gpointer data) {
|
||||
Logging::shutdownLogging();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,8 +124,8 @@ class SMSNetworkPlugin : public NetworkPlugin {
|
|||
|
||||
void handleSMSDir() {
|
||||
std::string dir = "/var/spool/sms/incoming/";
|
||||
if (config->getUnregistered().find("backend.incoming_dir") != config->getUnregistered().end()) {
|
||||
dir = config->getUnregistered().find("backend.incoming_dir")->second;
|
||||
if (CONFIG_HAS_KEY(config, "backend.incoming_dir")) {
|
||||
dir = CONFIG_STRING(config, "backend.incoming_dir");
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Checking directory " << dir << " for incoming SMS.");
|
||||
|
||||
|
|
10
backends/swiften/CMakeLists.txt
Normal file
10
backends/swiften/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_swiften_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin)
|
||||
|
302
backends/swiften/main.cpp
Normal file
302
backends/swiften/main.cpp
Normal file
|
@ -0,0 +1,302 @@
|
|||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
|
||||
// malloc_trim
|
||||
#include "malloc.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
DEFINE_LOGGER(logger, "Swiften");
|
||||
|
||||
// eventloop
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
// Plugins
|
||||
class SwiftenPlugin;
|
||||
SwiftenPlugin *np = NULL;
|
||||
|
||||
class SwiftenPlugin : public NetworkPlugin {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
|
||||
SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
|
||||
this->config = config;
|
||||
m_factories = new Swift::BoostNetworkFactories(loop);
|
||||
m_conn = m_factories->getConnectionFactory()->createConnection();
|
||||
m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1));
|
||||
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting the plugin.");
|
||||
}
|
||||
|
||||
// NetworkPlugin uses this method to send the data to networkplugin server
|
||||
void sendData(const std::string &string) {
|
||||
m_conn->write(Swift::createSafeByteArray(string));
|
||||
}
|
||||
|
||||
// This method has to call handleDataRead with all received data from network plugin server
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
std::string d(data->begin(), data->end());
|
||||
handleDataRead(d);
|
||||
}
|
||||
|
||||
void handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
|
||||
std::string message = "";
|
||||
if (error) {
|
||||
switch(error->getType()) {
|
||||
case Swift::ClientError::UnknownError: message = ("Unknown Error"); break;
|
||||
case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
|
||||
case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
|
||||
case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); break;
|
||||
case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); break;
|
||||
case Swift::ClientError::XMLError: message = ("Error parsing server data"); break;
|
||||
case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
|
||||
case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
|
||||
case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
|
||||
case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
|
||||
case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
|
||||
case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
|
||||
case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
|
||||
case Swift::ClientError::StreamError: message = ("Stream error"); break;
|
||||
case Swift::ClientError::TLSError: message = ("Encryption error"); break;
|
||||
case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
|
||||
case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
|
||||
|
||||
case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
|
||||
case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
|
||||
case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
|
||||
case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
|
||||
case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
|
||||
case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
|
||||
case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
|
||||
case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
|
||||
case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
|
||||
case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
|
||||
case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
|
||||
}
|
||||
}
|
||||
LOG4CXX_INFO(logger, user << ": Disconnected " << message);
|
||||
handleDisconnected(user, 3, message);
|
||||
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
m_users.erase(user);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleSwiftConnected(const std::string &user) {
|
||||
LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
|
||||
handleConnected(user);
|
||||
m_users[user]->requestRoster();
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setFrom(m_users[user]->getJID());
|
||||
m_users[user]->sendPresence(response);
|
||||
}
|
||||
|
||||
void handleSwiftRosterReceived(const std::string &user) {
|
||||
Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
|
||||
BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
|
||||
Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
|
||||
pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
|
||||
handleBuddyChanged(user, item.getJID().toBare().toString(),
|
||||
item.getName(), item.getGroups(), status);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
|
||||
LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
|
||||
|
||||
std::string message = presence->getStatus();
|
||||
std::string photo = "";
|
||||
|
||||
boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
|
||||
if (update) {
|
||||
photo = update->getPhotoHash();
|
||||
}
|
||||
|
||||
boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
|
||||
if (item) {
|
||||
handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
}
|
||||
else {
|
||||
std::vector<std::string> groups;
|
||||
handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
|
||||
std::string body = message->getBody();
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
handleMessage(user, message->getFrom().toBare().toString(), body, "", "");
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftVCardReceived(const std::string &user, unsigned int id, Swift::VCard::ref vcard, Swift::ErrorPayload::ref error) {
|
||||
if (error || !vcard) {
|
||||
LOG4CXX_INFO(logger, user << ": error fetching VCard with id=" << id);
|
||||
handleVCard(user, id, "", "", "", "");
|
||||
return;
|
||||
}
|
||||
LOG4CXX_INFO(logger, user << ": VCard fetched - id=" << id);
|
||||
std::string photo((const char *)&vcard->getPhoto()[0], vcard->getPhoto().size());
|
||||
handleVCard(user, id, vcard->getFullName(), vcard->getFullName(), vcard->getNickname(), photo);
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
|
||||
boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName), password, m_factories);
|
||||
m_users[user] = client;
|
||||
client->setAlwaysTrustCertificates();
|
||||
client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
Swift::ClientOptions opt;
|
||||
opt.allowPLAINWithoutTLS = true;
|
||||
client->connect(opt);
|
||||
}
|
||||
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
client->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "") {
|
||||
LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << ".");
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
boost::shared_ptr<Swift::Message> message(new Swift::Message());
|
||||
message->setTo(Swift::JID(legacyName));
|
||||
message->setFrom(client->getJID());
|
||||
message->setBody(msg);
|
||||
|
||||
client->sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
LOG4CXX_INFO(logger, user << ": fetching VCard of " << legacyName << " id=" << id);
|
||||
Swift::GetVCardRequest::ref request = Swift::GetVCardRequest::create(Swift::JID(legacyName), client->getIQRouter());
|
||||
request->onResponse.connect(boost::bind(&SwiftenPlugin::handleSwiftVCardReceived, this, user, id, _1, _2));
|
||||
request->send();
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
|
||||
// handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
Config *config;
|
||||
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
|
||||
};
|
||||
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
std::cout << "SIGCHLD handler can't be set\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
|
||||
desc.add_options()
|
||||
("host,h", value<std::string>(&host), "host")
|
||||
("port,p", value<int>(&port), "port")
|
||||
;
|
||||
try
|
||||
{
|
||||
boost::program_options::variables_map vm;
|
||||
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
|
||||
boost::program_options::notify(vm);
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (argc < 5) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Config config;
|
||||
if (!config.load(argv[5])) {
|
||||
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logging::initBackendLogging(&config);
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
loop_ = &eventLoop;
|
||||
np = new SwiftenPlugin(&config, &eventLoop, host, port);
|
||||
loop_->run();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -56,6 +56,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) {
|
||||
|
@ -63,6 +65,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) {
|
||||
|
|
103
backends/template/template_backend.py
Executable file
103
backends/template/template_backend.py
Executable file
|
@ -0,0 +1,103 @@
|
|||
#!/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()
|
|
@ -1,5 +1,8 @@
|
|||
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 )
|
||||
|
|
12
cmake_modules/yahoo2Config.cmake
Normal file
12
cmake_modules/yahoo2Config.cmake
Normal file
|
@ -0,0 +1,12 @@
|
|||
FIND_PATH(YAHOO2_INCLUDE_DIR yahoo2.h PATH_SUFFIXES libyahoo2)
|
||||
MARK_AS_ADVANCED(YAHOO2_INCLUDE_DIR)
|
||||
|
||||
FIND_LIBRARY(YAHOO2_LIBRARY yahoo2 )
|
||||
MARK_AS_ADVANCED(YAHOO2_LIBRARY)
|
||||
|
||||
if(YAHOO2_LIBRARY AND YAHOO2_INCLUDE_DIR)
|
||||
set( YAHOO2_FOUND 1 )
|
||||
message(STATUS "Found libyahoo2: ${YAHOO2_LIBRARY}, ${YAHOO2_INCLUDE_DIR}")
|
||||
else()
|
||||
message(STATUS "Could NOT find libyahoo2 library")
|
||||
endif()
|
1510
docs/Doxyfile
1510
docs/Doxyfile
File diff suppressed because it is too large
Load diff
39
include/Swiften/Parser/StringTreeParser.cpp
Normal file
39
include/Swiften/Parser/StringTreeParser.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Parser/StringTreeParser.h>
|
||||
#include <Swiften/Parser/PlatformXMLParserFactory.h>
|
||||
#include <Swiften/Parser/Tree/ParserElement.h>
|
||||
#include <Swiften/Parser/XMLParser.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
class DefaultStringTreeParser : public StringTreeParser {
|
||||
public:
|
||||
void handleTree(ParserElement::ref root) {
|
||||
root_ = root;
|
||||
}
|
||||
|
||||
ParserElement::ref getRoot() {
|
||||
return root_;
|
||||
}
|
||||
|
||||
private:
|
||||
ParserElement::ref root_;
|
||||
};
|
||||
|
||||
ParserElement::ref StringTreeParser::parse(const std::string &xml) {
|
||||
PlatformXMLParserFactory factory;
|
||||
DefaultStringTreeParser client;
|
||||
XMLParser *parser = factory.createXMLParser(&client);
|
||||
|
||||
parser->parse(xml);
|
||||
ParserElement::ref root = client.getRoot();
|
||||
delete parser;
|
||||
return root;
|
||||
}
|
||||
|
||||
}
|
56
include/Swiften/Parser/StringTreeParser.h
Normal file
56
include/Swiften/Parser/StringTreeParser.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Jan Kaluza
|
||||
* Licensed under the Simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#include <Swiften/Parser/Tree/ParserElement.h>
|
||||
#include <Swiften/Parser/XMLParserClient.h>
|
||||
|
||||
namespace Swift {
|
||||
/**
|
||||
* Generics parser offering something a bit like a DOM to work with.
|
||||
*/
|
||||
class StringTreeParser : public XMLParserClient {
|
||||
public:
|
||||
StringTreeParser() : XMLParserClient() {}
|
||||
|
||||
virtual void handleStartElement(const std::string& element, const std::string& xmlns, const AttributeMap& attributes) {
|
||||
if (!root_) {
|
||||
root_ = boost::make_shared<ParserElement>(element, xmlns, attributes);
|
||||
elementStack_.push_back(root_);
|
||||
}
|
||||
else {
|
||||
ParserElement::ref current = *elementStack_.rbegin();
|
||||
elementStack_.push_back(current->addChild(element, xmlns, attributes));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleEndElement(const std::string& /*element*/, const std::string&) {
|
||||
elementStack_.pop_back();
|
||||
if (elementStack_.empty()) {
|
||||
handleTree(root_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleCharacterData(const std::string& data) {
|
||||
ParserElement::ref current = *elementStack_.rbegin();
|
||||
current->appendCharacterData(data);
|
||||
}
|
||||
|
||||
virtual void handleTree(ParserElement::ref root) = 0;
|
||||
|
||||
static ParserElement::ref parse(const std::string &xml);
|
||||
|
||||
private:
|
||||
std::deque<ParserElement::ref> elementStack_;
|
||||
ParserElement::ref root_;
|
||||
};
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include "Swiften/Elements/Message.h"
|
||||
#include "Swiften/Elements/IQ.h"
|
||||
#include "Swiften/Elements/Presence.h"
|
||||
#include "Swiften/TLS/Certificate.h"
|
||||
|
||||
namespace Swift {
|
||||
class Error;
|
||||
|
@ -35,6 +36,10 @@ namespace Swift {
|
|||
bool isAvailable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Certificate::ref> getPeerCertificateChain() const {
|
||||
return std::vector<Certificate::ref>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string getNewIQID();
|
||||
|
|
72
include/transport/adhoccommand.h
Normal file
72
include/transport/adhoccommand.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class AdHocCommand {
|
||||
public:
|
||||
/// Creates new AdHocManager.
|
||||
|
||||
/// \param component Transport instance associated with this AdHocManager.
|
||||
AdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload) = 0;
|
||||
|
||||
void addFormField(Swift::FormField::ref field);
|
||||
|
||||
const std::string &getId() {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void refreshLastActivity() {
|
||||
m_lastActivity = time(NULL);
|
||||
}
|
||||
|
||||
time_t getLastActivity() {
|
||||
return m_lastActivity;
|
||||
}
|
||||
|
||||
protected:
|
||||
Component *m_component;
|
||||
Swift::JID m_initiator;
|
||||
Swift::JID m_to;
|
||||
std::vector<Swift::FormField::ref> m_fields;
|
||||
std::string m_id;
|
||||
|
||||
private:
|
||||
// This is used to remove AdHocCommand after long inactivity to prevent memory leaks
|
||||
// caused by users which disconnect before they finish the command.
|
||||
// AdHocManager uses this to garbage collect old AdHocCommands.
|
||||
time_t m_lastActivity;
|
||||
};
|
||||
|
||||
}
|
47
include/transport/adhoccommandfactory.h
Normal file
47
include/transport/adhoccommandfactory.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class AdHocCommandFactory {
|
||||
public:
|
||||
AdHocCommandFactory() {}
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocCommandFactory() {}
|
||||
|
||||
virtual AdHocCommand *createAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) = 0;
|
||||
|
||||
virtual std::string getNode() = 0;
|
||||
|
||||
virtual std::string getName() = 0;
|
||||
};
|
||||
|
||||
}
|
75
include/transport/adhocmanager.h
Normal file
75
include/transport/adhocmanager.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Conversation;
|
||||
class User;
|
||||
class Component;
|
||||
class DiscoItemsResponder;
|
||||
class AdHocCommandFactory;
|
||||
class AdHocCommand;
|
||||
|
||||
/// Listens for AdHoc commands and manages all AdHoc commands sessions
|
||||
class AdHocManager : public Swift::Responder<Swift::Command> {
|
||||
public:
|
||||
typedef std::map<std::string, AdHocCommand *> CommandsMap;
|
||||
typedef std::map<Swift::JID, CommandsMap> SessionsMap;
|
||||
/// Creates new AdHocManager.
|
||||
|
||||
/// \param component Transport instance associated with this AdHocManager.
|
||||
AdHocManager(Component *component, DiscoItemsResponder *discoItemsResponder);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocManager();
|
||||
|
||||
/// Starts handling AdHoc commands payloads.
|
||||
void start();
|
||||
|
||||
/// Stops handling AdHoc commands payloads and destroys all existing
|
||||
/// AdHoc commands sessions.
|
||||
void stop();
|
||||
|
||||
/// Adds factory to create new AdHoc commands sessions of particular type.
|
||||
void addAdHocCommand(AdHocCommandFactory *factory);
|
||||
|
||||
/// Remove sessions older than N seconds.
|
||||
void removeOldSessions();
|
||||
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload);
|
||||
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload);
|
||||
|
||||
Component *m_component;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
std::map<std::string, AdHocCommandFactory *> m_factories;
|
||||
SessionsMap m_sessions;
|
||||
Swift::Timer::ref m_collectTimer;
|
||||
};
|
||||
|
||||
}
|
|
@ -28,13 +28,13 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include <boost/signal.hpp>
|
||||
|
||||
|
||||
#define CONFIG_HAS_KEY(PTR, KEY) (*PTR).hasKey(KEY)
|
||||
#define CONFIG_STRING(PTR, KEY) (*PTR)[KEY].as<std::string>()
|
||||
#define CONFIG_INT(PTR, KEY) (*PTR)[KEY].as<int>()
|
||||
#define CONFIG_BOOL(PTR, KEY) (*PTR)[KEY].as<bool>()
|
||||
#define CONFIG_LIST(PTR, KEY) (*PTR)[KEY].as<std::list<std::string> >()
|
||||
#define CONFIG_VECTOR(PTR, KEY) (*PTR)[KEY].as<std::vector<std::string> >()
|
||||
#define CONFIG_HAS_KEY(PTR, KEY) (*PTR).hasKey(KEY)
|
||||
#define CONFIG_VECTOR(PTR, KEY) ((*PTR).hasKey(KEY) ? (*PTR)[KEY].as<std::vector<std::string> >() : std::vector<std::string>())
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
|
@ -50,7 +50,7 @@ typedef boost::program_options::variables_map Variables;
|
|||
class Config {
|
||||
public:
|
||||
/// Constructor.
|
||||
Config() {}
|
||||
Config(int argc = 0, char **argv = NULL) : m_argc(argc), m_argv(argv) {}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Config() {}
|
||||
|
@ -77,7 +77,7 @@ class Config {
|
|||
bool reload();
|
||||
|
||||
bool hasKey(const std::string &key) {
|
||||
return m_variables.find(key) != m_variables.end();
|
||||
return m_variables.find(key) != m_variables.end() || m_unregistered.find(key) != m_unregistered.end();
|
||||
}
|
||||
|
||||
/// Returns value of variable defined by key.
|
||||
|
@ -85,22 +85,23 @@ class Config {
|
|||
/// For variables in sections you can use "section.variable" key format.
|
||||
/// \param key config variable name
|
||||
const boost::program_options::variable_value &operator[] (const std::string &key) {
|
||||
return m_variables[key];
|
||||
if (m_variables.find(key) != m_variables.end()) {
|
||||
return m_variables[key];
|
||||
}
|
||||
return m_unregistered[key];
|
||||
}
|
||||
|
||||
/// Returns path to config file from which data were loaded.
|
||||
const std::string &getConfigFile() { return m_file; }
|
||||
|
||||
const std::map<std::string, std::string> &getUnregistered() {
|
||||
return m_unregistered;
|
||||
}
|
||||
|
||||
/// This signal is emitted when config is loaded/reloaded.
|
||||
boost::signal<void ()> onConfigReloaded;
|
||||
|
||||
private:
|
||||
int m_argc;
|
||||
char **m_argv;
|
||||
Variables m_variables;
|
||||
std::map<std::string, std::string> m_unregistered;
|
||||
std::map<std::string, boost::program_options::variable_value> m_unregistered;
|
||||
std::string m_file;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,14 +27,22 @@
|
|||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class DiscoItemsResponder : public Swift::GetResponder<Swift::DiscoItems> {
|
||||
public:
|
||||
DiscoItemsResponder(Swift::IQRouter *router);
|
||||
DiscoItemsResponder(Component *component);
|
||||
~DiscoItemsResponder();
|
||||
|
||||
void addAdHocCommand(const std::string &node, const std::string &name);
|
||||
// void removeAdHocCommand(const std::string &node);
|
||||
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoItems> payload);
|
||||
|
||||
Component *m_component;
|
||||
boost::shared_ptr<Swift::DiscoItems> m_commands;
|
||||
};
|
||||
|
||||
}
|
|
@ -51,10 +51,15 @@ class LocalBuddy : public Buddy {
|
|||
}
|
||||
|
||||
std::string getIconHash() { return m_iconHash; }
|
||||
void setIconHash(const std::string &iconHash) { m_iconHash = iconHash; }
|
||||
void setIconHash(const std::string &iconHash) {
|
||||
bool changed = m_iconHash != iconHash;
|
||||
m_iconHash = iconHash;
|
||||
if (changed)
|
||||
getRosterManager()->storeBuddy(this);
|
||||
}
|
||||
|
||||
std::vector<std::string> getGroups() { return m_groups; }
|
||||
void setGroups(const std::vector<std::string> &groups) { m_groups = groups; }
|
||||
void setGroups(const std::vector<std::string> &groups);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
@ -57,6 +75,11 @@ class NetworkPlugin {
|
|||
bool blocked = false
|
||||
);
|
||||
|
||||
/// Call this method when buddy is removed from legacy network contact list.
|
||||
/// \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")
|
||||
void handleBuddyRemoved(const std::string &user, const std::string &buddyName);
|
||||
|
||||
/// Call this function when participant in room 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 nickname Nickname of participant. If participant renamed, this is old name of participant. (eg. "HanzZ")
|
||||
|
|
|
@ -89,6 +89,7 @@ class NetworkPluginServer {
|
|||
void handleConnectedPayload(const std::string &payload);
|
||||
void handleDisconnectedPayload(const std::string &payload);
|
||||
void handleBuddyChangedPayload(const std::string &payload);
|
||||
void handleBuddyRemovedPayload(const std::string &payload);
|
||||
void handleConvMessagePayload(const std::string &payload, bool subject = false);
|
||||
void handleParticipantChangedPayload(const std::string &payload);
|
||||
void handleRoomChangedPayload(const std::string &payload);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -69,6 +69,10 @@ class RosterManager {
|
|||
/// \param buddy Buddy.
|
||||
void unsetBuddy(Buddy *buddy);
|
||||
|
||||
/// Removes buddy from this roster, sends proper XML to XMPP side and deletes it.
|
||||
/// \param name Buddy name.
|
||||
void removeBuddy(const std::string &name);
|
||||
|
||||
Buddy *getBuddy(const std::string &name);
|
||||
|
||||
void setStorageBackend(StorageBackend *storageBackend);
|
||||
|
@ -107,7 +111,11 @@ class RosterManager {
|
|||
|
||||
void sendBuddyRosterPush(Buddy *buddy);
|
||||
|
||||
void sendBuddyRosterRemove(Buddy *buddy);
|
||||
|
||||
void sendBuddySubscribePresence(Buddy *buddy);
|
||||
|
||||
void sendBuddyUnsubscribePresence(Buddy *buddy);
|
||||
|
||||
void sendCurrentPresences(const Swift::JID &to);
|
||||
|
||||
|
|
70
include/transport/settingsadhoccommand.h
Normal file
70
include/transport/settingsadhoccommand.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class SettingsAdHocCommand : public AdHocCommand {
|
||||
public:
|
||||
typedef enum { Init, WaitingForResponse } State;
|
||||
|
||||
SettingsAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~SettingsAdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Swift::Command> getForm();
|
||||
boost::shared_ptr<Swift::Command> handleResponse(boost::shared_ptr<Swift::Command> payload);
|
||||
State m_state;
|
||||
};
|
||||
|
||||
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
|
||||
public:
|
||||
SettingsAdHocCommandFactory() {}
|
||||
virtual ~SettingsAdHocCommandFactory() {}
|
||||
|
||||
AdHocCommand *createAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
return new SettingsAdHocCommand(component, initiator, to);
|
||||
}
|
||||
|
||||
std::string getNode() {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return "Transport settings";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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,
|
||||
|
@ -47,7 +48,6 @@ namespace Transport {
|
|||
//
|
||||
class StorageBackend;
|
||||
class DiscoInfoResponder;
|
||||
class DiscoItemsResponder;
|
||||
class Factory;
|
||||
class UserRegistry;
|
||||
|
||||
|
@ -165,6 +165,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);
|
||||
|
@ -186,7 +187,6 @@ namespace Transport {
|
|||
Transport::UserRegistry *m_userRegistry;
|
||||
StorageBackend *m_storageBackend;
|
||||
DiscoInfoResponder *m_discoInfoResponder;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
int m_reconnectCount;
|
||||
Config* m_config;
|
||||
std::string m_protocol;
|
||||
|
|
166
munin/spectrum2_
Executable file
166
munin/spectrum2_
Executable file
|
@ -0,0 +1,166 @@
|
|||
#!/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);
|
||||
}
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#ifndef WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <stdint.h>
|
||||
|
@ -60,6 +62,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);
|
||||
|
@ -144,6 +165,19 @@ void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::strin
|
|||
send(message);
|
||||
}
|
||||
|
||||
void NetworkPlugin::handleBuddyRemoved(const std::string &user, const std::string &buddyName) {
|
||||
pbnetwork::Buddy buddy;
|
||||
buddy.set_username(user);
|
||||
buddy.set_buddyname(buddyName);
|
||||
|
||||
std::string message;
|
||||
buddy.SerializeToString(&message);
|
||||
|
||||
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_REMOVED);
|
||||
|
||||
send(message);
|
||||
}
|
||||
|
||||
void NetworkPlugin::handleBuddyTyping(const std::string &user, const std::string &buddyName) {
|
||||
pbnetwork::Buddy buddy;
|
||||
buddy.set_username(user);
|
||||
|
|
|
@ -2,12 +2,14 @@ cmake_minimum_required(VERSION 2.6)
|
|||
|
||||
if (PROTOBUF_FOUND)
|
||||
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_BINARY_DIR}/../../include/transport/ ${CMAKE_CURRENT_BINARY_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_BINARY_DIR}/../../include/transport/protocol.proto
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
)
|
||||
ADD_CUSTOM_TARGET(pb-python DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/protocol_pb2.py)
|
||||
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
524
plugin/python/NetworkPlugin.py
Normal file
524
plugin/python/NetworkPlugin.py
Normal file
|
@ -0,0 +1,524 @@
|
|||
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
|
||||
|
|
@ -14,6 +14,9 @@
|
|||
#include "transport/util.h"
|
||||
#include "transport/gatewayresponder.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/discoitemsresponder.h"
|
||||
#include "transport/adhocmanager.h"
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -114,7 +117,7 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Config config;
|
||||
Config config(argc, argv);
|
||||
|
||||
boost::program_options::variables_map vm;
|
||||
bool no_daemon = false;
|
||||
|
@ -147,7 +150,7 @@ int main(int argc, char **argv)
|
|||
boost::program_options::positional_options_description p;
|
||||
p.add("config", -1);
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run(), vm);
|
||||
options(desc).positional(p).allow_unregistered().run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
if (vm.count("version")) {
|
||||
|
@ -313,6 +316,15 @@ int main(int argc, char **argv)
|
|||
GatewayResponder gatewayResponder(transport.getIQRouter(), &userManager);
|
||||
gatewayResponder.start();
|
||||
|
||||
DiscoItemsResponder discoItemsResponder(&transport);
|
||||
discoItemsResponder.start();
|
||||
|
||||
AdHocManager adhocmanager(&transport, &discoItemsResponder);
|
||||
adhocmanager.start();
|
||||
|
||||
SettingsAdHocCommandFactory settings;
|
||||
adhocmanager.addAdHocCommand(&settings);
|
||||
|
||||
eventLoop_ = &eventLoop;
|
||||
|
||||
eventLoop.run();
|
||||
|
|
|
@ -8,15 +8,15 @@ backend_host=localhost
|
|||
pidfile=./test.pid
|
||||
# < this option doesn't work yet
|
||||
#backend_port=10001
|
||||
admin_jid=admin@localhost
|
||||
#admin_jid=admin@localhost
|
||||
admin_password=test
|
||||
#cert=server.pfx #patch to PKCS#12 certificate
|
||||
#cert_password=test #password to that certificate if any
|
||||
users_per_backend=10
|
||||
#backend=../..//backends/libpurple/spectrum2_libpurple_backend
|
||||
backend=../../backends/template/spectrum2_template_backend
|
||||
protocol=prpl-xmpp
|
||||
#protocol=prpl-msn
|
||||
backend=../..//backends/libyahoo2/spectrum2_libyahoo2_backend
|
||||
#backend=../../backends/template/template_backend.py
|
||||
#protocol=prpl-jabber
|
||||
protocol=prpl-msn
|
||||
#protocol=any
|
||||
#protocol=prpl-icq
|
||||
working_dir=./
|
||||
|
|
|
@ -308,14 +308,16 @@ static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactorie
|
|||
Config cfg;
|
||||
if (cfg.load(itr->path().string()) == false) {
|
||||
std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
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";
|
||||
continue;
|
||||
}
|
||||
|
||||
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")));
|
||||
|
|
|
@ -68,6 +68,10 @@ class ManagerConfig {
|
|||
return m_variables[key];
|
||||
}
|
||||
|
||||
bool hasKey(const std::string &key) {
|
||||
return m_variables.find(key) != m_variables.end();
|
||||
}
|
||||
|
||||
/// Returns path to config file from which data were loaded.
|
||||
const std::string &getManagerConfigFile() { return m_file; }
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
|||
endif()
|
||||
|
||||
if (WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else (WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
|
||||
TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY})
|
||||
endif(WIN32)
|
||||
|
||||
SET_TARGET_PROPERTIES(transport PROPERTIES
|
||||
|
|
52
src/adhoccommand.cpp
Normal file
52
src/adhoccommand.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "AdHocCommand");
|
||||
|
||||
AdHocCommand::AdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
m_component = component;
|
||||
m_initiator = initiator;
|
||||
m_to = to;
|
||||
|
||||
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
|
||||
for (int i = 0; i < 32; i++) {
|
||||
m_id += bucket[rand() % bucket.size()];
|
||||
}
|
||||
}
|
||||
|
||||
AdHocCommand::~AdHocCommand() {
|
||||
}
|
||||
|
||||
void AdHocCommand::addFormField(Swift::FormField::ref field) {
|
||||
m_fields.push_back(field);
|
||||
}
|
||||
|
||||
}
|
163
src/adhocmanager.cpp
Normal file
163
src/adhocmanager.cpp
Normal file
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/adhocmanager.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include "transport/discoitemsresponder.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "AdHocManager");
|
||||
|
||||
AdHocManager::AdHocManager(Component *component, DiscoItemsResponder *discoItemsResponder) : Swift::Responder<Swift::Command>(component->getIQRouter()){
|
||||
m_component = component;
|
||||
m_discoItemsResponder = discoItemsResponder;
|
||||
|
||||
m_collectTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(20);
|
||||
m_collectTimer->onTick.connect(boost::bind(&AdHocManager::removeOldSessions, this));
|
||||
m_collectTimer->start();
|
||||
}
|
||||
|
||||
AdHocManager::~AdHocManager() {
|
||||
m_collectTimer->stop();
|
||||
stop();
|
||||
}
|
||||
|
||||
void AdHocManager::start() {
|
||||
Swift::Responder<Swift::Command>::start();
|
||||
}
|
||||
|
||||
void AdHocManager::stop() {
|
||||
Swift::Responder<Swift::Command>::stop();
|
||||
|
||||
for (SessionsMap::iterator it = m_sessions.begin(); it != m_sessions.end(); it++) {
|
||||
std::vector<std::string> candidates;
|
||||
for (CommandsMap::iterator ct = it->second.begin(); ct != it->second.end(); ct++) {
|
||||
delete ct->second;
|
||||
}
|
||||
}
|
||||
|
||||
m_sessions.clear();
|
||||
}
|
||||
|
||||
void AdHocManager::addAdHocCommand(AdHocCommandFactory *factory) {
|
||||
if (m_factories.find(factory->getNode()) != m_factories.end()) {
|
||||
LOG4CXX_ERROR(logger, "Command with node " << factory->getNode() << " is already registered. Ignoring this attempt.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_factories[factory->getNode()] = factory;
|
||||
m_discoItemsResponder->addAdHocCommand(factory->getNode(), factory->getName());
|
||||
}
|
||||
|
||||
void AdHocManager::removeOldSessions() {
|
||||
unsigned long removedCommands = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::vector<std::string> toRemove;
|
||||
for (SessionsMap::iterator it = m_sessions.begin(); it != m_sessions.end(); it++) {
|
||||
std::vector<std::string> candidates;
|
||||
for (CommandsMap::iterator ct = it->second.begin(); ct != it->second.end(); ct++) {
|
||||
if (now - ct->second->getLastActivity() > 15*60) {
|
||||
candidates.push_back(it->first);
|
||||
delete ct->second;
|
||||
removedCommands++;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string &key, candidates) {
|
||||
it->second.erase(key);
|
||||
}
|
||||
|
||||
if (it->second.empty()) {
|
||||
toRemove.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string &key, toRemove) {
|
||||
m_sessions.erase(key);
|
||||
}
|
||||
|
||||
if (removedCommands > 0) {
|
||||
LOG4CXX_INFO(logger, "Removed " << removedCommands << " old commands sessions.");
|
||||
}
|
||||
}
|
||||
|
||||
bool AdHocManager::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdHocManager::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload) {
|
||||
AdHocCommand *command = NULL;
|
||||
// Try to find AdHocCommand according to 'from' and session_id
|
||||
if (m_sessions.find(from) != m_sessions.end() && m_sessions[from].find(payload->getSessionID()) != m_sessions[from].end()) {
|
||||
command = m_sessions[from][payload->getSessionID()];
|
||||
}
|
||||
// Check if we can create command with this node
|
||||
else if (m_factories.find(payload->getNode()) != m_factories.end()) {
|
||||
command = m_factories[payload->getNode()]->createAdHocCommand(m_component, from, to);
|
||||
m_sessions[from][command->getId()] = command;
|
||||
LOG4CXX_INFO(logger, from.toString() << ": Started new AdHoc command session with node " << payload->getNode());
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, from.toString() << ": Unknown node " << payload->getNode() << ". Can't start AdHoc command session.");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!command) {
|
||||
LOG4CXX_ERROR(logger, from.toString() << ": createAdHocCommand for node " << payload->getNode() << " returned NULL pointer");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response = command->handleRequest(payload);
|
||||
if (!response) {
|
||||
LOG4CXX_ERROR(logger, from.toString() << ": handleRequest for node " << payload->getNode() << " returned NULL pointer");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
response->setSessionID(command->getId());
|
||||
|
||||
sendResponse(from, id, response);
|
||||
|
||||
command->refreshLastActivity();
|
||||
|
||||
// Command completed, so we can remove it now
|
||||
if (response->getStatus() == Swift::Command::Completed) {
|
||||
m_sessions[from].erase(command->getId());
|
||||
if (m_sessions[from].empty()) {
|
||||
m_sessions.erase(from);
|
||||
}
|
||||
delete command;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
|
|
|
@ -148,7 +148,6 @@ void Buddy::handleBuddyChanged() {
|
|||
if (presence) {
|
||||
m_rosterManager->getUser()->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
m_rosterManager->handleBuddyChanged(this);
|
||||
}
|
||||
|
||||
void Buddy::handleVCardReceived(const std::string &id, Swift::VCard::ref vcard) {
|
||||
|
|
|
@ -27,10 +27,16 @@
|
|||
#define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
|
||||
#include "iostream"
|
||||
#include "boost/version.hpp"
|
||||
|
||||
#define BOOST_MAJOR_VERSION BOOST_VERSION / 100000
|
||||
#define BOOST_MINOR_VERSION BOOST_VERSION / 100 % 1000
|
||||
|
||||
using namespace boost::program_options;
|
||||
|
||||
namespace Transport {
|
||||
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;
|
||||
|
@ -70,14 +76,14 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("service.protocol", value<std::string>()->default_value(""), "Protocol")
|
||||
("service.pidfile", value<std::string>()->default_value("/var/run/spectrum2/$jid.pid"), "Full path to pid file")
|
||||
("service.working_dir", value<std::string>()->default_value("/var/lib/spectrum2/$jid"), "Working dir")
|
||||
("service.allowed_servers", value<std::string>()->default_value(""), "Only users from these servers can connect")
|
||||
("service.allowed_servers", value<std::vector<std::string> >()->multitoken(), "Only users from these servers can connect")
|
||||
("service.server_mode", value<bool>()->default_value(false), "True if Spectrum should behave as server")
|
||||
("service.users_per_backend", value<int>()->default_value(100), "Number of users per one legacy network backend")
|
||||
("service.backend_host", value<std::string>()->default_value("localhost"), "Host to bind backend server to")
|
||||
("service.backend_port", value<std::string>()->default_value("0"), "Port to bind backend server to")
|
||||
("service.cert", value<std::string>()->default_value(""), "PKCS#12 Certificate.")
|
||||
("service.cert_password", value<std::string>()->default_value(""), "PKCS#12 Certificate password.")
|
||||
("service.admin_jid", value<std::string>()->default_value(""), "Administrator jid.")
|
||||
("service.admin_jid", value<std::vector<std::string> >()->multitoken(), "Administrator jid.")
|
||||
("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
|
||||
("service.reuse_old_backends", value<bool>()->default_value(true), "True if Spectrum should use old backends which were full in the past.")
|
||||
("service.idle_reconnect_time", value<int>()->default_value(0), "Time in seconds after which idle users are reconnected to let their backend die.")
|
||||
|
@ -99,6 +105,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.")
|
||||
|
@ -114,6 +122,13 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("backend.no_vcard_fetch", value<bool>()->default_value(false), "True if VCards for buddies should not be fetched. Only avatars will be forwarded.")
|
||||
;
|
||||
|
||||
// Load configs passed by command line
|
||||
if (m_argc != 0 && m_argv) {
|
||||
basic_command_line_parser<char> parser = command_line_parser(m_argc, m_argv).options(opts).allow_unregistered();
|
||||
parsed_options parsed = parser.run();
|
||||
store(parsed, m_variables);
|
||||
}
|
||||
|
||||
parsed_options parsed = parse_config_file(ifs, opts, true);
|
||||
|
||||
bool found_working = false;
|
||||
|
@ -172,7 +187,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
|
||||
BOOST_FOREACH(option &opt, parsed.options) {
|
||||
if (opt.unregistered) {
|
||||
m_unregistered[opt.string_key] = opt.value[0];
|
||||
m_unregistered[opt.string_key] = variable_value(opt.value[0], false);
|
||||
}
|
||||
else if (opt.value[0].find("$jid") != std::string::npos) {
|
||||
boost::replace_all(opt.value[0], "$jid", jid);
|
||||
|
@ -193,8 +208,17 @@ bool Config::load(std::istream &ifs) {
|
|||
}
|
||||
|
||||
bool Config::load(const std::string &configfile, const std::string &jid) {
|
||||
options_description opts("Transport options");
|
||||
return load(configfile, opts, jid);
|
||||
try {
|
||||
options_description opts("Transport options");
|
||||
return load(configfile, opts, jid);
|
||||
} catch ( const boost::program_options::multiple_occurrences& e ) {
|
||||
#if (BOOST_MAJOR_VERSION >= 1 && BOOST_MINOR_VERSION >= 42)
|
||||
std::cerr << configfile << " parsing error: " << e.what() << " from option: " << e.get_option_name() << std::endl;
|
||||
#else
|
||||
std::cerr << configfile << " parsing error: " << e.what() << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Config::reload() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -18,32 +18,45 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "discoitemsresponder.h"
|
||||
#include "transport/discoitemsresponder.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/bind.hpp>
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/DiscoItems.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DiscoItemsResponder::DiscoItemsResponder(Swift::IQRouter *router) : Swift::GetResponder<DiscoItems>(router) {
|
||||
DEFINE_LOGGER(logger, "DiscoItemsResponder");
|
||||
|
||||
DiscoItemsResponder::DiscoItemsResponder(Component *component) : Swift::GetResponder<DiscoItems>(component->getIQRouter()) {
|
||||
m_component = component;
|
||||
m_commands = boost::shared_ptr<DiscoItems>(new DiscoItems());
|
||||
m_commands->setNode("http://jabber.org/protocol/commands");
|
||||
}
|
||||
|
||||
DiscoItemsResponder::~DiscoItemsResponder() {
|
||||
|
||||
}
|
||||
|
||||
void DiscoItemsResponder::addAdHocCommand(const std::string &node, const std::string &name) {
|
||||
m_commands->addItem(DiscoItems::Item(name, m_component->getJID(), node));
|
||||
}
|
||||
|
||||
|
||||
bool DiscoItemsResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoItems> info) {
|
||||
// presence for transport
|
||||
if (to.getNode().empty()) {
|
||||
LOG4CXX_INFO(logger, "get request received with node " << info->getNode());
|
||||
if (info->getNode() == "http://jabber.org/protocol/commands") {
|
||||
sendResponse(from, id, m_commands);
|
||||
}
|
||||
else if (to.getNode().empty()) {
|
||||
sendResponse(from, id, boost::shared_ptr<DiscoItems>(new DiscoItems()));
|
||||
}
|
||||
// presence for buddy
|
||||
else {
|
||||
sendResponse(from, id, boost::shared_ptr<DiscoItems>(new DiscoItems()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -163,9 +163,14 @@ static unsigned long exec_(std::string path, const char *host, const char *port,
|
|||
if ( pid == 0 ) {
|
||||
setsid();
|
||||
// child process
|
||||
exit(execv(argv[0], argv));
|
||||
errno = 0;
|
||||
int ret = execv(argv[0], argv);
|
||||
if (ret == -1) {
|
||||
exit(errno);
|
||||
}
|
||||
exit(0);
|
||||
} else if ( pid < 0 ) {
|
||||
// fork failed
|
||||
LOG4CXX_ERROR(logger, "Fork failed");
|
||||
}
|
||||
free(p);
|
||||
|
||||
|
@ -258,12 +263,30 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
|
|||
|
||||
LOG4CXX_INFO(logger, "Listening on host " << CONFIG_STRING(m_config, "service.backend_host") << " port " << CONFIG_STRING(m_config, "service.backend_port"));
|
||||
|
||||
unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
|
||||
LOG4CXX_INFO(logger, "Tried to spawn first backend with pid " << pid);
|
||||
LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
|
||||
|
||||
#ifndef _WIN32
|
||||
// wait if the backend process will still be alive after 1 second
|
||||
sleep(1);
|
||||
pid_t result;
|
||||
int status;
|
||||
result = waitpid(-1, &status, WNOHANG);
|
||||
if (result != 0) {
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) != 0) {
|
||||
LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status) << ", possible error: " << strerror(WEXITSTATUS(status)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG4CXX_ERROR(logger, "Backend can not be started");
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGCHLD, SigCatcher);
|
||||
#endif
|
||||
|
||||
exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str());
|
||||
LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
|
||||
}
|
||||
|
||||
NetworkPluginServer::~NetworkPluginServer() {
|
||||
|
@ -487,8 +510,6 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) {
|
|||
if (!user)
|
||||
return;
|
||||
|
||||
LOG4CXX_INFO(logger, "HANDLE BUDDY CHANGED " << payload.buddyname() << "-" << payload.alias());
|
||||
|
||||
LocalBuddy *buddy = (LocalBuddy *) user->getRosterManager()->getBuddy(payload.buddyname());
|
||||
if (buddy) {
|
||||
handleBuddyPayload(buddy, payload);
|
||||
|
@ -502,6 +523,20 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) {
|
|||
}
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleBuddyRemovedPayload(const std::string &data) {
|
||||
pbnetwork::Buddy payload;
|
||||
if (payload.ParseFromString(data) == false) {
|
||||
// TODO: ERROR
|
||||
return;
|
||||
}
|
||||
|
||||
User *user = m_userManager->getUser(payload.username());
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
user->getRosterManager()->removeBuddy(payload.buddyname());
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleParticipantChangedPayload(const std::string &data) {
|
||||
pbnetwork::Participant payload;
|
||||
if (payload.ParseFromString(data) == false) {
|
||||
|
@ -806,6 +841,9 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::Sa
|
|||
case pbnetwork::WrapperMessage_Type_TYPE_FT_DATA:
|
||||
handleFTDataPayload(c, wrapper.payload());
|
||||
break;
|
||||
case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_REMOVED:
|
||||
handleBuddyRemovedPayload(wrapper.payload());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,46 @@ void RosterManager::setBuddy(Buddy *buddy) {
|
|||
setBuddyCallback(buddy);
|
||||
}
|
||||
|
||||
void RosterManager::removeBuddy(const std::string &name) {
|
||||
Buddy *buddy = getBuddy(name);
|
||||
if (!buddy) {
|
||||
LOG4CXX_WARN(logger, m_user->getJID().toString() << ": Tried to remove unknown buddy " << name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_component->inServerMode() || m_remoteRosterRequest) {
|
||||
sendBuddyRosterRemove(buddy);
|
||||
}
|
||||
else {
|
||||
sendBuddyUnsubscribePresence(buddy);
|
||||
}
|
||||
|
||||
unsetBuddy(buddy);
|
||||
delete buddy;
|
||||
}
|
||||
|
||||
void RosterManager::sendBuddyRosterRemove(Buddy *buddy) {
|
||||
Swift::RosterPayload::ref p = Swift::RosterPayload::ref(new Swift::RosterPayload());
|
||||
Swift::RosterItemPayload item;
|
||||
item.setJID(buddy->getJID().toBare());
|
||||
item.setSubscription(Swift::RosterItemPayload::Remove);
|
||||
|
||||
p->addItem(item);
|
||||
|
||||
// In server mode we have to send pushes to all resources, but in gateway-mode we send it only to bare JID
|
||||
if (m_component->inServerMode()) {
|
||||
std::vector<Swift::Presence::ref> presences = m_component->getPresenceOracle()->getAllPresence(m_user->getJID().toBare());
|
||||
BOOST_FOREACH(Swift::Presence::ref presence, presences) {
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, presence->getFrom(), m_component->getIQRouter());
|
||||
request->send();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, m_user->getJID().toBare(), m_component->getIQRouter());
|
||||
request->send();
|
||||
}
|
||||
}
|
||||
|
||||
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
|
||||
// user can't receive anything in server mode if he's not logged in.
|
||||
// He will ask for roster later (handled in rosterreponsder.cpp)
|
||||
|
@ -142,6 +182,20 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
|
|||
}
|
||||
}
|
||||
|
||||
void RosterManager::sendBuddyUnsubscribePresence(Buddy *buddy) {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(m_user->getJID());
|
||||
response->setFrom(buddy->getJID());
|
||||
response->setType(Swift::Presence::Unsubscribe);
|
||||
m_component->getStanzaChannel()->sendPresence(response);
|
||||
|
||||
response = Swift::Presence::create();
|
||||
response->setTo(m_user->getJID());
|
||||
response->setFrom(buddy->getJID());
|
||||
response->setType(Swift::Presence::Unsubscribed);
|
||||
m_component->getStanzaChannel()->sendPresence(response);
|
||||
}
|
||||
|
||||
void RosterManager::sendBuddySubscribePresence(Buddy *buddy) {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(m_user->getJID());
|
||||
|
@ -152,9 +206,6 @@ void RosterManager::sendBuddySubscribePresence(Buddy *buddy) {
|
|||
}
|
||||
|
||||
void RosterManager::handleBuddyChanged(Buddy *buddy) {
|
||||
if (m_rosterStorage) {
|
||||
m_rosterStorage->storeBuddy(buddy);
|
||||
}
|
||||
}
|
||||
|
||||
void RosterManager::setBuddyCallback(Buddy *buddy) {
|
||||
|
@ -235,7 +286,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;
|
||||
|
@ -243,6 +297,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);
|
||||
|
@ -294,6 +349,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()) {
|
||||
|
|
|
@ -86,6 +86,13 @@ RosterStorage::~RosterStorage() {
|
|||
}
|
||||
|
||||
void RosterStorage::storeBuddy(Buddy *buddy) {
|
||||
if (!buddy) {
|
||||
return;
|
||||
}
|
||||
if (buddy->getName().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_buddies[buddy->getName()] = buddy;
|
||||
m_storageTimer->start();
|
||||
}
|
||||
|
@ -129,6 +136,7 @@ bool RosterStorage::storeBuddies() {
|
|||
// }
|
||||
}
|
||||
|
||||
m_buddies.clear();
|
||||
m_storageBackend->commitTransaction();
|
||||
return true;
|
||||
}
|
||||
|
|
79
src/settingsadhoccommand.cpp
Normal file
79
src/settingsadhoccommand.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
|
||||
|
||||
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, initiator, to) {
|
||||
m_state = Init;
|
||||
}
|
||||
|
||||
SettingsAdHocCommand::~SettingsAdHocCommand() {
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::getForm() {
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
|
||||
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
|
||||
form->addField(field);
|
||||
}
|
||||
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> payload) {
|
||||
|
||||
|
||||
|
||||
boost::shared_ptr<Swift::Command> response;
|
||||
response->setStatus(Swift::Command::Completed);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
|
||||
boost::shared_ptr<Swift::Command> response;
|
||||
|
||||
switch (m_state) {
|
||||
case Init:
|
||||
response = getForm();
|
||||
m_state = WaitingForResponse;
|
||||
break;
|
||||
case WaitingForResponse:
|
||||
response = handleResponse(payload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
|
@ -199,7 +199,11 @@ bool SQLite3Backend::exec(const std::string &query) {
|
|||
char *errMsg = 0;
|
||||
int rc = sqlite3_exec(m_db, query.c_str(), NULL, 0, &errMsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
LOG4CXX_ERROR(logger, errMsg << " during statement " << query);
|
||||
// This error is OK, because we try to create buddies table every time
|
||||
// to detect if DB is created properly.
|
||||
if (errMsg != "table buddies already exists") {
|
||||
LOG4CXX_ERROR(logger, errMsg << " during statement " << query);
|
||||
}
|
||||
sqlite3_free(errMsg);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "transport/userregistry.h"
|
||||
#include "transport/logging.h"
|
||||
#include "discoinforesponder.h"
|
||||
#include "discoitemsresponder.h"
|
||||
#include "storageparser.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
|
||||
#include "Swiften/TLS/PKCS12Certificate.h"
|
||||
|
@ -149,9 +148,6 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
|
|||
m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter, m_config);
|
||||
m_discoInfoResponder->start();
|
||||
|
||||
m_discoItemsResponder = new DiscoItemsResponder(m_iqRouter);
|
||||
m_discoItemsResponder->start();
|
||||
|
||||
//
|
||||
// m_registerHandler = new SpectrumRegisterHandler(m_component);
|
||||
// m_registerHandler->start();
|
||||
|
@ -163,7 +159,6 @@ Component::~Component() {
|
|||
delete m_capsManager;
|
||||
delete m_capsMemoryStorage;
|
||||
delete m_discoInfoResponder;
|
||||
delete m_discoItemsResponder;
|
||||
if (m_component)
|
||||
delete m_component;
|
||||
if (m_server) {
|
||||
|
@ -196,6 +191,9 @@ void Component::setBuddyFeatures(std::list<std::string> &features) {
|
|||
void Component::start() {
|
||||
if (m_component && !m_component->isAvailable()) {
|
||||
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
|
||||
if (CONFIG_INT(m_config, "service.port") == 5222) {
|
||||
LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
|
||||
}
|
||||
m_reconnectCount++;
|
||||
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
m_reconnectTimer->stop();
|
||||
|
@ -203,6 +201,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();
|
||||
}
|
||||
|
@ -226,6 +229,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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
@ -189,7 +189,7 @@ bool UserRegistration::handleGetRequest(const Swift::JID& from, const Swift::JID
|
|||
reg->setRegistered(registered);
|
||||
reg->setUsername(res.uin);
|
||||
if (CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour")
|
||||
reg->setPassword(res.password);
|
||||
reg->setPassword("");
|
||||
|
||||
|
||||
// form
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++);
|
||||
|
|
Loading…
Add table
Reference in a new issue