Compare commits

...

8 Commits

Author SHA1 Message Date
Jan Vidar Krey
e59c21bdb0 Added all builtin commands plus some cleanups. 2011-09-02 11:12:37 +02:00
Jan Vidar Krey
8a6a10d4ec Cleaned up plugin callback hooks.
Started working on command storage by plugin.
2011-02-17 12:06:31 +01:00
Jan Vidar Krey
ff5609b018 Fix adc admin client main loop so that it exits on error. 2011-02-17 11:59:15 +01:00
Jan Vidar Krey
5ca27a1a6d Added function pointers for plugins to access hub internals. 2011-02-17 11:59:15 +01:00
Jan Vidar Krey
963564dc31 Aligned the hub_user and plugin_user data structures so that they can be mixed without a conversion.
The hub_user struct starts with the exact same data and size,
but contain more information which is purely internal to the hub.

Plugins thus have only access to the plugin_user struct part of it.
A simple cast from hub_user to plugin_user is legal.
2011-02-17 11:59:15 +01:00
Jan Vidar Krey
a761d4eec5 Split up plugin API header files somewhat. 2011-02-17 11:59:15 +01:00
Jan Vidar Krey
70a1fd543d Commands can be added and removed dynamically by plugins. 2011-02-17 11:59:14 +01:00
Jan Vidar Krey
6d902fce39 Fix conflicts while rebasing. 2011-02-17 11:59:14 +01:00
21 changed files with 981 additions and 469 deletions

View File

@ -1,6 +1,8 @@
Authors of uHub Authors of uhub
=============== ===============
Jan Vidar Krey, Design and implementation Jan Vidar Krey, Design and implementation
E_zombie, Centos/RedHat customization scripts and heavy load testing E_zombie, Centos/RedHat customization scripts and heavy load testing
FleetCommand, Hub topic
MiMic, Implemented user commands

View File

@ -140,6 +140,7 @@ libuhub_SOURCES := \
src/core/route.c \ src/core/route.c \
src/core/user.c \ src/core/user.c \
src/core/usermanager.c \ src/core/usermanager.c \
src/core/plugincallback.c \
src/core/plugininvoke.c \ src/core/plugininvoke.c \
src/core/pluginloader.c \ src/core/pluginloader.c \
src/network/backend.c \ src/network/backend.c \
@ -209,6 +210,8 @@ plugin_auth_sqlite_SOURCES := src/plugins/mod_auth_sqlite.c
plugin_auth_sqlite_TARGET := mod_auth_sqlite.so plugin_auth_sqlite_TARGET := mod_auth_sqlite.so
plugin_auth_sqlite_LIBS := -lsqlite3 plugin_auth_sqlite_LIBS := -lsqlite3
plugin_chat_history_SOURCE := src/plugins/mod_chat_history.c
plugin_chat_history_TARGET := mod_chat_history.so
# Source to objects # Source to objects
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o) libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
@ -221,7 +224,7 @@ adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
admin_OBJECTS := $(admin_SOURCES:.c=.o) admin_OBJECTS := $(admin_SOURCES:.c=.o)
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS) 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) all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET)
uhub_BINARY=uhub$(BIN_EXT) uhub_BINARY=uhub$(BIN_EXT)
adcrush_BINARY=adcrush$(BIN_EXT) adcrush_BINARY=adcrush$(BIN_EXT)
@ -253,6 +256,9 @@ $(plugin_example_TARGET): $(plugin_example_SOURCES)
$(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o $(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCE) $(libutils_OBJECTS)
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS) $(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)

View File

