aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.h1
-rw-r--r--commands.h2
-rw-r--r--irc_commands.c4
-rw-r--r--otr.c5
-rw-r--r--otr.h3
-rw-r--r--root_commands.c55
6 files changed, 53 insertions, 17 deletions
diff --git a/bitlbee.h b/bitlbee.h
index ae8f34d9..e312dc4c 100644
--- a/bitlbee.h
+++ b/bitlbee.h
@@ -164,6 +164,7 @@ gboolean bitlbee_io_current_client_write( gpointer data, gint source, b_input_co
void root_command_string( irc_t *irc, char *command );
void root_command( irc_t *irc, char *command[] );
+gboolean root_command_add( const char *command, int params, void (*func)(irc_t *, char **args), int flags );
gboolean cmd_identify_finish( gpointer data, gint fd, b_input_condition cond );
gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond );
diff --git a/commands.h b/commands.h
index 38572360..03b4ee7f 100644
--- a/commands.h
+++ b/commands.h
@@ -36,7 +36,7 @@ typedef struct command
int flags;
} command_t;
-extern const command_t commands[];
+extern command_t root_commands[];
#define IRC_CMD_PRE_LOGIN 1
#define IRC_CMD_LOGGED_IN 2
diff --git a/irc_commands.c b/irc_commands.c
index 4b1bc741..9730a288 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -625,8 +625,8 @@ static void irc_cmd_completions( irc_t *irc, char **cmd )
irc_send_msg_raw( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS OK" );
- for( i = 0; commands[i].command; i ++ )
- irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS %s", commands[i].command );
+ for( i = 0; root_commands[i].command; i ++ )
+ irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS %s", root_commands[i].command );
for( h = global.help; h; h = h->next )
irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS help %s", h->title );
diff --git a/otr.c b/otr.c
index 7d4a71a7..9031d7de 100644
--- a/otr.c
+++ b/otr.c
@@ -83,6 +83,7 @@ const char *op_account_name(void *opdata, const char *account, const char *proto
/** otr sub-command handlers: **/
+static void cmd_otr(irc_t *irc, char **args);
void cmd_otr_connect(irc_t *irc, char **args);
void cmd_otr_disconnect(irc_t *irc, char **args);
void cmd_otr_smp(irc_t *irc, char **args);
@@ -198,6 +199,8 @@ void otr_init(void)
global.otr_ops.max_message_size = &op_max_message_size;
global.otr_ops.account_name = &op_account_name;
global.otr_ops.account_name_free = NULL;
+
+ root_command_add( "otr", 1, cmd_otr, 0 );
}
otr_t *otr_new(void)
@@ -417,7 +420,7 @@ int otr_send_message(struct im_connection *ic, const char *handle, const char *m
return st;
}
-void cmd_otr(irc_t *irc, char **args)
+static void cmd_otr(irc_t *irc, char **args)
{
const command_t *cmd;
diff --git a/otr.h b/otr.h
index 7c1962a8..c0c06e76 100644
--- a/otr.h
+++ b/otr.h
@@ -39,9 +39,6 @@ struct irc;
struct im_connection;
struct account;
-// 'otr' root command, hooked up in root_commands.c
-void cmd_otr(struct irc *, char **args);
-
#ifdef WITH_OTR
#include <libotr/proto.h>
diff --git a/root_commands.c b/root_commands.c
index baad826d..3cc96c2d 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -28,7 +28,6 @@
#include "bitlbee.h"
#include "help.h"
#include "ipc.h"
-#include "otr.h"
void root_command_string( irc_t *irc, char *command )
{
@@ -55,17 +54,17 @@ void root_command( irc_t *irc, char *cmd[] )
return;
len = strlen( cmd[0] );
- for( i = 0; commands[i].command; i++ )
- if( g_strncasecmp( commands[i].command, cmd[0], len ) == 0 )
+ for( i = 0; root_commands[i].command; i++ )
+ if( g_strncasecmp( root_commands[i].command, cmd[0], len ) == 0 )
{
- if( commands[i+1].command &&
- g_strncasecmp( commands[i+1].command, cmd[0], len ) == 0 )
+ if( root_commands[i+1].command &&
+ g_strncasecmp( root_commands[i+1].command, cmd[0], len ) == 0 )
/* Only match on the first letters if the match is unique. */
break;
- MIN_ARGS( commands[i].required_parameters );
+ MIN_ARGS( root_commands[i].required_parameters );
- commands[i].execute( irc, cmd );
+ root_commands[i].execute( irc, cmd );
return;
}
@@ -1324,7 +1323,7 @@ static void bitlbee_whatsnew( irc_t *irc )
}
/* IMPORTANT: Keep this list sorted! The short command logic needs that. */
-const command_t commands[] = {
+command_t root_commands[] = {
{ "account", 1, cmd_account, 0 },
{ "add", 2, cmd_add, 0 },
{ "allow", 1, cmd_allow, 0 },
@@ -1339,7 +1338,6 @@ const command_t commands[] = {
{ "identify", 1, cmd_identify, 0 },
{ "info", 1, cmd_info, 0 },
{ "no", 0, cmd_yesno, 0 },
- { "otr", 1, cmd_otr, 0 },
{ "qlist", 0, cmd_qlist, 0 },
{ "register", 1, cmd_register, 0 },
{ "remove", 1, cmd_remove, 0 },
@@ -1348,5 +1346,42 @@ const command_t commands[] = {
{ "set", 0, cmd_set, 0 },
{ "transfer", 0, cmd_transfer, 0 },
{ "yes", 0, cmd_yesno, 0 },
- { NULL }
+ /* Not expecting too many plugins adding root commands so just make a
+ dumb array with some empty entried at the end. */
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
};
+static const int num_root_commands = sizeof( root_commands ) / sizeof( command_t );
+
+gboolean root_command_add( const char *command, int params, void (*func)(irc_t *, char **args), int flags )
+{
+ int i;
+
+ if( root_commands[num_root_commands-2].command )
+ /* Planning fail! List is full. */
+ return FALSE;
+
+ for( i = 0; root_commands[i].command; i++ )
+ {
+ if( g_strcasecmp( root_commands[i].command, command ) == 0 )
+ return FALSE;
+ else if( g_strcasecmp( root_commands[i].command, command ) > 0 )
+ break;
+ }
+ memmove( root_commands + i + 1, root_commands + i,
+ sizeof( command_t ) * ( num_root_commands - i - 1 ) );
+
+ root_commands[i].command = g_strdup( command );
+ root_commands[i].required_parameters = params;
+ root_commands[i].execute = func;
+ root_commands[i].flags = flags;
+
+ return TRUE;
+}