]>
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 | 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 | |
8 | ||
9 | diff -r e80591f05c47 include/channel.h | |
10 | --- a/include/channel.h Sat Mar 20 17:57:13 2010 +0100 | |
11 | +++ b/include/channel.h Sun Mar 21 15:49:28 2010 +0100 | |
12 | @@ -398,6 +398,7 @@ | |
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); | |
17 | ||
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 e80591f05c47 ircd/channel.c | |
21 | --- a/ircd/channel.c Sat Mar 20 17:57:13 2010 +0100 | |
22 | +++ b/ircd/channel.c Sun Mar 21 15:49:28 2010 +0100 | |
23 | @@ -778,6 +778,63 @@ | |
24 | return member_can_send_to_channel(member, reveal); | |
25 | } | |
26 | ||
27 | +/** Table with control chars that should be blocked by chanmode +c | |
28 | + * | |
29 | + * codes: bold 2, colour 3, reverse 22, ansi escape 27, underline 31 | |
30 | + * | |
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, | |
37 | +}; | |
38 | + | |
39 | +/** Check if a client can send control codes or CTCP to a channel | |
40 | + * | |
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) | |
46 | + * | |
47 | + * @returns true if the client is allowed to speak on the channel, false | |
48 | + * otherwise | |
49 | + * | |
50 | + */ | |
51 | +int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action) | |
52 | +{ | |
53 | + int control = 0, ctcp = 0; | |
54 | + const unsigned char *chr; | |
55 | + | |
56 | + assert(0 != cptr); | |
57 | + assert(0 != chptr); | |
58 | + | |
59 | + /* dont check this for remote users or servers - fail safe */ | |
60 | + if (!MyUser(cptr) || IsServer(cptr)) | |
61 | + return 1; | |
62 | + | |
63 | + /* mode +c set */ | |
64 | + if (chptr->mode.mode & MODE_NOCOLOUR) | |
65 | + control = 1; | |
66 | + | |
67 | + /* mode +C set - do allow CTCP ACTION though but only when action is 1 */ | |
68 | + if ((chptr->mode.mode & MODE_NOCTCP) && (!action || ircd_strncmp(text,"\001ACTION ",8))) | |
69 | + ctcp = 1; | |
70 | + | |
71 | + /* nothing to check */ | |
72 | + if (!control && !ctcp) | |
73 | + return 1; | |
74 | + | |
75 | + /* search for control codes and/or CTCP chars */ | |
76 | + for (chr=text;*chr;chr++) { | |
77 | + if ((ctcp && *chr==1) || (control && control_codes[*chr])) | |
78 | + return 0; | |
79 | + } | |
80 | + | |
81 | + return 1; | |
82 | +} | |
83 | + | |
84 | /** Returns the name of a channel that prevents the user from changing nick. | |
85 | * if a member and not (opped or voiced) and (banned or moderated), return | |
86 | * the name of the first channel banned on. | |
87 | diff -r e80591f05c47 ircd/ircd_relay.c | |
88 | --- a/ircd/ircd_relay.c Sat Mar 20 17:57:13 2010 +0100 | |
89 | +++ b/ircd/ircd_relay.c Sun Mar 21 15:49:28 2010 +0100 | |
90 | @@ -87,7 +87,6 @@ | |
91 | void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc) | |
92 | { | |
93 | struct Channel* chptr; | |
94 | - const char *ch; | |
95 | assert(0 != sptr); | |
96 | assert(0 != name); | |
97 | assert(0 != text); | |
98 | @@ -111,19 +110,10 @@ | |
99 | } | |
100 | ||
101 | /* +cC checks */ | |
102 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
103 | - for (ch=text;*ch;ch++) | |
104 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
105 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
106 | - return; | |
107 | - } | |
108 | - | |
109 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8)) | |
110 | - for (ch=text;*ch;) | |
111 | - if (*ch++==1) { | |
112 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
113 | - return; | |
114 | - } | |
115 | + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) { | |
116 | + send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
117 | + return; | |
118 | + } | |
119 | ||
120 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
121 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
122 | @@ -144,7 +134,6 @@ | |
123 | void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc) | |
124 | { | |
125 | struct Channel* chptr; | |
126 | - const char *ch; | |
127 | assert(0 != sptr); | |
128 | assert(0 != name); | |
129 | assert(0 != text); | |
130 | @@ -165,15 +154,8 @@ | |
131 | return; | |
132 | ||
133 | /* +cC checks */ | |
134 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
135 | - for (ch=text;*ch;ch++) | |
136 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) | |
137 | - return; | |
138 | - | |
139 | - if (chptr->mode.mode & MODE_NOCTCP) | |
140 | - for (ch=text;*ch;) | |
141 | - if (*ch++==1) | |
142 | - return; | |
143 | + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0)) | |
144 | + return; | |
145 | ||
146 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
147 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
148 | diff -r e80591f05c47 ircd/m_wallchops.c | |
149 | --- a/ircd/m_wallchops.c Sat Mar 20 17:57:13 2010 +0100 | |
150 | +++ b/ircd/m_wallchops.c Sun Mar 21 15:49:28 2010 +0100 | |
151 | @@ -103,7 +103,6 @@ | |
152 | { | |
153 | struct Channel *chptr; | |
154 | struct Membership* member; | |
155 | - const char *ch; | |
156 | ||
157 | assert(0 != cptr); | |
158 | assert(cptr == sptr); | |
159 | @@ -117,20 +116,9 @@ | |
160 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
161 | ||
162 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
163 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
164 | - | |
165 | - /* +cC checks */ | |
166 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
167 | - for (ch=parv[parc - 1];*ch;ch++) | |
168 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
169 | - return 0; | |
170 | - } | |
171 | - | |
172 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
173 | - for (ch=parv[parc - 1];*ch;) | |
174 | - if (*ch++==1) { | |
175 | - return 0; | |
176 | - } | |
177 | + if (client_can_send_to_channel(sptr, chptr, 0) && | |
178 | + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */ | |
179 | + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */ | |
180 | ||
181 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
182 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
183 | diff -r e80591f05c47 ircd/m_wallvoices.c | |
184 | --- a/ircd/m_wallvoices.c Sat Mar 20 17:57:13 2010 +0100 | |
185 | +++ b/ircd/m_wallvoices.c Sun Mar 21 15:49:28 2010 +0100 | |
186 | @@ -102,7 +102,6 @@ | |
187 | { | |
188 | struct Channel *chptr; | |
189 | struct Membership* member; | |
190 | - const char *ch; | |
191 | ||
192 | assert(0 != cptr); | |
193 | assert(cptr == sptr); | |
194 | @@ -116,20 +115,9 @@ | |
195 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
196 | ||
197 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
198 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
199 | - | |
200 | - /* +cC checks */ | |
201 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
202 | - for (ch=parv[parc - 1];*ch;ch++) | |
203 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
204 | - return 0; | |
205 | - } | |
206 | - | |
207 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
208 | - for (ch=parv[parc - 1];*ch;) | |
209 | - if (*ch++==1) { | |
210 | - return 0; | |
211 | - } | |
212 | + if (client_can_send_to_channel(sptr, chptr, 0) && | |
213 | + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */ | |
214 | + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */ | |
215 | ||
216 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
217 | check_target_limit(sptr, chptr, chptr->chname, 0)) |