summaryrefslogtreecommitdiff
path: root/src/plugins/irc
diff options
context:
space:
mode:
authorAndrew Potter <agpotter@gmail.com>2014-01-09 12:48:54 +0100
committerSebastien Helleu <flashcode@flashtux.org>2014-01-09 12:48:54 +0100
commit144dc60d0ab062aa5b3943d57f8f6515310f2dd5 (patch)
tree06c0e13ad72be462a3b018cf9905c5af5921ff07 /src/plugins/irc
parent9040dfbf521b12b675b6f7d5d93bb10767a40f90 (diff)
downloadweechat-144dc60d0ab062aa5b3943d57f8f6515310f2dd5.zip
xfer: add support of IPv6 for DCC chat/file (patch #7992)
Diffstat (limited to 'src/plugins/irc')
-rw-r--r--src/plugins/irc/irc-command.c28
-rw-r--r--src/plugins/irc/irc-server.c44
2 files changed, 55 insertions, 17 deletions
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index 3b643036e..82b5cd4fa 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -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,
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index b8acff11a..05e78fca3 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -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)
{
+ 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)
+ 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"));
}
}