]> jfr.im git - irc/quakenet/snircd-patchqueue.git/blob - centralizemodecccheck.patch
centralizemodecccheck: centralize mode checks for +c (no control codes) and +C (no...
[irc/quakenet/snircd-patchqueue.git] / centralizemodecccheck.patch
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 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
6 function loops over the text one time to check for control codes or CTCP chars, instead of twice as the old code did
7
8 diff -r 833a280b9406 include/channel.h
9 --- a/include/channel.h Sat Mar 20 15:42:02 2010 +0100
10 +++ b/include/channel.h Sat Mar 20 17:08:49 2010 +0100
11 @@ -398,6 +398,7 @@
12 extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
13 extern int member_can_send_to_channel(struct Membership* member, int reveal);
14 extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
15 +extern int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action);
16
17 extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr);
18 extern void remove_user_from_all_channels(struct Client* cptr);
19 diff -r 833a280b9406 ircd/channel.c
20 --- a/ircd/channel.c Sat Mar 20 15:42:02 2010 +0100
21 +++ b/ircd/channel.c Sat Mar 20 17:08:49 2010 +0100
22 @@ -778,6 +778,48 @@
23 return member_can_send_to_channel(member, reveal);
24 }
25
26 +/** Check if a client can send control codes or CTCP to a channel
27 + *
28 + * @param cptr The client to check
29 + * @param chptr The channel to check
30 + * @param text The text to check for control codes and/or CTCP chars
31 + * @param action When 1 allow CTCP ACTION (for PRIVMSG),
32 + * else dont allow (for NOTICE, WALLCHOPS, and WALLVOICES)
33 + *
34 + * @returns true if the client is allowed to speak on the channel, false
35 + * otherwise
36 + *
37 + */
38 +int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action)
39 +{
40 + int control = 0, ctcp = 0;
41 + const char *chr;
42 +
43 + /* dont check this for remote users or servers - fail safe */
44 + if (!MyUser(cptr) || IsServer(cptr))
45 + return 1;
46 +
47 + /* mode +c set */
48 + if (chptr->mode.mode & MODE_NOCOLOUR)
49 + control = 1;
50 +
51 + /* mode +C set - do allow CTCP ACTION though but only when action is 1 */
52 + if ((chptr->mode.mode & MODE_NOCTCP) && (!action || ircd_strncmp(text,"\001ACTION ",8)))
53 + ctcp = 1;
54 +
55 + /* nothing to check */
56 + if (!control && !ctcp)
57 + return 1;
58 +
59 + /* search for control codes and/or CTCP chars */
60 + for (chr=text;*chr;chr++) {
61 + if ((ctcp && *chr==1) || ((control) && (*chr==2 || *chr==3 || *chr==22 || *chr==27 || *chr==31)))
62 + return 0;
63 + }
64 +
65 + return 1;
66 +}
67 +
68 /** Returns the name of a channel that prevents the user from changing nick.
69 * if a member and not (opped or voiced) and (banned or moderated), return
70 * the name of the first channel banned on.
71 diff -r 833a280b9406 ircd/ircd_relay.c
72 --- a/ircd/ircd_relay.c Sat Mar 20 15:42:02 2010 +0100
73 +++ b/ircd/ircd_relay.c Sat Mar 20 17:08:49 2010 +0100
74 @@ -87,7 +87,6 @@
75 void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc)
76 {
77 struct Channel* chptr;
78 - const char *ch;
79 assert(0 != sptr);
80 assert(0 != name);
81 assert(0 != text);
82 @@ -111,19 +110,10 @@
83 }
84
85 /* +cC checks */
86 - if (chptr->mode.mode & MODE_NOCOLOUR)
87 - for (ch=text;*ch;ch++)
88 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
89 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
90 - return;
91 - }
92 -
93 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8))
94 - for (ch=text;*ch;)
95 - if (*ch++==1) {
96 - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
97 - return;
98 - }
99 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) {
100 + send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
101 + return;
102 + }
103
104 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
105 check_target_limit(sptr, chptr, chptr->chname, 0))
106 @@ -144,7 +134,6 @@
107 void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc)
108 {
109 struct Channel* chptr;
110 - const char *ch;
111 assert(0 != sptr);
112 assert(0 != name);
113 assert(0 != text);
114 @@ -165,15 +154,8 @@
115 return;
116
117 /* +cC checks */
118 - if (chptr->mode.mode & MODE_NOCOLOUR)
119 - for (ch=text;*ch;ch++)
120 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31)
121 - return;
122 -
123 - if (chptr->mode.mode & MODE_NOCTCP)
124 - for (ch=text;*ch;)
125 - if (*ch++==1)
126 - return;
127 + if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0))
128 + return;
129
130 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
131 check_target_limit(sptr, chptr, chptr->chname, 0))
132 diff -r 833a280b9406 ircd/m_wallchops.c
133 --- a/ircd/m_wallchops.c Sat Mar 20 15:42:02 2010 +0100
134 +++ b/ircd/m_wallchops.c Sat Mar 20 17:08:49 2010 +0100
135 @@ -103,7 +103,6 @@
136 {
137 struct Channel *chptr;
138 struct Membership* member;
139 - const char *ch;
140
141 assert(0 != cptr);
142 assert(cptr == sptr);
143 @@ -117,20 +116,9 @@
144 return send_reply(sptr, ERR_NOTEXTTOSEND);
145
146 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
147 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
148 -
149 - /* +cC checks */
150 - if (chptr->mode.mode & MODE_NOCOLOUR)
151 - for (ch=parv[parc - 1];*ch;ch++)
152 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
153 - return 0;
154 - }
155 -
156 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
157 - for (ch=parv[parc - 1];*ch;)
158 - if (*ch++==1) {
159 - return 0;
160 - }
161 + if (client_can_send_to_channel(sptr, chptr, 0) &&
162 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
163 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
164
165 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
166 check_target_limit(sptr, chptr, chptr->chname, 0))
167 diff -r 833a280b9406 ircd/m_wallvoices.c
168 --- a/ircd/m_wallvoices.c Sat Mar 20 15:42:02 2010 +0100
169 +++ b/ircd/m_wallvoices.c Sat Mar 20 17:08:49 2010 +0100
170 @@ -102,7 +102,6 @@
171 {
172 struct Channel *chptr;
173 struct Membership* member;
174 - const char *ch;
175
176 assert(0 != cptr);
177 assert(cptr == sptr);
178 @@ -116,20 +115,9 @@
179 return send_reply(sptr, ERR_NOTEXTTOSEND);
180
181 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
182 - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
183 -
184 - /* +cC checks */
185 - if (chptr->mode.mode & MODE_NOCOLOUR)
186 - for (ch=parv[parc - 1];*ch;ch++)
187 - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
188 - return 0;
189 - }
190 -
191 - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
192 - for (ch=parv[parc - 1];*ch;)
193 - if (*ch++==1) {
194 - return 0;
195 - }
196 + if (client_can_send_to_channel(sptr, chptr, 0) &&
197 + !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
198 + (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
199
200 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
201 check_target_limit(sptr, chptr, chptr->chname, 0))