1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-04 16:53:14 +02:00

xfer: add passive DCC support.

This commit also includes support for passive DCC RESUME.

There was also a potential segfault with calling `atoi(pos_token)` when `pos_token` is NULL, so `token` is set to be stored as a string. Although it is an integer, we don't need to store it as such. That's really more of an implementation detail.
This commit is contained in:
Mario Campos
2023-08-22 18:59:59 -05:00
committed by Sébastien Helleu
parent 23d70b5101
commit 7f0f947667
7 changed files with 173 additions and 105 deletions
+3 -21
View File
@@ -2104,11 +2104,9 @@ IRC_COMMAND_CALLBACK(cycle)
IRC_COMMAND_CALLBACK(dcc)
{
struct sockaddr_storage addr;
socklen_t length;
struct t_infolist *infolist;
struct t_infolist_item *item;
char str_address[NI_MAXHOST], charset_modifier[1024];
char charset_modifier[1024];
int rc;
IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
@@ -2119,22 +2117,7 @@ IRC_COMMAND_CALLBACK(dcc)
(void) data;
WEECHAT_COMMAND_MIN_ARGS(3, "");
/* use the local interface, from the server socket */
memset (&addr, 0, sizeof (addr));
length = sizeof (addr);
getsockname (ptr_server->sock, (struct sockaddr *)&addr, &length);
rc = getnameinfo ((struct sockaddr *)&addr, length, str_address,
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
if (rc != 0)
{
weechat_printf (
ptr_server->buffer,
_("%s%s: unable to resolve local address of server socket: error "
"%d %s"),
weechat_prefix ("error"), IRC_PLUGIN_NAME, rc, gai_strerror (rc));
return WEECHAT_RC_OK;
}
rc = WEECHAT_RC_ERROR;
/* DCC SEND file */
if (weechat_strcmp (argv[1], "send") == 0)
@@ -2153,7 +2136,6 @@ IRC_COMMAND_CALLBACK(dcc)
weechat_infolist_new_var_string (item, "remote_nick", argv[2]);
weechat_infolist_new_var_string (item, "local_nick", ptr_server->nick);
weechat_infolist_new_var_string (item, "filename", argv_eol[3]);
weechat_infolist_new_var_string (item, "local_address", str_address);
weechat_infolist_new_var_integer (item, "socket", ptr_server->sock);
rc = weechat_hook_signal_send ("xfer_add",
WEECHAT_HOOK_SIGNAL_POINTER,
@@ -2182,7 +2164,7 @@ IRC_COMMAND_CALLBACK(dcc)
snprintf (charset_modifier, sizeof (charset_modifier),
"irc.%s.%s", ptr_server->name, argv[2]);
weechat_infolist_new_var_string (item, "charset_modifier", charset_modifier);
weechat_infolist_new_var_string (item, "local_address", str_address);
weechat_infolist_new_var_integer (item, "socket", ptr_server->sock);
rc = weechat_hook_signal_send ("xfer_add",
WEECHAT_HOOK_SIGNAL_POINTER,
infolist);
+6 -17
View File
@@ -26,6 +26,9 @@
#include <time.h>
#include <sys/utsname.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "../weechat-plugin.h"
#include "irc.h"
@@ -889,22 +892,6 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick,
/* remove double quotes around filename */
filename = irc_ctcp_dcc_filename_without_quotes (pos_file);
/* use the local interface, from the server socket */
memset (&addr, 0, sizeof (addr));
length = sizeof (addr);
getsockname (server->sock, (struct sockaddr *)&addr, &length);
rc = getnameinfo ((struct sockaddr *)&addr, length, str_address,
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
if (rc != 0)
{
weechat_printf (
server->buffer,
_("%s%s: unable to resolve local address of server socket: error "
"%d %s"),
weechat_prefix ("error"), IRC_PLUGIN_NAME, rc, gai_strerror (rc));
return;
}
/* add DCC file via xfer plugin */
infolist = weechat_infolist_new ();
if (infolist)
@@ -914,7 +901,8 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick,
{
weechat_infolist_new_var_string (item, "plugin_name", weechat_plugin->name);
weechat_infolist_new_var_string (item, "plugin_id", server->name);
weechat_infolist_new_var_string (item, "type_string", "file_recv_active");
weechat_infolist_new_var_string (item, "type_string",
strcmp (pos_port, "0") ? "file_recv_active" : "file_recv_passive");
weechat_infolist_new_var_string (item, "protocol_string", "dcc");
weechat_infolist_new_var_string (item, "remote_nick", nick);
weechat_infolist_new_var_string (item, "local_nick", server->nick);
@@ -924,6 +912,7 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick,
weechat_infolist_new_var_string (item, "proxy",
IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PROXY));
weechat_infolist_new_var_string (item, "remote_address", pos_addr);
weechat_infolist_new_var_integer (item, "socket", server->sock);
weechat_infolist_new_var_integer (item, "port", atoi (pos_port));
weechat_infolist_new_var_string (item, "token", pos_token);
(void) weechat_hook_signal_send ("xfer_add",
+48 -12
View File
@@ -6226,7 +6226,25 @@ irc_server_xfer_send_ready_cb (const void *pointer, void *data,
if (type && converted_addr[0])
{
/* send DCC PRIVMSG */
if (strcmp (type, "file_send_passive") == 0)
if (strcmp (type, "file_recv_passive") == 0)
{
filename = weechat_infolist_string (infolist, "filename");
spaces_in_name = (strchr (filename, ' ') != NULL);
irc_server_sendf (
ptr_server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"PRIVMSG %s :\01DCC SEND %s%s%s "
"%s %d %s %s\01",
weechat_infolist_string (infolist, "remote_nick"),
(spaces_in_name) ? "\"" : "",
filename,
(spaces_in_name) ? "\"" : "",
converted_addr,
weechat_infolist_integer (infolist, "port"),
weechat_infolist_string (infolist, "size"),
weechat_infolist_string (infolist, "token"));
}
else if (strcmp (type, "file_send_passive") == 0)
{
filename = weechat_infolist_string (infolist, "filename");
spaces_in_name = (strchr (filename, ' ') != NULL);
@@ -6277,7 +6295,7 @@ irc_server_xfer_resume_ready_cb (const void *pointer, void *data,
{
struct t_infolist *infolist;
struct t_irc_server *ptr_server;
const char *plugin_name, *plugin_id, *filename;
const char *plugin_name, *plugin_id, *filename, *type;
int spaces_in_name;
/* make C compiler happy */
@@ -6297,18 +6315,36 @@ irc_server_xfer_resume_ready_cb (const void *pointer, void *data,
ptr_server = irc_server_search (plugin_id);
if (ptr_server)
{
type = weechat_infolist_string (infolist, "type_string");
filename = weechat_infolist_string (infolist, "filename");
spaces_in_name = (strchr (filename, ' ') != NULL);
irc_server_sendf (
ptr_server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"PRIVMSG %s :\01DCC RESUME %s%s%s %d %s\01",
weechat_infolist_string (infolist, "remote_nick"),
(spaces_in_name) ? "\"" : "",
filename,
(spaces_in_name) ? "\"" : "",
weechat_infolist_integer (infolist, "port"),
weechat_infolist_string (infolist, "start_resume"));
if (strcmp (type, "file_recv_passive") == 0)
{
irc_server_sendf (
ptr_server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"PRIVMSG %s :\01DCC RESUME %s%s%s %d %s %s\01",
weechat_infolist_string (infolist, "remote_nick"),
(spaces_in_name) ? "\"" : "",
filename,
(spaces_in_name) ? "\"" : "",
weechat_infolist_integer (infolist, "port"),
weechat_infolist_string (infolist, "start_resume"),
weechat_infolist_string (infolist, "token"));
}
else
{
irc_server_sendf (
ptr_server,
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
"PRIVMSG %s :\01DCC RESUME %s%s%s %d %s\01",
weechat_infolist_string (infolist, "remote_nick"),
(spaces_in_name) ? "\"" : "",
filename,
(spaces_in_name) ? "\"" : "",
weechat_infolist_integer (infolist, "port"),
weechat_infolist_string (infolist, "start_resume"));
}
}
}
}