{ 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;
}
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$");
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;
}
{ 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.
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$");
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;
}
{ 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;
}
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$");
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;
}
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;
};
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];
/* 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';
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:
* 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;
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)
{
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