Started working on mod_welcome which will replace the built-in file_motd and file_rules configuration options.
This commit is contained in:
parent
b24d4b85cd
commit
88dd1341d2
20
GNUmakefile
20
GNUmakefile
|
@ -155,7 +155,6 @@ libuhub_SOURCES := \
|
|||
src/network/connection.c \
|
||||
src/network/epoll.c \
|
||||
src/network/kqueue.c \
|
||||
src/network/network.c \
|
||||
src/network/select.c \
|
||||
src/network/timeout.c \
|
||||
src/network/timer.c
|
||||
|
@ -175,6 +174,7 @@ libutils_SOURCES := \
|
|||
src/util/log.c \
|
||||
src/util/memory.c \
|
||||
src/util/misc.c \
|
||||
src/network/network.c \
|
||||
src/util/rbtree.c \
|
||||
src/util/tiger.c
|
||||
|
||||
|
@ -213,6 +213,9 @@ autotest_OBJECTS = autotest.o
|
|||
plugin_example_SOURCES := src/plugins/mod_example.c
|
||||
plugin_example_TARGET := mod_example.so
|
||||
|
||||
plugin_welcome_SOURCES := src/plugins/mod_welcome.c
|
||||
plugin_welcome_TARGET := mod_welcome.so
|
||||
|
||||
plugin_logging_SOURCES := src/plugins/mod_logging.c
|
||||
plugin_logging_TARGET := mod_logging.so
|
||||
|
||||
|
@ -237,8 +240,9 @@ uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
|||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET) $(plugin_welcome_TARGET)
|
||||
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET)
|
||||
all_OBJECTS += $(all_plugins)
|
||||
|
||||
uhub_BINARY=uhub$(BIN_EXT)
|
||||
uhub-passwd_BINARY=uhub-passwd$(BIN_EXT)
|
||||
|
@ -246,16 +250,17 @@ adcrush_BINARY=adcrush$(BIN_EXT)
|
|||
admin_BINARY=uhub-admin$(BIN_EXT)
|
||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
||||
|
||||
ifeq ($(USE_PLUGINS),YES)
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET)
|
||||
all_OBJECTS += $(all_plugins)
|
||||
endif
|
||||
|
||||
.PHONY: revision.h.tmp all plugins
|
||||
|
||||
%.o: %.c version.h revision.h
|
||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
#%.so: %.c
|
||||
# $(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
||||
all: $(uhub_BINARY) $(uhub-passwd_BINARY) plugins
|
||||
|
||||
plugins: $(uhub_BINARY) $(all_plugins)
|
||||
|
@ -275,6 +280,9 @@ $(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc
|
|||
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCE) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_welcome_TARGET): $(plugin_welcome_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
#include "adc/adcconst.h"
|
||||
#include "adc/sid.h"
|
||||
#include "util/cbuffer.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/ipcalc.h"
|
||||
#include "plugin_api/handle.h"
|
||||
#include "plugin_api/command_api.h"
|
||||
|
||||
#include "util/misc.h"
|
||||
#include "util/config_token.h"
|
||||
#include <syslog.h>
|
||||
|
||||
#define MAX_WELCOME_SIZE 16384
|
||||
|
||||
struct welcome_data
|
||||
{
|
||||
char* motd_file;
|
||||
char* motd;
|
||||
char* rules_file;
|
||||
char* rules;
|
||||
struct plugin_command_handle* cmd_motd;
|
||||
struct plugin_command_handle* cmd_rules;
|
||||
};
|
||||
|
||||
static int command_handler_motd(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd);
|
||||
static int command_handler_rules(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd);
|
||||
|
||||
static char* read_file(const char* filename)
|
||||
{
|
||||
char* str;
|
||||
char buf[MAX_WELCOME_SIZE];
|
||||
int fd = open(filename, O_RDONLY);
|
||||
int ret;
|
||||
|
||||
if (fd == -1)
|
||||
return NULL;
|
||||
|
||||
ret = read(fd, buf, MAX_WELCOME_SIZE);
|
||||
close(fd);
|
||||
|
||||
buf[ret > 0 ? ret : 0] = 0;
|
||||
str = strdup(buf);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int read_motd(struct welcome_data* data)
|
||||
{
|
||||
data->motd = read_file(data->motd_file);
|
||||
return !!data->motd;
|
||||
}
|
||||
|
||||
int read_rules(struct welcome_data* data)
|
||||
{
|
||||
data->rules = read_file(data->rules_file);
|
||||
return !!data->rules;
|
||||
}
|
||||
|
||||
static void free_welcome_data(struct welcome_data* data)
|
||||
{
|
||||
hub_free(data->cmd_motd);
|
||||
hub_free(data->motd_file);
|
||||
hub_free(data->motd);
|
||||
hub_free(data->cmd_rules);
|
||||
hub_free(data->rules_file);
|
||||
hub_free(data->rules);
|
||||
hub_free(data);
|
||||
}
|
||||
|
||||
|
||||
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||
{
|
||||
plugin->error_msg = msg;
|
||||
}
|
||||
|
||||
static struct welcome_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||
{
|
||||
struct welcome_data* data = (struct welcome_data*) hub_malloc_zero(sizeof(struct welcome_data));
|
||||
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||
char* token = cfg_token_get_first(tokens);
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
while (token)
|
||||
{
|
||||
struct cfg_settings* setting = cfg_settings_split(token);
|
||||
|
||||
if (!setting)
|
||||
{
|
||||
set_error_message(plugin, "Unable to parse startup parameters");
|
||||
cfg_tokens_free(tokens);
|
||||
free_welcome_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(cfg_settings_get_key(setting), "motd") == 0)
|
||||
{
|
||||
data->motd_file = strdup(cfg_settings_get_value(setting));
|
||||
if (!read_motd(data))
|
||||
{
|
||||
set_error_message(plugin, "Unable to read motd file.");
|
||||
cfg_tokens_free(tokens);
|
||||
cfg_settings_free(setting);
|
||||
free_welcome_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->cmd_motd = hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||
PLUGIN_COMMAND_INITIALIZE(data->cmd_motd, (void*) data, "msg", "", auth_cred_guest, command_handler_motd, "Show the message of the day.");
|
||||
}
|
||||
else if (strcmp(cfg_settings_get_key(setting), "rules") == 0)
|
||||
{
|
||||
data->rules_file = strdup(cfg_settings_get_value(setting));
|
||||
if (!read_rules(data))
|
||||
{
|
||||
set_error_message(plugin, "Unable to read rules file.");
|
||||
cfg_tokens_free(tokens);
|
||||
cfg_settings_free(setting);
|
||||
free_welcome_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->cmd_rules = hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||
PLUGIN_COMMAND_INITIALIZE(data->cmd_rules, (void*) data, "rule", "", auth_cred_guest, command_handler_rules, "Show the hub rules.");
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error_message(plugin, "Unknown startup parameters given");
|
||||
cfg_tokens_free(tokens);
|
||||
cfg_settings_free(setting);
|
||||
free_welcome_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cfg_settings_free(setting);
|
||||
token = cfg_token_get_next(tokens);
|
||||
}
|
||||
|
||||
cfg_tokens_free(tokens);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static struct cbuffer* parse_message(struct plugin_user* user, const char* msg)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(strlen(msg));
|
||||
const char* start = msg;
|
||||
const char* offset = NULL;
|
||||
time_t timestamp = time(NULL);
|
||||
struct tm* now = localtime(×tamp);
|
||||
|
||||
while ((offset = strchr(start, '%')))
|
||||
{
|
||||
cbuf_append_bytes(buf, start, (offset - start));
|
||||
|
||||
offset++;
|
||||
switch (offset[0])
|
||||
{
|
||||
case 'n':
|
||||
cbuf_append(buf, user->nick);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
cbuf_append(buf, ip_convert_to_string(&user->addr));
|
||||
break;
|
||||
|
||||
case '%':
|
||||
cbuf_append(buf, "%");
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
cbuf_append_strftime(buf, "%H", now);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
cbuf_append_strftime(buf, "%I", now);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
cbuf_append_strftime(buf, "%P", now);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
cbuf_append_strftime(buf, "%p", now);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
cbuf_append_strftime(buf, "%M", now);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
cbuf_append_strftime(buf, "%S", now);
|
||||
break;
|
||||
}
|
||||
|
||||
start = offset + 1;
|
||||
}
|
||||
|
||||
if (*start)
|
||||
cbuf_append(buf, start);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void send_motd(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
{
|
||||
struct welcome_data* data = (struct welcome_data*) plugin->ptr;
|
||||
struct cbuffer* buf = NULL;
|
||||
if (data->motd)
|
||||
{
|
||||
buf = parse_message(user, data->motd);
|
||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||
cbuf_destroy(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_rules(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
{
|
||||
struct welcome_data* data = (struct welcome_data*) plugin->ptr;
|
||||
struct cbuffer* buf = NULL;
|
||||
if (data->rules)
|
||||
{
|
||||
buf = parse_message(user, data->rules);
|
||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||
cbuf_destroy(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
{
|
||||
send_motd(plugin, user);
|
||||
}
|
||||
|
||||
static int command_handler_motd(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||
{
|
||||
send_motd(plugin, user);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int command_handler_rules(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||
{
|
||||
send_rules(plugin, user);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||
{
|
||||
struct welcome_data* data;
|
||||
PLUGIN_INITIALIZE(plugin, "Welcome plugin", "0.1", "Sends a welcome message to users when they log into the hub.");
|
||||
data = parse_config(config, plugin);
|
||||
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
plugin->ptr = data;
|
||||
plugin->funcs.on_user_login = on_user_login;
|
||||
|
||||
if (data->cmd_motd)
|
||||
plugin->hub.command_add(plugin, data->cmd_motd);
|
||||
|
||||
if (data->cmd_rules)
|
||||
plugin->hub.command_add(plugin, data->cmd_rules);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plugin_unregister(struct plugin_handle* plugin)
|
||||
{
|
||||
struct welcome_data* data = (struct welcome_data*) plugin->ptr;
|
||||
|
||||
if (data->cmd_motd)
|
||||
plugin->hub.command_del(plugin, data->cmd_motd);
|
||||
|
||||
if (data->cmd_rules)
|
||||
plugin->hub.command_del(plugin, data->cmd_rules);
|
||||
|
||||
free_welcome_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue