diff options
author | Andrew Potter <agpotter@gmail.com> | 2014-01-09 12:48:54 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2014-01-09 12:48:54 +0100 |
commit | 144dc60d0ab062aa5b3943d57f8f6515310f2dd5 (patch) | |
tree | 06c0e13ad72be462a3b018cf9905c5af5921ff07 /src/plugins/irc | |
parent | 9040dfbf521b12b675b6f7d5d93bb10767a40f90 (diff) | |
download | weechat-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.c | 28 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 44 |
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")); } } |