1 centralize mode checks for +c (no control codes) and +C (no CTCPs)
3 add client_can_send_controlcode_or_ctcp_to_channel() function in channel.c
4 and use that (2x ircd_relay.c, m_wallchops.c, m_wallvoices.c), instead of duplicating code 4 times
5 function uses a table to check for control codes, which is faster than what was used before
6 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
7 corrects that CTCP ACTION is only allowed for PRIVMSG, and not for NOTICE WALLCHOPS and WALLVOICES
9 mode +c blocks bold (2), colour (3), reverse (22), ansi escape (27), italic (29) (mIRC 7 - ctrl+i), underline (31)
11 diff -r 98874e322210 include/channel.h
12 --- a/include/channel.h Sat Jul 20 11:59:11 2013 +0100
13 +++ b/include/channel.h Sat Jul 20 12:00:28 2013 +0100
15 extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
16 extern int member_can_send_to_channel(struct Membership* member, int reveal);
17 extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
18 +extern int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action);
20 extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr);
21 extern void remove_user_from_all_channels(struct Client* cptr);
22 diff -r 98874e322210 include/ircd_chattr.h
23 --- a/include/ircd_chattr.h Sat Jul 20 11:59:11 2013 +0100
24 +++ b/include/ircd_chattr.h Sat Jul 20 12:00:28 2013 +0100
26 #define NTL_KTIME 0x20000 /**< Valid character for a k:line time */
27 #define NTL_CHPFX 0x40000 /**< channel prefix char # & + */
28 #define NTL_IRCIP6 0x80000 /**< Numeric IPv6 character (hex or colon) */
29 +#define NTL_CTCP 0x100000 /**< CTCP char \\001 - snircd */
30 +#define NTL_CONTROL 0x200000 /**< control codes: bold 2, colour 3, reverse 22, ansi escape 27, italic 29 (mIRC 7), underline 31 - snircd */
33 * Tables used for translation and classification macros
35 #define IsUpper(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_UPPER)
36 /** Test whether a character is a control character. */
37 #define IsCntrl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CNTRL)
38 +/** Test whether a character is a CTCP character - snircd */
39 +#define IsCtcp(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CTCP)
40 +/** Test whether a character is a control character - snircd */
41 +#define IsControl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CONTROL)
42 +/** Test whether a character is a CTCP or control character - snircd */
43 +#define IsCtcpOrControl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & (NTL_CTCP|NTL_CONTROL))
45 /** Test whether a character is valid in a channel name. */
46 #define IsChannelChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCH)
48 #define IsKTimeChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME)
52 #endif /* INCLUDED_ircd_chattr_h */
53 diff -r 98874e322210 ircd/channel.c
54 --- a/ircd/channel.c Sat Jul 20 11:59:11 2013 +0100
55 +++ b/ircd/channel.c Sat Jul 20 12:00:28 2013 +0100
57 return member_can_send_to_channel(member, reveal);
60 +/** Check if a client can send control codes or CTCP to a channel
62 + * @param cptr The client to check
63 + * @param chptr The channel to check
64 + * @param text The text to check for control codes and/or CTCP chars
65 + * @param action When 1 allow CTCP ACTION (for PRIVMSG),
66 + * else dont allow (for NOTICE, WALLCHOPS, and WALLVOICES)
68 + * @returns true if the client is allowed to speak on the channel, false
72 +int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action)
74 + int control = 0, ctcp = 0;
75 + const unsigned char *chr;
80 + /* dont check this for remote users or servers - fail safe */
81 + if (!MyConnect(cptr) || IsServer(cptr))
85 + if (chptr->mode.mode & MODE_NOCOLOUR)
89 + if (chptr->mode.mode & MODE_NOCTCP) {
92 + /* when action is 1, do allow CTCP ACTION though */
93 + if (action && !ircd_strncmp(text,"\001ACTION ",8))
97 + /* nothing to check */
98 + if (!ctcp && !control)
101 + /* search for CTCP and control codes */
102 + if (ctcp && control) {
103 + for (chr = text; *chr; chr++) {
104 + if (IsCtcpOrControl(*chr))
109 + /* search for CTCP */
111 + for (chr = text; *chr; chr++) {
117 + /* search for control code */
119 + for (chr = text; *chr; chr++) {
120 + if (IsControl(*chr))
125 + /* nothing found */
129 /** Returns the name of a channel that prevents the user from changing nick.
130 * if a member and not (opped or voiced) and (banned or moderated), return
131 * the name of the first channel banned on.
132 diff -r 98874e322210 ircd/ircd_relay.c
133 --- a/ircd/ircd_relay.c Sat Jul 20 11:59:11 2013 +0100
134 +++ b/ircd/ircd_relay.c Sat Jul 20 12:00:28 2013 +0100
136 void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc)
138 struct Channel* chptr;
143 @@ -111,19 +110,10 @@
147 - if (chptr->mode.mode & MODE_NOCOLOUR)
148 - for (ch=text;*ch;ch++)
149 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
150 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
154 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8))
157 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
160 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) {
161 + send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
165 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
166 check_target_limit(sptr, chptr, chptr->chname, 0))
168 void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc)
170 struct Channel* chptr;
179 - if (chptr->mode.mode & MODE_NOCOLOUR)
180 - for (ch=text;*ch;ch++)
181 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31)
184 - if (chptr->mode.mode & MODE_NOCTCP)
188 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0))
191 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
192 check_target_limit(sptr, chptr, chptr->chname, 0))
193 diff -r 98874e322210 ircd/m_wallchops.c
194 --- a/ircd/m_wallchops.c Sat Jul 20 11:59:11 2013 +0100
195 +++ b/ircd/m_wallchops.c Sat Jul 20 12:00:28 2013 +0100
198 struct Channel *chptr;
199 struct Membership* member;
203 assert(cptr == sptr);
205 return send_reply(sptr, ERR_NOTEXTTOSEND);
207 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
208 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
211 - if (chptr->mode.mode & MODE_NOCOLOUR)
212 - for (ch=parv[parc - 1];*ch;ch++)
213 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
217 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
218 - for (ch=parv[parc - 1];*ch;)
222 + if (client_can_send_to_channel(sptr, chptr, 0) &&
223 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
224 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
226 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
227 check_target_limit(sptr, chptr, chptr->chname, 0))
228 diff -r 98874e322210 ircd/m_wallvoices.c
229 --- a/ircd/m_wallvoices.c Sat Jul 20 11:59:11 2013 +0100
230 +++ b/ircd/m_wallvoices.c Sat Jul 20 12:00:28 2013 +0100
233 struct Channel *chptr;
234 struct Membership* member;
238 assert(cptr == sptr);
240 return send_reply(sptr, ERR_NOTEXTTOSEND);
242 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
243 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
246 - if (chptr->mode.mode & MODE_NOCOLOUR)
247 - for (ch=parv[parc - 1];*ch;ch++)
248 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
252 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
253 - for (ch=parv[parc - 1];*ch;)
257 + if (client_can_send_to_channel(sptr, chptr, 0) &&
258 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
259 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
261 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
262 check_target_limit(sptr, chptr, chptr->chname, 0))
263 diff -r 98874e322210 ircd/table_gen.c
264 --- a/ircd/table_gen.c Sat Jul 20 11:59:11 2013 +0100
265 +++ b/ircd/table_gen.c Sat Jul 20 12:00:28 2013 +0100
268 markString(NTL_SPACE, "\011\012\013\014\015\040");
270 + /* CTCP char - snircd */
271 + markString(NTL_CTCP, "\001");
273 + /* control codes bold, colour, reverse, ansi escape, italic, underline - snircd */
274 + markString(NTL_CONTROL, "\002\003\026\033\035\037");
276 /* Make the derived sets,
277 * WARNING: The order of these calls is important, some depend on
278 * the results of the previous ones ! */