Commit 9d078b71 authored by Romain Bignon's avatar Romain Bignon

load a config file, use logger and some other tools

parent f9e9fc54
......@@ -4,6 +4,10 @@ cmake_minimum_required(VERSION 2.6)
SET(BIN_NAME bitlbee2)
ADD_EXECUTABLE(${BIN_NAME}
src/bitlbee.cpp
src/util.cpp
src/log.cpp
src/mutex.cpp
src/config.cpp
)
SET(CONF_NAME bitlbee.conf)
......
# Path settings
path {
users = test
}
# Log function
logging {
# What you want to log
# DEBUG :Debug informations (discouraged)
# PARSE :Parse informations (discouraged)
# ROUTING :Routing informations
# DESYNCH :Desynchronizations
# WARNING :Warnings
# ERR :Errors
# INFO :Informations
# ALL :Show all infos
# You can put several logging level on the same line, separated by a space
level = DESYNCH WARNING BIGWARNING ERR CONNEC INFO
# Wether to log errors and warning to syslog
to_syslog = true
}
......@@ -18,9 +18,61 @@
#include <stdlib.h>
#include <libpurple/purple.h>
int main(int argc, char** argv)
#include "bitlbee.h"
#include "config.h"
#include "log.h"
static guint purple_wg_input_add(gint fd, PurpleInputCondition condition,
PurpleInputFunction function, gpointer data)
{
return 0;
}
static PurpleEventLoopUiOps eventloop_wg_ops = {
/* timeout_add */ g_timeout_add,
/* timeout_remove */ g_source_remove,
/* input_add */ purple_wg_input_add,
/* input_remove */ g_source_remove,
/* input_get_error*/ NULL,
/* timeout_add_seconds */ NULL,
NULL, NULL, NULL
};
Bitlbee::Bitlbee()
{
ConfigSection* section;
section = conf.AddSection("path", "Path information", false);
section->AddItem(new ConfigItem_string("users", "Users directory"));
section = conf.AddSection("logging", "Log informations", false);
section->AddItem(new ConfigItem_string("level", "Logging level"));
section->AddItem(new ConfigItem_bool("to_syslog", "Log error and warnings to syslog"));
}
int Bitlbee::main(int argc, char** argv)
{
if(argc < 2)
{
fprintf(stderr, "Syntax: %s config_file\n", argv[0]);
return EXIT_FAILURE;
}
if(!conf.Load(argv[1]))
{
b_log[W_ERR] << "Unable to load configuration, exiting..";
return EXIT_FAILURE;
}
b_log.SetLoggedFlags(conf.GetSection("logging")->GetItem("level")->String(), conf.GetSection("logging")->GetItem("to_syslog")->Boolean());
purple_util_set_user_dir(conf.GetSection("path")->GetItem("users")->String().c_str());
purple_eventloop_set_ui_ops(&eventloop_wg_ops);
purple_core_init("bitlbee2");
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
Bitlbee bitlbee;
exit(bitlbee.main(argc, argv));
}
/*
* Copyright(C) 2009 Romain Bignon
*
* 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, version 2 of the License.
*
* 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.
*/
class Bitlbee
{
public:
Bitlbee();
int main(int argc, char** argv);
};
This diff is collapsed.
This diff is collapsed.
/*
* Copyright(C) 2008-2009 Laurent Defert, Romain Bignon
*
* 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, version 2 of the License.
*
* 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.
*/
#include <iostream>
#include <syslog.h>
#include <sys/time.h>
#include "util.h"
#include "log.h"
Log b_log;
static struct
{
uint32_t flag;
int level;
const char* s;
} all_flags[] =
{
{ W_DEBUG, LOG_DEBUG, "DEBUG" },
{ W_PARSE, LOG_DEBUG, "PARSE" },
{ W_ROUTING, LOG_DEBUG, "ROUTING" },
{ W_DESYNCH, LOG_WARNING, "DESYNCH" },
{ W_WARNING, LOG_WARNING, "WARNING" },
{ W_ERR, LOG_ERR, "ERR" },
{ W_INFO, LOG_NOTICE, "INFO" }
};
Log::flux::~flux()
{
int i;
if(!(flag & b_log.LoggedFlags()))
return;
for(i = (sizeof all_flags / sizeof *all_flags) - 1; i >= 0 && !(flag & all_flags[i].flag); --i)
;
if(i < 0)
syslog(LOG_WARNING, "[SYSLOG] (%X) Unable to find how to log this message: %s", (uint32_t)flag, str.c_str());
else
{
if((all_flags[i].level == LOG_ERR || all_flags[i].level == LOG_WARNING) && b_log.ToSyslog())
syslog(all_flags[i].level, "[%s] %s", all_flags[i].s, str.c_str());
struct timeval t;
gettimeofday(&t, NULL);
b_log.std_lock.Lock();
(all_flags[i].level == LOG_ERR ? std::cerr : std::cout)
<< (t.tv_sec % (24 * 60 * 60)) / (60 * 60)
<< ":" << (t.tv_sec % (60 * 60)) / 60
<< ":" << t.tv_sec % 60
<< "." << t.tv_usec / 1000
<< "[" << all_flags[i].s << "] " << str << std::endl;
b_log.std_lock.Unlock();
}
}
Log::Log()
: logged_flags(DEFAULT_LOGGED_FLAGS)
{
openlog("bitlbee", LOG_CONS, LOG_DAEMON);
}
Log::~Log()
{
closelog();
}
void Log::SetLoggedFlags(std::string s, bool _to_syslog)
{
std::string token;
to_syslog = _to_syslog;
logged_flags = 0;
while((token = stringtok(s, " ")).empty() == false)
{
int i;
if(token == "ALL")
{
logged_flags = (uint32_t) -1;
break;
}
for(i = (sizeof all_flags / sizeof *all_flags) - 1; i >= 0 && (token != all_flags[i].s); --i)
;
if(i >= 0)
logged_flags |= all_flags[i].flag;
}
}
/*
* Copyright(C) 2008-2009 Laurent Defert, Romain Bignon
*
* 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, version 2 of the License.
*
* 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 LOG_H
#define LOG_H
#include <string>
#include <sstream>
#include "mutex.h"
enum
{
W_DEBUG = 1 << 0, /* Debug */
W_PARSE = 1 << 1, /* Show parsing */
W_ROUTING = 1 << 2, /* Routing information */
W_DESYNCH = 1 << 3, /* Desynchronization */
W_WARNING = 1 << 4, /* Warnings */
W_ERR = 1 << 5, /* Errors */
W_INFO = 1 << 6 /* Info */
};
#define DEFAULT_LOGGED_FLAGS (W_DESYNCH|W_WARNING|W_ERR|W_INFO)
#define FLog(flags, msg) b_log[flags] << __FILE__ << ":" << __PRETTY_FUNCTION << "():" << __LINE__ << ": " << msg
/***************************
* Log *
***************************
*
* Usage:
* b_log[flags] << messages;
*
* Examples:
* b_log[W_WARNING] << cl << "There is a problem with this: " << i;
* b_log[W_ERR] << "This user isn't allowed to do this!";
*/
class Log
{
public:
Mutex std_lock;
Log();
~Log();
void SetLoggedFlags(std::string s, bool to_syslog = true);
uint32_t LoggedFlags() const { return logged_flags; }
bool ToSyslog() const { return to_syslog; }
class flux
{
std::string str;
size_t flag;
public:
flux(size_t i)
: flag(i)
{}
~flux();
template<typename T>
flux& operator<< (T s)
{
std::ostringstream oss;
oss << s;
str += oss.str();
return *this;
}
};
flux operator[](size_t __n)
{
return flux(__n);
}
private:
uint32_t logged_flags;
bool to_syslog;
};
template<>
inline Log::flux& Log::flux::operator<< <std::string> (std::string s)
{
str += s;
return *this;
}
extern Log b_log;
#endif /* LOG_H */
/*
* Copyright(C) 2008 Laurent Defert, Romain Bignon
*
* 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, version 2 of the License.
*
* 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 product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*
*/
#include <map>
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <assert.h>
#include <cstring>
#include "mutex.h"
void Mutex::Init(MutexType _type)
{
mutex = (pthread_mutex_t*) new pthread_mutex_t;
type = _type;
pthread_mutexattr_t attr;
if(pthread_mutexattr_init(&attr) != 0)
{
std::cerr << "pthread_attr_init: " << strerror(errno);
throw MutexError();
}
switch(type)
{
case NORMAL_MUTEX:
//#ifdef DEBUG
if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
{
std::cerr << "pthread_mutexattr_settype: " << strerror(errno) << std::endl;
throw MutexError();
}
//#else
// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
//#endif
break;
case RECURSIVE_MUTEX:
if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
{
std::cerr << "pthread_mutexattr_settype: " << strerror(errno) << std::endl;
throw MutexError();
}
break;
default:
assert(false);
}
if(pthread_mutex_init(mutex, &attr) != 0)
{
std::cerr << "pthread_mutex_init: " << strerror(errno) << std::endl;
throw MutexError();
}
pthread_mutexattr_destroy(&attr);
}
Mutex::Mutex(MutexType type)
{
Init(type);
}
Mutex::Mutex(const Mutex& m)
{
Init(m.type);
}
Mutex& Mutex::operator=(const Mutex& m)
{
std::cerr << "mutex so bad" << std::endl;
Init(m.type);
return *this;
}
Mutex::~Mutex()
{
pthread_mutex_destroy(mutex);
delete mutex;
}
void Mutex::Lock() const
{
int res = pthread_mutex_lock(mutex);
//assert(res == 0);
/* Don't use pf_log, because it locks the stdout mutex. */
if(res)
std::cerr << "Failed to lock " << this << std::endl;
}
void Mutex::Unlock() const
{
int res = pthread_mutex_unlock(mutex);
//assert(res == 0);
/* Don't use pf_log, because it locks the stdout mutex. */
if(res)
std::cerr << "Failed to unlock " << this << std::endl;
}
/*
* Copyright(C) 2008 Laurent Defert, Romain Bignon
*
* 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, version 2 of the License.
*
* 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 product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*
*/
#ifndef MUTEX_H
#define MUTEX_H
#include <pthread.h>
#include <exception>
enum MutexType
{
INVALID_MUTEX,
NORMAL_MUTEX,
RECURSIVE_MUTEX
};
class Mutex
{
private:
pthread_mutex_t* mutex;
MutexType type;
void Init(enum MutexType _type);
public:
class MutexError : public std::exception {};
Mutex(enum MutexType _type = NORMAL_MUTEX);
Mutex(const Mutex &m);
Mutex& operator=(const Mutex& m);
~Mutex();
void Lock() const;
void Unlock() const;
};
/** Lock a Mutex locally.
*
* On a block, juste create an auto instance of this class.
* When it will be removed (while exiting this block), mutex will be unlocked.
*
* Juste use:
* BlockLockMutex lock(mutex);
*
*/
class BlockLockMutex
{
const Mutex* p;
BlockLockMutex(const BlockLockMutex&);
BlockLockMutex& operator=(const BlockLockMutex&);
public:
explicit BlockLockMutex(const Mutex* _p)
: p(_p)
{
p->Lock();
}
~BlockLockMutex()
{
p->Unlock();
}
};
#endif
/*
* Copyright(C) 2009 Romain Bignon
*
* 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, version 2 of the License.
*
* 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.
*/
#include <string>
std::string stringtok(std::string &in, const char * const delimiters)
{
std::string::size_type i = 0;
std::string s;
// eat leading whitespace
i = in.find_first_not_of (delimiters, i);
// find the end of the token
std::string::size_type j = in.find_first_of (delimiters, i);
if (j == std::string::npos)
{
if(i == std::string::npos)
s = "";
else
s = in.substr(i);
in = "";
return s; // nothing left but white space
}
// push token
s = in.substr(i, j-i);
in = in.substr(j+1);
return s;
}
/*
* Copyright(C) 2009 Romain Bignon
*
* 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, version 2 of the License.
*
* 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.
*/
std::string stringtok(std::string &in, const char * const delimiters);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment