Merge branch 'master' of github.com:janvidar/uhub
This commit is contained in:
commit
70f13158d3
10
GNUmakefile
10
GNUmakefile
@ -10,9 +10,8 @@ LD := $(CC)
|
||||
MV := mv
|
||||
RANLIB := ranlib
|
||||
CFLAGS += -pipe -Wall
|
||||
USE_SSL ?= NO
|
||||
USE_SSL ?= YES
|
||||
USE_BIGENDIAN ?= AUTO
|
||||
USE_PLUGINS ?= YES
|
||||
BITS ?= AUTO
|
||||
SILENT ?= YES
|
||||
TERSE ?= NO
|
||||
@ -43,7 +42,6 @@ UHUB_PREFIX ?= c:/uhub/
|
||||
CFLAGS += -mno-cygwin
|
||||
LDFLAGS += -mno-cygwin
|
||||
BIN_EXT ?= .exe
|
||||
USE_PLUGINS := NO
|
||||
else
|
||||
DESTDIR ?= /
|
||||
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
||||
@ -121,11 +119,7 @@ CFLAGS += -DSSL_SUPPORT
|
||||
LDLIBS += -lssl
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PLUGINS),YES)
|
||||
CFLAGS += -DPLUGIN_SUPPORT
|
||||
LDLIBS += -ldl
|
||||
endif
|
||||
|
||||
|
||||
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
||||
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
||||
@ -243,7 +237,7 @@ endif
|
||||
%.o: %.c version.h revision.h
|
||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||
|
||||
all: $(uhub_BINARY)
|
||||
all: $(uhub_BINARY) plugins
|
||||
|
||||
plugins: $(uhub_BINARY) $(all_plugins)
|
||||
|
||||
|
@ -120,7 +120,6 @@ void sid_pool_destroy(struct sid_pool* pool)
|
||||
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
||||
{
|
||||
sid_t n;
|
||||
|
||||
if (pool->count >= (pool->max - pool->min))
|
||||
{
|
||||
#ifdef DEBUG_SID
|
||||
@ -129,8 +128,7 @@ sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = ++pool->count;
|
||||
|
||||
n = (++pool->count);
|
||||
for (; (pool->map[n % pool->max]); n++) ;
|
||||
|
||||
#ifdef DEBUG_SID
|
||||
|
@ -25,7 +25,6 @@
|
||||
struct sid_pool;
|
||||
struct hub_user;
|
||||
|
||||
extern const char* BASE32_ALPHABET;
|
||||
extern char* sid_to_string(sid_t sid_);
|
||||
extern sid_t string_to_sid(const char* sid);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||
*
|
||||
* 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
|
||||
@ -732,15 +732,22 @@ static int command_register(struct hub_info* hub, struct hub_user* user, struct
|
||||
data.password[MAX_PASS_LEN] = '\0';
|
||||
data.credentials = auth_cred_user;
|
||||
|
||||
if (acl_register_user(hub, &data))
|
||||
if (hub->config->register_self)
|
||||
{
|
||||
sprintf(tmp, "User \"%s\" registered.", user->id.nick);
|
||||
return command_status(hub, user, cmd, tmp);
|
||||
if (acl_register_user(hub, &data))
|
||||
{
|
||||
sprintf(tmp, "User \"%s\" registered.", user->id.nick);
|
||||
return command_status(hub, user, cmd, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "Unable to register user \"%s\".", user->id.nick);
|
||||
return command_status(hub, user, cmd, tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "Unable to register user \"%s\".", user->id.nick);
|
||||
return command_status(hub, user, cmd, tmp);
|
||||
return command_status(hub, user, cmd, "You are not allowed to register.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,15 @@
|
||||
<since>0.1.1</since>
|
||||
</option>
|
||||
|
||||
<option name="register_self" type="boolean" default="0">
|
||||
<short>Allow users to register themselves on the hub.</short>
|
||||
<description><![CDATA[
|
||||
If this is enabled guests can register their nickname on the hub.
|
||||
Otherwise only operators can register users.
|
||||
]]></description>
|
||||
<since>0.4.0</since>
|
||||
</option>
|
||||
|
||||
<option name="obsolete_clients" type="boolean" default="0">
|
||||
<short>Support obsolete clients using a ADC protocol prior to 1.0</short>
|
||||
<description><![CDATA[
|
||||
@ -417,6 +426,17 @@
|
||||
<since>0.3.0</since>
|
||||
</option>
|
||||
|
||||
<option name="tls_require_redirect_addr" type="string" default="">
|
||||
<check regexp="(adc|adcs|dchub)://.*" />
|
||||
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
|
||||
<description><![CDATA[
|
||||
This is the redirect address used when the hub wants to redirect a client for not using ADCS.
|
||||
For instance a hub at adc://adc.example.com might redirect to adcs://adc.example.com
|
||||
]]></description>
|
||||
<since>0.3.3</since>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="tls_certificate" type="file" default="">
|
||||
<short>Certificate file</short>
|
||||
<description><![CDATA[
|
||||
|
@ -11,6 +11,7 @@ void config_defaults(struct hub_config* config)
|
||||
config->show_banner_sys_info = 1;
|
||||
config->max_users = 500;
|
||||
config->registered_users_only = 0;
|
||||
config->register_self = 0;
|
||||
config->obsolete_clients = 0;
|
||||
config->chat_only = 0;
|
||||
config->chat_is_privileged = 0;
|
||||
@ -42,6 +43,7 @@ void config_defaults(struct hub_config* config)
|
||||
config->flood_ctl_extras = 0;
|
||||
config->tls_enable = 0;
|
||||
config->tls_require = 0;
|
||||
config->tls_require_redirect_addr = hub_strdup("");
|
||||
config->tls_certificate = hub_strdup("");
|
||||
config->tls_private_key = hub_strdup("");
|
||||
config->file_motd = hub_strdup("");
|
||||
@ -183,6 +185,16 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "register_self"))
|
||||
{
|
||||
if (!apply_boolean(key, data, &config->register_self))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "obsolete_clients"))
|
||||
{
|
||||
if (!apply_boolean(key, data, &config->obsolete_clients))
|
||||
@ -496,6 +508,16 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "tls_require_redirect_addr"))
|
||||
{
|
||||
if (!apply_string(key, data, &config->tls_require_redirect_addr, (char*) ""))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "tls_certificate"))
|
||||
{
|
||||
if (!apply_string(key, data, &config->tls_certificate, (char*) ""))
|
||||
@ -933,6 +955,8 @@ void free_config(struct hub_config* config)
|
||||
|
||||
hub_free(config->redirect_addr);
|
||||
|
||||
hub_free(config->tls_require_redirect_addr);
|
||||
|
||||
hub_free(config->tls_certificate);
|
||||
|
||||
hub_free(config->tls_private_key);
|
||||
@ -1048,6 +1072,9 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
||||
if (!ignore_defaults || config->registered_users_only != 0)
|
||||
fprintf(stdout, "registered_users_only = %s\n", config->registered_users_only ? "yes" : "no");
|
||||
|
||||
if (!ignore_defaults || config->register_self != 0)
|
||||
fprintf(stdout, "register_self = %s\n", config->register_self ? "yes" : "no");
|
||||
|
||||
if (!ignore_defaults || config->obsolete_clients != 0)
|
||||
fprintf(stdout, "obsolete_clients = %s\n", config->obsolete_clients ? "yes" : "no");
|
||||
|
||||
@ -1141,6 +1168,9 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
||||
if (!ignore_defaults || config->tls_require != 0)
|
||||
fprintf(stdout, "tls_require = %s\n", config->tls_require ? "yes" : "no");
|
||||
|
||||
if (!ignore_defaults || strcmp(config->tls_require_redirect_addr, "") != 0)
|
||||
fprintf(stdout, "tls_require_redirect_addr = \"%s\"\n", config->tls_require_redirect_addr);
|
||||
|
||||
if (!ignore_defaults || strcmp(config->tls_certificate, "") != 0)
|
||||
fprintf(stdout, "tls_certificate = \"%s\"\n", config->tls_certificate);
|
||||
|
||||
|
@ -11,6 +11,7 @@ struct hub_config
|
||||
int show_banner_sys_info; /*<<< Show banner on connect (default: 1) */
|
||||
int max_users; /*<<< Maximum number of users allowed on the hub (default: 500) */
|
||||
int registered_users_only; /*<<< Allow registered users only (default: 0) */
|
||||
int register_self; /*<<< Allow users to register themselves on the hub. (default: 0) */
|
||||
int obsolete_clients; /*<<< Support obsolete clients using a ADC protocol prior to 1.0 (default: 0) */
|
||||
int chat_only; /*<<< Allow chat only operation on hub (default: 0) */
|
||||
int chat_is_privileged; /*<<< Allow chat for operators and above only (default: 0) */
|
||||
@ -42,6 +43,7 @@ struct hub_config
|
||||
int flood_ctl_extras; /*<<< Max extra messages allowed in time interval (default: 0) */
|
||||
int tls_enable; /*<<< Enable SSL/TLS support (default: 0) */
|
||||
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) (default: 0) */
|
||||
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: ) */
|
||||
char* tls_certificate; /*<<< Certificate file (default: ) */
|
||||
char* tls_private_key; /*<<< Private key file (default: ) */
|
||||
char* file_motd; /*<<< File containing the 'message of the day (default: ) */
|
||||
|
@ -695,6 +695,7 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config
|
||||
|
||||
/* Disable SSLv2 */
|
||||
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_quiet_shutdown(hub->ssl_ctx, 1);
|
||||
|
||||
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
|
||||
{
|
||||
@ -824,7 +825,6 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
|
||||
event_queue_shutdown(hub->queue);
|
||||
net_con_close(hub->server);
|
||||
hub_free(hub->server);
|
||||
server_alt_port_stop(hub);
|
||||
uman_shutdown(hub);
|
||||
hub->status = hub_status_stopped;
|
||||
@ -840,21 +840,22 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
}
|
||||
|
||||
#ifdef PLUGIN_SUPPORT
|
||||
void hub_plugins_load(struct hub_info* hub)
|
||||
int hub_plugins_load(struct hub_info* hub)
|
||||
{
|
||||
if (!hub->config->file_plugins || !*hub->config->file_plugins)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
hub->plugins = hub_malloc_zero(sizeof(struct uhub_plugins));
|
||||
if (!hub->plugins)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
if (plugin_initialize(hub->config, hub->plugins) < 0)
|
||||
{
|
||||
hub_free(hub->plugins);
|
||||
hub->plugins = 0;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hub_plugins_unload(struct hub_info* hub)
|
||||
@ -943,7 +944,11 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
||||
}
|
||||
|
||||
#ifdef PLUGIN_SUPPORT
|
||||
hub_plugins_load(hub);
|
||||
if (hub_plugins_load(hub) < 0)
|
||||
{
|
||||
hub->status = hub_status_shutdown;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
|
||||
|
@ -50,6 +50,17 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
||||
if (probe->hub->config->tls_enable && probe->hub->config->tls_require)
|
||||
{
|
||||
LOG_TRACE("Not TLS connection - closing connection.");
|
||||
if (*probe->hub->config->tls_require_redirect_addr)
|
||||
{
|
||||
char buf[512];
|
||||
ssize_t len = snprintf(buf, sizeof(buf), "ISUP " ADC_PROTO_SUPPORT "\nISID AAAB\nIINF NIRedirecting...\nIQUI AAAB RD%s\n", probe->hub->config->tls_require_redirect_addr);
|
||||
net_con_send(con, buf, (size_t) len);
|
||||
LOG_TRACE("Not TLS connection - Redirecting to %s.", probe->hub->config->tls_require_redirect_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("Not TLS connection - closing connection.");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -60,9 +71,8 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
||||
probe_destroy(probe);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (bytes >= 11 &&
|
||||
else if (bytes >= 11 &&
|
||||
probe_recvbuf[0] == 22 &&
|
||||
probe_recvbuf[1] == 3 && /* protocol major version */
|
||||
probe_recvbuf[5] == 1 && /* message type */
|
||||
@ -107,6 +117,8 @@ struct hub_probe* probe_create(struct hub_info* hub, int sd, struct ip_addr_enca
|
||||
if (probe == NULL)
|
||||
return NULL; /* OOM */
|
||||
|
||||
LOG_TRACE("probe_create(): %p", probe);
|
||||
|
||||
probe->hub = hub;
|
||||
probe->connection = net_con_create();
|
||||
net_con_initialize(probe->connection, sd, probe_net_event, probe, NET_EVENT_READ);
|
||||
@ -118,6 +130,7 @@ struct hub_probe* probe_create(struct hub_info* hub, int sd, struct ip_addr_enca
|
||||
|
||||
void probe_destroy(struct hub_probe* probe)
|
||||
{
|
||||
LOG_TRACE("probe_destroy(): %p (connection=%p)", probe, probe->connection);
|
||||
if (probe->connection)
|
||||
{
|
||||
net_con_close(probe->connection);
|
||||
|
@ -71,6 +71,12 @@ void user_destroy(struct hub_user* user)
|
||||
hub_recvq_destroy(user->recv_queue);
|
||||
hub_sendq_destroy(user->send_queue);
|
||||
|
||||
if (user->connection)
|
||||
{
|
||||
LOG_TRACE("user_destory() -> net_con_close(%p)", user->connection);
|
||||
net_con_close(user->connection);
|
||||
}
|
||||
|
||||
adc_msg_free(user->info);
|
||||
user_clear_feature_cast_support(user);
|
||||
hub_free(user);
|
||||
|
@ -179,6 +179,14 @@ void net_con_close(struct net_connection* con)
|
||||
|
||||
g_backend->handler.con_del(g_backend->data, con);
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (con->ssl)
|
||||
{
|
||||
SSL_shutdown(con->ssl);
|
||||
SSL_clear(con->ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
net_close(con->sd);
|
||||
con->sd = -1;
|
||||
|
||||
@ -196,6 +204,7 @@ struct net_cleanup_handler* net_cleanup_initialize(size_t max)
|
||||
|
||||
void net_cleanup_shutdown(struct net_cleanup_handler* handler)
|
||||
{
|
||||
net_cleanup_process(handler);
|
||||
hub_free(handler->queue);
|
||||
hub_free(handler);
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -handle_openssl_error(con, ret);
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -201,7 +201,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
}
|
||||
else
|
||||
{
|
||||
return -handle_openssl_error(con, ret);
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -251,6 +251,9 @@ void* net_con_get_ptr(struct net_connection* con)
|
||||
|
||||
void net_con_destroy(struct net_connection* con)
|
||||
{
|
||||
#ifdef SSL_SUPPORT
|
||||
SSL_free(con->ssl);
|
||||
#endif
|
||||
hub_free(con);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,6 @@ int net_initialize()
|
||||
LOG_TRACE("Initializing OpenSSL...");
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
#endif /* SSL_SUPPORT */
|
||||
|
||||
net_initialized = 1;
|
||||
@ -101,7 +100,9 @@ int net_destroy()
|
||||
net_backend_shutdown();
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
/* FIXME: Shutdown OpenSSL here. */
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
#endif
|
||||
|
||||
#ifdef WINSOCK
|
||||
|
@ -51,6 +51,10 @@ struct plugin_user
|
||||
enum auth_credentials credentials;
|
||||
};
|
||||
|
||||
struct plugin_hub_info
|
||||
{
|
||||
};
|
||||
|
||||
enum plugin_status
|
||||
{
|
||||
st_default = 0, /* Use default */
|
||||
@ -100,6 +104,11 @@ typedef void (*on_user_nick_change_t)(struct plugin_handle*, struct plugin_user*
|
||||
typedef void (*on_user_update_error_t)(struct plugin_handle*, struct plugin_user*, const char* reason);
|
||||
typedef void (*on_user_chat_msg_t)(struct plugin_handle*, struct plugin_user*, const char* message, int flags);
|
||||
|
||||
typedef void (*on_hub_started_t)(struct plugin_handle*, struct plugin_hub_info*);
|
||||
typedef void (*on_hub_reloaded_t)(struct plugin_handle*, struct plugin_hub_info*);
|
||||
typedef void (*on_hub_shutdown_t)(struct plugin_handle*, struct plugin_hub_info*);
|
||||
typedef void (*on_hub_error_t)(struct plugin_handle*, struct plugin_hub_info*, const char* message);
|
||||
|
||||
typedef plugin_st (*on_change_nick_t)(struct plugin_handle*, struct plugin_user*, const char* new_nick);
|
||||
|
||||
typedef plugin_st (*on_check_ip_early_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||
@ -126,6 +135,12 @@ struct plugin_funcs
|
||||
on_user_update_error_t on_user_update_error;/* A user has failed to update - nickname, etc. */
|
||||
on_user_chat_msg_t on_user_chat_message;/* A user has sent a public chat message */
|
||||
|
||||
// Log hub events
|
||||
on_hub_started_t on_hub_started; /* Triggered just after plugins are loaded and the hub is started. */
|
||||
on_hub_reloaded_t on_hub_reloaded; /* Triggered immediately after hub configuration is reloaded. */
|
||||
on_hub_shutdown_t on_hub_shutdown; /* Triggered just before the hub is being shut down and before plugins are unloaded. */
|
||||
on_hub_error_t on_hub_error; /* Triggered for log-worthy error messages */
|
||||
|
||||
// Activity events (can be intercepted and refused/accepted by a plugin)
|
||||
on_chat_msg_t on_chat_msg; /* A public chat message is about to be sent (can be intercepted) */
|
||||
on_private_msg_t on_private_msg; /* A public chat message is about to be sent (can be intercepted) */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This is a minimal example plugin for uhub.
|
||||
* A logging plugin for uhub.
|
||||
* Logs to either file or syslog.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
#include "adc/adcconst.h"
|
||||
#include "adc/sid.h"
|
||||
@ -9,40 +9,138 @@
|
||||
#include "util/ipcalc.h"
|
||||
#include "plugin_api/handle.h"
|
||||
|
||||
#include "util/misc.h"
|
||||
#include "util/config_token.h"
|
||||
#include <syslog.h>
|
||||
|
||||
struct ip_addr_encap;
|
||||
|
||||
struct log_data
|
||||
{
|
||||
enum {
|
||||
mode_file,
|
||||
mode_syslog
|
||||
} logmode;
|
||||
char* logfile;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static void reset(struct log_data* data)
|
||||
{
|
||||
/* set defaults */
|
||||
data->logmode = mode_file;
|
||||
data->logfile = NULL;
|
||||
data->fd = -1;
|
||||
}
|
||||
|
||||
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||
{
|
||||
plugin->error_msg = msg;
|
||||
}
|
||||
|
||||
static int log_open_file(struct plugin_handle* plugin, struct log_data* data)
|
||||
{
|
||||
data->fd = open(data->logfile, O_CREAT | O_APPEND | O_NOATIME | O_LARGEFILE | O_WRONLY, 0664);
|
||||
return (data->fd != -1);
|
||||
}
|
||||
|
||||
static struct log_data* log_open(struct plugin_handle* plugin, const char* config)
|
||||
static int log_open_syslog(struct plugin_handle* plugin)
|
||||
{
|
||||
openlog("uhub", 0, LOG_USER);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct log_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||
{
|
||||
struct log_data* data = (struct log_data*) hub_malloc(sizeof(struct log_data));
|
||||
data->logfile = strdup(config);
|
||||
data->fd = open(data->logfile, O_CREAT | O_APPEND | O_NOATIME | O_LARGEFILE | O_WRONLY, 0664);
|
||||
if (data->fd == -1)
|
||||
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||
char* token = cfg_token_get_first(tokens);
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
reset(data);
|
||||
|
||||
while (token)
|
||||
{
|
||||
set_error_message(plugin, "Unable to open log file!");
|
||||
hub_free(data->logfile);
|
||||
hub_free(data);
|
||||
return NULL;
|
||||
struct cfg_settings* setting = cfg_settings_split(token);
|
||||
|
||||
if (!setting)
|
||||
{
|
||||
set_error_message(plugin, "Unable to parse startup parameters");
|
||||
cfg_tokens_free(tokens);
|
||||
hub_free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(cfg_settings_get_key(setting), "file") == 0)
|
||||
{
|
||||
data->logfile = strdup(cfg_settings_get_value(setting));
|
||||
data->logmode = mode_file;
|
||||
}
|
||||
else if (strcmp(cfg_settings_get_key(setting), "syslog") == 0)
|
||||
{
|
||||
int use_syslog = 0;
|
||||
if (!string_to_boolean(cfg_settings_get_value(setting), &use_syslog))
|
||||
{
|
||||
data->logmode = (use_syslog) ? mode_syslog : mode_file;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error_message(plugin, "Unknown startup parameters given");
|
||||
cfg_tokens_free(tokens);
|
||||
cfg_settings_free(setting);
|
||||
hub_free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cfg_settings_free(setting);
|
||||
token = cfg_token_get_next(tokens);
|
||||
}
|
||||
|
||||
if (data->logmode == mode_file)
|
||||
{
|
||||
if ((data->logmode == mode_file && !data->logfile))
|
||||
{
|
||||
set_error_message(plugin, "No log file is given, use file=<path>");
|
||||
hub_free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!log_open_file(plugin, data))
|
||||
{
|
||||
hub_free(data->logfile);
|
||||
hub_free(data);
|
||||
set_error_message(plugin, "Unable to open log file");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!log_open_syslog(plugin))
|
||||
{
|
||||
hub_free(data->logfile);
|
||||
hub_free(data);
|
||||
set_error_message(plugin, "Unable to open syslog");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void log_close(struct log_data* data)
|
||||
{
|
||||
hub_free(data->logfile);
|
||||
close(data->fd);
|
||||
if (data->logmode == mode_file)
|
||||
{
|
||||
hub_free(data->logfile);
|
||||
close(data->fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
hub_free(data);
|
||||
}
|
||||
|
||||
@ -54,16 +152,25 @@ static void log_message(struct log_data* data, const char *format, ...)
|
||||
va_list args;
|
||||
ssize_t size = 0;
|
||||
|
||||
t = time(NULL);
|
||||
tmp = localtime(&t);
|
||||
strftime(logmsg, 32, "%Y-%m-%d %H:%M:%S ", tmp);
|
||||
if (data->logmode == mode_file)
|
||||
{
|
||||
t = time(NULL);
|
||||
tmp = localtime(&t);
|
||||
strftime(logmsg, 32, "%Y-%m-%d %H:%M:%S ", tmp);
|
||||
|
||||
va_start(args, format);
|
||||
size = vsnprintf(logmsg + 20, 1004, format, args);
|
||||
va_end(args);
|
||||
va_start(args, format);
|
||||
size = vsnprintf(logmsg + 20, 1004, format, args);
|
||||
va_end(args);
|
||||
|
||||
write(data->fd, logmsg, size + 20);
|
||||
fdatasync(data->fd);
|
||||
write(data->fd, logmsg, size + 20);
|
||||
fdatasync(data->fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
va_start(args, format);
|
||||
vsyslog(LOG_INFO, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
@ -101,7 +208,7 @@ int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||
plugin->funcs.on_user_logout = log_user_logout;
|
||||
plugin->funcs.on_user_nick_change = log_change_nick;
|
||||
|
||||
plugin->ptr = log_open(plugin, config);
|
||||
plugin->ptr = parse_config(config, plugin);
|
||||
if (!plugin->ptr)
|
||||
return -1;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user