Index: include/channel_mode.h
===================================================================
--- include/channel_mode.h	(.../1.0.0)	(revision 131)
+++ include/channel_mode.h	(.../1.0.1)	(revision 131)
@@ -31,7 +31,7 @@
 #define MODEBUFLEN   200
 
 /* Maximum mode changes allowed per client, per server is different */
-#define MAXMODEPARAMS 4
+#define MAXMODEPARAMS 6
 
 /* can_send results */
 #define CAN_SEND_NO	0
@@ -58,8 +58,9 @@
 #define MODE_REGONLY    0x0040      /* only identified users may join */
 #define MODE_REGMOD     0x0080      /* only identified users may speak */
 #define MODE_REGISTERED 0x0100      /* registered with services */
-#define MODE_COLORLESS  0x0200      /* no colors, bold, or italics */
-#define MODE_OPERONLY   0x0400      /* only opers may join/msg */
+#define MODE_COLORLESS  0x0200      /* no colors */
+#define MODE_ASCIIONLY  0x0400      /* only ASCII characters */
+#define MODE_OPERONLY   0x0800      /* only opers may join/msg */
 
 /* cache flags for silence on ban */
 #define CHFL_BAN_CHECKED  0x0080
Index: include/numeric.h
===================================================================
--- include/numeric.h	(.../1.0.0)	(revision 131)
+++ include/numeric.h	(.../1.0.1)	(revision 131)
@@ -206,9 +206,11 @@
 /*#define	RPL_USERIP	     307	 Undernet extension */
 #define	RPL_WHOISREGNICK     307
 #define RPL_WHOISREGONLY     308
+#define RPL_WHOISCAPTURED    309
 /*	RPL_SUSERHOST	     307	austnet */
 /*      RPL_NOTIFYACTION     308         aircd */
 /*	RPL_RULESSTART	     308	unreal */
+
 /*      RPL_NICKTRACE        309         aircd */
 /*	RPL_WHOISSADMIN	     309	Numeric List: Dalnet */
 /*	RPL_ENDOFRULES	     309	unreal */
@@ -327,6 +329,7 @@
 #define ERR_NOORIGIN         409
 #define ERR_INVALIDCAPCMD    410
 
+#define ERR_NOORIGIN         409
 #define ERR_NORECIPIENT      411
 #define ERR_NOTEXTTOSEND     412
 #define ERR_NOTOPLEVEL       413
@@ -422,6 +425,8 @@
  * moved to 999
  */
 
+#define ERR_NOCONTROLSONCHAN 508
+
 /*      ERR_NOTIFYFULL       512           aircd */
 /*	ERR_TOOMANYWATCH     512           Numeric List: Dalnet */
 /*      ERR_NEEDPONG	     512           Numeric List: Dalnet */
Index: include/patchlevel.h
===================================================================
--- include/patchlevel.h	(.../1.0.0)	(revision 131)
+++ include/patchlevel.h	(.../1.0.1)	(revision 131)
@@ -23,5 +23,5 @@
  */
 
 #ifndef PATCHLEVEL
-#define PATCHLEVEL   "esphyb-1.0.0"
+#define PATCHLEVEL   "esphyb-1.0.1"
 #endif
Index: src/channel.c
===================================================================
--- src/channel.c	(.../1.0.0)	(revision 131)
+++ src/channel.c	(.../1.0.1)	(revision 131)
@@ -664,14 +664,16 @@
 int
 can_join(struct Client *source_p, struct Channel *chptr, const char *key)
 {
-  if (is_banned(chptr, source_p))
+  int not_invited = !dlinkFind(&source_p->localClient->invited, chptr);
+
+  if (is_banned(chptr, source_p) && not_invited)
     return ERR_BANNEDFROMCHAN;
 
   if (IsCaptured(source_p) && irccmp(chptr->chname, ServerInfo.help_channel) != 0)
     return ERR_NOJOINCAPTURED;
 
   if (chptr->mode.mode & MODE_INVITEONLY)
-    if (!dlinkFind(&source_p->localClient->invited, chptr))
+    if (not_invited)
       if (!ConfigChannel.use_invex || !find_bmask(source_p, &chptr->invexlist))
         return ERR_INVITEONLYCHAN;
 
Index: src/version.c
===================================================================
--- src/version.c	(.../1.0.0)	(revision 131)
+++ src/version.c	(.../1.0.1)	(revision 131)
@@ -119,6 +119,7 @@
   "",
   "eri, Sean Rees, <eri@esper.net>",
   "Kage, Kelmar Firesun, <kage@esper.net>",
+  "dNA, Daniel Pemberton, <dna@esper.net>",
   "",
   "The EsperNet IRC Network: irc.esper.net:5555 (http://www.esper.net)",
   "", 0
Index: src/s_conf.c
===================================================================
--- src/s_conf.c	(.../1.0.0)	(revision 131)
+++ src/s_conf.c	(.../1.0.1)	(revision 131)
@@ -2524,7 +2524,7 @@
 	     ConfigChannel.max_chans_per_user);
   add_isupport("CHANLIMIT", chanlimit, -1);
   ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
