summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2008-11-23 23:04:52 +0100
committerSebastien Helleu <flashcode@flashtux.org>2008-11-23 23:04:52 +0100
commit2e52e54a3afa953e12e1e009b19a66202f0674a6 (patch)
tree08fa64e1c2b89498977ae33004f62c1757288910 /src
parent09bed16dbd39791b43f86a1c00279c7fdb5cbb58 (diff)
downloadweechat-2e52e54a3afa953e12e1e009b19a66202f0674a6.zip
Add support for more than one proxy, with proxy selection for each IRC server (task #6859)
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/Makefile.am6
-rw-r--r--src/core/wee-command.c231
-rw-r--r--src/core/wee-config.c131
-rw-r--r--src/core/wee-config.h16
-rw-r--r--src/core/wee-hook.c6
-rw-r--r--src/core/wee-hook.h6
-rw-r--r--src/core/wee-network.c137
-rw-r--r--src/core/wee-network.h26
-rw-r--r--src/core/wee-proxy.c659
-rw-r--r--src/core/wee-proxy.h88
-rw-r--r--src/gui/gui-bar.c14
-rw-r--r--src/gui/gui-bar.h18
-rw-r--r--src/gui/gui-completion.c25
-rw-r--r--src/plugins/irc/irc-command.c2
-rw-r--r--src/plugins/irc/irc-config.c17
-rw-r--r--src/plugins/irc/irc-config.h1
-rw-r--r--src/plugins/irc/irc-protocol.c2
-rw-r--r--src/plugins/irc/irc-server.c178
-rw-r--r--src/plugins/irc/irc-server.h2
-rw-r--r--src/plugins/scripts/lua/weechat-lua-api.c13
-rw-r--r--src/plugins/scripts/perl/weechat-perl-api.c18
-rw-r--r--src/plugins/scripts/python/weechat-python-api.c10
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby-api.c24
-rw-r--r--src/plugins/scripts/script-api.c9
-rw-r--r--src/plugins/scripts/script-api.h1
-rw-r--r--src/plugins/scripts/tcl/weechat-tcl-api.c18
-rw-r--r--src/plugins/weechat-plugin.h25
-rw-r--r--src/plugins/xfer/xfer-dcc.c3
-rw-r--r--src/plugins/xfer/xfer-network.c3
-rw-r--r--src/plugins/xfer/xfer.c24
-rw-r--r--src/plugins/xfer/xfer.h1
32 files changed, 1444 insertions, 271 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index fe6d9f2fd..03c972493 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -27,6 +27,7 @@ wee-input.c wee-input.h
wee-list.c wee-list.h
wee-log.c wee-log.h
wee-network.c wee-network.h
+wee-proxy.c wee-proxy.h
wee-string.c wee-string.h
wee-upgrade.c wee-upgrade.h
wee-upgrade-file.c wee-upgrade-file.h
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index c2c57442f..61af3722f 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -42,12 +42,14 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-log.h \
wee-network.c \
wee-network.h \
+ wee-proxy.c \
+ wee-proxy.h \
+ wee-string.c \
+ wee-string.h \
wee-upgrade.c \
wee-upgrade.h \
wee-upgrade-file.c \
wee-upgrade-file.h \
- wee-string.c \
- wee-string.h \
wee-utf8.c \
wee-utf8.h \
wee-util.c \
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 3164e995d..a04f306d7 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -37,8 +37,9 @@
#include "wee-hook.h"
#include "wee-input.h"
#include "wee-log.h"
-#include "wee-upgrade.h"
+#include "wee-proxy.h"
#include "wee-string.h"
+#include "wee-upgrade.h"
#include "wee-utf8.h"
#include "wee-list.h"
#include "../gui/gui-bar.h"
@@ -150,7 +151,6 @@ command_bar (void *data, struct t_gui_buffer *buffer,
/* make C compiler happy */
(void) data;
- (void) buffer;
/* list of bars */
if ((argc == 1)
@@ -2218,6 +2218,201 @@ command_plugin (void *data, struct t_gui_buffer *buffer,
}
/*
+ * command_proxy_list: list proxies
+ */
+
+void
+command_proxy_list ()
+{
+ struct t_proxy *ptr_proxy;
+
+ if (weechat_proxies)
+ {
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL, _("List of proxies:"));
+ for (ptr_proxy = weechat_proxies; ptr_proxy;
+ ptr_proxy = ptr_proxy->next_proxy)
+ {
+ gui_chat_printf (NULL,
+ _(" %s%s%s: %s, %s/%d (%s), username: %s, "
+ "password: %s"),
+ GUI_COLOR(GUI_COLOR_CHAT_BUFFER),
+ ptr_proxy->name,
+ GUI_COLOR(GUI_COLOR_CHAT),
+ proxy_type_string[CONFIG_INTEGER(ptr_proxy->type)],
+ CONFIG_STRING(ptr_proxy->address),
+ CONFIG_INTEGER(ptr_proxy->port),
+ (CONFIG_INTEGER(ptr_proxy->ipv6)) ? "IPv6" : "IPv4",
+ (CONFIG_STRING(ptr_proxy->username) &&
+ CONFIG_STRING(ptr_proxy->username)[0]) ?
+ CONFIG_STRING(ptr_proxy->username) : _("(none)"),
+ (CONFIG_STRING(ptr_proxy->password) &&
+ CONFIG_STRING(ptr_proxy->password)[0]) ?
+ CONFIG_STRING(ptr_proxy->password) : _("(none)"));
+ }
+ }
+ else
+ gui_chat_printf (NULL, _("No proxy defined"));
+}
+
+/*
+ * command_proxy: manage proxies
+ */
+
+int
+command_proxy (void *data, struct t_gui_buffer *buffer,
+ int argc, char **argv, char **argv_eol)
+{
+ int type;
+ long number;
+ char *error;
+ struct t_proxy *ptr_proxy;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+
+ /* list of bars */
+ if ((argc == 1)
+ || ((argc == 2) && (string_strcasecmp (argv[1], "list") == 0)))
+ {
+ command_proxy_list ();
+ return WEECHAT_RC_OK;
+ }
+
+ /* add a new proxy */
+ if (string_strcasecmp (argv[1], "add") == 0)
+ {
+ if (argc < 6)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: missing arguments for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "proxy");
+ return WEECHAT_RC_ERROR;
+ }
+ type = proxy_search_type (argv[3]);
+ if (type < 0)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: wrong type \"%s\" for proxy "
+ "\"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[3], argv[2]);
+ return WEECHAT_RC_ERROR;
+ }
+ error = NULL;
+ number = strtol (argv[5], &error, 10);
+ if (error && !error[0])
+ {
+ /* create proxy */
+ if (proxy_new (argv[2], argv[3], "off", argv[4], argv[5],
+ (argc >= 7) ? argv[6] : NULL,
+ (argc >= 8) ? argv_eol[7] : NULL))
+ {
+ gui_chat_printf (NULL, _("Proxy \"%s\" created"),
+ argv[2]);
+ }
+ else
+ {
+ gui_chat_printf (NULL, _("%sError: failed to create proxy "
+ "\"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ }
+ }
+ else
+ {
+ gui_chat_printf (NULL,
+ _("%sError: wrong port \"%s\" for proxy "
+ "\"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[5], argv[2]);
+ return WEECHAT_RC_ERROR;
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* delete a proxy */
+ if (string_strcasecmp (argv[1], "del") == 0)
+ {
+ if (argc < 3)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: missing arguments for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "proxy");
+ return WEECHAT_RC_ERROR;
+ }
+ if (string_strcasecmp (argv[2], "-all") == 0)
+ {
+ proxy_free_all ();
+ gui_chat_printf (NULL, _("All proxies have been deleted"));
+ }
+ else
+ {
+ ptr_proxy = proxy_search (argv[2]);
+ if (!ptr_proxy)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: unknown proxy \"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ return WEECHAT_RC_ERROR;
+ }
+ proxy_free (ptr_proxy);
+ gui_chat_printf (NULL, _("Proxy deleted"));
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ /* set a proxy property */
+ if (string_strcasecmp (argv[1], "set") == 0)
+ {
+ if (argc < 5)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: missing arguments for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "proxy");
+ return WEECHAT_RC_ERROR;
+ }
+ ptr_proxy = proxy_search (argv[2]);
+ if (!ptr_proxy)
+ {
+ gui_chat_printf (NULL,
+ _("%sError: unknown proxy \"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[2]);
+ return WEECHAT_RC_ERROR;
+ }
+ if (!proxy_set (ptr_proxy, argv[3], argv_eol[4]))
+ {
+ gui_chat_printf (NULL,
+ _("%sError: unable to set option \"%s\" for "
+ "proxy \"%s\""),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ argv[3], argv[2]);
+ return WEECHAT_RC_ERROR;
+ }
+
+ return WEECHAT_RC_OK;
+ }
+
+ gui_chat_printf (NULL,
+ _("%sError: unknown option for \"%s\" "
+ "command"),
+ gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
+ "proxy");
+ return WEECHAT_RC_ERROR;
+}
+
+/*
* command_quit: quit WeeChat
*/
@@ -3119,7 +3314,7 @@ command_init ()
"separator item1,item2,...] | [default] | "
"[del barname|-all] | [set barname option value] | "
"[hide|show barname] | [scroll barname buffer "
- "scroll_value] | [list] | [listitems]"),
+ "scroll_value] | [list] | [listfull] | [listitems]"),
N_(" add: add a new bar\n"
" barname: name of bar (must be unique)\n"
" type: root: outside windows),\n"
@@ -3339,6 +3534,36 @@ command_init ()
"Without argument, this command lists loaded plugins."),
"list|listfull|load|autoload|reload|unload %f|%p",
&command_plugin, NULL);
+ hook_command (NULL, "proxy",
+ N_("manage proxies"),
+ N_("[add proxyname type address port [username "
+ "[password]]] | [del proxyname|-all] | [set "
+ "proxyname option value] | [list]"),
+ N_(" add: add a new proxy\n"
+ " proxyname: name of proxy (must be unique)\n"
+ " type: http, socks4 or socks5\n"
+ " address: IP or hostname\n"
+ " port: port\n"
+ " username: username (optional)\n"
+ " password: password (optional)\n"
+ " del: delete a proxy (or all proxies with -all)\n"
+ " set: set a value for a proxy property\n"
+ " option: option to change (for options list, look "
+ "at /set weechat.proxy.<proxyname>.*)\n"
+ " value: new value for option\n"
+ " list: list all proxies\n\n"
+ "Examples:\n"
+ " create a http proxy, running on local host, port 8888:\n"
+ " /proxy add local http 127.0.0.1 8888\n"
+ " create a http proxy using IPv6 protocol:\n"
+ " /proxy add local http 127.0.0.1 8888\n"
+ " /proxy set local ipv6 on\n"
+ " create a socks5 proxy with username/password:\n"
+ " /proxy add myproxy socks5 sample.host.org 3128 myuser mypass\n"
+ " delete a proxy:\n"
+ " /proxy del myproxy"),
+ "add|del|set|list %y name|type|ipv6|address|port|username|password",
+ &command_proxy, NULL);
hook_command (NULL, "quit",
N_("quit WeeChat"),
"", "",
diff --git a/src/core/wee-config.c b/src/core/wee-config.c
index 362ff6692..83f60dfca 100644
--- a/src/core/wee-config.c
+++ b/src/core/wee-config.c
@@ -39,6 +39,7 @@
#include "wee-log.h"
#include "wee-util.h"
#include "wee-list.h"
+#include "wee-proxy.h"
#include "wee-string.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-buffer.h"
@@ -55,6 +56,7 @@
struct t_config_file *weechat_config_file = NULL;
struct t_config_section *weechat_config_section_debug = NULL;
+struct t_config_section *weechat_config_section_proxy = NULL;
struct t_config_section *weechat_config_section_bar = NULL;
/* config, startup section */
@@ -162,16 +164,6 @@ struct t_config_option *config_history_max_lines;
struct t_config_option *config_history_max_commands;
struct t_config_option *config_history_display_default;
-/* config, proxy section */
-
-struct t_config_option *config_proxy_use;
-struct t_config_option *config_proxy_type;
-struct t_config_option *config_proxy_ipv6;
-struct t_config_option *config_proxy_address;
-struct t_config_option *config_proxy_port;
-struct t_config_option *config_proxy_username;
-struct t_config_option *config_proxy_password;
-
/* config, plugin section */
struct t_config_option *config_plugin_autoload;
@@ -451,6 +443,9 @@ config_weechat_reload (void *data, struct t_config_file *config_file)
gui_keyboard_free_all (&gui_keys, &last_gui_key);
gui_keyboard_default_bindings ();
+ /* remove all proxies */
+ proxy_free_all ();
+
/* remove all bars */
gui_bar_free_all ();
@@ -465,6 +460,7 @@ config_weechat_reload (void *data, struct t_config_file *config_file)
if (rc == WEECHAT_CONFIG_READ_OK)
{
+ proxy_use_temp_proxies ();
gui_bar_use_temp_bars ();
gui_bar_create_default ();
}
@@ -618,6 +614,75 @@ config_weechat_debug_set (const char *plugin_name, const char *value)
}
/*
+ * config_weechat_proxy_read: read proxy option in config file
+ */
+
+int
+config_weechat_proxy_read (void *data, struct t_config_file *config_file,
+ struct t_config_section *section,
+ const char *option_name, const char *value)
+{
+ char *pos_option, *proxy_name;
+ struct t_proxy *ptr_temp_proxy;
+ int index_option;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) config_file;
+ (void) section;
+
+ if (option_name)
+ {
+ pos_option = strchr (option_name, '.');
+ if (pos_option)
+ {
+ proxy_name = string_strndup (option_name, pos_option - option_name);
+ if (proxy_name)
+ {
+ pos_option++;
+ for (ptr_temp_proxy = weechat_temp_proxies; ptr_temp_proxy;
+ ptr_temp_proxy = ptr_temp_proxy->next_proxy)
+ {
+ if (strcmp (ptr_temp_proxy->name, proxy_name) == 0)
+ break;
+ }
+ if (!ptr_temp_proxy)
+ {
+ /* create new temp proxy */
+ ptr_temp_proxy = proxy_alloc (proxy_name);
+ if (ptr_temp_proxy)
+ {
+ /* add new temp proxy at end of queue */
+ ptr_temp_proxy->prev_proxy = last_weechat_temp_proxy;
+ ptr_temp_proxy->next_proxy = NULL;
+
+ if (!weechat_temp_proxies)
+ weechat_temp_proxies = ptr_temp_proxy;
+ else
+ last_weechat_temp_proxy->next_proxy = ptr_temp_proxy;
+ last_weechat_temp_proxy = ptr_temp_proxy;
+ }
+ }
+
+ if (ptr_temp_proxy)
+ {
+ index_option = proxy_search_option (pos_option);
+ if (index_option >= 0)
+ {
+ proxy_create_option_temp (ptr_temp_proxy, index_option,
+ value);
+ }
+ }
+
+ free (proxy_name);
+ }
+ }
+ }
+
+ return WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
+}
+
+/*
* config_weechat_bar_read: read bar option in config file
*/
@@ -1657,54 +1722,21 @@ config_weechat_init ()
N_("maximum number of commands to display by default in "
"history listing (0 = unlimited)"),
NULL, 0, INT_MAX, "5", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
- /* proxy */
+
+ /* proxies */
ptr_section = config_file_new_section (weechat_config_file, "proxy",
0, 0,
+ &config_weechat_proxy_read, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL);
if (!ptr_section)
{
config_file_free (weechat_config_file);
return 0;
}
- config_proxy_use = config_file_new_option (
- weechat_config_file, ptr_section,
- "use", "boolean",
- N_("use a proxy server"),
- NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_type = config_file_new_option (
- weechat_config_file, ptr_section,
- "type", "integer",
- N_("proxy type (http (default), socks4, socks5)"),
- "http|socks4|socks5", 0, 0, "http", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_ipv6 = config_file_new_option (
- weechat_config_file, ptr_section,
- "ipv6", "boolean",
- N_("connect to proxy using ipv6"),
- NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_address = config_file_new_option (
- weechat_config_file, ptr_section,
- "address", "string",
- N_("proxy server address (IP or hostname)"),
- NULL, 0, 0, "", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_port = config_file_new_option (
- weechat_config_file, ptr_section,
- "port", "integer",
- N_("port for connecting to proxy server"),
- NULL, 0, 65535, "3128", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_username = config_file_new_option (
- weechat_config_file, ptr_section,
- "username", "string",
- N_("username for proxy server"),
- NULL, 0, 0, "", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- config_proxy_password = config_file_new_option (
- weechat_config_file, ptr_section,
- "password", "string",
- N_("password for proxy server"),
- NULL, 0, 0, "", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
+ weechat_config_section_proxy = ptr_section;
+
/* plugin */
ptr_section = config_file_new_section (weechat_config_file, "plugin",
0, 0,
@@ -1826,6 +1858,7 @@ config_weechat_read ()
if (rc == WEECHAT_CONFIG_READ_OK)
{
config_change_day_change (NULL, NULL);
+ proxy_use_temp_proxies ();
gui_bar_use_temp_bars ();
gui_bar_create_default ();
}
diff --git a/src/core/wee-config.h b/src/core/wee-config.h
index 9def6d0e5..0cdd30777 100644
--- a/src/core/wee-config.h
+++ b/src/core/wee-config.h
@@ -65,14 +65,8 @@ enum t_config_look_save_layout_on_exit
CONFIG_LOOK_SAVE_LAYOUT_ON_EXIT_ALL,
};
-enum t_config_proxy_type
-{
- CONFIG_PROXY_TYPE_HTTP = 0,
- CONFIG_PROXY_TYPE_SOCKS4,
- CONFIG_PROXY_TYPE_SOCKS5,
-};
-
extern struct t_config_file *weechat_config_file;
+extern struct t_config_section *weechat_config_section_proxy;
extern struct t_config_section *weechat_config_section_bar;
extern struct t_config_option *config_startup_command_after_plugins;
@@ -170,14 +164,6 @@ extern struct t_config_option *config_history_max_lines;
extern struct t_config_option *config_history_max_commands;
extern struct t_config_option *config_history_display_default;
-extern struct t_config_option *config_proxy_use;
-extern struct t_config_option *config_proxy_type;
-extern struct t_config_option *config_proxy_ipv6;
-extern struct t_config_option *config_proxy_address;
-extern struct t_config_option *config_proxy_port;
-extern struct t_config_option *config_proxy_username;
-extern struct t_config_option *config_proxy_password;
-
extern struct t_config_option *config_plugin_autoload;
extern struct t_config_option *config_plugin_debug;
extern struct t_config_option *config_plugin_extension;
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 6c1bfb8b1..8e8627974 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -919,8 +919,9 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds)
*/
struct t_hook *
-hook_connect (struct t_weechat_plugin *plugin, const char *address, int port,
- int sock, int ipv6, void *gnutls_sess, const char *local_hostname,
+hook_connect (struct t_weechat_plugin *plugin, const char *proxy,
+ const char *address, int port, int sock, int ipv6,
+ void *gnutls_sess, const char *local_hostname,
t_hook_callback_connect *callback, void *callback_data)
{
struct t_hook *new_hook;
@@ -948,6 +949,7 @@ hook_connect (struct t_weechat_plugin *plugin, const char *address, int port,
new_hook->hook_data = new_hook_connect;
new_hook_connect->callback = callback;
+ new_hook_connect->proxy = (proxy) ? strdup (proxy) : NULL;
new_hook_connect->address = strdup (address);
new_hook_connect->port = port;
new_hook_connect->sock = sock;
diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h
index 0b130e1b8..6e6dd0c27 100644
--- a/src/core/wee-hook.h
+++ b/src/core/wee-hook.h
@@ -128,6 +128,7 @@ typedef int (t_hook_callback_connect)(void *data, int status,
struct t_hook_connect
{
t_hook_callback_connect *callback; /* connect callback */
+ char *proxy; /* proxy (optional) */
char *address; /* peer address */
int port; /* peer port */
int sock; /* socket (created by caller) */
@@ -256,8 +257,9 @@ extern int hook_fd_set (fd_set *read_fds, fd_set *write_fds,
extern void hook_fd_exec (fd_set *read_fds, fd_set *write_fds,
fd_set *exception_fds);
extern struct t_hook *hook_connect (struct t_weechat_plugin *plugin,
- const char *address, int port,
- int sock, int ipv6, void *gnutls_session,
+ const char *proxy, const char *address,
+ int port, int sock, int ipv6,
+ void *gnutls_session,
const char *local_hostname,
t_hook_callback_connect *callback,
void *callback_data);
diff --git a/src/core/wee-network.c b/src/core/wee-network.c
index d4888c984..e30ecf7ef 100644
--- a/src/core/wee-network.c
+++ b/src/core/wee-network.c
@@ -41,6 +41,7 @@
#include "wee-network.h"
#include "wee-hook.h"
#include "wee-config.h"
+#include "wee-proxy.h"
#include "wee-string.h"
#include "../plugins/plugin.h"
@@ -154,19 +155,20 @@ network_base64encode (const char *from, char *to)
*/
int
-network_pass_httpproxy (int sock, const char *address, int port)
+network_pass_httpproxy (struct t_proxy *proxy, int sock, const char *address,
+ int port)
{
char buffer[256], authbuf[128], authbuf_base64[196];
int n, m;
- if (CONFIG_STRING(config_proxy_username)
- && CONFIG_STRING(config_proxy_username)[0])
+ if (CONFIG_STRING(proxy->username)
+ && CONFIG_STRING(proxy->username)[0])
{
/* authentification */
snprintf (authbuf, sizeof (authbuf), "%s:%s",
- CONFIG_STRING(config_proxy_username),
- (CONFIG_STRING(config_proxy_password)) ?
- CONFIG_STRING(config_proxy_password) : "");
+ CONFIG_STRING(proxy->username),
+ (CONFIG_STRING(proxy->password)) ?
+ CONFIG_STRING(proxy->password) : "");
network_base64encode (authbuf, authbuf_base64);
n = snprintf (buffer, sizeof (buffer),
"CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n",
@@ -248,22 +250,12 @@ network_resolve (const char *hostname, char *ip, int *version)
*/
int
-network_pass_socks4proxy (int sock, const char *address, int port)
+network_pass_socks4proxy (struct t_proxy *proxy, int sock, const char *address,
+ int port)
{
- /*
- * socks4 protocol is explained here:
- * http://en.wikipedia.org/wiki/SOCKS
- *
- */
+ /* socks4 protocol is explained here: http://en.wikipedia.org/wiki/SOCKS */
- struct s_socks4
- {
- char version; /* 1 byte */ /* socks version : 4 or 5 */
- char method; /* 1 byte */ /* socks method : connect (1) or bind (2) */
- unsigned short port; /* 2 bytes */ /* destination port */
- unsigned int address; /* 4 bytes */ /* destination address */
- char user[64]; /* username (64 characters seems to be enought) */
- } socks4;
+ struct t_network_socks4 socks4;
unsigned char buffer[24];
char ip_addr[NI_MAXHOST];
@@ -272,7 +264,7 @@ network_pass_socks4proxy (int sock, const char *address, int port)
socks4.port = htons (port);
network_resolve (address, ip_addr, NULL);
socks4.address = inet_addr (ip_addr);
- strncpy (socks4.user, CONFIG_STRING(config_proxy_username),
+ strncpy (socks4.user, CONFIG_STRING(proxy->username),
sizeof (socks4.user) - 1);
send (sock, (char *) &socks4, 8 + strlen (socks4.user) + 1, 0);
@@ -294,19 +286,15 @@ network_pass_socks4proxy (int sock, const char *address, int port)
*/
int
-network_pass_socks5proxy (int sock, const char *address, int port)
+network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
+ int port)
{
/*
* socks5 protocol is explained in RFC 1928
* socks5 authentication with username/pass is explained in RFC 1929
*/
- struct s_sock5
- {
- char version; /* 1 byte */ /* socks version : 4 or 5 */
- char nmethods; /* 1 byte */ /* size in byte(s) of field 'method', here 1 byte */
- char method; /* 1-255 bytes */ /* socks method : noauth (0), auth(user/pass) (2), ... */
- } socks5;
+ struct t_network_socks5 socks5;
unsigned char buffer[288];
int username_len, password_len, addr_len, addr_buffer_len;
unsigned char *addr_buffer;
@@ -314,8 +302,8 @@ network_pass_socks5proxy (int sock, const char *address, int port)
socks5.version = 5;
socks5.nmethods = 1;
- if (CONFIG_STRING(config_proxy_username)
- && CONFIG_STRING(config_proxy_username)[0])
+ if (CONFIG_STRING(proxy->username)
+ && CONFIG_STRING(proxy->username)[0])
socks5.method = 2; /* with authentication */
else
socks5.method = 0; /* without authentication */
@@ -325,8 +313,8 @@ network_pass_socks5proxy (int sock, const char *address, int port)
if (recv (sock, buffer, 2, 0) != 2)
return 0;
- if (CONFIG_STRING(config_proxy_username)
- && CONFIG_STRING(config_proxy_username)[0])
+ if (CONFIG_STRING(proxy->username)
+ && CONFIG_STRING(proxy->username)[0])
{
/* with authentication */
/* -> socks server must respond with :
@@ -338,16 +326,16 @@ network_pass_socks5proxy (int sock, const char *address, int port)
return 0;
/* authentication as in RFC 1929 */
- username_len = strlen (CONFIG_STRING(config_proxy_username));
- password_len = strlen (CONFIG_STRING(config_proxy_password));
+ username_len = strlen (CONFIG_STRING(proxy->username));
+ password_len = strlen (CONFIG_STRING(proxy->password));
/* make username/password buffer */
buffer[0] = 1;
buffer[1] = (unsigned char) username_len;
- memcpy(buffer + 2, CONFIG_STRING(config_proxy_username), username_len);
+ memcpy(buffer + 2, CONFIG_STRING(proxy->username), username_len);
buffer[2 + username_len] = (unsigned char) password_len;
memcpy (buffer + 3 + username_len,
- CONFIG_STRING(config_proxy_password), password_len);
+ CONFIG_STRING(proxy->password), password_len);
send (sock, buffer, 3 + username_len + password_len, 0);
@@ -440,23 +428,26 @@ network_pass_socks5proxy (int sock, const char *address, int port)
*/
int
-network_pass_proxy (int sock, const char *address, int port)
+network_pass_proxy (const char *proxy, int sock, const char *address, int port)
{
int rc;
+ struct t_proxy *ptr_proxy;
rc = 0;
- if (CONFIG_BOOLEAN(config_proxy_use))
+
+ ptr_proxy = proxy_search (proxy);
+ if (ptr_proxy)
{
- switch (CONFIG_INTEGER(config_proxy_type))
+ switch (CONFIG_INTEGER(ptr_proxy->type))
{
- case CONFIG_PROXY_TYPE_HTTP:
- rc = network_pass_httpproxy (sock, address, port);
+ case PROXY_TYPE_HTTP:
+ rc = network_pass_httpproxy (ptr_proxy, sock, address, port);
break;
- case CONFIG_PROXY_TYPE_SOCKS4:
- rc = network_pass_socks4proxy (sock, address, port);
+ case PROXY_TYPE_SOCKS4:
+ rc = network_pass_socks4proxy (ptr_proxy, sock, address, port);
break;
- case CONFIG_PROXY_TYPE_SOCKS5:
- rc = network_pass_socks5proxy (sock, address, port);
+ case PROXY_TYPE_SOCKS5:
+ rc = network_pass_socks5proxy (ptr_proxy, sock, address, port);
break;
}
}
@@ -470,30 +461,40 @@ network_pass_proxy (int sock, const char *address, int port)
*/
int
-network_connect_to (int sock, unsigned long address, int port)
+network_connect_to (const char *proxy, int sock,
+ unsigned long address, int port)
{
+ struct t_proxy *ptr_proxy;
struct sockaddr_in addr;
struct hostent *hostent;
char *ip4;
int ret;
- if (CONFIG_BOOLEAN(config_proxy_use))
+ ptr_proxy = NULL;
+ if (proxy && proxy[0])
+ {
+ ptr_proxy = proxy_search (proxy);
+ if (!ptr_proxy)
+ return 0;
+ }
+
+ if (ptr_proxy)
{
memset (&addr, 0, sizeof (addr));
addr.sin_addr.s_addr = htonl (address);
ip4 = inet_ntoa(addr.sin_addr);
memset (&addr, 0, sizeof (addr));
- addr.sin_port = htons (CONFIG_INTEGER(config_proxy_port));
+ addr.sin_port = htons (CONFIG_INTEGER(ptr_proxy->port));
addr.sin_family = AF_INET;
- hostent = gethostbyname (CONFIG_STRING(config_proxy_address));
+ hostent = gethostbyname (CONFIG_STRING(ptr_proxy->address));
if (!hostent)
return 0;
memcpy(&(addr.sin_addr), *(hostent->h_addr_list), sizeof(struct in_addr));
ret = connect (sock, (struct sockaddr *) &addr, sizeof (addr));
if ((ret == -1) && (errno != EINPROGRESS))
return 0;
- if (!network_pass_proxy (sock, ip4, port))
+ if (!network_pass_proxy (proxy, sock, ip4, port))
return 0;
}
else
@@ -516,6 +517,7 @@ network_connect_to (int sock, unsigned long address, int port)
void
network_connect_child (struct t_hook *hook_connect)
{
+ struct t_proxy *ptr_proxy;
struct addrinfo hints, *res, *res_local, *ptr_res;
char status_str[2], *ptr_address, *status_ok_with_address;
char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
@@ -527,13 +529,27 @@ network_connect_child (struct t_hook *hook_connect)
status_str[1] = '\0';
- if (CONFIG_BOOLEAN(config_proxy_use))
+ ptr_proxy = NULL;
+ if (HOOK_CONNECT(hook_connect, proxy)
+ && HOOK_CONNECT(hook_connect, proxy)[0])
+ {
+ ptr_proxy = proxy_search (HOOK_CONNECT(hook_connect, proxy));
+ if (!ptr_proxy)
+ {
+ /* proxy not found */
+ status_str[0] = '0' + WEECHAT_HOOK_CONNECT_PROXY_ERROR;
+ write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
+ return;
+ }
+ }
+
+ if (ptr_proxy)
{
/* get info about peer */
memset (&hints, 0, sizeof (hints));
- hints.ai_family = (CONFIG_BOOLEAN(config_proxy_ipv6)) ? AF_INET6 : AF_INET;
+ hints.ai_family = (CONFIG_BOOLEAN(ptr_proxy->ipv6)) ? AF_INET6 : AF_INET;
hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo (CONFIG_STRING(config_proxy_address), NULL, &hints, &res) !=0)
+ if (getaddrinfo (CONFIG_STRING(ptr_proxy->address), NULL, &hints, &res) !=0)
{
/* address not found */
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND;
@@ -547,8 +563,8 @@ network_connect_child (struct t_hook *hook_connect)
write (HOOK_CONNECT(hook_connect, child_write), status_str, 1);
return;
}
- if ((CONFIG_BOOLEAN(config_proxy_ipv6) && (res->ai_family != AF_INET6))
- || ((!CONFIG_BOOLEAN(config_proxy_ipv6) && (res->ai_family != AF_INET))))
+ if ((CONFIG_BOOLEAN(ptr_proxy->ipv6) && (res->ai_family != AF_INET6))
+ || ((!CONFIG_BOOLEAN(ptr_proxy->ipv6) && (res->ai_family != AF_INET))))
{
/* IP address not found */
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND;
@@ -557,10 +573,10 @@ network_connect_child (struct t_hook *hook_connect)
return;
}
- if (CONFIG_BOOLEAN(config_proxy_ipv6))
- ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (CONFIG_INTEGER(config_proxy_port));
+ if (CONFIG_BOOLEAN(ptr_proxy->ipv6))
+ ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (CONFIG_INTEGER(ptr_proxy->port));
else
- ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (CONFIG_INTEGER(config_proxy_port));
+ ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (CONFIG_INTEGER(ptr_proxy->port));
/* connect to peer */
if (connect (HOOK_CONNECT(hook_connect, sock),
@@ -573,7 +589,8 @@ network_connect_child (struct t_hook *hook_connect)
return;
}
- if (!network_pass_proxy (HOOK_CONNECT(hook_connect, sock),
+ if (!network_pass_proxy (HOOK_CONNECT(hook_connect, proxy),
+ HOOK_CONNECT(hook_connect, sock),
HOOK_CONNECT(hook_connect, address),
HOOK_CONNECT(hook_connect, port)))
{
@@ -583,7 +600,7 @@ network_connect_child (struct t_hook *hook_connect)
freeaddrinfo (res);
return;
}
-
+
status_str[0] = '0' + WEECHAT_HOOK_CONNECT_OK;
}
else
diff --git a/src/core/wee-network.h b/src/core/wee-network.h
index 4f8031d57..056735751 100644
--- a/src/core/wee-network.h
+++ b/src/core/wee-network.h
@@ -22,10 +22,30 @@
struct t_hook;
+struct t_network_socks4
+{
+ char version; /* 1 byte : socks version: 4 or 5 */
+ char method; /* 1 byte : socks method: connect (1) or bind (2) */
+ unsigned short port; /* 2 bytes: destination port */
+ unsigned int address; /* 4 bytes: destination address */
+ char user[128]; /* username */
+};
+
+struct t_network_socks5
+{
+ char version; /* 1 byte: socks version : 4 or 5 */
+ char nmethods; /* 1 byte: size in byte(s) of field 'method', */
+ /* here 1 byte */
+ char method; /* 1 byte: socks method : noauth (0), */
+ /* auth(user/pass) (2), ... */
+};
+
extern void network_init ();
extern void network_end ();
-extern int network_pass_proxy (int sock, const char *address, int port);
-extern int network_connect_to (int sock, unsigned long address, int port);
-extern void network_connect_with_fork (struct t_hook *);
+extern int network_pass_proxy (const char *proxy, int sock,
+ const char *address, int port);
+extern int network_connect_to (const char *proxy, int sock,
+ unsigned long address, int port);
+extern void network_connect_with_fork (struct t_hook *hook_connect);
#endif /* wee-network.h */
diff --git a/src/core/wee-proxy.c b/src/core/wee-proxy.c
new file mode 100644
index 000000000..5c25c3431
--- /dev/null
+++ b/src/core/wee-proxy.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* wee-proxy.c: proxy functions */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "weechat.h"
+#include "wee-proxy.h"
+#include "wee-config.h"
+#include "wee-log.h"
+#include "wee-string.h"
+
+
+char *proxy_option_string[PROXY_NUM_OPTIONS] =
+{ "type", "ipv6", "address", "port", "username", "password" };
+char *proxy_type_string[PROXY_NUM_TYPES] =
+{ "http", "socks4", "socks5" };
+
+struct t_proxy *weechat_proxies = NULL; /* first proxy */
+struct t_proxy *last_weechat_proxy = NULL; /* last proxy */
+
+struct t_proxy *weechat_temp_proxies = NULL; /* proxies used when */
+struct t_proxy *last_weechat_temp_proxy = NULL; /* reading config */
+
+
+/*
+ * proxy_search_option search a proxy option name
+ * return index of option in array
+ * "proxy_option_string", or -1 if not found
+ */
+
+int
+proxy_search_option (const char *option_name)
+{
+ int i;
+
+ if (!option_name)
+ return -1;
+
+ for (i = 0; i < PROXY_NUM_OPTIONS; i++)
+ {
+ if (string_strcasecmp (proxy_option_string[i], option_name) == 0)
+ return i;
+ }
+
+ /* proxy option not found */
+ return -1;
+}
+
+/*
+ * proxy_search_type: search type number with string
+ * return -1 if type is not found
+ */
+
+int
+proxy_search_type (const char *type)
+{
+ int i;
+
+ if (!type)
+ return -1;
+
+ for (i = 0; i < PROXY_NUM_TYPES; i++)
+ {
+ if (string_strcasecmp (proxy_type_string[i], type) == 0)
+ return i;
+ }
+
+ /* type not found */
+ return -1;
+}
+
+/*
+ * proxy_search: search a proxy by name
+ */
+
+struct t_proxy *
+proxy_search (const char *name)
+{
+ struct t_proxy *ptr_proxy;
+
+ if (!name || !name[0])
+ return NULL;
+
+ for (ptr_proxy = weechat_proxies; ptr_proxy;
+ ptr_proxy = ptr_proxy->next_proxy)
+ {
+ if (strcmp (ptr_proxy->name, name) == 0)
+ return ptr_proxy;
+ }
+
+ /* proxy not found */
+ return NULL;
+}
+
+/*
+ * proxy_search_with_option_name: search a proxy with name of option
+ * (like "local_proxy.address")
+ */
+
+struct t_proxy *
+proxy_search_with_option_name (const char *option_name)
+{
+ char *proxy_name, *pos_option;
+ struct t_proxy *ptr_proxy;
+
+ ptr_proxy = NULL;
+
+ pos_option = strchr (option_name, '.');
+ if (pos_option)
+ {
+ proxy_name = string_strndup (option_name, pos_option - option_name);
+ if (proxy_name)
+ {
+ for (ptr_proxy = weechat_proxies; ptr_proxy;
+ ptr_proxy = ptr_proxy->next_proxy)
+ {
+ if (strcmp (ptr_proxy->name, proxy_name) == 0)
+ break;
+ }
+ free (proxy_name);
+ }
+ }
+
+ return ptr_proxy;
+}
+
+/*
+ * proxy_set_name: set name for a proxy
+ */
+
+void
+proxy_set_name (struct t_proxy *proxy, const char *name)
+{
+ int length;
+ char *option_name;
+
+ if (!name || !name[0])
+ return;
+
+ length = strlen (name) + 64;
+ option_name = malloc (length);
+ if (option_name)
+ {
+ snprintf (option_name, length, "%s.type", name);
+ config_file_option_rename (proxy->type, option_name);
+ snprintf (option_name, length, "%s.ipv6", name);
+ config_file_option_rename (proxy->ipv6, option_name);
+ snprintf (option_name, length, "%s.address", name);
+ config_file_option_rename (proxy->address, option_name);
+ snprintf (option_name, length, "%s.port", name);
+ config_file_option_rename (proxy->port, option_name);
+ snprintf (option_name, length, "%s.username", name);
+ config_file_option_rename (proxy->username, option_name);
+ snprintf (option_name, length, "%s.password", name);
+ config_file_option_rename (proxy->password, option_name);
+
+ if (proxy->name)
+ free (proxy->name);
+ proxy->name = strdup (name);
+
+ free (option_name);
+ }
+}
+
+/*
+ * proxy_set: set a property for a proxy
+ * return: 1 if ok, 0 if error
+ */
+
+int
+proxy_set (struct t_proxy *proxy, const char *property, const char *value)
+{
+ if (!proxy || !property || !value)
+ return 0;
+
+ if (string_strcasecmp (property, "name") == 0)
+ {
+ proxy_set_name (proxy, value);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "type") == 0)
+ {
+ config_file_option_set (proxy->type, value, 1);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "ipv6") == 0)
+ {
+ config_file_option_set (proxy->ipv6, value, 1);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "address") == 0)
+ {
+ config_file_option_set (proxy->address, value, 1);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "port") == 0)
+ {
+ config_file_option_set (proxy->port, value, 1);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "username") == 0)
+ {
+ config_file_option_set (proxy->username, value, 1);
+ return 1;
+ }
+ else if (string_strcasecmp (property, "password") == 0)
+ {
+ config_file_option_set (proxy->password, value, 1);
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * proxy_create_option: create an option for a proxy
+ */
+
+struct t_config_option *
+proxy_create_option (const char *proxy_name, int index_option,
+ const char *value)
+{
+ struct t_config_option *ptr_option;
+ int length;
+ char *option_name;
+
+ ptr_option = NULL;
+
+ length = strlen (proxy_name) + 1 +
+ strlen (proxy_option_string[index_option]) + 1;
+ option_name = malloc (length);
+ if (option_name)
+ {
+ snprintf (option_name, length, "%s.%s",
+ proxy_name, proxy_option_string[index_option]);
+
+ switch (index_option)
+ {
+ case PROXY_OPTION_TYPE:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "integer",
+ N_("proxy type (http (default), socks4, socks5)"),
+ "http|socks4|socks5", 0, 0, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_OPTION_IPV6:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "boolean",
+ N_("connect to proxy using ipv6"),
+ NULL, 0, 0, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_OPTION_ADDRESS:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "string",
+ N_("proxy server address (IP or hostname)"),
+ NULL, 0, 0, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_OPTION_PORT:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "integer",
+ N_("port for connecting to proxy server"),
+ NULL, 0, 65535, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_OPTION_USERNAME:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "string",
+ N_("username for proxy server"),
+ NULL, 0, 0, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_OPTION_PASSWORD:
+ ptr_option = config_file_new_option (
+ weechat_config_file, weechat_config_section_proxy,
+ option_name, "string",
+ N_("password for proxy server"),
+ NULL, 0, 0, value, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ break;
+ case PROXY_NUM_OPTIONS:
+ break;
+ }
+ free (option_name);
+ }
+
+ return ptr_option;
+}
+
+/*
+ * proxy_create_option_temp: create option for a temporary proxy (when reading
+ * config file)
+ */
+
+void
+proxy_create_option_temp (struct t_proxy *temp_proxy, int index_option,
+ const char *value)
+{
+ struct t_config_option *new_option;
+
+ new_option = proxy_create_option (temp_proxy->name,
+ index_option,
+ value);
+ if (new_option)
+ {
+ switch (index_option)
+ {
+ case PROXY_OPTION_TYPE:
+ temp_proxy->type = new_option;
+ break;
+ case PROXY_OPTION_IPV6:
+ temp_proxy->ipv6 = new_option;
+ break;
+ case PROXY_OPTION_ADDRESS:
+ temp_proxy->address = new_option;
+ break;
+ case PROXY_OPTION_PORT:
+ temp_proxy->port = new_option;
+ break;
+ case PROXY_OPTION_USERNAME:
+ temp_proxy->username = new_option;
+ break;
+ case PROXY_OPTION_PASSWORD:
+ temp_proxy->password = new_option;
+ break;
+ }
+ }
+}
+
+/*
+ * proxy_alloc: allocate and initialize new proxy structure
+ */
+
+struct t_proxy *
+proxy_alloc (const char *name)
+{
+ struct t_proxy *new_proxy;
+
+ new_proxy = malloc (sizeof (*new_proxy));
+ if (new_proxy)
+ {
+ new_proxy->name = strdup (name);
+ new_proxy->type = NULL;
+ new_proxy->ipv6 = NULL;
+ new_proxy->address = NULL;
+ new_proxy->port = NULL;
+ new_proxy->username = NULL;
+ new_proxy->password = NULL;
+ new_proxy->prev_proxy = NULL;
+ new_proxy->next_proxy = NULL;
+ }
+
+ return new_proxy;
+}
+
+/*
+ * proxy_new_with_options: create a new proxy with options
+ */
+
+struct t_proxy *
+proxy_new_with_options (const char *name,
+ struct t_config_option *type,
+ struct t_config_option *ipv6,
+ struct t_config_option *address,
+ struct t_config_option *port,
+ struct t_config_option *username,
+ struct t_config_option *password)
+{
+ struct t_proxy *new_proxy;
+
+ /* create proxy */
+ new_proxy = proxy_alloc (name);
+ if (new_proxy)
+ {
+ new_proxy->type = type;
+ new_proxy->ipv6 = ipv6;
+ new_proxy->address = address;
+ new_proxy->port = port;
+ new_proxy->username = username;
+ new_proxy->password = password;
+
+ /* add proxy to proxies list */
+ new_proxy->prev_proxy = last_weechat_proxy;
+ if (weechat_proxies)
+ last_weechat_proxy->next_proxy = new_proxy;
+ else
+ weechat_proxies = new_proxy;
+ last_weechat_proxy = new_proxy;
+ new_proxy->next_proxy = NULL;
+ }
+
+ return new_proxy;
+}
+
+/*
+ * proxy_new: create a new proxy
+ */
+
+struct t_proxy *
+proxy_new (const char *name, const char *type, const char *ipv6,
+ const char *address, const char *port, const char *username,
+ const char *password)
+{
+ struct t_config_option *option_type, *option_ipv6, *option_address;
+ struct t_config_option *option_port, *option_username, *option_password;
+ struct t_proxy *new_proxy;
+
+ if (!name || !name[0])
+ return NULL;
+
+ /* it's not possible to create 2 proxies with same name */
+ if (proxy_search (name))
+ return NULL;
+
+ /* look for type */
+ if (proxy_search_type (type) < 0)
+ return NULL;
+
+ option_type = proxy_create_option (name, PROXY_OPTION_TYPE,
+ type);
+ option_ipv6 = proxy_create_option (name, PROXY_OPTION_IPV6,
+ ipv6);
+ option_address = proxy_create_option (name, PROXY_OPTION_ADDRESS,
+ (address) ? address : "");
+ option_port = proxy_create_option (name, PROXY_OPTION_PORT,
+ port);
+ option_username = proxy_create_option (name, PROXY_OPTION_USERNAME,
+ (username) ? username : "");
+ option_password = proxy_create_option (name, PROXY_OPTION_PASSWORD,
+ (password) ? password : "");
+
+ new_proxy = proxy_new_with_options (name, option_type, option_ipv6,
+ option_address, option_port,
+ option_username, option_password);
+ if (!new_proxy)
+ {
+ if (option_type)
+ config_file_option_free (option_type);
+ if (option_ipv6)
+ config_file_option_free (option_ipv6);
+ if (option_address)
+ config_file_option_free (option_address);
+ if (option_port)
+ config_file_option_free (option_port);
+ if (option_username)
+ config_file_option_free (option_username);
+ if (option_password)
+ config_file_option_free (option_password);
+ }
+
+ return new_proxy;
+}
+
+/*
+ * proxy_use_temp_proxies: use temp proxies (created by reading config file)
+ */
+
+void
+proxy_use_temp_proxies ()
+{
+ struct t_proxy *ptr_temp_proxy, *next_temp_proxy;
+
+ for (ptr_temp_proxy = weechat_temp_proxies; ptr_temp_proxy;
+ ptr_temp_proxy = ptr_temp_proxy->next_proxy)
+ {
+ if (!ptr_temp_proxy->type)
+ ptr_temp_proxy->type = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_TYPE,
+ "http");
+ if (!ptr_temp_proxy->ipv6)
+ ptr_temp_proxy->ipv6 = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_IPV6,
+ "off");
+ if (!ptr_temp_proxy->address)
+ ptr_temp_proxy->address = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_ADDRESS,
+ "127.0.0.1");
+ if (!ptr_temp_proxy->port)
+ ptr_temp_proxy->port = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_PORT,
+ "3128");
+ if (!ptr_temp_proxy->username)
+ ptr_temp_proxy->username = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_USERNAME,
+ "");
+ if (!ptr_temp_proxy->password)
+ ptr_temp_proxy->password = proxy_create_option (ptr_temp_proxy->name,
+ PROXY_OPTION_PASSWORD,
+ "");
+
+ if (ptr_temp_proxy->type && ptr_temp_proxy->ipv6
+ && ptr_temp_proxy->address && ptr_temp_proxy->port
+ && ptr_temp_proxy->username && ptr_temp_proxy->password)
+ {
+ proxy_new_with_options (ptr_temp_proxy->name,
+ ptr_temp_proxy->type,
+ ptr_temp_proxy->ipv6,
+ ptr_temp_proxy->address,
+ ptr_temp_proxy->port,
+ ptr_temp_proxy->username,
+ ptr_temp_proxy->password);
+ }
+ else
+ {
+ if (ptr_temp_proxy->type)
+ {
+ config_file_option_free (ptr_temp_proxy->type);
+ ptr_temp_proxy->type = NULL;
+ }
+ if (ptr_temp_proxy->ipv6)
+ {
+ config_file_option_free (ptr_temp_proxy->ipv6);
+ ptr_temp_proxy->ipv6 = NULL;
+ }
+ if (ptr_temp_proxy->address)
+ {
+ config_file_option_free (ptr_temp_proxy->address);
+ ptr_temp_proxy->address = NULL;
+ }
+ if (ptr_temp_proxy->port)
+ {
+ config_file_option_free (ptr_temp_proxy->port);
+ ptr_temp_proxy->port = NULL;
+ }
+ if (ptr_temp_proxy->username)
+ {
+ config_file_option_free (ptr_temp_proxy->username);
+ ptr_temp_proxy->username = NULL;
+ }
+ if (ptr_temp_proxy->password)
+ {
+ config_file_option_free (ptr_temp_proxy->password);
+ ptr_temp_proxy->password = NULL;
+ }
+ }
+ }
+
+ /* free all temp proxies */
+ while (weechat_temp_proxies)
+ {
+ next_temp_proxy = weechat_temp_proxies->next_proxy;
+
+ if (weechat_temp_proxies->name)
+ free (weechat_temp_proxies->name);
+ free (weechat_temp_proxies);
+
+ weechat_temp_proxies = next_temp_proxy;
+ }
+ last_weechat_temp_proxy = NULL;
+}
+
+/*
+ * proxy_free: delete a proxy
+ */
+
+void
+proxy_free (struct t_proxy *proxy)
+{
+ if (!proxy)
+ return;
+
+ /* remove proxy from proxies list */
+ if (proxy->prev_proxy)
+ (proxy->prev_proxy)->next_proxy = proxy->next_proxy;
+ if (proxy->next_proxy)
+ (proxy->next_proxy)->prev_proxy = proxy->prev_proxy;
+ if (weechat_proxies == proxy)
+ weechat_proxies = proxy->next_proxy;
+ if (last_weechat_proxy == proxy)
+ last_weechat_proxy = proxy->prev_proxy;
+
+ /* free data */
+ if (proxy->name)
+ free (proxy->name);
+ if (proxy->type)
+ config_file_option_free (proxy->type);
+ if (proxy->ipv6)
+ config_file_option_free (proxy->ipv6);
+ if (proxy->address)
+ config_file_option_free (proxy->address);
+ if (proxy->port)
+ config_file_option_free (proxy->port);
+ if (proxy->username)
+ config_file_option_free (proxy->username);
+ if (proxy->password)
+ config_file_option_free (proxy->password);
+
+ free (proxy);
+}
+
+/*
+ * proxy_free_all: delete all proxies
+ */
+
+void
+proxy_free_all ()
+{
+ while (weechat_proxies)
+ {
+ proxy_free (weechat_proxies);
+ }
+}
+
+/*
+ * proxy_print_log: print proxy infos in log (usually for crash dump)
+ */
+
+void
+proxy_print_log ()
+{
+ struct t_proxy *ptr_proxy;
+
+ for (ptr_proxy = weechat_proxies; ptr_proxy;
+ ptr_proxy = ptr_proxy->next_proxy)
+ {
+ log_printf ("");
+ log_printf ("[proxy (addr:0x%lx)]", ptr_proxy);
+ log_printf (" name . . . . . . . . . : '%s'", ptr_proxy->name);
+ log_printf (" type . . . . . . . . . : %d (%s)",
+ CONFIG_INTEGER(ptr_proxy->type),
+ proxy_type_string[CONFIG_INTEGER(ptr_proxy->type)]);
+ log_printf (" ipv6 . . . . . . . . . : %d", CONFIG_INTEGER(ptr_proxy->ipv6));
+ log_printf (" address. . . . . . . . : '%s'", CONFIG_STRING(ptr_proxy->address));
+ log_printf (" port . . . . . . . . . : %d", CONFIG_INTEGER(ptr_proxy->port));
+ log_printf (" username . . . . . . . : '%s'", CONFIG_STRING(ptr_proxy->username));
+ log_printf (" password . . . . . . . : '%s'", CONFIG_STRING(ptr_proxy->password));
+ log_printf (" prev_proxy . . . . . . : 0x%lx", ptr_proxy->prev_proxy);
+ log_printf (" next_proxy . . . . . . : 0x%lx", ptr_proxy->next_proxy);
+ }
+}
diff --git a/src/core/wee-proxy.h b/src/core/wee-proxy.h
new file mode 100644
index 000000000..9d2d34b9b
--- /dev/null
+++ b/src/core/wee-proxy.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __WEECHAT_PROXY_H
+#define __WEECHAT_PROXY_H 1
+
+enum t_proxy_option
+{
+ PROXY_OPTION_TYPE = 0,
+ PROXY_OPTION_IPV6,
+ PROXY_OPTION_ADDRESS,
+ PROXY_OPTION_PORT,
+ PROXY_OPTION_USERNAME,
+ PROXY_OPTION_PASSWORD,
+ /* number of proxy options */
+ PROXY_NUM_OPTIONS,
+};
+
+enum t_proxy_type
+{
+ PROXY_TYPE_HTTP = 0,
+ PROXY_TYPE_SOCKS4,
+ PROXY_TYPE_SOCKS5,
+ /* number of proxy types */
+ PROXY_NUM_TYPES,
+};
+
+struct t_proxy
+{
+ char *name; /* proxy name */
+ struct t_config_option *type; /* type: http, socks4, socks5 */
+ struct t_config_option *ipv6; /* ipv6 ? or ipv4 ? */
+ struct t_config_option *address; /* address (IP or hostname) */
+ struct t_config_option *port; /* port */
+ struct t_config_option *username; /* username (optional) */
+ struct t_config_option *password; /* password (optional) */
+
+ struct t_proxy *prev_proxy; /* link to previous bar */
+ struct t_proxy *next_proxy; /* link to next bar */
+};
+
+/* variables */
+
+extern char *proxy_type_string[];
+extern struct t_proxy *weechat_proxies;
+extern struct t_proxy *last_weechat_proxy;
+extern struct t_proxy *weechat_temp_proxies;
+extern struct t_proxy *last_weechat_temp_proxy;
+
+/* functions */
+
+extern int proxy_search_option (const char *option_name);
+extern int proxy_search_type (const char *type);
+extern struct t_proxy *proxy_search (const char *name);
+extern int proxy_set (struct t_proxy *bar, const char *property,
+ const char *value);
+extern void proxy_create_option_temp (struct t_proxy *temp_proxy,
+ int index_option, const char *value);
+extern struct t_proxy *proxy_alloc (const char *name);
+extern struct t_proxy *proxy_new (const char *name,
+ const char *type,
+ const char *ipv6,
+ const char *address,
+ const char *port,
+ const char *username,
+ const char *password);
+extern void proxy_use_temp_proxies ();
+extern void proxy_free (struct t_proxy *proxy);
+extern void proxy_free_all ();
+extern void proxy_print_log ();
+
+#endif /* wee-proxy.h */
diff --git a/src/gui/gui-bar.c b/src/gui/gui-bar.c
index a72e98f8c..ac299dc3e 100644
--- a/src/gui/gui-bar.c
+++ b/src/gui/gui-bar.c
@@ -61,7 +61,7 @@ struct t_gui_bar *last_gui_temp_bar = NULL;
/*
* gui_bar_search_option search a bar option name
* return index of option in array
- * "gui_bar_option_str", or -1 if not found
+ * "gui_bar_option_string", or -1 if not found
*/
int
@@ -92,9 +92,12 @@ gui_bar_search_type (const char *type)
{
int i;
+ if (!type)
+ return -1;
+
for (i = 0; i < GUI_BAR_NUM_TYPES; i++)
{
- if (string_strcasecmp (type, gui_bar_type_string[i]) == 0)
+ if (string_strcasecmp (gui_bar_type_string[i], type) == 0)
return i;
}
@@ -112,9 +115,12 @@ gui_bar_search_position (const char *position)
{
int i;
+ if (!position)
+ return -1;
+
for (i = 0; i < GUI_BAR_NUM_POSITIONS; i++)
{
- if (string_strcasecmp (position, gui_bar_position_string[i]) == 0)
+ if (string_strcasecmp (gui_bar_position_string[i], position) == 0)
return i;
}
@@ -877,7 +883,7 @@ gui_bar_set_size_max (struct t_gui_bar *bar, const char *size)
}
/*
- * gui_bar_set: set a property for bar
+ * gui_bar_set: set a property for a bar
* return: 1 if ok, 0 if error
*/
diff --git a/src/gui/gui-bar.h b/src/gui/gui-bar.h
index aaf62a1c4..7338afc85 100644
--- a/src/gui/gui-bar.h
+++ b/src/gui/gui-bar.h
@@ -45,7 +45,7 @@ enum t_gui_bar_option
GUI_BAR_OPTION_COLOR_BG,
GUI_BAR_OPTION_SEPARATOR,
GUI_BAR_OPTION_ITEMS,
- /* number of bar types */
+ /* number of bar options */
GUI_BAR_NUM_OPTIONS,
};
@@ -98,15 +98,15 @@ struct t_gui_bar
struct t_config_option *items; /* bar items */
/* internal vars */
- int conditions_count; /* number of conditions */
- char **conditions_array; /* exploded bar conditions */
- int items_count; /* number of bar items */
- char **items_array; /* exploded bar items */
+ int conditions_count; /* number of conditions */
+ char **conditions_array; /* exploded bar conditions */
+ int items_count; /* number of bar items */
+ char **items_array; /* exploded bar items */
struct t_gui_bar_window *bar_window; /* pointer to bar window */
- /* (for type root only) */
- int bar_refresh_needed; /* refresh for bar is needed? */
- struct t_gui_bar *prev_bar; /* link to previous bar */
- struct t_gui_bar *next_bar; /* link to next bar */
+ /* (for type root only) */
+ int bar_refresh_needed; /* refresh for bar is needed? */
+ struct t_gui_bar *prev_bar; /* link to previous bar */
+ struct t_gui_bar *next_bar; /* link to next bar */
};
/* variables */
diff --git a/src/gui/gui-completion.c b/src/gui/gui-completion.c
index e53fd81af..fd09dd4ef 100644
--- a/src/gui/gui-completion.c
+++ b/src/gui/gui-completion.c
@@ -33,10 +33,11 @@
#include "../core/weechat.h"
#include "../core/wee-config.h"
#include "../core/wee-hook.h"
+#include "../core/wee-list.h"
#include "../core/wee-log.h"
+#include "../core/wee-proxy.h"
#include "../core/wee-string.h"
#include "../core/wee-utf8.h"
-#include "../core/wee-list.h"
#include "../plugins/plugin.h"
#include "../plugins/plugin-config.h"
#include "gui-completion.h"
@@ -321,7 +322,7 @@ gui_completion_list_add (struct t_gui_completion *completion, const char *word,
}
/*
- * gui_completion_list_add_bars_names: add buffers names to completion list
+ * gui_completion_list_add_bars_names: add bars names to completion list
*/
void
@@ -883,6 +884,23 @@ gui_completion_list_add_weechat_cmd (struct t_gui_completion *completion)
}
/*
+ * gui_completion_list_add_proxies_names: add proxies names to completion list
+ */
+
+void
+gui_completion_list_add_proxies_names (struct t_gui_completion *completion)
+{
+ struct t_proxy *ptr_proxy;
+
+ for (ptr_proxy = weechat_proxies; ptr_proxy;
+ ptr_proxy = ptr_proxy->next_proxy)
+ {
+ gui_completion_list_add (completion, ptr_proxy->name,
+ 0, WEECHAT_LIST_POS_SORT);
+ }
+}
+
+/*
* gui_completion_custom: custom completion by a plugin
*/
@@ -983,6 +1001,9 @@ gui_completion_build_list_template (struct t_gui_completion *completion,
case 'w': /* WeeChat commands */
gui_completion_list_add_weechat_cmd (completion);
break;
+ case 'y': /* proxy names */
+ gui_completion_list_add_proxies_names (completion);
+ break;
case '(': /* custom completion by a plugin */
pos++;
pos_end = strchr (pos, ')');
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index b4a312037..033060285 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -620,6 +620,7 @@ irc_command_connect (void *data, struct t_gui_buffer *buffer, int argc,
server_tmp.autoconnect,
server_tmp.autoreconnect,
server_tmp.autoreconnect_delay,
+ server_tmp.proxy,
server_tmp.addresses,
server_tmp.ipv6,
server_tmp.ssl,
@@ -2945,6 +2946,7 @@ irc_command_server (void *data, struct t_gui_buffer *buffer, int argc,
server_tmp.autoconnect,
server_tmp.autoreconnect,
server_tmp.autoreconnect_delay,
+ server_tmp.proxy,
server_tmp.addresses,
server_tmp.ipv6,
server_tmp.ssl,
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c
index 497e6bd4e..ec52f2af6 100644
--- a/src/plugins/irc/irc-config.c
+++ b/src/plugins/irc/irc-config.c
@@ -36,12 +36,12 @@
char *irc_config_server_option_string[IRC_CONFIG_NUM_SERVER_OPTIONS] =
-{ "autoconnect", "autoreconnect", "autoreconnect_delay", "addresses", "ipv6",
- "ssl", "password", "nicks", "username", "realname", "local_hostname",
+{ "autoconnect", "autoreconnect", "autoreconnect_delay", "proxy", "addresses",
+ "ipv6", "ssl", "password", "nicks", "username", "realname", "local_hostname",
"command", "command_delay", "autojoin", "autorejoin"
};
char *irc_config_server_option_default[IRC_CONFIG_NUM_SERVER_OPTIONS] =
-{ "off", "on", "30", "", "off", "off", "", "", "", "", "", "", "0", "",
+{ "off", "on", "30", "", "", "off", "off", "", "", "", "", "", "", "0", "",
"off", ""
};
@@ -710,6 +710,17 @@ 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_PROXY:
+ new_option = weechat_config_new_option (
+ config_file, section,
+ option_name, "string",
+ N_("proxy used for this server (optional)"),
+ NULL, 0, 0,
+ irc_config_server_option_default[index_option], value,
+ NULL, NULL,
+ callback_change, callback_change_data,
+ callback_delete, callback_delete_data);
+ break;
case IRC_CONFIG_SERVER_ADDRESSES:
new_option = weechat_config_new_option (
config_file, section,
diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h
index 3e0b70af9..229ab16a1 100644
--- a/src/plugins/irc/irc-config.h
+++ b/src/plugins/irc/irc-config.h
@@ -31,6 +31,7 @@ enum t_irc_config_server_option
IRC_CONFIG_SERVER_AUTOCONNECT = 0,
IRC_CONFIG_SERVER_AUTORECONNECT,
IRC_CONFIG_SERVER_AUTORECONNECT_DELAY,
+ IRC_CONFIG_SERVER_PROXY,
IRC_CONFIG_SERVER_ADDRESSES,
IRC_CONFIG_SERVER_IPV6,
IRC_CONFIG_SERVER_SSL,
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 126c55acc..b200c7579 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -1573,6 +1573,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, const char *command,
weechat_infolist_new_var_string (item, "local_nick", server->nick);
weechat_infolist_new_var_string (item, "filename", pos_file);
weechat_infolist_new_var_string (item, "size", pos_size);
+ weechat_infolist_new_var_string (item, "proxy", server->proxy);
weechat_infolist_new_var_string (item, "address", pos_addr);
weechat_infolist_new_var_integer (item, "port", atoi (pos_port));
weechat_hook_signal_send ("xfer_add",
@@ -1905,6 +1906,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, const char *command,
weechat_infolist_new_var_string (item, "type", "chat_recv");
weechat_infolist_new_var_string (item, "remote_nick", nick);
weechat_infolist_new_var_string (item, "local_nick", server->nick);
+ weechat_infolist_new_var_string (item, "proxy", server->proxy);
weechat_infolist_new_var_string (item, "address", pos_addr);
weechat_infolist_new_var_integer (item, "port", atoi (pos_port));
weechat_hook_signal_send ("xfer_add",
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index a8e12b9c4..dd1319cc5 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -240,6 +240,11 @@ irc_server_set_with_option (struct t_irc_server *server,
case IRC_CONFIG_SERVER_AUTORECONNECT_DELAY:
server->autoreconnect_delay = weechat_config_integer (option);
break;
+ case IRC_CONFIG_SERVER_PROXY:
+ if (server->proxy)
+ free (server->proxy);
+ server->proxy = strdup (weechat_config_string (option));
+ break;
case IRC_CONFIG_SERVER_ADDRESSES:
irc_server_set_addresses (server, weechat_config_string (option));
break;
@@ -333,6 +338,7 @@ irc_server_init (struct t_irc_server *server)
server->autoconnect = IRC_CONFIG_SERVER_DEFAULT_AUTOCONNECT;
server->autoreconnect = IRC_CONFIG_SERVER_DEFAULT_AUTORECONNECT;
server->autoreconnect_delay = IRC_CONFIG_SERVER_DEFAULT_AUTORECONNECT_DELAY;
+ server->proxy = NULL;
server->addresses = NULL;
server->ipv6 = IRC_CONFIG_SERVER_DEFAULT_IPV6;
server->ssl = IRC_CONFIG_SERVER_DEFAULT_SSL;
@@ -722,6 +728,8 @@ irc_server_free_data (struct t_irc_server *server)
/* free data */
if (server->name)
free (server->name);
+ if (server->proxy)
+ free (server->proxy);
if (server->addresses)
free (server->addresses);
if (server->addresses_array)
@@ -817,8 +825,9 @@ irc_server_free_all ()
struct t_irc_server *
irc_server_new (const char *name, int autoconnect, int autoreconnect,
- int autoreconnect_delay, const char *addresses, int ipv6,
- int ssl, const char *password, const char *nicks,
+ int autoreconnect_delay, const char *proxy,
+ const char *addresses, int ipv6, int ssl,
+ const char *password, const char *nicks,
const char *username, const char *realname,
const char *local_hostname, const char *command,
int command_delay, const char *autojoin, int autorejoin)
@@ -830,11 +839,11 @@ irc_server_new (const char *name, int autoconnect, int autoreconnect,
if (weechat_irc_plugin->debug)
{
- weechat_log_printf ("Creating new server (name:%s, addresses:%s, "
- "pwd:%s, nicks:%s, username:%s, realname:%s, "
- "local_hostname: %s, command:%s, autojoin:%s, "
- "autorejoin:%s)",
- name, addresses, (password) ? password : "",
+ weechat_log_printf ("Creating new server (name:%s, proxy:%s, "
+ "addresses:%s, pwd:%s, nicks:%s, username:%s, "
+ "realname:%s, local_hostname: %s, command:%s, "
+ "autojoin:%s, autorejoin:%s)",
+ name, proxy, addresses, (password) ? password : "",
(nicks) ? nicks : "", (username) ? username : "",
(realname) ? realname : "",
(local_hostname) ? local_hostname : "",
@@ -849,6 +858,7 @@ irc_server_new (const char *name, int autoconnect, int autoreconnect,
new_server->autoconnect = autoconnect;
new_server->autoreconnect = autoreconnect;
new_server->autoreconnect_delay = autoreconnect_delay;
+ new_server->proxy = (proxy) ? strdup (proxy) : NULL;
irc_server_set_addresses (new_server, addresses);
new_server->ipv6 = ipv6;
new_server->ssl = ssl;
@@ -898,6 +908,7 @@ irc_server_duplicate (struct t_irc_server *server, const char *new_server_name)
server->autoconnect,
server->autoreconnect,
server->autoreconnect_delay,
+ server->proxy,
server->addresses,
server->ipv6,
server->ssl,
@@ -1993,15 +2004,11 @@ int
irc_server_connect_cb (void *arg_server, int status, const char *ip_address)
{
struct t_irc_server *server;
- int config_proxy_use;
server = (struct t_irc_server *)arg_server;
server->hook_connect = NULL;
- config_proxy_use = weechat_config_boolean (
- weechat_config_get ("weechat.proxy.use"));
-
switch (status)
{
case WEECHAT_HOOK_CONNECT_OK:
@@ -2020,7 +2027,7 @@ irc_server_connect_cb (void *arg_server, int status, const char *ip_address)
break;
case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
weechat_printf (server->buffer,
- (config_proxy_use) ?
+ (server->proxy && server->proxy[0]) ?
_("%s%s: proxy address \"%s\" not found") :
_("%s%s: address \"%s\" not found"),
irc_buffer_get_server_prefix (server, "error"),
@@ -2031,7 +2038,7 @@ irc_server_connect_cb (void *arg_server, int status, const char *ip_address)
break;
case WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
weechat_printf (server->buffer,
- (config_proxy_use) ?
+ (server->proxy && server->proxy[0]) ?
_("%s%s: proxy IP address not found") :
_("%s%s: IP address not found"),
irc_buffer_get_server_prefix (server, "error"),
@@ -2041,7 +2048,7 @@ irc_server_connect_cb (void *arg_server, int status, const char *ip_address)
break;
case WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED:
weechat_printf (server->buffer,
- (config_proxy_use) ?
+ (server->proxy && server->proxy[0]) ?
_("%s%s: proxy connection refused") :
_("%s%s: connection refused"),
irc_buffer_get_server_prefix (server, "error"),
@@ -2158,40 +2165,17 @@ irc_server_create_buffer (struct t_irc_server *server, int all_servers)
int
irc_server_connect (struct t_irc_server *server, int disable_autojoin)
{
- int set;
- const char *config_proxy_type, *config_proxy_address;
- int config_proxy_use, config_proxy_ipv6, config_proxy_port;
-
- if (!server->addresses || !server->addresses[0])
- {
- weechat_printf (server->buffer,
- _("%s%s: addresses not defined for server \"%s\", "
- "cannot connect"),
- irc_buffer_get_server_prefix (server, "error"),
- IRC_PLUGIN_NAME, server->name);
- return 0;
- }
-
- if (!server->nicks || !server->nicks[0])
- {
- weechat_printf (server->buffer,
- _("%s%s: nicks not defined for server \"%s\", "
- "cannot connect"),
- irc_buffer_get_server_prefix (server, "error"),
- IRC_PLUGIN_NAME, server->name);
- return 0;
- }
+ int set, length;
+ char *option_name;
+ struct t_config_option *proxy_type, *proxy_ipv6, *proxy_address, *proxy_port;
+ const char *str_proxy_type, *str_proxy_address;
- config_proxy_use = weechat_config_boolean (
- weechat_config_get ("weechat.proxy.use"));
- config_proxy_ipv6 = weechat_config_boolean (
- weechat_config_get ("weechat.proxy.ipv6"));
- config_proxy_type = weechat_config_string (
- weechat_config_get ("weechat.proxy.type"));
- config_proxy_address = weechat_config_string (
- weechat_config_get ("weechat.proxy.address"));
- config_proxy_port = weechat_config_integer (
- weechat_config_get ("weechat.proxy.port"));
+ proxy_type = NULL;
+ proxy_ipv6 = NULL;
+ proxy_address = NULL;
+ proxy_port = NULL;
+ str_proxy_type = NULL;
+ str_proxy_address = NULL;
if (!server->buffer)
{
@@ -2222,6 +2206,74 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
"/command irc /server switch");
}
+ if (server->proxy && server->proxy[0])
+ {
+ length = 32 + strlen (server->proxy) + 1;
+ option_name = malloc (length);
+ if (!option_name)
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: not enough memory"),
+ irc_buffer_get_server_prefix (server, "error"),
+ IRC_PLUGIN_NAME);
+ return 0;
+ }
+ snprintf (option_name, length, "weechat.proxy.%s.type",
+ server->proxy);
+ proxy_type = weechat_config_get (option_name);
+ snprintf (option_name, length, "weechat.proxy.%s.ipv6",
+ server->proxy);
+ proxy_ipv6 = weechat_config_get (option_name);
+ snprintf (option_name, length, "weechat.proxy.%s.address",
+ server->proxy);
+ proxy_address = weechat_config_get (option_name);
+ snprintf (option_name, length, "weechat.proxy.%s.port",
+ server->proxy);
+ proxy_port = weechat_config_get (option_name);
+ free (option_name);
+ if (!proxy_type || !proxy_address)
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: proxy \"%s\" not found for server "
+ "\"%s\", cannot connect"),
+ irc_buffer_get_server_prefix (server, "error"),
+ IRC_PLUGIN_NAME, server->proxy, server->name);
+ return 0;
+ }
+ str_proxy_type = weechat_config_string (proxy_type);
+ str_proxy_address = weechat_config_string (proxy_address);
+ if (!str_proxy_type[0] || !proxy_ipv6 || !str_proxy_address[0]
+ || !proxy_port)
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: missing proxy settings, check options "
+ "for proxy \"%s\""),
+ irc_buffer_get_server_prefix (server, "error"),
+ IRC_PLUGIN_NAME, server->proxy);
+ return 0;
+ }
+ }
+
+ if (!server->addresses || !server->addresses[0])
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: addresses not defined for server \"%s\", "
+ "cannot connect"),
+ irc_buffer_get_server_prefix (server, "error"),
+ IRC_PLUGIN_NAME, server->name);
+ return 0;
+ }
+
+ if (!server->nicks || !server->nicks[0])
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: nicks not defined for server \"%s\", "
+ "cannot connect"),
+ irc_buffer_get_server_prefix (server, "error"),
+ IRC_PLUGIN_NAME, server->name);
+ return 0;
+ }
+
#ifndef HAVE_GNUTLS
if (server->ssl)
{
@@ -2233,7 +2285,7 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
return 0;
}
#endif
- if (config_proxy_use)
+ if (proxy_type)
{
weechat_printf (server->buffer,
_("%s%s: connecting to server %s/%d%s%s via %s "
@@ -2244,18 +2296,20 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
server->ports_array[server->current_address],
(server->ipv6) ? " (IPv6)" : "",
(server->ssl) ? " (SSL)" : "",
- config_proxy_type,
- config_proxy_address, config_proxy_port,
- (config_proxy_ipv6) ? " (IPv6)" : "");
+ str_proxy_type,
+ str_proxy_address,
+ weechat_config_integer (proxy_port),
+ (weechat_config_boolean (proxy_ipv6)) ? " (IPv6)" : "");
weechat_log_printf (_("Connecting to server %s/%d%s%s via %s proxy "
"%s/%d%s..."),
server->addresses_array[server->current_address],
server->ports_array[server->current_address],
(server->ipv6) ? " (IPv6)" : "",
(server->ssl) ? " (SSL)" : "",
- config_proxy_type,
- config_proxy_address, config_proxy_port,
- (config_proxy_ipv6) ? " (IPv6)" : "");
+ str_proxy_type,
+ str_proxy_address,
+ weechat_config_integer (proxy_port),
+ (weechat_config_boolean (proxy_ipv6)) ? " (IPv6)" : "");
}
else
{
@@ -2280,10 +2334,16 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
irc_server_close_connection (server);
/* create socket and set options */
- if (config_proxy_use)
- server->sock = socket ((config_proxy_ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
+ if (proxy_type)
+ {
+ server->sock = socket ((weechat_config_integer (proxy_ipv6)) ?
+ AF_INET6 : AF_INET,
+ SOCK_STREAM, 0);
+ }
else
+ {
server->sock = socket ((server->ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
+ }
if (server->sock == -1)
{
weechat_printf (server->buffer,
@@ -2326,7 +2386,8 @@ irc_server_connect (struct t_irc_server *server, int disable_autojoin)
server->disable_autojoin = disable_autojoin;
- server->hook_connect = weechat_hook_connect (server->addresses_array[server->current_address],
+ server->hook_connect = weechat_hook_connect (server->proxy,
+ server->addresses_array[server->current_address],
server->ports_array[server->current_address],
server->sock,
server->ipv6,
@@ -2901,6 +2962,8 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "autoreconnect_delay", server->autoreconnect_delay))
return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "proxy", server->proxy))
+ return 0;
if (!weechat_infolist_new_var_string (ptr_item, "addresses", server->addresses))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "ipv6", server->ipv6))
@@ -2988,6 +3051,7 @@ irc_server_print_log ()
weechat_log_printf (" autoconnect . . . . : %d", ptr_server->autoconnect);
weechat_log_printf (" autoreconnect . . . : %d", ptr_server->autoreconnect);
weechat_log_printf (" autoreconnect_delay : %d", ptr_server->autoreconnect_delay);
+ weechat_log_printf (" proxy . . . . . . . : '%s'", ptr_server->proxy);
weechat_log_printf (" addresses . . . . . : '%s'", ptr_server->addresses);
weechat_log_printf (" ipv6. . . . . . . . : %d", ptr_server->ipv6);
weechat_log_printf (" ssl . . . . . . . . : %d", ptr_server->ssl);
diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h
index 44a12eb13..1650f3637 100644
--- a/src/plugins/irc/irc-server.h
+++ b/src/plugins/irc/irc-server.h
@@ -63,6 +63,7 @@ struct t_irc_server
int autoconnect; /* = 1 if auto connect at startup */
int autoreconnect; /* = 1 if auto reco when disconnected */
int autoreconnect_delay; /* delay before trying again reconnect */
+ char *proxy; /* proxy used for this server (optional) */
char *addresses; /* server addresses (IP/name with port) */
int ipv6; /* use IPv6 protocol */
int ssl; /* SSL protocol */
@@ -157,6 +158,7 @@ extern void irc_server_free_all ();
extern struct t_irc_server *irc_server_new (const char *name, int autoconnect,
int autoreconnect,
int autoreconnect_delay,
+ const char *proxy,
const char *addresses,
int ipv6,
int ssl,
diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c
index 77d1432e6..30b6577d9 100644
--- a/src/plugins/scripts/lua/weechat-lua-api.c
+++ b/src/plugins/scripts/lua/weechat-lua-api.c
@@ -2752,7 +2752,7 @@ weechat_lua_api_hook_connect_cb (void *data, int status, const char *ip_address)
static int
weechat_lua_api_hook_connect (lua_State *L)
{
- const char *address, *local_hostname, *function;
+ const char *proxy, *address, *local_hostname, *function;
int n, port, sock, ipv6;
char *result;
@@ -2764,7 +2764,8 @@ weechat_lua_api_hook_connect (lua_State *L)
WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_connect");
LUA_RETURN_EMPTY;
}
-
+
+ proxy = NULL;
address = NULL;
port = 0;
sock = 0;
@@ -2773,13 +2774,14 @@ weechat_lua_api_hook_connect (lua_State *L)
function = NULL;
n = lua_gettop (lua_current_interpreter);
-
- if (n < 6)
+
+ if (n < 7)
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
LUA_RETURN_EMPTY;
}
-
+
+ proxy = lua_tostring (lua_current_interpreter, -7);
address = lua_tostring (lua_current_interpreter, -6);
port = lua_tonumber (lua_current_interpreter, -5);
sock = lua_tonumber (lua_current_interpreter, -4);
@@ -2789,6 +2791,7 @@ weechat_lua_api_hook_connect (lua_State *L)
result = script_ptr2str (script_api_hook_connect (weechat_lua_plugin,
lua_current_script,
+ proxy,
address,
port,
sock,
diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c
index 5e6dfd17e..5507136a1 100644
--- a/src/plugins/scripts/perl/weechat-perl-api.c
+++ b/src/plugins/scripts/perl/weechat-perl-api.c
@@ -2299,7 +2299,7 @@ weechat_perl_api_hook_connect_cb (void *data, int status,
static XS (XS_weechat_api_hook_connect)
{
- char *address, *local_hostname, *result;
+ char *proxy, *address, *local_hostname, *result;
dXSARGS;
/* make C compiler happy */
@@ -2311,25 +2311,27 @@ static XS (XS_weechat_api_hook_connect)
PERL_RETURN_EMPTY;
}
- if (items < 6)
+ if (items < 7)
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
PERL_RETURN_EMPTY;
}
- address = SvPV (ST (0), PL_na);
- local_hostname = SvPV (ST (4), PL_na);
+ proxy = SvPV (ST (0), PL_na);
+ address = SvPV (ST (1), PL_na);
+ local_hostname = SvPV (ST (5), PL_na);
result = script_ptr2str (script_api_hook_connect (weechat_perl_plugin,
perl_current_script,
+ proxy,
address,
- SvIV (ST (1)), /* port */
- SvIV (ST (2)), /* sock */
- SvIV (ST (3)), /* ipv6 */
+ SvIV (ST (2)), /* port */
+ SvIV (ST (3)), /* sock */
+ SvIV (ST (4)), /* ipv6 */
NULL, /* gnutls session */
local_hostname,
&weechat_perl_api_hook_connect_cb,
- SvPV (ST (5), PL_na))); /* perl function */
+ SvPV (ST (6), PL_na))); /* perl function */
PERL_RETURN_STRING_FREE(result);
}
diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c
index 872c3cbbd..ab629def6 100644
--- a/src/plugins/scripts/python/weechat-python-api.c
+++ b/src/plugins/scripts/python/weechat-python-api.c
@@ -2453,7 +2453,7 @@ weechat_python_api_hook_connect_cb (void *data, int status,
static PyObject *
weechat_python_api_hook_connect (PyObject *self, PyObject *args)
{
- char *address, *local_hostname, *function, *result;
+ char *proxy, *address, *local_hostname, *function, *result;
int port, sock, ipv6;
PyObject *object;
@@ -2465,7 +2465,8 @@ weechat_python_api_hook_connect (PyObject *self, PyObject *args)
WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_connect");
PYTHON_RETURN_EMPTY;
}
-
+
+ proxy = NULL;
address = NULL;
port = 0;
sock = 0;
@@ -2473,8 +2474,8 @@ weechat_python_api_hook_connect (PyObject *self, PyObject *args)
local_hostname = NULL;
function = NULL;
- if (!PyArg_ParseTuple (args, "siiiss", &address, &port, &sock, &ipv6,
- &local_hostname, &function))
+ if (!PyArg_ParseTuple (args, "ssiiiss", &proxy, &address, &port, &sock,
+ &ipv6, &local_hostname, &function))
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
PYTHON_RETURN_EMPTY;
@@ -2482,6 +2483,7 @@ weechat_python_api_hook_connect (PyObject *self, PyObject *args)
result = script_ptr2str (script_api_hook_connect (weechat_python_plugin,
python_current_script,
+ proxy,
address,
port,
sock,
diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c
index f2433becb..2e1209e71 100644
--- a/src/plugins/scripts/ruby/weechat-ruby-api.c
+++ b/src/plugins/scripts/ruby/weechat-ruby-api.c
@@ -2816,11 +2816,11 @@ weechat_ruby_api_hook_connect_cb (void *data, int status,
*/
static VALUE
-weechat_ruby_api_hook_connect (VALUE class, VALUE address, VALUE port,
- VALUE sock, VALUE ipv6, VALUE local_hostname,
- VALUE function)
+weechat_ruby_api_hook_connect (VALUE class, VALUE proxy, VALUE address,
+ VALUE port, VALUE sock, VALUE ipv6,
+ VALUE local_hostname, VALUE function)
{
- char *c_address, *c_local_hostname, *c_function, *result;
+ char *c_proxy, *c_address, *c_local_hostname, *c_function, *result;
int c_port, c_sock, c_ipv6;
VALUE return_value;
@@ -2832,7 +2832,8 @@ weechat_ruby_api_hook_connect (VALUE class, VALUE address, VALUE port,
WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_connect");
RUBY_RETURN_EMPTY;
}
-
+
+ c_proxy = NULL;
c_address = NULL;
c_port = 0;
c_sock = 0;
@@ -2840,20 +2841,22 @@ weechat_ruby_api_hook_connect (VALUE class, VALUE address, VALUE port,
c_local_hostname = NULL;
c_function = NULL;
- if (NIL_P (address) || NIL_P (port) || NIL_P (sock) || NIL_P (ipv6)
- || NIL_P (local_hostname) || NIL_P (function))
+ if (NIL_P (proxy) || NIL_P (address) || NIL_P (port) || NIL_P (sock)
+ || NIL_P (ipv6) || NIL_P (local_hostname) || NIL_P (function))
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
RUBY_RETURN_EMPTY;
}
-
+
+ Check_Type (proxy, T_STRING);
Check_Type (address, T_STRING);
Check_Type (port, T_FIXNUM);
Check_Type (sock, T_FIXNUM);
Check_Type (ipv6, T_FIXNUM);
Check_Type (local_hostname, T_STRING);
Check_Type (function, T_STRING);
-
+
+ c_proxy = STR2CSTR (proxy);
c_address = STR2CSTR (address);
c_port = FIX2INT (port);
c_sock = FIX2INT (sock);
@@ -2863,6 +2866,7 @@ weechat_ruby_api_hook_connect (VALUE class, VALUE address, VALUE port,
result = script_ptr2str (script_api_hook_connect (weechat_ruby_plugin,
ruby_current_script,
+ c_proxy,
c_address,
c_port,
c_sock,
@@ -5633,7 +5637,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat)
rb_define_module_function (ruby_mWeechat, "hook_command", &weechat_ruby_api_hook_command, 6);
rb_define_module_function (ruby_mWeechat, "hook_timer", &weechat_ruby_api_hook_timer, 4);
rb_define_module_function (ruby_mWeechat, "hook_fd", &weechat_ruby_api_hook_fd, 5);
- rb_define_module_function (ruby_mWeechat, "hook_connect", &weechat_ruby_api_hook_connect, 6);
+ rb_define_module_function (ruby_mWeechat, "hook_connect", &weechat_ruby_api_hook_connect, 7);
rb_define_module_function (ruby_mWeechat, "hook_print", &weechat_ruby_api_hook_print, 5);
rb_define_module_function (ruby_mWeechat, "hook_signal", &weechat_ruby_api_hook_signal, 2);
rb_define_module_function (ruby_mWeechat, "hook_signal_send", &weechat_ruby_api_hook_signal_send, 3);
diff --git a/src/plugins/scripts/script-api.c b/src/plugins/scripts/script-api.c
index c1b17bb60..40434ed62 100644
--- a/src/plugins/scripts/script-api.c
+++ b/src/plugins/scripts/script-api.c
@@ -744,8 +744,9 @@ script_api_hook_fd (struct t_weechat_plugin *weechat_plugin,
struct t_hook *
script_api_hook_connect (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
- const char *address, int port, int sock, int ipv6,
- void *gnutls_sess, const char *local_hostname,
+ const char *proxy, const char *address, int port,
+ int sock, int ipv6, void *gnutls_sess,
+ const char *local_hostname,
int (*callback)(void *data, int status, const char *ip_address),
const char *function)
{
@@ -756,8 +757,8 @@ script_api_hook_connect (struct t_weechat_plugin *weechat_plugin,
if (!new_script_callback)
return NULL;
- new_hook = weechat_hook_connect (address, port, sock, ipv6, gnutls_sess,
- local_hostname, callback,
+ new_hook = weechat_hook_connect (proxy, address, port, sock, ipv6,
+ gnutls_sess, local_hostname, callback,
new_script_callback);
if (!new_hook)
{
diff --git a/src/plugins/scripts/script-api.h b/src/plugins/scripts/script-api.h
index 2b7da7c2a..a3dafe8af 100644
--- a/src/plugins/scripts/script-api.h
+++ b/src/plugins/scripts/script-api.h
@@ -121,6 +121,7 @@ extern struct t_hook *script_api_hook_fd (struct t_weechat_plugin *weechat_plugi
const char *function);
extern struct t_hook *script_api_hook_connect (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
+ const char *proxy,
const char *address,
int port,
int sock,
diff --git a/src/plugins/scripts/tcl/weechat-tcl-api.c b/src/plugins/scripts/tcl/weechat-tcl-api.c
index 5d5818b02..382d0b5f5 100644
--- a/src/plugins/scripts/tcl/weechat-tcl-api.c
+++ b/src/plugins/scripts/tcl/weechat-tcl-api.c
@@ -2663,7 +2663,7 @@ weechat_tcl_api_hook_connect (ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[])
{
Tcl_Obj *objp;
- char *address, *local_hostname, *result;
+ char *proxy, *address, *local_hostname, *result;
int i, port, sock, ipv6;
/* make C compiler happy */
@@ -2675,25 +2675,27 @@ weechat_tcl_api_hook_connect (ClientData clientData, Tcl_Interp *interp,
TCL_RETURN_EMPTY;
}
- if (objc < 6)
+ if (objc < 7)
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
TCL_RETURN_EMPTY;
}
- if ((Tcl_GetIntFromObj (interp, objv[2], &port) != TCL_OK)
- || (Tcl_GetIntFromObj (interp, objv[3], &sock) != TCL_OK)
- || (Tcl_GetIntFromObj (interp, objv[4], &ipv6) != TCL_OK))
+ if ((Tcl_GetIntFromObj (interp, objv[3], &port) != TCL_OK)
+ || (Tcl_GetIntFromObj (interp, objv[4], &sock) != TCL_OK)
+ || (Tcl_GetIntFromObj (interp, objv[5], &ipv6) != TCL_OK))
{
WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_connect");
TCL_RETURN_EMPTY;
}
- address = Tcl_GetStringFromObj (objv[1], &i);
- local_hostname = Tcl_GetStringFromObj (objv[5], &i);
+ proxy = Tcl_GetStringFromObj (objv[1], &i);
+ address = Tcl_GetStringFromObj (objv[2], &i);
+ local_hostname = Tcl_GetStringFromObj (objv[6], &i);
result = script_ptr2str (script_api_hook_connect (weechat_tcl_plugin,
tcl_current_script,
+ proxy,
address,
port,
sock,
@@ -2701,7 +2703,7 @@ weechat_tcl_api_hook_connect (ClientData clientData, Tcl_Interp *interp,
NULL, /* gnutls session */
local_hostname,
&weechat_tcl_api_hook_connect_cb,
- Tcl_GetStringFromObj (objv[6], &i))); /* tcl function */
+ Tcl_GetStringFromObj (objv[7], &i))); /* tcl function */
TCL_RETURN_STRING_FREE(result);
}
diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h
index 657bd6c7d..641310916 100644
--- a/src/plugins/weechat-plugin.h
+++ b/src/plugins/weechat-plugin.h
@@ -342,6 +342,7 @@ struct t_weechat_plugin
int (*callback)(void *data),
void *callback_data);
struct t_hook *(*hook_connect) (struct t_weechat_plugin *plugin,
+ const char *proxy,
const char *address,
int port,
int sock,
@@ -518,8 +519,10 @@ struct t_weechat_plugin
struct t_gui_buffer *buffer, const char *command);
/* network */
- int (*network_pass_proxy) (int sock, const char *address, int port);
- int (*network_connect_to) (int sock, unsigned long address, int port);
+ int (*network_pass_proxy) (const char *proxy, int sock,
+ const char *address, int port);
+ int (*network_connect_to) (const char *proxy, int sock,
+ unsigned long address, int port);
/* infos */
const char *(*info_get) (struct t_weechat_plugin *plugin,
@@ -870,11 +873,11 @@ 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, \
+#define weechat_hook_connect(__proxy, __address, __port, __sock, \
+ __ipv6, __gnutls_sess, __local_hostname, \
__callback, __data) \
- weechat_plugin->hook_connect(weechat_plugin, __address, __port, \
- __sock, __ipv6, __gnutls_sess, \
+ weechat_plugin->hook_connect(weechat_plugin, __proxy, __address, \
+ __port, __sock, __ipv6, __gnutls_sess, \
__local_hostname, __callback, __data)
#define weechat_hook_print(__buffer, __tags, __msg, __strip__colors, \
__callback, __data) \
@@ -1014,10 +1017,12 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
weechat_plugin->command(weechat_plugin, __buffer, __command)
/* network */
-#define weechat_network_pass_proxy(__sock, __address, __port) \
- weechat_plugin->network_pass_proxy(__sock, __address, __port)
-#define weechat_network_connect_to(__sock, __address, __port) \
- weechat_plugin->network_connect_to(__sock, __address, __port)
+#define weechat_network_pass_proxy(__proxy, __sock, __address, __port) \
+ weechat_plugin->network_pass_proxy(__proxy, __sock, __address, \
+ __port)
+#define weechat_network_connect_to(__proxy, __sock, __address, __port) \
+ weechat_plugin->network_connect_to(__proxy, __sock, __address, \
+ __port)
/* infos */
#define weechat_info_get(__info_name, __arguments) \
diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c
index c44868f3a..f76d91484 100644
--- a/src/plugins/xfer/xfer-dcc.c
+++ b/src/plugins/xfer/xfer-dcc.c
@@ -167,7 +167,8 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
time_t last_sent, new_time;
/* first connect to sender (blocking) */
- if (!weechat_network_connect_to (xfer->sock, xfer->address, xfer->port))
+ if (!weechat_network_connect_to (xfer->proxy, xfer->sock,
+ xfer->address, xfer->port))
{
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
XFER_ERROR_CONNECT_SENDER);
diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c
index 229c962ce..f6848e61a 100644
--- a/src/plugins/xfer/xfer-network.c
+++ b/src/plugins/xfer/xfer-network.c
@@ -492,7 +492,8 @@ xfer_network_connect (struct t_xfer *xfer)
{
if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
return 0;
- weechat_network_connect_to (xfer->sock, xfer->address, xfer->port);
+ weechat_network_connect_to (xfer->proxy, xfer->sock, xfer->address,
+ xfer->port);
xfer->hook_fd = weechat_hook_fd (xfer->sock,
1, 0, 0,
diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c
index 7fe2ad521..14856c3d4 100644
--- a/src/plugins/xfer/xfer.c
+++ b/src/plugins/xfer/xfer.c
@@ -457,10 +457,10 @@ xfer_alloc ()
struct t_xfer *
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 *filename,
- unsigned long size, unsigned long address, int port, int sock,
- const char *local_filename)
+ enum t_xfer_protocol protocol, const char *remote_nick,
+ const char *local_nick, const char *filename,
+ unsigned long size, const char *proxy, unsigned long address,
+ int port, int sock, const char *local_filename)
{
struct t_xfer *new_xfer;
@@ -491,6 +491,7 @@ xfer_new (const char *plugin_name, const char *plugin_id, enum t_xfer_type type,
else
new_xfer->filename = strdup (_("xfer chat"));
new_xfer->size = size;
+ new_xfer->proxy = (proxy) ? strdup (proxy) : NULL;
new_xfer->address = address;
new_xfer->port = port;
@@ -657,7 +658,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, void *signal
{
struct t_infolist *infolist;
const char *plugin_name, *plugin_id, *str_type, *str_protocol;
- const char *remote_nick, *local_nick, *filename;
+ const char *remote_nick, *local_nick, *filename, *proxy;
int type, protocol;
const char *weechat_dir;
char *dir1, *dir2, *filename2, *short_filename, *pos;
@@ -708,6 +709,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, void *signal
remote_nick = weechat_infolist_string (infolist, "remote_nick");
local_nick = weechat_infolist_string (infolist, "local_nick");
filename = weechat_infolist_string (infolist, "filename");
+ proxy = weechat_infolist_string (infolist, "proxy");
protocol = XFER_NO_PROTOCOL;
if (!plugin_name || !plugin_id || !str_type || !remote_nick || !local_nick)
@@ -835,7 +837,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, void *signal
/* get local IP address */
sscanf (weechat_infolist_string (infolist, "address"), "%lu", &local_addr);
- /* look up the IP address from dcc_own_ip, if set */
+ /* look up the IP address from network_own_ip, if set */
if (weechat_config_string(xfer_config_network_own_ip)
&& weechat_config_string(xfer_config_network_own_ip)[0])
{
@@ -970,11 +972,12 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, void *signal
if (XFER_IS_FILE(type))
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
remote_nick, local_nick, short_filename,
- file_size, local_addr, port, sock, filename2);
+ file_size, proxy, local_addr, port, sock,
+ filename2);
else
ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
- remote_nick, local_nick, NULL, 0, local_addr,
- port, sock, NULL);
+ remote_nick, local_nick, NULL, 0, proxy,
+ local_addr, port, sock, NULL);
if (!ptr_xfer)
{
@@ -1207,6 +1210,8 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
snprintf (value, sizeof (value), "%lu", xfer->size);
if (!weechat_infolist_new_var_string (ptr_item, "size", value))
return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "proxy", xfer->proxy))
+ return 0;
snprintf (value, sizeof (value), "%lu", xfer->address);
if (!weechat_infolist_new_var_string (ptr_item, "address", value))
return 0;
@@ -1295,6 +1300,7 @@ xfer_print_log ()
weechat_log_printf (" local_nick. . . . . : '%s'", ptr_xfer->local_nick);
weechat_log_printf (" filename. . . . . . : '%s'", ptr_xfer->filename);
weechat_log_printf (" size. . . . . . . . : %lu", ptr_xfer->size);
+ weechat_log_printf (" proxy . . . . . . . : '%s'", ptr_xfer->proxy);
weechat_log_printf (" address . . . . . . : %lu", ptr_xfer->address);
weechat_log_printf (" port. . . . . . . . : %d", ptr_xfer->port);
diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h
index b4ebee9cf..2c5ad76b8 100644
--- a/src/plugins/xfer/xfer.h
+++ b/src/plugins/xfer/xfer.h
@@ -115,6 +115,7 @@ struct t_xfer
char *local_nick; /* local nick */
char *filename; /* filename */
unsigned long size; /* file size */
+ char *proxy; /* proxy to use (optional) */
unsigned long address; /* local or remote IP address */
int port; /* remote port */