Skip to content

Commit

Permalink
xfer: Use hook_connect() for receiving chats
Browse files Browse the repository at this point in the history
  • Loading branch information
talisein committed Aug 12, 2014
1 parent e4fb9a4 commit 2aab2e6
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 20 deletions.
137 changes: 117 additions & 20 deletions src/plugins/xfer/xfer-network.c
Expand Up @@ -521,6 +521,117 @@ xfer_network_timer_cb (void *arg_xfer, int remaining_calls)
return WEECHAT_RC_OK;
}

static int
xfer_network_connect_chat_recv_cb (void *data,
int status,
int gnutls_rc,
int sock,
const char *error,
const char *ip_address)
{
(void) gnutls_rc;
(void) ip_address;
(void) error;
struct t_xfer *xfer = (struct t_xfer*)data;

/* Unhook */
weechat_unhook (xfer->hook_connect);
xfer->hook_connect = NULL;

/* handle success */
if (WEECHAT_HOOK_CONNECT_OK == status)
{
xfer->sock = sock;

int flags = fcntl (xfer->sock, F_GETFL);
if (flags == -1)
flags = 0;
if (fcntl (xfer->sock, F_SETFL, flags | O_NONBLOCK) == -1)
{
weechat_printf (NULL,
_("%s%s: unable to connect set DCC chat nonblocking"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
close (sock);
xfer_close (xfer, XFER_STATUS_FAILED);
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
return WEECHAT_RC_OK;
}

xfer->hook_fd = weechat_hook_fd (xfer->sock,
1, 0, 0,
&xfer_chat_recv_cb,
xfer);

return WEECHAT_RC_OK;
}

/* Report the error and fail xfer */
switch (status)
{
case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Address (%s) not found"),
weechat_prefix ("error"), XFER_PLUGIN_NAME,
xfer->remote_address_str);
break;
case WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: IP address (%s) not found"),
weechat_prefix ("error"), XFER_PLUGIN_NAME,
xfer->remote_address_str);
break;
case WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Connection refused"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_PROXY_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Proxy error"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Local hostname error"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: GNUTLS initialization"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: GNUTLS handshake error"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_MEMORY_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Insufficient memory"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_TIMEOUT:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Timed out"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
case WEECHAT_HOOK_CONNECT_SOCKET_ERROR:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Unable to create socket"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
default:
weechat_printf (NULL,
_("%s%s: unable to connect to DCC chat: Unexpected error"),
weechat_prefix ("error"), XFER_PLUGIN_NAME);
break;
}
xfer_close (xfer, XFER_STATUS_FAILED);
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);

return WEECHAT_RC_OK;
}

/*
* Connects to another host.
*
Expand Down Expand Up @@ -579,26 +690,12 @@ 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;
}

xfer->hook_fd = weechat_hook_fd (xfer->sock,
1, 0, 0,
&xfer_chat_recv_cb,
xfer);
xfer->hook_connect = weechat_hook_connect (xfer->proxy,
xfer->remote_address_str,
xfer->port, 1, 0, NULL, NULL,
0, "NONE", NULL,
&xfer_network_connect_chat_recv_cb,
xfer);
}

/* for file receiving, connection is made in child process (blocking) */
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/xfer/xfer.c
Expand Up @@ -298,6 +298,11 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
weechat_unhook (xfer->hook_timer);
xfer->hook_timer = NULL;
}
if (xfer->hook_connect)
{
weechat_unhook (xfer->hook_connect);
xfer->hook_connect = NULL;
}
if (XFER_IS_FILE(xfer->type))
{
weechat_printf (NULL,
Expand Down Expand Up @@ -479,6 +484,7 @@ xfer_alloc ()
new_xfer->child_write = -1;
new_xfer->hook_fd = NULL;
new_xfer->hook_timer = NULL;
new_xfer->hook_connect = NULL;
new_xfer->unterminated_message = NULL;
new_xfer->file = -1;
new_xfer->local_filename = NULL;
Expand Down Expand Up @@ -1571,6 +1577,8 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "hook_timer", xfer->hook_timer))
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "hook_connect", xfer->hook_connect))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "unterminated_message", xfer->unterminated_message))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "file", xfer->file))
Expand Down Expand Up @@ -1661,6 +1669,7 @@ xfer_print_log ()
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 (" hook_connect. . . . . . : 0x%lx", ptr_xfer->hook_connect);
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);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/xfer/xfer.h
Expand Up @@ -163,6 +163,7 @@ struct t_xfer
int child_write; /* to write into child pipe */
struct t_hook *hook_fd; /* hook for socket or child pipe */
struct t_hook *hook_timer; /* timeout for receiver accept */
struct t_hook *hook_connect; /* hook for connection to chat recv */
char *unterminated_message; /* beginning of a message */
int file; /* local file (read or write) */
char *local_filename; /* local filename (with path) */
Expand Down

0 comments on commit 2aab2e6

Please sign in to comment.