diff --git a/backends/libcommuni/main.cpp b/backends/libcommuni/main.cpp index f5af84fb..6443c2bd 100644 --- a/backends/libcommuni/main.cpp +++ b/backends/libcommuni/main.cpp @@ -10,6 +10,7 @@ #include "transport/config.h" #include "transport/networkplugin.h" +#include "transport/logging.h" #include "session.h" #include #include @@ -83,30 +84,7 @@ int main (int argc, char* argv[]) { } QCoreApplication app(argc, argv); - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifndef _MSC_VER - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef _MSC_VER - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); Swift::QtEventLoop eventLoop; diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 137c7b8a..40118f67 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -2,6 +2,7 @@ #include #include "transport/config.h" +#include "transport/logging.h" #include "transport/transport.h" #include "transport/usermanager.h" #include "transport/memoryusage.h" @@ -901,18 +902,7 @@ int main(int argc, char **argv) { return 1; } - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - - p.load(istream); - p.setProperty("pid", boost::lexical_cast(getpid())); - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); // initPurple(config); diff --git a/backends/smstools3/main.cpp b/backends/smstools3/main.cpp index c152ef4f..a6502bdc 100644 --- a/backends/smstools3/main.cpp +++ b/backends/smstools3/main.cpp @@ -9,6 +9,7 @@ */ #include "transport/config.h" +#include "transport/logging.h" #include "transport/networkplugin.h" #include "transport/sqlite3backend.h" #include "transport/mysqlbackend.h" @@ -312,39 +313,17 @@ int main (int argc, char* argv[]) { return 1; } - if (CONFIG_STRING(&config, "logging.backend_config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifndef _MSC_VER - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config")); - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef _MSC_VER - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initBackendLogging(&config); std::string error; - storageBackend = StorageBackend::createBackend(&config, error); + StorageBackend *storageBackend = StorageBackend::createBackend(&config, error); if (storageBackend == NULL) { - std::cerr << error << "\n"; - return -2; + if (!error.empty()) { + std::cerr << error << "\n"; + return -2; + } } - - if (!storageBackend->connect()) { + else if (!storageBackend->connect()) { std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; return -1; } diff --git a/include/transport/logging.h b/include/transport/logging.h new file mode 100644 index 00000000..79b1dfd5 --- /dev/null +++ b/include/transport/logging.h @@ -0,0 +1,39 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * 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 +#include +#include +#include + +namespace Transport { + +class Config; + +namespace Logging { + +void initBackendLogging(Config *config); +void initMainLogging(Config *config); + +} + +} diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index 02e9e226..be525f60 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -13,6 +13,7 @@ #include "transport/usersreconnecter.h" #include "transport/util.h" #include "transport/gatewayresponder.h" +#include "transport/logging.h" #include "Swiften/EventLoop/SimpleEventLoop.h" #include #include @@ -235,71 +236,7 @@ int main(int argc, char **argv) } #endif - if (CONFIG_STRING(&config, "logging.config").empty()) { - LoggerPtr root = log4cxx::Logger::getRootLogger(); -#ifdef WIN32 - root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); -#else - root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); -#endif - } - else { - log4cxx::helpers::Properties p; - log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.config")); - - p.load(istream); - LogString pid, jid; - log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); - log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid); -#ifdef WIN32 - p.setProperty(L"pid", pid); - p.setProperty(L"jid", jid); -#else - p.setProperty("pid", pid); - p.setProperty("jid", jid); -#endif - - std::string dir; - BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) { - if (boost::ends_with(prop, ".File")) { - log4cxx::helpers::Transcoder::encode(p.get(prop), dir); - boost::replace_all(dir, "${jid}", jid); - break; - } - } - - if (!dir.empty()) { - // create directories - try { - boost::filesystem::create_directories( - boost::filesystem::path(dir).parent_path().string() - ); - } - catch (...) { - std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n"; - return 1; - } - -#ifndef WIN32 - if (!CONFIG_STRING(&config, "service.group").empty() && !CONFIG_STRING(&config, "service.user").empty()) { - struct group *gr; - if ((gr = getgrnam(CONFIG_STRING(&config, "service.group").c_str())) == NULL) { - std::cerr << "Invalid service.group name " << CONFIG_STRING(&config, "service.group") << "\n"; - return 1; - } - struct passwd *pw; - if ((pw = getpwnam(CONFIG_STRING(&config, "service.user").c_str())) == NULL) { - std::cerr << "Invalid service.user name " << CONFIG_STRING(&config, "service.user") << "\n"; - return 1; - } - chown(dir.c_str(), pw->pw_uid, gr->gr_gid); - } - -#endif - } - - log4cxx::PropertyConfigurator::configure(p); - } + Logging::initMainLogging(&config); #ifndef WIN32 if (!CONFIG_STRING(&config, "service.group").empty() ||!CONFIG_STRING(&config, "service.user").empty() ) { @@ -352,11 +289,12 @@ int main(int argc, char **argv) std::string error; StorageBackend *storageBackend = StorageBackend::createBackend(&config, error); if (storageBackend == NULL) { - std::cerr << error << "\n"; - return -2; + if (!error.empty()) { + std::cerr << error << "\n"; + return -2; + } } - - if (!storageBackend->connect()) { + else if (!storageBackend->connect()) { std::cerr << "Can't connect to database. Check the log to find out the reason.\n"; return -1; } @@ -399,4 +337,5 @@ int main(int argc, char **argv) delete storageBackend; delete factories; + return 0; } diff --git a/src/logging.cpp b/src/logging.cpp new file mode 100644 index 00000000..19dee6cf --- /dev/null +++ b/src/logging.cpp @@ -0,0 +1,132 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * 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/logging.h" +#include "transport/config.h" +#include +#include +#include +#include + +#include "log4cxx/logger.h" +#include "log4cxx/consoleappender.h" +#include "log4cxx/patternlayout.h" +#include "log4cxx/propertyconfigurator.h" +#include "log4cxx/helpers/properties.h" +#include "log4cxx/helpers/fileinputstream.h" +#include "log4cxx/helpers/transcoder.h" +#include +#include + +#ifndef WIN32 +#include "sys/signal.h" +#include +#include +#include +#include "libgen.h" +#else +#include +#endif + +using namespace boost::filesystem; +using namespace log4cxx; + +namespace Transport { + +namespace Logging { + +static LoggerPtr root; + +static void initLogging(Config *config, std::string key) { + if (CONFIG_STRING(config, key).empty()) { + root = log4cxx::Logger::getRootLogger(); +#ifdef WIN32 + root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); +#else + root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); +#endif + } + else { + log4cxx::helpers::Properties p; + log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(config, key)); + + p.load(istream); + LogString pid, jid; + log4cxx::helpers::Transcoder::decode(boost::lexical_cast(getpid()), pid); + log4cxx::helpers::Transcoder::decode(CONFIG_STRING(config, "service.jid"), jid); +#ifdef WIN32 + p.setProperty(L"pid", pid); + p.setProperty(L"jid", jid); +#else + p.setProperty("pid", pid); + p.setProperty("jid", jid); +#endif + + std::string dir; + BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) { + if (boost::ends_with(prop, ".File")) { + log4cxx::helpers::Transcoder::encode(p.get(prop), dir); + boost::replace_all(dir, "${jid}", jid); + break; + } + } + + if (!dir.empty()) { + // create directories + try { + boost::filesystem::create_directories( + boost::filesystem::path(dir).parent_path().string() + ); + } + catch (...) { + std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ".\n"; + } + +#ifndef WIN32 + if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) { + struct group *gr; + if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) { + std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n"; + } + struct passwd *pw; + if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) { + std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n"; + } + chown(dir.c_str(), pw->pw_uid, gr->gr_gid); + } + +#endif + } + + log4cxx::PropertyConfigurator::configure(p); + } +} + +void initBackendLogging(Config *config) { + initLogging(config, "logging.backend_config"); +} + +void initMainLogging(Config *config) { + initLogging(config, "logging.config"); +} + +} + +} diff --git a/src/storagebackend.cpp b/src/storagebackend.cpp new file mode 100644 index 00000000..17657a48 --- /dev/null +++ b/src/storagebackend.cpp @@ -0,0 +1,49 @@ +#include "transport/storagebackend.h" +#include "transport/config.h" + +#include "transport/sqlite3backend.h" +#include "transport/mysqlbackend.h" +#include "transport/pqxxbackend.h" + +namespace Transport { + +StorageBackend *StorageBackend::createBackend(Config *config, std::string &error) { + StorageBackend *storageBackend = NULL; +#ifdef WITH_SQLITE + if (CONFIG_STRING(config, "database.type") == "sqlite3") { + storageBackend = new SQLite3Backend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "sqlite3") { + error = "Libtransport is not compiled with sqlite3 backend support."; + } +#endif + +#ifdef WITH_MYSQL + if (CONFIG_STRING(config, "database.type") == "mysql") { + storageBackend = new MySQLBackend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "mysql") { + error = "Spectrum2 is not compiled with mysql backend support."; + } +#endif + +#ifdef WITH_PQXX + if (CONFIG_STRING(config, "database.type") == "pqxx") { + storageBackend = new PQXXBackend(config); + } +#else + if (CONFIG_STRING(config, "database.type") == "pqxx") { + error = "Spectrum2 is not compiled with pqxx backend support."; + } +#endif + + if (CONFIG_STRING(config, "database.type") != "mysql" && CONFIG_STRING(config, "database.type") != "sqlite3" + && CONFIG_STRING(config, "database.type") != "pqxx" && CONFIG_STRING(config, "database.type") != "none") { + error = "Unknown storage backend " + CONFIG_STRING(config, "database.type"); + } + return storageBackend; +} + +}