mirror of
https://github.com/weechat/weechat.git
synced 2026-07-04 16:53:14 +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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user