]>
Commit | Line | Data |
---|---|---|
97b63806 | 1 | centralize mode checks for +c (no control codes) and +C (no CTCPs) |
2 | ||
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 | |
a42ed697 | 5 | function uses a table to check for control codes, which is faster than what was used before |
8928264e | 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 | |
97b63806 | 8 | |
8928264e | 9 | mode +c blocks bold (2), colour (3), reverse (22), ansi escape (27), italic (29) (mIRC 7 - ctrl+i), underline (31) |
10 | ||
3975cc60 P |
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 | |
14 | @@ -399,6 +399,7 @@ | |
97b63806 | 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); | |
19 | ||
20 | extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr); | |
21 | extern void remove_user_from_all_channels(struct Client* cptr); | |
3975cc60 P |
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 | |
e556ab7d | 25 | @@ -59,6 +59,8 @@ |
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 */ | |
8928264e | 30 | +#define NTL_CONTROL 0x200000 /**< control codes: bold 2, colour 3, reverse 22, ansi escape 27, italic 29 (mIRC 7), underline 31 - snircd */ |
e556ab7d | 31 | |
32 | /* | |
33 | * Tables used for translation and classification macros | |
34 | @@ -104,6 +106,12 @@ | |
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)) | |
44 | ||
45 | /** Test whether a character is valid in a channel name. */ | |
46 | #define IsChannelChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCH) | |
47 | @@ -129,5 +137,4 @@ | |
48 | #define IsKTimeChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME) | |
49 | ||
50 | ||
51 | - | |
52 | #endif /* INCLUDED_ircd_chattr_h */ | |
3975cc60 P |
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 | |
e556ab7d | 56 | @@ -778,6 +778,75 @@ |
97b63806 | 57 | return member_can_send_to_channel(member, reveal); |
58 | } | |
59 | ||
60 | +/** Check if a client can send control codes or CTCP to a channel | |
61 | + * | |
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) | |
67 | + * | |
68 | + * @returns true if the client is allowed to speak on the channel, false | |
69 | + * otherwise | |
70 | + * | |
71 | + */ | |
72 | +int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action) | |
73 | +{ | |
74 | + int control = 0, ctcp = 0; | |
a42ed697 | 75 | + const unsigned char *chr; |
76 | + | |
77 | + assert(0 != cptr); | |
78 | + assert(0 != chptr); | |
97b63806 | 79 | + |
80 | + /* dont check this for remote users or servers - fail safe */ | |
6068a4e5 | 81 | + if (!MyConnect(cptr) || IsServer(cptr)) |
97b63806 | 82 | + return 1; |
e556ab7d | 83 | + |
97b63806 | 84 | + /* mode +c set */ |
85 | + if (chptr->mode.mode & MODE_NOCOLOUR) | |
86 | + control = 1; | |
e556ab7d | 87 | + |
37353147 | 88 | + /* mode +C set */ |
89 | + if (chptr->mode.mode & MODE_NOCTCP) { | |
97b63806 | 90 | + ctcp = 1; |
e556ab7d | 91 | + |
37353147 | 92 | + /* when action is 1, do allow CTCP ACTION though */ |
93 | + if (action && !ircd_strncmp(text,"\001ACTION ",8)) | |
94 | + ctcp = 0; | |
95 | + } | |
e556ab7d | 96 | + |
97b63806 | 97 | + /* nothing to check */ |
e556ab7d | 98 | + if (!ctcp && !control) |
97b63806 | 99 | + return 1; |
e556ab7d | 100 | + |
101 | + /* search for CTCP and control codes */ | |
102 | + if (ctcp && control) { | |
103 | + for (chr = text; *chr; chr++) { | |
104 | + if (IsCtcpOrControl(*chr)) | |
105 | + return 0; | |
106 | + } | |
107 | + } | |
108 | + | |
109 | + /* search for CTCP */ | |
110 | + else if (ctcp) { | |
111 | + for (chr = text; *chr; chr++) { | |
112 | + if (IsCtcp(*chr)) | |
113 | + return 0; | |
114 | + } | |
115 | + } | |
116 | + | |
117 | + /* search for control code */ | |
118 | + else { | |
119 | + for (chr = text; *chr; chr++) { | |
120 | + if (IsControl(*chr)) | |
121 | + return 0; | |
122 | + } | |
97b63806 | 123 | + } |
e556ab7d | 124 | + |
125 | + /* nothing found */ | |
97b63806 | 126 | + return 1; |
127 | +} | |
128 | + | |
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. | |
3975cc60 P |
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 | |
97b63806 | 135 | @@ -87,7 +87,6 @@ |
136 | void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc) | |
137 | { | |
138 | struct Channel* chptr; | |
139 | - const char *ch; | |
140 | assert(0 != sptr); | |
141 | assert(0 != name); | |
142 | assert(0 != text); | |
143 | @@ -111,19 +110,10 @@ | |
144 | } | |
145 | ||
146 | /* +cC checks */ | |
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); | |
151 | - return; | |
152 | - } | |
153 | - | |
154 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8)) | |
155 | - for (ch=text;*ch;) | |
3975cc60 | 156 | - if (*ch++==1) { |
97b63806 | 157 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); |
158 | - return; | |
159 | - } | |
160 | + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) { | |
161 | + send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
162 | + return; | |
163 | + } | |
164 | ||
165 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
166 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
167 | @@ -144,7 +134,6 @@ | |
168 | void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc) | |
169 | { | |
170 | struct Channel* chptr; | |
171 | - const char *ch; | |
172 | assert(0 != sptr); | |
173 | assert(0 != name); | |
174 | assert(0 != text); | |
175 | @@ -165,15 +154,8 @@ | |
176 | return; | |
177 | ||
178 | /* +cC checks */ | |
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) | |
182 | - return; | |
183 | - | |
184 | - if (chptr->mode.mode & MODE_NOCTCP) | |
185 | - for (ch=text;*ch;) | |
186 | - if (*ch++==1) | |
187 | - return; | |
188 | + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0)) | |
189 | + return; | |
190 | ||
191 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
192 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
3975cc60 P |
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 | |
97b63806 | 196 | @@ -103,7 +103,6 @@ |
197 | { | |
198 | struct Channel *chptr; | |
199 | struct Membership* member; | |
200 | - const char *ch; | |
201 | ||
202 | assert(0 != cptr); | |
203 | assert(cptr == sptr); | |
204 | @@ -117,20 +116,9 @@ | |
205 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
206 | ||
207 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
208 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
209 | - | |
210 | - /* +cC checks */ | |
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) { | |
214 | - return 0; | |
215 | - } | |
216 | - | |
217 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
218 | - for (ch=parv[parc - 1];*ch;) | |
219 | - if (*ch++==1) { | |
220 | - return 0; | |
221 | - } | |
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 */ | |
225 | ||
226 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
227 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
3975cc60 P |
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 | |
97b63806 | 231 | @@ -102,7 +102,6 @@ |
232 | { | |
233 | struct Channel *chptr; | |
234 | struct Membership* member; | |
235 | - const char *ch; | |
236 | ||
237 | assert(0 != cptr); | |
238 | assert(cptr == sptr); | |
239 | @@ -116,20 +115,9 @@ | |
240 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
241 | ||
242 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
243 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
244 | - | |
245 | - /* +cC checks */ | |
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) { | |
249 | - return 0; | |
250 | - } | |
251 | - | |
252 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
253 | - for (ch=parv[parc - 1];*ch;) | |
254 | - if (*ch++==1) { | |
255 | - return 0; | |
256 | - } | |
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 */ | |
260 | ||
261 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
262 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
3975cc60 P |
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 | |
e556ab7d | 266 | @@ -87,6 +87,12 @@ |
267 | ||
268 | markString(NTL_SPACE, "\011\012\013\014\015\040"); | |
269 | ||
270 | + /* CTCP char - snircd */ | |
271 | + markString(NTL_CTCP, "\001"); | |
272 | + | |
8928264e | 273 | + /* control codes bold, colour, reverse, ansi escape, italic, underline - snircd */ |
274 | + markString(NTL_CONTROL, "\002\003\026\033\035\037"); | |
e556ab7d | 275 | + |
276 | /* Make the derived sets, | |
277 | * WARNING: The order of these calls is important, some depend on | |
278 | * the results of the previous ones ! */ |