From 7f0f947667ec6ed22b30e205627da51dffe620c4 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 22 Aug 2023 18:59:59 -0500 Subject: [PATCH] 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. --- src/plugins/irc/irc-command.c | 24 +----- src/plugins/irc/irc-ctcp.c | 23 ++---- src/plugins/irc/irc-server.c | 60 ++++++++++++--- src/plugins/xfer/xfer-dcc.c | 17 +++-- src/plugins/xfer/xfer-network.c | 27 ++++++- src/plugins/xfer/xfer.c | 126 +++++++++++++++++++++----------- src/plugins/xfer/xfer.h | 1 + 7 files changed, 173 insertions(+), 105 deletions(-) diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index cef86f0d3..22b9f28ca 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -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); diff --git a/src/plugins/irc/irc-ctcp.c b/src/plugins/irc/irc-ctcp.c index 071636f52..1c7213881 100644 --- a/src/plugins/irc/irc-ctcp.c +++ b/src/plugins/irc/irc-ctcp.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #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", diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 7ef98bd67..8b9973b97 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -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")); + } } } } diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c index 3c4a37d22..e9d019d03 100644 --- a/src/plugins/xfer/xfer-dcc.c +++ b/src/plugins/xfer/xfer-dcc.c @@ -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 */ diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c index 02b0991d2..d69c43cf1 100644 --- a/src/plugins/xfer/xfer-network.c +++ b/src/plugins/xfer/xfer-network.c @@ -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; diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c index e4a62a2dc..32767200c 100644 --- a/src/plugins/xfer/xfer.c +++ b/src/plugins/xfer/xfer.c @@ -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, diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h index cc422f86f..fd213f6a8 100644 --- a/src/plugins/xfer/xfer.h +++ b/src/plugins/xfer/xfer.h @@ -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,..) */