1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-30 14:56:39 +02:00

- added dcc_own_ip and dcc_port_range settings, patch by Jim Ramsay

- fixed bug when exiting DCC buffer (wrong input buffer)
This commit is contained in:
Sebastien Helleu
2005-10-22 14:04:26 +00:00
parent 1a140ab8b5
commit 6beb8b6465
24 changed files with 2836 additions and 2166 deletions
+2 -1
View File
@@ -1,10 +1,11 @@
WeeChat - Wee Enhanced Environment for Chat
===========================================
ChangeLog - 2005-10-21
ChangeLog - 2005-10-22
Version 0.1.6 (under dev!):
* added dcc_own_ip and dcc_port_range settings
* full UTF-8 support, auto-detection of UTF-8 usage (locale)
* added "Day changed to [date]" message when day changes
* new plugin interface, rewritten from scratch: now loads dynamic C
+361 -279
View File
File diff suppressed because it is too large Load Diff
+275 -241
View File
File diff suppressed because it is too large Load Diff
+279 -239
View File
File diff suppressed because it is too large Load Diff
+267 -236
View File
File diff suppressed because it is too large Load Diff
+14 -1
View File
@@ -136,8 +136,11 @@ t_weechat_command weechat_commands[] =
"Without argument, /unignore command lists all defined ignore."),
0, 4, weechat_cmd_unignore, NULL },
{ "window", N_("manage windows"),
N_("[list | splith | splitv | [merge [down | up | left | right | all]]]"),
N_("[list | -1 | +1 | b# | splith | splitv | [merge [down | up | left | right | all]]]"),
N_("list: list opened windows (no parameter implies this list)\n"
"-1: jump to previous window\n"
"+1: jump to next window\n"
"b#: jump to next window displaying buffer number #\n"
"splith: split current window horizontally\n"
"splitv: split current window vertically\n"
"merge: merge window with another"),
@@ -2511,6 +2514,8 @@ weechat_cmd_window (int argc, char **argv)
{
t_gui_window *ptr_win;
int i;
char *error;
long number;
if ((argc == 0) || ((argc == 1) && (ascii_strcasecmp (argv[0], "list") == 0)))
{
@@ -2577,6 +2582,14 @@ weechat_cmd_window (int argc, char **argv)
else
gui_window_merge_auto (gui_current_window);
}
else if (ascii_strncasecmp (argv[0], "b", 1) == 0)
{
/* jump to window by buffer number */
error = NULL;
number = strtol (argv[0] + 1, &error, 10);
if ((error) && (error[0] == '\0'))
gui_switch_to_window_by_buffer (gui_current_window, number);
}
else if (ascii_strcasecmp (argv[0], "-1") == 0)
gui_switch_to_previous_window (gui_current_window);
else if (ascii_strcasecmp (argv[0], "+1") == 0)
+14 -1
View File
@@ -420,7 +420,7 @@ t_config_option weechat_options_colors[] =
{ "col_input_delimiters", N_("color for input text (delimiters)"),
N_("color for input text (delimiters)"),
OPTION_TYPE_COLOR, 0, 0, 0,
"lightgreen", NULL, &cfg_col_input_delimiters, NULL, &config_change_color },
"white", NULL, &cfg_col_input_delimiters, NULL, &config_change_color },
{ "col_input_bg", N_("background for input window"),
N_("background for input window"),
OPTION_TYPE_COLOR, 0, 0, 0,
@@ -677,6 +677,8 @@ int cfg_dcc_auto_accept_files;
int cfg_dcc_auto_accept_chats;
int cfg_dcc_timeout;
int cfg_dcc_blocksize;
char *cfg_dcc_port_range;
char *cfg_dcc_own_ip;
char *cfg_dcc_download_path;
char *cfg_dcc_upload_path;
int cfg_dcc_convert_spaces;
@@ -700,6 +702,17 @@ t_config_option weechat_options_dcc[] =
N_("block size for dcc packets in bytes (default: 65536)"),
OPTION_TYPE_INT, 1024, 102400, 65536,
NULL, NULL, &cfg_dcc_blocksize, NULL, &config_change_noop },
{ "dcc_port_range", N_("allowed ports for outgoing dcc"),
N_("restricts outgoing dcc to use only ports in the given range "
"(useful for NAT) (syntax: a single port, ie. 5000 or a port "
"range, ie. 5000-5015, empty value means any port)"),
OPTION_TYPE_STRING, 0, 0, 0, "",
NULL, NULL, &cfg_dcc_port_range, &config_change_noop },
{ "dcc_own_ip", N_("IP address for outgoing dcc"),
N_("IP or DNS address used for outgoing dcc "
"(if empty, local interface IP is used)"),
OPTION_TYPE_STRING, 0, 0, 0, "",
NULL, NULL, &cfg_dcc_own_ip, &config_change_noop },
{ "dcc_download_path", N_("path for incoming files with dcc"),
N_("path for writing incoming files with dcc (default: user home)"),
OPTION_TYPE_STRING, 0, 0, 0,
+2
View File
@@ -191,6 +191,8 @@ extern int cfg_dcc_auto_accept_files;
extern int cfg_dcc_auto_accept_chats;
extern int cfg_dcc_timeout;
extern int cfg_dcc_blocksize;
extern char *cfg_dcc_port_range;
extern char *cfg_dcc_own_ip;
extern char *cfg_dcc_download_path;
extern char *cfg_dcc_upload_path;
extern int cfg_dcc_convert_spaces;
+9 -4
View File
@@ -256,10 +256,15 @@ gui_input_read ()
if ((gui_key_pressed (key_str) != 0) && (insert_ok))
{
gui_input_insert_string (gui_current_window, key_str, -1);
gui_current_window->buffer->input_buffer_pos += utf8_strlen (key_str);
gui_draw_buffer_input (gui_current_window->buffer, 0);
gui_current_window->buffer->completion.position = -1;
if (gui_current_window->buffer->dcc)
gui_input_action_dcc (gui_current_window, key_str);
else
{
gui_input_insert_string (gui_current_window, key_str, -1);
gui_current_window->buffer->input_buffer_pos += utf8_strlen (key_str);
gui_draw_buffer_input (gui_current_window->buffer, 0);
gui_current_window->buffer->completion.position = -1;
}
}
i++;
+100 -72
View File
@@ -609,78 +609,89 @@ gui_input_optimize_buffer_size (t_gui_buffer *buffer)
/*
* gui_input_action_dcc: execute an action on a DCC after a user input
* return -1 if DCC buffer was closed due to action, 0 otherwise
*/
void
gui_input_action_dcc (t_gui_window *window, char action)
gui_input_action_dcc (t_gui_window *window, char *actions)
{
t_irc_dcc *dcc_selected, *ptr_dcc, *ptr_dcc_next;
t_gui_buffer *ptr_buffer;
dcc_selected = (window->dcc_selected) ?
(t_irc_dcc *) window->dcc_selected : dcc_list;
switch (action)
while (actions[0])
{
/* accept DCC */
case 'a':
case 'A':
if (dcc_selected
&& (DCC_IS_RECV(dcc_selected->status))
&& (dcc_selected->status == DCC_WAITING))
if (actions[0] >= 32)
{
dcc_selected = (window->dcc_selected) ?
(t_irc_dcc *) window->dcc_selected : dcc_list;
switch (actions[0])
{
dcc_accept (dcc_selected);
}
break;
/* cancel DCC */
case 'c':
case 'C':
if (dcc_selected
&& (!DCC_ENDED(dcc_selected->status)))
{
dcc_close (dcc_selected, DCC_ABORTED);
gui_redraw_buffer (window->buffer);
}
break;
/* purge old DCC */
case 'p':
case 'P':
window->dcc_selected = NULL;
ptr_dcc = dcc_list;
while (ptr_dcc)
{
ptr_dcc_next = ptr_dcc->next_dcc;
if (DCC_ENDED(ptr_dcc->status))
dcc_free (ptr_dcc);
ptr_dcc = ptr_dcc_next;
}
gui_redraw_buffer (window->buffer);
break;
/* close DCC window */
case 'q':
case 'Q':
if (buffer_before_dcc)
{
gui_buffer_free (window->buffer, 1);
gui_switch_to_buffer (window, buffer_before_dcc);
}
else
gui_buffer_free (window->buffer, 1);
gui_redraw_buffer (window->buffer);
break;
/* remove from DCC list */
case 'r':
case 'R':
if (dcc_selected
&& (DCC_ENDED(dcc_selected->status)))
{
if (dcc_selected->next_dcc)
window->dcc_selected = dcc_selected->next_dcc;
else
/* accept DCC */
case 'a':
case 'A':
if (dcc_selected
&& (DCC_IS_RECV(dcc_selected->status))
&& (dcc_selected->status == DCC_WAITING))
{
dcc_accept (dcc_selected);
}
break;
/* cancel DCC */
case 'c':
case 'C':
if (dcc_selected
&& (!DCC_ENDED(dcc_selected->status)))
{
dcc_close (dcc_selected, DCC_ABORTED);
gui_redraw_buffer (window->buffer);
}
break;
/* purge old DCC */
case 'p':
case 'P':
window->dcc_selected = NULL;
dcc_free (dcc_selected);
gui_redraw_buffer (window->buffer);
ptr_dcc = dcc_list;
while (ptr_dcc)
{
ptr_dcc_next = ptr_dcc->next_dcc;
if (DCC_ENDED(ptr_dcc->status))
dcc_free (ptr_dcc);
ptr_dcc = ptr_dcc_next;
}
gui_redraw_buffer (window->buffer);
break;
/* close DCC window */
case 'q':
case 'Q':
if (buffer_before_dcc)
{
ptr_buffer = window->buffer;
gui_switch_to_buffer (window, buffer_before_dcc);
gui_buffer_free (ptr_buffer, 0);
}
else
gui_buffer_free (window->buffer, 1);
gui_redraw_buffer (window->buffer);
return;
break;
/* remove from DCC list */
case 'r':
case 'R':
if (dcc_selected
&& (DCC_ENDED(dcc_selected->status)))
{
if (dcc_selected->next_dcc)
window->dcc_selected = dcc_selected->next_dcc;
else
window->dcc_selected = NULL;
dcc_free (dcc_selected);
gui_redraw_buffer (window->buffer);
}
break;
}
break;
}
actions = utf8_next_char (actions);
}
}
@@ -697,16 +708,7 @@ gui_input_insert_string (t_gui_window *window, char *string, int pos)
int size, length;
char *ptr_start;
if (window->buffer->dcc)
{
while (string[0])
{
if (string[0] >= 32)
gui_input_action_dcc (window, string[0]);
string = utf8_next_char (string);
}
}
else if (window->buffer->has_input)
if (window->buffer->has_input)
{
if (pos == -1)
pos = window->buffer->input_buffer_pos;
@@ -1760,6 +1762,32 @@ gui_switch_to_next_window (t_gui_window *window)
gui_redraw_buffer (gui_current_window->buffer);
}
/*
* gui_switch_to_window_by_buffer: switch to next window displaying a buffer
*/
void
gui_switch_to_window_by_buffer (t_gui_window *window, int buffer_number)
{
t_gui_window *ptr_win;
if (!gui_ok)
return;
ptr_win = (window->next_window) ? window->next_window : gui_windows;
while (ptr_win != window)
{
if (ptr_win->buffer->number == buffer_number)
{
gui_current_window = ptr_win;
gui_switch_to_buffer (gui_current_window, gui_current_window->buffer);
gui_redraw_buffer (gui_current_window->buffer);
return;
}
ptr_win = (ptr_win->next_window) ? ptr_win->next_window : gui_windows;
}
}
/*
* gui_switch_to_dcc_buffer: switch to dcc buffer (create it if it does not exist)
*/
+2
View File
@@ -331,6 +331,7 @@ extern t_gui_line *gui_new_line (t_gui_buffer *);
extern t_gui_message *gui_new_message (t_gui_buffer *);
extern void gui_input_clipboard_copy (char *, int);
extern void gui_input_clipboard_paste (t_gui_window *);
extern void gui_input_action_dcc (t_gui_window *, char *);
extern int gui_input_insert_string (t_gui_window *, char *, int);
extern void gui_input_return (t_gui_window *);
extern void gui_input_tab (t_gui_window *);
@@ -364,6 +365,7 @@ extern void gui_switch_to_previous_buffer (t_gui_window *);
extern void gui_switch_to_next_buffer (t_gui_window *);
extern void gui_switch_to_previous_window (t_gui_window *);
extern void gui_switch_to_next_window (t_gui_window *);
extern void gui_switch_to_window_by_buffer (t_gui_window *, int);
extern void gui_switch_to_dcc_buffer (t_gui_window *);
extern t_gui_buffer *gui_switch_to_buffer_by_number (t_gui_window *, int);
extern void gui_move_buffer_to_number (t_gui_window *, int);
+93 -9
View File
@@ -87,6 +87,26 @@ dcc_search (t_irc_server *server, int type, int status, int port)
return NULL;
}
/*
* dcc_port_in_use: return 1 if a port is in used (by an active or connecting DCC)
*/
int
dcc_port_in_use (int port)
{
t_irc_dcc *ptr_dcc;
/* skip any currently used ports */
for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
{
if ((ptr_dcc->port == port) && (!DCC_ENDED(ptr_dcc->status)))
return 1;
}
/* port not in use */
return 0;
}
/*
* dcc_file_is_resumable: check if a file can be used for resuming a download
*/
@@ -748,9 +768,11 @@ void
dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
{
char *ptr_home, *filename2, *short_filename, *pos;
int spaces;
int spaces, args, port_start, port_end;
struct stat st;
int sock, port;
struct hostent *host;
struct in_addr tmpaddr;
struct sockaddr_in addr;
socklen_t length;
unsigned long local_addr;
@@ -811,11 +833,32 @@ dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
}
/* get local IP address */
/* look up the IP address from dcc_own_ip, if set */
local_addr = 0;
if (cfg_dcc_own_ip && cfg_dcc_own_ip[0])
{
host = gethostbyname (cfg_dcc_own_ip);
if (host)
{
memcpy (&tmpaddr, host->h_addr_list[0], sizeof(struct in_addr));
local_addr = ntohl (tmpaddr.s_addr);
}
else
gui_printf (server->buffer,
_("%s could not find address for '%s'. Falling back to local IP.\n"),
WEECHAT_WARNING, cfg_dcc_own_ip);
}
/* use the local interface, from the server socket */
memset (&addr, 0, sizeof (struct sockaddr_in));
length = sizeof (addr);
getsockname (server->sock, (struct sockaddr *) &addr, &length);
addr.sin_family = AF_INET;
local_addr = ntohl (addr.sin_addr.s_addr);
/* fallback to the local IP address on the interface, if required */
if (local_addr == 0)
local_addr = ntohl (addr.sin_addr.s_addr);
/* open socket for DCC */
sock = socket (AF_INET, SOCK_STREAM, 0);
@@ -830,22 +873,63 @@ dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
return;
}
/* find port automatically */
addr.sin_port = 0;
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1)
/* look for port */
port = 0;
if (cfg_dcc_port_range && cfg_dcc_port_range[0])
{
/* find a free port in the specified range */
args = sscanf (cfg_dcc_port_range, "%d-%d", &port_start, &port_end);
if (args > 0)
{
port = port_start;
if (args == 1)
port_end = port_start;
/* loop through the entire allowed port range */
while (port <= port_end)
{
if (!dcc_port_in_use (port))
{
/* attempt to bind to the free port */
addr.sin_port = htons (port);
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
break;
}
}
if (port > port_end)
port = -1;
}
}
if (port == 0)
{
/* find port automatically */
addr.sin_port = 0;
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
{
length = sizeof (addr);
getsockname (sock, (struct sockaddr *) &addr, &length);
port = ntohs (addr.sin_port);
}
else
port = -1;
}
if (port == -1)
{
/* Could not find any port to bind */
irc_display_prefix (server->buffer, PREFIX_ERROR);
gui_printf (server->buffer,
_("%s cannot find port for DCC\n"),
_("%s cannot find available port for DCC\n"),
WEECHAT_ERROR);
close (sock);
if (filename2)
free (filename2);
return;
}
length = sizeof (addr);
getsockname (sock, (struct sockaddr *) &addr, &length);
port = ntohs (addr.sin_port);
if (type == DCC_FILE_SEND)
{
+2 -1
View File
@@ -1,10 +1,11 @@
WeeChat - Wee Enhanced Environment for Chat
===========================================
ChangeLog - 2005-10-21
ChangeLog - 2005-10-22
Version 0.1.6 (under dev!):
* added dcc_own_ip and dcc_port_range settings
* full UTF-8 support, auto-detection of UTF-8 usage (locale)
* added "Day changed to [date]" message when day changes
* new plugin interface, rewritten from scratch: now loads dynamic C
+361 -279
View File
File diff suppressed because it is too large Load Diff
+275 -241
View File
File diff suppressed because it is too large Load Diff
+279 -239
View File
File diff suppressed because it is too large Load Diff
+267 -236
View File
File diff suppressed because it is too large Load Diff
+14 -1
View File
@@ -136,8 +136,11 @@ t_weechat_command weechat_commands[] =
"Without argument, /unignore command lists all defined ignore."),
0, 4, weechat_cmd_unignore, NULL },
{ "window", N_("manage windows"),
N_("[list | splith | splitv | [merge [down | up | left | right | all]]]"),
N_("[list | -1 | +1 | b# | splith | splitv | [merge [down | up | left | right | all]]]"),
N_("list: list opened windows (no parameter implies this list)\n"
"-1: jump to previous window\n"
"+1: jump to next window\n"
"b#: jump to next window displaying buffer number #\n"
"splith: split current window horizontally\n"
"splitv: split current window vertically\n"
"merge: merge window with another"),
@@ -2511,6 +2514,8 @@ weechat_cmd_window (int argc, char **argv)
{
t_gui_window *ptr_win;
int i;
char *error;
long number;
if ((argc == 0) || ((argc == 1) && (ascii_strcasecmp (argv[0], "list") == 0)))
{
@@ -2577,6 +2582,14 @@ weechat_cmd_window (int argc, char **argv)
else
gui_window_merge_auto (gui_current_window);
}
else if (ascii_strncasecmp (argv[0], "b", 1) == 0)
{
/* jump to window by buffer number */
error = NULL;
number = strtol (argv[0] + 1, &error, 10);
if ((error) && (error[0] == '\0'))
gui_switch_to_window_by_buffer (gui_current_window, number);
}
else if (ascii_strcasecmp (argv[0], "-1") == 0)
gui_switch_to_previous_window (gui_current_window);
else if (ascii_strcasecmp (argv[0], "+1") == 0)
+14 -1
View File
@@ -420,7 +420,7 @@ t_config_option weechat_options_colors[] =
{ "col_input_delimiters", N_("color for input text (delimiters)"),
N_("color for input text (delimiters)"),
OPTION_TYPE_COLOR, 0, 0, 0,
"lightgreen", NULL, &cfg_col_input_delimiters, NULL, &config_change_color },
"white", NULL, &cfg_col_input_delimiters, NULL, &config_change_color },
{ "col_input_bg", N_("background for input window"),
N_("background for input window"),
OPTION_TYPE_COLOR, 0, 0, 0,
@@ -677,6 +677,8 @@ int cfg_dcc_auto_accept_files;
int cfg_dcc_auto_accept_chats;
int cfg_dcc_timeout;
int cfg_dcc_blocksize;
char *cfg_dcc_port_range;
char *cfg_dcc_own_ip;
char *cfg_dcc_download_path;
char *cfg_dcc_upload_path;
int cfg_dcc_convert_spaces;
@@ -700,6 +702,17 @@ t_config_option weechat_options_dcc[] =
N_("block size for dcc packets in bytes (default: 65536)"),
OPTION_TYPE_INT, 1024, 102400, 65536,
NULL, NULL, &cfg_dcc_blocksize, NULL, &config_change_noop },
{ "dcc_port_range", N_("allowed ports for outgoing dcc"),
N_("restricts outgoing dcc to use only ports in the given range "
"(useful for NAT) (syntax: a single port, ie. 5000 or a port "
"range, ie. 5000-5015, empty value means any port)"),
OPTION_TYPE_STRING, 0, 0, 0, "",
NULL, NULL, &cfg_dcc_port_range, &config_change_noop },
{ "dcc_own_ip", N_("IP address for outgoing dcc"),
N_("IP or DNS address used for outgoing dcc "
"(if empty, local interface IP is used)"),
OPTION_TYPE_STRING, 0, 0, 0, "",
NULL, NULL, &cfg_dcc_own_ip, &config_change_noop },
{ "dcc_download_path", N_("path for incoming files with dcc"),
N_("path for writing incoming files with dcc (default: user home)"),
OPTION_TYPE_STRING, 0, 0, 0,
+2
View File
@@ -191,6 +191,8 @@ extern int cfg_dcc_auto_accept_files;
extern int cfg_dcc_auto_accept_chats;
extern int cfg_dcc_timeout;
extern int cfg_dcc_blocksize;
extern char *cfg_dcc_port_range;
extern char *cfg_dcc_own_ip;
extern char *cfg_dcc_download_path;
extern char *cfg_dcc_upload_path;
extern int cfg_dcc_convert_spaces;
+9 -4
View File
@@ -256,10 +256,15 @@ gui_input_read ()
if ((gui_key_pressed (key_str) != 0) && (insert_ok))
{
gui_input_insert_string (gui_current_window, key_str, -1);
gui_current_window->buffer->input_buffer_pos += utf8_strlen (key_str);
gui_draw_buffer_input (gui_current_window->buffer, 0);
gui_current_window->buffer->completion.position = -1;
if (gui_current_window->buffer->dcc)
gui_input_action_dcc (gui_current_window, key_str);
else
{
gui_input_insert_string (gui_current_window, key_str, -1);
gui_current_window->buffer->input_buffer_pos += utf8_strlen (key_str);
gui_draw_buffer_input (gui_current_window->buffer, 0);
gui_current_window->buffer->completion.position = -1;
}
}
i++;
+100 -72
View File
@@ -609,78 +609,89 @@ gui_input_optimize_buffer_size (t_gui_buffer *buffer)
/*
* gui_input_action_dcc: execute an action on a DCC after a user input
* return -1 if DCC buffer was closed due to action, 0 otherwise
*/
void
gui_input_action_dcc (t_gui_window *window, char action)
gui_input_action_dcc (t_gui_window *window, char *actions)
{
t_irc_dcc *dcc_selected, *ptr_dcc, *ptr_dcc_next;
t_gui_buffer *ptr_buffer;
dcc_selected = (window->dcc_selected) ?
(t_irc_dcc *) window->dcc_selected : dcc_list;
switch (action)
while (actions[0])
{
/* accept DCC */
case 'a':
case 'A':
if (dcc_selected
&& (DCC_IS_RECV(dcc_selected->status))
&& (dcc_selected->status == DCC_WAITING))
if (actions[0] >= 32)
{
dcc_selected = (window->dcc_selected) ?
(t_irc_dcc *) window->dcc_selected : dcc_list;
switch (actions[0])
{
dcc_accept (dcc_selected);
}
break;
/* cancel DCC */
case 'c':
case 'C':
if (dcc_selected
&& (!DCC_ENDED(dcc_selected->status)))
{
dcc_close (dcc_selected, DCC_ABORTED);
gui_redraw_buffer (window->buffer);
}
break;
/* purge old DCC */
case 'p':
case 'P':
window->dcc_selected = NULL;
ptr_dcc = dcc_list;
while (ptr_dcc)
{
ptr_dcc_next = ptr_dcc->next_dcc;
if (DCC_ENDED(ptr_dcc->status))
dcc_free (ptr_dcc);
ptr_dcc = ptr_dcc_next;
}
gui_redraw_buffer (window->buffer);
break;
/* close DCC window */
case 'q':
case 'Q':
if (buffer_before_dcc)
{
gui_buffer_free (window->buffer, 1);
gui_switch_to_buffer (window, buffer_before_dcc);
}
else
gui_buffer_free (window->buffer, 1);
gui_redraw_buffer (window->buffer);
break;
/* remove from DCC list */
case 'r':
case 'R':
if (dcc_selected
&& (DCC_ENDED(dcc_selected->status)))
{
if (dcc_selected->next_dcc)
window->dcc_selected = dcc_selected->next_dcc;
else
/* accept DCC */
case 'a':
case 'A':
if (dcc_selected
&& (DCC_IS_RECV(dcc_selected->status))
&& (dcc_selected->status == DCC_WAITING))
{
dcc_accept (dcc_selected);
}
break;
/* cancel DCC */
case 'c':
case 'C':
if (dcc_selected
&& (!DCC_ENDED(dcc_selected->status)))
{
dcc_close (dcc_selected, DCC_ABORTED);
gui_redraw_buffer (window->buffer);
}
break;
/* purge old DCC */
case 'p':
case 'P':
window->dcc_selected = NULL;
dcc_free (dcc_selected);
gui_redraw_buffer (window->buffer);
ptr_dcc = dcc_list;
while (ptr_dcc)
{
ptr_dcc_next = ptr_dcc->next_dcc;
if (DCC_ENDED(ptr_dcc->status))
dcc_free (ptr_dcc);
ptr_dcc = ptr_dcc_next;
}
gui_redraw_buffer (window->buffer);
break;
/* close DCC window */
case 'q':
case 'Q':
if (buffer_before_dcc)
{
ptr_buffer = window->buffer;
gui_switch_to_buffer (window, buffer_before_dcc);
gui_buffer_free (ptr_buffer, 0);
}
else
gui_buffer_free (window->buffer, 1);
gui_redraw_buffer (window->buffer);
return;
break;
/* remove from DCC list */
case 'r':
case 'R':
if (dcc_selected
&& (DCC_ENDED(dcc_selected->status)))
{
if (dcc_selected->next_dcc)
window->dcc_selected = dcc_selected->next_dcc;
else
window->dcc_selected = NULL;
dcc_free (dcc_selected);
gui_redraw_buffer (window->buffer);
}
break;
}
break;
}
actions = utf8_next_char (actions);
}
}
@@ -697,16 +708,7 @@ gui_input_insert_string (t_gui_window *window, char *string, int pos)
int size, length;
char *ptr_start;
if (window->buffer->dcc)
{
while (string[0])
{
if (string[0] >= 32)
gui_input_action_dcc (window, string[0]);
string = utf8_next_char (string);
}
}
else if (window->buffer->has_input)
if (window->buffer->has_input)
{
if (pos == -1)
pos = window->buffer->input_buffer_pos;
@@ -1760,6 +1762,32 @@ gui_switch_to_next_window (t_gui_window *window)
gui_redraw_buffer (gui_current_window->buffer);
}
/*
* gui_switch_to_window_by_buffer: switch to next window displaying a buffer
*/
void
gui_switch_to_window_by_buffer (t_gui_window *window, int buffer_number)
{
t_gui_window *ptr_win;
if (!gui_ok)
return;
ptr_win = (window->next_window) ? window->next_window : gui_windows;
while (ptr_win != window)
{
if (ptr_win->buffer->number == buffer_number)
{
gui_current_window = ptr_win;
gui_switch_to_buffer (gui_current_window, gui_current_window->buffer);
gui_redraw_buffer (gui_current_window->buffer);
return;
}
ptr_win = (ptr_win->next_window) ? ptr_win->next_window : gui_windows;
}
}
/*
* gui_switch_to_dcc_buffer: switch to dcc buffer (create it if it does not exist)
*/
+2
View File
@@ -331,6 +331,7 @@ extern t_gui_line *gui_new_line (t_gui_buffer *);
extern t_gui_message *gui_new_message (t_gui_buffer *);
extern void gui_input_clipboard_copy (char *, int);
extern void gui_input_clipboard_paste (t_gui_window *);
extern void gui_input_action_dcc (t_gui_window *, char *);
extern int gui_input_insert_string (t_gui_window *, char *, int);
extern void gui_input_return (t_gui_window *);
extern void gui_input_tab (t_gui_window *);
@@ -364,6 +365,7 @@ extern void gui_switch_to_previous_buffer (t_gui_window *);
extern void gui_switch_to_next_buffer (t_gui_window *);
extern void gui_switch_to_previous_window (t_gui_window *);
extern void gui_switch_to_next_window (t_gui_window *);
extern void gui_switch_to_window_by_buffer (t_gui_window *, int);
extern void gui_switch_to_dcc_buffer (t_gui_window *);
extern t_gui_buffer *gui_switch_to_buffer_by_number (t_gui_window *, int);
extern void gui_move_buffer_to_number (t_gui_window *, int);
+93 -9
View File
@@ -87,6 +87,26 @@ dcc_search (t_irc_server *server, int type, int status, int port)
return NULL;
}
/*
* dcc_port_in_use: return 1 if a port is in used (by an active or connecting DCC)
*/
int
dcc_port_in_use (int port)
{
t_irc_dcc *ptr_dcc;
/* skip any currently used ports */
for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
{
if ((ptr_dcc->port == port) && (!DCC_ENDED(ptr_dcc->status)))
return 1;
}
/* port not in use */
return 0;
}
/*
* dcc_file_is_resumable: check if a file can be used for resuming a download
*/
@@ -748,9 +768,11 @@ void
dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
{
char *ptr_home, *filename2, *short_filename, *pos;
int spaces;
int spaces, args, port_start, port_end;
struct stat st;
int sock, port;
struct hostent *host;
struct in_addr tmpaddr;
struct sockaddr_in addr;
socklen_t length;
unsigned long local_addr;
@@ -811,11 +833,32 @@ dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
}
/* get local IP address */
/* look up the IP address from dcc_own_ip, if set */
local_addr = 0;
if (cfg_dcc_own_ip && cfg_dcc_own_ip[0])
{
host = gethostbyname (cfg_dcc_own_ip);
if (host)
{
memcpy (&tmpaddr, host->h_addr_list[0], sizeof(struct in_addr));
local_addr = ntohl (tmpaddr.s_addr);
}
else
gui_printf (server->buffer,
_("%s could not find address for '%s'. Falling back to local IP.\n"),
WEECHAT_WARNING, cfg_dcc_own_ip);
}
/* use the local interface, from the server socket */
memset (&addr, 0, sizeof (struct sockaddr_in));
length = sizeof (addr);
getsockname (server->sock, (struct sockaddr *) &addr, &length);
addr.sin_family = AF_INET;
local_addr = ntohl (addr.sin_addr.s_addr);
/* fallback to the local IP address on the interface, if required */
if (local_addr == 0)
local_addr = ntohl (addr.sin_addr.s_addr);
/* open socket for DCC */
sock = socket (AF_INET, SOCK_STREAM, 0);
@@ -830,22 +873,63 @@ dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
return;
}
/* find port automatically */
addr.sin_port = 0;
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1)
/* look for port */
port = 0;
if (cfg_dcc_port_range && cfg_dcc_port_range[0])
{
/* find a free port in the specified range */
args = sscanf (cfg_dcc_port_range, "%d-%d", &port_start, &port_end);
if (args > 0)
{
port = port_start;
if (args == 1)
port_end = port_start;
/* loop through the entire allowed port range */
while (port <= port_end)
{
if (!dcc_port_in_use (port))
{
/* attempt to bind to the free port */
addr.sin_port = htons (port);
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
break;
}
}
if (port > port_end)
port = -1;
}
}
if (port == 0)
{
/* find port automatically */
addr.sin_port = 0;
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0)
{
length = sizeof (addr);
getsockname (sock, (struct sockaddr *) &addr, &length);
port = ntohs (addr.sin_port);
}
else
port = -1;
}
if (port == -1)
{
/* Could not find any port to bind */
irc_display_prefix (server->buffer, PREFIX_ERROR);
gui_printf (server->buffer,
_("%s cannot find port for DCC\n"),
_("%s cannot find available port for DCC\n"),
WEECHAT_ERROR);
close (sock);
if (filename2)
free (filename2);
return;
}
length = sizeof (addr);
getsockname (sock, (struct sockaddr *) &addr, &length);
port = ntohs (addr.sin_port);
if (type == DCC_FILE_SEND)
{