summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.adoc1
-rw-r--r--doc/en/weechat_dev.en.adoc1
-rw-r--r--doc/fr/weechat_dev.fr.adoc1
-rw-r--r--doc/ja/weechat_dev.ja.adoc2
-rw-r--r--doc/sr/weechat_dev.sr.adoc2
-rw-r--r--po/srcfiles.cmake2
-rw-r--r--src/plugins/relay/CMakeLists.txt1
-rw-r--r--src/plugins/relay/api/relay-api-protocol.c2
-rw-r--r--src/plugins/relay/api/relay-api.c12
-rw-r--r--src/plugins/relay/irc/relay-irc.c6
-rw-r--r--src/plugins/relay/relay-buffer.c12
-rw-r--r--src/plugins/relay/relay-client.c55
-rw-r--r--src/plugins/relay/relay-client.h22
-rw-r--r--src/plugins/relay/relay-command.c361
-rw-r--r--src/plugins/relay/relay-completion.c33
-rw-r--r--src/plugins/relay/relay-config.c234
-rw-r--r--src/plugins/relay/relay-config.h4
-rw-r--r--src/plugins/relay/relay-info.c4
-rw-r--r--src/plugins/relay/relay-remote.c677
-rw-r--r--src/plugins/relay/relay-remote.h87
-rw-r--r--src/plugins/relay/relay.c35
-rw-r--r--src/plugins/relay/relay.h20
-rw-r--r--src/plugins/relay/weechat/relay-weechat-protocol.c4
-rw-r--r--src/plugins/relay/weechat/relay-weechat.c6
-rw-r--r--tests/unit/plugins/relay/api/test-relay-api.cpp2
25 files changed, 1487 insertions, 99 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc
index be23f30a3..687fd203c 100644
--- a/ChangeLog.adoc
+++ b/ChangeLog.adoc
@@ -41,6 +41,7 @@ New features::
* irc: add server option "autojoin_delay" (delay before autojoin), use option "command_delay" before execution of the command (issue #862)
* relay: add "api" protocol (HTTP REST API), add option relay.look.display_clients, change option type relay.look.auto_open_buffer to string, rename option relay.weechat.commands to relay.network.commands, add option relay.network.time_window (issue #2066)
* relay: add support of websocket extension "permessage-deflate" (issue #1549)
+ * relay: add command `/remote` to manage remote WeeChat relay servers and connect to them (issue #2066)
* script: add option `enable` in command `/script`
* script: add info "script_loaded"
diff --git a/doc/en/weechat_dev.en.adoc b/doc/en/weechat_dev.en.adoc
index 9271aa558..c9bf13695 100644
--- a/doc/en/weechat_dev.en.adoc
+++ b/doc/en/weechat_dev.en.adoc
@@ -335,6 +335,7 @@ WeeChat "core" is located in following directories:
|       relay-info.c | Relay info/infolists/hdata.
|       relay-network.c | Network functions for relay.
|       relay-raw.c | Relay raw buffer.
+|       relay-remote.c | Relay remote.
|       relay-server.c | Relay server.
|       relay-upgrade.c | Save/restore of relay data when upgrading WeeChat.
|       relay-websocket.c | WebSocket server functions (RFC 6455).
diff --git a/doc/fr/weechat_dev.fr.adoc b/doc/fr/weechat_dev.fr.adoc
index 2e34f1073..f7a21cdbf 100644
--- a/doc/fr/weechat_dev.fr.adoc
+++ b/doc/fr/weechat_dev.fr.adoc
@@ -337,6 +337,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|       relay-info.c | Info/infolists/hdata pour Relay.
|       relay-network.c | Fonctions de réseau pour Relay.
|       relay-raw.c | Tampon des données brutes de Relay.
+|       relay-remote.c | Relai distant.
|       relay-server.c | Serveur Relay.
|       relay-upgrade.c | Sauvegarde/restauration des données Relay lors de la mise à jour de WeeChat.
|       relay-websocket.c | Fonctions pour le serveur WebSocket (RFC 6455).
diff --git a/doc/ja/weechat_dev.ja.adoc b/doc/ja/weechat_dev.ja.adoc
index 85c5fb4ba..65f820d67 100644
--- a/doc/ja/weechat_dev.ja.adoc
+++ b/doc/ja/weechat_dev.ja.adoc
@@ -357,6 +357,8 @@ WeeChat "core" は以下のディレクトリに配置されています:
|       relay-info.c | relay の情報/インフォリスト/hdata
|       relay-network.c | relay 用のネットワーク関数
|       relay-raw.c | relay 生バッファ
+// TRANSLATION MISSING
+|       relay-remote.c | Relay remote.
|       relay-server.c | relay サーバ
|       relay-upgrade.c | WeeChat をアップグレードする際にデータを保存/回復
|       relay-websocket.c | リレー用の websocket サーバ関数 (RFC 6455)
diff --git a/doc/sr/weechat_dev.sr.adoc b/doc/sr/weechat_dev.sr.adoc
index 745a38118..630ebf3c2 100644
--- a/doc/sr/weechat_dev.sr.adoc
+++ b/doc/sr/weechat_dev.sr.adoc
@@ -337,6 +337,8 @@ WeeChat „језгро” се налази у следећим директо
|       relay-info.c | Релеј info/infolists/hdata.
|       relay-network.c | Мрежне функције за релеј.
|       relay-raw.c | Релеј сирови бафер.
+// TRANSLATION MISSING
+|       relay-remote.c | Relay remote.
|       relay-server.c | Релеј сервер.
|       relay-upgrade.c | Save/restore of relay data when upgrading WeeChat.
|       relay-websocket.c | WebSocket сервер функције (RFC 6455).
diff --git a/po/srcfiles.cmake b/po/srcfiles.cmake
index 60db4f36e..3b68e623a 100644
--- a/po/srcfiles.cmake
+++ b/po/srcfiles.cmake
@@ -374,6 +374,8 @@ SET(WEECHAT_SOURCES
./src/plugins/relay/relay-network.h
./src/plugins/relay/relay-raw.c
./src/plugins/relay/relay-raw.h
+./src/plugins/relay/relay-remote.c
+./src/plugins/relay/relay-remote.h
./src/plugins/relay/relay-server.c
./src/plugins/relay/relay-server.h
./src/plugins/relay/relay-upgrade.c
diff --git a/src/plugins/relay/CMakeLists.txt b/src/plugins/relay/CMakeLists.txt
index e467c384d..724191947 100644
--- a/src/plugins/relay/CMakeLists.txt
+++ b/src/plugins/relay/CMakeLists.txt
@@ -29,6 +29,7 @@ set(RELAY_SRC
relay-info.c relay-info.h
relay-network.c relay-network.h
relay-raw.c relay-raw.h
+ relay-remote.c relay-remote.h
relay-server.c relay-server.h
relay-upgrade.c relay-upgrade.h
relay-websocket.c relay-websocket.h
diff --git a/src/plugins/relay/api/relay-api-protocol.c b/src/plugins/relay/api/relay-api-protocol.c
index ac3b8f13e..265e0df3b 100644
--- a/src/plugins/relay/api/relay-api-protocol.c
+++ b/src/plugins/relay/api/relay-api-protocol.c
@@ -808,7 +808,7 @@ relay_api_protocol_recv_http (struct t_relay_client *client)
{ NULL, NULL, 0, 0, 0, NULL },
};
- if (!client->http_req || RELAY_CLIENT_HAS_ENDED(client))
+ if (!client->http_req || RELAY_STATUS_HAS_ENDED(client->status))
return;
/* display debug message */
diff --git a/src/plugins/relay/api/relay-api.c b/src/plugins/relay/api/relay-api.c
index 054ddbf29..e20e147f7 100644
--- a/src/plugins/relay/api/relay-api.c
+++ b/src/plugins/relay/api/relay-api.c
@@ -208,14 +208,16 @@ relay_api_alloc_with_infolist (struct t_relay_client *client,
RELAY_API_DATA(client, sync_colors) = weechat_infolist_integer (
infolist, "sync_colors");
- if (!RELAY_CLIENT_HAS_ENDED(client) && RELAY_API_DATA(client, sync_enabled))
+ if (!RELAY_STATUS_HAS_ENDED(client->status)
+ && RELAY_API_DATA(client, sync_enabled))
+ {
relay_api_hook_signals (client);
+ }
}
/*
- * Returns the client initial status: it is always "waiting_auth" for API
- * protocol because we always expect the "init" command, even without any
- * password.
+ * Returns the client initial status: it is always "authenticating" for API
+ * protocol because we always expect the client to authenticate.
*/
enum t_relay_status
@@ -224,7 +226,7 @@ relay_api_get_initial_status (struct t_relay_client *client)
/* make C compiler happy */
(void) client;
- return RELAY_STATUS_WAITING_AUTH;
+ return RELAY_STATUS_AUTHENTICATING;
}
/*
diff --git a/src/plugins/relay/irc/relay-irc.c b/src/plugins/relay/irc/relay-irc.c
index 0c406488b..c0885511c 100644
--- a/src/plugins/relay/irc/relay-irc.c
+++ b/src/plugins/relay/irc/relay-irc.c
@@ -2298,7 +2298,7 @@ relay_irc_alloc_with_infolist (struct t_relay_client *client,
}
/*
- * Returns the client initial status: it can be "waiting_auth" or "connected",
+ * Returns the client initial status: it can be "authenticating" or "connected",
* depending if a password is expected or not.
*/
@@ -2306,7 +2306,7 @@ enum t_relay_status
relay_irc_get_initial_status (struct t_relay_client *client)
{
return (RELAY_IRC_DATA(client, password_ok)) ?
- RELAY_STATUS_CONNECTED : RELAY_STATUS_WAITING_AUTH;
+ RELAY_STATUS_CONNECTED : RELAY_STATUS_AUTHENTICATING;
}
/*
@@ -2360,7 +2360,7 @@ relay_irc_add_to_infolist (struct t_infolist_item *item,
if (!item || !client)
return 0;
- if (!RELAY_CLIENT_HAS_ENDED(client) && force_disconnected_state)
+ if (!RELAY_STATUS_HAS_ENDED(client->status) && force_disconnected_state)
{
if (!weechat_infolist_new_var_integer (item, "connected", 0))
return 0;
diff --git a/src/plugins/relay/relay-buffer.c b/src/plugins/relay/relay-buffer.c
index 1cb3c1349..8476504ef 100644
--- a/src/plugins/relay/relay-buffer.c
+++ b/src/plugins/relay/relay-buffer.c
@@ -77,11 +77,11 @@ relay_buffer_refresh (const char *hotlist)
weechat_color ("lightgreen"),
/* disconnect */
(client_selected
- && !RELAY_CLIENT_HAS_ENDED(client_selected)) ?
+ && !RELAY_STATUS_HAS_ENDED(client_selected->status)) ?
_(" [D] Disconnect") : "",
/* remove */
(client_selected
- && RELAY_CLIENT_HAS_ENDED(client_selected)) ?
+ && RELAY_STATUS_HAS_ENDED(client_selected->status)) ?
_(" [R] Remove") : "",
/* purge old */
_(" [P] Purge finished"),
@@ -98,7 +98,7 @@ relay_buffer_refresh (const char *hotlist)
weechat_config_string (relay_config_color_text_bg));
snprintf (str_status, sizeof (str_status),
- "%s", _(relay_client_status_string[ptr_client->status]));
+ "%s", _(relay_status_string[ptr_client->status]));
length = weechat_utf8_strlen_screen (str_status);
if (length < 20)
{
@@ -191,7 +191,7 @@ relay_buffer_input_cb (const void *pointer, void *data,
/* disconnect client */
if (weechat_strcmp (input_data, "d") == 0)
{
- if (client && !RELAY_CLIENT_HAS_ENDED(client))
+ if (client && !RELAY_STATUS_HAS_ENDED(client->status))
{
relay_client_disconnect (client);
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
@@ -204,7 +204,7 @@ relay_buffer_input_cb (const void *pointer, void *data,
while (ptr_client)
{
next_client = ptr_client->next_client;
- if (RELAY_CLIENT_HAS_ENDED(ptr_client))
+ if (RELAY_STATUS_HAS_ENDED(ptr_client->status))
relay_client_free (ptr_client);
ptr_client = next_client;
}
@@ -218,7 +218,7 @@ relay_buffer_input_cb (const void *pointer, void *data,
/* remove client */
else if (weechat_strcmp (input_data, "r") == 0)
{
- if (client && RELAY_CLIENT_HAS_ENDED(client))
+ if (client && RELAY_STATUS_HAS_ENDED(client->status))
{
relay_client_free (client);
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c
index a5b8eac0b..312b67404 100644
--- a/src/plugins/relay/relay-client.c
+++ b/src/plugins/relay/relay-client.c
@@ -49,15 +49,6 @@
#include "weechat/relay-weechat.h"
-char *relay_client_status_string[] = /* status strings for display */
-{ N_("connecting"), N_("waiting auth"),
- N_("connected"), N_("auth failed"), N_("disconnected")
-};
-char *relay_client_status_name[] = /* name of status (for signal/info) */
-{ "connecting", "waiting_auth",
- "connected", "auth_failed", "disconnected"
-};
-
char *relay_client_data_type_string[] = /* strings for data types */
{ "text", "binary", "http" };
@@ -144,30 +135,6 @@ relay_client_search_by_id (int id)
}
/*
- * Searches for a client status.
- *
- * Returns index of status in enum t_relay_status, -1 if status is not found.
- */
-
-int
-relay_client_status_search (const char *name)
-{
- int i;
-
- if (!name)
- return -1;
-
- for (i = 0; i < RELAY_NUM_STATUS; i++)
- {
- if (strcmp (relay_client_status_name[i], name) == 0)
- return i;
- }
-
- /* status not found */
- return -1;
-}
-
-/*
* Returns the number of active clients (connecting or connected) on a given
* server port.
*/
@@ -183,7 +150,7 @@ relay_client_count_active_by_port (int server_port)
ptr_client = ptr_client->next_client)
{
if ((ptr_client->server_port == server_port)
- && !RELAY_CLIENT_HAS_ENDED(ptr_client))
+ && !RELAY_STATUS_HAS_ENDED(ptr_client->status))
{
count++;
}
@@ -203,7 +170,7 @@ relay_client_send_signal (struct t_relay_client *client)
snprintf (signal, sizeof (signal),
"relay_client_%s",
- relay_client_status_name[client->status]);
+ relay_status_name[client->status]);
weechat_hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_POINTER, client);
}
@@ -761,7 +728,7 @@ relay_client_recv_cb (const void *pointer, void *data, int fd)
* data can be received only during authentication
* or if connected (authentication was OK)
*/
- if ((client->status != RELAY_STATUS_WAITING_AUTH)
+ if ((client->status != RELAY_STATUS_AUTHENTICATING)
&& (client->status != RELAY_STATUS_CONNECTED))
{
return WEECHAT_RC_OK;
@@ -1361,7 +1328,7 @@ relay_client_timer_cb (const void *pointer, void *data, int remaining_calls)
{
ptr_next_client = ptr_client->next_client;
- if (RELAY_CLIENT_HAS_ENDED(ptr_client))
+ if (RELAY_STATUS_HAS_ENDED(ptr_client->status))
{
if ((purge_delay >= 0)
&& (current_time >= ptr_client->end_time + (purge_delay * 60)))
@@ -1377,7 +1344,7 @@ relay_client_timer_cb (const void *pointer, void *data, int remaining_calls)
/* disconnect clients not authenticated */
if ((auth_timeout > 0)
- && (ptr_client->status == RELAY_STATUS_WAITING_AUTH))
+ && (ptr_client->status == RELAY_STATUS_AUTHENTICATING))
{
if (current_time - ptr_client->start_time > auth_timeout)
{
@@ -1576,7 +1543,7 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
RELAY_COLOR_CHAT_CLIENT,
new_client->desc,
RELAY_COLOR_CHAT,
- _(relay_client_status_string[new_client->status]));
+ _(relay_status_string[new_client->status]));
}
else
{
@@ -1588,7 +1555,7 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
RELAY_COLOR_CHAT_CLIENT,
new_client->desc,
RELAY_COLOR_CHAT,
- _(relay_client_status_string[new_client->status]));
+ _(relay_status_string[new_client->status]));
}
}
@@ -1818,7 +1785,7 @@ relay_client_set_status (struct t_relay_client *client,
client->desc,
RELAY_COLOR_CHAT);
}
- else if (RELAY_CLIENT_HAS_ENDED(client))
+ else if (RELAY_STATUS_HAS_ENDED(client->status))
{
client->end_time = time (NULL);
@@ -2069,7 +2036,7 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "desc", client->desc))
return 0;
- if (!RELAY_CLIENT_HAS_ENDED(client) && force_disconnected_state)
+ if (!RELAY_STATUS_HAS_ENDED(client->status) && force_disconnected_state)
{
if (!weechat_infolist_new_var_integer (ptr_item, "sock", -1))
return 0;
@@ -2156,7 +2123,7 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "real_ip", client->real_ip))
return 0;
- if (!weechat_infolist_new_var_string (ptr_item, "status_string", relay_client_status_string[client->status]))
+ if (!weechat_infolist_new_var_string (ptr_item, "status_string", relay_status_string[client->status]))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "protocol", client->protocol))
return 0;
@@ -2244,7 +2211,7 @@ relay_client_print_log ()
weechat_log_printf (" real_ip . . . . . . . . . : '%s'", ptr_client->real_ip);
weechat_log_printf (" status. . . . . . . . . . : %d (%s)",
ptr_client->status,
- relay_client_status_string[ptr_client->status]);
+ relay_status_string[ptr_client->status]);
weechat_log_printf (" protocol. . . . . . . . . : %d (%s)",
ptr_client->protocol,
relay_protocol_string[ptr_client->protocol]);
diff --git a/src/plugins/relay/relay-client.h b/src/plugins/relay/relay-client.h
index 5978181fd..b2b5a7661 100644
--- a/src/plugins/relay/relay-client.h
+++ b/src/plugins/relay/relay-client.h
@@ -27,19 +27,6 @@
struct t_relay_server;
struct t_relay_http_request;
-/* relay status */
-
-enum t_relay_status
-{
- RELAY_STATUS_CONNECTING = 0, /* connecting to client */
- RELAY_STATUS_WAITING_AUTH, /* waiting AUTH from client */
- RELAY_STATUS_CONNECTED, /* connected to client */
- RELAY_STATUS_AUTH_FAILED, /* AUTH failed with client */
- RELAY_STATUS_DISCONNECTED, /* disconnected from client */
- /* number of relay status */
- RELAY_NUM_STATUS,
-};
-
/* type of data exchanged with client */
enum t_relay_client_data_type
@@ -75,12 +62,6 @@ enum t_relay_client_msg_type
RELAY_NUM_CLIENT_MSG_TYPES,
};
-/* macros for status */
-
-#define RELAY_CLIENT_HAS_ENDED(client) \
- ((client->status == RELAY_STATUS_AUTH_FAILED) || \
- (client->status == RELAY_STATUS_DISCONNECTED))
-
/* fake send function (for tests) */
typedef void (t_relay_fake_send_func)(void *client,
@@ -146,8 +127,6 @@ struct t_relay_client
struct t_relay_client *next_client;/* link to next client */
};
-extern char *relay_client_status_string[];
-extern char *relay_client_status_name[];
extern char *relay_client_msg_type_string[];
extern struct t_relay_client *relay_clients;
extern struct t_relay_client *last_relay_client;
@@ -156,7 +135,6 @@ extern int relay_client_count;
extern int relay_client_valid (struct t_relay_client *client);
extern struct t_relay_client *relay_client_search_by_number (int number);
extern struct t_relay_client *relay_client_search_by_id (int id);
-extern int relay_client_status_search (const char *name);
extern int relay_client_count_active_by_port (int server_port);
extern void relay_client_set_desc (struct t_relay_client *client);
extern void relay_client_recv_buffer (struct t_relay_client *client,
diff --git a/src/plugins/relay/relay-command.c b/src/plugins/relay/relay-command.c
index ce3142c91..edcbdffab 100644
--- a/src/plugins/relay/relay-command.c
+++ b/src/plugins/relay/relay-command.c
@@ -1,5 +1,5 @@
/*
- * relay-command.c - relay command
+ * relay-command.c - relay commands
*
* Copyright (C) 2003-2024 Sébastien Helleu <flashcode@flashtux.org>
*
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <time.h>
#include "../weechat-plugin.h"
@@ -30,6 +31,7 @@
#include "relay-config.h"
#include "relay-network.h"
#include "relay-raw.h"
+#include "relay-remote.h"
#include "relay-server.h"
@@ -49,7 +51,7 @@ relay_command_client_list (int full)
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
- if (!full && RELAY_CLIENT_HAS_ENDED(ptr_client))
+ if (!full && RELAY_STATUS_HAS_ENDED(ptr_client->status))
continue;
if (num_found == 0)
@@ -89,7 +91,7 @@ relay_command_client_list (int full)
ptr_client->desc,
RELAY_COLOR_CHAT,
weechat_color (weechat_config_string (relay_config_color_status[ptr_client->status])),
- relay_client_status_string[ptr_client->status],
+ relay_status_string[ptr_client->status],
RELAY_COLOR_CHAT,
date_start,
date_activity,
@@ -104,7 +106,7 @@ relay_command_client_list (int full)
ptr_client->desc,
RELAY_COLOR_CHAT,
weechat_color (weechat_config_string (relay_config_color_status[ptr_client->status])),
- relay_client_status_string[ptr_client->status],
+ relay_status_string[ptr_client->status],
RELAY_COLOR_CHAT,
date_start);
}
@@ -387,6 +389,309 @@ relay_command_relay (const void *pointer, void *data,
}
/*
+ * Displays a relay remote.
+ */
+
+void
+relay_command_display_remote (struct t_relay_remote *remote, int with_detail)
+{
+ if (with_detail)
+ {
+ weechat_printf (NULL, "");
+ weechat_printf (NULL, _("Remote: %s"), remote->name);
+ weechat_printf (NULL, " url. . . . . . . . . : '%s'",
+ weechat_config_string (remote->options[RELAY_REMOTE_OPTION_URL]));
+ weechat_printf (NULL, " password . . . . . . : '%s'",
+ weechat_config_string (remote->options[RELAY_REMOTE_OPTION_PASSWORD]));
+ weechat_printf (NULL, " totp_secret. . . . . : '%s'",
+ weechat_config_string (remote->options[RELAY_REMOTE_OPTION_TOTP_SECRET]));
+ }
+ else
+ {
+ weechat_printf (
+ NULL,
+ " %s: %s",
+ remote->name,
+ weechat_config_string (remote->options[RELAY_REMOTE_OPTION_URL]));
+ }
+}
+
+/*
+ * Callback for command "/remote".
+ */
+
+int
+relay_command_remote (const void *pointer, void *data,
+ struct t_gui_buffer *buffer, int argc,
+ char **argv, char **argv_eol)
+{
+ struct t_relay_remote *ptr_remote, *ptr_remote2;
+ int i, detailed_list, one_remote_found;
+ const char *ptr_password, *ptr_totp_secret;
+ char *remote_name;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) buffer;
+
+ if ((argc == 1)
+ || (weechat_strcmp (argv[1], "list") == 0)
+ || (weechat_strcmp (argv[1], "listfull") == 0))
+ {
+ /* list remotes */
+ remote_name = NULL;
+ detailed_list = 0;
+ for (i = 1; i < argc; i++)
+ {
+ if (weechat_strcmp (argv[i], "list") == 0)
+ continue;
+ if (weechat_strcmp (argv[i], "listfull") == 0)
+ {
+ detailed_list = 1;
+ continue;
+ }
+ if (!remote_name)
+ remote_name = argv[i];
+ }
+ if (remote_name)
+ {
+ one_remote_found = 0;
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ if (strstr (ptr_remote->name, remote_name))
+ {
+ if (!one_remote_found)
+ {
+ weechat_printf (NULL, "");
+ weechat_printf (NULL,
+ _("Relay remotes with \"%s\":"),
+ remote_name);
+ }
+ one_remote_found = 1;
+ relay_command_display_remote (ptr_remote, detailed_list);
+ }
+ }
+ if (!one_remote_found)
+ {
+ weechat_printf (NULL,
+ _("No relay remote found with \"%s\""),
+ remote_name);
+ }
+ }
+ else
+ {
+ if (relay_remotes)
+ {
+ weechat_printf (NULL, "");
+ weechat_printf (NULL, _("All relay remotes:"));
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ relay_command_display_remote (ptr_remote, detailed_list);
+ }
+ }
+ else
+ weechat_printf (NULL, _("No relay remote"));
+ }
+ return WEECHAT_RC_OK;
+ }
+
+ if (weechat_strcmp (argv[1], "add") == 0)
+ {
+ WEECHAT_COMMAND_MIN_ARGS(4, "add");
+
+ ptr_remote = relay_remote_search (argv[2]);
+ if (ptr_remote)
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: remote \"%s\" already exists, can't add it!"),
+ weechat_prefix ("error"), RELAY_PLUGIN_NAME, ptr_remote->name);
+ return WEECHAT_RC_OK;
+ }
+
+ if (!relay_remote_name_valid (argv[2]))
+ {
+ weechat_printf (NULL,
+ _("%s%s: invalid remote name: \"%s\""),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[2]);
+ return WEECHAT_RC_OK;
+ }
+
+
+ if (!relay_remote_url_valid (argv[3]))
+ {
+ weechat_printf (NULL,
+ _("%s%s: invalid remote URL: \"%s\""),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[3]);
+ return WEECHAT_RC_OK;
+ }
+
+ ptr_password = NULL;
+ ptr_totp_secret = NULL;
+
+ for (i = 4; i < argc; i++)
+ {
+ if (strncmp (argv[i], "-password=", 10) == 0)
+ {
+ ptr_password = argv[i] + 10;
+ }
+ else if (strncmp (argv[i], "-totp_secret=", 13) == 0)
+ {
+ ptr_totp_secret = argv[i] + 13;
+ }
+ else
+ {
+ weechat_printf (NULL,
+ _("%s%s: invalid remote option: \"%s\""),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[i]);
+ return WEECHAT_RC_OK;
+ }
+ }
+
+ ptr_remote = relay_remote_new (
+ argv[2],
+ argv[3],
+ (ptr_password) ? ptr_password : "",
+ (ptr_totp_secret) ? ptr_totp_secret : "");
+
+ if (ptr_remote)
+ {
+ weechat_printf (NULL, _("Remote \"%s\" created"), argv[2]);
+ }
+ else
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: failed to create remote \"%s\""),
+ weechat_prefix ("error"), RELAY_PLUGIN_NAME,
+ argv[2]);
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ if (weechat_strcmp (argv[1], "connect") == 0)
+ {
+ WEECHAT_COMMAND_MIN_ARGS(3, "connect");
+
+ ptr_remote = relay_remote_search (argv[2]);
+ if (!ptr_remote)
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: remote \"%s\" not found for \"%s\" command"),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[2],
+ "remote connect");
+ return WEECHAT_RC_OK;
+ }
+
+ WEECHAT_COMMAND_ERROR;
+ }
+
+ if (weechat_strcmp (argv[1], "rename") == 0)
+ {
+ WEECHAT_COMMAND_MIN_ARGS(4, "rename");
+
+ /* look for remote by name */
+ ptr_remote = relay_remote_search (argv[2]);
+ if (!ptr_remote)
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: remote \"%s\" not found for \"%s\" command"),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[2],
+ "remote rename");
+ return WEECHAT_RC_OK;
+ }
+
+ /* check if target name already exists */
+ ptr_remote2 = relay_remote_search (argv[3]);
+ if (ptr_remote2)
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: remote \"%s\" already exists for \"%s\" command"),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ ptr_remote2->name,
+ "server rename");
+ return WEECHAT_RC_OK;
+ }
+
+ /* rename remote */
+ if (relay_remote_rename (ptr_remote, argv[3]))
+ {
+ weechat_printf (
+ NULL,
+ _("%s: remote \"%s\" has been renamed to \"%s\""),
+ RELAY_PLUGIN_NAME,
+ argv[2],
+ argv[3]);
+ return WEECHAT_RC_OK;
+ }
+
+ WEECHAT_COMMAND_ERROR;
+ }
+
+ if (weechat_strcmp (argv[1], "del") == 0)
+ {
+ WEECHAT_COMMAND_MIN_ARGS(3, "del");
+
+ /* look for remote by name */
+ ptr_remote = relay_remote_search (argv[2]);
+ if (!ptr_remote)
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: remote \"%s\" not found for \"%s\" command"),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[2],
+ "remote del");
+ return WEECHAT_RC_OK;
+ }
+ if (!RELAY_STATUS_HAS_ENDED(ptr_remote->status))
+ {
+ weechat_printf (
+ NULL,
+ _("%s%s: you can not delete remote \"%s\" because you are "
+ "connected to. Try \"/remote disconnect %s\" before."),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME,
+ argv[2],
+ argv[2]);
+ return WEECHAT_RC_OK;
+ }
+ remote_name = strdup (ptr_remote->name);
+ relay_remote_free (ptr_remote);
+ weechat_printf (
+ NULL,
+ _("%s: remote \"%s\" has been deleted"),
+ RELAY_PLUGIN_NAME,
+ (remote_name) ? remote_name : "???");
+ if (remote_name)
+ free (remote_name);
+
+ return WEECHAT_RC_OK;
+ }
+
+ WEECHAT_COMMAND_ERROR;
+}
+
+/*
* Hooks command.
*/
@@ -435,8 +740,13 @@ relay_command_init ()
"",
N_("The \"irc\" protocol allows any IRC client (including WeeChat "
"itself) to connect on the port."),
- N_("The \"weechat\" protocol allows a remote interface to connect on "
- "the port, see the list here: https://weechat.org/about/interfaces/"),
+ N_("The \"api\" protocol allows a remote interface (including "
+ "WeeChat itself) to connect on the port."),
+ N_("The \"weechat\" protocol allows a remote interface "
+ "(but not WeeChat itself) to connect on the port."),
+ "",
+ N_("The list of remote interfaces is here: "
+ "https://weechat.org/about/interfaces/"),
"",
N_("Without argument, this command opens buffer with list of relay "
"clients."),
@@ -462,4 +772,43 @@ relay_command_init ()
" || raw"
" || tlscertkey",
&relay_command_relay, NULL, NULL);
+ weechat_hook_command (
+ "remote",
+ N_("control of remote relay servers"),
+ /* TRANSLATORS: only text between angle brackets (eg: "<name>") must be translated */
+ N_("list|listfull [<name>]"
+ " || add <name> <url> [-<option>[=<value>]]"
+ " || connect <name>"
+ " || rename <name> <new_name>"
+ " || del <name>"),
+ WEECHAT_CMD_ARGS_DESC(
+ N_("raw[list]: list remote relay servers"),
+ N_("raw[listfull]: list remote relay servers (verbose)"),
+ N_("raw[add]: add a remote relay server"),
+ N_("name: name of remote relay server, for internal and display use; "
+ "this name is used to connect to the server and to set server "
+ "options: relay.remote.name.xxx"),
+ N_("url: URL of the remote, format is https://example.com:9000 "
+ "or http://example.com:9000 (plain-text connection, not recommended)"),
+ N_("option: set option for remote: password or totp_secret"),
+ N_("raw[connect]: connect to a remote relay server"),
+ N_("raw[rename]: rename a remote relay server"),
+ N_("raw[del]: delete a remote relay server"),
+ "",
+ N_("Without argument, this command opens buffer with list of relay "
+ "clients."),
+ "",
+ N_("Examples:"),
+ AI(" /remote add example https://localhost:9000 "
+ "-password=my_secret_password -totp_secret=secrettotp"),
+ AI(" /remote connect example"),
+ AI(" /remote del example")),
+ "list %(relay_remotes)"
+ " || listfull %(relay_remotes)"
+ " || add %(relay_remotes) https://localhost:9000 "
+ "-password=${xxx}|-totp_secret=${xxx}|%*"
+ " || connect %(relay_remotes)"
+ " || rename %(relay_remotes) %(relay_remotes)"
+ " || del %(relay_remotes)",
+ &relay_command_remote, NULL, NULL);
}
diff --git a/src/plugins/relay/relay-completion.c b/src/plugins/relay/relay-completion.c
index 65bf39925..0c09693ce 100644
--- a/src/plugins/relay/relay-completion.c
+++ b/src/plugins/relay/relay-completion.c
@@ -25,6 +25,7 @@
#include "../weechat-plugin.h"
#include "relay.h"
+#include "relay-remote.h"
#include "relay-server.h"
@@ -156,6 +157,35 @@ relay_completion_free_port_cb (const void *pointer, void *data,
}
/*
+ * Adds relay remotes to completion list.
+ */
+
+int
+relay_completion_remotes_cb (const void *pointer, void *data,
+ const char *completion_item,
+ struct t_gui_buffer *buffer,
+ struct t_gui_completion *completion)
+{
+ struct t_relay_remote *ptr_remote;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) buffer;
+ (void) completion_item;
+
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ weechat_completion_list_add (completion,
+ ptr_remote->name,
+ 0, WEECHAT_LIST_POS_SORT);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* Hooks completions.
*/
@@ -172,4 +202,7 @@ relay_completion_init ()
weechat_hook_completion ("relay_free_port",
N_("first free port for relay plugin"),
&relay_completion_free_port_cb, NULL, NULL);
+ weechat_hook_completion ("relay_remotes",
+ N_("relay remotes"),
+ &relay_completion_remotes_cb, NULL, NULL);
}
diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c
index 150ed8d03..c37669af3 100644
--- a/src/plugins/relay/relay-config.c
+++ b/src/plugins/relay/relay-config.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <regex.h>
@@ -31,10 +32,11 @@
#include "../weechat-plugin.h"
#include "relay.h"
-#include "relay-config.h"
#include "relay-client.h"
+#include "relay-config.h"
#include "relay-buffer.h"
#include "relay-network.h"
+#include "relay-remote.h"
#include "relay-server.h"
#include "irc/relay-irc.h"
@@ -49,6 +51,7 @@ struct t_config_section *relay_config_section_network = NULL;
struct t_config_section *relay_config_section_irc = NULL;
struct t_config_section *relay_config_section_port = NULL;
struct t_config_section *relay_config_section_path = NULL;
+struct t_config_section *relay_config_section_remote = NULL;
/* relay config, look section */
@@ -960,6 +963,217 @@ relay_config_create_option_port_path (const void *pointer, void *data,
}
/*
+ * Creates an option for a remote.
+ *
+ * Returns pointer to new option, NULL if error.
+ */
+
+struct t_config_option *
+relay_config_create_remote_option (const char *remote_name, int index_option,
+ const char *value)
+{
+ struct t_config_option *ptr_option;
+ int length;
+ char *option_name;
+
+ ptr_option = NULL;
+
+ length = strlen (remote_name) + 1 +
+ strlen (relay_remote_option_string[index_option]) + 1;
+ option_name = malloc (length);
+ if (!option_name)
+ return NULL;
+
+ snprintf (option_name, length, "%s.%s",
+ remote_name, relay_remote_option_string[index_option]);
+
+ switch (index_option)
+ {
+ case RELAY_REMOTE_OPTION_URL:
+ ptr_option = weechat_config_new_option (
+ relay_config_file, relay_config_section_remote,
+ option_name, "string",
+ N_("remote URL"),
+ NULL, 0, 0, value, NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case RELAY_REMOTE_OPTION_PASSWORD:
+ ptr_option = weechat_config_new_option (
+ relay_config_file, relay_config_section_remote,
+ option_name, "string",
+ N_("password"),
+ NULL, 0, 0, value, NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case RELAY_REMOTE_OPTION_TOTP_SECRET:
+ ptr_option = weechat_config_new_option (
+ relay_config_file, relay_config_section_remote,
+ option_name, "string",
+ N_("TOTP secret"),
+ NULL, 0, 0, value, NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case RELAY_REMOTE_NUM_OPTIONS:
+ break;
+ }
+
+ free (option_name);
+
+ return ptr_option;
+}
+
+/*
+ * Creates option for a temporary remote (when reading configuration file).
+ */
+
+void
+relay_config_create_option_temp (struct t_relay_remote *temp_remote,
+ int index_option, const char *value)
+{
+ struct t_config_option *new_option;
+
+ new_option = relay_config_create_remote_option (temp_remote->name,
+ index_option, value);
+ if (new_option
+ && (index_option >= 0) && (index_option < RELAY_REMOTE_NUM_OPTIONS))
+ {
+ temp_remote->options[index_option] = new_option;
+ }
+}
+
+/*
+ * Uses temporary remotes (created by reading configuration file).
+ */
+
+void
+relay_config_use_temp_remotes ()
+{
+ struct t_relay_remote *ptr_temp_remote, *next_temp_remote;
+ int i, num_options_ok;
+
+ for (ptr_temp_remote = relay_remotes_temp; ptr_temp_remote;
+ ptr_temp_remote = ptr_temp_remote->next_remote)
+ {
+ num_options_ok = 0;
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ if (!ptr_temp_remote->options[i])
+ {
+ ptr_temp_remote->options[i] =
+ relay_config_create_remote_option (
+ ptr_temp_remote->name,
+ i,
+ relay_remote_option_default[i]);
+ }
+ if (ptr_temp_remote->options[i])
+ num_options_ok++;
+ }
+
+ if (num_options_ok == RELAY_REMOTE_NUM_OPTIONS)
+ {
+ relay_remote_new_with_options (ptr_temp_remote->name,
+ ptr_temp_remote->options);
+ }
+ else
+ {
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ if (ptr_temp_remote->options[i])
+ {
+ weechat_config_option_free (ptr_temp_remote->options[i]);
+ ptr_temp_remote->options[i] = NULL;
+ }
+ }
+ }
+ }
+
+ /* free all temporary remotes */
+ while (relay_remotes_temp)
+ {
+ next_temp_remote = relay_remotes_temp->next_remote;
+
+ if (relay_remotes_temp->name)
+ free (relay_remotes_temp->name);
+ free (relay_remotes_temp);
+
+ relay_remotes_temp = next_temp_remote;
+ }
+ last_relay_remote_temp = NULL;
+}
+
+/*
+ * Reads a remote option in relay configuration file.
+ */
+
+int
+relay_config_remote_read_cb (const void *pointer, void *data,
+ struct t_config_file *config_file,
+ struct t_config_section *section,
+ const char *option_name, const char *value)
+{
+ char *pos_option, *remote_name;
+ struct t_relay_remote *ptr_temp_remote;
+ int index_option;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) config_file;
+ (void) section;
+
+ if (!option_name)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ pos_option = strchr (option_name, '.');
+ if (!pos_option)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ remote_name = weechat_strndup (option_name, pos_option - option_name);
+ if (!remote_name)
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+
+ pos_option++;
+
+ /* search temporary remote */
+ for (ptr_temp_remote = relay_remotes_temp; ptr_temp_remote;
+ ptr_temp_remote = ptr_temp_remote->next_remote)
+ {
+ if (strcmp (ptr_temp_remote->name, remote_name) == 0)
+ break;
+ }
+ if (!ptr_temp_remote)
+ {
+ /* create new temporary remote */
+ ptr_temp_remote = relay_remote_alloc (remote_name);
+ if (ptr_temp_remote)
+ relay_remote_add (ptr_temp_remote, &relay_remotes_temp, &last_relay_remote_temp);
+ }
+
+ if (ptr_temp_remote)
+ {
+ index_option = relay_remote_search_option (pos_option);
+ if (index_option >= 0)
+ {
+ relay_config_create_option_temp (ptr_temp_remote, index_option,
+ value);
+ }
+ else
+ {
+ weechat_printf (NULL,
+ _("%sWarning: unknown option for section \"%s\": "
+ "%s (value: \"%s\")"),
+ weechat_prefix ("error"),
+ RELAY_CONFIG_SECTION_REMOTE,
+ option_name, value);
+ }
+ }
+
+ free (remote_name);
+
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+}
+
+/*
* Reloads relay configuration file.
*/
@@ -1196,10 +1410,10 @@ relay_config_init ()
NULL, NULL, NULL,
&relay_config_refresh_cb, NULL, NULL,
NULL, NULL, NULL);
- relay_config_color_status[RELAY_STATUS_WAITING_AUTH] = weechat_config_new_option (
+ relay_config_color_status[RELAY_STATUS_AUTHENTICATING] = weechat_config_new_option (
relay_config_file, relay_config_section_color,
- "status_waiting_auth", "color",
- N_("text color for \"waiting authentication\" status"),
+ "status_authenticating", "color",
+ N_("text color for \"authenticating\" status"),
NULL, 0, 0, "yellow", NULL, 0,
NULL, NULL, NULL,
&relay_config_refresh_cb, NULL, NULL,
@@ -1518,6 +1732,17 @@ relay_config_init ()
&relay_config_create_option_port_path, NULL, NULL,
NULL, NULL, NULL);
+ /* remote */
+ relay_config_section_remote = weechat_config_new_section (
+ relay_config_file,
+ RELAY_CONFIG_SECTION_REMOTE,
+ 0, 0,
+ &relay_config_remote_read_cb, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
return 1;
}
@@ -1538,6 +1763,7 @@ relay_config_read ()
relay_config_change_network_allowed_ips (NULL, NULL, NULL);
relay_config_change_network_password_hash_algo (NULL, NULL, NULL);
relay_config_change_irc_backlog_tags (NULL, NULL, NULL);
+ relay_config_use_temp_remotes ();
}
return rc;
}
diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h
index e454ba97e..afc8afc96 100644
--- a/src/plugins/relay/relay-config.h
+++ b/src/plugins/relay/relay-config.h
@@ -24,6 +24,7 @@
#define RELAY_CONFIG_NAME "relay"
#define RELAY_CONFIG_PRIO_NAME (TO_STR(RELAY_PLUGIN_PRIORITY) "|" RELAY_CONFIG_NAME)
+#define RELAY_CONFIG_SECTION_REMOTE "remote"
#define RELAY_CONFIG_VERSION 2
@@ -85,6 +86,9 @@ extern int relay_config_create_option_port_path (const void *pointer, void *data
const char *value);
extern int relay_config_check_path_length (const char *path);
extern int relay_config_check_path_available (const char *path);
+extern struct t_config_option *relay_config_create_remote_option (const char *remote_name,
+ int index_option,
+ const char *value);
extern int relay_config_init ();
extern int relay_config_read ();
extern int relay_config_write ();
diff --git a/src/plugins/relay/relay-info.c b/src/plugins/relay/relay-info.c
index c7fb864fd..18322ffbf 100644
--- a/src/plugins/relay/relay-info.c
+++ b/src/plugins/relay/relay-info.c
@@ -69,7 +69,7 @@ relay_info_info_relay_client_count_cb (const void *pointer, void *data,
protocol = relay_protocol_search (items[0]);
if (protocol < 0)
{
- status = relay_client_status_search (items[0]);
+ status = relay_status_search (items[0]);
if (status < 0)
goto end;
}
@@ -86,7 +86,7 @@ relay_info_info_relay_client_count_cb (const void *pointer, void *data,
}
if (strcmp (items[1], "*") != 0)
{
- status = relay_client_status_search (items[1]);
+ status = relay_status_search (items[1]);
if (status < 0)
goto end;
}
diff --git a/src/plugins/relay/relay-remote.c b/src/plugins/relay/relay-remote.c
new file mode 100644
index 000000000..b10222977
--- /dev/null
+++ b/src/plugins/relay/relay-remote.c
@@ -0,0 +1,677 @@
+/*
+ * relay-remote.c - remote relay server functions for relay plugin
+ *
+ * Copyright (C) 2024 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <gnutls/gnutls.h>
+
+#include "../weechat-plugin.h"
+#include "relay.h"
+#include "relay-config.h"
+#include "relay-remote.h"
+
+
+char *relay_remote_option_string[RELAY_REMOTE_NUM_OPTIONS] =
+{ "url", "password", "totp_secret" };
+char *relay_remote_option_default[RELAY_REMOTE_NUM_OPTIONS] =
+{ "", "", "" };
+
+struct t_relay_remote *relay_remotes = NULL;
+struct t_relay_remote *last_relay_remote = NULL;
+int relay_remotes_count = 0; /* number of remotes */
+
+struct t_relay_remote *relay_remotes_temp = NULL; /* first temp. remote */
+struct t_relay_remote *last_relay_remote_temp = NULL; /* last temp. remote */
+
+
+/*
+ * Searches for a remote option name.
+ *
+ * Returns index of option in enum t_relay_remote_option, -1 if not found.
+ */
+
+int
+relay_remote_search_option (const char *option_name)
+{
+ int i;
+
+ if (!option_name)
+ return -1;
+
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ if (strcmp (relay_remote_option_string[i], option_name) == 0)
+ return i;
+ }
+
+ /* remote option not found */
+ return -1;
+}
+
+/*
+ * Checks if a remote pointer is valid.
+ *
+ * Returns:
+ * 1: remote exists
+ * 0: remote does not exist
+ */
+
+int
+relay_remote_valid (struct t_relay_remote *remote)
+{
+ struct t_relay_remote *ptr_remote;
+
+ if (!remote)
+ return 0;
+
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ if (ptr_remote == remote)
+ return 1;
+ }
+
+ /* remote not found */
+ return 0;
+}
+
+/*
+ * Searches for a remote by name.
+ *
+ * Returns pointer to remote found, NULL if not found.
+ */
+
+struct t_relay_remote *
+relay_remote_search (const char *name)
+{
+ struct t_relay_remote *ptr_remote;
+
+ if (!name || !name[0])
+ return NULL;
+
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ if (strcmp (ptr_remote->name, name) == 0)
+ return ptr_remote;
+ }
+
+ /* remote not found */
+ return NULL;
+}
+
+/*
+ * Searches for a remote by number (first remote is 0).
+ *
+ * Returns pointer to remote found, NULL if not found.
+ */
+
+struct t_relay_remote *
+relay_remote_search_by_number (int number)
+{
+ struct t_relay_remote *ptr_remote;
+ int i;
+
+ i = 0;
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ if (i == number)
+ return ptr_remote;
+ i++;
+ }
+
+ /* remote not found */
+ return NULL;
+}
+
+/*
+ * Checks if a remote name is valid: it must contain only alphabetic chars
+ * or digits.
+ *
+ * Returns:
+ * 1: name is valid
+ * 0: name is invalid
+ */
+
+int
+relay_remote_name_valid (const char *name)
+{
+ const char *ptr_name;
+
+ if (!name || !name[0])
+ return 0;
+
+ ptr_name = name;
+ while (ptr_name[0])
+ {
+ if (!isalnum ((unsigned char)ptr_name[0]))
+ return 0;
+ ptr_name++;
+ }
+
+ /* name is valid */
+ return 1;
+}
+
+/*
+ * Checks if a remote URL is valid;
+ *
+ * Returns:
+ * 1: URL is valid
+ * 0: URL is invalid
+ */
+
+int
+relay_remote_url_valid (const char *url)
+{
+ const char *pos;
+
+ if (!url || !url[0])
+ return 0;
+
+ /* URL must start with "https://" or "http://" */
+ if ((strncmp (url, "https://", 8) != 0) && (strncmp (url, "http://", 7) != 0))
+ return 0;
+
+ pos = strchr (url + 7, ':');
+
+ /* invalid port? */
+ if (pos && !isdigit ((unsigned char)pos[1]))
+ return 0;
+
+ /* URL is valid */
+ return 1;
+}
+
+/*
+ * Sends a signal with the status of remote ("relay_remote_xxx").
+ */
+
+void
+relay_remote_send_signal (struct t_relay_remote *remote)
+{
+ char signal[128];
+
+ snprintf (signal, sizeof (signal),
+ "relay_remote_%s",
+ relay_status_name[remote->status]);
+ weechat_hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_POINTER, remote);
+}
+
+/*
+ * Allocates and initializes new remote structure.
+ *
+ * Returns pointer to new remote, NULL if error.
+ */
+
+struct t_relay_remote *
+relay_remote_alloc (const char *name)
+{
+ struct t_relay_remote *new_remote;
+ int i;
+
+ if (!relay_remote_name_valid (name))
+ return NULL;
+
+ if (relay_remote_search (name))
+ return NULL;
+
+ new_remote = malloc (sizeof (*new_remote));
+ if (!new_remote)
+ return NULL;
+
+ new_remote->name = strdup (name);
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ new_remote->options[i] = NULL;
+ }
+ new_remote->address = NULL;
+ new_remote->port = 0;
+ new_remote->tls = 0;
+ new_remote->status = RELAY_STATUS_DISCONNECTED;
+ new_remote->sock = -1;
+ new_remote->gnutls_sess = NULL;
+ new_remote->prev_remote = NULL;
+ new_remote->next_remote = NULL;
+
+ return new_remote;
+}
+
+/*
+ * Searches for position of remote in list (to keep remotes sorted by name).
+ */
+
+struct t_relay_remote *
+relay_remote_find_pos (struct t_relay_remote *remote,
+ struct t_relay_remote *list_remotes)
+{
+ struct t_relay_remote *ptr_remote;
+
+ for (ptr_remote = list_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ if (weechat_strcmp (remote->name, ptr_remote->name) < 0)
+ return ptr_remote;
+ }
+
+ /* position not found */
+ return NULL;
+}
+
+/*
+ * Adds a remote in a linked list.
+ */
+
+void
+relay_remote_add (struct t_relay_remote *remote,
+ struct t_relay_remote **list_remotes,
+ struct t_relay_remote **last_list_remote)
+{
+ struct t_relay_remote *pos_remote;
+
+ pos_remote = relay_remote_find_pos (remote, *list_remotes);
+ if (pos_remote)
+ {
+ /* add remote before "pos_remote" */
+ remote->prev_remote = pos_remote->prev_remote;
+ remote->next_remote = pos_remote;
+ if (pos_remote->prev_remote)
+ (pos_remote->prev_remote)->next_remote = remote;
+ else
+ *list_remotes = remote;
+ pos_remote->prev_remote = remote;
+ }
+ else
+ {
+ /* add remote to end of list */
+ remote->prev_remote = *last_list_remote;
+ remote->next_remote = NULL;
+ if (*last_list_remote)
+ (*last_list_remote)->next_remote = remote;
+ else
+ *list_remotes = remote;
+ *last_list_remote = remote;
+ }
+}
+
+/*
+ * Creates a new remote with options.
+ *
+ * Returns pointer to new remote, NULL if error.
+ */
+
+struct t_relay_remote *
+relay_remote_new_with_options (const char *name, struct t_config_option **options)
+{
+ struct t_relay_remote *new_remote;
+ int i;
+
+ new_remote = relay_remote_alloc (name);
+ if (!new_remote)
+ return NULL;
+
+ if (!relay_remote_url_valid (weechat_config_string (options[RELAY_REMOTE_OPTION_URL])))
+ {
+ free (new_remote);
+ return NULL;
+ }
+
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ new_remote->options[i] = options[i];
+ }
+ relay_remote_add (new_remote, &relay_remotes, &last_relay_remote);
+ relay_remotes_count++;
+
+ relay_remote_send_signal (new_remote);
+
+ return new_remote;
+}
+
+/*
+ * Creates a new remote.
+ *
+ * Returns pointer to new remote, NULL if error.
+ */
+
+struct t_relay_remote *
+relay_remote_new (const char *name, const char *url, const char *password,
+ const char *totp_secret)
+{
+ struct t_config_option *option[RELAY_REMOTE_NUM_OPTIONS];
+ const char *value[RELAY_REMOTE_NUM_OPTIONS];
+ struct t_relay_remote *new_remote;
+ int i;
+
+ if (!name || !name[0] || !url || !url[0])
+ return NULL;
+
+ new_remote = malloc (sizeof (*new_remote));
+ if (!new_remote)
+ return NULL;
+
+ value[RELAY_REMOTE_OPTION_URL] = url;
+ value[RELAY_REMOTE_OPTION_PASSWORD] = password;
+ value[RELAY_REMOTE_OPTION_TOTP_SECRET] = totp_secret;
+
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ option[i] = relay_config_create_remote_option (name, i, value[i]);
+ }
+
+ new_remote = relay_remote_new_with_options (name, option);
+ if (!new_remote)
+ {
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ weechat_config_option_free (option[i]);
+ }
+ }
+
+ return new_remote;
+}
+
+/*
+ * Creates a new remote using an infolist.
+ *
+ * This is called to restore remotes after /upgrade.
+ */
+
+struct t_relay_remote *
+relay_remote_new_with_infolist (struct t_infolist *infolist)
+{
+ struct t_relay_remote *new_remote;
+
+ new_remote = malloc (sizeof (*new_remote));
+ if (!new_remote)
+ return NULL;
+
+ new_remote->address = strdup (weechat_infolist_string (infolist, "name"));
+ new_remote->address = strdup (weechat_infolist_string (infolist, "address"));
+ new_remote->port = weechat_infolist_integer (infolist, "port");
+ new_remote->tls = weechat_infolist_integer (infolist, "tls");
+ new_remote->status = weechat_infolist_integer (infolist, "status");
+ new_remote->sock = weechat_infolist_integer (infolist, "sock");
+ new_remote->gnutls_sess = NULL;
+ new_remote->prev_remote = NULL;
+ new_remote->next_remote = relay_remotes;
+ if (relay_remotes)
+ relay_remotes->prev_remote = new_remote;
+ else
+ last_relay_remote = new_remote;
+ relay_remotes = new_remote;
+
+ relay_remotes_count++;
+
+ return new_remote;
+}
+
+/*
+ * Sets status for a remote.
+ */
+
+void
+relay_remote_set_status (struct t_relay_remote *remote,
+ enum t_relay_status status)
+{
+ /*
+ * IMPORTANT: if changes are made in this function or sub-functions called,
+ * please also update the function relay_remote_add_to_infolist:
+ * when the flag force_disconnected_state is set to 1 we simulate
+ * a disconnected state for remote in infolist (used on /upgrade -save)
+ */
+
+ remote->status = status;
+
+ relay_remote_send_signal (remote);
+}
+
+/*
+ * Renames a remote.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error (remote not renamed)
+ */
+
+int
+relay_remote_rename (struct t_relay_remote *remote, const char *name)
+{
+ int length, i;
+ char *option_name;
+
+ if (!remote || !name || !name[0] || !relay_remote_name_valid (name)
+ || relay_remote_search (name))
+ {
+ return 0;
+ }
+
+ length = strlen (name) + 64;
+ option_name = malloc (length);
+ if (!option_name)
+ return 0;
+
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ if (remote->options[i])
+ {
+ snprintf (option_name, length,
+ "%s.%s",
+ name,
+ relay_remote_option_string[i]);
+ weechat_config_option_rename (remote->options[i], option_name);
+ }
+ }
+
+ if (remote->name)
+ free (remote->name);
+ remote->name = strdup (name);
+
+ free (option_name);
+
+ /* re-insert remote in list (for sorting remotes by name) */
+ if (remote->prev_remote)
+ (remote->prev_remote)->next_remote = remote->next_remote;
+ else
+ relay_remotes = remote->next_remote;
+ if (remote->next_remote)
+ (remote->next_remote)->prev_remote = remote->prev_remote;
+ else
+ last_relay_remote = remote->prev_remote;
+ relay_remote_add (remote, &relay_remotes, &last_relay_remote);
+
+ return 1;
+}
+
+/*
+ * Deletes a remote.
+ */
+
+void
+relay_remote_free (struct t_relay_remote *remote)
+{
+ int i;
+
+ if (!remote)
+ return;
+
+ /* remove remote from list */
+ if (remote->prev_remote)
+ (remote->prev_remote)->next_remote = remote->next_remote;
+ if (remote->next_remote)
+ (remote->next_remote)->prev_remote = remote->prev_remote;
+ if (relay_remotes == remote)
+ relay_remotes = remote->next_remote;
+ if (last_relay_remote == remote)
+ last_relay_remote = remote->prev_remote;
+
+ /* free data */
+ if (remote->name)
+ free (remote->name);
+ for (i = 0; i < RELAY_REMOTE_NUM_OPTIONS; i++)
+ {
+ if (remote->options[i])
+ weechat_config_option_free (remote->options[i]);
+ }
+ if (remote->address)
+ free (remote->address);
+
+ free (remote);
+
+ relay_remotes_count--;
+}
+
+/*
+ * Removes all remotes.
+ */
+
+void
+relay_remote_free_all ()
+{
+ while (relay_remotes)
+ {
+ relay_remote_free (relay_remotes);
+ }
+}
+
+/*
+ * Disconnects one remote.
+ */
+
+void
+relay_remote_disconnect (struct t_relay_remote *remote)
+{
+ if (remote->sock >= 0)
+ {
+ relay_remote_set_status (remote, RELAY_STATUS_DISCONNECTED);
+ }
+}
+
+/*
+ * Disconnects all remotes.
+ */
+
+void
+relay_remote_disconnect_all ()
+{
+ struct t_relay_remote *ptr_remote;
+
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ relay_remote_disconnect (ptr_remote);
+ }
+}
+
+/*
+ * Adds a remote in an infolist.
+ *
+ * If force_disconnected_state == 1, the infolist contains the remote
+ * in a disconnected state (but the remote is unchanged, still connected if it
+ * was).
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+relay_remote_add_to_infolist (struct t_infolist *infolist,
+ struct t_relay_remote *remote,
+ int force_disconnected_state)
+{
+ struct t_infolist_item *ptr_item;
+
+ if (!infolist || !remote)
+ return 0;
+
+ ptr_item = weechat_infolist_new_item (infolist);
+ if (!ptr_item)
+ return 0;
+
+ if (!weechat_infolist_new_var_string (ptr_item, "name", remote->name))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "address", remote->address))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "port", remote->port))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "tls", remote->tls))
+ return 0;
+ if (!RELAY_STATUS_HAS_ENDED(remote->status) && force_disconnected_state)
+ {
+ if (!weechat_infolist_new_var_integer (ptr_item, "status", RELAY_STATUS_DISCONNECTED))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "sock", -1))
+ return 0;
+ }
+ else
+ {
+ if (!weechat_infolist_new_var_integer (ptr_item, "status", remote->status))
+ return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "sock", remote->sock))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Prints remotes in WeeChat log file (usually for crash dump).
+ */
+
+void
+relay_remote_print_log ()
+{
+ struct t_relay_remote *ptr_remote;
+
+ for (ptr_remote = relay_remotes; ptr_remote;
+ ptr_remote = ptr_remote->next_remote)
+ {
+ weechat_log_printf ("");
+ weechat_log_printf ("[relay remote (addr:0x%lx)]", ptr_remote);
+ weechat_log_printf (" name. . . . . . . . . : '%s'", ptr_remote->name);
+ weechat_log_printf (" url . . . . . . . . . : '%s'",
+ weechat_config_string (ptr_remote->options[RELAY_REMOTE_OPTION_URL]));
+ weechat_log_printf (" password. . . . . . . : '%s'",
+ weechat_config_string (ptr_remote->options[RELAY_REMOTE_OPTION_PASSWORD]));
+ weechat_log_printf (" totp_secret . . . . . : '%s'",
+ weechat_config_string (ptr_remote->options[RELAY_REMOTE_OPTION_TOTP_SECRET]));
+ weechat_log_printf (" address . . . . . . . : '%s'", ptr_remote->address);
+ weechat_log_printf (" port. . . . . . . . . : %d", ptr_remote->port);
+ weechat_log_printf (" tls . . . . . . . . . : %d", ptr_remote->tls);
+ weechat_log_printf (" status. . . . . . . . : %d (%s)",
+ ptr_remote->status,
+ relay_status_string[ptr_remote->status]);
+ weechat_log_printf (" sock. . . . . . . . . : %d", ptr_remote->sock);
+ weechat_log_printf (" gnutls_sess . . . . . : 0x%lx", ptr_remote->gnutls_sess);
+ weechat_log_printf (" prev_remote . . . . . : 0x%lx", ptr_remote->prev_remote);
+ weechat_log_printf (" next_remote . . . . . : 0x%lx", ptr_remote->next_remote);
+ }
+}
diff --git a/src/plugins/relay/relay-remote.h b/src/plugins/relay/relay-remote.h
new file mode 100644
index 000000000..aa7b69e6e
--- /dev/null
+++ b/src/plugins/relay/relay-remote.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 Sébastien Helleu <flashcode@flashtux.org>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef WEECHAT_PLUGIN_RELAY_REMOTE_H
+#define WEECHAT_PLUGIN_RELAY_REMOTE_H
+
+#include <gnutls/gnutls.h>
+
+enum t_relay_remote_option
+{
+ RELAY_REMOTE_OPTION_URL = 0, /* remote URL */
+ RELAY_REMOTE_OPTION_PASSWORD, /* password for remote relay */
+ RELAY_REMOTE_OPTION_TOTP_SECRET, /* TOTP secret for remote relay */
+ /* number of relay remote options */
+ RELAY_REMOTE_NUM_OPTIONS,
+};
+
+/* relay remote */
+
+struct t_relay_remote
+{
+ char *name; /* internal remote name */
+ struct t_config_option *options[RELAY_REMOTE_NUM_OPTIONS];
+ char *address; /* address */
+ int port; /* port number */
+ int tls; /* 1 if TLS is enabled */
+ enum t_relay_status status; /* status (connecting, active,..) */
+ int sock; /* connected socket */
+ gnutls_session_t gnutls_sess; /* gnutls session (only if TLS used) */
+ struct t_relay_remote *prev_remote;/* link to previous remote */
+ struct t_relay_remote *next_remote;/* link to next remote */
+};
+
+extern char *relay_remote_option_string[];
+extern char *relay_remote_option_default[];
+extern struct t_relay_remote *relay_remotes;
+extern struct t_relay_remote *last_relay_remote;
+extern int relay_remotes_count;
+extern struct t_relay_remote *relay_remotes_temp;
+extern struct t_relay_remote *last_relay_remote_temp;
+
+extern int relay_remote_search_option (const char *option_name);
+extern int relay_remote_valid (struct t_relay_remote *remote);
+extern struct t_relay_remote *relay_remote_search (const char *name);
+extern struct t_relay_remote *relay_remote_search_by_number (int number);
+extern int relay_remote_name_valid (const char *name);
+extern int relay_remote_url_valid (const char *url);
+extern struct t_relay_remote *relay_remote_alloc (const char *name);
+extern void relay_remote_add (struct t_relay_remote *remote,
+ struct t_relay_remote **list_remotes,
+ struct t_relay_remote **last_list_remote);
+extern struct t_relay_remote *relay_remote_new_with_options (const char *name,
+ struct t_config_option **options);
+extern struct t_relay_remote *relay_remote_new (const char *name,
+ const char *url,
+ const char *password,
+ const char *totp_secret);
+extern struct t_relay_remote *relay_remote_new_with_infolist (struct t_infolist *infolist);
+extern void relay_remote_set_status (struct t_relay_remote *remote,
+ enum t_relay_status status);
+extern int relay_remote_rename (struct t_relay_remote *remote, const char *name);
+extern void relay_remote_free (struct t_relay_remote *remote);
+extern void relay_remote_free_all ();
+extern void relay_remote_disconnect (struct t_relay_remote *remote);
+extern void relay_remote_disconnect_all ();
+extern int relay_remote_add_to_infolist (struct t_infolist *infolist,
+ struct t_relay_remote *remote,
+ int force_disconnected_state);
+extern void relay_remote_print_log ();
+
+#endif /* WEECHAT_PLUGIN_RELAY_REMOTE_H */
diff --git a/src/plugins/relay/relay.c b/src/plugins/relay/relay.c
index debce9167..bf3188937 100644
--- a/src/plugins/relay/relay.c
+++ b/src/plugins/relay/relay.c
@@ -32,6 +32,7 @@
#include "relay-info.h"
#include "relay-network.h"
#include "relay-raw.h"
+#include "relay-remote.h"
#include "relay-server.h"
#include "relay-upgrade.h"
@@ -49,6 +50,15 @@ struct t_weechat_plugin *weechat_relay_plugin = NULL;
char *relay_protocol_string[] = /* strings for protocols */
{ "weechat", "irc", "api" };
+char *relay_status_string[] = /* status strings for display */
+{ N_("connecting"), N_("authenticating"),
+ N_("connected"), N_("authentication failed"), N_("disconnected")
+};
+char *relay_status_name[] = /* name of status (for signal/info) */
+{ "connecting", "waiting_auth",
+ "connected", "auth_failed", "disconnected"
+};
+
struct t_hdata *relay_hdata_buffer = NULL;
struct t_hdata *relay_hdata_lines = NULL;
struct t_hdata *relay_hdata_line = NULL;
@@ -90,6 +100,30 @@ relay_protocol_search (const char *name)
}
/*
+ * Searches for a status.
+ *
+ * Returns index of status in enum t_relay_status, -1 if status is not found.
+ */
+
+int
+relay_status_search (const char *name)
+{
+ int i;
+
+ if (!name)
+ return -1;
+
+ for (i = 0; i < RELAY_NUM_STATUS; i++)
+ {
+ if (strcmp (relay_status_name[i], name) == 0)
+ return i;
+ }
+
+ /* status not found */
+ return -1;
+}
+
+/*
* Callback for signal "upgrade".
*/
@@ -191,6 +225,7 @@ relay_debug_dump_cb (const void *pointer, void *data,
relay_server_print_log ();
relay_client_print_log ();
+ relay_remote_print_log ();
weechat_log_printf ("");
weechat_log_printf ("***** End of \"%s\" plugin dump *****",
diff --git a/src/plugins/relay/relay.h b/src/plugins/relay/relay.h
index b2797f2ab..f933021b7 100644
--- a/src/plugins/relay/relay.h
+++ b/src/plugins/relay/relay.h
@@ -49,13 +49,33 @@ enum t_relay_protocol
RELAY_NUM_PROTOCOLS,
};
+/* client/remote status */
+
+enum t_relay_status
+{
+ RELAY_STATUS_CONNECTING = 0, /* network connection in progress */
+ RELAY_STATUS_AUTHENTICATING, /* authentication in progress */
+ RELAY_STATUS_CONNECTED, /* connected and authenticated */
+ RELAY_STATUS_AUTH_FAILED, /* authentication failed */
+ RELAY_STATUS_DISCONNECTED, /* disconnected */
+ /* number of relay status */
+ RELAY_NUM_STATUS,
+};
+
+#define RELAY_STATUS_HAS_ENDED(status) \
+ ((status == RELAY_STATUS_AUTH_FAILED) || \
+ (status == RELAY_STATUS_DISCONNECTED))
+
#define RELAY_COLOR_CHAT weechat_color("chat")
#define RELAY_COLOR_CHAT_HOST weechat_color("chat_host")
#define RELAY_COLOR_CHAT_BUFFER weechat_color("chat_buffer")
#define RELAY_COLOR_CHAT_CLIENT weechat_color(weechat_config_string(relay_config_color_client))
extern char *relay_protocol_string[];
+extern char *relay_status_string[];
+extern char *relay_status_name[];
extern int relay_protocol_search (const char *name);
+extern int relay_status_search (const char *name);
#endif /* WEECHAT_PLUGIN_RELAY_H */
diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.c b/src/plugins/relay/weechat/relay-weechat-protocol.c
index 9340d9453..56aa69cfe 100644
--- a/src/plugins/relay/weechat/relay-weechat-protocol.c
+++ b/src/plugins/relay/weechat/relay-weechat-protocol.c
@@ -225,7 +225,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake)
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
- if (client->status != RELAY_STATUS_WAITING_AUTH)
+ if (client->status != RELAY_STATUS_AUTHENTICATING)
return WEECHAT_RC_OK;
/* only one handshake is allowed */
@@ -1724,7 +1724,7 @@ relay_weechat_protocol_recv (struct t_relay_client *client, const char *data)
{ NULL, NULL }
};
- if (!data || !data[0] || RELAY_CLIENT_HAS_ENDED(client))
+ if (!data || !data[0] || RELAY_STATUS_HAS_ENDED(client->status))
return;
/* display debug message */
diff --git a/src/plugins/relay/weechat/relay-weechat.c b/src/plugins/relay/weechat/relay-weechat.c
index b217c3d04..12fa78b1a 100644
--- a/src/plugins/relay/weechat/relay-weechat.c
+++ b/src/plugins/relay/weechat/relay-weechat.c
@@ -286,12 +286,12 @@ relay_weechat_alloc_with_infolist (struct t_relay_client *client,
&relay_weechat_free_buffers_nicklist);
RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL;
- if (!RELAY_CLIENT_HAS_ENDED(client))
+ if (!RELAY_STATUS_HAS_ENDED(client->status))
relay_weechat_hook_signals (client);
}
/*
- * Returns the client initial status: it is always "waiting_auth" for weechat
+ * Returns the client initial status: it is always "authenticating" for weechat
* protocol because we always expect the "init" command, even without any
* password.
*/
@@ -302,7 +302,7 @@ relay_weechat_get_initial_status (struct t_relay_client *client)
/* make C compiler happy */
(void) client;
- return RELAY_STATUS_WAITING_AUTH;
+ return RELAY_STATUS_AUTHENTICATING;
}
/*
diff --git a/tests/unit/plugins/relay/api/test-relay-api.cpp b/tests/unit/plugins/relay/api/test-relay-api.cpp
index 08d1cb4bb..795b30daa 100644
--- a/tests/unit/plugins/relay/api/test-relay-api.cpp
+++ b/tests/unit/plugins/relay/api/test-relay-api.cpp
@@ -126,7 +126,7 @@ TEST(RelayApi, AllocWithInfolist)
TEST(RelayApi, GetInitialStatus)
{
- LONGS_EQUAL(RELAY_STATUS_WAITING_AUTH, relay_api_get_initial_status (NULL));
+ LONGS_EQUAL(RELAY_STATUS_AUTHENTICATING, relay_api_get_initial_status (NULL));
}
/*