summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/irc/irc-command.c16
-rw-r--r--src/plugins/irc/irc-config.c10
-rw-r--r--src/plugins/irc/irc-config.h2
-rw-r--r--src/plugins/irc/irc-display.c6
-rw-r--r--src/plugins/irc/irc-server.c485
-rw-r--r--src/plugins/irc/irc-server.h10
-rw-r--r--src/plugins/irc/irc.c17
-rw-r--r--src/plugins/irc/irc.h4
-rw-r--r--src/plugins/plugin.c1
-rw-r--r--src/plugins/weechat-plugin.h23
10 files changed, 162 insertions, 412 deletions
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index dbb6d1644..4498fceac 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -496,7 +496,7 @@ irc_command_connect_one_server (struct t_irc_server *server, int no_join)
server->name);
return 0;
}
- if (server->child_pid > 0)
+ if (server->hook_connect)
{
weechat_printf (NULL,
_("%s%s: currently connecting to server "
@@ -576,7 +576,7 @@ irc_command_connect (void *data, struct t_gui_buffer *buffer, int argc,
ptr_server = ptr_server->next_server)
{
nb_connect++;
- if (!ptr_server->is_connected && (ptr_server->child_pid == 0))
+ if (!ptr_server->is_connected && (!ptr_server->hook_connect))
{
if (!irc_command_connect_one_server (ptr_server, no_join))
connect_ok = 0;
@@ -615,7 +615,7 @@ irc_command_connect (void *data, struct t_gui_buffer *buffer, int argc,
server_tmp.nicks,
server_tmp.username,
server_tmp.realname,
- server_tmp.hostname,
+ server_tmp.local_hostname,
server_tmp.command,
1, /* command_delay */
server_tmp.autojoin,
@@ -1138,7 +1138,7 @@ irc_command_disconnect_one_server (struct t_irc_server *server)
if (!server)
return 0;
- if ((!server->is_connected) && (server->child_pid == 0)
+ if ((!server->is_connected) && (!server->hook_connect)
&& (server->reconnect_start == 0))
{
weechat_printf (server->buffer,
@@ -1186,7 +1186,7 @@ irc_command_disconnect (void *data, struct t_gui_buffer *buffer, int argc,
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
- if ((ptr_server->is_connected) || (ptr_server->child_pid != 0)
+ if ((ptr_server->is_connected) || (ptr_server->hook_connect)
|| (ptr_server->reconnect_start != 0))
{
if (!irc_command_disconnect_one_server (ptr_server))
@@ -2373,7 +2373,7 @@ irc_command_reconnect_one_server (struct t_irc_server *server, int no_join)
if (!server)
return 0;
- if ((!server->is_connected) && (server->child_pid == 0))
+ if ((!server->is_connected) && (!server->hook_connect))
{
weechat_printf (server->buffer,
_("%s%s: not connected to server \"%s\"!"),
@@ -2427,7 +2427,7 @@ irc_command_reconnect (void *data, struct t_gui_buffer *buffer, int argc,
ptr_server = ptr_server->next_server)
{
nb_reconnect++;
- if ((ptr_server->is_connected) || (ptr_server->child_pid != 0))
+ if ((ptr_server->is_connected) || (ptr_server->hook_connect))
{
if (!irc_command_reconnect_one_server (ptr_server, no_join))
reconnect_ok = 0;
@@ -2771,7 +2771,7 @@ irc_command_server (void *data, struct t_gui_buffer *buffer, int argc,
server_tmp.nicks,
server_tmp.username,
server_tmp.realname,
- server_tmp.hostname,
+ server_tmp.local_hostname,
server_tmp.command,
1, /* command_delay */
server_tmp.autojoin,
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c
index d55719c8e..603f0a0c9 100644
--- a/src/plugins/irc/irc-config.c
+++ b/src/plugins/irc/irc-config.c
@@ -35,8 +35,8 @@
char *irc_config_server_option_string[IRC_CONFIG_NUM_SERVER_OPTIONS] =
{ "autoconnect", "autoreconnect", "autoreconnect_delay", "addresses", "ipv6",
- "ssl", "password", "nicks", "username", "realname", "hostname", "command",
- "command_delay", "autojoin", "autorejoin", "notify_levels"
+ "ssl", "password", "nicks", "username", "realname", "local_hostname",
+ "command", "command_delay", "autojoin", "autorejoin", "notify_levels"
};
char *irc_config_server_option_default[IRC_CONFIG_NUM_SERVER_OPTIONS] =
{ "off", "on", "30", "", "off", "off", "", "", "", "", "", "", "0", "",
@@ -614,12 +614,12 @@ irc_config_server_new_option (struct t_config_file *config_file,
callback_change, callback_change_data,
callback_delete, callback_delete_data);
break;
- case IRC_CONFIG_SERVER_HOSTNAME:
+ case IRC_CONFIG_SERVER_LOCAL_HOSTNAME:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
- N_("custom hostname/IP for server (optional, if empty local hostname "
- "is used)"),
+ N_("custom local hostname/IP for server (optional, if empty "
+ "local hostname is used)"),
NULL, 0, 0, value, NULL, NULL,
callback_change, callback_change_data,
callback_delete, callback_delete_data);
diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h
index dc161d94a..2610749af 100644
--- a/src/plugins/irc/irc-config.h
+++ b/src/plugins/irc/irc-config.h
@@ -38,7 +38,7 @@ enum t_irc_config_server_option
IRC_CONFIG_SERVER_NICKS,
IRC_CONFIG_SERVER_USERNAME,
IRC_CONFIG_SERVER_REALNAME,
- IRC_CONFIG_SERVER_HOSTNAME,
+ IRC_CONFIG_SERVER_LOCAL_HOSTNAME,
IRC_CONFIG_SERVER_COMMAND,
IRC_CONFIG_SERVER_COMMAND_DELAY,
IRC_CONFIG_SERVER_AUTOJOIN,
diff --git a/src/plugins/irc/irc-display.c b/src/plugins/irc/irc-display.c
index 855652fd6..fa4034360 100644
--- a/src/plugins/irc/irc-display.c
+++ b/src/plugins/irc/irc-display.c
@@ -193,9 +193,9 @@ irc_display_server (struct t_irc_server *server, int with_detail)
weechat_printf (NULL, " realname . . . . . : %s",
(server->realname && server->realname[0]) ?
server->realname : "");
- weechat_printf (NULL, " hostname . . . . . : %s",
- (server->hostname && server->hostname[0]) ?
- server->hostname : "");
+ weechat_printf (NULL, " local_hostname . . : %s",
+ (server->local_hostname && server->local_hostname[0]) ?
+ server->local_hostname : "");
if (server->command && server->command[0])
string = strdup (server->command);
else
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 63270e728..651b05fc8 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -22,18 +22,11 @@
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#include <signal.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <time.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include "../weechat-plugin.h"
#include "irc.h"
@@ -53,17 +46,6 @@ struct t_irc_server *last_irc_server = NULL;
struct t_irc_message *irc_recv_msgq = NULL;
struct t_irc_message *irc_msgq_last_msg = NULL;
-#ifdef HAVE_GNUTLS
-const int gnutls_cert_type_prio[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
-#if LIBGNUTLS_VERSION_NUMBER >= 0x010700
- const int gnutls_prot_prio[] = { GNUTLS_TLS1_2, GNUTLS_TLS1_1,
- GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
-#else
- const int gnutls_prot_prio[] = { GNUTLS_TLS1_1, GNUTLS_TLS1_0,
- GNUTLS_SSL3, 0 };
-#endif
-#endif
-
/*
* irc_server_set_addresses: set addresses for server
@@ -205,10 +187,10 @@ irc_server_set_with_option (struct t_irc_server *server,
free (server->realname);
server->realname = strdup (weechat_config_string (option));
break;
- case IRC_CONFIG_SERVER_HOSTNAME:
- if (server->hostname)
- free (server->hostname);
- server->hostname = strdup (weechat_config_string (option));
+ case IRC_CONFIG_SERVER_LOCAL_HOSTNAME:
+ if (server->local_hostname)
+ free (server->local_hostname);
+ server->local_hostname = strdup (weechat_config_string (option));
break;
case IRC_CONFIG_SERVER_COMMAND:
if (server->command)
@@ -280,7 +262,7 @@ irc_server_init (struct t_irc_server *server)
server->nicks = NULL;
server->username = NULL;
server->realname = NULL;
- server->hostname = NULL;
+ server->local_hostname = NULL;
server->command = NULL;
server->command_delay = IRC_CONFIG_SERVER_DEFAULT_COMMAND_DELAY;
server->autojoin = NULL;
@@ -293,10 +275,8 @@ irc_server_init (struct t_irc_server *server)
server->addresses_array = NULL;
server->ports_array = NULL;
server->current_address = 0;
- server->child_pid = 0;
- server->child_read = -1;
- server->child_write = -1;
server->sock = -1;
+ server->hook_connect = NULL;
server->hook_fd = NULL;
server->is_connected = 0;
server->ssl_connected = 0;
@@ -598,8 +578,8 @@ irc_server_free_data (struct t_irc_server *server)
free (server->username);
if (server->realname)
free (server->realname);
- if (server->hostname)
- free (server->hostname);
+ if (server->local_hostname)
+ free (server->local_hostname);
if (server->command)
free (server->command);
if (server->autojoin)
@@ -677,7 +657,7 @@ struct t_irc_server *
irc_server_new (char *name, int autoconnect, int autoreconnect,
int autoreconnect_delay, int temp_server, char *addresses,
int ipv6, int ssl, char *password, char *nicks,
- char *username, char *realname, char *hostname,
+ char *username, char *realname, char *local_hostname,
char *command, int command_delay, char *autojoin,
int autorejoin, char *notify_levels)
{
@@ -690,12 +670,12 @@ irc_server_new (char *name, int autoconnect, int autoreconnect,
{
weechat_log_printf ("Creating new server (name:%s, addresses:%s, "
"pwd:%s, nicks:%s, username:%s, realname:%s, "
- "hostname: %s, command:%s, autojoin:%s, "
+ "local_hostname: %s, command:%s, autojoin:%s, "
"autorejoin:%s, notify_levels:%s)",
name, addresses, (password) ? password : "",
(nicks) ? nicks : "", (username) ? username : "",
(realname) ? realname : "",
- (hostname) ? hostname : "",
+ (local_hostname) ? local_hostname : "",
(command) ? command : "",
(autojoin) ? autojoin : "",
(autorejoin) ? "on" : "off",
@@ -719,8 +699,8 @@ irc_server_new (char *name, int autoconnect, int autoreconnect,
(username) ? strdup (username) : strdup ("weechat");
new_server->realname =
(realname) ? strdup (realname) : strdup ("realname");
- new_server->hostname =
- (hostname) ? strdup (hostname) : NULL;
+ new_server->local_hostname =
+ (local_hostname) ? strdup (local_hostname) : NULL;
new_server->command =
(command) ? strdup (command) : NULL;
new_server->command_delay = command_delay;
@@ -763,7 +743,7 @@ irc_server_duplicate (struct t_irc_server *server, char *new_name)
server->nicks,
server->username,
server->realname,
- server->hostname,
+ server->local_hostname,
server->command,
server->command_delay,
server->autojoin,
@@ -1599,47 +1579,22 @@ irc_server_timer_check_away (void *empty)
}
/*
- * irc_server_child_kill: kill child process and close pipe
- */
-
-void
-irc_server_child_kill (struct t_irc_server *server)
-{
- /* kill process */
- if (server->child_pid > 0)
- {
- kill (server->child_pid, SIGKILL);
- waitpid (server->child_pid, NULL, 0);
- server->child_pid = 0;
- }
-
- /* close pipe used with child */
- if (server->child_read != -1)
- {
- close (server->child_read);
- server->child_read = -1;
- }
- if (server->child_write != -1)
- {
- close (server->child_write);
- server->child_write = -1;
- }
-}
-
-/*
* irc_server_close_connection: close server connection
- * (kill child, close socket/pipes)
*/
void
irc_server_close_connection (struct t_irc_server *server)
{
+ if (server->hook_connect)
+ {
+ weechat_unhook (server->hook_connect);
+ server->hook_connect = NULL;
+ }
if (server->hook_fd)
{
weechat_unhook (server->hook_fd);
server->hook_fd = NULL;
}
- irc_server_child_kill (server);
/* close network socket */
if (server->sock != -1)
@@ -1743,257 +1698,102 @@ irc_server_switch_address (struct t_irc_server *server)
}
/*
- * irc_server_child_read_cb: read connection progress from child process
+ * irc_server_connect_cb: read connection status
*/
int
-irc_server_child_read_cb (void *arg_server)
+irc_server_connect_cb (void *arg_server, int status)
{
struct t_irc_server *server;
- char buffer[1];
- int num_read;
int config_proxy_use;
server = (struct t_irc_server *)arg_server;
- num_read = read (server->child_read, buffer, sizeof (buffer));
- if (num_read > 0)
- {
- config_proxy_use = weechat_config_boolean (
- weechat_config_get ("weechat.proxy.use"));
- switch (buffer[0])
- {
- /* connection OK */
- case '0':
- /* enable SSL if asked */
-#ifdef HAVE_GNUTLS
- if (server->ssl_connected)
- {
- gnutls_transport_set_ptr (server->gnutls_sess,
- (gnutls_transport_ptr) ((unsigned long) server->sock));
- if (gnutls_handshake (server->gnutls_sess) < 0)
- {
- weechat_printf (server->buffer,
- _("%s%s: GnuTLS handshake failed"),
- weechat_prefix ("error"), "irc");
- irc_server_close_connection (server);
- irc_server_switch_address (server);
- return WEECHAT_RC_OK;
- }
- }
-#endif
- /* kill child and login to server */
- weechat_unhook (server->hook_fd);
- irc_server_child_kill (server);
- irc_server_login (server);
- server->hook_fd = weechat_hook_fd (server->sock,
- 1, 0, 0,
- irc_server_recv_cb,
- server);
- break;
- /* adress not found */
- case '1':
- weechat_printf (server->buffer,
- (config_proxy_use) ?
- _("%s%s: proxy address \"%s\" not found") :
- _("%s%s: address \"%s\" not found"),
- weechat_prefix ("error"), "irc",
- server->addresses_array[server->current_address]);
- irc_server_close_connection (server);
- irc_server_switch_address (server);
- break;
- /* IP address not found */
- case '2':
- weechat_printf (server->buffer,
- (config_proxy_use) ?
- _("%s%s: proxy IP address not found") :
- _("%s%s: IP address not found"),
- weechat_prefix ("error"), "irc");
- irc_server_close_connection (server);
- irc_server_switch_address (server);
- break;
- /* connection refused */
- case '3':
- weechat_printf (server->buffer,
- (config_proxy_use) ?
- _("%s%s: proxy connection refused") :
- _("%s%s: connection refused"),
- weechat_prefix ("error"), "irc");
- irc_server_close_connection (server);
- irc_server_switch_address (server);
- break;
- /* proxy fails to connect to server */
- case '4':
- weechat_printf (server->buffer,
- _("%s%s: proxy fails to establish "
- "connection to server "
- "(check username/password if used "
- "and if IRC server address/port is "
- "allowed by proxy)"),
- weechat_prefix ("error"), "irc");
- irc_server_close_connection (server);
- irc_server_switch_address (server);
- break;
- /* fails to set local hostname/IP */
- case '5':
- weechat_printf (server->buffer,
- _("%s%s: unable to set local hostname/IP"),
- weechat_prefix ("error"), "irc");
- irc_server_close_connection (server);
- irc_server_reconnect_schedule (server);
- break;
- }
- }
-
- return WEECHAT_RC_OK;
-}
-
-/*
- * irc_server_child: child process trying to connect to server
- */
-
-int
-irc_server_child (struct t_irc_server *server)
-{
- struct addrinfo hints, *res, *res_local;
- int rc;
- int config_proxy_use, config_proxy_ipv6, config_proxy_port;
- char *config_proxy_address;
+ server->hook_connect = NULL;
- res = NULL;
- res_local = NULL;
-
config_proxy_use = weechat_config_boolean (
weechat_config_get ("weechat.proxy.use"));
- config_proxy_ipv6 = weechat_config_integer (
- weechat_config_get ("weechat.proxy.ipv6"));
- config_proxy_port = weechat_config_integer (
- weechat_config_get ("weechat.proxy.port"));
- config_proxy_address = weechat_config_string (
- weechat_config_get ("weechat.proxy.address"));
- if (config_proxy_use)
- {
- /* get info about server */
- memset (&hints, 0, sizeof (hints));
- hints.ai_family = (config_proxy_ipv6) ? AF_INET6 : AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo (config_proxy_address, NULL, &hints, &res) !=0)
- {
- write (server->child_write, "1", 1);
- return 0;
- }
- if (!res)
- {
- write (server->child_write, "1", 1);
- return 0;
- }
- if ((config_proxy_ipv6 && (res->ai_family != AF_INET6))
- || ((!config_proxy_ipv6 && (res->ai_family != AF_INET))))
- {
- write (server->child_write, "2", 1);
- freeaddrinfo (res);
- return 0;
- }
-
- if (config_proxy_ipv6)
- ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (config_proxy_port);
- else
- ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (config_proxy_port);
-
- /* connect to server */
- if (connect (server->sock, res->ai_addr, res->ai_addrlen) != 0)
- {
- write (server->child_write, "3", 1);
- freeaddrinfo (res);
- return 0;
- }
-
- if (weechat_network_pass_proxy (server->sock,
- server->addresses_array[server->current_address],
- server->ports_array[server->current_address]))
- {
- write (server->child_write, "4", 1);
- freeaddrinfo (res);
- return 0;
- }
- }
- else
+ switch (status)
{
- /* set local hostname/IP if asked by user */
- if (server->hostname && server->hostname[0])
- {
- memset (&hints, 0, sizeof(hints));
- hints.ai_family = (server->ipv6) ? AF_INET6 : AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- rc = getaddrinfo (server->hostname, NULL, &hints, &res_local);
- if ((rc != 0) || !res_local
- || (server->ipv6 && (res_local->ai_family != AF_INET6))
- || ((!server->ipv6 && (res_local->ai_family != AF_INET))))
- {
- write (server->child_write, "5", 1);
- if (res_local)
- freeaddrinfo (res_local);
- return 0;
- }
- if (bind (server->sock, res_local->ai_addr, res_local->ai_addrlen) < 0)
- {
- write (server->child_write, "5", 1);
- if (res_local)
- freeaddrinfo (res_local);
- return 0;
- }
- }
-
- /* get info about server */
- memset (&hints, 0, sizeof(hints));
- hints.ai_family = (server->ipv6) ? AF_INET6 : AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- rc = getaddrinfo (server->addresses_array[server->current_address],
- NULL, &hints, &res);
- if ((rc != 0) || !res)
- {
- write (server->child_write, "1", 1);
- if (res)
- freeaddrinfo (res);
- return 0;
- }
- if ((server->ipv6 && (res->ai_family != AF_INET6))
- || ((!server->ipv6 && (res->ai_family != AF_INET))))
- {
- write (server->child_write, "2", 1);
- if (res)
- freeaddrinfo (res);
- if (res_local)
- freeaddrinfo (res_local);
- return 0;
- }
-
- /* connect to server */
- if (server->ipv6)
- ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port =
- htons (server->ports_array[server->current_address]);
- else
- ((struct sockaddr_in *)(res->ai_addr))->sin_port =
- htons (server->ports_array[server->current_address]);
-
- if (connect (server->sock, res->ai_addr, res->ai_addrlen) != 0)
- {
- write (server->child_write, "3", 1);
- if (res)
- freeaddrinfo (res);
- if (res_local)
- freeaddrinfo (res_local);
- return 0;
- }
+ case WEECHAT_HOOK_CONNECT_OK:
+ /* login to server */
+ irc_server_login (server);
+ server->hook_fd = weechat_hook_fd (server->sock,
+ 1, 0, 0,
+ irc_server_recv_cb,
+ server);
+ break;
+ case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
+ weechat_printf (server->buffer,
+ (config_proxy_use) ?
+ _("%s%s: proxy address \"%s\" not found") :
+ _("%s%s: address \"%s\" not found"),
+ weechat_prefix ("error"), "irc",
+ server->addresses_array[server->current_address]);
+ irc_server_close_connection (server);
+ irc_server_switch_address (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
+ weechat_printf (server->buffer,
+ (config_proxy_use) ?
+ _("%s%s: proxy IP address not found") :
+ _("%s%s: IP address not found"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_switch_address (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED:
+ weechat_printf (server->buffer,
+ (config_proxy_use) ?
+ _("%s%s: proxy connection refused") :
+ _("%s%s: connection refused"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_switch_address (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_PROXY_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: proxy fails to establish "
+ "connection to server "
+ "(check username/password if used "
+ "and if IRC server address/port is "
+ "allowed by proxy)"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_switch_address (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: unable to set local hostname/IP"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_reconnect_schedule (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: GnuTLS init error"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_reconnect_schedule (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: GnuTLS handshake failed"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_switch_address (server);
+ break;
+ case WEECHAT_HOOK_CONNECT_MEMORY_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: not enough memory"),
+ weechat_prefix ("error"), "irc");
+ irc_server_close_connection (server);
+ irc_server_reconnect_schedule (server);
+ break;
}
- write (server->child_write, "0", 1);
- if (res)
- freeaddrinfo (res);
- if (res_local)
- freeaddrinfo (res_local);
- return 0;
+ return WEECHAT_RC_OK;
}
/*
@@ -2005,10 +1805,7 @@ irc_server_child (struct t_irc_server *server)
int
irc_server_connect (struct t_irc_server *server, int disable_autojoin)
{
- int child_pipe[2], set;
-#ifndef __CYGWIN__
- pid_t pid;
-#endif
+ int set;
char *config_proxy_type, *config_proxy_address;
int config_proxy_use, config_proxy_ipv6, config_proxy_port;
@@ -2105,42 +1902,9 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
(server->ssl) ? " (SSL)" : "");
}
- /* close any opened connection and kill child process if running */
+ /* close connection if open */
irc_server_close_connection (server);
- /* init SSL if asked */
- server->ssl_connected = 0;
-#ifdef HAVE_GNUTLS
- if (server->ssl)
- {
- if (gnutls_init (&server->gnutls_sess, GNUTLS_CLIENT) != 0)
- {
- weechat_printf (server->buffer,
- _("%s%s: GnuTLS init error"),
- weechat_prefix ("error"), "irc");
- return 0;
- }
- gnutls_set_default_priority (server->gnutls_sess);
- gnutls_certificate_type_set_priority (server->gnutls_sess,
- gnutls_cert_type_prio);
- gnutls_protocol_set_priority (server->gnutls_sess, gnutls_prot_prio);
- gnutls_credentials_set (server->gnutls_sess, GNUTLS_CRD_CERTIFICATE,
- gnutls_xcred);
- server->ssl_connected = 1;
- }
-#endif
-
- /* create pipe for child process */
- if (pipe (child_pipe) < 0)
- {
- weechat_printf (server->buffer,
- _("%s%s: cannot create pipe"),
- weechat_prefix ("error"), "irc");
- return 0;
- }
- server->child_read = child_pipe[0];
- server->child_write = child_pipe[1];
-
/* create socket and set options */
if (config_proxy_use)
server->sock = socket ((config_proxy_ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
@@ -2175,38 +1939,25 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
"\"SO_KEEPALIVE\""),
weechat_prefix ("error"), "irc");
}
-
-#ifdef __CYGWIN__
- /* connection may block under Cygwin, there's no other known way
- to do better today, since connect() in child process seems not to work
- any suggestion is welcome to improve that!
- */
- irc_server_child (server);
- server->child_pid = 0;
- irc_server_child_read (server);
-#else
- switch (pid = fork ())
- {
- /* fork failed */
- case -1:
- irc_server_close_connection (server);
- return 0;
- /* child process */
- case 0:
- setuid (getuid ());
- irc_server_child (server);
- _exit (EXIT_SUCCESS);
- }
- /* parent process */
- server->child_pid = pid;
- server->hook_fd = weechat_hook_fd (server->child_read,
- 1, 0, 0,
- irc_server_child_read_cb,
- server);
+
+ /* init SSL if asked */
+ server->ssl_connected = 0;
+#ifdef HAVE_GNUTLS
+ if (server->ssl)
+ server->ssl_connected = 1;
#endif
server->disable_autojoin = disable_autojoin;
+ server->hook_connect = weechat_hook_connect (server->addresses_array[server->current_address],
+ server->ports_array[server->current_address],
+ server->sock,
+ server->ipv6,
+ (server->ssl_connected) ? &server->gnutls_sess : NULL,
+ server->local_hostname,
+ irc_server_connect_cb,
+ server);
+
return 1;
}
@@ -2809,10 +2560,8 @@ irc_server_print_log ()
weechat_log_printf (" addresses_count . . : %d", ptr_server->addresses_count);
weechat_log_printf (" addresses_array . . : 0x%x", ptr_server->addresses_array);
weechat_log_printf (" ports_array . . . . : 0x%x", ptr_server->ports_array);
- weechat_log_printf (" child_pid . . . . . : %d", ptr_server->child_pid);
- weechat_log_printf (" child_read . . . . : %d", ptr_server->child_read);
- weechat_log_printf (" child_write . . . . : %d", ptr_server->child_write);
weechat_log_printf (" sock. . . . . . . . : %d", ptr_server->sock);
+ weechat_log_printf (" hook_connect. . . . : 0x%x", ptr_server->hook_connect);
weechat_log_printf (" hook_fd . . . . . . : 0x%x", ptr_server->hook_fd);
weechat_log_printf (" is_connected. . . . : %d", ptr_server->is_connected);
weechat_log_printf (" ssl_connected . . . : %d", ptr_server->ssl_connected);
diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h
index b63c18526..136ddf022 100644
--- a/src/plugins/irc/irc-server.h
+++ b/src/plugins/irc/irc-server.h
@@ -69,7 +69,7 @@ struct t_irc_server
char *nicks; /* nicknames as one string */
char *username; /* user name */
char *realname; /* real name */
- char *hostname; /* custom hostname */
+ char *local_hostname; /* custom local hostname */
char *command; /* command to run once connected */
int command_delay; /* delay after execution of command */
char *autojoin; /* channels to automatically join */
@@ -82,15 +82,13 @@ struct t_irc_server
char **addresses_array; /* exploded addresses */
int *ports_array; /* ports for addresses */
int current_address; /* current address index in array */
- pid_t child_pid; /* pid of child process (connecting) */
- int child_read; /* to read into child pipe */
- int child_write; /* to write into child pipe */
int sock; /* socket for server (IPv4 or IPv6) */
- struct t_hook *hook_fd; /* hook for server socket or child pipe */
+ struct t_hook *hook_connect; /* connection hook */
+ struct t_hook *hook_fd; /* hook for server socket */
int is_connected; /* 1 if WeeChat is connected to server */
int ssl_connected; /* = 1 if connected with SSL */
#ifdef HAVE_GNUTLS
- gnutls_session gnutls_sess; /* gnutls session (only if SSL is used) */
+ gnutls_session_t gnutls_sess; /* gnutls session (only if SSL is used) */
#endif
char *unterminated_message; /* beginning of a message in input buf */
int nicks_count; /* number of nicknames */
diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c
index c07e5ce1d..ee9f24481 100644
--- a/src/plugins/irc/irc.c
+++ b/src/plugins/irc/irc.c
@@ -46,10 +46,6 @@ struct t_weechat_plugin *weechat_irc_plugin = NULL;
struct t_hook *irc_hook_timer = NULL;
struct t_hook *irc_hook_timer_check_away = NULL;
-#ifdef HAVE_GNUTLS
-gnutls_certificate_credentials gnutls_xcred; /* gnutls client credentials */
-#endif
-
/*
* irc_signal_quit_cb: callback for "quit" signal
@@ -89,13 +85,6 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
weechat_plugin = plugin;
-#ifdef HAVE_GNUTLS
- /* init GnuTLS */
- gnutls_global_init ();
- gnutls_certificate_allocate_credentials (&gnutls_xcred);
- gnutls_certificate_set_x509_trust_file (gnutls_xcred, "ca.pem", GNUTLS_X509_FMT_PEM);
-#endif
-
if (!irc_config_init ())
return WEECHAT_RC_ERROR;
@@ -168,11 +157,5 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
//irc_dcc_end ();
irc_server_free_all ();
-#ifdef HAVE_GNUTLS
- /* GnuTLS end */
- gnutls_certificate_free_credentials (gnutls_xcred);
- gnutls_global_deinit();
-#endif
-
return WEECHAT_RC_OK;
}
diff --git a/src/plugins/irc/irc.h b/src/plugins/irc/irc.h
index f00c7922f..38b54d446 100644
--- a/src/plugins/irc/irc.h
+++ b/src/plugins/irc/irc.h
@@ -68,8 +68,4 @@ extern struct t_hook *irc_hook_timer_check_away;
extern int irc_debug;
-#ifdef HAVE_GNUTLS
-extern gnutls_certificate_credentials gnutls_xcred;
-#endif
-
#endif /* irc.h */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 250c0481f..734385c47 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -364,6 +364,7 @@ plugin_load (char *filename)
new_plugin->hook_command = &hook_command;
new_plugin->hook_timer = &hook_timer;
new_plugin->hook_fd = &hook_fd;
+ new_plugin->hook_connect = &hook_connect;
new_plugin->hook_print = &hook_print;
new_plugin->hook_signal = &hook_signal;
new_plugin->hook_signal_send = &hook_signal_send;
diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h
index 8d49971a7..68e89b3ce 100644
--- a/src/plugins/weechat-plugin.h
+++ b/src/plugins/weechat-plugin.h
@@ -58,6 +58,17 @@ struct t_weelist;
#define WEECHAT_HOTLIST_PRIVATE "2"
#define WEECHAT_HOTLIST_HIGHLIGHT "3"
+/* connect status for connection hooked */
+#define WEECHAT_HOOK_CONNECT_OK 0
+#define WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND 1
+#define WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND 2
+#define WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED 3
+#define WEECHAT_HOOK_CONNECT_PROXY_ERROR 4
+#define WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR 5
+#define WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR 6
+#define WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR 7
+#define WEECHAT_HOOK_CONNECT_MEMORY_ERROR 8
+
/* type of data for signal hooked */
#define WEECHAT_HOOK_SIGNAL_STRING "string"
#define WEECHAT_HOOK_SIGNAL_INT "int"
@@ -280,6 +291,12 @@ struct t_weechat_plugin
int flag_exception,
int (*callback)(void *data),
void *callback_data);
+ struct t_hook *(*hook_connect) (struct t_weechat_plugin *plugin,
+ char *address, int port,
+ int sock, int ipv6, void *gnutls_sess,
+ char *local_hostname,
+ int (*callback)(void *data, int status),
+ void *callback_data);
struct t_hook *(*hook_print) (struct t_weechat_plugin *plugin,
struct t_gui_buffer *buffer,
char *tags, char *message,
@@ -711,6 +728,12 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
weechat_plugin->hook_fd(weechat_plugin, __fd, __flag_read, \
__flag_write, __flag_exception, __callback, \
__data)
+#define weechat_hook_connect(__address, __port, __sock, __ipv6, \
+ __gnutls_sess, __local_hostname, \
+ __callback, __data) \
+ weechat_plugin->hook_connect(weechat_plugin, __address, __port, \
+ __sock, __ipv6, __gnutls_sess, \
+ __local_hostname, __callback, __data)
#define weechat_hook_print(__buffer, __tags, __msg, __strip__colors, \
__callback, __data) \
weechat_plugin->hook_print(weechat_plugin, __buffer, __tags, \