@ -20,7 +20,11 @@
#ifndef HAVE_UHUB_ADC_CONSTANTS_H #ifndef HAVE_UHUB_ADC_CONSTANTS_H
#define HAVE_UHUB_ADC_CONSTANTS_H #define HAVE_UHUB_ADC_CONSTANTS_H
#ifndef SID_T_DEFINED
typedef uint32_t sid_t; typedef uint32_t sid_t;
#define SID_T_DEFINED
#endif
typedef uint32_t fourcc_t; typedef uint32_t fourcc_t;
/* Internal uhub limit */ /* Internal uhub limit */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -19,4 +19,80 @@
#include "uhub.h" #include "uhub.h"
extern int command_dipatcher(struct hub_info* hub, struct hub_user* user, const char* message); struct command_base;
struct hub_command
{
const char* message;
char* prefix;
size_t prefix_len;
struct linked_list* args;
};
typedef int (*command_handler)(struct command_base*, struct hub_user* user, struct hub_command*);
/**
* Argument codes are used to automatically parse arguments
* for a a hub command.
*
* n = nick name (must exist in hub session)
* i = CID (must exist in hub)
* a = (IP) address (must be a valid IPv4 or IPv6 address)
* m = message (string)
* p = password (string)
* C = credentials (see auth_string_to_cred).
* c = command (name of command)
* N = number (integer)
*
* Prefix an argument with ? to make it optional.
* NOTE; if an argument is optional then all following arguments must also be optional.
*
* Example:
* "nia" means "nick cid ip"
* "n?p" means "nick [password]" where password is optional.
*
*/
struct command_handle
{
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
size_t length; /**<<< "Length of the prefix" */
const char* args; /**<<< "Argument codes (see above)" */
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
command_handler handler; /**<<< "Function pointer for the command" */
const char* description; /**<<< "Description for the command" */
const char* command_origin; /**<<< "Name of module where the command is implemented." */
};
/**
* Returns NULL on error, or handle
*/
extern struct command_base* command_initialize(struct hub_info* hub);
extern void command_shutdown(struct command_base* cbase);
/**
* Add a new command to the command base.
* Returns 1 on success, or 0 on error.
*/
extern int command_add(struct command_base*, struct command_handle*);
/**
* Remove a command from the command base.
* Returns 1 on success, or 0 on error.
*/
extern int command_del(struct command_base*, struct command_handle*);
/**
* Returns 1 if a command is available to a user (user has access to run it.)
*/
extern int command_is_available(struct command_handle*, struct hub_user* user);
/**
* Dispatch a message and forward it as a command.
* Returns 1 if the message should be forwarded as a chat message, or 0 if
* it is supposed to be handled internally in the dispatcher.
*
* This will break the message down into a struct hub_command and invoke the command handler
* for that command if the sufficient access credentials are met.
*/
extern int command_invoke(struct command_base*, struct hub_user* user, const char* message);

View File

@ -289,7 +289,7 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
} }
else else
{ {
relay = command_dipatcher(hub, u, message); relay = command_invoke(hub->commands, u, message);
} }
} }
@ -810,6 +810,9 @@ struct hub_info* hub_start_service(struct hub_config* config)
hub->status = hub_status_running; hub->status = hub_status_running;
g_hub = hub; g_hub = hub;
// Start the hub command sub-system
hub->commands = command_initialize(hub);
return hub; return hub;
} }
@ -834,6 +837,7 @@ void hub_shutdown_service(struct hub_info* hub)
list_destroy(hub->chat_history); list_destroy(hub->chat_history);
list_clear(hub->logout_info, &hub_free); list_clear(hub->logout_info, &hub_free);
list_destroy(hub->logout_info); list_destroy(hub->logout_info);
command_shutdown(hub->commands);
hub_free(hub); hub_free(hub);
hub = 0; hub = 0;
g_hub = 0; g_hub = 0;
@ -849,7 +853,7 @@ void hub_plugins_load(struct hub_info* hub)
if (!hub->plugins) if (!hub->plugins)
return; return;
if (plugin_initialize(hub->config, hub->plugins) < 0) if (plugin_initialize(hub->config, hub) < 0)
{ {
hub_free(hub->plugins); hub_free(hub->plugins);
hub->plugins = 0; hub->plugins = 0;
@ -969,37 +973,6 @@ void hub_free_variables(struct hub_info* hub)
adc_msg_free(hub->command_support); adc_msg_free(hub->command_support);
} }
/**
* @return 1 if nickname is in use, or 0 if not used.
*/
static int is_nick_in_use(struct hub_info* hub, const char* nick)
{
struct hub_user* lookup = uman_get_user_by_nick(hub, nick);
if (lookup)
{
return 1;
}
return 0;
}
/**
* @return 1 if CID is in use, or 0 if not used.
*/
static int is_cid_in_use(struct hub_info* hub, const char* cid)
{
struct hub_user* lookup = uman_get_user_by_cid(hub, cid);
if (lookup)
{
return 1;
}
return 0;
}
static void set_status_code(enum msg_status_level level, int code, char buffer[4]) static void set_status_code(enum msg_status_level level, int code, char buffer[4])
{ {
buffer[0] = ('0' + (int) level); buffer[0] = ('0' + (int) level);

View File

@ -114,6 +114,8 @@ struct hub_info
struct linked_list* chat_history; /* Chat history */ struct linked_list* chat_history; /* Chat history */
struct linked_list* logout_info; /* Log of people logging out. */ struct linked_list* logout_info; /* Log of people logging out. */
struct command_base* commands; /* Hub command handler */
#ifdef PLUGIN_SUPPORT #ifdef PLUGIN_SUPPORT
struct uhub_plugins* plugins; struct uhub_plugins* plugins;
#endif #endif

View File

@ -378,7 +378,7 @@ static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct
ua = adc_msg_unescape(ua_encoded); ua = adc_msg_unescape(ua_encoded);
if (ua) if (ua)
{ {
memcpy(user->user_agent, ua, MIN(strlen(ua), MAX_UA_LEN)); memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
hub_free(ua); hub_free(ua);
} }
} }

