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
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.
33 /* From the old supported.h which is
34 * Copyright (C) 1996-2002 Hybrid Development Team
35 * Copyright (C) 2002-2004 ircd-ratbox development team
38 * - from mirc's versions.txt
40 * mIRC now supports the numeric 005 tokens: CHANTYPES=# and
41 * PREFIX=(ohv)@%+ and can handle a dynamic set of channel and
44 * mIRC assumes that @ is supported on all networks, any mode
45 * left of @ is assumed to have at least equal power to @, and
46 * any mode right of @ has less power.
48 * mIRC has internal support for @%+ modes.
50 * $nick() can now handle all mode letters listed in PREFIX.
52 * Also added support for CHANMODES=A,B,C,D token (not currently
53 * supported by any servers), which lists all modes supported
54 * by a channel, where:
56 * A = modes that take a parameter, and add or remove nicks
57 * or addresses to a list, such as +bIe for the ban,
58 * invite, and exception lists.
60 * B = modes that change channel settings, but which take
61 * a parameter when they are set and unset, such as
64 * C = modes that change channel settings, but which take
65 * a parameter only when they are set, such as +l N,
68 * D = modes that change channel settings, such as +imnpst
69 * and take no parameters.
71 * All unknown/unlisted modes are treated as type D.
77 * U = user count search (< >)
78 * C = creation time search (C> C<)
79 * T = topic search (T> T<)
88 #include "supported.h"
91 rb_dlink_list isupportlist
;
96 const char *(*func
)(const void *);
102 add_isupport(const char *name
, const char *(*func
)(const void *), const void *param
)
104 struct isupportitem
*item
;
106 item
= rb_malloc(sizeof(struct isupportitem
));
110 rb_dlinkAddTail(item
, &item
->node
, &isupportlist
);
114 change_isupport(const char *name
, const char *(*func
)(const void *), const void *param
)
117 struct isupportitem
*item
;
118 const void *oldvalue
= NULL
;
120 RB_DLINK_FOREACH(ptr
, isupportlist
.head
)
124 if (!strcmp(item
->name
, name
))
126 oldvalue
= item
->param
;
128 // item->name = name;
140 delete_isupport(const char *name
)
142 rb_dlink_node
*ptr
, *next_ptr
;
143 struct isupportitem
*item
;
145 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, isupportlist
.head
)
149 if (!strcmp(item
->name
, name
))
151 rb_dlinkDelete(ptr
, &isupportlist
);
159 show_isupport(struct Client
*client_p
)
162 struct isupportitem
*item
;
166 unsigned int nchars
, nparams
;
169 extra_space
= strlen(client_p
->name
);
171 if (!MyClient(client_p
) && extra_space
< 9)
173 /* :<me.name> 005 <nick> <params> :are supported by this server */
174 /* form_str(RPL_ISUPPORT) is %s :are supported by this server */
175 extra_space
+= strlen(me
.name
) + 1 + strlen(form_str(RPL_ISUPPORT
));
177 nchars
= extra_space
, nparams
= 0, buf
[0] = '\0';
178 RB_DLINK_FOREACH(ptr
, isupportlist
.head
)
181 value
= (*item
->func
)(item
->param
);
184 l
= strlen(item
->name
) + (EmptyString(value
) ? 0 : 1 + strlen(value
));
185 if (nchars
+ l
+ (nparams
> 0) >= sizeof buf
|| nparams
+ 1 > 12)
187 sendto_one_numeric(client_p
, RPL_ISUPPORT
, form_str(RPL_ISUPPORT
), buf
);
188 nchars
= extra_space
, nparams
= 0, buf
[0] = '\0';
191 rb_strlcat(buf
, " ", sizeof buf
), nchars
++;
192 rb_strlcat(buf
, item
->name
, sizeof buf
);
193 if (!EmptyString(value
))
195 rb_strlcat(buf
, "=", sizeof buf
);
196 rb_strlcat(buf
, value
, sizeof buf
);
202 sendto_one_numeric(client_p
, RPL_ISUPPORT
, form_str(RPL_ISUPPORT
), buf
);
206 isupport_intptr(const void *ptr
)
209 rb_snprintf(buf
, sizeof buf
, "%d", *(const int *)ptr
);
214 isupport_boolean(const void *ptr
)
217 return *(const int *)ptr
? "" : NULL
;
221 isupport_string(const void *ptr
)
224 return (const char *)ptr
;
228 isupport_stringptr(const void *ptr
)
230 return *(char * const *)ptr
;
234 isupport_chanmodes(const void *ptr
)
236 static char result
[80];
238 rb_snprintf(result
, sizeof result
, "%s%sb%s,k,%sl%s,%s",
239 ConfigChannel
.use_except
? "e" : "",
240 ConfigChannel
.use_invex
? "I" : "",
241 strchr(ConfigChannel
.disabledmodes
, "q") ? "" : "q",
242 ConfigChannel
.use_forward
? "f" : "",
243 strchr(ConfigChannel
.disabledmodes
, "j") ? "" : "j",
249 isupport_chantypes(const void *ptr
)
251 return ConfigChannel
.use_local_channels
? "&#" : "#";
255 isupport_chanlimit(const void *ptr
)
257 static char result
[30];
259 rb_snprintf(result
, sizeof result
, "%s:%i",
260 ConfigChannel
.use_local_channels
? "&#" : "#",
261 ConfigChannel
.max_chans_per_user
);
266 isupport_prefix(const void *ptr
)
268 static char result
[11];
270 rb_snprintf(result
, sizeof result
, "(%so%sv)%s@%s+",
271 ConfigChannel
.use_admin
? "a" : "",
272 ConfigChannel
.use_halfop
? "h" : "",
273 ConfigChannel
.use_admin
? "!" : "",
274 ConfigChannel
.use_halfop
? "%" : "");
279 isupport_maxlist(const void *ptr
)
281 static char result
[30];
283 rb_snprintf(result
, sizeof result
, "bq%s%s:%i",
284 ConfigChannel
.use_except
? "e" : "",
285 ConfigChannel
.use_invex
? "I" : "",
286 ConfigChannel
.max_bans
);
291 isupport_targmax(const void *ptr
)
293 static char result
[200];
295 rb_snprintf(result
, sizeof result
, "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%d,NOTICE:%d,ACCEPT:,MONITOR:",
296 ConfigFileEntry
.max_targets
,
297 ConfigFileEntry
.max_targets
);
302 isupport_extban(const void *ptr
)
305 static char result
[200];
307 p
= get_extban_string();
310 rb_snprintf(result
, sizeof result
, "$,%s", p
);
317 static int maxmodes
= MAXMODEPARAMS
;
318 static int nicklen
= NICKLEN
-1;
319 static int channellen
= LOC_CHANNELLEN
;
320 static int topiclen
= TOPICLEN
;
322 add_isupport("CHANTYPES", isupport_chantypes
, NULL
);
323 add_isupport("EXCEPTS", isupport_boolean
, &ConfigChannel
.use_except
);
324 add_isupport("INVEX", isupport_boolean
, &ConfigChannel
.use_invex
);
325 add_isupport("CHANMODES", isupport_chanmodes
, NULL
);
326 add_isupport("CHANLIMIT", isupport_chanlimit
, NULL
);
327 add_isupport("PREFIX", isupport_prefix
, NULL
);
328 add_isupport("MAXLIST", isupport_maxlist
, NULL
);
329 add_isupport("MODES", isupport_intptr
, &maxmodes
);
330 add_isupport("NETWORK", isupport_stringptr
, &ServerInfo
.network_name
);
331 add_isupport("KNOCK", isupport_boolean
, &ConfigChannel
.use_knock
);
332 add_isupport("STATUSMSG", isupport_string
, "@+");
333 add_isupport("CALLERID", isupport_string
, "g");
334 add_isupport("SAFELIST", isupport_string
, "");
335 add_isupport("ELIST", isupport_string
, "CTU");
336 add_isupport("CASEMAPPING", isupport_string
, "rfc1459");
337 add_isupport("CHARSET", isupport_string
, "ascii");
338 add_isupport("NICKLEN", isupport_intptr
, &nicklen
);
339 add_isupport("CHANNELLEN", isupport_intptr
, &channellen
);
340 add_isupport("TOPICLEN", isupport_intptr
, &topiclen
);
341 add_isupport("ETRACE", isupport_string
, "");
342 add_isupport("CPRIVMSG", isupport_string
, "");
343 add_isupport("CNOTICE", isupport_string
, "");
344 add_isupport("DEAF", isupport_string
, "D");
345 add_isupport("MONITOR", isupport_intptr
, &ConfigFileEntry
.max_monitor
);
346 add_isupport("FNC", isupport_string
, "");
347 add_isupport("TARGMAX", isupport_targmax
, NULL
);
348 add_isupport("EXTBAN", isupport_extban
, NULL
);
349 add_isupport("WHOX", isupport_string
, "");
350 add_isupport("CLIENTVER", isupport_string
, "3.0");