2007-01-25 07:40:21 +01:00
|
|
|
/*
|
|
|
|
* charybdis: A slightly useful ircd.
|
|
|
|
* supported.c: isupport (005) numeric
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 Jilles Tjoelker
|
2016-08-25 09:59:58 +02:00
|
|
|
* Copyright (C) 2016 Charybdis Development Team
|
|
|
|
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
2007-01-25 07:40:21 +01:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* 1.Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
* 2.Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3.The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
|
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* From the old supported.h which is
|
|
|
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
|
|
|
* Copyright (C) 2002-2004 ircd-ratbox development team
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* - from mirc's versions.txt
|
|
|
|
*
|
|
|
|
* mIRC now supports the numeric 005 tokens: CHANTYPES=# and
|
|
|
|
* PREFIX=(ohv)@%+ and can handle a dynamic set of channel and
|
|
|
|
* nick prefixes.
|
|
|
|
*
|
|
|
|
* mIRC assumes that @ is supported on all networks, any mode
|
|
|
|
* left of @ is assumed to have at least equal power to @, and
|
|
|
|
* any mode right of @ has less power.
|
|
|
|
*
|
|
|
|
* mIRC has internal support for @%+ modes.
|
|
|
|
*
|
|
|
|
* $nick() can now handle all mode letters listed in PREFIX.
|
|
|
|
*
|
|
|
|
* Also added support for CHANMODES=A,B,C,D token (not currently
|
|
|
|
* supported by any servers), which lists all modes supported
|
|
|
|
* by a channel, where:
|
|
|
|
*
|
|
|
|
* A = modes that take a parameter, and add or remove nicks
|
|
|
|
* or addresses to a list, such as +bIe for the ban,
|
|
|
|
* invite, and exception lists.
|
|
|
|
*
|
|
|
|
* B = modes that change channel settings, but which take
|
|
|
|
* a parameter when they are set and unset, such as
|
|
|
|
* +k key, and -k key.
|
|
|
|
*
|
|
|
|
* C = modes that change channel settings, but which take
|
|
|
|
* a parameter only when they are set, such as +l N,
|
|
|
|
* and -l.
|
|
|
|
*
|
|
|
|
* D = modes that change channel settings, such as +imnpst
|
|
|
|
* and take no parameters.
|
|
|
|
*
|
|
|
|
* All unknown/unlisted modes are treated as type D.
|
|
|
|
*/
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
using namespace ircd;
|
2016-08-13 05:05:54 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
std::map<std::string, supported::value> supported::map;
|
2007-01-25 07:40:21 +01:00
|
|
|
|
|
|
|
void
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::init()
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
// These should all eventually get filed away into their own
|
|
|
|
// subsystem's namespace
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CHANTYPES", [](ostream &s)
|
|
|
|
{
|
|
|
|
s << ConfigChannel.disable_local_channels? "#" : "&#";
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("EXCEPTS", []
|
|
|
|
{
|
|
|
|
return ConfigChannel.use_except;
|
|
|
|
});
|
2008-08-29 22:27:34 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("INVEX", []
|
2008-08-29 22:27:34 +02:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
return ConfigChannel.use_invex;
|
|
|
|
});
|
2008-08-29 22:27:34 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CHANMODES", [](ostream &s)
|
|
|
|
{
|
|
|
|
using namespace chan::mode;
|
2008-08-29 22:36:41 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << categories[uint(category::A)] << ',';
|
|
|
|
s << categories[uint(category::B)] << ',';
|
|
|
|
s << categories[uint(category::C)] << ',';
|
|
|
|
s << categories[uint(category::D)];
|
|
|
|
});
|
2008-08-29 22:27:34 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CHANLIMIT", [](ostream &s)
|
|
|
|
{
|
|
|
|
char result[30];
|
|
|
|
snprintf(result, sizeof(result), "%s:%i",
|
|
|
|
ConfigChannel.disable_local_channels? "#" : "&#",
|
|
|
|
ConfigChannel.max_chans_per_user);
|
2008-08-29 22:36:41 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << result;
|
|
|
|
});
|
2008-08-29 22:27:34 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("PREFIX", "(ov)@+");
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("MAXLIST", [](ostream &s)
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
char result[30];
|
|
|
|
snprintf(result, sizeof result, "bq%s%s:%i",
|
|
|
|
ConfigChannel.use_except ? "e" : "",
|
|
|
|
ConfigChannel.use_invex ? "I" : "",
|
|
|
|
ConfigChannel.max_bans);
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << result;
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("MODES", chan::mode::MAXPARAMS);
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("NETWORK", [](ostream &s)
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
s << ServerInfo.network_name;
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("STATUSMSG", "@+");
|
|
|
|
add("CALLERID", [](ostream &s)
|
|
|
|
{
|
2016-08-28 06:52:31 +02:00
|
|
|
if(ConfigFileEntry.oper_only_umodes & umode::table['g'])
|
2016-08-25 09:59:58 +02:00
|
|
|
return;
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << 'g';
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CASEMAPPING", "rfc1459");
|
|
|
|
add("NICKLEN", [](ostream &s)
|
|
|
|
{
|
|
|
|
char result[200];
|
|
|
|
snprintf(result, sizeof(result), "%u", ConfigFileEntry.nicklen - 1);
|
|
|
|
s << result;
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("MAXNICKLEN", NICKLEN - 1);
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CHANNELLEN", LOC_CHANNELLEN);
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("TOPICLEN", TOPICLEN);
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("DEAF", [](ostream &s)
|
|
|
|
{
|
2016-08-28 06:52:31 +02:00
|
|
|
if(ConfigFileEntry.oper_only_umodes & umode::table['D'])
|
2016-08-25 09:59:58 +02:00
|
|
|
return;
|
2012-05-27 22:46:24 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << 'D';
|
|
|
|
});
|
2012-05-27 22:46:24 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("TARGMAX", [](ostream &s)
|
|
|
|
{
|
|
|
|
char result[200];
|
|
|
|
snprintf(result, sizeof result, "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%d,NOTICE:%d,ACCEPT:,MONITOR:",
|
|
|
|
ConfigFileEntry.max_targets,
|
|
|
|
ConfigFileEntry.max_targets);
|
2016-08-17 05:01:20 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
s << result;
|
|
|
|
});
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("EXTBAN", [](ostream &s)
|
|
|
|
{
|
|
|
|
const char *const p(chan::get_extban_string());
|
|
|
|
if(!EmptyString(p))
|
|
|
|
s << "$," << p;
|
|
|
|
});
|
2016-06-26 05:54:37 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
add("CLIENTVER", "3.0");
|
2007-01-25 07:40:21 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
bool
|
|
|
|
supported::del(const std::string &key)
|
2010-12-21 21:38:04 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
return map.erase(key);
|
2010-12-21 21:38:04 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
void
|
|
|
|
supported::show(client &client)
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
uint leading(strlen(client.name));
|
|
|
|
|
|
|
|
// UID
|
|
|
|
if(!my(client) && leading < 9)
|
|
|
|
leading = 9;
|
|
|
|
|
|
|
|
/* :<me.name> 005 <nick> <params> :are supported by this server */
|
|
|
|
/* form_str(RPL_ISUPPORT) is %s :are supported by this server */
|
|
|
|
leading += strlen(me.name) + 1 + strlen(form_str(RPL_ISUPPORT));
|
|
|
|
|
|
|
|
//TODO: XXX: It's almost time for the ircstream
|
|
|
|
uint nparams(3);
|
|
|
|
std::ostringstream buf;
|
|
|
|
for(const auto &pit : map)
|
|
|
|
{
|
|
|
|
const auto &key(pit.first);
|
|
|
|
const auto &val(pit.second);
|
|
|
|
const auto len(size(buf));
|
|
|
|
val(key, buf);
|
|
|
|
buf << ' ';
|
|
|
|
++nparams;
|
|
|
|
|
|
|
|
if(size(buf) + leading >= 510 || nparams > 14)
|
|
|
|
{
|
|
|
|
buf.seekp(len, std::ios::beg);
|
|
|
|
sendto_one_numeric(&client, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf.str().c_str());
|
|
|
|
buf.str(std::string{});
|
|
|
|
nparams = 3;
|
|
|
|
}
|
|
|
|
else continue;
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
val(key, buf);
|
|
|
|
buf << ' ';
|
|
|
|
++nparams;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(nparams > 3)
|
|
|
|
sendto_one_numeric(&client, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf.str().c_str());
|
2007-01-25 07:40:21 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
ostream &
|
|
|
|
supported::value::operator()(const std::string &key, ostream &s)
|
|
|
|
const
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
using type = supported::type;
|
|
|
|
switch(this->type)
|
|
|
|
{
|
|
|
|
case type::FUNC_STREAM:
|
|
|
|
s << key << '=';
|
|
|
|
func_stream(s);
|
|
|
|
break;
|
2007-01-25 07:40:21 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
case type::FUNC_BOOLEAN:
|
|
|
|
if(func_boolean())
|
|
|
|
s << key;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case type::STRING:
|
|
|
|
s << key << '=' << string;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case type::INTEGER:
|
|
|
|
s << key << '=' << integer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case type::BOOLEAN:
|
|
|
|
s << key;
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
return s;
|
2007-01-25 07:40:21 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::value(const std::function<void (ostream &)> &val)
|
|
|
|
:type{supported::type::FUNC_STREAM}
|
|
|
|
,func_stream{val}
|
2015-11-20 06:10:36 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::value(const std::function<bool ()> &val)
|
|
|
|
:type{supported::type::FUNC_BOOLEAN}
|
|
|
|
,func_boolean{val}
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::value(const std::string &val)
|
|
|
|
:type{supported::type::STRING}
|
|
|
|
,string{val}
|
2011-11-29 23:24:48 +01:00
|
|
|
{
|
2016-08-25 09:59:58 +02:00
|
|
|
}
|
2011-11-29 23:24:48 +01:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::value(const int64_t &val)
|
|
|
|
:type{supported::type::INTEGER}
|
|
|
|
,integer{val}
|
|
|
|
{
|
2011-11-29 23:24:48 +01:00
|
|
|
}
|
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::value()
|
|
|
|
:type{supported::type::BOOLEAN}
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
|
|
|
}
|
2016-08-13 05:05:54 +02:00
|
|
|
|
2016-08-25 09:59:58 +02:00
|
|
|
supported::value::~value()
|
|
|
|
noexcept
|
|
|
|
{
|
2016-08-13 05:05:54 +02:00
|
|
|
}
|