]> jfr.im git - irc/quakenet/snircd-patchqueue.git/blame - commonchansumode.patch
Add my common channel umode patch.
[irc/quakenet/snircd-patchqueue.git] / commonchansumode.patch
CommitLineData
4f141ee4
CP
1Add usermode +q which requires users /msg'ing or /notice'ing you to be in at least one common channel.
2This is designed to stop the spam bots which sit outside a channel, while a spy sits inside, preventing channel operators dealing with the problem.
3We currently also block invites, this might not be such a good idea, but these days everyone can get Q.
4
5diff -r f2182ca2442a include/channel.h
6--- a/include/channel.h Sun Jan 11 22:53:16 2009 +0000
7+++ b/include/channel.h Sun Jan 11 22:54:00 2009 +0000
8@@ -462,5 +462,6 @@
9 extern void free_ban(struct Ban *ban);
10
11 extern unsigned int get_channel_marker(void);
12+extern int common_chan_count(struct Client *a, struct Client *b, int max);
13
14 #endif /* INCLUDED_channel_h */
15diff -r f2182ca2442a include/client.h
16--- a/include/client.h Sun Jan 11 22:53:16 2009 +0000
17+++ b/include/client.h Sun Jan 11 22:54:00 2009 +0000
18@@ -90,7 +90,7 @@
19 #define FlagClr(set,flag) ((set)->bits[FLAGSET_INDEX(flag)] &= ~FLAGSET_MASK(flag))
20
21 /** String containing valid user modes, in no particular order. */
22-#define infousermodes "dioOswkgxRXInP"
23+#define infousermodes "dioOswkgxRXInPq"
24
25 /** Character to indicate no oper name available */
26 #define NOOPERNAMECHARACTER '-'
27@@ -192,7 +192,8 @@
28 FLAG_NOIDLE, /**< user's idletime is hidden */
29 FLAG_XTRAOP, /**< oper has special powers */
30 FLAG_OPERNAME, /**< Server sends oper name in mode string */
31-
32+ FLAG_COMMONCHANSONLY, /**< SNIRCD_q: hide privmsgs/notices if in no
33+ common channels (with +ok exceptions) */
34 FLAG_LAST_FLAG, /**< number of flags */
35 FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */
36 FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */
37@@ -622,6 +623,8 @@
38 #define IsParanoid(x) HasFlag(x, FLAG_PARANOID)
39 /** Return non-zero if the server should send opername information */
40 #define IsSendOperName(x) HasFlag(x, FLAG_OPERNAME)
41+/** Return non-zero if the client has set mode +q (common chans only). */
42+#define IsCommonChansOnly(x) HasFlag(x, FLAG_COMMONCHANSONLY)
43
44 /** Return non-zero if the client has operator or server privileges. */
45 #define IsPrivileged(x) (IsAnOper(x) || IsServer(x))
46@@ -685,6 +688,8 @@
47 #define SetAccountOnly(x) SetFlag(x, FLAG_ACCOUNTONLY)
48 /** Mark a client as having mode +P (paranoid). */
49 #define SetParanoid(x) SetFlag(x, FLAG_PARANOID)
50+/** Mark a client as having mode +q (common chans only). */
51+#define SetCommonChansOnly(x) SetFlag(x, FLAG_COMMONCHANSONLY)
52
53 /** Return non-zero if \a sptr sees \a acptr as an operator. */
54 #define SeeOper(sptr,acptr) (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) \
55@@ -730,6 +735,8 @@
56 #define ClearAccountOnly(x) ClrFlag(x, FLAG_ACCOUNTONLY)
57 /** Remove mode +P (paranoid) from a client */
58 #define ClearParanoid(x) ClrFlag(x, FLAG_PARANOID)
59+/** Remove mode +q (common chans only) from a client */
60+#define ClearCommonChansOnly(x) ClrFlag(x, FLAG_COMMONCHANSONLY)
61
62 /* free flags */
63 #define FREEFLAG_SOCKET 0x0001 /**< socket needs to be freed */
64diff -r f2182ca2442a include/numeric.h
65--- a/include/numeric.h Sun Jan 11 22:53:16 2009 +0000
66+++ b/include/numeric.h Sun Jan 11 22:54:00 2009 +0000
67@@ -420,6 +420,7 @@
68 /* ERR_HTMDISABLED 486 unreal */
69 #define ERR_ACCOUNTONLY 486 /* QuakeNet/ASUKA extension */
70 /* ERR_CHANTOORECENT 487 IRCnet extension (?) */
71+#define ERR_COMMONCHANSONLY 487 /* QuakeNet/snircd extension */
72 /* ERR_TSLESSCHAN 488 IRCnet extension (?) */
73 #define ERR_VOICENEEDED 489 /* Undernet extension */
74
75diff -r f2182ca2442a ircd/channel.c
76--- a/ircd/channel.c Sun Jan 11 22:53:16 2009 +0000
77+++ b/ircd/channel.c Sun Jan 11 22:54:00 2009 +0000
78@@ -3801,3 +3801,39 @@
79
80 return marker;
81 }
82+
83+/* Returns the number of common channels between two users, upto max. */
84+int common_chan_count(struct Client *a, struct Client *b, int max)
85+{
86+ int count = 0;
87+ struct Membership *cptr;
88+ struct User *ua, *ub;
89+ unsigned int marker = get_client_marker();
90+
91+ ua = cli_user(a);
92+ ub = cli_user(b);
93+
94+ /* makes no difference to the big O complexity I know */
95+ if(ua->joined > ub->joined)
96+ {
97+ struct User *swapee = ua;
98+ ua = ub;
99+ ub = swapee;
100+ }
101+
102+ for (cptr=ua->channel;cptr;cptr=cptr->next_channel)
103+ {
104+ cptr->channel->marker = marker;
105+ }
106+
107+ for (cptr=ub->channel;cptr;cptr=cptr->next_channel)
108+ {
109+ if (cptr->channel->marker == marker) {
110+ count++;
111+ if (max && (count >= max))
112+ return count;
113+ }
114+ }
115+
116+ return count;
117+}
118diff -r f2182ca2442a ircd/ircd_relay.c
119--- a/ircd/ircd_relay.c Sun Jan 11 22:53:16 2009 +0000
120+++ b/ircd/ircd_relay.c Sun Jan 11 22:54:00 2009 +0000
121@@ -308,6 +308,10 @@
122 if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr))
123 return;
124
125+ /* slug: same applies here, since only opers can be +k */
126+ if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1))
127+ return;
128+
129 if (!(is_silenced(sptr, acptr)))
130 sendcmdto_one(sptr, CMD_PRIVATE, acptr, "%s :%s", name, text);
131 }
132@@ -360,6 +364,9 @@
133 if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr))
134 return;
135
136+ if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1))
137+ return;
138+
139 if (!(is_silenced(sptr, acptr)))
140 sendcmdto_one(sptr, CMD_NOTICE, acptr, "%s :%s", name, text);
141 }
142@@ -399,6 +406,11 @@
143 return;
144 }
145
146+ if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) {
147+ send_reply(sptr, ERR_COMMONCHANSONLY, cli_name(acptr));
148+ return;
149+ }
150+
151 /*
152 * send away message if user away
153 */
154@@ -443,6 +455,9 @@
155 if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr))
156 return;
157
158+ if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1))
159+ return;
160+
161 /*
162 * deliver the message
163 */
164diff -r f2182ca2442a ircd/m_invite.c
165--- a/ircd/m_invite.c Sun Jan 11 22:53:16 2009 +0000
166+++ b/ircd/m_invite.c Sun Jan 11 22:54:00 2009 +0000
167@@ -171,6 +171,9 @@
168 return 0;
169 }
170
171+ if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1))
172+ return;
173+
174 if (check_target_limit(sptr, acptr, cli_name(acptr), 0))
175 return 0;
176
177diff -r f2182ca2442a ircd/s_err.c
178--- a/ircd/s_err.c Sun Jan 11 22:53:16 2009 +0000
179+++ b/ircd/s_err.c Sun Jan 11 22:54:00 2009 +0000
180@@ -1006,7 +1006,7 @@
181 /* 486 */
182 { ERR_ACCOUNTONLY, "%s :You must be authed in order to message this user -- For details of how to obtain an account visit %s", "486" },
183 /* 487 */
184- { 0 },
185+ { ERR_COMMONCHANSONLY, "%s :You must share at least one channel with this user in order to message them", "487" },
186 /* 488 */
187 { 0 },
188 /* 489 */
189diff -r f2182ca2442a ircd/s_user.c
190--- a/ircd/s_user.c Sun Jan 11 22:53:16 2009 +0000
191+++ b/ircd/s_user.c Sun Jan 11 22:54:00 2009 +0000
192@@ -546,7 +546,8 @@
193 { FLAG_NOCHAN, 'n' },
194 { FLAG_NOIDLE, 'I' },
195 { FLAG_SETHOST, 'h' },
196- { FLAG_PARANOID, 'P' }
197+ { FLAG_PARANOID, 'P' },
198+ { FLAG_COMMONCHANSONLY, 'q' }
199 };
200
201 /** Length of #userModeList. */
202@@ -856,7 +857,9 @@
203 send_reply(source, ERR_ACCOUNTONLY, cli_name(source), feature_str(FEAT_URLREG));
204 return 0;
205 }
206-
207+
208+ /* No check here for IsCommonChansOnly since by definition we share at least one! */
209+
210 if (is_notice)
211 sendcmdto_one(source, CMD_NOTICE, dest, "%C :%s", dest, text);
212 else
213@@ -1428,6 +1431,12 @@
214 else
215 ClearParanoid(sptr);
216 break;
217+ case 'q':
218+ if (what == MODE_ADD)
219+ SetCommonChansOnly(sptr);
220+ else
221+ ClearCommonChansOnly(sptr);
222+ break;
223 case 'r':
224 if ((what == MODE_ADD) && *(p + 1)) {
225 account = *(++p);