From ef1fcbd1830778e9ba8065fc764105f0b67bff27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sun, 12 May 2019 22:18:42 +0200 Subject: [PATCH] relay: do not overwrite a file if it's not a socket, display an error when the socket can not be created --- src/plugins/relay/relay-config.c | 38 +++++++++++++++++++++++++ src/plugins/relay/relay-config.h | 1 + src/plugins/relay/relay-server.c | 49 +++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c index 904537216..4c0771387 100644 --- a/src/plugins/relay/relay-config.c +++ b/src/plugins/relay/relay-config.c @@ -19,11 +19,15 @@ * along with WeeChat. If not, see . */ +#include #include #include #include #include #include +#include +#include +#include #include "../weechat-plugin.h" #include "relay.h" @@ -545,6 +549,40 @@ relay_config_check_path_length (const char *path) return 1; } +/* + * Checks if a UNIX path is available: it is available if not existing, or + * if a file of type socket already exists. + * + * Returns: + * 0: path is available + * -1: path already exists and is not a socket + * -2: invalid path + */ + +int +relay_config_check_path_available (const char *path) +{ + struct stat buf; + int rc; + + rc = stat (path, &buf); + + /* OK if an existing file is a socket */ + if ((rc == 0) && S_ISSOCK(buf.st_mode)) + return 0; + + /* error if an existing file is NOT a socket */ + if (rc == 0) + return -1; + + /* OK if the file does not exist */ + if (errno == ENOENT) + return 0; + + /* on any other error, the path it considered as not available */ + return -2; +} + /* * Checks if a path is valid. * diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h index 2b5e53000..f28f39a5a 100644 --- a/src/plugins/relay/relay-config.h +++ b/src/plugins/relay/relay-config.h @@ -74,6 +74,7 @@ extern int relay_config_create_option_port_path (const void *pointer, void *data const char *option_name, const char *value); extern int relay_config_check_path_length (const char *path); +extern int relay_config_check_path_available (const char *path); extern int relay_config_init (); extern int relay_config_read (); extern int relay_config_write (); diff --git a/src/plugins/relay/relay-server.c b/src/plugins/relay/relay-server.c index 03e3d0e82..9c2aa1caa 100644 --- a/src/plugins/relay/relay-server.c +++ b/src/plugins/relay/relay-server.c @@ -472,7 +472,7 @@ end: int relay_server_create_socket (struct t_relay_server *server) { - int domain, set, max_clients, addr_size; + int domain, set, max_clients, addr_size, rc; struct sockaddr_in server_addr; struct sockaddr_in6 server_addr6; struct sockaddr_un server_addr_unix; @@ -535,8 +535,32 @@ relay_server_create_socket (struct t_relay_server *server) ptr_addr = &server_addr_unix; addr_size = sizeof (struct sockaddr_un); if (!relay_config_check_path_length (server->path)) + { + weechat_printf (NULL, + _("%s%s: invalid socket path \"%s\""), + weechat_prefix ("error"), RELAY_PLUGIN_NAME, + server->path); return 0; - /* just in case it already exists */ + } + rc = relay_config_check_path_available (server->path); + switch (rc) + { + case -1: + weechat_printf (NULL, + _("%s%s: socket path \"%s\" exists and is not " + "a socket"), + weechat_prefix ("error"), RELAY_PLUGIN_NAME, + server->path); + break; + case -2: + weechat_printf (NULL, + _("%s%s: socket path \"%s\" is invalid"), + weechat_prefix ("error"), RELAY_PLUGIN_NAME, + server->path); + } + if (rc < 0) + return 0; + /* just in case a socket already exists */ unlink (server->path); } @@ -749,11 +773,22 @@ relay_server_new (const char *protocol_string, enum t_relay_protocol protocol, void relay_server_update_path (struct t_relay_server *server, const char *path) { - relay_server_close_socket (server); - free (server->path); - server->path = weechat_string_eval_path_home (path, NULL, NULL, NULL); - server->port = -1; - relay_server_create_socket (server); + char *new_path; + + new_path = weechat_string_eval_path_home (path, NULL, NULL, NULL); + if (!new_path) + return; + + if (strcmp (new_path, server->path) != 0) + { + relay_server_close_socket (server); + free (server->path); + server->path = strdup (new_path); + server->port = -1; + relay_server_create_socket (server); + } + + free (new_path); } /*