Pass command the same command line options as we have in main instance to backend instances

This commit is contained in:
Jan Kaluza 2012-09-04 10:28:11 +02:00
parent c2cdd3702f
commit ad7461beec
14 changed files with 358 additions and 282 deletions

View file

@ -339,46 +339,48 @@ int main (int argc, char* argv[]) {
return -1;
}
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
// QStringList channels;
// for (int i = 3; i < argc; ++i)
// {
// channels.append(argv[i]);
// }
//
// MyIrcSession session;
// session.setNick(argv[2]);
// session.setAutoJoinChannels(channels);
// session.connectToServer(argv[1], 6667);
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -28,47 +28,48 @@ int main (int argc, char* argv[]) {
int port;
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
qDebug("Usage: %s <config>", argv[0]);
return 1;
}
// QStringList channels;
// for (int i = 3; i < argc; ++i)
// {
// channels.append(argv[i]);
// }
//
// MyIrcSession session;
// session.setNick(argv[2]);
// session.setAutoJoinChannels(channels);
// session.connectToServer(argv[1], 6667);
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -15,6 +15,7 @@
#include "malloc.h"
#include <algorithm>
#include "errno.h"
#include <boost/make_shared.hpp>
#ifdef WITH_LIBEVENT
#include <event.h>
@ -69,48 +70,10 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
class SpectrumNetworkPlugin;
GKeyFile *keyfile;
boost::shared_ptr<Config> config;
SpectrumNetworkPlugin *np;
static std::string replaceAll(
std::string result,
const std::string& replaceWhat,
const std::string& replaceWithWhat)
{
while(1)
{
const int pos = result.find(replaceWhat);
if (pos==-1) break;
result.replace(pos,replaceWhat.size(),replaceWithWhat);
}
return result;
}
static std::string KEYFILE_STRING(const std::string &cat, const std::string &key, const std::string &def = "") {
gchar *str = g_key_file_get_string(keyfile, cat.c_str(), key.c_str(), 0);
if (!str) {
return def;
}
std::string ret(str);
g_free(str);
if (ret.find("#") != std::string::npos) {
ret = ret.substr(0, ret.find("#"));
while(*(ret.end() - 1) == ' ') {
ret.erase(ret.end() - 1);
}
}
if (ret.find("$jid") != std::string::npos) {
std::string jid = KEYFILE_STRING("service", "jid");
ret = replaceAll(ret, "$jid", jid);
}
return ret;
}
#define KEYFILE_BOOL(CAT, KEY) g_key_file_get_boolean(keyfile, CAT, KEY, 0)
static gchar *host = NULL;
static std::string host;
static int port = 10000;
struct FTData {
@ -119,12 +82,6 @@ struct FTData {
bool paused;
};
static GOptionEntry options_entries[] = {
{ "host", 'h', 0, G_OPTION_ARG_STRING, &host, "Host to connect to", NULL },
{ "port", 'p', 0, G_OPTION_ARG_INT, &port, "Port to connect to", NULL },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
};
static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info);
static gboolean ft_ui_ready(void *data) {
@ -231,7 +188,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
void getProtocolAndName(const std::string &legacyName, std::string &name, std::string &protocol) {
name = legacyName;
protocol = KEYFILE_STRING("service", "protocol");
protocol = CONFIG_STRING(config, "service.protocol");
if (protocol == "any") {
protocol = name.substr(0, name.find("."));
name = name.substr(name.find(".") + 1);
@ -242,13 +199,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
char* contents;
gsize length;
gboolean ret = false;
if (!KEYFILE_STRING("backend", "avatars_directory").empty()) {
std::string f = KEYFILE_STRING("backend", "avatars_directory") + "/" + legacyName;
if (!CONFIG_STRING(config, "backend.avatars_directory").empty()) {
std::string f = CONFIG_STRING(config, "backend.avatars_directory") + "/" + legacyName;
ret = g_file_get_contents (f.c_str(), &contents, &length, NULL);
}
if (!KEYFILE_STRING("backend", "default_avatar").empty() && !ret) {
ret = g_file_get_contents (KEYFILE_STRING("backend", "default_avatar").c_str(),
if (!CONFIG_STRING(config, "backend.default_avatar").empty() && !ret) {
ret = g_file_get_contents (CONFIG_STRING(config, "backend.default_avatar").c_str(),
&contents, &length, NULL);
}
@ -259,13 +216,16 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
void setDefaultAccountOptions(PurpleAccount *account) {
int i = 0;
gchar **keys = g_key_file_get_keys (keyfile, "purple", NULL, NULL);
while (keys && keys[i] != NULL) {
std::string key = keys[i];
Config::SectionValuesCont purpleConfigValues = config->getSectionValues("purple");
if (key == "fb_api_key" || key == "fb_api_secret") {
BOOST_FOREACH ( const Config::SectionValuesCont::value_type & keyItem, purpleConfigValues )
{
std::string key = keyItem.first;
std::string strippedKey = boost::erase_first_copy(key, "purple.");
if (strippedKey == "fb_api_key" || strippedKey == "fb_api_secret") {
purple_account_set_bool(account, "auth_fb", TRUE);
}
}
PurplePlugin *plugin = purple_find_prpl(purple_account_get_protocol_id(account));
PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
@ -274,23 +234,23 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
PurpleAccountOption *option = (PurpleAccountOption *) l->data;
PurplePrefType type = purple_account_option_get_type(option);
std::string key2(purple_account_option_get_setting(option));
if (key != key2) {
if (strippedKey != key2) {
continue;
}
found = true;
switch (type) {
case PURPLE_PREF_BOOLEAN:
purple_account_set_bool(account, key.c_str(), fromString<bool>(KEYFILE_STRING("purple", key)));
purple_account_set_bool(account, strippedKey.c_str(), fromString<bool>(keyItem.second.as<std::string>()));
break;
case PURPLE_PREF_INT:
purple_account_set_int(account, key.c_str(), fromString<int>(KEYFILE_STRING("purple", key)));
purple_account_set_int(account, strippedKey.c_str(), fromString<int>(keyItem.second.as<std::string>()));
break;
case PURPLE_PREF_STRING:
case PURPLE_PREF_STRING_LIST:
purple_account_set_string(account, key.c_str(), KEYFILE_STRING("purple", key).c_str());
purple_account_set_string(account, strippedKey.c_str(), keyItem.second.as<std::string>().c_str());
break;
default:
continue;
@ -299,11 +259,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
if (!found) {
purple_account_set_string(account, key.c_str(), KEYFILE_STRING("purple", key).c_str());
purple_account_set_string(account, strippedKey.c_str(), keyItem.second.as<std::string>().c_str());
}
i++;
}
g_strfreev (keys);
char* contents;
gsize length;
@ -313,7 +272,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
if (KEYFILE_STRING("service", "protocol") == "prpl-novell") {
if (CONFIG_STRING(config, "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());
@ -372,7 +331,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
// Enable account + privacy lists
purple_account_set_enabled(account, "spectrum", TRUE);
if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
purple_account_set_privacy_type(account, PURPLE_PRIVACY_DENY_USERS);
}
@ -493,12 +452,12 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
PurpleAccount *account = m_sessions[user];
if (account) {
std::string name = legacyName;
if (KEYFILE_STRING("service", "protocol") == "any" && legacyName.find("prpl-") == 0) {
if (CONFIG_STRING(config, "service.protocol") == "any" && legacyName.find("prpl-") == 0) {
name = name.substr(name.find(".") + 1);
}
m_vcards[user + name] = id;
if (KEYFILE_BOOL("backend", "no_vcard_fetch") && name != purple_account_get_username(account)) {
if (CONFIG_BOOL(config, "backend.no_vcard_fetch") && name != purple_account_get_username(account)) {
PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
notify_user_info(purple_account_get_connection(account), name.c_str(), user_info);
purple_notify_user_info_destroy(user_info);
@ -580,7 +539,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
void handleBuddyBlockToggled(const std::string &user, const std::string &buddyName, bool blocked) {
if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
PurpleAccount *account = m_sessions[user];
if (account) {
if (blocked) {
@ -848,7 +807,7 @@ static void buddyListNewNode(PurpleBlistNode *node) {
PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
bool blocked = false;
if (KEYFILE_BOOL("service", "enable_privacy_lists")) {
if (CONFIG_BOOL(config, "service.enable_privacy_lists")) {
if (prpl_info && prpl_info->tooltip_text) {
PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
prpl_info->tooltip_text(buddy, user_info, true);
@ -1578,13 +1537,13 @@ static bool initPurple() {
purple_debug_set_verbose(true);
purple_core_set_ui_ops(&coreUiOps);
if (KEYFILE_STRING("service", "eventloop") == "libev") {
if (CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev") {
LOG4CXX_INFO(logger, "Will use libev based event loop");
}
else {
LOG4CXX_INFO(logger, "Will use glib based event loop");
}
purple_eventloop_set_ui_ops(getEventLoopUiOps(KEYFILE_STRING("service", "eventloop") == "libev"));
purple_eventloop_set_ui_ops(getEventLoopUiOps(CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev"));
ret = purple_core_init("spectrum");
if (ret) {
@ -1670,30 +1629,6 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
}
int main(int argc, char **argv) {
GError *error = NULL;
GOptionContext *context;
context = g_option_context_new("config_file_name or profile name");
g_option_context_add_main_entries(context, options_entries, "");
if (!g_option_context_parse (context, &argc, &argv, &error)) {
std::cerr << "option parsing failed: " << error->message << "\n";
return -1;
}
if (argc != 2) {
#ifdef WIN32
std::cout << "Usage: spectrum.exe <configuration_file.cfg>\n";
#else
#if GLIB_CHECK_VERSION(2,14,0)
std::cout << g_option_context_get_help(context, FALSE, NULL);
#else
std::cout << "Usage: spectrum <configuration_file.cfg>\n";
std::cout << "See \"man spectrum\" for more info.\n";
#endif
#endif
}
else {
#ifndef WIN32
mallopt(M_CHECK_ACTION, 2);
mallopt(M_PERTURB, 0xb);
@ -1702,53 +1637,84 @@ int main(int argc, char **argv) {
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
std::cout << "SIGCHLD handler can't be set\n";
g_option_context_free(context);
return -1;
}
#endif
keyfile = g_key_file_new ();
if (!g_key_file_load_from_file (keyfile, argv[1], (GKeyFileFlags) 0, 0)) {
std::cout << "Can't open " << argv[1] << " configuration file.\n";
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
Config config;
if (!config.load(argv[1])) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
Logging::initBackendLogging(&config);
initPurple();
main_socket = create_socket(host, port);
purple_input_add(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL);
purple_timeout_add_seconds(30, pingTimeout, NULL);
np = new SpectrumNetworkPlugin();
bool libev = KEYFILE_STRING("service", "eventloop") == "libev";
GMainLoop *m_loop;
#ifdef WITH_LIBEVENT
if (!libev) {
m_loop = g_main_loop_new(NULL, FALSE);
}
else {
event_init();
}
#endif
m_loop = g_main_loop_new(NULL, FALSE);
if (m_loop) {
g_main_loop_run(m_loop);
}
#ifdef WITH_LIBEVENT
else {
event_loop(0);
}
#endif
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
return 1;
}
catch (...)
{
std::cout << desc << "\n";
return 1;
}
g_option_context_free(context);
config = boost::make_shared<Config>(argc, argv);
if (!config->load(vm["config"].as<std::string>())) {
std::cerr << "Can't load configuration file.\n";
return 1;
}
Logging::initBackendLogging(config.get());
initPurple();
main_socket = create_socket(host.c_str(), port);
purple_input_add(main_socket, PURPLE_INPUT_READ, &transportDataReceived, NULL);
purple_timeout_add_seconds(30, pingTimeout, NULL);
np = new SpectrumNetworkPlugin();
bool libev = CONFIG_STRING_DEFAULTED(config, "service.eventloop", "") == "libev";
GMainLoop *m_loop;
#ifdef WITH_LIBEVENT
if (!libev) {
m_loop = g_main_loop_new(NULL, FALSE);
}
else {
event_init();
}
#endif
m_loop = g_main_loop_new(NULL, FALSE);
if (m_loop) {
g_main_loop_run(m_loop);
}
#ifdef WITH_LIBEVENT
else {
event_loop(0);
}
#endif
return 0;
}

View file

@ -125,7 +125,7 @@ void spectrum_sigchld_handler(int sig)
}
#endif
int create_socket(char *host, int portno) {
int create_socket(const char *host, int portno) {
struct sockaddr_in serv_addr;
int main_socket = socket(AF_INET, SOCK_STREAM, 0);

View file

@ -27,7 +27,7 @@
void spectrum_sigchld_handler(int sig);
#endif
int create_socket(char *host, int portno);
int create_socket(const char *host, int portno);
GHashTable *spectrum_ui_get_info(void);
void execute_purple_plugin_action(PurpleConnection *gc, const std::string &name);

View file

@ -741,35 +741,48 @@ int main (int argc, char* argv[]) {
}
#endif
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -260,46 +260,48 @@ int main (int argc, char* argv[]) {
return -1;
}
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
// QStringList channels;
// for (int i = 3; i < argc; ++i)
// {
// channels.append(argv[i]);
// }
//
// MyIrcSession session;
// session.setNick(argv[2]);
// session.setAutoJoinChannels(channels);
// session.connectToServer(argv[1], 6667);
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -264,35 +264,48 @@ int main (int argc, char* argv[]) {
}
#endif
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -113,35 +113,48 @@ int main (int argc, char* argv[]) {
return -1;
}
#endif
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -27,35 +27,48 @@ int main (int argc, char* argv[]) {
return -1;
}
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
std::string configFile;
boost::program_options::variables_map vm;
boost::program_options::options_description desc("Usage: spectrum <config_file.cfg>\nAllowed options");
desc.add_options()
("host,h", value<std::string>(&host), "host")
("port,p", value<int>(&port), "port")
("help", "help")
("host,h", boost::program_options::value<std::string>(&host)->default_value(""), "Host to connect to")
("port,p", boost::program_options::value<int>(&port)->default_value(10000), "Port to connect to")
("config", boost::program_options::value<std::string>(&configFile)->default_value(""), "Config file")
;
try
{
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
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).allow_unregistered().run(), vm);
boost::program_options::notify(vm);
if(vm.count("help"))
{
std::cout << desc << "\n";
return 1;
}
if(vm.count("config") == 0) {
std::cout << desc << "\n";
return 1;
}
}
catch (std::runtime_error& e)
{
std::cout << desc << "\n";
exit(1);
return 1;
}
catch (...)
{
std::cout << desc << "\n";
exit(1);
}
if (argc < 5) {
return 1;
}
Config config;
if (!config.load(argv[5])) {
Config config(argc, argv);
if (!config.load(configFile)) {
std::cerr << "Can't open " << argv[1] << " configuration file.\n";
return 1;
}

View file

@ -42,6 +42,10 @@ std::vector<std::string> deserializeGroups(std::string &groups);
int getRandomPort(const std::string &s);
#ifdef _WIN32
std::wstring utf8ToUtf16(const std::string& str);
#endif
}
}

View file

@ -14,7 +14,8 @@ admin_password=test
#cert_password=test #password to that certificate if any
users_per_backend=10
#backend=../..//backends/swiften/spectrum2_swiften_backend
backend=../../backends/twitter/spectrum2_twitter_backend
#backend=../../backends/twitter/spectrum2_twitter_backend
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
protocol=prpl-jabber
#protocol=prpl-msn
#protocol=any

View file

@ -43,6 +43,7 @@
#include "Swiften/Elements/InvisiblePayload.h"
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "transport/protocol.pb.h"
#include "transport/util.h"
#include "utf8.h"
@ -58,6 +59,8 @@
#include "popt.h"
#endif
using namespace Transport::Util;
namespace Transport {
static unsigned long backend_id;
@ -122,16 +125,24 @@ class NetworkFactory : public Factory {
wrap.SerializeToString(&MESSAGE);
// Executes new backend
static unsigned long exec_(std::string path, const char *host, const char *port, const char *config) {
std::string original_path = path;
static unsigned long exec_(const std::string& exePath, const char *host, const char *port, const char *cmdlineArgs) {
// BACKEND_ID is replaced with unique ID. The ID is increasing for every backend.
boost::replace_all(path, "BACKEND_ID", boost::lexical_cast<std::string>(backend_id++));
// Add host and port.
path += std::string(" --host ") + host + " --port " + port + " " + config;
LOG4CXX_INFO(logger, "Starting new backend " << path);
std::string finalExePath = boost::replace_all_copy(exePath, "BACKEND_ID", boost::lexical_cast<std::string>(backend_id++));
#ifdef _WIN32
// Add host and port.
std::ostringstream fullCmdLine;
fullCmdLine << "\"" << finalExePath << "\" --host " << host << " --port " << port;
if (cmdlineArgs)
fullCmdLine << " " << cmdlineArgs;
LOG4CXX_INFO(logger, "Starting new backend " << fullCmdLine.str());
// We must provide a non-const buffer to CreateProcess below
std::vector<wchar_t> rawCommandLineArgs( fullCmdLine.str().size() + 1 );
wcscpy_s(&rawCommandLineArgs[0], rawCommandLineArgs.size(), utf8ToUtf16(fullCmdLine.str()).c_str());
STARTUPINFO si;
PROCESS_INFORMATION pi;
@ -139,26 +150,30 @@ static unsigned long exec_(std::string path, const char *host, const char *port,
si.cb=sizeof (si);
if (! CreateProcess(
NULL,
(LPSTR)path.c_str(), // command line
0, // process attributes
0, // thread attributes
0, // inherit handles
0, // creation flags
0, // environment
0, // cwd
&si,
&pi
)
utf8ToUtf16(finalExePath).c_str(),
&rawCommandLineArgs[0],
0, // process attributes
0, // thread attributes
0, // inherit handles
0, // creation flags
0, // environment
0, // cwd
&si,
&pi
)
) {
LOG4CXX_ERROR(logger, "Could not start process");
}
return 0;
#else
// Add host and port.
finalExePath += std::string(" --host ") + host + " --port " + port + " " + cmdlineArgs;
LOG4CXX_INFO(logger, "Starting new backend " << finalExePath);
// Create array of char * from string using -lpopt library
char *p = (char *) malloc(path.size() + 1);
strcpy(p, path.c_str());
char *p = (char *) malloc(finalExePath.size() + 1);
strcpy(p, finalExePath.c_str());
int argc;
char **argv;
poptParseArgvString(p, &argc, (const char ***) &argv);
@ -269,7 +284,7 @@ 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"));
while (true) {
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());
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->getCommandLineArgs().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");
@ -1509,7 +1524,7 @@ NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient(bool acceptUser
if (c == NULL && !m_startingBackend) {
m_isNextLongRun = longRun;
m_startingBackend = true;
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());
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->getCommandLineArgs().c_str());
}
return c;

View file

@ -25,6 +25,7 @@
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/numeric/conversion/cast.hpp>
using namespace boost::filesystem;
@ -137,6 +138,38 @@ int getRandomPort(const std::string &s) {
return 30000 + rand() % 10000;
}
#ifdef _WIN32
std::wstring utf8ToUtf16(const std::string& str)
{
try
{
if (str.empty())
return L"";
// First request the size of the required UTF-16 buffer
int numRequiredBytes = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), boost::numeric_cast<int>(str.size()), NULL, 0);
if (!numRequiredBytes)
return L"";
// Allocate memory for the UTF-16 string
std::vector<wchar_t> utf16Str(numRequiredBytes);
int numConverted = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), boost::numeric_cast<int>(str.size()), &utf16Str[0], numRequiredBytes);
if (!numConverted)
return L"";
std::wstring wstr(&utf16Str[0], numConverted);
return wstr;
}
catch (...)
{
// I don't believe libtransport is exception-safe so we'll just return an empty string instead
return L"";
}
}
#endif // _WIN32
}
}