diff -r e6b8fd0ebc1f include/channel.h
--- a/include/channel.h	Tue Apr 08 16:14:01 2008 +0400
+++ b/include/channel.h	Tue Apr 08 17:28:26 2008 +0400
@@ -258,7 +258,7 @@
 extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
             	struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
 
-extern const struct mode_letter chmode_flags[];
+extern int chmode_flags[256];
 
 extern struct ChannelMode chmode_table[256];
 
diff -r e6b8fd0ebc1f modules/core/m_join.c
--- a/modules/core/m_join.c	Tue Apr 08 16:14:01 2008 +0400
+++ b/modules/core/m_join.c	Tue Apr 08 17:28:26 2008 +0400
@@ -581,48 +581,6 @@
 	{
 		switch (*(s++))
 		{
-		case 'i':
-			mode.mode |= MODE_INVITEONLY;
-			break;
-		case 'n':
-			mode.mode |= MODE_NOPRIVMSGS;
-			break;
-		case 'p':
-			mode.mode |= MODE_PRIVATE;
-			break;
-		case 's':
-			mode.mode |= MODE_SECRET;
-			break;
-		case 'm':
-			mode.mode |= MODE_MODERATED;
-			break;
-		case 't':
-			mode.mode |= MODE_TOPICLIMIT;
-			break;
-		case 'r':
-			mode.mode |= MODE_REGONLY;
-			break;
-		case 'L':
-			mode.mode |= MODE_EXLIMIT;
-			break;
-		case 'P':
-			mode.mode |= MODE_PERMANENT;
-			break;
-		case 'c':
-			mode.mode |= MODE_NOCOLOR;
-			break;
-		case 'g':
-			mode.mode |= MODE_FREEINVITE;
-			break;
-		case 'z':
-			mode.mode |= MODE_OPMODERATE;
-			break;
-		case 'F':
-			mode.mode |= MODE_FREETARGET;
-			break;
-		case 'Q':
-			mode.mode |= MODE_DISFORWARD;
-			break;
 		case 'f':
 			strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
 			args++;
@@ -649,6 +607,11 @@
 			if(parc < 5 + args)
 				return 0;
 			break;
+		default:
+			if(chmode_flags[(int) *s] != 0)
+			{
+				mode.mode |= chmode_flags[(int) *s];
+			}
 		}
 	}
 
@@ -1124,30 +1087,30 @@
 	int i;
 
 	/* ok, first get a list of modes we need to add */
-	for (i = 0; chmode_flags[i].letter; i++)
+	for (i = 0; i < 256; i++)
 	{
-		if((mode->mode & chmode_flags[i].mode) && !(oldmode->mode & chmode_flags[i].mode))
+		if((mode->mode & chmode_flags[i]) && !(oldmode->mode & chmode_flags[i]))
 		{
 			if(dir != MODE_ADD)
 			{
 				*mbuf++ = '+';
 				dir = MODE_ADD;
 			}
-			*mbuf++ = chmode_flags[i].letter;
+			*mbuf++ = i;
 		}
 	}
 
 	/* now the ones we need to remove. */
-	for (i = 0; chmode_flags[i].letter; i++)
+	for (i = 0; i < 256; i++)
 	{
-		if((oldmode->mode & chmode_flags[i].mode) && !(mode->mode & chmode_flags[i].mode))
+		if((oldmode->mode & chmode_flags[i]) && !(mode->mode & chmode_flags[i]))
 		{
 			if(dir != MODE_DEL)
 			{
 				*mbuf++ = '-';
 				dir = MODE_DEL;
 			}
-			*mbuf++ = chmode_flags[i].letter;
+			*mbuf++ = i;
 		}
 	}
 
diff -r e6b8fd0ebc1f src/channel.c
--- a/src/channel.c	Tue Apr 08 16:14:01 2008 +0400
+++ b/src/channel.c	Tue Apr 08 17:28:26 2008 +0400
@@ -1080,25 +1080,6 @@
 	}
 }
 
-const struct mode_letter chmode_flags[] =
-{
-	{MODE_INVITEONLY, 'i'},
-	{MODE_MODERATED, 'm'},
-	{MODE_NOPRIVMSGS, 'n'},
-	{MODE_PRIVATE, 'p'},
-	{MODE_SECRET, 's'},
-	{MODE_TOPICLIMIT, 't'},
-	{MODE_NOCOLOR, 'c'},
-	{MODE_FREEINVITE, 'g'},
-	{MODE_OPMODERATE, 'z'},
-	{MODE_EXLIMIT, 'L'},
-	{MODE_PERMANENT, 'P'},
-	{MODE_FREETARGET, 'F'},
-	{MODE_DISFORWARD, 'Q'},
-	{MODE_REGONLY, 'r'},
-	{0, '\0'}
-};
-
 /* channel_modes()
  *
  * inputs       - pointer to channel
@@ -1121,9 +1102,9 @@
 	*mbuf++ = '+';
 	*pbuf = '\0';
 
-	for (i = 0; chmode_flags[i].mode; ++i)
-		if(chptr->mode.mode & chmode_flags[i].mode)
-			*mbuf++ = chmode_flags[i].letter;
+	for (i = 0; i < 256; i++)
+		if(chptr->mode.mode & chmode_flags[i])
+			*mbuf++ = i;
 
 	if(chptr->mode.limit)
 	{
diff -r e6b8fd0ebc1f src/chmode.c
--- a/src/chmode.c	Tue Apr 08 16:14:01 2008 +0400
+++ b/src/chmode.c	Tue Apr 08 17:28:26 2008 +0400
@@ -42,6 +42,7 @@
 #include "s_conf.h"		/* ConfigFileEntry, ConfigChannel */
 #include "s_newconf.h"
 #include "logger.h"
+#include "chmode.h"
 
 /* bitmasks for error returns, so we send once per call */
 #define SM_ERR_NOTS             0x00000001	/* No TS on channel */
@@ -67,6 +68,27 @@
 static int mode_count;
 static int mode_limit;
 static int mask_pos;
+
+int chmode_flags[256];
+void
+construct_noparam_modes(void)
+{
+	int i;
+
+	for(i = 0; i < 256; i++)
+	{
+		if( (chmode_table[i].set_func == chm_simple) ||
+			(chmode_table[i].set_func == chm_staff) ||
+			(chmode_table[i].set_func == chm_regonly))
+		{
+			chmode_flags[i] = chmode_table[i].mode_type;
+		}
+		else
+		{
+			chmode_flags[i] = 0;
+		}
+	}
+}
 
 int
 get_channel_access(struct Client *source_p, struct membership *msptr)
diff -r e6b8fd0ebc1f src/ircd.c
--- a/src/ircd.c	Tue Apr 08 16:14:01 2008 +0400
+++ b/src/ircd.c	Tue Apr 08 17:28:26 2008 +0400
@@ -66,6 +66,7 @@
 #include "patchlevel.h"
 #include "serno.h"
 #include "sslproc.h"
+#include "chmode.h"
 
 /* /quote set variables */
 struct SetOptions GlobalSetOptions;
@@ -594,6 +595,7 @@
 	init_client();
 	initUser();
 	init_hook();
+	construct_noparam_modes();
 	init_channels();
 	initclass();
 	initwhowas();
