void xfer_network_connect_init (struct t_xfer *xfer) { if (!xfer_network_connect (xfer)) { xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); } else { /* for a file: launch child process */ if (XFER_IS_FILE(xfer->type)) { xfer->status = XFER_STATUS_CONNECTING; xfer_network_recv_file_fork (xfer); } else { /* for a chat => associate with buffer */ xfer->status = XFER_STATUS_ACTIVE; xfer_chat_open_buffer (xfer); } } xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); }
int xfer_network_connect_chat_recv_cb (const void *pointer, void *data, int status, int gnutls_rc, int sock, const char *error, const char *ip_address) { struct t_xfer *xfer; int flags; /* make C compiler happy */ (void) data; (void) gnutls_rc; (void) ip_address; xfer = (struct t_xfer*)pointer; weechat_unhook (xfer->hook_connect); xfer->hook_connect = NULL; /* connection OK? */ if (status == WEECHAT_HOOK_CONNECT_OK) { xfer->sock = sock; 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 set option \"nonblock\" " "for socket: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, errno, strerror (errno)); close (xfer->sock); xfer->sock = -1; 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, NULL); xfer_chat_open_buffer (xfer); xfer->status = XFER_STATUS_ACTIVE; xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } /* connection error */ switch (status) { case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND: weechat_printf (NULL, (xfer->proxy && xfer->proxy[0]) ? _("%s%s: proxy address \"%s\" not found") : _("%s%s: 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, (xfer->proxy && xfer->proxy[0]) ? _("%s%s: proxy IP address not found") : _("%s%s: IP address not found"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; case WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED: weechat_printf (NULL, (xfer->proxy && xfer->proxy[0]) ? _("%s%s: proxy connection refused") : _("%s%s: connection refused"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; case WEECHAT_HOOK_CONNECT_PROXY_ERROR: weechat_printf (NULL, _("%s%s: proxy fails to establish connection to " "server (check username/password if used and if " "server address/port is allowed by proxy)"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; case WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR: weechat_printf (NULL, _("%s%s: unable to set local hostname/IP"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; case WEECHAT_HOOK_CONNECT_MEMORY_ERROR: weechat_printf (NULL, _("%s%s: not enough memory (%s)"), weechat_prefix ("error"), XFER_PLUGIN_NAME, (error) ? error : "-"); break; case WEECHAT_HOOK_CONNECT_TIMEOUT: weechat_printf (NULL, _("%s%s: timeout"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; case WEECHAT_HOOK_CONNECT_SOCKET_ERROR: weechat_printf (NULL, _("%s%s: unable to create socket"), weechat_prefix ("error"), XFER_PLUGIN_NAME); break; default: weechat_printf (NULL, _("%s%s: unable to connect: unexpected error (%d)"), weechat_prefix ("error"), XFER_PLUGIN_NAME, status); break; } if (error && error[0]) { weechat_printf (NULL, _("%s%s: error: %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, error); } xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; }
int xfer_network_fd_cb (void *arg_xfer, int fd) { struct t_xfer *xfer; int sock; struct sockaddr_in addr; socklen_t length; /* make C compiler happy */ (void) fd; xfer = (struct t_xfer *)arg_xfer; if (xfer->status == XFER_STATUS_CONNECTING) { if (xfer->type == XFER_TYPE_FILE_SEND) { xfer->last_activity = time (NULL); length = sizeof (addr); sock = accept (xfer->sock, (struct sockaddr *) &addr, &length); weechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { weechat_printf (NULL, _("%s%s: unable to create socket for sending " "file"), weechat_prefix ("error"), XFER_PLUGIN_NAME); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->sock = sock; if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1) { weechat_printf (NULL, _("%s%s: unable to set option \"nonblock\" " "for socket"), weechat_prefix ("error"), XFER_PLUGIN_NAME); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->address = ntohl (addr.sin_addr.s_addr); xfer->status = XFER_STATUS_ACTIVE; xfer->start_transfer = time (NULL); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); xfer_network_send_file_fork (xfer); } /* if (xfer->type == XFER_TYPE_FILE_RECV) { if (xfer->child_read != -1) irc_dcc_file_child_read (dcc); } */ } if (xfer->status == XFER_STATUS_WAITING) { if (xfer->type == XFER_TYPE_CHAT_SEND) { length = sizeof (addr); sock = accept (xfer->sock, (struct sockaddr *) &addr, &length); weechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { weechat_printf (NULL, _("%s%s: unable to create socket for sending " "file"), weechat_prefix ("error"), XFER_PLUGIN_NAME); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->sock = sock; if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1) { weechat_printf (NULL, _("%s%s: unable to set option \"nonblock\" " "for socket"), weechat_prefix ("error"), XFER_PLUGIN_NAME); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->address = ntohl (addr.sin_addr.s_addr); xfer->status = XFER_STATUS_ACTIVE; xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); xfer->hook_fd = weechat_hook_fd (xfer->sock, 1, 0, 0, &xfer_chat_recv_cb, xfer); xfer_chat_open_buffer (xfer); } } /* if (xfer->status == XFER_STATUS_ACTIVE) { if (XFER_IS_CHAT(dcc->type)) { irc_dcc_chat_recv (dcc); } else irc_dcc_file_child_read (dcc); } */ return WEECHAT_RC_OK; }
int xfer_network_fd_cb (const void *pointer, void *data, int fd) { struct t_xfer *xfer; int sock, flags, error; struct sockaddr_storage addr; socklen_t length; char str_address[NI_MAXHOST]; /* make C compiler happy */ (void) data; (void) fd; length = sizeof (addr); memset (&addr, 0, length); xfer = (struct t_xfer *)pointer; if (xfer->status == XFER_STATUS_CONNECTING) { if (xfer->type == XFER_TYPE_FILE_SEND) { xfer->last_activity = time (NULL); sock = accept (xfer->sock, (struct sockaddr *) &addr, &length); error = errno; weechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { weechat_printf (NULL, _("%s%s: unable to create socket for sending " "file: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, error, strerror (error)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->sock = sock; 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 set option \"nonblock\" " "for socket: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, errno, strerror (errno)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } error = getnameinfo ((struct sockaddr *)&addr, length, str_address, sizeof (str_address), NULL, 0, NI_NUMERICHOST); if (error != 0) { snprintf (str_address, sizeof (str_address), "error: %s", gai_strerror (error)); } xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length, str_address); xfer->status = XFER_STATUS_ACTIVE; xfer->start_transfer = time (NULL); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); xfer_network_send_file_fork (xfer); } } if (xfer->status == XFER_STATUS_WAITING) { if (xfer->type == XFER_TYPE_CHAT_SEND) { length = sizeof (addr); sock = accept (xfer->sock, (struct sockaddr *) &addr, &length); error = errno; weechat_unhook (xfer->hook_fd); xfer->hook_fd = NULL; close (xfer->sock); xfer->sock = -1; if (sock < 0) { weechat_printf (NULL, _("%s%s: unable to create socket for sending " "file: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, error, strerror (error)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } xfer->sock = sock; 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 set option \"nonblock\" " "for socket: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, errno, strerror (errno)); xfer_close (xfer, XFER_STATUS_FAILED); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } error = getnameinfo ((struct sockaddr *)&addr, length, str_address, sizeof (str_address), NULL, 0, NI_NUMERICHOST); if (error != 0) { snprintf (str_address, sizeof (str_address), "error: %s", gai_strerror (error)); } xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length, str_address); xfer->status = XFER_STATUS_ACTIVE; xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); xfer->hook_fd = weechat_hook_fd (xfer->sock, 1, 0, 0, &xfer_chat_recv_cb, xfer, NULL); xfer_chat_open_buffer (xfer); } } return WEECHAT_RC_OK; }