84
src/core/plugincallback.c Normal file
View File

@ -0,0 +1,84 @@
/*
* 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 "uhub.h"
struct plugin_callback_data
{
struct linked_list* commands;
};
/*
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
{
uhub_assert(plugin && plugin->handle && plugin->handle->callback_data);
struct plugin_callback_data* data = (struct plugin_callback_data*) plugin->handle->callback_data;
return data;
}
*/
static struct hub_user* convert_user_type(struct plugin_user* user)
{
struct hub_user* huser = (struct hub_user*) user;
return huser;
}
static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* user, const char* message)
{
// struct plugin_callback_data* data = get_callback_data(plugin);
char* buffer = adc_msg_escape(message);
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(plugin_get_hub(plugin), convert_user_type(user), command);
adc_msg_free(command);
hub_free(buffer);
return 1;
}
static int cbfunc_user_disconnect(struct plugin_handle* plugin, struct plugin_user* user)
{
// struct plugin_callback_data* data = get_callback_data(plugin);
hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked);
return 0;
}
static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
{
// struct plugin_callback_data* data = get_callback_data(plugin);
return 0;
}
static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_command_handle* cmdh)
{
// struct plugin_callback_data* data = get_callback_data(plugin);
return 0;
}
void plugin_register_callback_functions(struct plugin_handle* handle)
{
handle->hub.send_message = cbfunc_send_message;
handle->hub.user_disconnect = cbfunc_user_disconnect;
handle->hub.command_add = cbfunc_command_add;
handle->hub.command_del = cbfunc_command_del;
}
void plugin_unregister_callback_functions(struct plugin_handle* handle)
{
}

28
src/core/plugincallback.h Normal file
View File

