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 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
7 also corrects that CTCP ACTION is only allowed for PRIVMSG, and not for NOTICE WALLCHOPS and WALLVOICES
9 diff -r 8567e020893c include/channel.h
10 --- a/include/channel.h Thu Mar 25 13:10:37 2010 +0100
11 +++ b/include/channel.h Thu Mar 25 13:25:55 2010 +0100
13 extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
14 extern int member_can_send_to_channel(struct Membership* member, int reveal);
15 extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
16 +extern int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action);
18 extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr);
19 extern void remove_user_from_all_channels(struct Client* cptr);
20 diff -r 8567e020893c ircd/channel.c
21 --- a/ircd/channel.c Thu Mar 25 13:10:37 2010 +0100
22 +++ b/ircd/channel.c Thu Mar 25 13:25:55 2010 +0100
24 return member_can_send_to_channel(member, reveal);
27 +/** Table with control chars that should be blocked by chanmode +c
29 + * codes: bold 2, colour 3, reverse 22, ansi escape 27, underline 31
32 +static int control_codes[256] = {
33 + 0, 0, 1, 1, 0, 0, 0, 0,
34 + 0, 0, 0, 0, 0, 0, 0, 0,
35 + 0, 0, 0, 0, 0, 0, 1, 0,
36 + 0, 0, 0, 1, 0, 0, 0, 1,
39 +/** Check if a client can send control codes or CTCP to a channel
41 + * @param cptr The client to check
42 + * @param chptr The channel to check
43 + * @param text The text to check for control codes and/or CTCP chars
44 + * @param action When 1 allow CTCP ACTION (for PRIVMSG),
45 + * else dont allow (for NOTICE, WALLCHOPS, and WALLVOICES)
47 + * @returns true if the client is allowed to speak on the channel, false
51 +int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action)
53 + int control = 0, ctcp = 0;
54 + const unsigned char *chr;
59 + /* dont check this for remote users or servers - fail safe */
60 + if (!MyUser(cptr) || IsServer(cptr))
64 + if (chptr->mode.mode & MODE_NOCOLOUR)
68 + if (chptr->mode.mode & MODE_NOCTCP) {
71 + /* when action is 1, do allow CTCP ACTION though */
72 + if (action && !ircd_strncmp(text,"\001ACTION ",8))
76 + /* nothing to check */
77 + if (!control && !ctcp)
80 + /* search for control codes and/or CTCP chars */
81 + for (chr=text;*chr;chr++) {
82 + if ((ctcp && *chr==1) || (control && control_codes[*chr]))
89 /** Returns the name of a channel that prevents the user from changing nick.
90 * if a member and not (opped or voiced) and (banned or moderated), return
91 * the name of the first channel banned on.
92 diff -r 8567e020893c ircd/ircd_relay.c
93 --- a/ircd/ircd_relay.c Thu Mar 25 13:10:37 2010 +0100
94 +++ b/ircd/ircd_relay.c Thu Mar 25 13:25:55 2010 +0100
96 void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc)
98 struct Channel* chptr;
103 @@ -111,19 +110,10 @@
107 - if (chptr->mode.mode & MODE_NOCOLOUR)
108 - for (ch=text;*ch;ch++)
109 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
110 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
114 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8))
117 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
120 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) {
121 + send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
125 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
126 check_target_limit(sptr, chptr, chptr->chname, 0))
128 void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc)
130 struct Channel* chptr;
139 - if (chptr->mode.mode & MODE_NOCOLOUR)
140 - for (ch=text;*ch;ch++)
141 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31)
144 - if (chptr->mode.mode & MODE_NOCTCP)
148 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0))
151 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
152 check_target_limit(sptr, chptr, chptr->chname, 0))
153 diff -r 8567e020893c ircd/m_wallchops.c
154 --- a/ircd/m_wallchops.c Thu Mar 25 13:10:37 2010 +0100
155 +++ b/ircd/m_wallchops.c Thu Mar 25 13:25:55 2010 +0100
158 struct Channel *chptr;
159 struct Membership* member;
163 assert(cptr == sptr);
165 return send_reply(sptr, ERR_NOTEXTTOSEND);
167 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
168 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
171 - if (chptr->mode.mode & MODE_NOCOLOUR)
172 - for (ch=parv[parc - 1];*ch;ch++)
173 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
177 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
178 - for (ch=parv[parc - 1];*ch;)
182 + if (client_can_send_to_channel(sptr, chptr, 0) &&
183 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
184 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
186 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
187 check_target_limit(sptr, chptr, chptr->chname, 0))
188 diff -r 8567e020893c ircd/m_wallvoices.c
189 --- a/ircd/m_wallvoices.c Thu Mar 25 13:10:37 2010 +0100
190 +++ b/ircd/m_wallvoices.c Thu Mar 25 13:25:55 2010 +0100
193 struct Channel *chptr;
194 struct Membership* member;
198 assert(cptr == sptr);
200 return send_reply(sptr, ERR_NOTEXTTOSEND);
202 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
203 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
206 - if (chptr->mode.mode & MODE_NOCOLOUR)
207 - for (ch=parv[parc - 1];*ch;ch++)
208 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
212 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
213 - for (ch=parv[parc - 1];*ch;)
217 + if (client_can_send_to_channel(sptr, chptr, 0) &&
218 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
219 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
221 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
222 check_target_limit(sptr, chptr, chptr->chname, 0))