Anonymous avatar Anonymous committed 8199c80 Merge

Automated merge with ssh://shadowircd/uranium/shadowircd/

Comments (0)

Files changed (27)

 # the system one.
 #CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
 SHELL=/bin/sh
-SUBDIRS=libratbox modules extensions src tools ssld bandb doc help
+SUBDIRS=libratbox modules modes extensions src tools ssld bandb doc help
 CLEANDIRS = ${SUBDIRS}
 RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
 
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for shadowircd 6.1.0.
+# Generated by GNU Autoconf 2.65 for shadowircd 6.2.0.
 #
 # $Id: configure.ac 3516 2007-06-10 16:14:03Z jilles $
 #
 # Identity of this package.
 PACKAGE_NAME='shadowircd'
 PACKAGE_TARNAME='shadowircd'
-PACKAGE_VERSION='6.1.0'
-PACKAGE_STRING='shadowircd 6.1.0'
+PACKAGE_VERSION='6.2.0'
+PACKAGE_STRING='shadowircd 6.2.0'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures shadowircd 6.1.0 to adapt to many kinds of systems.
+\`configure' configures shadowircd 6.2.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of shadowircd 6.1.0:";;
+     short | recursive ) echo "Configuration of shadowircd 6.2.0:";;
    esac
   cat <<\_ACEOF
 
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-shadowircd configure 6.1.0
+shadowircd configure 6.2.0
 generated by GNU Autoconf 2.65
 
 Copyright (C) 2009 Free Software Foundation, Inc.
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by shadowircd $as_me 6.1.0, which was
+It was created by shadowircd $as_me 6.2.0, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   $ $0 $@
 
 fi
 
-ac_config_files="$ac_config_files Makefile bandb/Makefile ssld/Makefile extensions/Makefile unsupported/Makefile src/Makefile modules/Makefile tools/Makefile doc/Makefile help/Makefile"
+ac_config_files="$ac_config_files Makefile bandb/Makefile ssld/Makefile extensions/Makefile modes/Makefile unsupported/Makefile src/Makefile modules/Makefile tools/Makefile doc/Makefile help/Makefile"
 
 
 cat >confcache <<\_ACEOF
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by shadowircd $as_me 6.1.0, which was
+This file was extended by shadowircd $as_me 6.2.0, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-shadowircd config.status 6.1.0
+shadowircd config.status 6.2.0
 configured by $0, generated by GNU Autoconf 2.65,
   with options \\"\$ac_cs_config\\"
 
     "bandb/Makefile") CONFIG_FILES="$CONFIG_FILES bandb/Makefile" ;;
     "ssld/Makefile") CONFIG_FILES="$CONFIG_FILES ssld/Makefile" ;;
     "extensions/Makefile") CONFIG_FILES="$CONFIG_FILES extensions/Makefile" ;;
+    "modes/Makefile") CONFIG_FILES="$CONFIG_FILES modes/Makefile" ;;
     "unsupported/Makefile") CONFIG_FILES="$CONFIG_FILES unsupported/Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;;
 dnl Sneaky way to get an Id tag into the configure script
 AC_COPYRIGHT([$Id: configure.ac 3516 2007-06-10 16:14:03Z jilles $])
 
-AC_INIT([shadowircd],[6.1.0])
+AC_INIT([shadowircd],[6.2.0])
 
 AC_CONFIG_HEADER(include/setup.h)
 
 	bandb/Makefile			\
 	ssld/Makefile			\
 	extensions/Makefile		\
+	modes/Makefile			\
 	unsupported/Makefile		\
 	src/Makefile			\
 	modules/Makefile		\
 loadmodule "extensions/sno_globaloper.so";
 #loadmodule "extensions/sno_whois.so";
 
+/* Modesets, load only one */
+loadmodule "modes/shadowircd.so";
+#loadmodule "modes/charybdis.so";
+
 serverinfo {
 	name = "hades.arpa";
 	sid = "42X";
 	use_invex = yes;
 	use_except = yes;
 	use_knock = yes;
-	use_forward = yes;
 	use_local_channels = yes;
 	knock_delay = 5 minutes;
 	knock_delay_channel = 1 minute;

doc/reference.conf

 loadmodule "extensions/sno_globaloper.so";
 #loadmodule "extensions/sno_whois.so";
 
+/* modesets: Modesets are modules that enable various user and channel
+ * modes. When enabled, they enable usermodes and channel modes equivalent
+ * to the named ircd. This is useful for linking to other TS6 IRCds. 
+ * If you do not know what this does or do not know if you need it
+ * then you should just load modes/shadowircd.so for full functionality.
+ * Without any modeset loaded, you will only have the modes that are included
+ * in ircd-ratbox. Unloading a modeset while the ircd is running is possible,
+ * but will be confusing for users, as it will leave all existent unloaded
+ * modes in place without users being able to remove them. Said modes will, 
+ * however, not function. You should be able to load a module that provides 
+ * more modes than your current (say, going from charybdis to shadowircd) 
+ * on the fly without any problems. The slight exception to this is unloading
+ * a module that provides quiets (cmode +q). Users affected by quiets will
+ * have to part and rejoin the channel before the quiet will cease affecting
+ * them. In addition, unloaded modes will remain in the IRCd's VERSION reply
+ * until restart. For these reasons, it is highly recommended to restart if you wish
+ * to change modeset.
+ * Modesets currently only affect cmodes. 
+ * You should only load one of these at a time.
+ * Modules are listed in order of highest functionality to least,
+ * while no module provides the least functionality of all. */
+ 
+loadmodule "modes/shadowircd.so";
+#loadmodule "modes/charybdis.so";
+
  
 /* serverinfo {}:  Contains information about the server. (OLD M:) */
 serverinfo {
 	 */
 	use_except = yes;
 
-	/* forward: Enable/disable channel mode +f, which allows you to set 
-	 * a channel to forward users to if they can't join because of +i etc.
-	 * Disabling this option via rehash will leave all previously set 
-	 * forwards hanging around, though they will not do anything. For 
-	 * this reason, you may want to restart to disable this option.
-	 */
-	use_forward = yes;
-
 	/* knock: Allows users to request an invite to a channel that
 	 * is locked somehow (+ikl).  If the channel is +p or you are banned
 	 * the knock will not be sent.

extensions/chm_quietunreg_compat.c

 #include "hook.h"
 #include "ircd.h"
 #include "chmode.h"
+#include "channel.h"
+
+struct module_modes ModuleModes;
 
 static int _modinit(void);
 static void _moddeinit(void);
 
 	if (MyClient(source_p))
 		chm_ban(source_p, chptr, alevel, 1, &newparn, newparv,
-				errors, dir, 'q', CHFL_QUIET);
+				errors, dir, 'q', ModuleModes.CHFL_QUIET);
 	else
 		chm_nosuch(source_p, chptr, alevel, parc, parn, parv,
 				errors, dir, c, mode_type);

extensions/m_okick.c

 #include "s_conf.h"
 #include "s_serv.h"
 
+struct module_modes ModuleModes;
+
 static int mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
 
 
 	rb_snprintf(text, sizeof(text), "K%s", who->id);
 
 	/* we don't need to track NOREJOIN stuff unless it's our client being kicked */
-	if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
+	if(MyClient(who) && chptr->mode.mode & ModuleModes.MODE_NOREJOIN)
 		channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
 	return 0;
 }

include/channel.h

 	long mode_type;
 };
 
+/* modes added by the module files in modes/ */
+struct module_modes
+{
+	unsigned int MODE_REGONLY; 
+	unsigned int MODE_NOCTCP; /* Block CTCPs directed to this channel */
+	unsigned int MODE_NOCOLOR;
+	unsigned int MODE_EXLIMIT; /* exempt from list limits, +b/+e/+I/+q */
+	unsigned int MODE_PERMANENT; /* permanant channel, +P */
+	unsigned int MODE_OPMODERATE; /* send rejected messages to ops */
+	unsigned int MODE_FREEINVITE; /* allow free use of /invite */
+	unsigned int MODE_FREETARGET; /* can be forwarded to without authorization */
+	unsigned int MODE_DISFORWARD; /* disable channel forwarding */
+	unsigned int MODE_THROTTLE; /* throttle joins */
+	unsigned int MODE_FORWARD;
+	unsigned int MODE_NONOTICE; /* Block notices directed to this channel */
+	unsigned int MODE_NOACTION; /* Block CTCP ACTION directed to this channel */
+	unsigned int MODE_NOKICK; /* Disable /kick on this channel */
+	unsigned int MODE_NONICK; /* Disable /nick for anyone on this channel */
+	unsigned int MODE_NOCAPS; /* Block messages in all capital letters */
+	unsigned int MODE_NOREJOIN; /* Block rejoin immediately after kick */
+	unsigned int MODE_NOREPEAT; /* Block repeat messages */
+	unsigned int MODE_NOOPERKICK; /* disallow kicking opers */
+
+	unsigned int CHFL_QUIET;
+};
+
 typedef int (*ExtbanFunc)(const char *data, struct Client *client_p,
 		struct Channel *chptr, long mode_type);
 
 #define MODE_TOPICLIMIT 0x0008
 #define MODE_INVITEONLY 0x0010
 #define MODE_NOPRIVMSGS 0x0020
-#define MODE_REGONLY	0x0040
-#define MODE_NOCOLOR	0x0080
-#define MODE_EXLIMIT	0x0100  /* exempt from list limits, +b/+e/+I/+q */
-#define MODE_PERMANENT  0x0200  /* permanant channel, +P */
-#define MODE_OPMODERATE 0x0400  /* send rejected messages to ops */
-#define MODE_FREEINVITE 0x0800  /* allow free use of /invite */
-#define MODE_FREETARGET 0x1000  /* can be forwarded to without authorization */
-#define MODE_DISFORWARD 0x2000  /* disable channel forwarding */
-#define MODE_NOCTCP     0x8000  /* Block CTCPs directed to this channel */
-#define MODE_NONOTICE	0x10000	/* Block notices directed to this channel */
-#define MODE_NOACTION	0x20000 /* Block CTCP ACTION directed to this channel */
-#define MODE_NOKICK	0x40000 /* Disable /kick on this channel */
-#define MODE_NONICK	0x80000 /* Disable /nick for anyone on this channel */
-#define MODE_NOCAPS	0x100000 /* Block messages in all capital letters */
-#define MODE_NOREJOIN	0x200000 /* Block rejoin immediately after kick */
-#define MODE_NOREPEAT	0x400000 /* Block repeat messages */
-#define MODE_NOOPERKICK	0x800000 /* disallow kicking opers */
 
 #define CHFL_BAN        0x10000000	/* ban channel flag */
 #define CHFL_EXCEPTION  0x20000000	/* exception to ban channel flag */
 #define CHFL_INVEX      0x40000000
-#define CHFL_QUIET      0x80000000
 
 /* mode flags for direction indication */
 #define MODE_QUERY     0
 
 extern rb_dlink_list global_channel_list;
 void init_channels(void);
+void init_module_modes(void);
 
 struct Channel *allocate_channel(const char *chname);
 void free_channel(struct Channel *chptr);
 	int use_except;
 	int use_invex;
 	int use_knock;
-	int use_forward;
 	int use_local_channels;
 	int knock_delay;
 	int knock_delay_channel;

modes/Makefile.in

+#
+# Makefile.in for ircd/modes
+#
+#
+CC		= @CC@
+RM		= @RM@
+SED             = @SED@
+LEX		= @LEX@
+LEXLIB		= @LEXLIB@
+CFLAGS		= @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+PICFLAGS	= @PICFLAGS@
+MKDEP		= @MKDEP@
+INSTALL		= @INSTALL@
+INSTALL_PROGRAM	= @INSTALL_PROGRAM@
+INSTALL_DATA	= @INSTALL_DATA@
+INSTALL_SUID    = @INSTALL_PROGRAM@ -o root -m 4755
+SHELL		= /bin/sh
+AUTOMODULEDIR	= @moduledir@/modes
+
+SSL_LIBS	= @SSL_LIBS@
+SSL_INCLUDES	= @SSL_INCLUDES@
+
+IRCDLIBS	= @LIBS@ $(SSL_LIBS)
+
+INCLUDES	= -I. -I../include -I../libratbox/include $(SSL_INCLUDES)
+CPPFLAGS	= ${INCLUDES} @CPPFLAGS@
+
+SRCS =                          \
+  charybdis.c			\
+  shadowircd.c
+
+OBJS = ${SRCS:.c=.so}
+
+default:	build
+build: all
+all: $(OBJS)
+
+install: all
+	-@if test ! -d $(DESTDIR)$(AUTOMODULEDIR); then \
+                mkdir $(DESTDIR)$(AUTOMODULEDIR); \
+        fi
+	@echo "Installing modules into $(DESTDIR)$(AUTOMODULEDIR) .."
+	@for file in $(OBJS); do \
+		$(INSTALL_DATA) $$file $(DESTDIR)$(AUTOMODULEDIR); \
+	done
+
+.SUFFIXES: .so
+
+.c.so:
+	${CC} ${PICFLAGS}  ${CPPFLAGS} ${CFLAGS} $< -o $@
+
+.PHONY: depend clean distclean
+depend:
+	@${MKDEP} ${CPPFLAGS} ${SRCS} > .depend
+	@sed s/\\\.o/\\\.so/ < .depend > .depend.tmp
+	@sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
+	@echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
+	@echo '# make depend needs it.' >>Makefile.depend
+	@cat .depend.tmp >>Makefile.depend
+	@mv Makefile.depend Makefile
+	@rm -f .depend.tmp .depend
+
+clean:
+	${RM} -f *.so *~ 
+
+distclean: clean
+	${RM} -f Makefile
+

modes/charybdis.c

+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+#include "chmode.h"
+#include "channel.h"
+
+struct module_modes ModuleModes;
+
+static int
+_modinit(void)
+{
+	ModuleModes.MODE_NOCTCP = cflag_add('C', chm_simple);
+	if (ModuleModes.MODE_NOCTCP == 0)
+		return -1;
+
+	ModuleModes.MODE_REGONLY = cflag_add('r', chm_regonly);
+	if (ModuleModes.MODE_REGONLY == 0)
+		return -1;
+
+	ModuleModes.MODE_NOCOLOR = cflag_add('c', chm_simple);
+	if (ModuleModes.MODE_NOCOLOR == 0)
+		return -1;
+
+	ModuleModes.MODE_EXLIMIT = cflag_add('L', chm_staff);
+	if (ModuleModes.MODE_EXLIMIT == 0)
+		return -1;
+
+	ModuleModes.MODE_PERMANENT = cflag_add('P', chm_staff);
+	if (ModuleModes.MODE_PERMANENT == 0)
+		return -1;
+
+	ModuleModes.MODE_OPMODERATE = cflag_add('z', chm_simple);
+	if (ModuleModes.MODE_OPMODERATE == 0)
+		return -1;
+
+	ModuleModes.MODE_FREEINVITE = cflag_add('g', chm_simple);
+	if (ModuleModes.MODE_FREEINVITE == 0)
+		return -1;
+
+	ModuleModes.MODE_FREETARGET = cflag_add('F', chm_simple);
+	if (ModuleModes.MODE_FREETARGET == 0)
+		return -1;
+
+	ModuleModes.MODE_DISFORWARD = cflag_add('Q', chm_simple);
+	if (ModuleModes.MODE_DISFORWARD == 0)
+		return -1;
+
+	ModuleModes.CHFL_QUIET = cflag_add('q', chm_ban);
+	if (ModuleModes.CHFL_QUIET == 0)
+		return -1;
+
+	ModuleModes.MODE_FORWARD = cflag_add('f', chm_forward);
+	if (ModuleModes.MODE_FORWARD == 0)
+		return -1;
+
+	ModuleModes.MODE_THROTTLE = cflag_add('j', chm_throttle);
+	if (ModuleModes.MODE_THROTTLE == 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+_moddeinit(void)
+{
+	cflag_orphan('C');
+	ModuleModes.MODE_NOCTCP = 0;
+
+	cflag_orphan('r');
+	ModuleModes.MODE_REGONLY = 0;
+
+	cflag_orphan('c');
+	ModuleModes.MODE_NOCOLOR = 0;
+
+	cflag_orphan('L');
+	ModuleModes.MODE_EXLIMIT = 0;
+
+	cflag_orphan('P');
+	ModuleModes.MODE_PERMANENT = 0;
+
+	cflag_orphan('z');
+	ModuleModes.MODE_OPMODERATE = 0;
+
+	cflag_orphan('g');
+	ModuleModes.MODE_FREEINVITE = 0;
+
+	cflag_orphan('F');
+	ModuleModes.MODE_FREETARGET = 0;
+
+	cflag_orphan('Q');
+	ModuleModes.MODE_DISFORWARD = 0;
+
+	cflag_orphan('q');
+	ModuleModes.CHFL_QUIET = 0;
+
+	cflag_orphan('f');
+	ModuleModes.MODE_FORWARD = 0;
+
+	cflag_orphan('j');
+	ModuleModes.MODE_THROTTLE = 0;
+}
+
+DECLARE_MODULE_AV1(charybdis, _modinit, _moddeinit, NULL, NULL, NULL, "$charybdis$");

modes/shadowircd.c

+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+#include "chmode.h"
+#include "channel.h"
+
+struct module_modes ModuleModes;
+
+static int
+_modinit(void)
+{
+	/* charybdis modes */
+	ModuleModes.MODE_NOCTCP = cflag_add('C', chm_simple);
+	if (ModuleModes.MODE_NOCTCP == 0)
+		return -1;
+
+	ModuleModes.MODE_REGONLY = cflag_add('r', chm_regonly);
+	if (ModuleModes.MODE_REGONLY == 0)
+		return -1;
+
+	ModuleModes.MODE_NOCOLOR = cflag_add('c', chm_simple);
+	if (ModuleModes.MODE_NOCOLOR == 0)
+		return -1;
+
+	ModuleModes.MODE_EXLIMIT = cflag_add('L', chm_staff);
+	if (ModuleModes.MODE_EXLIMIT == 0)
+		return -1;
+
+	ModuleModes.MODE_PERMANENT = cflag_add('P', chm_staff);
+	if (ModuleModes.MODE_PERMANENT == 0)
+		return -1;
+
+	ModuleModes.MODE_OPMODERATE = cflag_add('z', chm_simple);
+	if (ModuleModes.MODE_OPMODERATE == 0)
+		return -1;
+
+	ModuleModes.MODE_FREEINVITE = cflag_add('g', chm_simple);
+	if (ModuleModes.MODE_FREEINVITE == 0)
+		return -1;
+
+	ModuleModes.MODE_FREETARGET = cflag_add('F', chm_simple);
+	if (ModuleModes.MODE_FREETARGET == 0)
+		return -1;
+
+	ModuleModes.MODE_DISFORWARD = cflag_add('Q', chm_simple);
+	if (ModuleModes.MODE_DISFORWARD == 0)
+		return -1;
+
+	ModuleModes.CHFL_QUIET = cflag_add('q', chm_ban);
+	if (ModuleModes.CHFL_QUIET == 0)
+		return -1;
+
+	ModuleModes.MODE_FORWARD = cflag_add('f', chm_forward);
+	if (ModuleModes.MODE_FORWARD == 0)
+		return -1;
+
+	ModuleModes.MODE_THROTTLE = cflag_add('j', chm_throttle);
+	if (ModuleModes.MODE_THROTTLE == 0)
+		return -1;
+
+	/* shadowircd modes */
+
+	ModuleModes.MODE_NONOTICE = cflag_add('T', chm_simple);
+	if (ModuleModes.MODE_NONOTICE == 0)
+		return -1;
+
+	ModuleModes.MODE_NOACTION = cflag_add('D', chm_simple);
+	if (ModuleModes.MODE_NOACTION == 0)
+		return -1;
+
+	ModuleModes.MODE_NOKICK = cflag_add('E', chm_simple);
+	if (ModuleModes.MODE_NOKICK == 0)
+		return -1;
+
+	ModuleModes.MODE_NONICK = cflag_add('N', chm_simple);
+	if (ModuleModes.MODE_NONICK == 0)
+		return -1;
+
+	ModuleModes.MODE_NOCAPS = cflag_add('G', chm_simple);
+	if (ModuleModes.MODE_NOCAPS == 0)
+		return -1;
+
+	ModuleModes.MODE_NOREJOIN = cflag_add('J', chm_simple);
+	if (ModuleModes.MODE_NOREJOIN == 0)
+		return -1;
+
+	ModuleModes.MODE_NOREPEAT = cflag_add('K', chm_simple);
+	if (ModuleModes.MODE_NOREPEAT == 0)
+		return -1;
+
+	ModuleModes.MODE_NOOPERKICK = cflag_add('M', chm_hidden);
+	if (ModuleModes.MODE_NOOPERKICK == 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+_moddeinit(void)
+{
+	/* charybdis modes */
+	cflag_orphan('C');
+	ModuleModes.MODE_NOCTCP = 0;
+
+	cflag_orphan('r');
+	ModuleModes.MODE_REGONLY = 0;
+
+	cflag_orphan('c');
+	ModuleModes.MODE_NOCOLOR = 0;
+
+	cflag_orphan('L');
+	ModuleModes.MODE_EXLIMIT = 0;
+
+	cflag_orphan('P');
+	ModuleModes.MODE_PERMANENT = 0;
+
+	cflag_orphan('z');
+	ModuleModes.MODE_OPMODERATE = 0;
+
+	cflag_orphan('g');
+	ModuleModes.MODE_FREEINVITE = 0;
+
+	cflag_orphan('F');
+	ModuleModes.MODE_FREETARGET = 0;
+
+	cflag_orphan('Q');
+	ModuleModes.MODE_DISFORWARD = 0;
+
+	cflag_orphan('q');
+	ModuleModes.CHFL_QUIET = 0;
+
+	cflag_orphan('f');
+	ModuleModes.MODE_FORWARD = 0;
+
+	cflag_orphan('j');
+	ModuleModes.MODE_THROTTLE = 0;
+
+	/* shadowircd modes */
+
+	cflag_orphan('T');
+	ModuleModes.MODE_NONOTICE = 0;
+
+	cflag_orphan('D');
+	ModuleModes.MODE_NOACTION = 0;
+
+	cflag_orphan('E');
+	ModuleModes.MODE_NOKICK = 0;
+
+	cflag_orphan('N');
+	ModuleModes.MODE_NONICK = 0;
+
+	cflag_orphan('G');
+	ModuleModes.MODE_NOCAPS = 0;
+
+	cflag_orphan('J');
+	ModuleModes.MODE_NOREJOIN = 0;
+
+	cflag_orphan('K');
+	ModuleModes.MODE_NOREPEAT = 0;
+
+	cflag_orphan('M');
+	ModuleModes.MODE_NOOPERKICK = 0;
+}
+
+DECLARE_MODULE_AV1(charybdis, _modinit, _moddeinit, NULL, NULL, NULL, "$charybdis$");

modules/core/m_join.c

 static int ms_join(struct Client *, struct Client *, int, const char **);
 static int ms_sjoin(struct Client *, struct Client *, int, const char **);
 
+struct module_modes ModuleModes;
+
 struct Message join_msgtab = {
 	"JOIN", 0, 0, 0, MFLG_SLOW,
 	{mg_unreg, {m_join, 2}, {ms_join, 2}, mg_ignore, mg_ignore, {m_join, 2}}
 				     CheckEmpty(para[2]), CheckEmpty(para[3]));
 	}
 
-	if(!joins && !(chptr->mode.mode & MODE_PERMANENT) && isnew)
+	if(!joins && !(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && isnew)
 	{
 		destroy_channel(chptr);
 
 		len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
 		pbuf += len;
 	}
-	if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
+	if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ModuleModes.MODE_FORWARD)
 	{
 		if(dir != MODE_ADD)
 		{

modules/core/m_kick.c

 #include "s_conf.h"
 #include "hook.h"
 
+struct module_modes ModuleModes;
+
 static int m_kick(struct Client *, struct Client *, int, const char **);
 #define mg_kick { m_kick, 3 }
 
 			return 0;
 		}
 
-		if(MyClient(source_p) && chptr->mode.mode & MODE_NOKICK)
+		if(MyClient(source_p) && chptr->mode.mode & ModuleModes.MODE_NOKICK)
 		{
 			sendto_one_numeric(source_p, ERR_NOKICK,
 					form_str(ERR_NOKICK),
 			return 0;
 		}
 
-		if (MyClient(source_p) && chptr->mode.mode & MODE_NOOPERKICK && IsOper(who))
+		if (MyClient(source_p) && chptr->mode.mode & ModuleModes.MODE_NOOPERKICK && IsOper(who))
 		{
 			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
 					"Overriding KICK from %s on %s in %s (channel is +M)",
 		rb_snprintf(text, sizeof(text), "K%s", who->id);
 
 		/* we don't need to track NOREJOIN stuff unless it's our client being kicked */
-		if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
+		if(MyClient(who) && chptr->mode.mode & ModuleModes.MODE_NOREJOIN)
 			channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
 	}
 	else if (MyClient(source_p))

modules/core/m_message.c

 #include "tgchange.h"
 #include "inline/stringops.h"
 #include "irc_dictionary.h"
+#include "channel.h"
 
 static int m_message(int, const char *, struct Client *, struct Client *, int, const char **);
 static int m_privmsg(struct Client *, struct Client *, int, const char **);
 static void expire_tgchange(void *unused);
 static struct ev_entry *expire_tgchange_event;
 
+struct module_modes ModuleModes;
+
 static int
 modinit(void)
 {
 			source_p->localClient->last = rb_current_time();
 	}
 
-	if(chptr->mode.mode & MODE_NOREPEAT)
+	if(chptr->mode.mode & ModuleModes.MODE_NOREPEAT)
 	{
 		rb_strlcpy(text2, text, BUFSIZE);
 		strip_unprintable(text2);
 		channel_metadata_add(chptr, "NOREPEAT", text2, 0);
 	}
 
-	if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
+	if(chptr->mode.mode & ModuleModes.MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
 	{
 		rb_strlcpy(text2, text, BUFSIZE);
 		strip_colour(text2);
 		if(result == CAN_SEND_OPV ||
 		   !flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
 		{
-			if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
+			if (strlen(text) > 10 && chptr->mode.mode & ModuleModes.MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
 			{
 				rb_strlcpy(text2, text, BUFSIZE);
 				strip_unprintable(text2);
 					return;
 				}
 			}
-			if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
+			if (p_or_n != PRIVMSG && chptr->mode.mode & ModuleModes.MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
 			{
 				sendto_one_numeric(source_p, 404, "%s :Cannot send to channel - Notices are disallowed (+T set)", chptr->chname);
 				return;
 			}
-			if (p_or_n != NOTICE && chptr->mode.mode & MODE_NOACTION &&
+			if (p_or_n != NOTICE && chptr->mode.mode & ModuleModes.MODE_NOACTION &&
 					!strncasecmp(text + 1, "ACTION", 6) &&
 					(!ConfigChannel.exempt_cmode_D || !is_any_op(msptr)))
 			{
 			if (p_or_n != NOTICE && *text == '\001' &&
 					strncasecmp(text + 1, "ACTION", 6))
 			{
-				if (chptr->mode.mode & MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
+				if (chptr->mode.mode & ModuleModes.MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
 				{
 					sendto_one_numeric(source_p, 404, "%s :Cannot send to channel - CTCPs to this channel are disallowed (+C set)", chptr->chname);
 					return;
 					     "%s %s :%s", command, chptr->chname, text);
 		}
 	}
-	else if(chptr->mode.mode & MODE_OPMODERATE &&
+	else if(chptr->mode.mode & ModuleModes.MODE_OPMODERATE &&
 			(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
 			 IsMember(source_p, chptr)))
 	{
 {
 	char text2[BUFSIZE];
 
-	if(chptr->mode.mode & MODE_NOCOLOR)
+	if(chptr->mode.mode & ModuleModes.MODE_NOCOLOR)
 	{
 		rb_strlcpy(text2, text, BUFSIZE);
 		strip_colour(text2);
 		}
 	}
 
-	if(chptr->mode.mode & MODE_OPMODERATE &&
+	if(chptr->mode.mode & ModuleModes.MODE_OPMODERATE &&
 			(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
 			 IsMember(source_p, chptr)))
 	{

modules/core/m_mode.c

 #include "packet.h"
 #include "s_newconf.h"
 
+struct module_modes ModuleModes;
+
 static int m_mode(struct Client *, struct Client *, int, const char **);
 static int ms_mode(struct Client *, struct Client *, int, const char **);
 static int ms_tmode(struct Client *, struct Client *, int, const char **);
 
 	case 'q':
 		banlist = &chptr->quietlist;
-		mode_type = CHFL_QUIET;
+		mode_type = ModuleModes.CHFL_QUIET;
 		mems = ALL_MEMBERS;
 		break;
 

modules/core/m_part.c

 #include "s_conf.h"
 #include "packet.h"
 #include "inline/stringops.h"
+#include "channel.h"
 
 static int m_part(struct Client *, struct Client *, int, const char **);
 
 static void part_one_client(struct Client *client_p,
 			    struct Client *source_p, char *name, char *reason);
 
+struct module_modes ModuleModes;
 
 /*
 ** m_part
 			   (source_p->localClient->firsttime +
 			    ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time()))))
 	{
-		if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
+		if(chptr->mode.mode & ModuleModes.MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
 		{
 			rb_strlcpy(reason2, reason, BUFSIZE);
 			strip_colour(reason2);
 		"Enable chanmode +I (invite exceptions)",
 	},
 	{
-		"use_forward",
-		OUTPUT_BOOLEAN_YN,
-		&ConfigChannel.use_forward,
-		"Enable chanmode +f (channel forwarding)",
-	},
-	{
 		"use_knock",
 		OUTPUT_BOOLEAN_YN,
 		&ConfigChannel.use_knock,

modules/m_invite.c

 #include "modules.h"
 #include "packet.h"
 #include "tgchange.h"
+#include "channel.h"
+
+struct module_modes ModuleModes;
 
 static int m_invite(struct Client *, struct Client *, int, const char **);
 
 	/* unconditionally require ops, unless the channel is +g */
 	/* treat remote clients as chanops */
 	if(MyClient(source_p) && !is_any_op(msptr) &&
-			!(chptr->mode.mode & MODE_FREEINVITE))
+			!(chptr->mode.mode & ModuleModes.MODE_FREEINVITE))
 	{
 		if(IsOverride(source_p))
 		{
 	 * for +l/+j just check if the mode is set, this varies over time
 	 */
 	if(chptr->mode.mode & MODE_INVITEONLY ||
-			(chptr->mode.mode & MODE_REGONLY && EmptyString(target_p->user->suser)) ||
+			(chptr->mode.mode & ModuleModes.MODE_REGONLY && EmptyString(target_p->user->suser)) ||
 			chptr->mode.limit || chptr->mode.join_num)
 		store_invite = 1;
 

modules/m_knock.c

 #include "modules.h"
 #include "s_serv.h"
 
+struct module_modes ModuleModes;
+
 static int m_knock(struct Client *, struct Client *, int, const char **);
 
 struct Message knock_msgtab = {
 	chptr->last_knock = rb_current_time();
 
 	if(ConfigChannel.use_knock)
-		sendto_channel_local(chptr->mode.mode & MODE_FREEINVITE ? ALL_MEMBERS : ONLY_CHANOPS,
+		sendto_channel_local(chptr->mode.mode & ModuleModes.MODE_FREEINVITE ? ALL_MEMBERS : ONLY_CHANOPS,
 				     chptr, form_str(RPL_KNOCK),
 				     me.name, name, name, source_p->name,
 				     source_p->username, source_p->host);
 static int h_can_create_channel;
 static int h_channel_join;
 
+struct module_modes ModuleModes;
+
 /* init_channels()
  *
  * input	-
 	h_can_create_channel = register_hook("can_create_channel");
 }
 
+/* is this the best place to put this? */
+/* init_module_modes()
+ *
+ * input	-
+ * output	-
+ * side effects - various MODE_ values are set to 0
+ */
+void
+init_module_modes()
+{
+	ModuleModes.MODE_REGONLY = 0;
+	ModuleModes.MODE_NOCTCP = 0;
+	ModuleModes.MODE_NOCOLOR = 0;
+	ModuleModes.MODE_EXLIMIT = 0;
+	ModuleModes.MODE_PERMANENT = 0;
+	ModuleModes.MODE_OPMODERATE = 0;
+	ModuleModes.MODE_FREEINVITE = 0;
+	ModuleModes.MODE_FREETARGET = 0;
+	ModuleModes.MODE_DISFORWARD = 0;
+	ModuleModes.MODE_THROTTLE = 0;
+	ModuleModes.MODE_FORWARD = 0;
+	ModuleModes.MODE_NONOTICE = 0;
+	ModuleModes.MODE_NOACTION = 0;
+	ModuleModes.MODE_NOKICK = 0;
+	ModuleModes.MODE_NONICK = 0;
+	ModuleModes.MODE_NOCAPS = 0;
+	ModuleModes.MODE_NOREJOIN = 0;
+	ModuleModes.MODE_NOREPEAT = 0;
+	ModuleModes.MODE_NOOPERKICK = 0;
+
+	ModuleModes.CHFL_QUIET = 0;
+}
+
+
 /*
  * allocate_channel - Allocates a channel
  */
 	if(client_p->servptr == &me)
 		rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
 
-	if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
+	if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
 		destroy_channel(chptr);
 
 	rb_bh_free(member_heap, msptr);
 		if(client_p->servptr == &me)
 			rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
 
-		if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
+		if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
 			destroy_channel(chptr);
 
 		rb_bh_free(member_heap, msptr);
 	struct Ban *actualBan = NULL;
 	struct Ban *actualExcept = NULL;
 
+	/* check to make sure quiets even exist on this server first */
+	if(ModuleModes.CHFL_QUIET == 0)
+		return 0;
+
 	if(!MyClient(who))
 		return 0;
 
 		if(match(actualBan->banstr, s) ||
 		   match(actualBan->banstr, s2) ||
 		   match_cidr(actualBan->banstr, s2) ||
-		   match_extban(actualBan->banstr, who, chptr, CHFL_QUIET) ||
+		   match_extban(actualBan->banstr, who, chptr, ModuleModes.CHFL_QUIET) ||
 		   (s3 != NULL && match(actualBan->banstr, s3)))
 			break;
 		else
 	if(chptr->mode.limit &&
 	   rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
 		i = ERR_CHANNELISFULL;
-	if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser))
+	if(chptr->mode.mode & ModuleModes.MODE_REGONLY && EmptyString(source_p->user->suser))
 		i = ERR_NEEDREGGEDNICK;
 	/* join throttling stuff --nenolod */
-	else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
+	/* only check for throttles if they exist on this server --Taros */
+	else if(ModuleModes.MODE_THROTTLE)
 	{
-		if ((rb_current_time() - chptr->join_delta <= 
-			chptr->mode.join_time) && (chptr->join_count >=
-			chptr->mode.join_num))
-			i = ERR_THROTTLE;
+		if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
+		{
+			if ((rb_current_time() - chptr->join_delta <= 
+				chptr->mode.join_time) && (chptr->join_count >=
+				chptr->mode.join_num))
+				i = ERR_THROTTLE;
+		}
 	}
 
 	/* allow /invite to override +l/+r/+j also -- jilles */
 	{
 		msptr = ptr->data;
 		chptr = msptr->chptr;
-		if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
+		if (chptr->mode.mode & ModuleModes.MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
 			return chptr;
 	}
 	return NULL;
 					   chptr->mode.join_time);
 	}
 
-	if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p)))
+	if(*chptr->mode.forward && (ModuleModes.MODE_FORWARD || !IsClient(client_p)))
 	{
 		*mbuf++ = 'f';
 
 		if (hash_find_resv(chptr->chname))
 			return NULL;
 		/* Don't forward to +Q channel */
-		if (chptr->mode.mode & MODE_DISFORWARD)
+		if (chptr->mode.mode & ModuleModes.MODE_DISFORWARD)
 			return NULL;
 		i = can_join(source_p, chptr, key);
 		if (i == 0)
 						me.name, get_oper_name(source_p), chptr->chname);
 			}
 			else if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) ||
-			    (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL))
+			    (!ModuleModes.MODE_FORWARD || (chptr = check_forward(source_p, chptr, key)) == NULL))
 			{
 				/* might be wrong, but is there any other better location for such?
 				 * see extensions/chm_operonly.c for other comments on this
 
 int chmode_flags[256];
 
+struct module_modes ModuleModes;
+
 /* OPTIMIZE ME! -- dwr */
 void
 construct_cflags_strings(void)
 			chmode_flags[i] = 0;
 		}
                 
-		switch (chmode_flags[i])
+		if(chmode_flags[i] == ModuleModes.MODE_DISFORWARD)
 		{
-		    case MODE_EXLIMIT:
-		    case MODE_DISFORWARD:
-			if(ConfigChannel.use_forward)
+			if (ModuleModes.MODE_FORWARD)
 			{
-			    *ptr++ = (char) i;
+				*ptr++ = (char) i;
 			}
-			
-			break;
-		    case MODE_REGONLY:
-			if(rb_dlink_list_length(&service_list))
+		}
+		else if(chmode_flags[i] == ModuleModes.MODE_REGONLY)
+		{
+			if (rb_dlink_list_length(&service_list))
 			{
-			    *ptr++ = (char) i;
+				*ptr++ = (char) i;
 			}
-
-			break;
-		    default:
-			if(chmode_flags[i] != 0)
-			{
-			    *ptr++ = (char) i;
-			}
+		}
+		else if(chmode_flags[i] != ModuleModes.MODE_EXLIMIT && chmode_flags[i] != 0)
+		{
+			*ptr++ = (char) i;
 		}
 		
 		/* Should we leave orphaned check here? -- dwr */
 	 */
 	if(MyClient(source_p))
 	{
-		if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (chptr->mode.mode & MODE_EXLIMIT ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
+		if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (chptr->mode.mode & ModuleModes.MODE_EXLIMIT ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
 		{
 			sendto_one(source_p, form_str(ERR_BANLISTFULL),
 				   me.name, source_p->name, chptr->chname, realban);
 	rb_dlinkAdd(actualBan, &actualBan->node, list);
 
 	/* invalidate the can_send() cache */
-	if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+	if(mode_type == CHFL_BAN || mode_type == ModuleModes.CHFL_QUIET || mode_type == CHFL_EXCEPTION)
 		chptr->bants++;
 
 	return 1;
 			free_ban(banptr);
 
 			/* invalidate the can_send() cache */
-			if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+			if(mode_type == CHFL_BAN || mode_type == ModuleModes.CHFL_QUIET || mode_type == CHFL_EXCEPTION)
 				chptr->bants++;
 
 			return 1;
 	if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
 	{
 		/* if +f is disabled, ignore an attempt to set +QF locally */
-		if(!ConfigChannel.use_forward && MyClient(source_p) &&
+		if(!ModuleModes.MODE_FORWARD && MyClient(source_p) &&
 		   (c == 'Q' || c == 'F'))
 			return;
 
 	int mems;
 	int override = 0;
 
-	switch (mode_type)
+	if(mode_type == CHFL_BAN)
 	{
-	case CHFL_BAN:
 		list = &chptr->banlist;
 		errorval = SM_ERR_RPL_B;
 		rpl_list = RPL_BANLIST;
 		rpl_endlist = RPL_ENDOFBANLIST;
 		mems = ALL_MEMBERS;
 		caps = 0;
-		break;
-
-	case CHFL_EXCEPTION:
+	}
+	else if(mode_type == CHFL_EXCEPTION)
+	{
 		/* if +e is disabled, allow all but +e locally */
 		if(!ConfigChannel.use_except && MyClient(source_p) &&
 		   ((dir == MODE_ADD) && (parc > *parn)))
 			mems = ONLY_CHANOPS;
 		else
 			mems = ONLY_SERVERS;
-		break;
-
-	case CHFL_INVEX:
+	}
+	else if(mode_type == CHFL_INVEX)
+	{
 		/* if +I is disabled, allow all but +I locally */
 		if(!ConfigChannel.use_invex && MyClient(source_p) &&
 		   (dir == MODE_ADD) && (parc > *parn))
 			mems = ONLY_CHANOPS;
 		else
 			mems = ONLY_SERVERS;
-		break;
-
-	case CHFL_QUIET:
+	}
+	else if(mode_type == ModuleModes.CHFL_QUIET)
+	{
 		list = &chptr->quietlist;
 		errorval = SM_ERR_RPL_Q;
 		rpl_list = RPL_QUIETLIST;
 		rpl_endlist = RPL_ENDOFQUIETLIST;
 		mems = ALL_MEMBERS;
 		caps = 0;
-		break;
-
-	default:
+	}
+	else
+	{
 		sendto_realops_snomask(SNO_GENERAL, L_ALL, "chm_ban() called with unknown type!");
 		return;
-		break;
 	}
 
 	if(dir == 0 || parc <= *parn)
 
 		/* non-ops cant see +eI lists.. */
 		if(alevel != CHFL_CHANOP && alevel != CHFL_ADMIN && alevel != CHFL_HALFOP && mode_type != CHFL_BAN &&
-				mode_type != CHFL_QUIET)
+				mode_type != ModuleModes.CHFL_QUIET)
 		{
 			if(IsOverride(source_p))
 			{
 	int override = 0;
 
 	/* if +f is disabled, ignore local attempts to set it */
-	if(!ConfigChannel.use_forward && MyClient(source_p) &&
+	if(!ModuleModes.MODE_FORWARD && MyClient(source_p) &&
 	   (dir == MODE_ADD) && (parc > *parn))
 		return;
 
 					   form_str(ERR_NOSUCHCHANNEL), forward);
 			return;
 		}
-		if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET))
+		if(MyClient(source_p) && !(targptr->mode.mode & ModuleModes.MODE_FREETARGET))
 		{
 			if((msptr = find_channel_membership(targptr, source_p)) == NULL ||
-				is_any_op(msptr))
+				!is_any_op(msptr))
 			{
 				if(IsOverride(source_p))
 					override = 1;
 		mode_changes[mode_count].dir = MODE_ADD;
 		mode_changes[mode_count].caps = 0;
 		mode_changes[mode_count].nocaps = 0;
-		mode_changes[mode_count].mems = ConfigChannel.use_forward ? ALL_MEMBERS : ONLY_SERVERS;
+		mode_changes[mode_count].mems = ModuleModes.MODE_FORWARD ? ALL_MEMBERS : ONLY_SERVERS;
 		mode_changes[mode_count].id = NULL;
 		mode_changes[mode_count].override = override;
 		mode_changes[mode_count++].arg = forward;
 }
 
 /* *INDENT-OFF* */
+/* Only RFC and ircd-ratbox modes are held in this table
+ * All other modes are added via loading modules in shadowircd/modes
+ * Such is documented in the comments for each mode, ex: C - NOCTCP. */
 struct ChannelMode chmode_table[256] =
 {
   {chm_nosuch,  0 },			/* 0x00 */
   {chm_nosuch,	0 },			/* @ */
   {chm_nosuch,	0 },			/* A */
   {chm_nosuch,	0 },			/* B */
-  {chm_simple,	MODE_NOCTCP },		/* C */
-  {chm_simple,	MODE_NOACTION },	/* D */
-  {chm_simple,	MODE_NOKICK },		/* E */
-  {chm_simple,	MODE_FREETARGET },	/* F */
-  {chm_simple,	MODE_NOCAPS },		/* G */
+  {chm_nosuch,	0 },			/* C - MODE_NOCTCP */
+  {chm_nosuch,	0 },			/* D - MODE_NOACTION */
+  {chm_nosuch,	0 },			/* E - MODE_NOKICK */
+  {chm_nosuch,	0 },			/* F - MODE_FREETARGET */
+  {chm_nosuch,	0 },			/* G - MODE_NOCAPS */
   {chm_nosuch,	0 },			/* H */
   {chm_ban,	CHFL_INVEX },           /* I */
-  {chm_simple,	MODE_NOREJOIN },	/* J */
-  {chm_simple,	MODE_NOREPEAT },	/* K */
-  {chm_staff,	MODE_EXLIMIT },		/* L */
-  {chm_hidden,	MODE_NOOPERKICK },	/* M */
-  {chm_simple,	MODE_NONICK },		/* N */
+  {chm_nosuch,	0 },			/* J - MODE_NOREJOIN */
+  {chm_nosuch,	0 },			/* K - MODE_NOREPEAT */
+  {chm_nosuch,	0 },			/* L - MODE_EXLIMIT */
+  {chm_nosuch,	0 },			/* M - MODE_NOOPERKICK */
+  {chm_nosuch,	0 },			/* N - MODE_NONICK */
   {chm_nosuch,	0 },			/* O */
-  {chm_staff,	MODE_PERMANENT },	/* P */
-  {chm_simple,	MODE_DISFORWARD },	/* Q */
+  {chm_nosuch,	0 },			/* P - MODE_PERMANENT */
+  {chm_nosuch,	0 },			/* Q - MODE_DISFORWARD */
   {chm_nosuch,	0 },			/* R */
   {chm_nosuch,	0 },			/* S */
-  {chm_simple,	MODE_NONOTICE },	/* T */
+  {chm_nosuch,	0 },			/* T - MODE_NONOTICE */
   {chm_nosuch,	0 },			/* U */
   {chm_nosuch,	0 },			/* V */
   {chm_nosuch,	0 },			/* W */
   {chm_nosuch,	0 },
   {chm_admin,	0 },			/* a */
   {chm_ban,	CHFL_BAN },		/* b */
-  {chm_simple,	MODE_NOCOLOR },		/* c */
+  {chm_nosuch,	0 },			/* c - MODE_NOCOLOR */
   {chm_nosuch,	0 },			/* d */
   {chm_ban,	CHFL_EXCEPTION },	/* e */
-  {chm_forward,	0 },			/* f */
-  {chm_simple,	MODE_FREEINVITE },	/* g */
+  {chm_nosuch,	0 },			/* f - MODE_FORWARD */
+  {chm_nosuch,	0 },			/* g - MODE_FREEINVITE */
   {chm_halfop,	0 },			/* h */
   {chm_simple,	MODE_INVITEONLY },	/* i */
-  {chm_throttle, 0 },			/* j */
+  {chm_nosuch, 0 },			/* j - MODE_THROTTLE */
   {chm_key,	0 },			/* k */
   {chm_limit,	0 },			/* l */
   {chm_simple,	MODE_MODERATED },	/* m */
   {chm_simple,	MODE_NOPRIVMSGS },	/* n */
   {chm_op,	0 },			/* o */
   {chm_simple,	MODE_PRIVATE },		/* p */
-  {chm_ban,	CHFL_QUIET },		/* q */
-  {chm_regonly, MODE_REGONLY },		/* r */
+  {chm_nosuch,	0 },			/* q - CHFL_QUIET */
+  {chm_nosuch,	0 },			/* r - MODE_REGONLY */
   {chm_simple,	MODE_SECRET },		/* s */
   {chm_simple,	MODE_TOPICLIMIT },	/* t */
   {chm_nosuch,	0 },			/* u */
   {chm_nosuch,	0 },			/* w */
   {chm_nosuch,	0 },			/* x */
   {chm_nosuch,	0 },			/* y */
-  {chm_simple,	MODE_OPMODERATE },	/* z */
+  {chm_nosuch,	0 },			/* z - MODE_OPMODERATE */
 
   {chm_nosuch,  0 },			/* 0x7b */
   {chm_nosuch,  0 },			/* 0x7c */
 
 	seed_random(NULL);
 
+	init_module_modes();
 	init_main_logfile();
 	newconf_init();
 	init_s_conf();
 	{ "use_except",		CF_YESNO, NULL, 0, &ConfigChannel.use_except		},
 	{ "use_invex",		CF_YESNO, NULL, 0, &ConfigChannel.use_invex		},
 	{ "use_knock",		CF_YESNO, NULL, 0, &ConfigChannel.use_knock		},
-	{ "use_forward",	CF_YESNO, NULL, 0, &ConfigChannel.use_forward		},
 	{ "use_local_channels",	CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels	},
 	{ "resv_forcepart",     CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart	},
 	{ "exempt_cmode_c",	CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c	},
 	ConfigChannel.use_except = YES;
 	ConfigChannel.use_invex = YES;
 	ConfigChannel.use_knock = YES;
-	ConfigChannel.use_forward = YES;
 	ConfigChannel.use_local_channels = YES;
 	ConfigChannel.knock_delay = 300;
 	ConfigChannel.knock_delay_channel = 60;
 #include "substitution.h"
 #include "chmode.h"
 
+struct module_modes ModuleModes;
+
 static void report_and_set_user_flags(struct Client *, struct ConfItem *);
 void user_welcome(struct Client *source_p);
 
 			}
 			/* FALLTHROUGH */
 		default:
-			if (MyConnect(source_p) && *pm == 'Q' && !ConfigChannel.use_forward) {
+			if (MyConnect(source_p) && *pm == 'Q' && !ModuleModes.MODE_FORWARD) {
 				badflag = YES;
 				break;
 			}
 #include "s_conf.h"
 #include "supported.h"
 #include "chmode.h"
+#include "channel.h"
+
+struct module_modes ModuleModes;
 
 rb_dlink_list isupportlist;
 
 	rb_snprintf(result, sizeof result, "%s%sbq,k,%slj,%s",
 			ConfigChannel.use_except ? "e" : "",
 			ConfigChannel.use_invex ? "I" : "",
-			ConfigChannel.use_forward ? "f" : "",
+			ModuleModes.MODE_FORWARD ? "f" : "",
 			cflagsbuf);
 	return result;
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.