-	     ConfigChannel.use_invex ? "I" : "", "b,k,l,cimMnOpRst");
+	     ConfigChannel.use_invex ? "I" : "", "b,k,l,cCimMnOpRst");
   add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
   if (ConfigChannel.use_except)
     add_isupport("EXCEPTS", "e", -1);
Index: src/channel_mode.c
===================================================================
--- src/channel_mode.c	(.../1.0.0)	(revision 131)
+++ src/channel_mode.c	(.../1.0.1)	(revision 131)
@@ -336,6 +336,7 @@
   { MODE_REGONLY,    'R' },
   { MODE_REGMOD,     'M' },
   { MODE_COLORLESS,  'c' },
+  { MODE_ASCIIONLY,  'C' },
   { MODE_OPERONLY,   'O' },
   { 0, '\0' }
 };
@@ -1313,7 +1314,7 @@
   {chm_nosuch, NULL},
   {chm_nosuch, NULL},                             /* A */
   {chm_nosuch, NULL},                             /* B */
-  {chm_nosuch, NULL},                             /* C */
+  {chm_simple, (void *) MODE_ASCIIONLY},          /* C */
   {chm_nosuch, NULL},                             /* D */
   {chm_nosuch, NULL},                             /* E */
   {chm_nosuch, NULL},                             /* F */
@@ -1343,7 +1344,7 @@
   {chm_nosuch, NULL},
   {chm_nosuch, NULL},
   {chm_nosuch, NULL},
-  {chm_nosuch, NULL},				  /* a */
+  {chm_nosuch, NULL},                             /* a */
   {chm_ban, NULL},                                /* b */
   {chm_simple, (void *) MODE_COLORLESS},          /* c */
   {chm_nosuch, NULL},                             /* d */
@@ -1353,7 +1354,7 @@
 #ifdef HALFOPS
   {chm_hop, NULL},                                /* h */
 #else
-  {chm_nosuch, NULL},				  /* h */
+  {chm_nosuch, NULL},                             /* h */
 #endif
   {chm_simple, (void *) MODE_INVITEONLY},         /* i */
   {chm_nosuch, NULL},                             /* j */
Index: src/messages.tab
===================================================================
--- src/messages.tab	(.../1.0.0)	(revision 131)
+++ src/messages.tab	(.../1.0.1)	(revision 131)
@@ -333,7 +333,7 @@
 /* 306 */  {"RPL_NOWAWAY", ":%s 306 %s :You have been marked as being away", NULL},
 /* 307 */  {"RPL_WHOISREGNICK", ":%s 307 %s %s :has identified for this nick", NULL},
 /* 308 */  {"RPL_WHOISREGONLY", ":%s 308 %s %s :accepts messages from identified users only", NULL},
-/* 309 */  {NULL, NULL, NULL},
+/* 309 */  {"RPL_WHOISCAPTURED", ":%s 309 %s %s :is captured", NULL},
 /* 310 */  {NULL, NULL, NULL},
 /* 311 */  {"RPL_WHOISUSER", ":%s 311 %s %s %s %s * :%s", NULL},
 /* 312 */  {"RPL_WHOISSERVER", ":%s 312 %s %s %s :%s", NULL},
@@ -532,7 +532,7 @@
 /* 505 */  {"ERR_SERVICESONLY", ":%s 481 %s :Permission Denied", NULL},
 /* 506 */  {NULL, NULL, NULL},
 /* 507 */  {NULL, NULL, NULL},
-/* 508 */  {NULL, NULL, NULL},
+/* 508 */  {"ERR_NOCONTROLSONCHAN", ":%s 408 %s %s :Cannot send to channel; non-ASCII characters are not permitted on %s", NULL},
 /* 509 */  {NULL, NULL, NULL},
 /* 510 */  {NULL, NULL, NULL},
 /* 511 */  {NULL, NULL, NULL},
@@ -740,9 +740,9 @@
 /* 713 */  {"ERR_CHANOPEN", ":%s 713 %s %s :Channel is open.", NULL},
 /* 714 */  {"ERR_KNOCKONCHAN", ":%s 714 %s %s :You are already on that channel.", NULL},
 /* 715 */  {"ERR_KNOCKDISABLED", ":%s 715 %s :KNOCKs are disabled.", NULL},
