Restore stats_spy hook that was removed in commit 401f2454671ca233e35b0e6e4f3fa4c43cd...
[seven-1.x.git] / src / supported.c
blobbd6239e39d0d0d296ef288f76c76fac422283c96
1 /*
2 * charybdis: A slightly useful ircd.
3 * supported.c: isupport (005) numeric
5 * Copyright (C) 2006 Jilles Tjoelker
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
11 * 1.Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2.Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3.The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 /* From the old supported.h which is
33 * Copyright (C) 1996-2002 Hybrid Development Team
34 * Copyright (C) 2002-2004 ircd-ratbox development team
37 * - from mirc's versions.txt
39 * mIRC now supports the numeric 005 tokens: CHANTYPES=# and
40 * PREFIX=(ohv)@%+ and can handle a dynamic set of channel and
41 * nick prefixes.
43 * mIRC assumes that @ is supported on all networks, any mode
44 * left of @ is assumed to have at least equal power to @, and
45 * any mode right of @ has less power.
47 * mIRC has internal support for @%+ modes.
49 * $nick() can now handle all mode letters listed in PREFIX.
51 * Also added support for CHANMODES=A,B,C,D token (not currently
52 * supported by any servers), which lists all modes supported
53 * by a channel, where:
55 * A = modes that take a parameter, and add or remove nicks
56 * or addresses to a list, such as +bIe for the ban,
57 * invite, and exception lists.
59 * B = modes that change channel settings, but which take
60 * a parameter when they are set and unset, such as
61 * +k key, and -k key.
63 * C = modes that change channel settings, but which take
64 * a parameter only when they are set, such as +l N,
65 * and -l.
67 * D = modes that change channel settings, such as +imnpst
68 * and take no parameters.
70 * All unknown/unlisted modes are treated as type D.
72 /* ELIST=[tokens]:
74 * M = mask search
75 * N = !mask search
76 * U = user count search (< >)
77 * C = creation time search (C> C<)
78 * T = topic search (T> T<)
81 #include "stdinc.h"
82 #include "tools.h"
83 #include "client.h"
84 #include "common.h"
85 #include "numeric.h"
86 #include "ircd.h"
87 #include "s_conf.h"
89 dlink_list isupportlist;
91 struct isupportitem
93 const char *name;
94 const char *(*func)(void *);
95 void *param;
96 dlink_node node;
99 void
100 add_isupport(const char *name, const char *(*func)(void *), void *param)
102 struct isupportitem *item;
104 item = MyMalloc(sizeof(struct isupportitem));
105 item->name = name;
106 item->func = func;
107 item->param = param;
108 dlinkAddTail(item, &item->node, &isupportlist);
111 void
112 delete_isupport(const char *name)
114 dlink_node *ptr, *next_ptr;
115 struct isupportitem *item;
117 DLINK_FOREACH_SAFE(ptr, next_ptr, isupportlist.head)
119 item = ptr->data;
121 if (!strcmp(item->name, name))
123 dlinkDelete(ptr, &isupportlist);
124 MyFree(item);
129 /* XXX caching? */
130 void
131 show_isupport(struct Client *client_p)
133 dlink_node *ptr;
134 struct isupportitem *item;
135 const char *value;
136 char buf[512];
137 int extra_space;
138 int nchars, nparams;
139 int l;
141 extra_space = strlen(client_p->name);
142 /* UID */
143 if (!MyClient(client_p) && extra_space < 9)
144 extra_space = 9;
145 /* :<me.name> 005 <nick> <params> :are supported by this server */
146 /* form_str(RPL_ISUPPORT) is %s :are supported by this server */
147 extra_space += strlen(me.name) + 1 + strlen(form_str(RPL_ISUPPORT));
149 nchars = extra_space, nparams = 0, buf[0] = '\0';
150 DLINK_FOREACH(ptr, isupportlist.head)
152 item = ptr->data;
153 value = (*item->func)(item->param);
154 if (value == NULL)
155 continue;
156 l = strlen(item->name) + (EmptyString(value) ? 0 : 1 + strlen(value));
157 if (nchars + l + (nparams > 0) >= sizeof buf || nparams + 1 > 12)
159 sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
160 nchars = extra_space, nparams = 0, buf[0] = '\0';
162 if (nparams > 0)
163 strlcat(buf, " ", sizeof buf), nchars++;
164 strlcat(buf, item->name, sizeof buf);
165 if (!EmptyString(value))
167 strlcat(buf, "=", sizeof buf);
168 strlcat(buf, value, sizeof buf);
170 nchars += l;
171 nparams++;
173 if (nparams > 0)
174 sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
177 const char *
178 isupport_intptr(void *ptr)
180 static char buf[15];
182 ircsnprintf(buf, sizeof buf, "%d", *(int *)ptr);
183 return buf;
186 const char *
187 isupport_boolean(void *ptr)
190 return *(int *)ptr ? "" : NULL;
193 const char *
194 isupport_string(void *ptr)
197 return (const char *)ptr;
200 const char *
201 isupport_stringptr(void *ptr)
204 return *(const char **)ptr;
207 const char *
208 isupport_chanmodes(void *ptr)
210 static char result[80];
212 ircsnprintf(result, sizeof result, "%s%sbq,k,flLj,imnpstrcgzPQFR",
213 ConfigChannel.use_except ? "e" : "",
214 ConfigChannel.use_invex ? "I" : "");
215 return result;
218 const char *
219 isupport_chanlimit(void *ptr)
221 static char result[30];
223 ircsnprintf(result, sizeof result, "#:%i", ConfigChannel.max_chans_per_user);
224 return result;
227 const char *
228 isupport_maxlist(void *ptr)
230 static char result[30];
232 ircsnprintf(result, sizeof result, "bq%s%s:%i",
233 ConfigChannel.use_except ? "e" : "",
234 ConfigChannel.use_invex ? "I" : "",
235 ConfigChannel.max_bans);
236 return result;
239 const char *
240 isupport_targmax(void *ptr)
242 static char result[200];
244 ircsnprintf(result, sizeof result, "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%d,NOTICE:%d,ACCEPT:,MONITOR:",
245 ConfigFileEntry.max_targets,
246 ConfigFileEntry.max_targets);
247 return result;
250 const char *
251 isupport_extban(void *ptr)
253 const char *p;
254 static char result[200];
256 p = get_extban_string();
257 if (EmptyString(p))
258 return NULL;
259 ircsnprintf(result, sizeof result, "$:%s", p);
260 return result;
263 void
264 init_isupport(void)
266 static int maxmodes = MAXMODEPARAMS;
267 static int nicklen = NICKLEN-1;
268 static int channellen = LOC_CHANNELLEN;
269 static int topiclen = TOPICLEN;
271 add_isupport("CHANTYPES", isupport_string, "#");
272 add_isupport("EXCEPTS", isupport_boolean, &ConfigChannel.use_except);
273 add_isupport("INVEX", isupport_boolean, &ConfigChannel.use_invex);
274 add_isupport("CHANMODES", isupport_chanmodes, NULL);
275 add_isupport("CHANLIMIT", isupport_chanlimit, NULL);
276 add_isupport("PREFIX", isupport_string, "(ov)@+");
277 add_isupport("MAXLIST", isupport_maxlist, NULL);
278 add_isupport("MODES", isupport_intptr, &maxmodes);
279 add_isupport("NETWORK", isupport_stringptr, &ServerInfo.network_name);
280 add_isupport("KNOCK", isupport_boolean, &ConfigChannel.use_knock);
281 add_isupport("STATUSMSG", isupport_string, "@+");
282 add_isupport("CALLERID", isupport_string, "g");
283 add_isupport("SAFELIST", isupport_string, "");
284 add_isupport("ELIST", isupport_string, "U");
285 add_isupport("CASEMAPPING", isupport_string, "rfc1459");
286 add_isupport("CHARSET", isupport_string, "ascii");
287 add_isupport("NICKLEN", isupport_intptr, &nicklen);
288 add_isupport("CHANNELLEN", isupport_intptr, &channellen);
289 add_isupport("TOPICLEN", isupport_intptr, &topiclen);
290 add_isupport("ETRACE", isupport_string, "");
291 add_isupport("CPRIVMSG", isupport_string, "");
292 add_isupport("CNOTICE", isupport_string, "");
293 add_isupport("DEAF", isupport_string, "D");
294 add_isupport("MONITOR", isupport_intptr, &ConfigFileEntry.max_monitor);
295 add_isupport("FNC", isupport_string, "");
296 add_isupport("TARGMAX", isupport_targmax, NULL);
297 add_isupport("EXTBAN", isupport_extban, NULL);