diff --git a/extensions/chm_adminonly.c b/extensions/chm_adminonly.c index 9380c3d..c478e91 100644 --- a/extensions/chm_adminonly.c +++ b/extensions/chm_adminonly.c @@ -17,13 +17,14 @@ mapi_hfn_list_av1 adminonly_hfnlist[] = { { NULL, NULL } }; +static unsigned int mymode; + static int _modinit(void) { - chmode_table['A'].mode_type = find_cflag_slot(); - chmode_table['A'].set_func = chm_staff; - - construct_noparam_modes(); + mymode = cflag_add('A', chm_staff); + if (mymode == 0) + return -1; return 0; } @@ -31,9 +32,7 @@ _modinit(void) static void _moddeinit(void) { - chmode_table['A'].mode_type = 0; - - construct_noparam_modes(); + cflag_orphan('A'); } DECLARE_MODULE_AV1(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, "$Revision$"); @@ -44,7 +43,7 @@ h_can_join(hook_data_channel *data) struct Client *source_p = data->client; struct Channel *chptr = data->chptr; - if((chptr->mode.mode & chmode_flags['A']) && !IsAdmin(source_p)) { + if((chptr->mode.mode & mymode) && !IsAdmin(source_p)) { sendto_one_numeric(source_p, 519, "%s :Cannot join channel (+A) - you are not an IRC server administrator", chptr->chname); data->approved = ERR_CUSTOM; } diff --git a/extensions/chm_operonly.c b/extensions/chm_operonly.c index 4912e5a..5cb87ab 100644 --- a/extensions/chm_operonly.c +++ b/extensions/chm_operonly.c @@ -17,7 +17,7 @@ mapi_hfn_list_av1 operonly_hfnlist[] = { { NULL, NULL } }; - +static unsigned int mymode; /* This is a simple example of how to use dynamic channel modes. * Not tested enough yet, use at own risk. @@ -26,27 +26,18 @@ mapi_hfn_list_av1 operonly_hfnlist[] = { static int _modinit(void) { - /* add the channel mode to the available slot */ - chmode_table['O'].mode_type = find_cflag_slot(); - chmode_table['O'].set_func = chm_staff; - - construct_noparam_modes(); + mymode = cflag_add('O', chm_staff); + if (mymode == 0) + return -1; return 0; } -/* Well, the first ugly thing is that we changle chmode_table in _modinit - * and chmode_flags in _moddeinit (different arrays) - must be fixed. - * -- dwr - */ static void _moddeinit(void) { - /* disable the channel mode and remove it from the available list */ - chmode_table['O'].mode_type = 0; - - construct_noparam_modes(); + cflag_orphan('O'); } DECLARE_MODULE_AV1(chm_operonly, _modinit, _moddeinit, NULL, NULL, operonly_hfnlist, "$Revision$"); @@ -57,7 +48,7 @@ h_can_join(hook_data_channel *data) struct Client *source_p = data->client; struct Channel *chptr = data->chptr; - if((chptr->mode.mode & chmode_flags['O']) && !IsOper(source_p)) { + if((chptr->mode.mode & mymode) && !IsOper(source_p)) { sendto_one_numeric(source_p, 520, "%s :Cannot join channel (+O) - you are not an IRC operator", chptr->chname); data->approved = ERR_CUSTOM; } diff --git a/extensions/chm_sslonly.c b/extensions/chm_sslonly.c index 197aac6..2808bb1 100644 --- a/extensions/chm_sslonly.c +++ b/extensions/chm_sslonly.c @@ -17,13 +17,14 @@ mapi_hfn_list_av1 sslonly_hfnlist[] = { { NULL, NULL } }; +static unsigned int mymode; + static int _modinit(void) { - chmode_table['S'].mode_type = find_cflag_slot(); - chmode_table['S'].set_func = chm_simple; - - construct_noparam_modes(); + mymode = cflag_add('S', chm_simple); + if (mymode == 0) + return -1; return 0; } @@ -32,9 +33,7 @@ _modinit(void) static void _moddeinit(void) { - chmode_table['S'].mode_type = 0; - - construct_noparam_modes(); + cflag_orphan('S'); } DECLARE_MODULE_AV1(chm_sslonly, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, "$Revision$"); @@ -45,7 +44,7 @@ h_can_join(hook_data_channel *data) struct Client *source_p = data->client; struct Channel *chptr = data->chptr; - if((chptr->mode.mode & chmode_flags['S']) && !IsSSLClient(source_p)) { + if((chptr->mode.mode & mymode) && !IsSSLClient(source_p)) { sendto_one_notice(source_p, ":Only users using SSL could join this channel!"); data->approved = ERR_CUSTOM; } diff --git a/include/channel.h b/include/channel.h index cc8a18c..3a74689 100644 --- a/include/channel.h +++ b/include/channel.h @@ -127,11 +127,13 @@ struct ChCapCombo int cap_no; }; +typedef void (*ChannelModeFunc)(struct Client *source_p, struct Channel *chptr, + int alevel, int parc, int *parn, + const char **parv, int *errors, int dir, char c, long mode_type); + struct ChannelMode { - void (*set_func) (struct Client * source_p, struct Channel * chptr, - int alevel, int parc, int *parn, - const char **parv, int *errors, int dir, char c, long mode_type); + ChannelModeFunc set_func; long mode_type; }; diff --git a/include/chmode.h b/include/chmode.h index 9fd623c..82d8ecd 100644 --- a/include/chmode.h +++ b/include/chmode.h @@ -82,9 +82,9 @@ extern void chm_voice(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type); -extern void construct_noparam_modes(void); -extern void find_orphaned_cflags(void); -extern unsigned int find_cflag_slot(void); +extern unsigned int cflag_add(char c, ChannelModeFunc function); +extern void cflag_orphan(char c); +extern void construct_cflags_strings(void); extern char cflagsbuf[256]; extern char cflagsmyinfo[256]; diff --git a/src/chmode.c b/src/chmode.c index 3161b64..583e30c 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -74,12 +74,11 @@ int chmode_flags[256]; /* OPTIMIZE ME! -- dwr */ void -construct_noparam_modes(void) +construct_cflags_strings(void) { int i; char *ptr = cflagsbuf; char *ptr2 = cflagsmyinfo; - static int prev_chmode_flags[256]; *ptr = '\0'; *ptr2 = '\0'; @@ -103,22 +102,6 @@ construct_noparam_modes(void) chmode_flags[i] = 0; } - if (prev_chmode_flags[i] != 0 && prev_chmode_flags[i] != chmode_flags[i]) - { - if (chmode_flags[i] == 0) - { - chmode_table[i].set_func = chm_orphaned; - sendto_realops_snomask(SNO_DEBUG, L_ALL, "Cmode +%c is now orphaned", i); - } - else - { - sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned cmode +%c is picked up by module", i); - } - chmode_flags[i] = prev_chmode_flags[i]; - } - else - prev_chmode_flags[i] = chmode_flags[i]; - switch (chmode_flags[i]) { case MODE_EXLIMIT: @@ -162,7 +145,7 @@ construct_noparam_modes(void) * 0 if no cflags are available * side effects - NONE */ -unsigned int +static unsigned int find_cflag_slot(void) { unsigned int all_cflags = 0, my_cflag = 0, i; @@ -176,6 +159,34 @@ find_cflag_slot(void) return my_cflag; } +unsigned int +cflag_add(char c_, ChannelModeFunc function) +{ + int c = (unsigned char)c_; + + if (chmode_table[c].set_func != chm_nosuch && + chmode_table[c].set_func != chm_orphaned) + return 0; + + if (chmode_table[c].set_func == chm_nosuch) + chmode_table[c].mode_type = find_cflag_slot(); + if (chmode_table[c].mode_type == 0) + return 0; + chmode_table[c].set_func = function; + construct_cflags_strings(); + return chmode_table[c].mode_type; +} + +void +cflag_orphan(char c_) +{ + int c = (unsigned char)c_; + + s_assert(chmode_flags[c] != 0); + chmode_table[c].set_func = chm_orphaned; + construct_cflags_strings(); +} + static int get_channel_access(struct Client *source_p, struct membership *msptr) { diff --git a/src/ircd.c b/src/ircd.c index 8577081..a9f6cfb 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -649,13 +649,7 @@ main(int argc, char *argv[]) init_monitor(); init_isupport(); - /* noparam core modes have to be initialized before the module - * system is initialized, otherwise we have a table collision. - * - * modules call this after they are done initializing... - * --nenolod - */ - construct_noparam_modes(); + construct_cflags_strings(); load_all_modules(1); #ifndef STATIC_MODULES