add client_can_send_controlcode_or_ctcp_to_channel() function in channel.c
and use that (2x ircd_relay.c, m_wallchops.c, m_wallvoices.c), instead of duplicating code 4 times
-also corrects that an error is returned in WALLVOICES and WALLCHOPS in case +c or +C blocks the message, which is also done for other modes there
-function loops over the text one time to check for control codes or CTCP chars, instead of twice as the old code did
+function uses a table to check for control codes, which is faster than what was used before
+corrects that an error is returned in WALLVOICES and WALLCHOPS in case +c or +C blocks the message, which is also done for other modes there
+corrects that CTCP ACTION is only allowed for PRIVMSG, and not for NOTICE WALLCHOPS and WALLVOICES
-diff -r 833a280b9406 include/channel.h
---- a/include/channel.h Sat Mar 20 15:42:02 2010 +0100
-+++ b/include/channel.h Sat Mar 20 17:08:49 2010 +0100
-@@ -398,6 +398,7 @@
+mode +c blocks bold (2), colour (3), reverse (22), ansi escape (27), italic (29) (mIRC 7 - ctrl+i), underline (31)
+
+diff -r 98874e322210 include/channel.h
+--- a/include/channel.h Sat Jul 20 11:59:11 2013 +0100
++++ b/include/channel.h Sat Jul 20 12:00:28 2013 +0100
+@@ -399,6 +399,7 @@
extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
extern int member_can_send_to_channel(struct Membership* member, int reveal);
extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr);
extern void remove_user_from_all_channels(struct Client* cptr);
-diff -r 833a280b9406 ircd/channel.c
---- a/ircd/channel.c Sat Mar 20 15:42:02 2010 +0100
-+++ b/ircd/channel.c Sat Mar 20 17:08:49 2010 +0100
-@@ -778,6 +778,48 @@
+diff -r 98874e322210 include/ircd_chattr.h
+--- a/include/ircd_chattr.h Sat Jul 20 11:59:11 2013 +0100
++++ b/include/ircd_chattr.h Sat Jul 20 12:00:28 2013 +0100
+@@ -59,6 +59,8 @@
+ #define NTL_KTIME 0x20000 /**< Valid character for a k:line time */
+ #define NTL_CHPFX 0x40000 /**< channel prefix char # & + */
+ #define NTL_IRCIP6 0x80000 /**< Numeric IPv6 character (hex or colon) */
++#define NTL_CTCP 0x100000 /**< CTCP char \\001 - snircd */
++#define NTL_CONTROL 0x200000 /**< control codes: bold 2, colour 3, reverse 22, ansi escape 27, italic 29 (mIRC 7), underline 31 - snircd */
+
+ /*
+ * Tables used for translation and classification macros
+@@ -104,6 +106,12 @@
+ #define IsUpper(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_UPPER)
+ /** Test whether a character is a control character. */
+ #define IsCntrl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CNTRL)
++/** Test whether a character is a CTCP character - snircd */
++#define IsCtcp(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CTCP)
++/** Test whether a character is a control character - snircd */
++#define IsControl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CONTROL)
++/** Test whether a character is a CTCP or control character - snircd */
++#define IsCtcpOrControl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & (NTL_CTCP|NTL_CONTROL))
+
+ /** Test whether a character is valid in a channel name. */
+ #define IsChannelChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCH)
+@@ -129,5 +137,4 @@
+ #define IsKTimeChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME)
+
+
+-
+ #endif /* INCLUDED_ircd_chattr_h */
+diff -r 98874e322210 ircd/channel.c
+--- a/ircd/channel.c Sat Jul 20 11:59:11 2013 +0100
++++ b/ircd/channel.c Sat Jul 20 12:00:28 2013 +0100
+@@ -778,6 +778,75 @@
return member_can_send_to_channel(member, reveal);
}
+int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action)
+{
+ int control = 0, ctcp = 0;
-+ const char *chr;
++ const unsigned char *chr;
++
++ assert(0 != cptr);
++ assert(0 != chptr);
+
+ /* dont check this for remote users or servers - fail safe */
-+ if (!MyUser(cptr) || IsServer(cptr))
++ if (!MyConnect(cptr) || IsServer(cptr))
+ return 1;
-+
++
+ /* mode +c set */
+ if (chptr->mode.mode & MODE_NOCOLOUR)
+ control = 1;
-+
-+ /* mode +C set - do allow CTCP ACTION though but only when action is 1 */
-+ if ((chptr->mode.mode & MODE_NOCTCP) && (!action || ircd_strncmp(text,"\001ACTION ",8)))
++
++ /* mode +C set */
++ if (chptr->mode.mode & MODE_NOCTCP) {
+ ctcp = 1;
-+
++
++ /* when action is 1, do allow CTCP ACTION though */
++ if (action && !ircd_strncmp(text,"\001ACTION ",8))
++ ctcp = 0;
++ }
++
+ /* nothing to check */
-+ if (!control && !ctcp)
++ if (!ctcp && !control)
+ return 1;
-+
-+ /* search for control codes and/or CTCP chars */
-+ for (chr=text;*chr;chr++) {
-+ if ((ctcp && *chr==1) || ((control) && (*chr==2 || *chr==3 || *chr==22 || *chr==27 || *chr==31)))
-+ return 0;
++
++ /* search for CTCP and control codes */
++ if (ctcp && control) {
++ for (chr = text; *chr; chr++) {
++ if (IsCtcpOrControl(*chr))
++ return 0;
++ }
++ }
++
++ /* search for CTCP */
++ else if (ctcp) {
++ for (chr = text; *chr; chr++) {
++ if (IsCtcp(*chr))
++ return 0;
++ }
++ }
++
++ /* search for control code */
++ else {
++ for (chr = text; *chr; chr++) {
++ if (IsControl(*chr))
++ return 0;
++ }
+ }
-+
++
++ /* nothing found */
+ return 1;
+}
+
/** Returns the name of a channel that prevents the user from changing nick.
* if a member and not (opped or voiced) and (banned or moderated), return
* the name of the first channel banned on.
-diff -r 833a280b9406 ircd/ircd_relay.c
---- a/ircd/ircd_relay.c Sat Mar 20 15:42:02 2010 +0100
-+++ b/ircd/ircd_relay.c Sat Mar 20 17:08:49 2010 +0100
+diff -r 98874e322210 ircd/ircd_relay.c
+--- a/ircd/ircd_relay.c Sat Jul 20 11:59:11 2013 +0100
++++ b/ircd/ircd_relay.c Sat Jul 20 12:00:28 2013 +0100
@@ -87,7 +87,6 @@
void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc)
{
-
- if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8))
- for (ch=text;*ch;)
-- if (*ch++==1) {
+- if (*ch++==1) {
- send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
- return;
- }
if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
check_target_limit(sptr, chptr, chptr->chname, 0))
-diff -r 833a280b9406 ircd/m_wallchops.c
---- a/ircd/m_wallchops.c Sat Mar 20 15:42:02 2010 +0100
-+++ b/ircd/m_wallchops.c Sat Mar 20 17:08:49 2010 +0100
+diff -r 98874e322210 ircd/m_wallchops.c
+--- a/ircd/m_wallchops.c Sat Jul 20 11:59:11 2013 +0100
++++ b/ircd/m_wallchops.c Sat Jul 20 12:00:28 2013 +0100
@@ -103,7 +103,6 @@
{
struct Channel *chptr;
if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
check_target_limit(sptr, chptr, chptr->chname, 0))
-diff -r 833a280b9406 ircd/m_wallvoices.c
---- a/ircd/m_wallvoices.c Sat Mar 20 15:42:02 2010 +0100
-+++ b/ircd/m_wallvoices.c Sat Mar 20 17:08:49 2010 +0100
+diff -r 98874e322210 ircd/m_wallvoices.c
+--- a/ircd/m_wallvoices.c Sat Jul 20 11:59:11 2013 +0100
++++ b/ircd/m_wallvoices.c Sat Jul 20 12:00:28 2013 +0100
@@ -102,7 +102,6 @@
{
struct Channel *chptr;
if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
check_target_limit(sptr, chptr, chptr->chname, 0))
+diff -r 98874e322210 ircd/table_gen.c
+--- a/ircd/table_gen.c Sat Jul 20 11:59:11 2013 +0100
++++ b/ircd/table_gen.c Sat Jul 20 12:00:28 2013 +0100
+@@ -87,6 +87,12 @@
+
+ markString(NTL_SPACE, "\011\012\013\014\015\040");
+
++ /* CTCP char - snircd */
++ markString(NTL_CTCP, "\001");
++
++ /* control codes bold, colour, reverse, ansi escape, italic, underline - snircd */
++ markString(NTL_CONTROL, "\002\003\026\033\035\037");
++
+ /* Make the derived sets,
+ * WARNING: The order of these calls is important, some depend on
+ * the results of the previous ones ! */