mirror of
https://github.com/weechat/weechat.git
synced 2026-06-30 06:46:38 +02:00
xfer: add support of IPv6 for DCC chat/file (patch #7992)
This commit is contained in:
committed by
Sebastien Helleu
parent
9040dfbf52
commit
144dc60d0a
@@ -97,6 +97,7 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
|
||||
* lua: fix crash on calls to callbacks during load of script
|
||||
* python: fix load of scripts with python >= 3.3
|
||||
* ruby: fix ruby init with ruby >= 2.0 (bug #41115)
|
||||
* xfer: add support of IPv6 for DCC chat/file (patch #7992)
|
||||
* xfer: use same infolist for hook and signals (patch #7974)
|
||||
* xfer: add option xfer.file.auto_check_crc32 (patch #7963)
|
||||
|
||||
|
||||
+57
-29
@@ -645,56 +645,84 @@ network_connect (int sock, const struct sockaddr *addr, socklen_t addrlen)
|
||||
* process.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
* >= 0: connected socket fd
|
||||
* -1: error
|
||||
*/
|
||||
|
||||
int
|
||||
network_connect_to (const char *proxy, int sock,
|
||||
unsigned long address, int port)
|
||||
network_connect_to (const char *proxy, struct sockaddr *address,
|
||||
socklen_t address_length)
|
||||
{
|
||||
struct t_proxy *ptr_proxy;
|
||||
struct sockaddr_in addr;
|
||||
struct hostent *hostent;
|
||||
char *ip4;
|
||||
struct addrinfo *proxy_addrinfo, hints;
|
||||
char str_port[16], ip[NI_MAXHOST];
|
||||
int port, sock;
|
||||
|
||||
sock = -1;
|
||||
proxy_addrinfo = NULL;
|
||||
|
||||
ptr_proxy = NULL;
|
||||
if (proxy && proxy[0])
|
||||
{
|
||||
ptr_proxy = proxy_search (proxy);
|
||||
if (!ptr_proxy)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr_proxy)
|
||||
{
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_addr.s_addr = htonl (address);
|
||||
ip4 = inet_ntoa(addr.sin_addr);
|
||||
/* get IP address/port */
|
||||
if (getnameinfo (address, address_length, ip, sizeof (ip),
|
||||
str_port, sizeof (str_port),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
port = atoi (str_port);
|
||||
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_port = htons (CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT]));
|
||||
addr.sin_family = AF_INET;
|
||||
hostent = gethostbyname (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS]));
|
||||
if (!hostent)
|
||||
return 0;
|
||||
memcpy(&(addr.sin_addr), *(hostent->h_addr_list), sizeof(struct in_addr));
|
||||
if (!network_connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
|
||||
return 0;
|
||||
if (!network_pass_proxy (proxy, sock, ip4, port))
|
||||
return 0;
|
||||
/* get sockaddr for proxy */
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_NUMERICSERV;
|
||||
snprintf (str_port, sizeof (str_port), "%d",
|
||||
CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT]));
|
||||
if (getaddrinfo (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS]),
|
||||
str_port, &hints, &proxy_addrinfo) != 0)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* connect and pass address to proxy */
|
||||
sock = socket (proxy_addrinfo->ai_family, SOCK_STREAM, 0);
|
||||
if (sock == -1)
|
||||
goto error;
|
||||
if (!network_connect (sock, proxy_addrinfo->ai_addr,
|
||||
proxy_addrinfo->ai_addrlen))
|
||||
goto error;
|
||||
if (!network_pass_proxy (proxy, sock, ip, port))
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_port = htons (port);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl (address);
|
||||
if (!network_connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
|
||||
return 0;
|
||||
sock = socket (address->sa_family, SOCK_STREAM, 0);
|
||||
if (sock == -1)
|
||||
goto error;
|
||||
if (!network_connect (sock, address, address_length))
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (proxy_addrinfo)
|
||||
freeaddrinfo (proxy_addrinfo);
|
||||
|
||||
return sock;
|
||||
|
||||
error:
|
||||
if (sock >= 0)
|
||||
close (sock);
|
||||
if (proxy_addrinfo)
|
||||
freeaddrinfo (proxy_addrinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#ifndef __WEECHAT_NETWORK_H
|
||||
#define __WEECHAT_NETWORK_H 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct t_hook;
|
||||
|
||||
struct t_network_socks4
|
||||
@@ -48,8 +51,8 @@ extern void network_init_gnutls ();
|
||||
extern void network_end ();
|
||||
extern int network_pass_proxy (const char *proxy, int sock,
|
||||
const char *address, int port);
|
||||
extern int network_connect_to (const char *proxy, int sock,
|
||||
unsigned long address, int port);
|
||||
extern int network_connect_to (const char *proxy, struct sockaddr *address,
|
||||
socklen_t address_length);
|
||||
extern void network_connect_with_fork (struct t_hook *hook_connect);
|
||||
|
||||
#endif /* __WEECHAT_NETWORK_H */
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "irc.h"
|
||||
@@ -1380,12 +1381,12 @@ int
|
||||
irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
|
||||
char **argv, char **argv_eol)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t length;
|
||||
unsigned long address;
|
||||
struct t_infolist *infolist;
|
||||
struct t_infolist_item *item;
|
||||
char str_address[128], charset_modifier[256];
|
||||
char str_address[NI_MAXHOST], charset_modifier[256];
|
||||
int rc;
|
||||
|
||||
IRC_BUFFER_GET_SERVER_CHANNEL(buffer);
|
||||
IRC_COMMAND_CHECK_SERVER("dcc", 1);
|
||||
@@ -1396,11 +1397,20 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
|
||||
if (argc > 1)
|
||||
{
|
||||
/* use the local interface, from the server socket */
|
||||
memset (&addr, 0, sizeof (struct sockaddr_in));
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
length = sizeof (addr);
|
||||
getsockname (ptr_server->sock, (struct sockaddr *) &addr, &length);
|
||||
addr.sin_family = AF_INET;
|
||||
address = ntohl (addr.sin_addr.s_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;
|
||||
}
|
||||
|
||||
/* DCC SEND file */
|
||||
if (weechat_strcasecmp (argv[1], "send") == 0)
|
||||
@@ -1422,8 +1432,6 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
|
||||
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]);
|
||||
snprintf (str_address, sizeof (str_address),
|
||||
"%lu", address);
|
||||
weechat_infolist_new_var_string (item, "local_address", str_address);
|
||||
weechat_infolist_new_var_integer (item, "socket", ptr_server->sock);
|
||||
weechat_hook_signal_send ("xfer_add",
|
||||
@@ -1454,8 +1462,6 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
|
||||
snprintf (charset_modifier, sizeof (charset_modifier),
|
||||
"irc.%s.%s", ptr_server->name, argv[2]);
|
||||
weechat_infolist_new_var_string (item, "charset_modifier", charset_modifier);
|
||||
snprintf (str_address, sizeof (str_address),
|
||||
"%lu", address);
|
||||
weechat_infolist_new_var_string (item, "local_address", str_address);
|
||||
weechat_hook_signal_send ("xfer_add",
|
||||
WEECHAT_HOOK_SIGNAL_POINTER,
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
@@ -4402,8 +4405,11 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal,
|
||||
{
|
||||
struct t_infolist *infolist;
|
||||
struct t_irc_server *ptr_server;
|
||||
const char *plugin_name, *plugin_id, *type, *filename;
|
||||
int spaces_in_name;
|
||||
const char *plugin_name, *plugin_id, *type, *filename, *local_address;
|
||||
char converted_addr[NI_MAXHOST];
|
||||
struct addrinfo *ainfo;
|
||||
struct sockaddr_in *saddr;
|
||||
int spaces_in_name, rc;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
@@ -4416,14 +4422,40 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal,
|
||||
{
|
||||
plugin_name = weechat_infolist_string (infolist, "plugin_name");
|
||||
plugin_id = weechat_infolist_string (infolist, "plugin_id");
|
||||
if (plugin_name && (strcmp (plugin_name, IRC_PLUGIN_NAME) == 0) && plugin_id)
|
||||
if (plugin_name && (strcmp (plugin_name, IRC_PLUGIN_NAME) == 0)
|
||||
&& plugin_id)
|
||||
{
|
||||
ptr_server = irc_server_search (plugin_id);
|
||||
if (ptr_server)
|
||||
{
|
||||
type = weechat_infolist_string (infolist, "type_string");
|
||||
if (type)
|
||||
converted_addr[0] = '\0';
|
||||
local_address = weechat_infolist_string (infolist,
|
||||
"local_address");
|
||||
if (local_address)
|
||||
{
|
||||
rc = getaddrinfo (local_address, NULL, NULL, &ainfo);
|
||||
if ((rc == 0) && ainfo && ainfo->ai_addr)
|
||||
{
|
||||
if (ainfo->ai_family == AF_INET)
|
||||
{
|
||||
/* transform dotted 4 IP address to ulong string */
|
||||
saddr = (struct sockaddr_in *)ainfo->ai_addr;
|
||||
snprintf (converted_addr, sizeof (converted_addr),
|
||||
"%lu",
|
||||
(unsigned long)ntohl (saddr->sin_addr.s_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (converted_addr, sizeof (converted_addr),
|
||||
"%s", local_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type = weechat_infolist_string (infolist, "type_string");
|
||||
if (type && converted_addr[0])
|
||||
{
|
||||
/* send DCC PRIVMSG */
|
||||
if (strcmp (type, "file_send") == 0)
|
||||
{
|
||||
filename = weechat_infolist_string (infolist, "filename");
|
||||
@@ -4436,7 +4468,7 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal,
|
||||
(spaces_in_name) ? "\"" : "",
|
||||
filename,
|
||||
(spaces_in_name) ? "\"" : "",
|
||||
weechat_infolist_string (infolist, "local_address"),
|
||||
converted_addr,
|
||||
weechat_infolist_integer (infolist, "port"),
|
||||
weechat_infolist_string (infolist, "size"));
|
||||
}
|
||||
@@ -4446,7 +4478,7 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal,
|
||||
IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL,
|
||||
"PRIVMSG %s :\01DCC CHAT chat %s %d\01",
|
||||
weechat_infolist_string (infolist, "remote_nick"),
|
||||
weechat_infolist_string (infolist, "local_address"),
|
||||
converted_addr,
|
||||
weechat_infolist_integer (infolist, "port"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* some systems like GNU/Hurd do not define PATH_MAX */
|
||||
#ifndef PATH_MAX
|
||||
@@ -56,7 +57,7 @@ struct timeval;
|
||||
* please change the date with current one; for a second change at same
|
||||
* date, increment the 01, otherwise please keep 01.
|
||||
*/
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20140105-01"
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20140109-01"
|
||||
|
||||
/* macros for defining plugin infos */
|
||||
#define WEECHAT_PLUGIN_NAME(__name) \
|
||||
@@ -807,8 +808,9 @@ struct t_weechat_plugin
|
||||
/* network */
|
||||
int (*network_pass_proxy) (const char *proxy, int sock,
|
||||
const char *address, int port);
|
||||
int (*network_connect_to) (const char *proxy, int sock,
|
||||
unsigned long address, int port);
|
||||
int (*network_connect_to) (const char *proxy,
|
||||
struct sockaddr *address,
|
||||
socklen_t address_length);
|
||||
|
||||
/* infos */
|
||||
const char *(*info_get) (struct t_weechat_plugin *plugin,
|
||||
@@ -1587,9 +1589,10 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
||||
#define weechat_network_pass_proxy(__proxy, __sock, __address, __port) \
|
||||
weechat_plugin->network_pass_proxy(__proxy, __sock, __address, \
|
||||
__port)
|
||||
#define weechat_network_connect_to(__proxy, __sock, __address, __port) \
|
||||
weechat_plugin->network_connect_to(__proxy, __sock, __address, \
|
||||
__port)
|
||||
#define weechat_network_connect_to(__proxy, __address, \
|
||||
__address_length) \
|
||||
weechat_plugin->network_connect_to(__proxy, __address, \
|
||||
__address_length)
|
||||
|
||||
/* infos */
|
||||
#define weechat_info_get(__info_name, __arguments) \
|
||||
|
||||
@@ -44,7 +44,7 @@ xfer_buffer_refresh (const char *hotlist)
|
||||
{
|
||||
struct t_xfer *ptr_xfer, *xfer_selected;
|
||||
char str_color[256], suffix[32], status[64], date[128], eta[128];
|
||||
char str_ip[32], str_hash[128];
|
||||
char str_ip[128], str_hash[128];
|
||||
char *progress_bar, *str_pos, *str_total, *str_bytes_per_sec;
|
||||
int i, length, line, progress_bar_size, num_bars;
|
||||
unsigned long long pos, pct_complete;
|
||||
@@ -93,14 +93,11 @@ xfer_buffer_refresh (const char *hotlist)
|
||||
weechat_config_string (xfer_config_color_text_bg));
|
||||
|
||||
str_ip[0] = '\0';
|
||||
if (ptr_xfer->remote_address != 0)
|
||||
if (ptr_xfer->remote_address_str)
|
||||
{
|
||||
snprintf (str_ip, sizeof (str_ip),
|
||||
" (%ld.%ld.%ld.%ld)",
|
||||
ptr_xfer->remote_address >> 24,
|
||||
(ptr_xfer->remote_address >> 16) & 0xff,
|
||||
(ptr_xfer->remote_address >> 8) & 0xff,
|
||||
ptr_xfer->remote_address & 0xff);
|
||||
" (%s)",
|
||||
ptr_xfer->remote_address_str);
|
||||
}
|
||||
|
||||
str_hash[0] = '\0';
|
||||
|
||||
@@ -372,14 +372,11 @@ xfer_chat_open_buffer (struct t_xfer *xfer)
|
||||
}
|
||||
|
||||
weechat_printf (xfer->buffer,
|
||||
_("%s%s: connected to %s (%ld.%ld.%ld.%ld)"),
|
||||
_("%s%s: connected to %s (%s) via xfer chat"),
|
||||
weechat_prefix ("network"),
|
||||
XFER_PLUGIN_NAME,
|
||||
xfer->remote_nick,
|
||||
xfer->remote_address >> 24,
|
||||
(xfer->remote_address >> 16) & 0xff,
|
||||
(xfer->remote_address >> 8) & 0xff,
|
||||
xfer->remote_address & 0xff);
|
||||
xfer->remote_address_str);
|
||||
|
||||
free (name);
|
||||
}
|
||||
|
||||
@@ -157,15 +157,12 @@ xfer_command_xfer_list (int full)
|
||||
weechat_printf (NULL,
|
||||
_(" plugin: %s (id: %s), file: %llu "
|
||||
"bytes (position: %llu), address: "
|
||||
"%ld.%ld.%ld.%ld (port %d)"),
|
||||
"%s (port %d)"),
|
||||
ptr_xfer->plugin_name,
|
||||
ptr_xfer->plugin_id,
|
||||
ptr_xfer->size,
|
||||
ptr_xfer->pos,
|
||||
ptr_xfer->remote_address >> 24,
|
||||
(ptr_xfer->remote_address >> 16) & 0xff,
|
||||
(ptr_xfer->remote_address >> 8) & 0xff,
|
||||
ptr_xfer->remote_address & 0xff,
|
||||
ptr_xfer->remote_address_str,
|
||||
ptr_xfer->port);
|
||||
date[0] = '\0';
|
||||
date_tmp = localtime (&(ptr_xfer->start_transfer));
|
||||
|
||||
@@ -327,8 +327,10 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
|
||||
}
|
||||
|
||||
/* first connect to sender (blocking) */
|
||||
if (!weechat_network_connect_to (xfer->proxy, xfer->sock,
|
||||
xfer->remote_address, xfer->port))
|
||||
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);
|
||||
|
||||
@@ -253,14 +253,11 @@ xfer_network_send_file_fork (struct t_xfer *xfer)
|
||||
}
|
||||
|
||||
weechat_printf (NULL,
|
||||
_("%s: sending file to %s (%ld.%ld.%ld.%ld, %s.%s), "
|
||||
_("%s: sending file to %s (%s, %s.%s), "
|
||||
"name: %s (local filename: %s), %llu bytes (protocol: %s)"),
|
||||
XFER_PLUGIN_NAME,
|
||||
xfer->remote_nick,
|
||||
xfer->remote_address >> 24,
|
||||
(xfer->remote_address >> 16) & 0xff,
|
||||
(xfer->remote_address >> 8) & 0xff,
|
||||
xfer->remote_address & 0xff,
|
||||
xfer->remote_address_str,
|
||||
xfer->plugin_name,
|
||||
xfer->plugin_id,
|
||||
xfer->filename,
|
||||
@@ -375,12 +372,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd)
|
||||
{
|
||||
struct t_xfer *xfer;
|
||||
int sock, flags, error;
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t length;
|
||||
char str_address[NI_MAXHOST];
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) fd;
|
||||
|
||||
length = sizeof (addr);
|
||||
memset (&addr, 0, length);
|
||||
xfer = (struct t_xfer *)arg_xfer;
|
||||
|
||||
if (xfer->status == XFER_STATUS_CONNECTING)
|
||||
@@ -388,7 +388,6 @@ xfer_network_fd_cb (void *arg_xfer, int fd)
|
||||
if (xfer->type == XFER_TYPE_FILE_SEND)
|
||||
{
|
||||
xfer->last_activity = time (NULL);
|
||||
length = sizeof (addr);
|
||||
sock = accept (xfer->sock,
|
||||
(struct sockaddr *) &addr, &length);
|
||||
error = errno;
|
||||
@@ -422,7 +421,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd)
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
xfer->remote_address = ntohl (addr.sin_addr.s_addr);
|
||||
error = getnameinfo ((struct sockaddr *)&addr, length, str_address,
|
||||
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
|
||||
if (error != 0)
|
||||
{
|
||||
snprintf (str_address, sizeof (str_address),
|
||||
"error: %s", gai_strerror (error));
|
||||
}
|
||||
xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length,
|
||||
str_address);
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer->start_transfer = time (NULL);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
@@ -467,7 +474,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd)
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
xfer->remote_address = ntohl (addr.sin_addr.s_addr);
|
||||
error = getnameinfo ((struct sockaddr *)&addr, length, str_address,
|
||||
sizeof (str_address), NULL, 0, NI_NUMERICHOST);
|
||||
if (error != 0)
|
||||
{
|
||||
snprintf (str_address, sizeof (str_address),
|
||||
"error: %s", gai_strerror (error));
|
||||
}
|
||||
xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length,
|
||||
str_address);
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
xfer->hook_fd = weechat_hook_fd (xfer->sock,
|
||||
@@ -528,15 +543,17 @@ xfer_network_connect (struct t_xfer *xfer)
|
||||
else
|
||||
xfer->status = XFER_STATUS_CONNECTING;
|
||||
|
||||
if (xfer->sock < 0)
|
||||
{
|
||||
xfer->sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (xfer->sock < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (XFER_IS_SEND(xfer->type))
|
||||
{
|
||||
/* create socket */
|
||||
if (xfer->sock < 0)
|
||||
{
|
||||
xfer->sock = socket (xfer->remote_address->sa_family, SOCK_STREAM,
|
||||
0);
|
||||
if (xfer->sock < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* listen to socket */
|
||||
flags = fcntl (xfer->sock, F_GETFL);
|
||||
if (flags == -1)
|
||||
@@ -566,13 +583,21 @@ xfer_network_connect (struct t_xfer *xfer)
|
||||
/* for chat receiving, connect to listening host */
|
||||
if (xfer->type == XFER_TYPE_CHAT_RECV)
|
||||
{
|
||||
xfer->sock = weechat_network_connect_to (xfer->proxy,
|
||||
xfer->remote_address,
|
||||
xfer->remote_address_length);
|
||||
if (xfer->sock < 0)
|
||||
return 0;
|
||||
|
||||
flags = fcntl (xfer->sock, F_GETFL);
|
||||
if (flags == -1)
|
||||
flags = 0;
|
||||
if (fcntl (xfer->sock, F_SETFL, flags | O_NONBLOCK) == -1)
|
||||
{
|
||||
close (xfer->sock);
|
||||
xfer->sock = -1;
|
||||
return 0;
|
||||
weechat_network_connect_to (xfer->proxy, xfer->sock,
|
||||
xfer->remote_address, xfer->port);
|
||||
}
|
||||
|
||||
xfer->hook_fd = weechat_hook_fd (xfer->sock,
|
||||
1, 0, 0,
|
||||
|
||||
+202
-149
@@ -31,6 +31,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <gcrypt.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
@@ -300,16 +301,13 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
|
||||
if (XFER_IS_FILE(xfer->type))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: file %s %s %s (%ld.%ld.%ld.%ld): %s"),
|
||||
_("%s%s: file %s %s %s (%s): %s"),
|
||||
(xfer->status == XFER_STATUS_DONE) ? "" : weechat_prefix ("error"),
|
||||
XFER_PLUGIN_NAME,
|
||||
xfer->filename,
|
||||
(xfer->type == XFER_TYPE_FILE_SEND) ? _("sent to") : _("received from"),
|
||||
xfer->remote_nick,
|
||||
xfer->remote_address >> 24,
|
||||
(xfer->remote_address >> 16) & 0xff,
|
||||
(xfer->remote_address >> 8) & 0xff,
|
||||
xfer->remote_address & 0xff,
|
||||
xfer->remote_address_str,
|
||||
(xfer->status == XFER_STATUS_DONE) ? _("OK") : _("FAILED"));
|
||||
xfer_network_child_kill (xfer);
|
||||
}
|
||||
@@ -320,14 +318,11 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
|
||||
{
|
||||
weechat_printf (xfer->buffer,
|
||||
_("%s%s: chat closed with %s "
|
||||
"(%ld.%ld.%ld.%ld)"),
|
||||
"(%s)"),
|
||||
weechat_prefix ("network"),
|
||||
XFER_PLUGIN_NAME,
|
||||
xfer->remote_nick,
|
||||
xfer->remote_address >> 24,
|
||||
(xfer->remote_address >> 16) & 0xff,
|
||||
(xfer->remote_address >> 8) & 0xff,
|
||||
xfer->remote_address & 0xff);
|
||||
xfer->remote_address_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,8 +452,12 @@ xfer_alloc ()
|
||||
/* default values */
|
||||
new_xfer->filename = NULL;
|
||||
new_xfer->size = 0;
|
||||
new_xfer->local_address = 0;
|
||||
new_xfer->remote_address = 0;
|
||||
new_xfer->local_address = NULL;
|
||||
new_xfer->local_address_length = 0;
|
||||
new_xfer->local_address_str = NULL;
|
||||
new_xfer->remote_address = NULL;
|
||||
new_xfer->remote_address_length = 0;
|
||||
new_xfer->remote_address_str = NULL;
|
||||
new_xfer->port = 0;
|
||||
new_xfer->remote_nick = NULL;
|
||||
new_xfer->local_nick = NULL;
|
||||
@@ -616,11 +615,14 @@ 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, unsigned long address,
|
||||
int port, int sock, const char *local_filename)
|
||||
unsigned long long size, const char *proxy, struct sockaddr *address,
|
||||
socklen_t address_length, int port, int sock,
|
||||
const char *local_filename)
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
const char *ptr_color, *ptr_crc32;
|
||||
char str_address[NI_MAXHOST];
|
||||
int rc;
|
||||
|
||||
new_xfer = xfer_alloc ();
|
||||
if (!new_xfer)
|
||||
@@ -653,17 +655,36 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
new_xfer->filename = strdup (_("xfer chat"));
|
||||
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->local_address = calloc (1, sizeof (struct sockaddr_storage));
|
||||
new_xfer->local_address_length = sizeof (struct sockaddr_storage);
|
||||
new_xfer->remote_address = calloc (1, sizeof (struct sockaddr_storage));
|
||||
new_xfer->remote_address_length = sizeof (struct sockaddr_storage);
|
||||
|
||||
if (XFER_IS_RECV(type))
|
||||
{
|
||||
new_xfer->local_address = 0;
|
||||
new_xfer->remote_address = address;
|
||||
new_xfer->local_address_str = strdup ("");
|
||||
new_xfer->remote_address_str = strdup (str_address);
|
||||
memcpy (new_xfer->remote_address, address, address_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_xfer->local_address = address;
|
||||
new_xfer->remote_address = 0;
|
||||
new_xfer->local_address_str = strdup (str_address);
|
||||
memcpy (new_xfer->local_address, address, address_length);
|
||||
new_xfer->remote_address_str = strdup ("");
|
||||
}
|
||||
new_xfer->port = port;
|
||||
|
||||
new_xfer->status = XFER_STATUS_WAITING;
|
||||
new_xfer->sock = sock;
|
||||
@@ -708,14 +729,11 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
case XFER_TYPE_FILE_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming file from %s "
|
||||
"(%ld.%ld.%ld.%ld, %s.%s), name: %s, %llu bytes "
|
||||
"(%s, %s.%s), name: %s, %llu bytes "
|
||||
"(protocol: %s)"),
|
||||
XFER_PLUGIN_NAME,
|
||||
remote_nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff,
|
||||
str_address,
|
||||
plugin_name,
|
||||
plugin_id,
|
||||
filename,
|
||||
@@ -740,13 +758,10 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
case XFER_TYPE_CHAT_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming chat request from %s "
|
||||
"(%ld.%ld.%ld.%ld, %s.%s)"),
|
||||
"(%s, %s.%s)"),
|
||||
XFER_PLUGIN_NAME,
|
||||
remote_nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff,
|
||||
str_address,
|
||||
plugin_name,
|
||||
plugin_id);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
@@ -814,6 +829,25 @@ xfer_new (const char *plugin_name, const char *plugin_id,
|
||||
return new_xfer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the remote address field.
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_set_remote_address (struct t_xfer *xfer, struct sockaddr *address,
|
||||
socklen_t length, char *address_str)
|
||||
{
|
||||
if (xfer->remote_address)
|
||||
free (xfer->remote_address);
|
||||
xfer->remote_address = calloc (1, length);
|
||||
xfer->remote_address_length = length;
|
||||
memcpy (xfer->remote_address, address, length);
|
||||
|
||||
if (xfer->remote_address_str)
|
||||
free (xfer->remote_address_str);
|
||||
xfer->remote_address_str = strdup ((address_str) ? address_str : "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees xfer struct and removes it from list.
|
||||
*/
|
||||
@@ -850,6 +884,14 @@ xfer_free (struct t_xfer *xfer)
|
||||
free (xfer->charset_modifier);
|
||||
if (xfer->filename)
|
||||
free (xfer->filename);
|
||||
if (xfer->local_address)
|
||||
free (xfer->local_address);
|
||||
if (xfer->local_address_str)
|
||||
free (xfer->local_address_str);
|
||||
if (xfer->remote_address)
|
||||
free (xfer->remote_address);
|
||||
if (xfer->remote_address_str)
|
||||
free (xfer->remote_address_str);
|
||||
if (xfer->remote_nick_color)
|
||||
free (xfer->remote_nick_color);
|
||||
if (xfer->unterminated_message)
|
||||
@@ -884,15 +926,13 @@ xfer_add_cb (void *data, const char *signal, const char *type_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;
|
||||
int type, protocol, args, port_start, port_end, sock, port;
|
||||
const char *weechat_dir;
|
||||
char *dir1, *dir2, *filename2, *short_filename, *pos;
|
||||
const char *weechat_dir, *str_address, *str_port;
|
||||
int type, protocol, args, port_start, port_end, sock, port, rc, own_ip_used;
|
||||
char *dir1, *dir2, *filename2, *short_filename, *pos, str_port_temp[16];
|
||||
struct stat st;
|
||||
struct hostent *host;
|
||||
struct sockaddr_in addr;
|
||||
struct addrinfo *ainfo, hints;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t length;
|
||||
struct in_addr tmpaddr;
|
||||
unsigned long local_addr;
|
||||
unsigned long long file_size;
|
||||
struct t_xfer *ptr_xfer;
|
||||
|
||||
@@ -921,6 +961,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
|
||||
filename2 = NULL;
|
||||
short_filename = NULL;
|
||||
file_size = 0;
|
||||
|
||||
sock = -1;
|
||||
port = 0;
|
||||
@@ -974,10 +1015,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
}
|
||||
}
|
||||
|
||||
filename2 = NULL;
|
||||
file_size = 0;
|
||||
port = 0;
|
||||
|
||||
if (type == XFER_TYPE_FILE_RECV)
|
||||
{
|
||||
filename2 = strdup (filename);
|
||||
@@ -1029,10 +1066,8 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
if (filename2[strlen (filename2) - 1] != DIR_SEPARATOR_CHAR)
|
||||
strcat (filename2, DIR_SEPARATOR);
|
||||
strcat (filename2, filename);
|
||||
if (dir1)
|
||||
free (dir1);
|
||||
if (dir2)
|
||||
free (dir2);
|
||||
free (dir1);
|
||||
free (dir2);
|
||||
}
|
||||
#endif
|
||||
/* check if file exists */
|
||||
@@ -1042,66 +1077,75 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
_("%s%s: cannot access file \"%s\""),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
filename2);
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
goto error;
|
||||
}
|
||||
file_size = st.st_size;
|
||||
}
|
||||
port = weechat_infolist_integer (infolist, "port");
|
||||
|
||||
/* set address */
|
||||
memset (&hints, 0, sizeof (struct addrinfo));
|
||||
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
|
||||
hints.ai_family = AF_UNSPEC; /* allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
own_ip_used = 0;
|
||||
|
||||
if (XFER_IS_RECV(type))
|
||||
{
|
||||
sscanf (weechat_infolist_string (infolist, "remote_address"), "%lu", &local_addr);
|
||||
port = weechat_infolist_integer (infolist, "port");
|
||||
str_address = weechat_infolist_string (infolist, "remote_address");
|
||||
snprintf (str_port_temp, sizeof (str_port_temp), "%d", port);
|
||||
str_port = str_port_temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get local IP address */
|
||||
sscanf (weechat_infolist_string (infolist, "local_address"), "%lu", &local_addr);
|
||||
|
||||
memset (&addr, 0, sizeof (struct sockaddr_in));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl (local_addr);
|
||||
|
||||
/* look up the IP address from network_own_ip, if set */
|
||||
if (weechat_config_string(xfer_config_network_own_ip)
|
||||
&& weechat_config_string(xfer_config_network_own_ip)[0])
|
||||
str_port = NULL;
|
||||
if (weechat_config_string (xfer_config_network_own_ip)
|
||||
&& weechat_config_string (xfer_config_network_own_ip)[0])
|
||||
{
|
||||
host = gethostbyname (weechat_config_string (xfer_config_network_own_ip));
|
||||
if (host)
|
||||
{
|
||||
memcpy (&tmpaddr, host->h_addr_list[0], sizeof(struct in_addr));
|
||||
local_addr = ntohl (tmpaddr.s_addr);
|
||||
|
||||
sock = weechat_infolist_integer (infolist, "socket");
|
||||
if (sock > 0)
|
||||
{
|
||||
memset (&addr, 0, sizeof (struct sockaddr_in));
|
||||
length = sizeof (addr);
|
||||
getsockname (sock, (struct sockaddr *) &addr, &length);
|
||||
addr.sin_family = AF_INET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: could not find address for \"%s\", "
|
||||
"falling back to local IP"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
weechat_config_string (xfer_config_network_own_ip));
|
||||
}
|
||||
str_address = weechat_config_string (xfer_config_network_own_ip);
|
||||
hints.ai_flags = AI_NUMERICSERV;
|
||||
own_ip_used = 1;
|
||||
}
|
||||
else
|
||||
str_address = weechat_infolist_string (infolist, "local_address");
|
||||
}
|
||||
|
||||
rc = getaddrinfo (str_address, str_port, &hints, &ainfo);
|
||||
if ((rc == 0) && ainfo && ainfo->ai_addr)
|
||||
{
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
memcpy (&addr, ainfo->ai_addr, ainfo->ai_addrlen);
|
||||
length = ainfo->ai_addrlen;
|
||||
freeaddrinfo (ainfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
(own_ip_used) ?
|
||||
_("%s%s: invalid address \"%s\" (option "
|
||||
"xfer.network.own_ip): error %d %s") :
|
||||
_("%s%s: unable to find address for \"%s\": "
|
||||
"error %d %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
str_address, rc, gai_strerror (rc));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (XFER_IS_SEND(type))
|
||||
{
|
||||
/* open socket for xfer */
|
||||
sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
sock = socket (addr.ss_family, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: cannot create socket for xfer: error %d %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
errno, strerror (errno));
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1126,8 +1170,11 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
if (!xfer_port_in_use (port))
|
||||
{
|
||||
/* attempt to bind to the free port */
|
||||
addr.sin_port = htons (port);
|
||||
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
|
||||
if (addr.ss_family == AF_INET)
|
||||
((struct sockaddr_in *)&addr)->sin_port = htons (port);
|
||||
else
|
||||
((struct sockaddr_in6 *)&addr)->sin6_port = htons (port);
|
||||
if (bind (sock, (struct sockaddr *)&addr, length) == 0)
|
||||
break;
|
||||
}
|
||||
port++;
|
||||
@@ -1141,12 +1188,13 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
if (port == 0)
|
||||
{
|
||||
/* find port automatically */
|
||||
addr.sin_port = 0;
|
||||
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
|
||||
if (bind (sock, (struct sockaddr *)&addr, length) == 0)
|
||||
{
|
||||
length = sizeof (addr);
|
||||
getsockname (sock, (struct sockaddr *) &addr, &length);
|
||||
port = ntohs (addr.sin_port);
|
||||
getsockname (sock, (struct sockaddr *)&addr, &length);
|
||||
if (addr.ss_family == AF_INET)
|
||||
port = ntohs (((struct sockaddr_in *)&addr)->sin_port);
|
||||
else
|
||||
port = ntohs (((struct sockaddr_in6 *)&addr)->sin6_port);
|
||||
}
|
||||
else
|
||||
port = -1;
|
||||
@@ -1159,8 +1207,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
_("%s%s: cannot find available port for xfer"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME);
|
||||
close (sock);
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -1198,14 +1244,20 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
|
||||
/* add xfer entry and listen to socket if type is file or chat "send" */
|
||||
if (XFER_IS_FILE(type))
|
||||
{
|
||||
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
|
||||
remote_nick, local_nick, charset_modifier,
|
||||
short_filename, file_size, proxy, local_addr,
|
||||
port, sock, filename2);
|
||||
short_filename, file_size, proxy,
|
||||
(struct sockaddr *)&addr, length, port, sock,
|
||||
filename2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
|
||||
remote_nick, local_nick, charset_modifier, NULL,
|
||||
0, proxy, local_addr, port, sock, NULL);
|
||||
0, proxy, (struct sockaddr *)&addr, length,
|
||||
port, sock, NULL);
|
||||
}
|
||||
|
||||
if (!ptr_xfer)
|
||||
{
|
||||
@@ -1213,10 +1265,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
_("%s%s: error creating xfer"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME);
|
||||
close (sock);
|
||||
if (short_filename)
|
||||
free (short_filename);
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1224,15 +1272,18 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
|
||||
if (XFER_IS_SEND(ptr_xfer->type) && !XFER_HAS_ENDED(ptr_xfer->status))
|
||||
xfer_send_signal (ptr_xfer, "xfer_send_ready");
|
||||
|
||||
if (short_filename)
|
||||
free (short_filename);
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
|
||||
if (short_filename)
|
||||
free (short_filename);
|
||||
weechat_infolist_reset_item_cursor (infolist);
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
error:
|
||||
if (filename2)
|
||||
free (filename2);
|
||||
if (short_filename)
|
||||
free (short_filename);
|
||||
weechat_infolist_reset_item_cursor (infolist);
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
@@ -1458,11 +1509,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "proxy", xfer->proxy))
|
||||
return 0;
|
||||
snprintf (value, sizeof (value), "%lu", xfer->local_address);
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "local_address", value))
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "local_address", xfer->local_address_str))
|
||||
return 0;
|
||||
snprintf (value, sizeof (value), "%lu", xfer->remote_address);
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "remote_address", value))
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "remote_address", xfer->remote_address_str))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "port", xfer->port))
|
||||
return 0;
|
||||
@@ -1548,57 +1597,61 @@ xfer_print_log ()
|
||||
{
|
||||
weechat_log_printf ("");
|
||||
weechat_log_printf ("[xfer (addr:0x%lx)]", ptr_xfer);
|
||||
weechat_log_printf (" plugin_name . . . . : '%s'", ptr_xfer->plugin_name);
|
||||
weechat_log_printf (" plugin_id . . . . . : '%s'", ptr_xfer->plugin_id);
|
||||
weechat_log_printf (" type. . . . . . . . : %d (%s)",
|
||||
weechat_log_printf (" plugin_name . . . . . . : '%s'", ptr_xfer->plugin_name);
|
||||
weechat_log_printf (" plugin_id . . . . . . . : '%s'", ptr_xfer->plugin_id);
|
||||
weechat_log_printf (" type. . . . . . . . . . : %d (%s)",
|
||||
ptr_xfer->type,
|
||||
xfer_type_string[ptr_xfer->type]);
|
||||
weechat_log_printf (" protocol. . . . . . : %d (%s)",
|
||||
weechat_log_printf (" protocol. . . . . . . . : %d (%s)",
|
||||
ptr_xfer->protocol,
|
||||
xfer_protocol_string[ptr_xfer->protocol]);
|
||||
weechat_log_printf (" remote_nick . . . . : '%s'", ptr_xfer->remote_nick);
|
||||
weechat_log_printf (" local_nick. . . . . : '%s'", ptr_xfer->local_nick);
|
||||
weechat_log_printf (" charset_modifier. . : '%s'", ptr_xfer->charset_modifier);
|
||||
weechat_log_printf (" filename. . . . . . : '%s'", ptr_xfer->filename);
|
||||
weechat_log_printf (" size. . . . . . . . : %llu", ptr_xfer->size);
|
||||
weechat_log_printf (" proxy . . . . . . . : '%s'", ptr_xfer->proxy);
|
||||
weechat_log_printf (" local_address . . . : %lu", ptr_xfer->local_address);
|
||||
weechat_log_printf (" remote_address. . . : %lu", ptr_xfer->remote_address);
|
||||
weechat_log_printf (" port. . . . . . . . : %d", ptr_xfer->port);
|
||||
weechat_log_printf (" remote_nick . . . . . . : '%s'", ptr_xfer->remote_nick);
|
||||
weechat_log_printf (" local_nick. . . . . . . : '%s'", ptr_xfer->local_nick);
|
||||
weechat_log_printf (" charset_modifier. . . . : '%s'", ptr_xfer->charset_modifier);
|
||||
weechat_log_printf (" filename. . . . . . . . : '%s'", ptr_xfer->filename);
|
||||
weechat_log_printf (" size. . . . . . . . . . : %llu", ptr_xfer->size);
|
||||
weechat_log_printf (" proxy . . . . . . . . . : '%s'", ptr_xfer->proxy);
|
||||
weechat_log_printf (" local_address . . . . . : 0x%lx", ptr_xfer->local_address);
|
||||
weechat_log_printf (" local_address_length. . : %d", ptr_xfer->local_address_length);
|
||||
weechat_log_printf (" local_address_str . . . : '%s'" , ptr_xfer->local_address_str);
|
||||
weechat_log_printf (" remote_address. . . . . : 0x%lx", ptr_xfer->remote_address);
|
||||
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 (" status. . . . . . . : %d (%s)",
|
||||
weechat_log_printf (" status. . . . . . . . . : %d (%s)",
|
||||
ptr_xfer->status,
|
||||
xfer_status_string[ptr_xfer->status]);
|
||||
weechat_log_printf (" buffer. . . . . . . : 0x%lx", ptr_xfer->buffer);
|
||||
weechat_log_printf (" remote_nick_color . : '%s'", ptr_xfer->remote_nick_color);
|
||||
weechat_log_printf (" fast_send . . . . . : %d", ptr_xfer->fast_send);
|
||||
weechat_log_printf (" blocksize . . . . . : %d", ptr_xfer->blocksize);
|
||||
weechat_log_printf (" start_time. . . . . : %ld", ptr_xfer->start_time);
|
||||
weechat_log_printf (" start_transfer. . . : %ld", ptr_xfer->start_transfer);
|
||||
weechat_log_printf (" sock. . . . . . . . : %d", ptr_xfer->sock);
|
||||
weechat_log_printf (" child_pid . . . . . : %d", ptr_xfer->child_pid);
|
||||
weechat_log_printf (" child_read. . . . . : %d", ptr_xfer->child_read);
|
||||
weechat_log_printf (" child_write . . . . : %d", ptr_xfer->child_write);
|
||||
weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_xfer->hook_fd);
|
||||
weechat_log_printf (" hook_timer. . . . . : 0x%lx", ptr_xfer->hook_timer);
|
||||
weechat_log_printf (" unterminated_message: '%s'", ptr_xfer->unterminated_message);
|
||||
weechat_log_printf (" file. . . . . . . . : %d", ptr_xfer->file);
|
||||
weechat_log_printf (" local_filename. . . : '%s'", ptr_xfer->local_filename);
|
||||
weechat_log_printf (" filename_suffix . . : %d", ptr_xfer->filename_suffix);
|
||||
weechat_log_printf (" pos . . . . . . . . : %llu", ptr_xfer->pos);
|
||||
weechat_log_printf (" ack . . . . . . . . : %llu", ptr_xfer->ack);
|
||||
weechat_log_printf (" start_resume. . . . : %llu", ptr_xfer->start_resume);
|
||||
weechat_log_printf (" last_check_time . . : %ld", ptr_xfer->last_check_time);
|
||||
weechat_log_printf (" last_check_pos. . . : %llu", ptr_xfer->last_check_pos);
|
||||
weechat_log_printf (" last_activity . . . : %ld", ptr_xfer->last_activity);
|
||||
weechat_log_printf (" bytes_per_sec . . . : %llu", ptr_xfer->bytes_per_sec);
|
||||
weechat_log_printf (" eta . . . . . . . . : %llu", ptr_xfer->eta);
|
||||
weechat_log_printf (" hash_target . . . . : '%s'", ptr_xfer->hash_target);
|
||||
weechat_log_printf (" hash_status . . . . : %d (%s)",
|
||||
weechat_log_printf (" buffer. . . . . . . . . : 0x%lx", ptr_xfer->buffer);
|
||||
weechat_log_printf (" remote_nick_color . . . : '%s'", ptr_xfer->remote_nick_color);
|
||||
weechat_log_printf (" fast_send . . . . . . . : %d", ptr_xfer->fast_send);
|
||||
weechat_log_printf (" blocksize . . . . . . . : %d", ptr_xfer->blocksize);
|
||||
weechat_log_printf (" start_time. . . . . . . : %ld", ptr_xfer->start_time);
|
||||
weechat_log_printf (" start_transfer. . . . . : %ld", ptr_xfer->start_transfer);
|
||||
weechat_log_printf (" sock. . . . . . . . . . : %d", ptr_xfer->sock);
|
||||
weechat_log_printf (" child_pid . . . . . . . : %d", ptr_xfer->child_pid);
|
||||
weechat_log_printf (" child_read. . . . . . . : %d", ptr_xfer->child_read);
|
||||
weechat_log_printf (" child_write . . . . . . : %d", ptr_xfer->child_write);
|
||||
weechat_log_printf (" hook_fd . . . . . . . . : 0x%lx", ptr_xfer->hook_fd);
|
||||
weechat_log_printf (" hook_timer. . . . . . . : 0x%lx", ptr_xfer->hook_timer);
|
||||
weechat_log_printf (" unterminated_message. . : '%s'", ptr_xfer->unterminated_message);
|
||||
weechat_log_printf (" file. . . . . . . . . . : %d", ptr_xfer->file);
|
||||
weechat_log_printf (" local_filename. . . . . : '%s'", ptr_xfer->local_filename);
|
||||
weechat_log_printf (" filename_suffix . . . . : %d", ptr_xfer->filename_suffix);
|
||||
weechat_log_printf (" pos . . . . . . . . . . : %llu", ptr_xfer->pos);
|
||||
weechat_log_printf (" ack . . . . . . . . . . : %llu", ptr_xfer->ack);
|
||||
weechat_log_printf (" start_resume. . . . . . : %llu", ptr_xfer->start_resume);
|
||||
weechat_log_printf (" last_check_time . . . . : %ld", ptr_xfer->last_check_time);
|
||||
weechat_log_printf (" last_check_pos. . . . . : %llu", ptr_xfer->last_check_pos);
|
||||
weechat_log_printf (" last_activity . . . . . : %ld", ptr_xfer->last_activity);
|
||||
weechat_log_printf (" bytes_per_sec . . . . . : %llu", ptr_xfer->bytes_per_sec);
|
||||
weechat_log_printf (" eta . . . . . . . . . . : %llu", ptr_xfer->eta);
|
||||
weechat_log_printf (" hash_target . . . . . . : '%s'", ptr_xfer->hash_target);
|
||||
weechat_log_printf (" hash_status . . . . . . : %d (%s)",
|
||||
ptr_xfer->hash_status,
|
||||
xfer_hash_status_string[ptr_xfer->hash_status]);
|
||||
weechat_log_printf (" prev_xfer . . . . . : 0x%lx", ptr_xfer->prev_xfer);
|
||||
weechat_log_printf (" next_xfer . . . . . : 0x%lx", ptr_xfer->next_xfer);
|
||||
weechat_log_printf (" prev_xfer . . . . . . . : 0x%lx", ptr_xfer->prev_xfer);
|
||||
weechat_log_printf (" next_xfer . . . . . . . : 0x%lx", ptr_xfer->next_xfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,8 +140,12 @@ struct t_xfer
|
||||
char *filename; /* filename */
|
||||
unsigned long long size; /* file size */
|
||||
char *proxy; /* proxy to use (optional) */
|
||||
unsigned long local_address; /* local IP address */
|
||||
unsigned long remote_address; /* remote IP address */
|
||||
struct sockaddr *local_address; /* local IP address */
|
||||
socklen_t local_address_length; /* local sockaddr length */
|
||||
char *local_address_str; /* local IP address as string */
|
||||
struct sockaddr *remote_address; /* remote IP address */
|
||||
socklen_t remote_address_length; /* remote sockaddr length */
|
||||
char *remote_address_str; /* remote IP address as string */
|
||||
int port; /* remote port */
|
||||
|
||||
/* internal data */
|
||||
@@ -191,6 +195,9 @@ extern struct t_xfer *xfer_search_by_number (int number);
|
||||
extern struct t_xfer *xfer_search_by_buffer (struct t_gui_buffer *buffer);
|
||||
extern void xfer_close (struct t_xfer *xfer, enum t_xfer_status status);
|
||||
extern void xfer_send_signal (struct t_xfer *xfer, const char *signal);
|
||||
extern void xfer_set_remote_address (struct t_xfer *xfer,
|
||||
struct sockaddr *address, socklen_t length,
|
||||
char *address_str);
|
||||
extern void xfer_free (struct t_xfer *xfer);
|
||||
extern int xfer_add_to_infolist (struct t_infolist *infolist,
|
||||
struct t_xfer *xfer);
|
||||
|
||||
Reference in New Issue
Block a user