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 }