merge next
This commit is contained in:
commit
37cc935c18
8 changed files with 258 additions and 77 deletions
|
@ -171,7 +171,9 @@ ADD_SUBDIRECTORY(include)
|
|||
ADD_SUBDIRECTORY(spectrum)
|
||||
ADD_SUBDIRECTORY(backends)
|
||||
#ADD_SUBDIRECTORY(tests)
|
||||
ADD_SUBDIRECTORY(spectrum_manager)
|
||||
if (NOT WIN32)
|
||||
ADD_SUBDIRECTORY(spectrum_manager)
|
||||
endif()
|
||||
|
||||
if (CPPUNIT_FOUND)
|
||||
message("tests : yes")
|
||||
|
|
|
@ -1697,6 +1697,33 @@ static void spectrum_sigchld_handler(int sig)
|
|||
}
|
||||
}
|
||||
|
||||
static int create_socket(char *host, int portno) {
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
int m_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
hostent *hos; // Resolve name
|
||||
if ((hos = gethostbyname(host)) == NULL) {
|
||||
// strerror() will not work for gethostbyname() and hstrerror()
|
||||
// is supposedly obsolete
|
||||
exit(1);
|
||||
}
|
||||
serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
|
||||
|
||||
if (connect(m_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
close(m_sock);
|
||||
m_sock = 0;
|
||||
}
|
||||
|
||||
int flags = fcntl(m_sock, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(m_sock, F_SETFL, flags);
|
||||
return m_sock;
|
||||
}
|
||||
|
||||
static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond) {
|
||||
if (cond & PURPLE_INPUT_READ) {
|
||||
char buffer[65535];
|
||||
|
@ -1798,30 +1825,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
initPurple();
|
||||
|
||||
int portno = port;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
m_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
hostent *hos; // Resolve name
|
||||
if ((hos = gethostbyname(host)) == NULL) {
|
||||
// strerror() will not work for gethostbyname() and hstrerror()
|
||||
// is supposedly obsolete
|
||||
exit(1);
|
||||
}
|
||||
serv_addr.sin_addr.s_addr = *((unsigned long *) hos->h_addr_list[0]);
|
||||
|
||||
if (connect(m_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
close(m_sock);
|
||||
m_sock = 0;
|
||||
}
|
||||
|
||||
int flags = fcntl(m_sock, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(m_sock, F_SETFL, flags);
|
||||
m_sock = create_socket(host, port);
|
||||
|
||||
purple_input_add(m_sock, PURPLE_INPUT_READ, &transportDataReceived, NULL);
|
||||
// purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
|
||||
|
|
|
@ -8,8 +8,9 @@ if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
|||
execute_process(
|
||||
COMMAND ${SWIFTEN_CONFIG_EXECUTABLE} --libs
|
||||
OUTPUT_VARIABLE SWIFTEN_LIBRARY)
|
||||
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIBRARY "${SWIFTEN_LIBRARY}")
|
||||
string(REGEX REPLACE " +$" "" SWIFTEN_LIBRARY "${SWIFTEN_LIBRARY}")
|
||||
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY})
|
||||
string(REGEX REPLACE " +$" "" SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY})
|
||||
string(REGEX REPLACE " " ";" SWIFTEN_LIBRARY ${SWIFTEN_LIBRARY})
|
||||
else()
|
||||
message( FATAL_ERROR "Could NOT find swiften-config" )
|
||||
endif()
|
||||
|
|
|
@ -10,6 +10,12 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
|||
ADD_DEFINITIONS(-fPIC)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES} ws2_32.lib)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARIES} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
|
|
|
@ -65,7 +65,6 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
pid_t pid, sid;
|
||||
FILE* lock_file_f;
|
||||
char process_pid[20];
|
||||
|
||||
/* already a daemon */
|
||||
if ( getppid() == 1 ) return;
|
||||
|
||||
|
@ -76,11 +75,23 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
}
|
||||
/* If we got a good PID, then we can exit the parent process. */
|
||||
if (pid > 0) {
|
||||
if (lock_file) {
|
||||
/* write our pid into it & close the file. */
|
||||
lock_file_f = fopen(lock_file, "w+");
|
||||
if (lock_file_f == NULL) {
|
||||
std::cerr << "Cannot create lock file " << lock_file << ". Exiting\n";
|
||||
exit(1);
|
||||
}
|
||||
sprintf(process_pid,"%d\n",pid);
|
||||
if (fwrite(process_pid,1,strlen(process_pid),lock_file_f) < strlen(process_pid)) {
|
||||
std::cerr << "Cannot write to lock file " << lock_file << ". Exiting\n";
|
||||
exit(1);
|
||||
}
|
||||
fclose(lock_file_f);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* At this point we are executing as the child process */
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
|
@ -95,21 +106,6 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
if ((chdir(cwd)) < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (lock_file) {
|
||||
/* write our pid into it & close the file. */
|
||||
lock_file_f = fopen(lock_file, "w+");
|
||||
if (lock_file_f == NULL) {
|
||||
std::cout << "EE cannot create lock file " << lock_file << ". Exiting\n";
|
||||
exit(1);
|
||||
}
|
||||
sprintf(process_pid,"%d\n",getpid());
|
||||
if (fwrite(process_pid,1,strlen(process_pid),lock_file_f) < strlen(process_pid)) {
|
||||
std::cout << "EE cannot write to lock file " << lock_file << ". Exiting\n";
|
||||
exit(1);
|
||||
}
|
||||
fclose(lock_file_f);
|
||||
}
|
||||
|
||||
if (freopen( "/dev/null", "r", stdin) == NULL) {
|
||||
std::cout << "EE cannot open /dev/null. Exiting\n";
|
||||
|
|
|
@ -7,8 +7,22 @@
|
|||
#include "transport/networkpluginserver.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
using namespace boost;
|
||||
|
||||
static int finished;
|
||||
static std::string *m;
|
||||
|
||||
|
@ -37,19 +51,172 @@ static void handleMessageReceived(Swift::Client *client, Swift::Message::ref mes
|
|||
}
|
||||
}
|
||||
|
||||
static std::string searchForBinary(const std::string &binary) {
|
||||
std::vector<std::string> path_list;
|
||||
char * env_path = getenv("PATH");
|
||||
|
||||
if (env_path != NULL) {
|
||||
std::string buffer = "";
|
||||
for (int s = 0; s < strlen(env_path); s++) {
|
||||
if (env_path[s] == ':') {
|
||||
path_list.insert(path_list.end(), std::string(buffer));
|
||||
buffer = "";
|
||||
}
|
||||
else {
|
||||
buffer += env_path[s];
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer != "") {
|
||||
path_list.insert(path_list.end(), std::string(buffer));
|
||||
buffer = "";
|
||||
}
|
||||
|
||||
for (std::vector<std::string>::iterator dit = path_list.begin(); dit < path_list.end(); dit++) {
|
||||
std::string bpath = *dit;
|
||||
bpath += "/";
|
||||
bpath += binary;
|
||||
path p(bpath);
|
||||
if (exists(p) && !is_directory(p)) {
|
||||
return bpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Executes new backend
|
||||
static unsigned long exec_(std::string path, std::string config) {
|
||||
// fork and exec
|
||||
pid_t pid = fork();
|
||||
if ( pid == 0 ) {
|
||||
// child process
|
||||
exit(execl(path.c_str(), path.c_str(), config.c_str(), NULL));
|
||||
} else if ( pid < 0 ) {
|
||||
// fork failed
|
||||
}
|
||||
else {
|
||||
waitpid(pid, 0, 0);
|
||||
}
|
||||
|
||||
return (unsigned long) pid;
|
||||
}
|
||||
|
||||
static int isRunning(const std::string &pidfile) {
|
||||
path p(pidfile);
|
||||
if (!exists(p) || is_directory(p)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ifstream f(p.string().c_str(), std::ios_base::in);
|
||||
std::string pid;
|
||||
f >> pid;
|
||||
|
||||
if (pid.empty())
|
||||
return 0;
|
||||
|
||||
if (kill(boost::lexical_cast<int>(pid), 0) != 0)
|
||||
return 0;
|
||||
|
||||
return boost::lexical_cast<int>(pid);
|
||||
}
|
||||
|
||||
static void start_all_instances(ManagerConfig *config) {
|
||||
path p(CONFIG_STRING(config, "service.config_directory"));
|
||||
|
||||
try {
|
||||
if (!exists(p)) {
|
||||
std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
exit(6);
|
||||
}
|
||||
|
||||
if (!is_directory(p)) {
|
||||
std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
exit(7);
|
||||
}
|
||||
|
||||
std::string spectrum2_binary = searchForBinary("spectrum2");
|
||||
if (spectrum2_binary.empty()) {
|
||||
std::cerr << "spectrum2 binary not found in PATH\n";
|
||||
exit(8);
|
||||
}
|
||||
|
||||
directory_iterator end_itr;
|
||||
for (directory_iterator itr(p); itr != end_itr; ++itr) {
|
||||
if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
|
||||
Config cfg;
|
||||
if (cfg.load(itr->path().string()) == false) {
|
||||
std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
}
|
||||
|
||||
if (!isRunning(CONFIG_STRING(&cfg, "service.pidfile"))) {
|
||||
exec_(spectrum2_binary, itr->path().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const filesystem_error& ex) {
|
||||
std::cerr << "boost filesystem error\n";
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
static void stop_all_instances(ManagerConfig *config) {
|
||||
path p(CONFIG_STRING(config, "service.config_directory"));
|
||||
|
||||
try {
|
||||
if (!exists(p)) {
|
||||
std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
exit(6);
|
||||
}
|
||||
|
||||
if (!is_directory(p)) {
|
||||
std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
exit(7);
|
||||
}
|
||||
|
||||
directory_iterator end_itr;
|
||||
for (directory_iterator itr(p); itr != end_itr; ++itr) {
|
||||
if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
|
||||
Config cfg;
|
||||
if (cfg.load(itr->path().string()) == false) {
|
||||
std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
}
|
||||
|
||||
int pid = isRunning(CONFIG_STRING(&cfg, "service.pidfile"));
|
||||
if (pid) {
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const filesystem_error& ex) {
|
||||
std::cerr << "boost filesystem error\n";
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ManagerConfig config;
|
||||
std::string config_file;
|
||||
std::string command;
|
||||
boost::program_options::variables_map vm;
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum_manager <config_file.cfg> <command>\nAllowed options");
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\nAllowed options");
|
||||
desc.add_options()
|
||||
("help,h", "help")
|
||||
("help,h", "Show help output")
|
||||
("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum-manager.cfg"), "Spectrum manager config file")
|
||||
("command", boost::program_options::value<std::string>(&command)->default_value(""), "Command")
|
||||
;
|
||||
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("command", -1);
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
if(vm.count("help"))
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
|
@ -59,44 +226,47 @@ int main(int argc, char **argv)
|
|||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 3) {
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
if (!config.load(argv[1])) {
|
||||
if (!config.load(config_file)) {
|
||||
std::cerr << "Can't load configuration file.\n";
|
||||
return 1;
|
||||
return 4;
|
||||
}
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Swift::BoostNetworkFactories networkFactories(&eventLoop);
|
||||
|
||||
std::string message = argv[2];
|
||||
m = &message;
|
||||
|
||||
std::vector<std::string> servers = CONFIG_VECTOR(&config, "servers.server");
|
||||
for (std::vector<std::string>::const_iterator it = servers.begin(); it != servers.end(); it++) {
|
||||
finished++;
|
||||
Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + (*it), CONFIG_STRING(&config, "service.admin_password"), &networkFactories);
|
||||
client->setAlwaysTrustCertificates();
|
||||
client->onConnected.connect(boost::bind(&handleConnected, client));
|
||||
client->onDisconnected.connect(bind(&handleDisconnected, client, _1));
|
||||
client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1));
|
||||
Swift::ClientOptions opt;
|
||||
opt.allowPLAINWithoutTLS = true;
|
||||
client->connect(opt);
|
||||
// std::cout << *it << "\n";
|
||||
if (command == "start") {
|
||||
start_all_instances(&config);
|
||||
}
|
||||
else if (command == "stop") {
|
||||
stop_all_instances(&config);
|
||||
}
|
||||
else {
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Swift::BoostNetworkFactories networkFactories(&eventLoop);
|
||||
|
||||
eventLoop.run();
|
||||
std::string message = argv[1];
|
||||
m = &message;
|
||||
|
||||
std::vector<std::string> servers = CONFIG_VECTOR(&config, "servers.server");
|
||||
for (std::vector<std::string>::const_iterator it = servers.begin(); it != servers.end(); it++) {
|
||||
finished++;
|
||||
Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + (*it), CONFIG_STRING(&config, "service.admin_password"), &networkFactories);
|
||||
client->setAlwaysTrustCertificates();
|
||||
client->onConnected.connect(boost::bind(&handleConnected, client));
|
||||
client->onDisconnected.connect(bind(&handleDisconnected, client, _1));
|
||||
client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1));
|
||||
Swift::ClientOptions opt;
|
||||
opt.allowPLAINWithoutTLS = true;
|
||||
client->connect(opt);
|
||||
// std::cout << *it << "\n";
|
||||
}
|
||||
|
||||
eventLoop.run();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ bool ManagerConfig::load(const std::string &configfile, boost::program_options::
|
|||
opts.add_options()
|
||||
("service.admin_username", value<std::string>()->default_value(""), "Administrator username.")
|
||||
("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
|
||||
("service.config_directory", value<std::string>()->default_value("/etc/spectrum2/transports/"), "Directory with spectrum2 configuration files. One .cfg file per one instance")
|
||||
("servers.server", value<std::vector<std::string> >()->multitoken(), "Server.")
|
||||
;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[service]
|
||||
admin_username=admin
|
||||
admin_password=test
|
||||
config_directory=/etc/spectrum2/transports/
|
||||
|
||||
[servers]
|
||||
server=localhost
|
||||
|
|
Loading…
Add table
Reference in a new issue