mirror of
https://github.com/weechat/weechat.git
synced 2026-06-26 04:46:37 +02:00
relay: add command /remote, add remote configuration in relay.conf (issue #2066)
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" };
|
||||
|
||||
@@ -143,30 +134,6 @@ relay_client_search_by_id (int id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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]);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -386,6 +388,309 @@ relay_command_relay (const void *pointer, void *data,
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -959,6 +962,217 @@ relay_config_create_option_port_path (const void *pointer, void *data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 *****",
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user