-/* 716 */  {"RPL_TARGUMODEG", ":%s 716 %s %s :is in +g mode (server side ignore)", NULL},
+/* 716 */  {"RPL_TARGUMODEG", ":%s 716 %s %s :has enabled caller ID (server side ignore)", NULL},
 /* 717 */  {"RPL_TARGNOTIFY", ":%s 717 %s %s :has been informed that you messaged them.", NULL},
-/* 718 */  {"RPL_UMODEGMSG", ":%s 718 %s %s :is messaging you, and you are umode +g.", NULL},
+/* 718 */  {"RPL_UMODEGMSG", ":%s 718 %s %s :is messaging you. If you wish, you may /ACCEPT their message.", NULL},
 /* 719 */  {NULL, NULL, NULL},
 /* 720 */  {"RPL_OMOTDSTART", ":%s 720 %s :Start of OPER MOTD.", NULL},
 /* 721 */  {"RPL_OMOTD", ":%s 721 %s :%s", NULL},
Index: doc/modes.txt
===================================================================
--- doc/modes.txt	(.../1.0.0)	(revision 131)
+++ doc/modes.txt	(.../1.0.1)	(revision 131)
@@ -42,7 +42,8 @@
 Channel Modes:
 
 +b - ban          - Channel ban on nick!user@host
-+c - colorless    - No colors or control characters
++c - colorless    - No colors on channel
++C - ascii only   - No colors or control characters. Only ASCII characters permitted
 +e - exempt       - Exemption from bans
 +I - invex        - Invite exceptions, nick!user@host does not need to be
                     explicitly INVITE'd into the channel before being able
Index: modules/m_invite.c
===================================================================
--- modules/m_invite.c	(.../1.0.0)	(revision 131)
+++ modules/m_invite.c	(.../1.0.1)	(revision 131)
@@ -195,9 +195,10 @@
                               target_p->name, chptr->chname);
       }
 
-      /* Add the invite if channel is +i */
-      add_invite(chptr, target_p);
     }
+
+    /* Always add invite, since invitation bypasses ban */
+    add_invite(chptr, target_p);
   }
   else if (target_p->from != client_p)
     sendto_one(target_p, ":%s INVITE %s %s %lu",
Index: modules/m_whois.c
===================================================================
--- modules/m_whois.c	(.../1.0.0)	(revision 131)
+++ modules/m_whois.c	(.../1.0.1)	(revision 131)
@@ -388,7 +388,7 @@
       }
 
       /* Let oper snoops know that they're looking at a secret channel */
-      if (!PubChannel(chptr) && IsOperSnoop(source_p))
+      if (!PubChannel(chptr) && !IsMember(source_p, chptr) && IsOperSnoop(source_p))
       {
         tlen = ircsprintf(t, "*");
         t += tlen;
@@ -450,7 +450,7 @@
   }
 
   if (IsOper(source_p) && IsCaptured(target_p))
