unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

proc_io_server.c (6217B)

      1 /************************************************************************
      2  *   UnrealIRCd - Unreal Internet Relay Chat Daemon - src/proc_io_server.c
      3  *   (c) 2022- Bram Matthys and The UnrealIRCd team
      4  *
      5  *   See file AUTHORS in IRC package for additional names of
      6  *   the programmers. 
      7  *
      8  *   This program is free software; you can redistribute it and/or modify
      9  *   it under the terms of the GNU General Public License as published by
     10  *   the Free Software Foundation; either version 1, or (at your option)
     11  *   any later version.
     12  *
     13  *   This program is distributed in the hope that it will be useful,
     14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  *   GNU General Public License for more details.
     17  *
     18  *   You should have received a copy of the GNU General Public License
     19  *   along with this program; if not, write to the Free Software
     20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     21  */
     22 
     23 /** @file
     24  * @brief Inter-process I/O
     25  */
     26 #include "unrealircd.h"
     27 #include <ares.h>
     28 
     29 /* Forward declarations */
     30 CMD_FUNC(procio_status);
     31 CMD_FUNC(procio_modules);
     32 CMD_FUNC(procio_rehash);
     33 CMD_FUNC(procio_exit);
     34 CMD_FUNC(procio_help);
     35 void start_of_control_client_handshake(Client *client);
     36 int procio_accept(Client *client);
     37 
     38 /** Create the unrealircd.ctl socket (server-side) */
     39 void add_proc_io_server(void)
     40 {
     41 	ConfigItem_listen *listener;
     42 
     43 #ifdef _WIN32
     44 	/* Ignore silently on Windows versions older than W10 build 17061 */
     45 	if (!unix_sockets_capable())
     46 		return;
     47 #endif
     48 	listener = safe_alloc(sizeof(ConfigItem_listen));
     49 	safe_strdup(listener->file, CONTROLFILE);
     50 	listener->socket_type = SOCKET_TYPE_UNIX;
     51 	listener->options = LISTENER_CONTROL|LISTENER_NO_CHECK_CONNECT_FLOOD|LISTENER_NO_CHECK_ZLINED;
     52 	listener->start_handshake = start_of_control_client_handshake;
     53 	listener->fd = -1;
     54 	AddListItem(listener, conf_listen);
     55 	if (add_listener(listener) == -1)
     56 		exit(-1);
     57 	CommandAdd(NULL, "STATUS", procio_status, MAXPARA, CMD_CONTROL);
     58 	CommandAdd(NULL, "MODULES", procio_modules, MAXPARA, CMD_CONTROL);
     59 	CommandAdd(NULL, "REHASH", procio_rehash, MAXPARA, CMD_CONTROL);
     60 	CommandAdd(NULL, "EXIT", procio_exit, MAXPARA, CMD_CONTROL);
     61 	CommandAdd(NULL, "HELP", procio_help, MAXPARA, CMD_CONTROL);
     62 	HookAdd(NULL, HOOKTYPE_ACCEPT, -1000000, procio_accept);
     63 }
     64 
     65 int procio_accept(Client *client)
     66 {
     67 	if (client->local->listener->options & LISTENER_CONTROL)
     68 	{
     69 		irccounts.unknown--;
     70 		client->status = CLIENT_STATUS_CONTROL;
     71 		list_del(&client->lclient_node);
     72 		list_add(&client->lclient_node, &control_list);
     73 	}
     74 	return 0;
     75 }
     76 
     77 /** Start of "control channel" client handshake - this is minimal
     78  * @param client	The client
     79  */
     80 void start_of_control_client_handshake(Client *client)
     81 {
     82 	sendto_one(client, NULL, "READY %s %s", me.name, version);
     83 	fd_setselect(client->local->fd, FD_SELECT_READ, read_packet, client);
     84 }
     85 
     86 CMD_FUNC(procio_status)
     87 {
     88 	sendto_one(client, NULL, "REPLY servername %s", me.name);
     89 	sendto_one(client, NULL, "REPLY unrealircd_version %s", version);
     90 	sendto_one(client, NULL, "REPLY libssl_version %s", SSLeay_version(SSLEAY_VERSION));
     91 	sendto_one(client, NULL, "REPLY libsodium_version %s", sodium_version_string());
     92 #ifdef USE_LIBCURL
     93 	sendto_one(client, NULL, "REPLY libcurl_version %s", curl_version());
     94 #endif
     95 	sendto_one(client, NULL, "REPLY libcares_version %s", ares_version(NULL));
     96 	sendto_one(client, NULL, "REPLY libpcre2_version %s", pcre2_version());
     97 #if JANSSON_VERSION_HEX >= 0x020D00
     98 	sendto_one(client, NULL, "REPLY libjansson %s\n", jansson_version_str());
     99 #endif
    100 	sendto_one(client, NULL, "REPLY global_clients %ld", (long)irccounts.clients);
    101 	sendto_one(client, NULL, "REPLY local_clients %ld", (long)irccounts.me_clients);
    102 	sendto_one(client, NULL, "REPLY operators %ld", (long)irccounts.operators);
    103 	sendto_one(client, NULL, "REPLY servers %ld", (long)irccounts.servers);
    104 	sendto_one(client, NULL, "REPLY channels %ld", (long)irccounts.channels);
    105 	sendto_one(client, NULL, "END 0");
    106 }
    107 
    108 extern MODVAR Module *Modules;
    109 CMD_FUNC(procio_modules)
    110 {
    111 	char tmp[1024];
    112 	Module *m;
    113 
    114 	for (m = Modules; m; m = m->next)
    115 	{
    116 		tmp[0] = '\0';
    117 		if (m->flags & MODFLAG_DELAYED)
    118 			strlcat(tmp, "[Unloading] ", sizeof(tmp));
    119 		if (m->options & MOD_OPT_PERM_RELOADABLE)
    120 			strlcat(tmp, "[PERM-BUT-RELOADABLE] ", sizeof(tmp));
    121 		if (m->options & MOD_OPT_PERM)
    122 			strlcat(tmp, "[PERM] ", sizeof(tmp));
    123 		if (!(m->options & MOD_OPT_OFFICIAL))
    124 			strlcat(tmp, "[3RD] ", sizeof(tmp));
    125 		sendto_one(client, NULL, "REPLY %s %s - %s - by %s %s",
    126 		           m->header->name,
    127 		           m->header->version,
    128 		           m->header->description,
    129 		           m->header->author,
    130 		           tmp);
    131 	}
    132 	sendto_one(client, NULL, "END 0");
    133 }
    134 
    135 CMD_FUNC(procio_rehash)
    136 {
    137 	if (loop.rehashing)
    138 	{
    139 		sendto_one(client, NULL, "REPLY ERROR: A rehash is already in progress");
    140 		sendto_one(client, NULL, "END 1");
    141 		return;
    142 	}
    143 	
    144 
    145 	if (parv[1] && !strcmp(parv[1], "-tls"))
    146 	{
    147 		int ret;
    148 		SetMonitorRehash(client);
    149 		unreal_log(ULOG_INFO, "config", "CONFIG_RELOAD_TLS", NULL, "Reloading all TLS related data (./unrealircd reloadtls)");
    150 		ret = reinit_tls();
    151 		sendto_one(client, NULL, "END %d", ret == 0 ? -1 : 0);
    152 		ClearMonitorRehash(client);
    153 	} else {
    154 		SetMonitorRehash(client);
    155 		unreal_log(ULOG_INFO, "config", "CONFIG_RELOAD", client, "Rehashing server configuration file [./unrealircd rehash]");
    156 		request_rehash(client);
    157 		/* completion will go via procio_post_rehash() */
    158 	}
    159 }
    160 
    161 CMD_FUNC(procio_exit)
    162 {
    163 	sendto_one(client, NULL, "END 0");
    164 	exit_client(client, NULL, "");
    165 }
    166 
    167 CMD_FUNC(procio_help)
    168 {
    169 	sendto_one(client, NULL, "REPLY Commands available:");
    170 	sendto_one(client, NULL, "REPLY EXIT");
    171 	sendto_one(client, NULL, "REPLY HELP");
    172 	sendto_one(client, NULL, "REPLY REHASH");
    173 	sendto_one(client, NULL, "REPLY STATUS");
    174 	sendto_one(client, NULL, "REPLY MODULES");
    175 	sendto_one(client, NULL, "END 0");
    176 }
    177 
    178 /** Called upon REHASH completion (with or without failure) */
    179 void procio_post_rehash(int failure)
    180 {
    181 	Client *client;
    182 
    183 	list_for_each_entry(client, &control_list, lclient_node)
    184 	{
    185 		if (IsMonitorRehash(client))
    186 		{
    187 			sendto_one(client, NULL, "END %d", failure);
    188 			ClearMonitorRehash(client);
    189 		}
    190 	}
    191 }