diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 37d58b26f..df4471ddc 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1,6 +1,6 @@ # Only install cron.example.sh and anope.example.conf from this directory # NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file) -set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf) +set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf) install(FILES ${DATA} DESTINATION ${CONF_DIR} ) diff --git a/data/anope.example.conf b/data/anope.example.conf index 2b7860f2a..68db39c4d 100644 --- a/data/anope.example.conf +++ b/data/anope.example.conf @@ -1414,23 +1414,3 @@ include type = "file" name = "chanstats.example.conf" } - -/* - * [DEPRECATED] IRC2SQL Gateway - * - * This module collects data about users, channels and servers. It doesn't build stats - * itself, however, it gives you the database, it's up to you how you use it. - * - * This module is deprecated in favour of the RPC interface and the rpc_data - * module. This should provide almost all of the same information as irc2sql but - * without requiring MySQL and with much better performance. If you have a use - * case which is not covered by rpc_data then please open an issue so we can - * extend rpc_data before irc2sql is removed. - * - * Requires a MySQL Database and MySQL version 5.5 or higher - */ -#include -{ - type = "file" - name = "irc2sql.example.conf" -} diff --git a/data/irc2sql.example.conf b/data/irc2sql.example.conf deleted file mode 100644 index 260cf836a..000000000 --- a/data/irc2sql.example.conf +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Example configuration file for the irc2sql gateway - * - */ - -service -{ - /* - * The name of the StatServ client. - */ - nick = "StatServ" - - /* - * The username of the StatServ client. - */ - user = "StatServ" - - /* - * The hostname of the StatServ client. - */ - host = "${services.host}" - - /* - * The realname of the StatServ client. - */ - real = "Statistical Service" - - /* - * The modes this client should use. - * Do not modify this unless you know what you are doing. - * - * These modes are very IRCd specific. If left commented, sane defaults - * are used based on what protocol module you have loaded. - * - * Note that setting this option incorrectly could potentially BREAK some, if - * not all, usefulness of the client. We will not support you if this client is - * unable to do certain things if this option is enabled. - */ - #modes = "+o" - - /* - * An optional comma separated list of channels this service should join. Outside - * of log channels this is not very useful, as the service will just idle in the - * specified channels, and will not accept any types of commands. - * - * Prefixes may be given to the channels in the form of mode characters or prefix symbols. - */ - #channels = "@#stats,#mychan" -} - -module -{ - name = "irc2sql" - - /* - * The name of the client that should send the CTCP VERSION requests. - * It must already exist or must be defined in the following service block. - */ - client = "StatServ" - - /* - * The name of the SQL engine to use. - * This must be MySQL and must match the name in the mysql{} block - */ - engine = "mysql/main" - - /* - * An optional prefix to prepended to the name of each created table. - * Do not use the same prefix for other programs. - */ - prefix = "anope_" - - /* - * GeoIP - Automatically adds users geoip location to the user table. - * Tables are created by irc2sql, you have to run the - * geoipupdate script after you started Anope to download - * and import the GeoIP database. - * - * The geoip database can be the smaller "country" database or the - * larger "city" database. Comment to disable geoip lookup. - */ - geoip_database = "country" - - /* - * Get the CTCP version from users - * The users connecting to the network will receive a CTCP VERSION - * request from the above configured stats client - */ - ctcpuser = "yes" - - /* - * Send out CTCP VERSION requests to users during burst. - * Disable this if you restart Anope often and don't want to - * annoy your users. - */ - ctcpeob = "yes" -} diff --git a/data/stats.standalone.example.conf b/data/stats.standalone.example.conf deleted file mode 100644 index 00c2e3e17..000000000 --- a/data/stats.standalone.example.conf +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Example configuration file for Anope. After making the appropriate - * changes to this file, place it in the Anope conf directory (as - * specified in the "Config" script, default /home/username/anope/conf) - * under the name "anope.conf". - * - * The format of this file is fairly simple: three types of comments are supported: - * - All text after a '#' on a line is ignored, as in shell scripting - * - All text after '//' on a line is ignored, as in C++ - * - A block of text like this one is ignored, as in C - * - * Outside of comments, there are three structures: blocks, keys, and values. - * - * A block is a named container, which contains a number of key to value pairs - * - you may think of this as an array. - * - * A block is created like so: - * foobar - * { - * moo = "cow" - * foo = bar - * } - * - * Note that nameless blocks are allowed and are often used with comments to allow - * easily commenting an entire block, for example: - * #foobar - * { - * moo = "cow" - * foo = bar - * } - * is an entirely commented block. - * - * Keys are case insensitive. Values depend on what key - generally, information is - * given in the key comment. The quoting of values (and most other syntax) is quite - * flexible, however, please do not forget to quote your strings: - * - * "This is a parameter string with spaces in it" - * - * If you need to include a double quote inside a quoted string, precede it - * by a backslash: - * - * "This string has \"double quotes\" in it" - * - * Time parameters can be specified either as an integer representing a - * number of seconds (e.g. "3600" = 1 hour), or as an integer with a unit - * specifier: "s" = seconds, "m" = minutes, "h" = hours, "d" = days. - * Combinations (such as "1h30m") are not permitted. Examples (all of which - * represent the same length of time, one day): - * - * "86400", "86400s", "1440m", "24h", "1d" - * - * In the documentation for each directive, one of the following will be - * included to indicate whether an option is required: - * - * [REQUIRED] - * Indicates a directive which must be given. Without it, Anope will - * not start. - * - * [RECOMMENDED] - * Indicates a directive which may be omitted, but omitting it may cause - * undesirable side effects. - * - * [OPTIONAL] - * Indicates a directive which is optional. If not given, the feature - * will typically be disabled. If this is not the case, more - * information will be given in the documentation. - * - * [DISCOURAGED] - * Indicates a directive which may cause undesirable side effects if - * specified. - * - * [DEPRECATED] - * Indicates a directive which will disappear in a future version of - * Anope, usually because its functionality has been either - * superseded by that of other directives or incorporated into the main - * program. - */ - -/* - * [OPTIONAL] Defines - * - * You can use defines for repeated information, which can be used to easily change many - * values in the configuration at once. - * - * To use a define called foo.bar you use ${foo.bar} in your config file. You can also use - * environment variables by prefixing their name with "env." like ${env.USER}. - */ - -/* - * The services.host define is used in multiple different locations throughout the - * configuration for the server name and pseudoclient hostnames. - */ -define -{ - name = "services.host" - value = "stats.example.com" -} - -/* - * [OPTIONAL] Additional Includes - * - * You can include additional configuration files here. - * You may also include executable files, which will be executed and - * the output from it will be included into your configuration. - */ - -#include -{ - type = "file" - name = "some.conf" -} - -#include -{ - type = "executable" - name = "/usr/bin/wget -q -O - https://some.misconfigured.network.com/stats.conf" -} - -/* - * [REQUIRED] IRCd Config - * - * This section is used to set up Anope to connect to your IRC network. - * This section can be included multiple times, and Anope will attempt to - * connect to each server until it finally connects. - * - * Each uplink IRCd should have a corresponding configuration to allow Anope - * to link to it. - * - * An example configuration for InspIRCd that is compatible with the below uplink - * and serverinfo configuration would look like: - * - * # This goes in inspircd.conf, *NOT* your Anope config! - * - * - * - * - * An example configuration for UnrealIRCd that is compatible with the below uplink - * and serverinfo configuration would look like: - * - * // This goes in unrealircd.conf, *NOT* your Anope config! - * listen { - * ip 127.0.0.1; - * port 7000; - * options { - * serversonly; - * }; - * }; - * link stats.example.com { - * incoming { - * mask *@127.0.0.1; - * }; - * password "mypassword"; - * class servers; - * }; - * ulines { stats.example.com; }; - */ -uplink -{ - /* - * The IP address, hostname, or UNIX socket path of the IRC server you wish - * to connect Anope to. - * Usually, you will want to connect over 127.0.0.1 (aka localhost). - * - * NOTE: On some shell providers, this will not be an option. - */ - host = "127.0.0.1" - - /* - * The protocol that Anope should use when connecting to the uplink. Can - * be set to "ipv4" (the default), "ipv6", or "unix". - */ - protocol = "ipv4" - - /* - * Enable if Anope should connect using SSL. - * You must have an SSL module loaded for this to work. - */ - ssl = no - - /* - * The port to connect to. - * The IRCd *MUST* be configured to listen on this port, and to accept - * server connections. - * - * Refer to your IRCd documentation for how this is to be done. - */ - port = 7000 - - /* - * The password to send to the IRC server for authentication. - * This must match the link block on your IRCd. - * - * Refer to your IRCd documentation for more information on link blocks. - */ - password = "mypassword" -} - -/* - * [REQUIRED] Server Information - * - * This section contains information about the services server. - */ -serverinfo -{ - /* - * The hostname that Anope will be seen as, it must have no conflicts with any - * other server names on the rest of your IRC network. Note that it does not have - * to be an existing hostname, just one that isn't on your network already. - */ - name = "${services.host}" - - /* - * The text which should appear as the server's information in /WHOIS and similar - * queries. - */ - description = "Anope IRC Statistics" - - /* - * The local address that Anope will bind to before connecting to the remote - * server. This may be useful for multihomed hosts. If omitted, Anope will let - * the Operating System choose the local address. This directive is optional. - * - * If you don't know what this means or don't need to use it, just leave this - * directive commented out. - */ - #localhost = "nowhere." - - /* - * What Server ID to use for this connection? - * Note: This should *ONLY* be used for TS6/P10 IRCds. Refer to your IRCd documentation - * to see if this is needed. - */ - #id = "00A" - - /* - * The filename containing the Anope process ID. The path is relative to the - * data directory. - */ - pid = "anope.pid" - - /* - * The filename containing the Message of the Day. The path is relative to the - * config directory. - */ - motd = "motd.txt" -} - -/* - * [REQUIRED] Protocol module - * - * This directive tells Anope which IRCd Protocol to speak when connecting. - * You MUST modify this to match the IRCd you run. - * - * Supported: - * - hybrid - * - inspircd - * - ngircd - * - plexus - * - ratbox - * - solanum - * - unrealircd - */ -module -{ - name = "inspircd" -} - -/* - * [REQUIRED] Network Information - * - * This section contains information about the IRC network that Anope will be - * connecting to. - */ -networkinfo -{ - /* - * This is the name of the network that Anope will be running on. - */ - networkname = "LocalNet" - - /* - * Set this to the maximum allowed nick length on your network. - * Be sure to set this correctly, as setting this wrong can result in - * Anope being disconnected from the network. Defaults to 31. - */ - #nicklen = 31 - - /* Set this to the maximum allowed ident length on your network. - * Be sure to set this correctly, as setting this wrong can result in - * Anope being disconnected from the network. Defaults to 10. - */ - #userlen = 10 - - /* Set this to the maximum allowed hostname length on your network. - * Be sure to set this correctly, as setting this wrong can result in - * Anope being disconnected from the network. Defaults to 64. - */ - #hostlen = 64 - - /* Set this to the maximum allowed channel length on your network. - * Defaults to 64. - */ - #chanlen = 32 - - /* The maximum number of list modes settable on a channel (such as b, e, I). - * Comment out or set to 0 to disable. - */ - modelistsize = 100 - - /* - * The characters allowed in hostnames. This is used for validating hostnames given - * to services, such as BotServ bot hostnames and user vhosts. Changing this is not - * recommended unless you know for sure your IRCd supports whatever characters you are - * wanting to use. Telling services to set a vhost containing characters your IRCd - * disallows could potentially break the IRCd and/or Anope. - * - * It is recommended you DON'T change this. - */ - vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-" - - /* - * If enabled, allows vhosts to not contain dots (.). - * Newer IRCds generally do not have a problem with this, but the same warning as - * vhost_chars applies. - * - * It is recommended you DON'T change this. - */ - allow_undotted_vhosts = no - - /* - * The characters that are not allowed to be at the very beginning or very ending - * of a vhost. The same warning as vhost_chars applies. - * - * It is recommended you DON'T change this. - */ - disallow_start_or_end = ".-" -} - -/* - * [REQUIRED] Anope Options - * - * This section contains various options which determine how Anope will operate. - */ -options -{ - /* - * On Linux/UNIX systems Anope can setuid and setgid to this user and group - * after starting up. This is useful if Anope has to bind to privileged ports. - */ - #user = "anope" - #group = "anope" - - /* - * The case mapping used by services. This must be set to a valid locale name - * installed on your machine. Anope uses this case map to compare, with - * case insensitivity, things such as nick names, channel names, etc. - * - * We provide two special casemaps shipped with Anope, ascii and rfc1459. - * - * This value should be set to what your IRCd uses, which is probably rfc1459, - * however Anope has always used ascii for comparison, so the default is ascii. - * - * Changing this value once set is not recommended. - */ - casemap = "ascii" - - /* - * Sets the timeout period for reading from the uplink. - */ - readtimeout = 5s - - /* - * If set, Anope will only show /stats o to IRC Operators. This directive - * is optional. - */ - #hidestatso = yes - - /* - * A space-separated list of U-lined servers on your network, it is assumed that - * the servers in this list are allowed to set channel modes and Anope will - * not attempt to reverse their mode changes. - * - * WARNING: Do NOT put your normal IRC user servers in this directive. - * - * This directive is optional. - */ - #ulineservers = "services.your.network" - - /* - * How long to wait between connection retries with the uplink(s). - */ - retrywait = 60s -} - -/* - * [RECOMMENDED] Logging Configuration - * - * This section is used for configuring what is logged and where it is logged to. - * You may have multiple log blocks if you wish. Remember to properly secure any - * channels you choose to have Anope log to! - */ -log -{ - /* - * Target(s) to log to, which may be one of the following: - * - a channel name - * - a filename - * - globops - */ - target = "stats.log" - - /* Log to both stats.log and the channel #stats - * - * Note that some older IRCds, such as Ratbox, require services to be in the - * log channel to be able to message it. To do this, configure service:channels to - * join your logging channel. - */ - #target = "stats.log #stats" - - /* - * The source(s) to only accept log messages from. Leave commented to allow all sources. - * This can be a users name, a channel name, one of our clients (e.g. OperServ), or a server name. - */ - #source = "" - - /* - * The bot used to log generic messages which have no predefined sender if there - * is a channel in the target directive. - */ - bot = "Global" - - /* - * The number of days to keep log files, only useful if you are logging to a file. - * Set to 0 to never delete old log files. - * - * Note that Anope must run 24 hours a day for this feature to work correctly. - */ - logage = 7 - - /* - * What types of log messages should be logged by this block. There are nine general categories: - * - * servers - Server actions, linking, squitting, etc. - * channels - Actions in channels such as joins, parts, kicks, etc. - * users - User actions such as connecting, disconnecting, changing name, etc. - * other - All other messages without a category. - * rawio - Logs raw input and output from services - * debug - Debug messages (log files can become VERY large from this). - * - * These options determine what messages from the categories should be logged. Wildcards are accepted, and - * you can also negate values with a ~. For example, "~operserv/akill operserv/*" would log all operserv - * messages except for operserv/akill. Note that processing stops at the first matching option, which - * means "* ~operserv/*" would log everything because * matches everything. - * - * Valid server options are: - * connect, quit, sync, squit - * - * Valid channel options are: - * create, destroy, join, part, kick, leave, mode - * - * Valid user options are: - * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper, away - * - * Rawio and debug are simple yes/no answers, there are no types for them. - * - * Note that modules may add their own values to these options. - */ - servers = "*" - #channels = "~mode *" - users = "connect disconnect nick" - other = "*" - rawio = no - debug = no -} - -/* - * [REQUIRED] MySQL Database configuration. - * - * mysql - * - * This module allows other modules to use MySQL. - */ -module -{ - name = "mysql" - - mysql - { - /* The name of this service. */ - name = "mysql/main" - database = "anope" - server = "127.0.0.1" - username = "anope" - password = "mypassword" - port = 3306 - } -} - -/* - * IRC2SQL Gateway - * This module collects data about users, channels and servers. It doesn't build stats - * itself, however, it gives you the database, it's up to you how you use it. - * - * Requires a MySQL Database and MySQL version 5.5 or higher - */ -include -{ - type = "file" - name = "irc2sql.example.conf" -} diff --git a/modules/irc2sql/CMakeLists.txt b/modules/irc2sql/CMakeLists.txt deleted file mode 100644 index 781f0ef1f..000000000 --- a/modules/irc2sql/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -build_subdir(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/modules/irc2sql/irc2sql.cpp b/modules/irc2sql/irc2sql.cpp deleted file mode 100644 index 629a749d2..000000000 --- a/modules/irc2sql/irc2sql.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - * - * (C) 2013-2025 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "irc2sql.h" - -void IRC2SQL::OnShutdown() -{ - // TODO: test if we really have to use blocking query here - // (sometimes mysql get unloaded before the other thread executed all queries) - if (this->sql) - SQL::Result r = this->sql->RunQuery(SQL::Query("CALL " + prefix + "OnShutdown()")); - quitting = true; -} - -void IRC2SQL::OnReload(Configuration::Conf &conf) -{ - const auto &block = Config->GetModule(this); - prefix = block.Get("prefix", "anope_"); - GeoIPDB = block.Get("geoip_database"); - ctcpuser = block.Get("ctcpuser", "no"); - ctcpeob = block.Get("ctcpeob", "yes"); - Anope::string engine = block.Get("engine"); - this->sql = ServiceReference("SQL::Provider", engine); - if (sql) - this->CheckTables(); - else - Log() << "IRC2SQL: no database connection to " << engine; - - const Anope::string &snick = block.Get("client"); - if (snick.empty()) - throw ConfigException(Module::name + ": must be defined"); - StatServ = BotInfo::Find(snick, true); - if (!StatServ) - throw ConfigException(Module::name + ": no bot named " + snick); - - if (firstrun) - { - firstrun = false; - - for (Anope::map::const_iterator it = Servers::ByName.begin(); it != Servers::ByName.end(); ++it) - { - this->OnNewServer(it->second); - } - - for (const auto &[_, c] : ChannelList) - { - this->OnChannelCreate(c); - } - - for (const auto &[_, u] : UserListByNick) - { - bool exempt = false; - this->OnUserConnect(u, exempt); - for (const auto &[_, uc] : u->chans) - { - this->OnJoinChannel(u, uc->chan); - } - } - } - -} - -void IRC2SQL::OnNewServer(Server *server) -{ - query = "INSERT DELAYED INTO `" + prefix + "server` (name, hops, comment, link_time, online, ulined) " - "VALUES (@name@, @hops@, @comment@, now(), 'Y', @ulined@) " - "ON DUPLICATE KEY UPDATE name=VALUES(name), hops=VALUES(hops), comment=VALUES(comment), " - "link_time=VALUES(link_time), online=VALUES(online), ulined=VALUES(ulined)"; - query.SetValue("name", server->GetName()); - query.SetValue("hops", server->GetHops()); - query.SetValue("comment", server->GetDescription()); - query.SetValue("ulined", server->IsULined() ? "Y" : "N"); - this->RunQuery(query); -} - -void IRC2SQL::OnServerQuit(Server *server) -{ - if (quitting) - return; - - query = "CALL " + prefix + "ServerQuit(@name@)"; - query.SetValue("name", server->GetName()); - this->RunQuery(query); -} - -void IRC2SQL::OnUserConnect(User *u, bool &exempt) -{ - if (!introduced_myself) - { - this->OnNewServer(Me); - introduced_myself = true; - } - - query = "CALL " + prefix + "UserConnect(@nick@,@host@,@vhost@,@chost@,@realname@,@ip@,@ident@,@vident@," - "@account@,@secure@,@fingerprint@,@signon@,@server@,@uuid@,@modes@,@oper@)"; - query.SetValue("nick", u->nick); - query.SetValue("host", u->host); - query.SetValue("vhost", u->vhost); - query.SetValue("chost", u->chost); - query.SetValue("realname", u->realname); - query.SetValue("ip", u->ip.addr()); - query.SetValue("ident", u->GetIdent()); - query.SetValue("vident", u->GetVIdent()); - query.SetValue("secure", u->IsSecurelyConnected() ? "Y" : "N"); - query.SetValue("account", u->IsIdentified() ? u->Account()->display : ""); - query.SetValue("fingerprint", u->fingerprint); - query.SetValue("signon", u->signon); - query.SetValue("server", u->server->GetName()); - query.SetValue("uuid", u->GetUID()); - query.SetValue("modes", u->GetModes()); - query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N"); - this->RunQuery(query); - - if (ctcpuser && (Me->IsSynced() || ctcpeob) && u->server != Me) - IRCD->SendPrivmsg(StatServ, u->GetUID(), Anope::FormatCTCP("VERSION")); - -} - -void IRC2SQL::OnUserQuit(User *u, const Anope::string &msg) -{ - if (quitting || u->server->IsQuitting()) - return; - - query = "CALL " + prefix + "UserQuit(@nick@)"; - query.SetValue("nick", u->nick); - this->RunQuery(query); -} - -void IRC2SQL::OnUserNickChange(User *u, const Anope::string &oldnick) -{ - query = "UPDATE `" + prefix + "user` SET nick=@newnick@ WHERE nick=@oldnick@"; - query.SetValue("newnick", u->nick); - query.SetValue("oldnick", oldnick); - this->RunQuery(query); -} - -void IRC2SQL::OnUserAway(User *u, const Anope::string &message) -{ - query = "UPDATE `" + prefix + "user` SET away=@away@, awaymsg=@awaymsg@ WHERE nick=@nick@"; - query.SetValue("away", (!message.empty()) ? "Y" : "N"); - query.SetValue("awaymsg", message); - query.SetValue("nick", u->nick); - this->RunQuery(query); -} - -void IRC2SQL::OnFingerprint(User *u) -{ - query = "UPDATE `" + prefix + "user` SET secure=@secure@, fingerprint=@fingerprint@ WHERE nick=@nick@"; - query.SetValue("secure", u->IsSecurelyConnected() ? "Y" : "N"); - query.SetValue("fingerprint", u->fingerprint); - query.SetValue("nick", u->nick); - this->RunQuery(query); -} - -void IRC2SQL::OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) -{ - query = "UPDATE `" + prefix + "user` SET modes=@modes@, oper=@oper@ WHERE nick=@nick@"; - query.SetValue("nick", u->nick); - query.SetValue("modes", u->GetModes()); - query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N"); - this->RunQuery(query); -} - -void IRC2SQL::OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) -{ - this->OnUserModeSet(setter, u, mname); -} - -void IRC2SQL::OnUserLogin(User *u) -{ - query = "UPDATE `" + prefix + "user` SET account=@account@ WHERE nick=@nick@"; - query.SetValue("nick", u->nick); - query.SetValue("account", u->IsIdentified() ? u->Account()->display : ""); - this->RunQuery(query); -} - -void IRC2SQL::OnNickLogout(User *u) -{ - this->OnUserLogin(u); -} - -void IRC2SQL::OnSetDisplayedHost(User *u) -{ - query = "UPDATE `" + prefix + "user` " - "SET vhost=@vhost@ " - "WHERE nick=@nick@"; - query.SetValue("vhost", u->GetDisplayedHost()); - query.SetValue("nick", u->nick); - this->RunQuery(query); -} - -void IRC2SQL::OnChannelCreate(Channel *c) -{ - query = "INSERT INTO `" + prefix + "chan` (channel, topic, topicauthor, topictime, modes) " - "VALUES (@channel@,@topic@,@topicauthor@,@topictime@,@modes@) " - "ON DUPLICATE KEY UPDATE channel=VALUES(channel), topic=VALUES(topic)," - "topicauthor=VALUES(topicauthor), topictime=VALUES(topictime), modes=VALUES(modes)"; - query.SetValue("channel", c->name); - query.SetValue("topic", c->topic); - query.SetValue("topicauthor", c->topic_setter); - if (c->topic_ts > 0) - query.SetValue("topictime", c->topic_ts); - else - query.SetValue("topictime", "NULL", false); - query.SetValue("modes", c->GetModes(true,true)); - this->RunQuery(query); -} - -void IRC2SQL::OnChannelDelete(Channel *c) -{ - query = "DELETE FROM `" + prefix + "chan` WHERE channel=@channel@"; - query.SetValue("channel", c->name); - this->RunQuery(query); -} - -void IRC2SQL::OnJoinChannel(User *u, Channel *c) -{ - Anope::string modes; - ChanUserContainer *cu = u->FindChannel(c); - if (cu) - modes = cu->status.Modes(); - - query = "CALL " + prefix + "JoinUser(@nick@,@channel@,@modes@)"; - query.SetValue("nick", u->nick); - query.SetValue("channel", c->name); - query.SetValue("modes", modes); - this->RunQuery(query); -} - -EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const ModeData &data) -{ - if (mode->type == MODE_STATUS) - { - User *u = User::Find(data.value); - if (u == NULL) - return EVENT_CONTINUE; - - ChanUserContainer *cc = u->FindChannel(c); - if (cc == NULL) - return EVENT_CONTINUE; - - query = "UPDATE `" + prefix + "user` AS u, `" + prefix + "ison` AS i, `" + prefix + "chan` AS c" - " SET i.modes=@modes@" - " WHERE u.nick=@nick@ AND c.channel=@channel@" - " AND u.nickid = i.nickid AND c.chanid = i.chanid"; - query.SetValue("nick", u->nick); - query.SetValue("modes", cc->status.Modes()); - query.SetValue("channel", c->name); - this->RunQuery(query); - } - else - { - query = "UPDATE `" + prefix + "chan` SET modes=@modes@ WHERE channel=@channel@"; - query.SetValue("channel", c->name); - query.SetValue("modes", c->GetModes(true,true)); - this->RunQuery(query); - } - return EVENT_CONTINUE; -} - -EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) -{ - this->OnChannelModeSet(c, setter, mode, param); - return EVENT_CONTINUE; -} - -void IRC2SQL::OnLeaveChannel(User *u, Channel *c) -{ - if (quitting) - return; - /* - * user is quitting, we already received a OnUserQuit() - * at this point the user is already removed from SQL and all channels - */ - if (u->Quitting()) - return; - query = "CALL " + prefix + "PartUser(@nick@,@channel@)"; - query.SetValue("nick", u->nick); - query.SetValue("channel", c->name); - this->RunQuery(query); -} - -void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) -{ - query = "UPDATE `" + prefix + "chan` " - "SET topic=@topic@, topicauthor=@author@, topictime=FROM_UNIXTIME(@time@) " - "WHERE channel=@channel@"; - query.SetValue("topic", c->topic); - query.SetValue("author", c->topic_setter); - query.SetValue("time", c->topic_ts); - query.SetValue("channel", c->name); - this->RunQuery(query); -} - -void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message, const Anope::map &tags) -{ - if (bi != StatServ) - return; - - Anope::string ctcpname, ctcpbody; - if (!Anope::ParseCTCP(message, ctcpname, ctcpbody) || ctcpname != "VERSION") - return; - - if (u->HasExt("CTCPVERSION")) - return; - - u->Extend("CTCPVERSION"); - auto versionstr = Anope::NormalizeBuffer(ctcpbody); - if (versionstr.empty()) - return; - - query = "UPDATE `" + prefix + "user` " - "SET version=@version@ " - "WHERE nick=@nick@"; - query.SetValue("version", versionstr); - query.SetValue("nick", u->nick); - this->RunQuery(query); -} - -MODULE_INIT(IRC2SQL) diff --git a/modules/irc2sql/irc2sql.h b/modules/irc2sql/irc2sql.h deleted file mode 100644 index 95d01cc4a..000000000 --- a/modules/irc2sql/irc2sql.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * (C) 2013-2025 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#pragma once - -#include "module.h" -#include "modules/sql.h" - -class MySQLInterface final - : public SQL::Interface -{ -public: - MySQLInterface(Module *o) : SQL::Interface(o) { } - - void OnResult(const SQL::Result &r) override - { - } - - void OnError(const SQL::Result &r) override - { - if (!r.GetQuery().query.empty()) - Log(LOG_DEBUG) << "irc2sql: Error executing query " << r.finished_query << ": " << r.GetError(); - else - Log(LOG_DEBUG) << "irc2sql: Error executing query: " << r.GetError(); - } -}; - -class IRC2SQL final - : public Module -{ - ServiceReference sql; - MySQLInterface sqlinterface; - SQL::Query query; - std::vector TableList, ProcedureList, EventList; - Anope::string prefix, GeoIPDB; - bool quitting, introduced_myself, ctcpuser, ctcpeob, firstrun; - BotInfo *StatServ; - PrimitiveExtensibleItem versionreply; - - void RunQuery(const SQL::Query &q); - void GetTables(); - - bool HasTable(const Anope::string &table); - bool HasProcedure(const Anope::string &table); - bool HasEvent(const Anope::string &table); - - void CheckTables(); - -public: - IRC2SQL(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, EXTRA | VENDOR), sql("", ""), sqlinterface(this), versionreply(this, "CTCPVERSION") - { - firstrun = true; - quitting = false; - introduced_myself = false; - } - - void OnShutdown() override; - void OnReload(Configuration::Conf &config) override; - void OnNewServer(Server *server) override; - void OnServerQuit(Server *server) override; - void OnUserConnect(User *u, bool &exempt) override; - void OnUserQuit(User *u, const Anope::string &msg) override; - void OnUserNickChange(User *u, const Anope::string &oldnick) override; - void OnUserAway(User *u, const Anope::string &message) override; - void OnFingerprint(User *u) override; - void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override; - void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override; - void OnUserLogin(User *u) override; - void OnNickLogout(User *u) override; - void OnSetDisplayedHost(User *u) override; - - void OnChannelCreate(Channel *c) override; - void OnChannelDelete(Channel *c) override; - void OnLeaveChannel(User *u, Channel *c) override; - void OnJoinChannel(User *u, Channel *c) override; - EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const ModeData &data) override; - EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override; - - void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override; - - void OnBotNotice(User *u, BotInfo *bi, Anope::string &message, const Anope::map &tags) override; -}; diff --git a/modules/irc2sql/tables.cpp b/modules/irc2sql/tables.cpp deleted file mode 100644 index b00c0e9a5..000000000 --- a/modules/irc2sql/tables.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * - * (C) 2013-2025 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "irc2sql.h" - -void IRC2SQL::CheckTables() -{ - Anope::string geoquery(""); - - if (firstrun) - { - /* - * reset some tables to make sure they are really empty - */ - this->sql->RunQuery("TRUNCATE TABLE " + prefix + "user"); - this->sql->RunQuery("TRUNCATE TABLE " + prefix + "chan"); - this->sql->RunQuery("TRUNCATE TABLE " + prefix + "ison"); - this->sql->RunQuery("UPDATE `" + prefix + "server` SET currentusers=0, online='N'"); - } - - this->GetTables(); - - if (GeoIPDB.equals_ci("country")) - { - if (!this->HasTable(prefix + "geoip_country")) - { - query = "CREATE TABLE `" + prefix + "geoip_country` (" - "`start` INT UNSIGNED NOT NULL," - "`end` INT UNSIGNED NOT NULL," - "`countrycode` varchar(2)," - "`countryname` varchar(50)," - "PRIMARY KEY `end` (`end`)," - "KEY `start` (`start`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - } - else if (GeoIPDB.equals_ci("city")) - { - if (!this->HasTable(prefix + "geoip_city_blocks")) - { - query = "CREATE TABLE `" + prefix + "geoip_city_blocks` (" - "`start` INT UNSIGNED NOT NULL," - "`end` INT UNSIGNED NOT NULL," - "`locId` INT UNSIGNED NOT NULL," - "PRIMARY KEY `end` (`end`)," - "KEY `start` (`start`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "geoip_city_location")) - { - query = "CREATE TABLE `" + prefix + "geoip_city_location` (" - "`locId` INT UNSIGNED NOT NULL," - "`country` CHAR(2) NOT NULL," - "`region` CHAR(2) NOT NULL," - "`city` VARCHAR(50)," - "`latitude` FLOAT," - "`longitude` FLOAT," - "`areaCode` INT," - "PRIMARY KEY (`locId`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "geoip_city_region")) - { query = "CREATE TABLE `" + prefix + "geoip_city_region` (" - "`country` CHAR(2) NOT NULL," - "`region` CHAR(2) NOT NULL," - "`regionname` VARCHAR(100) NOT NULL," - "PRIMARY KEY (`country`,`region`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - } - if (!this->HasTable(prefix + "server")) - { - query = "CREATE TABLE `" + prefix + "server` (" - "`id` int UNSIGNED NOT NULL AUTO_INCREMENT," - "`name` varchar(64) NOT NULL," - "`hops` tinyint NOT NULL," - "`comment` varchar(255) NOT NULL," - "`link_time` datetime DEFAULT NULL," - "`split_time` datetime DEFAULT NULL," - "`version` varchar(127) DEFAULT NULL," - "`currentusers` int DEFAULT 0," - "`online` enum('Y','N') NOT NULL DEFAULT 'Y'," - "`ulined` enum('Y','N') NOT NULL DEFAULT 'N'," - "PRIMARY KEY (`id`)," - "UNIQUE KEY `name` (`name`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "chan")) - { - query = "CREATE TABLE `" + prefix + "chan` (" - "`chanid` int UNSIGNED NOT NULL AUTO_INCREMENT," - "`channel` varchar(255) NOT NULL," - "`topic` varchar(512) DEFAULT NULL," - "`topicauthor` varchar(255) DEFAULT NULL," - "`topictime` datetime DEFAULT NULL," - "`modes` varchar(512) DEFAULT NULL," - "PRIMARY KEY (`chanid`)," - "UNIQUE KEY `channel`(`channel`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "user")) - { - query = "CREATE TABLE `" + prefix + "user` (" - "`nickid` int UNSIGNED NOT NULL AUTO_INCREMENT," - "`nick` varchar(255) NOT NULL DEFAULT ''," - "`host` varchar(255) NOT NULL DEFAULT ''," - "`vhost` varchar(255) NOT NULL DEFAULT ''," - "`chost` varchar(255) NOT NULL DEFAULT ''," - "`realname` varchar(255) NOT NULL DEFAULT ''," - "`ip` varchar(255) NOT NULL DEFAULT ''," - "`ident` varchar(32) NOT NULL DEFAULT ''," - "`vident` varchar(32) NOT NULL DEFAULT ''," - "`modes` varchar(255) NOT NULL DEFAULT ''," - "`account` varchar(255) NOT NULL DEFAULT ''," - "`secure` enum('Y','N') NOT NULL DEFAULT 'N'," - "`fingerprint` varchar(128) NOT NULL DEFAULT ''," - "`signon` datetime DEFAULT NULL," - "`server` varchar(255) NOT NULL DEFAULT ''," - "`servid` int UNSIGNED NOT NULL DEFAULT '0'," - "`uuid` varchar(32) NOT NULL DEFAULT ''," - "`oper` enum('Y','N') NOT NULL DEFAULT 'N'," - "`away` enum('Y','N') NOT NULL DEFAULT 'N'," - "`awaymsg` varchar(255) NOT NULL DEFAULT ''," - "`version` varchar(255) NOT NULL DEFAULT ''," - "`geocode` varchar(16) NOT NULL DEFAULT ''," - "`geocountry` varchar(64) NOT NULL DEFAULT ''," - "`georegion` varchar(100) NOT NULL DEFAULT ''," - "`geocity` varchar(128) NOT NULL DEFAULT ''," - "`locId` INT UNSIGNED," - "PRIMARY KEY (`nickid`)," - "UNIQUE KEY `nick` (`nick`)," - "KEY `servid` (`servid`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "ison")) - { - query = "CREATE TABLE `" + prefix + "ison` (" - "`nickid` int unsigned NOT NULL default '0'," - "`chanid` int unsigned NOT NULL default '0'," - "`modes` varchar(255) NOT NULL default ''," - "PRIMARY KEY (`nickid`,`chanid`)," - "KEY `modes` (`modes`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (!this->HasTable(prefix + "maxusers")) - { - query = "CREATE TABLE `" + prefix + "maxusers` (" - "`name` VARCHAR(255) NOT NULL," - "`maxusers` int NOT NULL," - "`maxtime` DATETIME NOT NULL," - "`lastused` DATETIME NOT NULL," - "UNIQUE KEY `name` (`name`)" - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; - this->RunQuery(query); - } - if (this->HasProcedure(prefix + "UserConnect")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserConnect")); - - if (GeoIPDB.equals_ci("country")) - geoquery = "UPDATE `" + prefix + "user` AS u " - "JOIN ( SELECT `countrycode`, `countryname` " - "FROM `" + prefix + "geoip_country` " - "WHERE INET_ATON(ip_) <= `end` " - "AND `start` <= INET_ATON(ip_) " - "ORDER BY `end` ASC LIMIT 1 ) as c " - "SET u.geocode = c.countrycode, u.geocountry = c.countryname " - "WHERE u.nick = nick_; "; - else if (GeoIPDB.equals_ci("city")) - geoquery = "UPDATE `" + prefix + "user` as u " - "JOIN ( SELECT * FROM `" + prefix + "geoip_city_location` " - "WHERE `locID` = ( SELECT `locID` " - "FROM `" + prefix + "geoip_city_blocks` " - "WHERE INET_ATON(ip_) <= `end` " - "AND `start` <= INET_ATON(ip_) " - "ORDER BY `end` ASC LIMIT 1 ) " - ") as l " - "SET u.geocode = l.country, " - "u.geocity = l.city, " - "u.locID = l.locID, " - "u.georegion = ( SELECT `regionname` " - "FROM `" + prefix + "geoip_city_region` " - "WHERE `country` = l.country " - "AND `region` = l.region )" - "WHERE u.nick = nick_;"; - - query = "CREATE PROCEDURE `" + prefix + "UserConnect`" - "(nick_ varchar(255), host_ varchar(255), vhost_ varchar(255), " - "chost_ varchar(255), realname_ varchar(255), ip_ varchar(255), " - "ident_ varchar(255), vident_ varchar(255), account_ varchar(255), " - "secure_ enum('Y','N'), fingerprint_ varchar(255), signon_ int, " - "server_ varchar(255), uuid_ varchar(32), modes_ varchar(255), " - "oper_ enum('Y','N')) " - "BEGIN " - "DECLARE cur int;" - "DECLARE max int;" - "INSERT INTO `" + prefix + "user` " - "(nick, host, vhost, chost, realname, ip, ident, vident, account, " - "secure, fingerprint, signon, server, uuid, modes, oper) " - "VALUES (nick_, host_, vhost_, chost_, realname_, ip_, ident_, vident_, " - "account_, secure_, fingerprint_, FROM_UNIXTIME(signon_), server_, " - "uuid_, modes_, oper_) " - "ON DUPLICATE KEY UPDATE host=VALUES(host), vhost=VALUES(vhost), " - "chost=VALUES(chost), realname=VALUES(realname), ip=VALUES(ip), " - "ident=VALUES(ident), vident=VALUES(vident), account=VALUES(account), " - "secure=VALUES(secure), fingerprint=VALUES(fingerprint), signon=VALUES(signon), " - "server=VALUES(server), uuid=VALUES(uuid), modes=VALUES(modes), " - "oper=VALUES(oper);" - "UPDATE `" + prefix + "user` as `u`, `" + prefix + "server` as `s`" - "SET u.servid = s.id, " - "s.currentusers = s.currentusers + 1 " - "WHERE s.name = server_ AND u.nick = nick_;" - "SELECT `currentusers` INTO cur FROM `" + prefix + "server` WHERE name=server_;" - "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=server_;" - "IF found_rows() AND cur <= max THEN " - "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=server_;" - "ELSE " - "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) " - "VALUES ( server_, cur, now(), now() ) " - "ON DUPLICATE KEY UPDATE " - "name=VALUES(name), maxusers=VALUES(maxusers)," - "maxtime=VALUES(maxtime), lastused=VALUES(lastused);" - "END IF;" - + geoquery + - "END"; - this->RunQuery(query); - - if (this->HasProcedure(prefix + "ServerQuit")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ServerQuit")); - query = "CREATE PROCEDURE " + prefix + "ServerQuit(sname_ varchar(255)) " - "BEGIN " - /* 1. - * remove all users on the splitting server from the ison table - */ - "DELETE i FROM `" + prefix + "ison` AS i " - "INNER JOIN `" + prefix + "server` AS s " - "INNER JOIN `" + prefix + "user` AS u " - "WHERE i.nickid = u.nickid " - "AND u.servid = s.id " - "AND s.name = sname_;" - - /* 2. - * remove all users on the splitting server from the user table - */ - "DELETE u FROM `" + prefix + "user` AS u " - "INNER JOIN `" + prefix + "server` AS s " - "WHERE s.id = u.servid " - "AND s.name = sname_;" - - /* 3. - * on the splitting server, set usercount = 0, split_time = now(), online = 'N' - */ - "UPDATE `" + prefix + "server` SET currentusers = 0, split_time = now(), online = 'N' " - "WHERE name = sname_;" - "END;"; // end of the procedure - this->RunQuery(query); - - - if (this->HasProcedure(prefix + "UserQuit")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserQuit")); - query = "CREATE PROCEDURE `" + prefix + "UserQuit`" - "(nick_ varchar(255)) " - "BEGIN " - /* decrease usercount on the server where the user was on */ - "UPDATE `" + prefix + "user` AS `u`, `" + prefix + "server` AS `s` " - "SET s.currentusers = s.currentusers - 1 " - "WHERE u.nick=nick_ AND u.servid = s.id; " - /* remove from all channels where the user was on */ - "DELETE i FROM `" + prefix + "ison` AS i " - "INNER JOIN `" + prefix + "user` as u " - "WHERE u.nick = nick_ " - "AND i.nickid = u.nickid;" - /* remove the user from the user table */ - "DELETE FROM `" + prefix + "user` WHERE nick = nick_; " - "END"; - this->RunQuery(query); - - if (this->HasProcedure(prefix + "ShutDown")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ShutDown")); - query = "CREATE PROCEDURE `" + prefix + "ShutDown`()" - "BEGIN " - "UPDATE `" + prefix + "server` " - "SET currentusers=0, online='N', split_time=now();" - "TRUNCATE TABLE `" + prefix + "user`;" - "TRUNCATE TABLE `" + prefix + "chan`;" - "TRUNCATE TABLE `" + prefix + "ison`;" - "END"; - this->RunQuery(query); - - if (this->HasProcedure(prefix + "JoinUser")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "JoinUser")); - query = "CREATE PROCEDURE `"+ prefix + "JoinUser`" - "(nick_ varchar(255), channel_ varchar(255), modes_ varchar(255)) " - "BEGIN " - "DECLARE cur int;" - "DECLARE max int;" - "INSERT INTO `" + prefix + "ison` (nickid, chanid, modes) " - "SELECT u.nickid, c.chanid, modes_ " - "FROM " + prefix + "user AS u, " + prefix + "chan AS c " - "WHERE u.nick=nick_ AND c.channel=channel_;" - "SELECT count(i.chanid) INTO cur " - "FROM `" + prefix + "chan` AS c, " + prefix + "ison AS i " - "WHERE i.chanid = c.chanid AND c.channel=channel_;" - "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=channel_;" - "IF found_rows() AND cur <= max THEN " - "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=channel_;" - "ELSE " - "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) " - "VALUES ( channel_, cur, now(), now() ) " - "ON DUPLICATE KEY UPDATE " - "name=VALUES(name), maxusers=VALUES(maxusers)," - "maxtime=VALUES(maxtime), lastused=VALUES(lastused);" - "END IF;" - "END"; - this->RunQuery(query); - - if (this->HasProcedure(prefix + "PartUser")) - this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "PartUser")); - query = "CREATE PROCEDURE `" + prefix + "PartUser`" - "(nick_ varchar(255), channel_ varchar(255)) " - "BEGIN " - "DELETE i FROM `" + prefix + "ison` AS i " - "INNER JOIN `" + prefix + "user` AS u " - "INNER JOIN `" + prefix + "chan` AS c " - "WHERE i.nickid = u.nickid " - "AND u.nick = nick_ " - "AND i.chanid = c.chanid " - "AND c.channel = channel_;" - "END"; - this->RunQuery(query); -} diff --git a/modules/irc2sql/utils.cpp b/modules/irc2sql/utils.cpp deleted file mode 100644 index 7debdda9d..000000000 --- a/modules/irc2sql/utils.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * (C) 2013-2025 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "irc2sql.h" - -void IRC2SQL::RunQuery(const SQL::Query &q) -{ - if (sql) - sql->Run(&sqlinterface, q); -} - -void IRC2SQL::GetTables() -{ - TableList.clear(); - ProcedureList.clear(); - EventList.clear(); - if (!sql) - return; - - SQL::Result r = this->sql->RunQuery(this->sql->GetTables(prefix)); - for (int i = 0; i < r.Rows(); ++i) - { - const std::map &map = r.Row(i); - for (std::map::const_iterator it = map.begin(); it != map.end(); ++it) - TableList.push_back(it->second); - } - query = "SHOW PROCEDURE STATUS WHERE `Db` = Database();"; - r = this->sql->RunQuery(query); - for (int i = 0; i < r.Rows(); ++i) - { - ProcedureList.push_back(r.Get(i, "Name")); - } - query = "SHOW EVENTS WHERE `Db` = Database();"; - r = this->sql->RunQuery(query); - for (int i = 0; i < r.Rows(); ++i) - { - EventList.push_back(r.Get(i, "Name")); - } -} - -bool IRC2SQL::HasTable(const Anope::string &table) -{ - for (std::vector::const_iterator it = TableList.begin(); it != TableList.end(); ++it) - if (*it == table) - return true; - return false; -} - -bool IRC2SQL::HasProcedure(const Anope::string &table) -{ - for (std::vector::const_iterator it = ProcedureList.begin(); it != ProcedureList.end(); ++it) - if (*it == table) - return true; - return false; -} - -bool IRC2SQL::HasEvent(const Anope::string &table) -{ - for (std::vector::const_iterator it = EventList.begin(); it != EventList.end(); ++it) - if (*it == table) - return true; - return false; -} diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 249a036ad..56130e004 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -41,9 +41,6 @@ if(NOT WIN32) install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/anoperc DESTINATION ${BIN_DIR} ) - install (PROGRAMS geoipupdate.sh - DESTINATION ${BIN_DIR} - ) endif() # On non-Windows platforms, if RUNGROUP is set, change the permissions of the tools directory diff --git a/src/tools/geoipupdate.sh b/src/tools/geoipupdate.sh deleted file mode 100755 index fbc521318..000000000 --- a/src/tools/geoipupdate.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -# This script is a helper script for the irc2sql module. -# It downloads the configured geoip databases and inserts -# them into existing mysql tables. The tables are created -# by the irc2sql module on the first load. - -# Don't forget to rename this file or your changes -# will be overwritten on the next 'make install' - -############################ -# Config -############################ - - -geoip_database="country" # available options: "country" and "city" -mysql_host="localhost" -mysql_user="anope" -mysql_password="anope" -mysql_database="anope" -prefix="anope_" -die="yes" - -########################### - -# The GeoIP data is created by MaxMind, available from www.maxmind.com. -geoip_country_source="https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip" -geoip_city_source="https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoLiteCity-latest.tar.xz" -geoip_region_source="https://www.maxmind.com/download/geoip/misc/region_codes.csv" - -########################### -LOGIN="--host=$mysql_host --user=$mysql_user --password=$mysql_password $mysql_database" -PARAMS="--delete --local --fields-terminated-by=, --fields-enclosed-by=\" --lines-terminated-by=\n $LOGIN" - -download() { - local url=$1 - local desc=$2 - echo -n " $desc " - wget --progress=dot $url 2>&1 | grep --line-buffered "%" | sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}' - echo -ne " Done\n" -} - - -if test $die = "yes"; then - echo "You have to edit and configure this script first." - exit -fi - - -if test $geoip_database = "country"; then - echo "Downloading..." - download "$geoip_country_source" "Country Database:" - echo "Unpacking..." - unzip -jo GeoIPCountryCSV.zip - rm GeoIPCountryCSV.zip - echo "Converting to UTF-8..." - iconv -f ISO-8859-1 -t UTF-8 GeoIPCountryWhois.csv -o $prefix"geoip_country.csv" - rm GeoIPCountryWhois.csv - echo "Importing..." - mysqlimport --columns=@x,@x,start,end,countrycode,countryname $PARAMS $prefix"geoip_country.csv" - rm $prefix"geoip_country.csv" $prefix"geoip_country6.csv" - echo "Done..." -elif test $geoip_database = "city"; then - echo "Downloading..." - download "$geoip_city_source" "City Database:" - download "$geoip_region_source" "Region Database:" - echo "Unpacking..." - tar -xf GeoLiteCity-latest.tar.xz --strip-components 1 - rm GeoLiteCity-latest.tar.xz - echo "Converting to utf-8..." - iconv -f ISO-8859-1 -t UTF-8 GeoLiteCity-Blocks.csv -o $prefix"geoip_city_blocks.csv" - iconv -f ISO-8859-1 -t UTF-8 GeoLiteCity-Location.csv -o $prefix"geoip_city_location.csv" - iconv -f ISO-8859-1 -t UTF-8 region_codes.csv -o $prefix"geoip_city_region.csv" - rm GeoLiteCity-Blocks.csv GeoLiteCity-Location.csv region_codes.csv - echo "Importing..." - mysqlimport --columns=start,end,locID --ignore-lines=2 $PARAMS $prefix"geoip_city_blocks.csv" - mysqlimport --columns=locID,country,region,city,@x,latitude,longitude,@x,areaCode --ignore-lines=2 $PARAMS $prefix"geoip_city_location.csv" - mysqlimport --columns=country,region,regionname $PARAMS $prefix"geoip_city_region.csv" - rm $prefix"geoip_city_blocks.csv" $prefix"geoip_city_location.csv" $prefix"geoip_city_region.csv" - echo "Done..." -fi