1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-09 05:45:42 +02:00

relay: add command /remote, add remote configuration in relay.conf (issue #2066)

This commit is contained in:
Sébastien Helleu
2024-02-10 22:30:03 +01:00
parent a89bc85dc0
commit 786f889251
25 changed files with 1487 additions and 99 deletions
+1
View File
@@ -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"
+1
View File
@@ -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).
+1
View File
@@ -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).
+2
View File
@@ -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)
+2
View File
@@ -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).
+2
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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 */
+7 -5
View File
@@ -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;
}
/*
+3 -3
View File
@@ -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;
+6 -6
View File
@@ -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);
File diff suppressed because it is too large Load Diff
-22
View File
@@ -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,
File diff suppressed because it is too large Load Diff
+33
View File
@@ -25,6 +25,7 @@
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-remote.h"
#include "relay-server.h"
@@ -155,6 +156,35 @@ relay_completion_free_port_cb (const void *pointer, void *data,
return WEECHAT_RC_OK;
}
/*
* 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);
}
File diff suppressed because it is too large Load Diff
+4
View File
@@ -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 ();
+2 -2
View File
@@ -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;
}
File diff suppressed because it is too large Load Diff
+87
View File
@@ -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 */
+35
View File
@@ -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;
@@ -89,6 +99,30 @@ relay_protocol_search (const char *name)
return -1;
}
/*
* 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 *****",
+20
View File
@@ -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 */
@@ -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 */
+3 -3
View File
@@ -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;
}
/*
@@ -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));
}
/*