-    sendto_one(source_p, form_str(RPL_ISCAPTURED),
+    sendto_one(source_p, form_str(RPL_WHOISCAPTURED),
                me.name, source_p->name, target_p->name);
 
   if (ConfigFileEntry.use_whois_actually)
Index: modules/core/m_sjoin.c
===================================================================
--- modules/core/m_sjoin.c	(.../1.0.0)	(revision 131)
+++ modules/core/m_sjoin.c	(.../1.0.1)	(revision 131)
@@ -153,6 +153,9 @@
   {
     switch (*s)
     {
+      case 'C':
+        mode.mode |= MODE_ASCIIONLY;
+        break;
       case 'M':
         mode.mode |= MODE_REGMOD;
         break;
@@ -645,6 +648,7 @@
   { MODE_REGONLY,    'R' },
   { MODE_REGMOD,     'M' },
   { MODE_COLORLESS,  'c' },
+  { MODE_ASCIIONLY,  'C' },
   { MODE_OPERONLY,   'O' },
   { 0, '\0' }
 };
Index: modules/core/m_message.c
===================================================================
--- modules/core/m_message.c	(.../1.0.0)	(revision 131)
+++ modules/core/m_message.c	(.../1.0.1)	(revision 131)
@@ -59,6 +59,7 @@
 static struct Client* find_userhost (char *, char *, int *);
 
 static int has_ctrl_chars(char *msg);
+static int has_colors(char *msg);
 
 #define ENTITY_NONE    0
 #define ENTITY_CHANNEL 1
@@ -491,16 +492,24 @@
   execute_callback(channel_message, source_p, chptr, text);
 #endif
 
-  /* Test for control characters */
-  if ((chptr->mode.mode & MODE_COLORLESS) && has_ctrl_chars(text))
+  /* Test for control characters and colors */
+  if ((chptr->mode.mode & MODE_ASCIIONLY) && has_ctrl_chars(text))
   {
     if (p_or_n != NOTICE)
-      sendto_one(source_p, form_str(ERR_NOCOLORSONCHAN),
+      sendto_one(source_p, form_str(ERR_NOCONTROLSONCHAN),
                  ID_or_name(&me, client_p),
                  ID_or_name(source_p, client_p), chptr->chname, chptr->chname);
 
     return;
   }
+  else if ((chptr->mode.mode & MODE_COLORLESS) && has_colors(text))
+  {
+    if (p_or_n != NOTICE)
+      sendto_one(source_p, form_str(ERR_NOCOLORSONCHAN),
+                 ID_or_name(&me, client_p),
+                 ID_or_name(source_p, client_p), chptr->chname, chptr->chname);
+    return;
+  }
 
   /* chanops and voiced can flood their own channel with impunity */
   if ((result = can_send(chptr, source_p, NULL)))
@@ -1098,3 +1107,32 @@
   return 0;
 }
 
+/*
+ * has_colors
+ * inputs   - msg
+ * outputs  - returns 1 if message has colors, 0 otherwise
+ * side-effects - none
+ * 
+ * shamelessly stolen from bahamut 1.8.3
+*/
+static int
+has_colors(char *msg)
+{
+  char *c;
+  if (msg == NULL)
+    return 0;
+
+  c = msg;
+  while(*c)
+  {
+    if(*c == '\003' || *c == '\033')
+      break;
+    else
+      c++;
+  }
+
+  if(*c)
+    return 1;
+
+  return 0;
+}
Index: modules/core/m_join.c
===================================================================
--- modules/core/m_join.c	(.../1.0.0)	(revision 131)
+++ modules/core/m_join.c	(.../1.0.1)	(revision 131)
@@ -501,6 +501,7 @@
   { MODE_REGONLY,    'R' },
   { MODE_REGMOD,     'M' },
   { MODE_COLORLESS,  'c' },
+  { MODE_ASCIIONLY,  'C' },
   { MODE_OPERONLY,   'O' },
   { 0, '\0' }
 };
Index: modules/m_webirc.c
===================================================================
--- modules/m_webirc.c	(.../1.0.0)	(revision 131)
+++ modules/m_webirc.c	(.../1.0.1)	(revision 131)
@@ -42,6 +42,7 @@
 #include "packet.h"
 
 static void mr_webirc(struct Client *, struct Client *, int, char *[]);
+static struct ConfItem *find_webirc_conf(struct Client *);
 
 struct Message webirc_msgtab = {
   "WEBIRC", 0, 0, 5, 0, MFLG_SLOW, 0,
@@ -89,7 +90,7 @@
     return;
   }
 
-  if ((conf = find_exact_name_conf(WEBIRC_TYPE, NULL, NULL, source_p->host)) == NULL)
+  if ((conf = find_webirc_conf(source_p)) == NULL)
   {
     exit_client(source_p, &me, "No CGI:IRC access");
     ilog(L_NOTICE, "INVALID WEBIRC (no host) from %s for %s (%s)", source_p->host, hostname, address);
@@ -111,3 +112,17 @@
     ilog(L_NOTICE, "INVALID WEBIRC (bad password) from %s for %s (%s)", source_p->host, hostname, address);
   }
 }
+
+static struct ConfItem *
+find_webirc_conf(struct Client *source_p)
+{
+  struct ConfItem *conf;
+
+  if ((conf = find_exact_name_conf(WEBIRC_TYPE, NULL, NULL, source_p->host)) != NULL)
+    return conf;
+
+  if ((conf = find_exact_name_conf(WEBIRC_TYPE, NULL, NULL, source_p->sockhost)) != NULL)
+    return conf;
+
+  return NULL;
+}
Index: modules/m_topic.c
===================================================================
--- modules/m_topic.c	(.../1.0.0)	(revision 131)
+++ modules/m_topic.c	(.../1.0.1)	(revision 131)
@@ -165,7 +165,7 @@
     }
     else /* only asking for topic */
     {
-      if (!SecretChannel(chptr) || IsMember(source_p, chptr))
+      if (!SecretChannel(chptr) || IsMember(source_p, chptr) || (IsOper(source_p) && IsOperSnoop(source_p)))
       {
         if (chptr->topic == NULL)
           sendto_one(source_p, form_str(RPL_NOTOPIC),