@ -0,0 +1,28 @@
/*
* 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/>.
*
*/
#ifndef HAVE_UHUB_PLUGIN_CALLBACK_H
#define HAVE_UHUB_PLUGIN_CALLBACK_H
struct plugin_handle;
extern void plugin_register_callback_functions(struct plugin_handle* handle);
extern void plugin_unregister_callback_functions(struct plugin_handle* handle);
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_H */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -74,14 +74,10 @@
#define PLUGIN_INVOKE_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); }) #define PLUGIN_INVOKE_3(HUB, FUNCNAME, ARG1, ARG2, ARG3) INVOKE(HUB, FUNCNAME, { plugin->funcs.FUNCNAME(plugin, ARG1, ARG2, ARG3); })
static void convert_user_type(struct plugin_user* puser, struct hub_user* user) static struct plugin_user* convert_user_type(struct hub_user* user)
{ {
puser->sid = user->id.sid; struct plugin_user* puser = (struct plugin_user*) user;
puser->nick = user->id.nick; return puser;
puser->cid = user->id.cid;
puser->user_agent = user->user_agent;
puser->addr = user->id.addr;
puser->credentials = user->credentials;
} }
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr) plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr)
@ -106,85 +102,71 @@ void plugin_log_connection_denied(struct hub_info* hub, struct ip_addr_encap* ip
void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* who) void plugin_log_user_login_success(struct hub_info* hub, struct hub_user* who)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_1(hub, on_user_login, user);
PLUGIN_INVOKE_1(hub, on_user_login, &user);
} }
void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason) void plugin_log_user_login_error(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_2(hub, on_user_login_error, user, reason);
PLUGIN_INVOKE_2(hub, on_user_login_error, &user, reason);
} }
void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason) void plugin_log_user_logout(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_2(hub, on_user_logout, user, reason);
PLUGIN_INVOKE_2(hub, on_user_logout, &user, reason);
} }
void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick) void plugin_log_user_nick_change(struct hub_info* hub, struct hub_user* who, const char* new_nick)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_2(hub, on_user_nick_change, user, new_nick);
PLUGIN_INVOKE_2(hub, on_user_nick_change, &user, new_nick);
} }
void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason) void plugin_log_user_update_error(struct hub_info* hub, struct hub_user* who, const char* reason)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_2(hub, on_user_update_error, user, reason);
PLUGIN_INVOKE_2(hub, on_user_update_error, &user, reason);
} }
void plugin_log_chat_message(struct hub_info* hub, struct hub_user* who, const char* message, int flags) void plugin_log_chat_message(struct hub_info* hub, struct hub_user* who, const char* message, int flags)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(who);
convert_user_type(&user, who); PLUGIN_INVOKE_3(hub, on_user_chat_message, user, message, flags);
PLUGIN_INVOKE_3(hub, on_user_chat_message, &user, message, flags);
} }
plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags) plugin_st plugin_handle_chat_message(struct hub_info* hub, struct hub_user* from, const char* message, int flags)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(from);
convert_user_type(&user, from); PLUGIN_INVOKE_STATUS_2(hub, on_chat_msg, user, message);
PLUGIN_INVOKE_STATUS_2(hub, on_chat_msg, &user, message);
} }
plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags) plugin_st plugin_handle_private_message(struct hub_info* hub, struct hub_user* from, struct hub_user* to, const char* message, int flags)
{ {
struct plugin_user user1; struct plugin_user* user1 = convert_user_type(from);
struct plugin_user user2; struct plugin_user* user2 = convert_user_type(to);
convert_user_type(&user1, from); PLUGIN_INVOKE_STATUS_3(hub, on_private_msg, user1, user2, message);
convert_user_type(&user2, to);
PLUGIN_INVOKE_STATUS_3(hub, on_private_msg, &user1, &user2, message);
} }
plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data) plugin_st plugin_handle_search(struct hub_info* hub, struct hub_user* from, const char* data)
{ {
struct plugin_user user; struct plugin_user* user = convert_user_type(from);
convert_user_type(&user, from); PLUGIN_INVOKE_STATUS_2(hub, on_search, user, data);
PLUGIN_INVOKE_STATUS_2(hub, on_search, &user, data);
} }
plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to) plugin_st plugin_handle_connect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
{ {
struct plugin_user user1; struct plugin_user* user1 = convert_user_type(from);
struct plugin_user user2; struct plugin_user* user2 = convert_user_type(to);
convert_user_type(&user1, from); PLUGIN_INVOKE_STATUS_2(hub, on_p2p_connect, user1, user2);
convert_user_type(&user2, to);
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_connect, &user1, &user2);
} }
plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to) plugin_st plugin_handle_revconnect(struct hub_info* hub, struct hub_user* from, struct hub_user* to)
{ {
struct plugin_user user1; struct plugin_user* user1 = convert_user_type(from);
struct plugin_user user2; struct plugin_user* user2 = convert_user_type(to);
convert_user_type(&user1, from); PLUGIN_INVOKE_STATUS_2(hub, on_p2p_revconnect, user1, user2);
convert_user_type(&user2, to);
PLUGIN_INVOKE_STATUS_2(hub, on_p2p_revconnect, &user1, &user2);
} }
plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info) plugin_st plugin_auth_get_user(struct hub_info* hub, const char* nickname, struct auth_info* info)

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -22,6 +22,19 @@
#ifdef PLUGIN_SUPPORT #ifdef PLUGIN_SUPPORT
#include "plugin_api/handle.h" #include "plugin_api/handle.h"
struct plugin_hub_internals
{
struct hub_info* hub;
plugin_unregister_f unregister;
};
static struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
{
assert(handle && handle->handle && handle->handle->internals);
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) handle->handle->internals;
return internals;
}
struct uhub_plugin* plugin_open(const char* filename) struct uhub_plugin* plugin_open(const char* filename)
{ {
LOG_TRACE("plugin_open: \"%s\"", filename); LOG_TRACE("plugin_open: \"%s\"", filename);
@ -41,6 +54,8 @@ struct uhub_plugin* plugin_open(const char* filename)
return 0; return 0;
} }
plugin->internals = hub_malloc_zero(sizeof(struct plugin_hub_internals));
return plugin; return plugin;
#else #else
return 0; return 0;
@ -49,6 +64,7 @@ struct uhub_plugin* plugin_open(const char* filename)
void plugin_close(struct uhub_plugin* plugin) void plugin_close(struct uhub_plugin* plugin)
{ {
hub_free(plugin->internals);
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
dlclose(plugin->handle); dlclose(plugin->handle);
hub_free(plugin); hub_free(plugin);
@ -65,13 +81,16 @@ void* plugin_lookup_symbol(struct uhub_plugin* plugin, const char* symbol)
#endif #endif
} }
struct plugin_handle* plugin_load(const char* filename, const char* config)
struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub)
{ {
plugin_register_f register_f; plugin_register_f register_f;
plugin_unregister_f unregister_f; plugin_unregister_f unregister_f;
int ret; int ret;
struct plugin_handle* handle = hub_malloc_zero(sizeof(struct plugin_handle)); struct plugin_handle* handle = hub_malloc_zero(sizeof(struct plugin_handle));
struct uhub_plugin* plugin = plugin_open(filename); struct uhub_plugin* plugin = plugin_open(filename);
struct plugin_hub_internals* internals;
if (!plugin) if (!plugin)
return NULL; return NULL;
@ -86,6 +105,10 @@ struct plugin_handle* plugin_load(const char* filename, const char* config)
register_f = plugin_lookup_symbol(plugin, "plugin_register"); register_f = plugin_lookup_symbol(plugin, "plugin_register");
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister"); unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
plugin_register_callback_functions(handle);
internals = (struct plugin_hub_internals*) plugin->internals;
if (register_f && unregister_f) if (register_f && unregister_f)
{ {
ret = register_f(handle, config); ret = register_f(handle, config);
@ -95,7 +118,11 @@ struct plugin_handle* plugin_load(const char* filename, const char* config)
{ {
LOG_INFO("Loaded plugin: %s: %s, version %s.", filename, handle->name, handle->version); LOG_INFO("Loaded plugin: %s: %s, version %s.", filename, handle->name, handle->version);
LOG_TRACE("Plugin API version: %d (func table size: " PRINTF_SIZE_T ")", handle->plugin_api_version, handle->plugin_funcs_size); LOG_TRACE("Plugin API version: %d (func table size: " PRINTF_SIZE_T ")", handle->plugin_api_version, handle->plugin_funcs_size);
plugin->unregister = unregister_f;
// Set hub internals
internals->unregister = unregister_f;
internals->hub = hub;
return handle; return handle;
} }
else else
@ -116,15 +143,18 @@ struct plugin_handle* plugin_load(const char* filename, const char* config)
void plugin_unload(struct plugin_handle* plugin) void plugin_unload(struct plugin_handle* plugin)
{ {
plugin->handle->unregister(plugin); struct plugin_hub_internals* internals = get_internals(plugin);
plugin_unregister_callback_functions(plugin);
internals->unregister(plugin);
plugin_close(plugin->handle); plugin_close(plugin->handle);
} }
static int plugin_parse_line(char* line, int line_count, void* ptr_data) static int plugin_parse_line(char* line, int line_count, void* ptr_data)
{ {
struct uhub_plugins* handle = (struct uhub_plugins*) ptr_data; struct hub_info* hub = (struct hub_info*) ptr_data;
struct plugin_handle* plugin; struct uhub_plugins* handle = hub->plugins;
struct cfg_tokens* tokens = cfg_tokenize(line); struct cfg_tokens* tokens = cfg_tokenize(line);
struct plugin_handle* plugin;
char *directive, *soname, *params; char *directive, *soname, *params;
if (cfg_token_count(tokens) == 0) if (cfg_token_count(tokens) == 0)
@ -149,7 +179,7 @@ static int plugin_parse_line(char* line, int line_count, void* ptr_data)
params = ""; params = "";
LOG_TRACE("Load plugin: \"%s\", params=\"%s\"", soname, params); LOG_TRACE("Load plugin: \"%s\", params=\"%s\"", soname, params);
plugin = plugin_load(soname, params); plugin = plugin_load(soname, params, hub);
if (plugin) if (plugin)
{ {
list_append(handle->loaded, plugin); list_append(handle->loaded, plugin);
@ -162,12 +192,12 @@ static int plugin_parse_line(char* line, int line_count, void* ptr_data)
return -1; return -1;
} }
int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle) int plugin_initialize(struct hub_config* config, struct hub_info* hub)
{ {
int ret; int ret;
handle->loaded = list_create(); hub->plugins->loaded = list_create();
if (!handle->loaded) if (!hub->plugins->loaded)
return -1; return -1;
if (config) if (config)
@ -175,7 +205,7 @@ int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle)
if (!*config->file_plugins) if (!*config->file_plugins)
return 0; return 0;
ret = file_read_lines(config->file_plugins, handle, &plugin_parse_line); ret = file_read_lines(config->file_plugins, hub, &plugin_parse_line);
if (ret == -1) if (ret == -1)
return -1; return -1;
} }
@ -195,4 +225,11 @@ void plugin_shutdown(struct uhub_plugins* handle)
list_destroy(handle->loaded); list_destroy(handle->loaded);
} }
// Used internally only
struct hub_info* plugin_get_hub(struct plugin_handle* plugin)
{
struct plugin_hub_internals* data = get_internals(plugin);
return data->hub;
}
#endif /* PLUGIN_SUPPORT */ #endif /* PLUGIN_SUPPORT */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -23,13 +23,15 @@
#include "plugin_api/handle.h" #include "plugin_api/handle.h"
struct hub_config; struct hub_config;
struct hub_info;
struct linked_list; struct linked_list;
struct plugin_handle; struct plugin_handle;
struct uhub_plugin struct uhub_plugin
{ {
void* handle; void* handle;
plugin_unregister_f unregister; void* internals; // Hub internal stuff
void* callback_data; // Hub internal stuff
}; };
struct uhub_plugins struct uhub_plugins
@ -38,11 +40,11 @@ struct uhub_plugins
}; };
// High level plugin loader ode // High level plugin loader ode
extern struct plugin_handle* plugin_load(const char* filename, const char* config); extern struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub);
extern void plugin_unload(struct plugin_handle* plugin); extern void plugin_unload(struct plugin_handle* plugin);
// extern void plugin_unload(struct plugin_handle*); // extern void plugin_unload(struct plugin_handle*);
extern int plugin_initialize(struct hub_config* config, struct uhub_plugins* handle); extern int plugin_initialize(struct hub_config* config, struct hub_info* hub);
extern void plugin_shutdown(struct uhub_plugins* handle); extern void plugin_shutdown(struct uhub_plugins* handle);
// Low level plugin loader code (used internally) // Low level plugin loader code (used internally)
@ -50,5 +52,8 @@ extern struct uhub_plugin* plugin_open(const char* filename);
extern void plugin_close(struct uhub_plugin*); extern void plugin_close(struct uhub_plugin*);
extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol); extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol);
// Used internally only
extern struct hub_info* plugin_get_hub(struct plugin_handle*);
#endif /* HAVE_UHUB_PLUGIN_LOADER_H */ #endif /* HAVE_UHUB_PLUGIN_LOADER_H */

