mirror of
https://github.com/weechat/weechat.git
synced 2026-06-29 22:36:38 +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:
committed by
Sébastien Helleu
parent
23d70b5101
commit
7f0f947667
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,14 +342,17 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
|
||||
}
|
||||
|
||||
/* first connect to sender (blocking) */
|
||||
xfer->sock = weechat_network_connect_to (xfer->proxy,
|
||||
xfer->remote_address,
|
||||
xfer->remote_address_length);
|
||||
if (xfer->sock == -1)
|
||||
if (xfer->type == XFER_TYPE_FILE_RECV_ACTIVE)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_CONNECT_SENDER);
|
||||
return;
|
||||
xfer->sock = weechat_network_connect_to (xfer->proxy,
|
||||
xfer->remote_address,
|
||||
xfer->remote_address_length);
|
||||
if (xfer->sock == -1)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_CONNECT_SENDER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* set TCP_NODELAY to be more aggressive with acks */
|
||||
|
||||
@@ -498,7 +498,7 @@ xfer_network_fd_cb (const void *pointer, void *data, int fd)
|
||||
|
||||
if (xfer->status == XFER_STATUS_CONNECTING)
|
||||
{
|
||||
if (xfer->type == XFER_TYPE_FILE_SEND_PASSIVE)
|
||||
if (XFER_IS_PASSIVE(xfer->type))
|
||||
{
|
||||
xfer->last_activity = time (NULL);
|
||||
sock = accept (xfer->sock,
|
||||
@@ -546,7 +546,22 @@ xfer_network_fd_cb (const void *pointer, void *data, int fd)
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer->start_transfer = time (NULL);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
xfer_network_send_file_fork (xfer);
|
||||
switch (xfer->type)
|
||||
{
|
||||
case XFER_TYPE_FILE_SEND_PASSIVE:
|
||||
xfer_network_send_file_fork (xfer);
|
||||
break;
|
||||
case XFER_TYPE_FILE_RECV_PASSIVE:
|
||||
xfer_network_recv_file_fork (xfer);
|
||||
break;
|
||||
default:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: encountered unexpected xfer type (%d)"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME, xfer->type);
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,7 +802,7 @@ xfer_network_connect (struct t_xfer *xfer)
|
||||
else
|
||||
xfer->status = XFER_STATUS_CONNECTING;
|
||||
|
||||
if (XFER_IS_SEND(xfer->type))
|
||||
if (XFER_IS_SEND(xfer->type) || (xfer->type == XFER_TYPE_FILE_RECV_PASSIVE))
|
||||
{
|
||||
/* create socket */
|
||||
if (xfer->sock < 0)
|
||||
@@ -822,6 +837,10 @@ xfer_network_connect (struct t_xfer *xfer)
|
||||
&xfer_network_timer_cb,
|
||||
xfer, NULL);
|
||||
}
|
||||
|
||||
/* send signal if type is file or chat "send" */
|
||||
if ((xfer->type == XFER_TYPE_FILE_RECV_PASSIVE) && !XFER_HAS_ENDED(xfer->status))
|
||||
xfer_send_signal (xfer, "xfer_send_ready");
|
||||
}
|
||||
|
||||
/* for chat receiving, connect to listening host */
|
||||
@@ -854,7 +873,7 @@ xfer_network_connect_init (struct t_xfer *xfer)
|
||||
else
|
||||
{
|
||||
/* for a file: launch child process */
|
||||
if (XFER_IS_FILE(xfer->type))
|
||||
if (XFER_IS_FILE(xfer->type) && XFER_IS_ACTIVE(xfer->type))
|
||||
xfer_network_recv_file_fork (xfer);
|
||||
|
||||
xfer->status = XFER_STATUS_CONNECTING;
|
||||
|
||||
+82
-44
@@ -637,9 +637,10 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
enum t_xfer_type type, enum t_xfer_protocol protocol,
|
||||
const char *remote_nick, const char *local_nick,
|
||||
const char *charset_modifier, const char *filename,
|
||||
unsigned long long size, const char *proxy, struct sockaddr *address,
|
||||
socklen_t address_length, int port, int sock,
|
||||
const char *local_filename)
|
||||
unsigned long long size, const char *proxy, struct sockaddr *remote_address,
|
||||
socklen_t remote_address_length, struct sockaddr *local_address,
|
||||
socklen_t local_address_length, int port, int sock,
|
||||
const char *local_filename, const char *token)
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
const char *ptr_crc32;
|
||||
@@ -680,29 +681,46 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
new_xfer->size = size;
|
||||
new_xfer->proxy = (proxy) ? strdup (proxy) : NULL;
|
||||
new_xfer->port = port;
|
||||
|
||||
rc = getnameinfo ((struct sockaddr *)address, address_length, str_address,
|
||||
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
|
||||
if (rc != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to interpret address: error %d %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
rc, gai_strerror (rc));
|
||||
snprintf (str_address, sizeof (str_address), "?");
|
||||
}
|
||||
new_xfer->token = (token) ? strdup (token) : NULL;
|
||||
|
||||
if (XFER_IS_RECV(type))
|
||||
{
|
||||
new_xfer->local_address_str = strdup ("");
|
||||
xfer_set_remote_address (new_xfer, address, address_length, str_address);
|
||||
rc = getnameinfo ((struct sockaddr *)remote_address, remote_address_length, str_address,
|
||||
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
|
||||
if (rc != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to interpret address: error %d %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
rc, gai_strerror (rc));
|
||||
snprintf (str_address, sizeof (str_address), "?");
|
||||
}
|
||||
xfer_set_remote_address (new_xfer, remote_address, remote_address_length, str_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
xfer_set_local_address (new_xfer, address, address_length, str_address);
|
||||
new_xfer->remote_address_str = strdup ("");
|
||||
}
|
||||
|
||||
if (XFER_IS_PASSIVE(type))
|
||||
{
|
||||
rc = getnameinfo ((struct sockaddr *)local_address, local_address_length, str_address,
|
||||
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
|
||||
if (rc != 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to interpret address: error %d %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
rc, gai_strerror (rc));
|
||||
snprintf (str_address, sizeof (str_address), "?");
|
||||
}
|
||||
xfer_set_local_address (new_xfer, local_address, local_address_length, str_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_xfer->local_address_str = strdup ("");
|
||||
}
|
||||
|
||||
new_xfer->status = XFER_STATUS_WAITING;
|
||||
new_xfer->sock = sock;
|
||||
if (local_filename)
|
||||
@@ -744,13 +762,14 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
switch (type)
|
||||
{
|
||||
case XFER_TYPE_FILE_RECV_ACTIVE:
|
||||
case XFER_TYPE_FILE_RECV_PASSIVE:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming file from %s "
|
||||
"(%s, %s.%s), name: %s, %llu bytes "
|
||||
"(protocol: %s)"),
|
||||
XFER_PLUGIN_NAME,
|
||||
remote_nick,
|
||||
str_address,
|
||||
new_xfer->remote_address_str,
|
||||
plugin_name,
|
||||
plugin_id,
|
||||
filename,
|
||||
@@ -758,6 +777,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
xfer_protocol_string[protocol]);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_FILE_SEND_ACTIVE:
|
||||
case XFER_TYPE_FILE_SEND_PASSIVE:
|
||||
weechat_printf (NULL,
|
||||
_("%s: offering file to %s (%s.%s), name: %s "
|
||||
@@ -778,7 +798,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
"(%s, %s.%s)"),
|
||||
XFER_PLUGIN_NAME,
|
||||
remote_nick,
|
||||
str_address,
|
||||
new_xfer->remote_address_str,
|
||||
plugin_name,
|
||||
plugin_id);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
@@ -990,13 +1010,14 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
struct t_infolist *infolist;
|
||||
const char *plugin_name, *plugin_id, *str_type, *str_protocol;
|
||||
const char *remote_nick, *local_nick, *charset_modifier, *filename, *proxy;
|
||||
const char *str_address, *str_port;
|
||||
int type, protocol, args, port_start, port_end, sock, port;
|
||||
const char *str_address, *str_port, *token;
|
||||
int type, protocol, args, port_start, port_end, sock, server_sock, port;
|
||||
char *path, *filename2, *short_filename, *pos, str_port_temp[16];
|
||||
struct stat st;
|
||||
struct sockaddr_storage addr, own_ip_addr, bind_addr;
|
||||
struct sockaddr *out_addr = (struct sockaddr*)&addr;
|
||||
socklen_t length, bind_addr_len;
|
||||
struct sockaddr_storage local_addr_storage, remote_addr_storage, own_ip_addr, bind_addr;
|
||||
struct sockaddr *local_addr = (struct sockaddr*)&local_addr_storage;
|
||||
struct sockaddr *remote_addr = (struct sockaddr*)&remote_addr_storage;
|
||||
socklen_t local_addr_length, remote_addr_length, bind_addr_len;
|
||||
unsigned long long file_size;
|
||||
struct t_xfer *ptr_xfer;
|
||||
struct t_hashtable *options;
|
||||
@@ -1040,6 +1061,7 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
charset_modifier = weechat_infolist_string (infolist, "charset_modifier");
|
||||
filename = weechat_infolist_string (infolist, "filename");
|
||||
proxy = weechat_infolist_string (infolist, "proxy");
|
||||
token = weechat_infolist_string (infolist, "token");
|
||||
protocol = XFER_NO_PROTOCOL;
|
||||
|
||||
if (!plugin_name || !plugin_id || !str_type || !remote_nick || !local_nick)
|
||||
@@ -1080,7 +1102,7 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
if (type == XFER_TYPE_FILE_RECV_ACTIVE)
|
||||
if (XFER_IS_RECV(type))
|
||||
{
|
||||
filename2 = strdup (filename);
|
||||
sscanf (weechat_infolist_string (infolist, "size"), "%llu", &file_size);
|
||||
@@ -1157,20 +1179,31 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
port = weechat_infolist_integer (infolist, "port");
|
||||
|
||||
/* resolve address */
|
||||
if (XFER_IS_RECV(type))
|
||||
if ((type == XFER_TYPE_CHAT_RECV) || (type == XFER_TYPE_FILE_RECV_ACTIVE))
|
||||
{
|
||||
str_address = weechat_infolist_string (infolist, "remote_address");
|
||||
snprintf (str_port_temp, sizeof (str_port_temp), "%d", port);
|
||||
str_port = str_port_temp;
|
||||
length = sizeof (addr);
|
||||
remote_addr_length = sizeof (remote_addr_storage);
|
||||
if (!xfer_network_resolve_addr (str_address, str_port,
|
||||
(struct sockaddr*)&addr, &length,
|
||||
(struct sockaddr*)&remote_addr_storage, &remote_addr_length,
|
||||
AI_NUMERICSERV | AI_NUMERICHOST))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (type == XFER_TYPE_FILE_RECV_PASSIVE)
|
||||
{
|
||||
str_address = weechat_infolist_string (infolist, "remote_address");
|
||||
remote_addr_length = sizeof (remote_addr_storage);
|
||||
if (!xfer_network_resolve_addr (str_address, NULL,
|
||||
(struct sockaddr*)&remote_addr_storage, &remote_addr_length,
|
||||
AI_NUMERICSERV | AI_NUMERICHOST))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (XFER_IS_PASSIVE(type))
|
||||
{
|
||||
memset (&bind_addr, 0, sizeof (bind_addr));
|
||||
|
||||
@@ -1180,18 +1213,18 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
{
|
||||
/* resolve own_ip to a numeric address */
|
||||
str_address = weechat_config_string (xfer_config_network_own_ip);
|
||||
length = sizeof (own_ip_addr);
|
||||
local_addr_length = sizeof (own_ip_addr);
|
||||
|
||||
if (!xfer_network_resolve_addr (str_address, NULL,
|
||||
(struct sockaddr*)&own_ip_addr,
|
||||
&length,
|
||||
&local_addr_length,
|
||||
AI_NUMERICSERV))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set the advertised address to own_ip */
|
||||
out_addr = (struct sockaddr*)&own_ip_addr;
|
||||
local_addr = (struct sockaddr*)&own_ip_addr;
|
||||
|
||||
/* bind_addr's family should be the advertised family */
|
||||
bind_addr.ss_family = own_ip_addr.ss_family;
|
||||
@@ -1199,15 +1232,15 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
else
|
||||
{
|
||||
/* no own_ip, so bind_addr's family comes from irc connection */
|
||||
str_address = weechat_infolist_string (infolist, "local_address");
|
||||
length = sizeof (addr);
|
||||
if (!xfer_network_resolve_addr (str_address, NULL,
|
||||
(struct sockaddr*)&addr, &length,
|
||||
AI_NUMERICSERV | AI_NUMERICHOST))
|
||||
/* use the local interface, from the server socket */
|
||||
memset (&local_addr_storage, 0, sizeof (local_addr_storage));
|
||||
local_addr_length = sizeof (local_addr_storage);
|
||||
server_sock = weechat_infolist_integer (infolist, "socket");
|
||||
if (getsockname (server_sock, (struct sockaddr *)&local_addr_storage, &local_addr_length))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
bind_addr.ss_family = addr.ss_family;
|
||||
bind_addr.ss_family = local_addr_storage.ss_family;
|
||||
}
|
||||
|
||||
/* determine bind wildcard address */
|
||||
@@ -1318,7 +1351,7 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
if (type == XFER_TYPE_FILE_RECV_ACTIVE)
|
||||
if (XFER_IS_RECV(type))
|
||||
{
|
||||
if (filename2)
|
||||
{
|
||||
@@ -1332,14 +1365,14 @@ xfer_add_cb (const void *pointer, void *data,
|
||||
{
|
||||
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
|
||||
remote_nick, local_nick, charset_modifier,
|
||||
short_filename, file_size, proxy,
|
||||
out_addr, length, port, sock, filename2);
|
||||
short_filename, file_size, proxy, remote_addr,
|
||||
remote_addr_length, local_addr, local_addr_length, port, sock, filename2, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
|
||||
remote_nick, local_nick, charset_modifier, NULL,
|
||||
0, proxy, out_addr, length, port, sock, NULL);
|
||||
0, proxy, NULL, 0, local_addr, local_addr_length, port, sock, NULL, token);
|
||||
}
|
||||
|
||||
if (!ptr_xfer)
|
||||
@@ -1382,7 +1415,7 @@ xfer_start_resume_cb (const void *pointer, void *data,
|
||||
{
|
||||
struct t_infolist *infolist;
|
||||
struct t_xfer *ptr_xfer;
|
||||
const char *plugin_name, *plugin_id, *filename, *str_start_resume;
|
||||
const char *plugin_name, *plugin_id, *filename, *str_start_resume, *token;
|
||||
int port;
|
||||
unsigned long long start_resume;
|
||||
|
||||
@@ -1417,6 +1450,7 @@ xfer_start_resume_cb (const void *pointer, void *data,
|
||||
filename = weechat_infolist_string (infolist, "filename");
|
||||
port = weechat_infolist_integer (infolist, "port");
|
||||
str_start_resume = weechat_infolist_string (infolist, "start_resume");
|
||||
token = weechat_infolist_string (infolist, "token");
|
||||
|
||||
if (!plugin_name || !plugin_id || !filename || !str_start_resume)
|
||||
{
|
||||
@@ -1429,7 +1463,8 @@ xfer_start_resume_cb (const void *pointer, void *data,
|
||||
|
||||
sscanf (str_start_resume, "%llu", &start_resume);
|
||||
|
||||
ptr_xfer = xfer_search (plugin_name, plugin_id, XFER_TYPE_FILE_RECV_ACTIVE,
|
||||
ptr_xfer = xfer_search (plugin_name, plugin_id,
|
||||
(!token) ? XFER_TYPE_FILE_RECV_ACTIVE : XFER_TYPE_FILE_RECV_PASSIVE,
|
||||
XFER_STATUS_CONNECTING, port);
|
||||
if (ptr_xfer)
|
||||
{
|
||||
@@ -1602,6 +1637,8 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "port", xfer->port))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "token", xfer->token))
|
||||
return 0;
|
||||
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "status", xfer->status))
|
||||
return 0;
|
||||
@@ -1709,6 +1746,7 @@ xfer_print_log ()
|
||||
weechat_log_printf (" remote_address_length . : %d", ptr_xfer->remote_address_length);
|
||||
weechat_log_printf (" remote_address_str. . . : '%s'", ptr_xfer->remote_address_str);
|
||||
weechat_log_printf (" port. . . . . . . . . . : %d", ptr_xfer->port);
|
||||
weechat_log_printf (" token . . . . . . . . . : %s", ptr_xfer->token);
|
||||
|
||||
weechat_log_printf (" status. . . . . . . . . : %d (%s)",
|
||||
ptr_xfer->status,
|
||||
|
||||
@@ -160,6 +160,7 @@ struct t_xfer
|
||||
socklen_t remote_address_length; /* remote sockaddr length */
|
||||
char *remote_address_str; /* remote IP address as string */
|
||||
int port; /* remote port */
|
||||
char *token; /* remote passive-DCC token */
|
||||
|
||||
/* internal data */
|
||||
enum t_xfer_status status; /* xfer status (waiting, sending,..) */
|
||||
|
||||
Reference in New Issue
Block a user