]>
Commit | Line | Data |
---|---|---|
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 | |
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 | |
8 | ||
9 | mode +c blocks bold (2), colour (3), reverse (22), ansi escape (27), italic (29) (mIRC 7 - ctrl+i), underline (31) | |
10 | ||
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 @@ | |
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); | |
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 | |
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 */ | |
30 | +#define NTL_CONTROL 0x200000 /**< control codes: bold 2, colour 3, reverse 22, ansi escape 27, italic 29 (mIRC 7), underline 31 - snircd */ | |
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 */ | |
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 | |
56 | @@ -778,6 +778,75 @@ | |
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; | |
75 | + const unsigned char *chr; | |
76 | + | |
77 | + assert(0 != cptr); | |
78 | + assert(0 != chptr); | |
79 | + | |
80 | + /* dont check this for remote users or servers - fail safe */ | |
81 | + if (!MyConnect(cptr) || IsServer(cptr)) | |
82 | + return 1; | |
83 | + | |
84 | + /* mode +c set */ | |
85 | + if (chptr->mode.mode & MODE_NOCOLOUR) | |
86 | + control = 1; | |
87 | + | |
88 | + /* mode +C set */ | |
89 | + if (chptr->mode.mode & MODE_NOCTCP) { | |
90 | + ctcp = 1; | |
91 | + | |
92 | + /* when action is 1, do allow CTCP ACTION though */ | |
93 | + if (action && !ircd_strncmp(text,"\001ACTION ",8)) | |
94 | + ctcp = 0; | |
95 | + } | |
96 | + | |
97 | + /* nothing to check */ | |
98 | + if (!ctcp && !control) | |
99 | + return 1; | |
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 | + } | |
123 | + } | |
124 | + | |
125 | + /* nothing found */ | |
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. | |
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 | |
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;) | |
156 | - if (*ch++==1) { | |
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)) | |
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 | |
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)) | |
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 | |
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)) | |
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 | |
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 | + | |
273 | + /* control codes bold, colour, reverse, ansi escape, italic, underline - snircd */ | |
274 | + markString(NTL_CONTROL, "\002\003\026\033\035\037"); | |
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 ! */ |