Added support for dynamic commands.
Dynamic commands are user commands that can be added dynamically to the hub by a plugin. The example plugin (mod_example.c) adds a !example command that when invoked send a message to the user who invoked it.
This commit is contained in:
parent
78ed83840b
commit
318163c066
10
AUTHORS
10
AUTHORS
|
@ -1,11 +1,9 @@
|
||||||
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
|
||||||
Thanks to:
|
MiMic, Implemented user commands
|
||||||
==========
|
tehnick, Debian and Ubuntu packaging.
|
||||||
|
|
||||||
tehnick, Fixing Debian's lintian warnings.
|
|
||||||
|
|
||||||
|
|
10
GNUmakefile
10
GNUmakefile
|
@ -139,6 +139,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 \
|
||||||
|
@ -208,6 +209,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)
|
||||||
|
@ -220,7 +223,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 :=
|
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)
|
||||||
|
@ -247,12 +250,15 @@ $(plugin_auth_TARGET): $(plugin_auth_SOURCES) $(libutils_OBJECTS)
|
||||||
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS) $(plugin_auth_sqlite_LIBS)
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS) $(plugin_auth_sqlite_LIBS)
|
||||||
|
|
||||||
$(plugin_example_TARGET): $(plugin_example_SOURCES)
|
$(plugin_example_TARGET): $(plugin_example_SOURCES) $(libutils_OBJECTS)
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||||
|
|
||||||
$(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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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,83 @@
|
||||||
|
|
||||||
#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 command_handle;
|
||||||
|
|
||||||
|
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 command_handle*, 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* origin; /**<<< "Name of module where the command is implemented." */
|
||||||
|
void* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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*, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
void commands_builtin_add(struct command_base*);
|
||||||
|
void commands_builtin_remove(struct command_base*);
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,6 +813,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,6 +839,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;
|
||||||
|
@ -851,7 +855,7 @@ int hub_plugins_load(struct hub_info* hub)
|
||||||
if (!hub->plugins)
|
if (!hub->plugins)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
#include "plugin_api/command_api.h"
|
||||||
|
|
||||||
|
struct plugin_callback_data
|
||||||
|
{
|
||||||
|
struct linked_list* commands;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct plugin_callback_data* data;
|
||||||
|
uhub_assert(plugin && plugin->handle && plugin->handle->internals);
|
||||||
|
data = (struct plugin_callback_data*) plugin->handle->internals;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int plugin_command_dispatch(struct command_base* cbase, struct hub_user* user, struct command_handle* handle, struct hub_command* cmd)
|
||||||
|
{
|
||||||
|
struct plugin_handle* plugin = (struct plugin_handle*) handle->ptr;
|
||||||
|
struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
|
struct plugin_command_handle* cmdh;
|
||||||
|
struct plugin_user* puser = (struct plugin_user*) user; // FIXME: Use a proper conversion function instead.
|
||||||
|
struct plugin_command* pcommand = (struct plugin_command*) cmd; // FIXME: Use a proper conversion function instead.
|
||||||
|
|
||||||
|
LOG_INFO("plugin_command_dispatch: cmd=%s", cmd->prefix);
|
||||||
|
|
||||||
|
cmdh = (struct plugin_command_handle*) list_get_first(data->commands);
|
||||||
|
while (cmdh)
|
||||||
|
{
|
||||||
|
if (cmdh->length != cmd->prefix_len)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(cmdh->prefix, cmd->prefix) == 0)
|
||||||
|
return cmdh->handler(plugin, puser, pcommand);
|
||||||
|
|
||||||
|
cmdh = (struct plugin_command_handle*) list_get_next(data->commands);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct plugin_callback_data* plugin_callback_data_create()
|
||||||
|
{
|
||||||
|
struct plugin_callback_data* data = (struct plugin_callback_data*) hub_malloc_zero(sizeof(struct plugin_callback_data));
|
||||||
|
data->commands = list_create();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plugin_callback_data_destroy(struct plugin_callback_data* data)
|
||||||
|
{
|
||||||
|
if (data->commands)
|
||||||
|
{
|
||||||
|
uhub_assert(list_size(data->commands) == 0);
|
||||||
|
list_destroy(data->commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
hub_free(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);
|
||||||
|
struct command_handle* command = (struct command_handle*) hub_malloc_zero(sizeof(struct command_handle));
|
||||||
|
|
||||||
|
command->prefix = cmdh->prefix;
|
||||||
|
command->length = cmdh->length;
|
||||||
|
command->args = cmdh->args;
|
||||||
|
command->cred = cmdh->cred;
|
||||||
|
command->description = cmdh->description;
|
||||||
|
command->origin = cmdh->origin;
|
||||||
|
command->handler = plugin_command_dispatch;
|
||||||
|
|
||||||
|
cmdh->internal_handle = data;
|
||||||
|
list_append(data->commands, cmdh);
|
||||||
|
command_add(plugin_get_hub(plugin)->commands, command, (void*) 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);
|
||||||
|
struct command_handle* command = (struct command_handle*) cmdh->internal_handle;
|
||||||
|
|
||||||
|
list_remove(data->commands, cmdh);
|
||||||
|
cmdh->internal_handle = 0;
|
||||||
|
|
||||||
|
command_del(plugin_get_hub(plugin)->commands, (void*) command);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
struct uhub_plugin;
|
||||||
|
|
||||||
|
extern struct plugin_callback_data* plugin_callback_data_create();
|
||||||
|
extern void plugin_callback_data_destroy(struct plugin_callback_data* data);
|
||||||
|
|
||||||
|
extern void plugin_register_callback_functions(struct plugin_handle* plugin);
|
||||||
|
extern void plugin_unregister_callback_functions(struct plugin_handle* plugin);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_H */
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,23 @@
|
||||||
#ifdef PLUGIN_SUPPORT
|
#ifdef PLUGIN_SUPPORT
|
||||||
#include "plugin_api/handle.h"
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
|
struct plugin_callback_data;
|
||||||
|
|
||||||
|
struct plugin_hub_internals
|
||||||
|
{
|
||||||
|
struct hub_info* hub;
|
||||||
|
plugin_unregister_f unregister; /* The unregister function. */
|
||||||
|
struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
|
||||||
|
{
|
||||||
|
struct plugin_hub_internals* internals;
|
||||||
|
assert(handle && handle->handle && handle->handle->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)
|
||||||
{
|
{
|
||||||
struct uhub_plugin* plugin;
|
struct uhub_plugin* plugin;
|
||||||
|
@ -51,12 +68,14 @@ struct uhub_plugin* plugin_open(const char* filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin->filename = strdup(filename);
|
plugin->filename = strdup(filename);
|
||||||
|
plugin->internals = hub_malloc_zero(sizeof(struct plugin_hub_internals));
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plugin_close(struct uhub_plugin* plugin)
|
void plugin_close(struct uhub_plugin* plugin)
|
||||||
{
|
{
|
||||||
LOG_TRACE("plugin_close: \"%s\"", plugin->filename);
|
LOG_TRACE("plugin_close: \"%s\"", plugin->filename);
|
||||||
|
hub_free(plugin->internals);
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
dlclose(plugin->handle);
|
dlclose(plugin->handle);
|
||||||
#else
|
#else
|
||||||
|
@ -77,13 +96,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 = (struct plugin_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 = (struct plugin_hub_internals*) plugin->internals;
|
||||||
|
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -98,6 +120,14 @@ 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");
|
||||||
|
|
||||||
|
// register hub internals
|
||||||
|
internals->unregister = unregister_f;
|
||||||
|
internals->hub = hub;
|
||||||
|
internals->callback_data = plugin_callback_data_create();
|
||||||
|
|
||||||
|
// setup callback functions, where the plugin can contact the hub.
|
||||||
|
plugin_register_callback_functions(handle);
|
||||||
|
|
||||||
if (register_f && unregister_f)
|
if (register_f && unregister_f)
|
||||||
{
|
{
|
||||||
ret = register_f(handle, config);
|
ret = register_f(handle, config);
|
||||||
|
@ -107,7 +137,6 @@ 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;
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -128,16 +157,19 @@ 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);
|
||||||
hub_free(plugin);
|
hub_free(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -162,7 +194,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);
|
||||||
|
@ -175,12 +207,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)
|
||||||
|
@ -188,12 +220,12 @@ 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)
|
||||||
{
|
{
|
||||||
list_clear(handle->loaded, hub_free);
|
list_clear(hub->plugins->loaded, hub_free);
|
||||||
list_destroy(handle->loaded);
|
list_destroy(hub->plugins->loaded);
|
||||||
handle->loaded = 0;
|
hub->plugins->loaded = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,4 +245,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 */
|
||||||
|
|
|
@ -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,6 +23,7 @@
|
||||||
#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;
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ struct uhub_plugin
|
||||||
void* handle;
|
void* handle;
|
||||||
plugin_unregister_f unregister;
|
plugin_unregister_f unregister;
|
||||||
char* filename;
|
char* filename;
|
||||||
|
void* internals; // Hub internal stuff
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uhub_plugins
|
struct uhub_plugins
|
||||||
|
@ -39,11 +41,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)
|
||||||
|
@ -51,5 +53,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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -20,74 +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;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plugin_hub_info
|
|
||||||
{
|
|
||||||
const char* description;
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -122,6 +62,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
|
||||||
|
@ -158,9 +101,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 */
|
||||||
|
@ -171,9 +133,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; \
|
||||||
|
|
|
@ -3,16 +3,50 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "plugin_api/handle.h"
|
#include "plugin_api/handle.h"
|
||||||
|
#include "plugin_api/command_api.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
struct example_plugin_data
|
||||||
|
{
|
||||||
|
struct plugin_command_handle* example;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int example_command_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||||
|
{
|
||||||
|
plugin->hub.send_message(plugin, user, "Hello from mod_example.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void command_register(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct example_plugin_data* data = (struct example_plugin_data*) hub_malloc(sizeof(struct example_plugin_data));
|
||||||
|
data->example = hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||||
|
PLUGIN_COMMAND_INITIALIZE(data->example, (void*) data, "example", "", auth_cred_guest, example_command_handler, "This is an example command that is added dynamically by loading the mod_example plug-in.");
|
||||||
|
plugin->hub.command_add(plugin, data->example);
|
||||||
|
plugin->ptr = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void command_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct example_plugin_data* data = (struct example_plugin_data*) plugin->ptr;
|
||||||
|
|
||||||
|
plugin->hub.command_del(plugin, data->example);
|
||||||
|
hub_free(data->example);
|
||||||
|
|
||||||
|
hub_free(data);
|
||||||
|
plugin->ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int plugin_register(struct plugin_handle* plugin, const char* config)
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
{
|
{
|
||||||
PLUGIN_INITIALIZE(plugin, "Example plugin", "1.0", "A simple example plugin");
|
PLUGIN_INITIALIZE(plugin, "Example plugin", "1.0", "A simple example plugin");
|
||||||
|
command_register(plugin);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int plugin_unregister(struct plugin_handle* plugin)
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
{
|
{
|
||||||
/* No need to do anything! */
|
command_unregister(plugin);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,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.");
|
||||||
|
@ -84,10 +85,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();
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_auth_simple", "plugins\
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_example", "plugins\mod_example\mod_example.vcxproj", "{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -31,6 +33,10 @@ Global
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Debug|Win32.Build.0 = Debug|Win32
|
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.ActiveCfg = Release|Win32
|
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.Build.0 = Release|Win32
|
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
<ClCompile Include="..\src\core\inf.c" />
|
<ClCompile Include="..\src\core\inf.c" />
|
||||||
<ClCompile Include="..\src\core\main.c" />
|
<ClCompile Include="..\src\core\main.c" />
|
||||||
<ClCompile Include="..\src\core\netevent.c" />
|
<ClCompile Include="..\src\core\netevent.c" />
|
||||||
|
<ClCompile Include="..\src\core\plugincallback.c" />
|
||||||
<ClCompile Include="..\src\core\plugininvoke.c" />
|
<ClCompile Include="..\src\core\plugininvoke.c" />
|
||||||
<ClCompile Include="..\src\core\pluginloader.c" />
|
<ClCompile Include="..\src\core\pluginloader.c" />
|
||||||
<ClCompile Include="..\src\core\probe.c" />
|
<ClCompile Include="..\src\core\probe.c" />
|
||||||
|
@ -115,6 +116,7 @@
|
||||||
<ClInclude Include="..\src\adc\sid.h" />
|
<ClInclude Include="..\src\adc\sid.h" />
|
||||||
<ClInclude Include="..\src\core\auth.h" />
|
<ClInclude Include="..\src\core\auth.h" />
|
||||||
<ClInclude Include="..\src\core\commands.h" />
|
<ClInclude Include="..\src\core\commands.h" />
|
||||||
|
<ClInclude Include="..\src\core\commands_builtin.h" />
|
||||||
<ClInclude Include="..\src\core\config.h" />
|
<ClInclude Include="..\src\core\config.h" />
|
||||||
<ClInclude Include="..\src\core\eventid.h" />
|
<ClInclude Include="..\src\core\eventid.h" />
|
||||||
<ClInclude Include="..\src\core\eventqueue.h" />
|
<ClInclude Include="..\src\core\eventqueue.h" />
|
||||||
|
@ -124,6 +126,7 @@
|
||||||
<ClInclude Include="..\src\core\hubio.h" />
|
<ClInclude Include="..\src\core\hubio.h" />
|
||||||
<ClInclude Include="..\src\core\inf.h" />
|
<ClInclude Include="..\src\core\inf.h" />
|
||||||
<ClInclude Include="..\src\core\netevent.h" />
|
<ClInclude Include="..\src\core\netevent.h" />
|
||||||
|
<ClInclude Include="..\src\core\plugincallback.h" />
|
||||||
<ClInclude Include="..\src\core\plugininvoke.h" />
|
<ClInclude Include="..\src\core\plugininvoke.h" />
|
||||||
<ClInclude Include="..\src\core\pluginloader.h" />
|
<ClInclude Include="..\src\core\pluginloader.h" />
|
||||||
<ClInclude Include="..\src\core\probe.h" />
|
<ClInclude Include="..\src\core\probe.h" />
|
||||||
|
@ -135,6 +138,7 @@
|
||||||
<ClInclude Include="..\src\network\connection.h" />
|
<ClInclude Include="..\src\network\connection.h" />
|
||||||
<ClInclude Include="..\src\network\network.h" />
|
<ClInclude Include="..\src\network\network.h" />
|
||||||
<ClInclude Include="..\src\network\timeout.h" />
|
<ClInclude Include="..\src\network\timeout.h" />
|
||||||
|
<ClInclude Include="..\src\plugin_api\command_api.h" />
|
||||||
<ClInclude Include="..\src\plugin_api\handle.h" />
|
<ClInclude Include="..\src\plugin_api\handle.h" />
|
||||||
<ClInclude Include="..\src\system.h" />
|
<ClInclude Include="..\src\system.h" />
|
||||||
<ClInclude Include="..\src\uhub.h" />
|
<ClInclude Include="..\src\uhub.h" />
|
||||||
|
|
Loading…
Reference in New Issue