summaryrefslogtreecommitdiff
path: root/modules/m_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/m_info.c')
-rw-r--r--modules/m_info.c733
1 files changed, 733 insertions, 0 deletions
diff --git a/modules/m_info.c b/modules/m_info.c
new file mode 100644
index 0000000..c3e81d7
--- /dev/null
+++ b/modules/m_info.c
@@ -0,0 +1,733 @@
+/*
+ * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ * m_info.c: Sends information about the server.
+ *
+ * Copyright (C) 2005 by the past and present ircd coders, and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * $Id$
+ */
+
+#include "stdinc.h"
+#include "list.h"
+#include "channel.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_user.h"
+#include "send.h"
+#include "conf.h"
+#include "parse.h"
+#include "modules.h"
+
+
+static void send_conf_options(struct Client *);
+static void send_birthdate_online_time(struct Client *);
+static void send_info_text(struct Client *);
+
+/*
+ * jdc -- Structure for our configuration value table
+ */
+struct InfoStruct
+{
+ const char *name; /* Displayed variable name */
+ unsigned int output_type; /* See below #defines */
+ void *option; /* Pointer reference to the value */
+ const char *desc; /* ASCII description of the variable */
+};
+
+/* Types for output_type in InfoStruct */
+#define OUTPUT_STRING 0x0001 /* Output option as %s w/ dereference */
+#define OUTPUT_STRING_PTR 0x0002 /* Output option as %s w/out deference */
+#define OUTPUT_DECIMAL 0x0004 /* Output option as decimal (%d) */
+#define OUTPUT_BOOLEAN 0x0008 /* Output option as "ON" or "OFF" */
+#define OUTPUT_BOOLEAN_YN 0x0010 /* Output option as "YES" or "NO" */
+#define OUTPUT_BOOLEAN2 0x0020 /* Output option as "YES/NO/MASKED" */
+
+static const struct InfoStruct info_table[] =
+{
+ /* --[ START OF TABLE ]-------------------------------------------- */
+
+ {
+ "CPATH",
+ OUTPUT_STRING,
+ &ConfigFileEntry.configfile,
+ "Path to Main Configuration File"
+ },
+ {
+ "DPATH",
+ OUTPUT_STRING,
+ &ConfigFileEntry.dpath,
+ "Directory Containing Configuration Files"
+ },
+ {
+ "DLPATH",
+ OUTPUT_STRING,
+ &ConfigFileEntry.dlinefile,
+ "Path to D-line File"
+ },
+ {
+ "KPATH",
+ OUTPUT_STRING,
+ &ConfigFileEntry.klinefile,
+ "Path to K-line File"
+ },
+ {
+ "network_name",
+ OUTPUT_STRING,
+ &ServerInfo.network_name,
+ "Network name"
+ },
+ {
+ "network_desc",
+ OUTPUT_STRING,
+ &ServerInfo.network_desc,
+ "Network description"
+ },
+ {
+ "hub",
+ OUTPUT_BOOLEAN_YN,
+ &ServerInfo.hub,
+ "Server is a hub"
+ },
+ {
+ "use_logging",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigLoggingEntry.use_logging,
+ "Enable logging"
+ },
+ {
+ "restrict_channels",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.restrict_channels,
+ "Only reserved channels are allowed"
+ },
+ {
+ "knock_delay",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.knock_delay,
+ "Delay between a users KNOCK attempts"
+ },
+ {
+ "knock_delay_channel",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.knock_delay_channel,
+ "Delay between KNOCK attempts to a channel"
+ },
+ {
+ "max_chans_per_user",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_chans_per_user,
+ "Maximum number of channels a user can join"
+ },
+ {
+ "max_chans_per_oper",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_chans_per_oper,
+ "Maximum number of channels an oper can join"
+ },
+ {
+ "quiet_on_ban",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.quiet_on_ban,
+ "Banned users may not send text to a channel"
+ },
+ {
+ "max_bans",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_bans,
+ "Total +b/e/I modes allowed in a channel"
+ },
+ {
+ "default_split_user_count",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.default_split_user_count,
+ "Startup value of SPLITUSERS"
+ },
+ {
+ "default_split_server_count",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.default_split_server_count,
+ "Startup value of SPLITNUM"
+ },
+ {
+ "no_create_on_split",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.no_create_on_split,
+ "Disallow creation of channels when split"
+ },
+ {
+ "no_join_on_split",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.no_join_on_split,
+ "Disallow joining channels when split"
+ },
+ {
+ "flatten_links",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.flatten_links,
+ "Flatten /links list"
+ },
+ {
+ "links_delay",
+ OUTPUT_DECIMAL,
+ &ConfigServerHide.links_delay,
+ "Links rehash delay"
+ },
+ {
+ "hidden",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.hidden,
+ "Hide this server from a flattened /links on remote servers"
+ },
+ {
+ "hide_servers",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.hide_servers,
+ "Hide servernames from users"
+ },
+ {
+ "hidden_name",
+ OUTPUT_STRING,
+ &ConfigServerHide.hidden_name,
+ "Server name users see if hide_servers = yes"
+ },
+ {
+ "hide_server_ips",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.hide_server_ips,
+ "Prevent people from seeing server IPs"
+ },
+ {
+ "gline_min_cidr",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_min_cidr,
+ "Minimum required length of a CIDR bitmask for IPv4 G-Lines"
+ },
+ {
+ "gline_min_cidr6",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_min_cidr6,
+ "Minimum required length of a CIDR bitmask for IPv6 G-Lines"
+ },
+ {
+ "invisible_on_connect",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.invisible_on_connect,
+ "Automatically set mode +i on connecting users"
+ },
+ {
+ "kill_chase_time_limit",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.kill_chase_time_limit,
+ "Nick Change Tracker for KILL"
+ },
+ {
+ "hide_spoof_ips",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.hide_spoof_ips,
+ "Hide spoofed IP's"
+ },
+ {
+ "ignore_bogus_ts",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.ignore_bogus_ts,
+ "Ignore bogus timestamps from other servers"
+ },
+ {
+ "disable_auth",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.disable_auth,
+ "Completely disable ident lookups"
+ },
+ {
+ "disable_remote_commands",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.disable_remote,
+ "Prevent users issuing commands on remote servers"
+ },
+ {
+ "tkline_expire_notices",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.tkline_expire_notices,
+ "Show temporary kline/xline expire notices"
+ },
+ {
+ "default_floodcount",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.default_floodcount,
+ "Startup value of FLOODCOUNT"
+ },
+ {
+ "failed_oper_notice",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.failed_oper_notice,
+ "Inform opers if someone /oper's with the wrong password"
+ },
+ {
+ "dots_in_ident",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.dots_in_ident,
+ "Number of permissable dots in an ident"
+ },
+ {
+ "min_nonwildcard",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.min_nonwildcard,
+ "Minimum non-wildcard chars in K/G lines"
+ },
+ {
+ "min_nonwildcard_simple",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.min_nonwildcard_simple,
+ "Minimum non-wildcards in gecos bans"
+ },
+ {
+ "max_accept",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_accept,
+ "Maximum nicknames on accept list"
+ },
+ {
+ "anti_nick_flood",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.anti_nick_flood,
+ "NICK flood protection"
+ },
+ {
+ "max_nick_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_nick_time,
+ "NICK flood protection time interval"
+ },
+ {
+ "max_nick_changes",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_nick_changes,
+ "NICK change threshhold setting"
+ },
+ {
+ "anti_spam_exit_message_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.anti_spam_exit_message_time,
+ "Duration a client must be connected for to have an exit message"
+ },
+ {
+ "ts_warn_delta",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.ts_warn_delta,
+ "Maximum permitted TS delta before displaying a warning"
+ },
+ {
+ "ts_max_delta",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.ts_max_delta,
+ "Maximum permitted TS delta from another server"
+ },
+ {
+ "warn_no_nline",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.warn_no_nline,
+ "Display warning if connecting server lacks N-line"
+ },
+ {
+ "stats_o_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_o_oper_only,
+ "STATS O output is only shown to operators"
+ },
+ {
+ "stats_P_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_P_oper_only,
+ "STATS P is only shown to operators"
+ },
+ {
+ "stats_i_oper_only",
+ OUTPUT_BOOLEAN2,
+ &ConfigFileEntry.stats_i_oper_only,
+ "STATS I output is only shown to operators"
+ },
+ {
+ "stats_k_oper_only",
+ OUTPUT_BOOLEAN2,
+ &ConfigFileEntry.stats_k_oper_only,
+ "STATS K output is only shown to operators"
+ },
+ {
+ "caller_id_wait",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.caller_id_wait,
+ "Minimum delay between notifying UMODE +g users of messages"
+ },
+ {
+ "opers_bypass_callerid",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.opers_bypass_callerid,
+ "Allows IRC operators to message users who are +g (callerid)"
+ },
+ {
+ "pace_wait_simple",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.pace_wait_simple,
+ "Minimum delay between less intensive commands"
+ },
+ {
+ "pace_wait",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.pace_wait,
+ "Minimum delay between uses of certain commands"
+ },
+ {
+ "short_motd",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.short_motd,
+ "Do not show MOTD; only tell clients they should read it"
+ },
+ {
+ "ping_cookie",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.ping_cookie,
+ "Require ping cookies to connect"
+ },
+ {
+ "no_oper_flood",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.no_oper_flood,
+ "Reduce flood control for operators"
+ },
+ {
+ "true_no_oper_flood",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.true_no_oper_flood,
+ "Completely disable flood control for operators"
+ },
+ {
+ "oper_pass_resv",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.oper_pass_resv,
+ "Opers can over-ride RESVs"
+ },
+ {
+ "max_targets",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_targets,
+ "The maximum number of PRIVMSG/NOTICE targets"
+ },
+ {
+ "throttle_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.throttle_time,
+ "Minimum time between client reconnects"
+ },
+ {
+ "glines",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.glines,
+ "G-line (network-wide K-line) support"
+ },
+ {
+ "gline_duration",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_time,
+ "Expiry time for G-lines"
+ },
+
+ {
+ "gline_request_duration",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_request_time,
+ "Expiry time for pending G-lines"
+ },
+
+ /* --[ END OF TABLE ]---------------------------------------------- */
+ {
+ NULL,
+ 0,
+ NULL,
+ 0
+ }
+};
+
+/*
+** m_info()
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static void
+m_info(struct Client *client_p, struct Client *source_p,
+ int parc, char *parv[])
+{
+ static time_t last_used = 0;
+
+ if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name);
+ return;
+ }
+
+ last_used = CurrentTime;
+
+ if (!ConfigFileEntry.disable_remote)
+ if (hunt_server(client_p,source_p, ":%s INFO :%s", 1,
+ parc, parv) != HUNTED_ISME)
+ return;
+
+ send_info_text(source_p);
+}
+
+/*
+** mo_info()
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static void
+mo_info(struct Client *client_p, struct Client *source_p,
+ int parc, char *parv[])
+{
+ if (hunt_server(client_p, source_p, ":%s INFO :%s", 1,
+ parc, parv) != HUNTED_ISME)
+ return;
+
+ send_info_text(source_p);
+}
+
+/*
+** ms_info()
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static void
+ms_info(struct Client *client_p, struct Client *source_p,
+ int parc, char *parv[])
+{
+ if (!IsClient(source_p))
+ return;
+
+ if (hunt_server(client_p, source_p, ":%s INFO :%s", 1,
+ parc, parv) != HUNTED_ISME)
+ return;
+
+ send_info_text(source_p);
+}
+
+/* send_info_text()
+ *
+ * inputs - client pointer to send info text to
+ * output - NONE
+ * side effects - info text is sent to client
+ */
+static void
+send_info_text(struct Client *source_p)
+{
+ const char **text = infotext;
+ char *source, *target;
+
+ sendto_realops_flags(UMODE_SPY, L_ALL,
+ "INFO requested by %s (%s@%s) [%s]",
+ source_p->name, source_p->username,
+ source_p->host, source_p->servptr->name);
+
+ if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) &&
+ HasID(source_p))
+ source = me.id, target = source_p->id;
+ else
+ source = me.name, target = source_p->name;
+
+ while (*text)
+ {
+ const char *line = *text++;
+
+ if (*line == '\0')
+ line = " ";
+
+ sendto_one(source_p, form_str(RPL_INFO),
+ source, target, line);
+ }
+
+ if (HasUMode(source_p, UMODE_OPER))
+ send_conf_options(source_p);
+
+ send_birthdate_online_time(source_p);
+
+ sendto_one(source_p, form_str(RPL_ENDOFINFO),
+ me.name, source_p->name);
+}
+
+/* send_birthdate_online_time()
+ *
+ * inputs - client pointer to send to
+ * output - NONE
+ * side effects - birthdate and online time are sent
+ */
+static void
+send_birthdate_online_time(struct Client *source_p)
+{
+ if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
+ {
+ sendto_one(source_p, ":%s %d %s :On-line since %s",
+ me.id, RPL_INFO, source_p->id,
+ myctime(me.localClient->firsttime));
+ }
+ else
+ {
+ sendto_one(source_p, ":%s %d %s :On-line since %s",
+ me.name, RPL_INFO, source_p->name,
+ myctime(me.localClient->firsttime));
+ }
+}
+
+/* send_conf_options()
+ *
+ * inputs - client pointer to send to
+ * output - NONE
+ * side effects - send config options to client
+ */
+static void
+send_conf_options(struct Client *source_p)
+{
+ const char *from, *to;
+ const struct InfoStruct *iptr = NULL;
+
+ /* Now send them a list of all our configuration options
+ * (mostly from defaults.h and config.h)
+ */
+ if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
+ {
+ from = me.id;
+ to = source_p->id;
+ }
+ else
+ {
+ from = me.name;
+ to = source_p->name;
+ }
+
+ /*
+ * Parse the info_table[] and do the magic.
+ */
+ for (iptr = info_table; iptr->name; ++iptr)
+ {
+ switch (iptr->output_type)
+ {
+ /* For "char *" references */
+ case OUTPUT_STRING:
+ {
+ const char *option = *((char **)iptr->option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ from, RPL_INFO, to,
+ iptr->name, option ? option : "NONE",
+ iptr->desc ? iptr->desc : "<none>");
+ break;
+ }
+
+ /* For "char foo[]" references */
+ case OUTPUT_STRING_PTR:
+ {
+ const char *option = iptr->option;
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ from, RPL_INFO, to,
+ iptr->name, option ? option : "NONE",
+ iptr->desc ? iptr->desc : "<none>");
+ break;
+ }
+
+ /* Output info_table[i].option as a decimal value. */
+ case OUTPUT_DECIMAL:
+ {
+ const int option = *((int *)iptr->option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
+ from, RPL_INFO, to, iptr->name,
+ option, iptr->desc ? iptr->desc : "<none>");
+ break;
+ }
+
+ /* Output info_table[i].option as "ON" or "OFF" */
+ case OUTPUT_BOOLEAN:
+ {
+ const int option = *((int *)iptr->option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ from, RPL_INFO, to,
+ iptr->name, option ? "ON" : "OFF",
+ iptr->desc ? iptr->desc : "<none>");
+
+ break;
+ }
+
+ /* Output info_table[i].option as "YES" or "NO" */
+ case OUTPUT_BOOLEAN_YN:
+ {
+ int option = *((int *)iptr->option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ from, RPL_INFO, to,
+ iptr->name, option ? "YES" : "NO",
+ iptr->desc ? iptr->desc : "<none>");
+ break;
+ }
+
+ case OUTPUT_BOOLEAN2:
+ {
+ int option = *((int *)iptr->option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ from, RPL_INFO, to,
+ iptr->name, option ? ((option == 1) ? "MASK" : "YES") : "NO",
+ iptr->desc ? iptr->desc : "<none>");
+ break;
+ }
+ }
+ }
+
+ sendto_one(source_p, form_str(RPL_INFO),
+ from, to, "");
+}
+
+static struct Message info_msgtab = {
+ "INFO", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
+ { m_unregistered, m_info, ms_info, m_ignore, mo_info, m_ignore }
+};
+
+static void
+module_init(void)
+{
+ mod_add_cmd(&info_msgtab);
+}
+
+static void
+module_exit(void)
+{
+ mod_del_cmd(&info_msgtab);
+}
+
+struct module module_entry = {
+ .node = { NULL, NULL, NULL },
+ .name = NULL,
+ .version = "$Revision$",
+ .handle = NULL,
+ .modinit = module_init,
+ .modexit = module_exit,
+ .flags = 0
+};