View File

@ -82,8 +82,9 @@ extern const char* user_get_quit_reason_string(enum user_quit_reason);
struct hub_user_info struct hub_user_info
{ {
sid_t sid; /** session ID */ sid_t sid; /** session ID */
char cid[MAX_CID_LEN+1]; /** global client ID */
char nick[MAX_NICK_LEN+1]; /** User's nick name */ char nick[MAX_NICK_LEN+1]; /** User's nick name */
char cid[MAX_CID_LEN+1]; /** global client ID */
char user_agent[MAX_UA_LEN+1];/** User agent string */
struct ip_addr_encap addr; /** User's IP address */ struct ip_addr_encap addr; /** User's IP address */
}; };
@ -105,11 +106,10 @@ struct hub_user_limits
struct hub_user struct hub_user
{ {
enum user_state state; /** see enum user_state */
enum auth_credentials credentials; /** see enum user_credentials */
struct hub_user_info id; /** Contains nick name and CID */ struct hub_user_info id; /** Contains nick name and CID */
enum auth_credentials credentials; /** see enum user_credentials */
enum user_state state; /** see enum user_state */
uint32_t flags; /** see enum user_features */ uint32_t flags; /** see enum user_features */
char user_agent[MAX_UA_LEN+1];/** User agent string */
struct linked_list* feature_cast; /** Features supported by feature cast */ struct linked_list* feature_cast; /** Features supported by feature cast */
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */ struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
struct hub_info* hub; /** The hub instance this user belong to */ struct hub_info* hub; /** The hub instance this user belong to */

View File

@ -0,0 +1,79 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, 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/>.
*
*/
#ifndef HAVE_UHUB_PLUGIN_API_H
#define HAVE_UHUB_PLUGIN_API_H
/**
* This file describes the interface a plugin implementation may use from
* uhub.
*/
#include "system.h"
#include "plugin_api/types.h"
struct plugin_command
{
const char* message;
char* prefix;
size_t prefix_len;
struct linked_list* args;
};
typedef int (*plugin_command_handler)(struct plugin_handle*, struct plugin_user* to, struct plugin_command*);
struct plugin_command_handle
{
void* internal_handle; /**<<< "Internal used by the hub only" */
struct plugin_handle* handle; /**<<< "The plugin handle this is associated with" */
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
size_t length; /**<<< "Length of the prefix" */
const char* args; /**<<< "Argument codes" */
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
plugin_command_handler handler; /**<<< "Function pointer for the command" */
const char* description; /**<<< "Description for the command" */
};
#define PLUGIN_COMMAND_INITIALIZE(PTR, HANDLE, PREFIX, ARGS, CRED, CALLBACK, DESC) \
do { \
PTR->internal_handle = 0; \
PTR->handle = HANDLE; \
PTR->prefix = PREFIX; \
PTR->length = strlen(PREFIX); \
PTR->args = ARGS; \
PTR->cred = CRED; \
PTR->handler = CALLBACK; \
PTR->description = DESC; \
} while (0)
extern int plugin_command_add(struct plugin_handle*, struct plugin_command_handle*);
extern int plugin_command_del(struct plugin_handle*, struct plugin_command_handle*);
/**
* Send a message to a user.
* From the user's perspective the message will originate from the hub.
*/
extern int plugin_command_send_message(struct plugin_handle*, struct plugin_user* to, const char* message);
/**
* Send a reply to a command.
*/
extern int plugin_command_send_reply(struct plugin_handle*, struct plugin_user* user, struct plugin_command* command, const char* message);
#endif /* HAVE_UHUB_PLUGIN_API_H */

View File

@ -20,69 +20,14 @@
#ifndef HAVE_UHUB_PLUGIN_HANDLE_H #ifndef HAVE_UHUB_PLUGIN_HANDLE_H
#define HAVE_UHUB_PLUGIN_HANDLE_H #define HAVE_UHUB_PLUGIN_HANDLE_H
/**
* This file describes the interface a uhub uses to interact with plugins.
*/
#include "system.h" #include "system.h"
#include "util/credentials.h" #include "util/credentials.h"
#include "util/ipcalc.h" #include "util/ipcalc.h"
#include "plugin_api/types.h"
#define PLUGIN_API_VERSION 1
#ifndef MAX_NICK_LEN
#define MAX_NICK_LEN 64
#endif
#ifndef MAX_PASS_LEN
#define MAX_PASS_LEN 64
#endif
#ifndef MAX_CID_LEN
#define MAX_CID_LEN 39
#endif
struct plugin_handle;
struct plugin_user
{
unsigned int sid;
const char* nick;
const char* cid;
const char* user_agent;
struct ip_addr_encap addr;
enum auth_credentials credentials;
};
enum plugin_status
{
st_default = 0, /* Use default */
st_allow = 1, /* Allow action */
st_deny = -1, /* Deny action */
};
typedef enum plugin_status plugin_st;
struct auth_info
{
char nickname[MAX_NICK_LEN+1];
char password[MAX_PASS_LEN+1];
enum auth_credentials credentials;
};
enum ban_flags
{
ban_nickname = 0x01, /* Nickname is banned */
ban_cid = 0x02, /* CID is banned */
ban_ip = 0x04, /* IP address (range) is banned */
};
struct ban_info
{
unsigned int flags; /* See enum ban_flags. */
char nickname[MAX_NICK_LEN+1]; /* Nickname - only defined if (ban_nickname & flags). */
char cid[MAX_CID_LEN+1]; /* CID - only defined if (ban_cid & flags). */
struct ip_addr_encap ip_addr_lo; /* Low IP address of an IP range */
struct ip_addr_encap ip_addr_hi; /* High IP address of an IP range */
time_t expiry; /* Time when the ban record expires */
};
typedef plugin_st (*on_chat_msg_t)(struct plugin_handle*, struct plugin_user* from, const char* message); typedef plugin_st (*on_chat_msg_t)(struct plugin_handle*, struct plugin_user* from, const char* message);
typedef plugin_st (*on_private_msg_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to, const char* message); typedef plugin_st (*on_private_msg_t)(struct plugin_handle*, struct plugin_user* from, struct plugin_user* to, const char* message);
@ -112,6 +57,9 @@ typedef plugin_st (*auth_register_user_t)(struct plugin_handle*, struct auth_inf
typedef plugin_st (*auth_update_user_t)(struct plugin_handle*, struct auth_info* user); typedef plugin_st (*auth_update_user_t)(struct plugin_handle*, struct auth_info* user);
typedef plugin_st (*auth_delete_user_t)(struct plugin_handle*, struct auth_info* user); typedef plugin_st (*auth_delete_user_t)(struct plugin_handle*, struct auth_info* user);
/**
* These are callbacks used for the hub to invoke functions in plugins.
*/
struct plugin_funcs struct plugin_funcs
{ {
// Log events for connections // Log events for connections
@ -142,9 +90,28 @@ struct plugin_funcs
// Login check functions // Login check functions
on_check_ip_early_t login_check_ip_early; on_check_ip_early_t login_check_ip_early;
on_check_ip_late_t login_check_ip_late; on_check_ip_late_t login_check_ip_late;
}; };
struct plugin_command_handle;
typedef int (*hfunc_send_message)(struct plugin_handle*, struct plugin_user* user, const char* message);
typedef int (*hfunc_user_disconnect)(struct plugin_handle*, struct plugin_user* user);
typedef int (*hfunc_command_add)(struct plugin_handle*, struct plugin_command_handle*);
typedef int (*hfunc_command_del)(struct plugin_handle*, struct plugin_command_handle*);
/**
* These are functions created and initialized by the hub and which can be used
* by plugins to access functionality internal to the hub.
*/
struct plugin_hub_funcs
{
hfunc_send_message send_message;
hfunc_user_disconnect user_disconnect;
hfunc_command_add command_add;
hfunc_command_del command_del;
};
struct plugin_handle struct plugin_handle
{ {
struct uhub_plugin* handle; /* Must NOT be modified by the plugin */ struct uhub_plugin* handle; /* Must NOT be modified by the plugin */
@ -155,9 +122,11 @@ struct plugin_handle
const char* error_msg; /* Error message for registration error. */ const char* error_msg; /* Error message for registration error. */
size_t plugin_api_version; /* Plugin API version */ size_t plugin_api_version; /* Plugin API version */
size_t plugin_funcs_size; /* Size of the plugin funcs */ size_t plugin_funcs_size; /* Size of the plugin funcs */
struct plugin_funcs funcs; struct plugin_funcs funcs; /* Table of functions that can be implemented by a plugin */
struct plugin_hub_funcs hub; /* Table of core hub functions that can be used by a plugin */
}; };
#define PLUGIN_INITIALIZE(PTR, NAME, VERSION, DESCRIPTION) \ #define PLUGIN_INITIALIZE(PTR, NAME, VERSION, DESCRIPTION) \
do { \ do { \
PTR->name = NAME; \ PTR->name = NAME; \

View File

@ -0,0 +1,29 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, 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/>.
*
*/
#ifndef HAVE_UHUB_PLUGIN_MESSAGE_API_H
#define HAVE_UHUB_PLUGIN_MESSAGE_API_H
/**
* Send an informal message to a user.
* The user will see the message as if the hub sent it.
*/
extern int plugin_send_message(struct plugin_handle*, struct plugin_user* to, const char* message);
#endif /* HAVE_UHUB_PLUGIN_API_H */

91
src/plugin_api/types.h Normal file
View File

@ -0,0 +1,91 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, 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/>.
*
*/
#ifndef HAVE_UHUB_PLUGIN_TYPES_H
#define HAVE_UHUB_PLUGIN_TYPES_H
#define PLUGIN_API_VERSION 1
#ifndef MAX_NICK_LEN
#define MAX_NICK_LEN 64
#endif
#ifndef MAX_PASS_LEN
#define MAX_PASS_LEN 64
#endif
#ifndef MAX_CID_LEN
#define MAX_CID_LEN 39
#endif
#ifndef MAX_UA_LEN
#define MAX_UA_LEN 32
#endif
#ifndef SID_T_DEFINED
typedef uint32_t sid_t;
#define SID_T_DEFINED
#endif
struct plugin_handle;
struct plugin_user
{
sid_t sid;
char nick[MAX_NICK_LEN+1];
char cid[MAX_CID_LEN+1];
char user_agent[MAX_UA_LEN+1];
struct ip_addr_encap addr;
enum auth_credentials credentials;
};
enum plugin_status
{
st_default = 0, /* Use default */
st_allow = 1, /* Allow action */
st_deny = -1, /* Deny action */
};
typedef enum plugin_status plugin_st;
struct auth_info
{
char nickname[MAX_NICK_LEN+1];
char password[MAX_PASS_LEN+1];
enum auth_credentials credentials;
};
enum ban_flags
{
ban_nickname = 0x01, /* Nickname is banned */
ban_cid = 0x02, /* CID is banned */
ban_ip = 0x04, /* IP address (range) is banned */
};
struct ban_info
{
unsigned int flags; /* See enum ban_flags. */
char nickname[MAX_NICK_LEN+1]; /* Nickname - only defined if (ban_nickname & flags). */
char cid[MAX_CID_LEN+1]; /* CID - only defined if (ban_cid & flags). */
struct ip_addr_encap ip_addr_lo; /* Low IP address of an IP range */
struct ip_addr_encap ip_addr_hi; /* High IP address of an IP range */
time_t expiry; /* Time when the ban record expires */
};
#endif /* HAVE_UHUB_PLUGIN_TYPES_H */

View File

@ -26,6 +26,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
case ADC_CLIENT_PASSWORD_REQ: case ADC_CLIENT_PASSWORD_REQ:
puts("*** Requesting password."); puts("*** Requesting password.");
break;
case ADC_CLIENT_LOGGED_IN: case ADC_CLIENT_LOGGED_IN:
puts("*** Logged in."); puts("*** Logged in.");
@ -80,10 +81,7 @@ int main(int argc, char** argv)
ADC_client_set_callback(&client, handle); ADC_client_set_callback(&client, handle);
ADC_client_connect(&client, argv[1]); ADC_client_connect(&client, argv[1]);
while (running) while (running && net_backend_process()) { }
{
net_backend_process();
}
ADC_client_destroy(&client); ADC_client_destroy(&client);
net_destroy(); net_destroy();

View File

@ -90,8 +90,10 @@ extern "C" {
#include "core/pluginloader.h" #include "core/pluginloader.h"
#include "core/hub.h" #include "core/hub.h"
#include "core/commands.h" #include "core/commands.h"
#include "core/commands_builtin.h"
#include "core/inf.h" #include "core/inf.h"
#include "core/hubevent.h" #include "core/hubevent.h"
#include "core/plugincallback.h"
#include "core/plugininvoke.h" #include "core/plugininvoke.h"
#include "core/pluginloader.h" #include "core/pluginloader.h"