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" }; @@ -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]); 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 * @@ -21,6 +21,7 @@ #include #include +#include #include #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: "") must be translated */ + N_("list|listfull []" + " || add [-