summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2008-05-06 16:51:30 +0200
committerSebastien Helleu <flashcode@flashtux.org>2008-05-06 16:51:30 +0200
commite9603acb1a1943bda3c2cc809e5e39ff8a13b68c (patch)
treed4fb7fef63f5a4c1d415fdca9c1938016b23bbb3 /src
parente7a16efa0cf5123f87ef6d7072fbbb9ccdd42bac (diff)
downloadweechat-e9603acb1a1943bda3c2cc809e5e39ff8a13b68c.zip
IRC DCC chat and file (without resume) reintroduced, via xfer plugin (called by /dcc command)
Diffstat (limited to 'src')
-rw-r--r--src/gui/curses/gui-curses-window.c1
-rw-r--r--src/plugins/irc/irc-command.c48
-rw-r--r--src/plugins/irc/irc-dcc.c175
-rw-r--r--src/plugins/irc/irc-protocol.c97
-rw-r--r--src/plugins/irc/irc-server.c69
-rw-r--r--src/plugins/plugin-infolist.c6
-rw-r--r--src/plugins/plugin.c1
-rw-r--r--src/plugins/scripts/lua/weechat-lua-api.c37
-rw-r--r--src/plugins/scripts/perl/weechat-perl-api.c29
-rw-r--r--src/plugins/scripts/python/weechat-python-api.c32
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby-api.c36
-rw-r--r--src/plugins/weechat-plugin.h3
-rw-r--r--src/plugins/xfer/CMakeLists.txt1
-rw-r--r--src/plugins/xfer/Makefile.am2
-rw-r--r--src/plugins/xfer/xfer-buffer.c302
-rw-r--r--src/plugins/xfer/xfer-buffer.h5
-rw-r--r--src/plugins/xfer/xfer-chat.c116
-rw-r--r--src/plugins/xfer/xfer-chat.h2
-rw-r--r--src/plugins/xfer/xfer-command.c83
-rw-r--r--src/plugins/xfer/xfer-command.h25
-rw-r--r--src/plugins/xfer/xfer-config.c7
-rw-r--r--src/plugins/xfer/xfer-config.h3
-rw-r--r--src/plugins/xfer/xfer-dcc.c1
-rw-r--r--src/plugins/xfer/xfer-file.c4
-rw-r--r--src/plugins/xfer/xfer-network.c317
-rw-r--r--src/plugins/xfer/xfer-network.h3
-rw-r--r--src/plugins/xfer/xfer.c333
-rw-r--r--src/plugins/xfer/xfer.h12
28 files changed, 1195 insertions, 555 deletions
diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c
index 77a8ece29..c7fb4c250 100644
--- a/src/gui/curses/gui-curses-window.c
+++ b/src/gui/curses/gui-curses-window.c
@@ -323,6 +323,7 @@ gui_window_set_custom_color_fg_bg (WINDOW *window, int fg, int bg)
if ((fg >= 0) && (fg < GUI_CURSES_NUM_WEECHAT_COLORS)
&& (bg >= 0) && (bg < GUI_CURSES_NUM_WEECHAT_COLORS))
{
+ gui_window_remove_color_style (window, A_BOLD);
wattron (window, gui_weechat_colors[fg].attributes);
gui_window_set_color (window,
gui_weechat_colors[fg].foreground,
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c
index 6cfa50d64..0741dc51c 100644
--- a/src/plugins/irc/irc-command.c
+++ b/src/plugins/irc/irc-command.c
@@ -894,12 +894,14 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
item = weechat_infolist_new_item (infolist);
if (item)
{
+ weechat_infolist_new_var_string (item, "plugin_name", weechat_plugin->name);
snprintf (plugin_id, sizeof (plugin_id),
- "irc_%x", (unsigned int)ptr_server);
+ "%x", (unsigned int)ptr_server);
weechat_infolist_new_var_string (item, "plugin_id", plugin_id);
weechat_infolist_new_var_string (item, "type", "file_send");
weechat_infolist_new_var_string (item, "protocol", "dcc");
- weechat_infolist_new_var_string (item, "nick", argv[2]);
+ weechat_infolist_new_var_string (item, "remote_nick", argv[2]);
+ weechat_infolist_new_var_string (item, "local_nick", ptr_server->nick);
weechat_infolist_new_var_string (item, "filename", argv_eol[3]);
snprintf (str_address, sizeof (str_address),
"%lu", address);
@@ -924,11 +926,13 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
item = weechat_infolist_new_item (infolist);
if (item)
{
+ weechat_infolist_new_var_string (item, "plugin_name", weechat_plugin->name);
snprintf (plugin_id, sizeof (plugin_id),
- "irc_%x", (unsigned int)ptr_server);
+ "%x", (unsigned int)ptr_server);
weechat_infolist_new_var_string (item, "plugin_id", plugin_id);
weechat_infolist_new_var_string (item, "type", "chat_send");
- weechat_infolist_new_var_string (item, "nick", argv[2]);
+ weechat_infolist_new_var_string (item, "remote_nick", argv[2]);
+ weechat_infolist_new_var_string (item, "local_nick", ptr_server->nick);
snprintf (str_address, sizeof (str_address),
"%lu", address);
weechat_infolist_new_var_string (item, "address", str_address);
@@ -939,17 +943,6 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc,
weechat_infolist_free (infolist);
}
}
- /* close DCC CHAT */
- else if (weechat_strcasecmp (argv[1], "close") == 0)
- {
- if (ptr_channel && (ptr_channel != IRC_CHANNEL_TYPE_CHANNEL)
- && (ptr_channel->dcc_chat))
- {
- //irc_dcc_close (ptr_channel->dcc_chat,
- // IRC_DCC_ABORTED);
- //irc_dcc_redraw (1);
- }
- }
/* unknown DCC action */
else
{
@@ -3589,7 +3582,7 @@ irc_command_init ()
"given, away status is removed)"),
"-all", &irc_command_away, NULL);
weechat_hook_command ("ban",
- N_("bans nicks or hosts"),
+ N_("ban nicks or hosts"),
N_("[channel] [nickname [nickname ...]]"),
N_(" channel: channel for ban\n"
"nickname: user or host to ban"),
@@ -3627,28 +3620,27 @@ irc_command_init ()
"users)"),
"%(irc_msg_part)", &irc_command_cycle, NULL);
weechat_hook_command ("dcc",
- N_("starts DCC (file or chat) or close chat"),
+ N_("start DCC (file or chat)"),
N_("action [nickname [file]]"),
- N_(" action: 'send' (file) or 'chat' or 'close' "
- "(chat)\n"
+ N_(" action: 'send' (file) or 'chat'\n"
"nickname: nickname to send file or chat\n"
" file: filename (on local host)"),
- "chat|send|close %n %f",
+ "chat|send %n %f",
&irc_command_dcc, NULL);
weechat_hook_command ("dehalfop",
- N_("removes half channel operator status from "
+ N_("remove half channel operator status from "
"nickname(s)"),
N_("[nickname [nickname]]"),
"",
NULL, &irc_command_dehalfop, NULL);
weechat_hook_command ("deop",
- N_("removes channel operator status from "
+ N_("remove channel operator status from "
"nickname(s)"),
N_("[nickname [nickname]]"),
"",
NULL, &irc_command_deop, NULL);
weechat_hook_command ("devoice",
- N_("removes voice from nickname(s)"),
+ N_("remove voice from nickname(s)"),
N_("[nickname [nickname]]"),
"",
NULL, &irc_command_devoice, NULL);
@@ -3664,7 +3656,7 @@ irc_command_init ()
"servername: server name to disconnect"),
"%(irc_servers)|-all", &irc_command_disconnect, NULL);
weechat_hook_command ("halfop",
- N_("gives half channel operator status to "
+ N_("give half channel operator status to "
"nickname(s)"),
N_("[nickname [nickname]]"),
"",
@@ -3798,7 +3790,7 @@ irc_command_init ()
" text: text to send"),
"%n %-", &irc_command_notice, NULL);
weechat_hook_command ("op",
- N_("gives channel operator status to nickname(s)"),
+ N_("give channel operator status to nickname(s)"),
N_("nickname [nickname]"),
"",
NULL, &irc_command_op, NULL);
@@ -3961,7 +3953,7 @@ irc_command_init ()
N_("target: server"),
NULL, &irc_command_trace, NULL);
weechat_hook_command ("unban",
- N_("unbans nicks or hosts"),
+ N_("unban nicks or hosts"),
N_("[channel] nickname [nickname ...]"),
N_(" channel: channel for unban\n"
"nickname: user or host to unban"),
@@ -3977,14 +3969,14 @@ irc_command_init ()
N_("target: server"),
NULL, &irc_command_users, NULL);
weechat_hook_command ("version",
- N_("gives the version info of nick or server "
+ N_("give the version info of nick or server "
"(current or specified)"),
N_("[server | nickname]"),
N_(" server: server name\n"
"nickname: nickname"),
"%n", &irc_command_version, NULL);
weechat_hook_command ("voice",
- N_("gives voice to nickname(s)"),
+ N_("give voice to nickname(s)"),
N_("[nickname [nickname]]"),
"",
NULL, &irc_command_voice, NULL);
diff --git a/src/plugins/irc/irc-dcc.c b/src/plugins/irc/irc-dcc.c
index 5a4efe982..7557941f1 100644
--- a/src/plugins/irc/irc-dcc.c
+++ b/src/plugins/irc/irc-dcc.c
@@ -45,41 +45,7 @@ struct t_irc_dcc *irc_dcc_list = NULL; /* DCC files & chat list */
struct t_irc_dcc *irc_last_dcc = NULL; /* last DCC in list */
-/*
- * irc_dcc_channel_for_chat: create channel for DCC chat
- */
-/*
-void
-irc_dcc_channel_for_chat (struct t_irc_dcc *dcc)
-{
- if (!irc_channel_create_dcc (dcc))
- {
- gui_chat_printf_error (dcc->server->buffer,
- _("%s can't associate DCC chat with private "
- "buffer (maybe private buffer has already "
- "DCC CHAT?)\n"),
- WEECHAT_ERROR);
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- return;
- }
-
- gui_chat_printf_type (dcc->channel->buffer, GUI_MSG_TYPE_MSG,
- cfg_look_prefix_info, cfg_col_chat_prefix_info,
- _("Connected to %s%s %s(%s%d.%d.%d.%d%s)%s via DCC "
- "chat\n"),
- GUI_COLOR(GUI_COLOR_CHAT_NICK),
- dcc->nick,
- GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
- GUI_COLOR(GUI_COLOR_CHAT_HOST),
- dcc->addr >> 24,
- (dcc->addr >> 16) & 0xff,
- (dcc->addr >> 8) & 0xff,
- dcc->addr & 0xff,
- GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
- GUI_COLOR(GUI_COLOR_CHAT));
-}
-*/
+
/*
* irc_dcc_chat_remove_channel: remove a buffer for DCC chat
*/
@@ -167,142 +133,3 @@ irc_dcc_start_resume (struct t_irc_server *server, char *filename, int port,
WEECHAT_ERROR, filename, port, pos_start);
}
*/
-/*
- * irc_dcc_handle: receive/send data for all active DCC
- */
-/*
-void
-irc_dcc_handle ()
-{
- struct t_irc_dcc *dcc;
- fd_set read_fd;
- static struct timeval timeout;
- int sock;
- struct sockaddr_in addr;
- socklen_t length;
-
- for (dcc = irc_dcc_list; dcc; dcc = dcc->next_dcc)
- {
- // check DCC timeout
- if (IRC_DCC_IS_FILE(dcc->type) && !IRC_DCC_ENDED(dcc->status))
- {
- if ((irc_cfg_dcc_timeout != 0)
- && (time (NULL) > dcc->last_activity + irc_cfg_dcc_timeout))
- {
- gui_chat_printf_error (dcc->server->buffer,
- _("%s DCC: timeout\n"),
- WEECHAT_ERROR);
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- continue;
- }
- }
-
- if (dcc->status == IRC_DCC_CONNECTING)
- {
- if (dcc->type == IRC_DCC_FILE_SEND)
- {
- FD_ZERO (&read_fd);
- FD_SET (dcc->sock, &read_fd);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- // something to read on socket?
- if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
- {
- if (FD_ISSET (dcc->sock, &read_fd))
- {
- dcc->last_activity = time (NULL);
- length = sizeof (addr);
- sock = accept (dcc->sock,
- (struct sockaddr *) &addr, &length);
- close (dcc->sock);
- dcc->sock = -1;
- if (sock < 0)
- {
- gui_chat_printf_error (dcc->server->buffer,
- _("%s DCC: unable to "
- "create socket for "
- "sending file\n"),
- WEECHAT_ERROR);
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- continue;
- }
- dcc->sock = sock;
- if (fcntl (dcc->sock, F_SETFL, O_NONBLOCK) == -1)
- {
- gui_chat_printf_error (dcc->server->buffer,
- _("%s DCC: unable to set "
- "'nonblock' option for "
- "socket\n"),
- WEECHAT_ERROR);
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- continue;
- }
- dcc->addr = ntohl (addr.sin_addr.s_addr);
- dcc->status = IRC_DCC_ACTIVE;
- dcc->start_transfer = time (NULL);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- irc_dcc_file_send_fork (dcc);
- }
- }
- }
- if (dcc->type == IRC_DCC_FILE_RECV)
- {
- if (dcc->child_read != -1)
- irc_dcc_file_child_read (dcc);
- }
- }
-
- if (dcc->status == IRC_DCC_WAITING)
- {
- if (dcc->type == IRC_DCC_CHAT_SEND)
- {
- FD_ZERO (&read_fd);
- FD_SET (dcc->sock, &read_fd);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- // something to read on socket?
- if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
- {
- if (FD_ISSET (dcc->sock, &read_fd))
- {
- length = sizeof (addr);
- sock = accept (dcc->sock, (struct sockaddr *) &addr, &length);
- close (dcc->sock);
- dcc->sock = -1;
- if (sock < 0)
- {
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- continue;
- }
- dcc->sock = sock;
- if (fcntl (dcc->sock, F_SETFL, O_NONBLOCK) == -1)
- {
- irc_dcc_close (dcc, IRC_DCC_FAILED);
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- continue;
- }
- dcc->addr = ntohl (addr.sin_addr.s_addr);
- dcc->status = IRC_DCC_ACTIVE;
- irc_dcc_redraw (WEECHAT_HOTLIST_MESSAGE);
- irc_dcc_channel_for_chat (dcc);
- }
- }
- }
- }
-
- if (dcc->status == IRC_DCC_ACTIVE)
- {
- if (IRC_DCC_IS_CHAT(dcc->type))
- irc_dcc_chat_recv (dcc);
- else
- irc_dcc_file_child_read (dcc);
- }
- }
-}
-*/
diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c
index 95e845816..b945f3fbc 100644
--- a/src/plugins/irc/irc-protocol.c
+++ b/src/plugins/irc/irc-protocol.c
@@ -1331,6 +1331,9 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
{
char *nick, *host, *pos_args, *pos_end_01, *pos, *pos_message;
char *dcc_args, *pos_file, *pos_addr, *pos_port, *pos_size, *pos_start_resume; /* for DCC */
+ struct t_plugin_infolist *infolist;
+ struct t_plugin_infolist_item *item;
+ char plugin_id[128];
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
int highlight_displayed, look_infobar_delay_highlight;
@@ -1644,11 +1647,9 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
"privmsg");
return WEECHAT_RC_ERROR;
}
-
- pos_end_01[0] = '\0';
- dcc_args = strdup (pos_args + 9);
- pos_end_01[0] = '\01';
-
+
+ dcc_args = weechat_strndup (pos_args + 9, pos_end_01 - pos_args - 9);
+
if (!dcc_args)
{
weechat_printf (server->buffer,
@@ -1722,7 +1723,33 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
pos--;
}
pos[1] = '\0';
-
+
+ /* add DCC file via xfer plugin */
+ infolist = weechat_infolist_new ();
+ if (infolist)
+ {
+ item = weechat_infolist_new_item (infolist);
+ if (item)
+ {
+ weechat_infolist_new_var_string (item, "plugin_name", weechat_plugin->name);
+ snprintf (plugin_id, sizeof (plugin_id),
+ "%x", (unsigned int)server);
+ weechat_infolist_new_var_string (item, "plugin_id", plugin_id);
+ weechat_infolist_new_var_string (item, "type", "file_recv");
+ weechat_infolist_new_var_string (item, "protocol", "dcc");
+ 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, "filename", pos_file);
+ weechat_infolist_new_var_string (item, "size", pos_size);
+ 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",
+ WEECHAT_HOOK_SIGNAL_POINTER,
+ infolist);
+ }
+ weechat_infolist_free (infolist);
+ }
+
/* TODO: add DCC file */
//irc_dcc_add (server, IRC_DCC_FILE_RECV,
// strtoul (pos_addr, NULL, 10),
@@ -1751,11 +1778,9 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
"privmsg");
return WEECHAT_RC_ERROR;
}
-
- pos_end_01[0] = '\0';
- dcc_args = strdup (pos_args + 11);
- pos_end_01[0] = '\01';
-
+
+ dcc_args = weechat_strndup (pos_args + 11, pos_end_01 - pos_args - 11);
+
if (!dcc_args)
{
weechat_printf (server->buffer,
@@ -1825,7 +1850,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
}
/* incoming DCC ACCEPT (resume accepted by sender) */
- if (strncmp (pos, "\01DCC ACCEPT", 11) == 0)
+ if (strncmp (pos_args, "\01DCC ACCEPT", 11) == 0)
{
/* check if DCC ACCEPT is ok, i.e. with 0x01 at end */
pos_end_01 = strchr (pos_args + 1, '\01');
@@ -1837,11 +1862,9 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
"privmsg");
return WEECHAT_RC_ERROR;
}
-
- pos_end_01[0] = '\0';
- dcc_args = strdup (pos_args + 11);
- pos_end_01[0] = '\01';
-
+
+ dcc_args = weechat_strndup (pos_args + 11, pos_end_01 - pos_args - 11);
+
if (!dcc_args)
{
weechat_printf (server->buffer,
@@ -1911,7 +1934,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
}
/* incoming DCC CHAT */
- if (strncmp (pos, "\01DCC CHAT", 9) == 0)
+ if (strncmp (pos_args, "\01DCC CHAT", 9) == 0)
{
/* check if DCC CHAT is ok, i.e. with 0x01 at end */
pos_end_01 = strchr (pos_args + 1, '\01');
@@ -1924,10 +1947,8 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
return WEECHAT_RC_ERROR;
}
- pos_end_01[0] = '\0';
- dcc_args = strdup (pos_args + 9);
- pos_end_01[0] = '\01';
-
+ dcc_args = weechat_strndup (pos_args + 9, pos_end_01 - pos_args - 9);
+
if (!dcc_args)
{
weechat_printf (server->buffer,
@@ -1944,7 +1965,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
{
pos_file++;
}
-
+
/* DCC IP address */
pos_addr = strchr (pos_file, ' ');
if (!pos_addr)
@@ -1995,11 +2016,29 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
return WEECHAT_RC_ERROR;
}
- /* TODO: add DCC chat */
- //irc_dcc_add (server, IRC_DCC_CHAT_RECV,
- // strtoul (pos_addr, NULL, 10),
- // atoi (pos_port), nick, -1, NULL, NULL, 0);
-
+ /* add DCC chat via xfer plugin */
+ infolist = weechat_infolist_new ();
+ if (infolist)
+ {
+ item = weechat_infolist_new_item (infolist);
+ if (item)
+ {
+ weechat_infolist_new_var_string (item, "plugin_name", weechat_plugin->name);
+ snprintf (plugin_id, sizeof (plugin_id),
+ "%x", (unsigned int)server);
+ weechat_infolist_new_var_string (item, "plugin_id", plugin_id);
+ 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, "address", pos_addr);
+ weechat_infolist_new_var_integer (item, "port", atoi (pos_port));
+ weechat_hook_signal_send ("xfer_add",
+ WEECHAT_HOOK_SIGNAL_POINTER,
+ infolist);
+ }
+ weechat_infolist_free (infolist);
+ }
+
weechat_hook_signal_send ("irc_dcc",
WEECHAT_HOOK_SIGNAL_STRING,
argv_eol[0]);
@@ -2012,7 +2051,7 @@ irc_protocol_cmd_privmsg (struct t_irc_server *server, char *command,
/* private message received => display it */
ptr_channel = irc_channel_search (server, nick);
- if (strncmp (pos, "\01ACTION ", 8) == 0)
+ if (strncmp (pos_args, "\01ACTION ", 8) == 0)
{
if (!ptr_channel)
{
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index bef2fdcaf..9cd9dbded 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -2803,8 +2803,9 @@ irc_server_xfer_send_ready_cb (void *data, char *signal, char *type_data,
{
struct t_plugin_infolist *infolist;
struct t_irc_server *server, *ptr_server;
- char *plugin_id, *type;
-
+ char *plugin_name, *plugin_id, *type, *filename;
+ int spaces_in_name;
+
/* make C compiler happy */
(void) data;
(void) signal;
@@ -2814,42 +2815,44 @@ irc_server_xfer_send_ready_cb (void *data, char *signal, char *type_data,
if (weechat_infolist_next (infolist))
{
+ plugin_name = weechat_infolist_string (infolist, "plugin_name");
plugin_id = weechat_infolist_string (infolist, "plugin_id");
- if (plugin_id)
+ if (plugin_name && (strcmp (plugin_name, "irc") == 0) && plugin_id)
{
- if (strncmp (plugin_id, "irc_", 4) == 0)
+ sscanf (plugin_id, "%x", (unsigned int *)&server);
+ for (ptr_server = irc_servers; ptr_server;
+ ptr_server = ptr_server->next_server)
{
- sscanf (plugin_id + 4, "%x", (unsigned int *)&server);
- for (ptr_server = irc_servers; ptr_server;
- ptr_server = ptr_server->next_server)
- {
- if (ptr_server == server)
- break;
- }
- if (ptr_server)
+ if (ptr_server == server)
+ break;
+ }
+ if (ptr_server)
+ {
+ type = weechat_infolist_string (infolist, "type");
+ if (type)
{
- type = weechat_infolist_string (infolist, "type");
- if (type)
+ if (strcmp (type, "file_send") == 0)
{
- if (strcmp (type, "file_send") == 0)
- {
- irc_server_sendf (server,
- "PRIVMSG %s :\01DCC SEND \"%s\" "
- "%s %d %s\01\n",
- weechat_infolist_string (infolist, "nick"),
- weechat_infolist_string (infolist, "filename"),
- weechat_infolist_string (infolist, "address"),
- weechat_infolist_integer (infolist, "port"),
- weechat_infolist_string (infolist, "size"));
- }
- else if (strcmp (type, "chat_send") == 0)
- {
- irc_server_sendf (server,
- "PRIVMSG %s :\01DCC CHAT chat %s %d\01",
- weechat_infolist_string (infolist, "nick"),
- weechat_infolist_string (infolist, "address"),
- weechat_infolist_integer (infolist, "port"));
- }
+ filename = weechat_infolist_string (infolist, "filename");
+ spaces_in_name = (strchr (filename, ' ') != NULL);
+ irc_server_sendf (server,
+ "PRIVMSG %s :\01DCC SEND %s%s%s "
+ "%s %d %s\01",
+ weechat_infolist_string (infolist, "remote_nick"),
+ (spaces_in_name) ? "\"" : "",
+ filename,
+ (spaces_in_name) ? "\"" : "",
+ weechat_infolist_string (infolist, "address"),
+ weechat_infolist_integer (infolist, "port"),
+ weechat_infolist_string (infolist, "size"));
+ }
+ else if (strcmp (type, "chat_send") == 0)
+ {
+ irc_server_sendf (server,
+ "PRIVMSG %s :\01DCC CHAT chat %s %d\01",
+ weechat_infolist_string (infolist, "remote_nick"),
+ weechat_infolist_string (infolist, "address"),
+ weechat_infolist_integer (infolist, "port"));
}
}
}
diff --git a/src/plugins/plugin-infolist.c b/src/plugins/plugin-infolist.c
index 689345ecb..2b780f707 100644
--- a/src/plugins/plugin-infolist.c
+++ b/src/plugins/plugin-infolist.c
@@ -111,7 +111,8 @@ plugin_infolist_new_var_integer (struct t_plugin_infolist_item *item,
new_var->name = strdup (name);
new_var->type = PLUGIN_INFOLIST_INTEGER;
new_var->value = malloc (sizeof (int));
- *((int *)new_var->value) = value;
+ if (new_var->value)
+ *((int *)new_var->value) = value;
new_var->prev_var = item->last_var;
new_var->next_var = NULL;
@@ -208,7 +209,8 @@ plugin_infolist_new_var_time (struct t_plugin_infolist_item *item,
new_var->name = strdup (name);
new_var->type = PLUGIN_INFOLIST_TIME;
new_var->value = malloc (sizeof (time_t));
- *((time_t *)new_var->value) = time;
+ if (new_var->value)
+ *((time_t *)new_var->value) = time;
new_var->prev_var = item->last_var;
new_var->next_var = NULL;
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 90979594e..fd26a3347 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -372,6 +372,7 @@ plugin_load (char *filename)
new_plugin->buffer_new = &gui_buffer_new;
new_plugin->buffer_search = &gui_buffer_search_by_category_name;
+ new_plugin->buffer_clear = &gui_buffer_clear;
new_plugin->buffer_close = &gui_buffer_close;
new_plugin->buffer_get_string = &gui_buffer_get_string;
new_plugin->buffer_get_pointer = &gui_buffer_get_pointer;
diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c
index fe874cb46..9e0431da1 100644
--- a/src/plugins/scripts/lua/weechat-lua-api.c
+++ b/src/plugins/scripts/lua/weechat-lua-api.c
@@ -3291,6 +3291,42 @@ weechat_lua_api_buffer_search (lua_State *L)
}
/*
+ * weechat_lua_api_buffer_clear: clear a buffer
+ */
+
+static int
+weechat_lua_api_buffer_clear (lua_State *L)
+{
+ const char *buffer;
+ int n;
+
+ /* make C compiler happy */
+ (void) L;
+
+ if (!lua_current_script)
+ {
+ WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("buffer_clear");
+ LUA_RETURN_ERROR;
+ }
+
+ buffer = NULL;
+
+ n = lua_gettop (lua_current_interpreter);
+
+ if (n < 1)
+ {
+ WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_clear");
+ LUA_RETURN_ERROR;
+ }
+
+ buffer = lua_tostring (lua_current_interpreter, -1);
+
+ weechat_buffer_clear (script_str2ptr ((char *)buffer));
+
+ LUA_RETURN_OK;
+}
+
+/*
* weechat_lua_api_buffer_close: close a buffer
*/
@@ -4794,6 +4830,7 @@ const struct luaL_reg weechat_lua_api_funcs[] = {
{ "unhook_all", &weechat_lua_api_unhook_all },
{ "buffer_new", &weechat_lua_api_buffer_new },
{ "buffer_search", &weechat_lua_api_buffer_search },
+ { "buffer_clear", &weechat_lua_api_buffer_clear },
{ "buffer_close", &weechat_lua_api_buffer_close },
{ "buffer_get_string", &weechat_lua_api_buffer_get_string },
{ "buffer_get_pointer", &weechat_lua_api_buffer_get_pointer },
diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c
index 082363983..b1081e00f 100644
--- a/src/plugins/scripts/perl/weechat-perl-api.c
+++ b/src/plugins/scripts/perl/weechat-perl-api.c
@@ -2751,6 +2751,34 @@ static XS (XS_weechat_buffer_search)
}
/*
+ * weechat::buffer_clear: clear a buffer
+ */
+
+static XS (XS_weechat_buffer_clear)
+{
+ dXSARGS;
+
+ /* make C compiler happy */
+ (void) cv;
+
+ if (!perl_current_script)
+ {
+ WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("buffer_clear");
+ PERL_RETURN_ERROR;
+ }
+
+ if (items < 1)
+ {
+ WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_clear");
+ PERL_RETURN_ERROR;
+ }
+
+ weechat_buffer_clear (script_str2ptr (SvPV (ST (0), PL_na))); /* buffer */
+
+ PERL_RETURN_OK;
+}
+
+/*
* weechat::buffer_close: close a buffer
*/
@@ -3867,6 +3895,7 @@ weechat_perl_api_init (pTHX)
newXS ("weechat::unhook_all", XS_weechat_unhook_all, "weechat");
newXS ("weechat::buffer_new", XS_weechat_buffer_new, "weechat");
newXS ("weechat::buffer_search", XS_weechat_buffer_search, "weechat");
+ newXS ("weechat::buffer_clear", XS_weechat_buffer_clear, "weechat");
newXS ("weechat::buffer_close", XS_weechat_buffer_close, "weechat");
newXS ("weechat::buffer_get_string", XS_weechat_buffer_get_string, "weechat");
newXS ("weechat::buffer_get_pointer", XS_weechat_buffer_get_pointer, "weechat");
diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c
index 9a7696c24..c1ea8821d 100644
--- a/src/plugins/scripts/python/weechat-python-api.c
+++ b/src/plugins/scripts/python/weechat-python-api.c
@@ -2919,6 +2919,37 @@ weechat_python_api_buffer_search (PyObject *self, PyObject *args)
}
/*
+ * weechat_python_api_buffer_clear: clear a buffer
+ */
+
+static PyObject *
+weechat_python_api_buffer_clear (PyObject *self, PyObject *args)
+{
+ char *buffer;
+
+ /* make C compiler happy */
+ (void) self;
+
+ if (!python_current_script)
+ {
+ WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("buffer_clear");
+ PYTHON_RETURN_ERROR;
+ }
+
+ buffer = NULL;
+
+ if (!PyArg_ParseTuple (args, "s", &buffer))
+ {
+ WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_clear");
+ PYTHON_RETURN_ERROR;
+ }
+
+ weechat_buffer_clear (script_str2ptr (buffer));
+
+ PYTHON_RETURN_OK;
+}
+
+/*
* weechat_python_api_buffer_close: close a buffer
*/
@@ -4110,6 +4141,7 @@ PyMethodDef weechat_python_funcs[] =
{ "unhook_all", &weechat_python_api_unhook_all, METH_VARARGS, "" },
{ "buffer_new", &weechat_python_api_buffer_new, METH_VARARGS, "" },
{ "buffer_search", &weechat_python_api_buffer_search, METH_VARARGS, "" },
+ { "buffer_clear", &weechat_python_api_buffer_clear, METH_VARARGS, "" },
{ "buffer_close", &weechat_python_api_buffer_close, METH_VARARGS, "" },
{ "buffer_get_string", &weechat_python_api_buffer_get_string, METH_VARARGS, "" },
{ "buffer_get_pointer", &weechat_python_api_buffer_get_pointer, METH_VARARGS, "" },
diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c
index 70bba8fde..2439b1b36 100644
--- a/src/plugins/scripts/ruby/weechat-ruby-api.c
+++ b/src/plugins/scripts/ruby/weechat-ruby-api.c
@@ -3349,6 +3349,41 @@ weechat_ruby_api_buffer_search (VALUE class, VALUE category, VALUE name)
}
/*
+ * weechat_ruby_api_buffer_clear: clear a buffer
+ */
+
+static VALUE
+weechat_ruby_api_buffer_clear (VALUE class, VALUE buffer)
+{
+ char *c_buffer;
+
+ /* make C compiler happy */
+ (void) class;
+
+ if (!ruby_current_script)
+ {
+ WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("buffer_clear");
+ RUBY_RETURN_ERROR;
+ }
+
+ c_buffer = NULL;
+
+ if (NIL_P (buffer))
+ {
+ WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("buffer_clear");
+ RUBY_RETURN_ERROR;
+ }
+
+ Check_Type (buffer, T_STRING);
+
+ c_buffer = STR2CSTR (buffer);
+
+ weechat_buffer_clear (script_str2ptr (c_buffer));
+
+ RUBY_RETURN_OK;
+}
+
+/*
* weechat_ruby_api_buffer_close: close a buffer
*/
@@ -4714,6 +4749,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat)
rb_define_module_function (ruby_mWeechat, "unhook_all", &weechat_ruby_api_unhook_all, 0);
rb_define_module_function (ruby_mWeechat, "buffer_new", &weechat_ruby_api_buffer_new, 4);
rb_define_module_function (ruby_mWeechat, "buffer_search", &weechat_ruby_api_buffer_search, 2);
+ rb_define_module_function (ruby_mWeechat, "buffer_clear", &weechat_ruby_api_buffer_clear, 1);
rb_define_module_function (ruby_mWeechat, "buffer_close", &weechat_ruby_api_buffer_close, 1);
rb_define_module_function (ruby_mWeechat, "buffer_get_string", &weechat_ruby_api_buffer_get_string, 2);
rb_define_module_function (ruby_mWeechat, "buffer_get_pointer", &weechat_ruby_api_buffer_get_pointer, 2);
diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h
index 557fc6608..0bcf417fc 100644
--- a/src/plugins/weechat-plugin.h
+++ b/src/plugins/weechat-plugin.h
@@ -335,6 +335,7 @@ struct t_weechat_plugin
struct t_gui_buffer *buffer),
void *close_callback_data);
struct t_gui_buffer *(*buffer_search) (char *category, char *name);
+ void (*buffer_clear) (struct t_gui_buffer *buffer);
void (*buffer_close) (struct t_gui_buffer *buffer, int switch_to_another);
char *(*buffer_get_string) (struct t_gui_buffer *buffer, char *property);
void *(*buffer_get_pointer) (struct t_gui_buffer *buffer, char *property);
@@ -749,6 +750,8 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
weechat_plugin->buffer_search(__category, __name)
#define weechat_current_buffer \
weechat_plugin->buffer_search(NULL, NULL)
+#define weechat_buffer_clear(__buffer) \
+ weechat_plugin->buffer_clear(__buffer)
#define weechat_buffer_close(__buffer, __switch_to_another) \
weechat_plugin->buffer_close(__buffer, __switch_to_another)
#define weechat_buffer_get_string(__buffer, __property) \
diff --git a/src/plugins/xfer/CMakeLists.txt b/src/plugins/xfer/CMakeLists.txt
index f9849e367..78c1c006b 100644
--- a/src/plugins/xfer/CMakeLists.txt
+++ b/src/plugins/xfer/CMakeLists.txt
@@ -18,6 +18,7 @@ ADD_LIBRARY(xfer MODULE
xfer.c xfer.h
xfer-buffer.c xfer-buffer.h
xfer-chat.c xfer-chat.h
+xfer-command.c xfer-command.h
xfer-config.c xfer-config.h
xfer-dcc.c xfer-dcc.h
xfer-file.c xfer-file.h
diff --git a/src/plugins/xfer/Makefile.am b/src/plugins/xfer/Makefile.am
index ad7538bb4..9280fa432 100644
--- a/src/plugins/xfer/Makefile.am
+++ b/src/plugins/xfer/Makefile.am
@@ -26,6 +26,8 @@ xfer_la_SOURCES = xfer.c \
xfer-buffer.h \
xfer-chat.c \
xfer-chat.h \
+ xfer-command.c \
+ xfer-command.h \
xfer-config.c \
xfer-config.h \
xfer-dcc.c \
diff --git a/src/plugins/xfer/xfer-buffer.c b/src/plugins/xfer/xfer-buffer.c
index 52823985f..dd32ca0b0 100644
--- a/src/plugins/xfer/xfer-buffer.c
+++ b/src/plugins/xfer/xfer-buffer.c
@@ -21,11 +21,13 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <time.h>
#include "../weechat-plugin.h"
#include "xfer.h"
-#include "xfer-buffer.h"
#include "xfer-config.h"
+#include "xfer-network.h"
struct t_gui_buffer *xfer_buffer = NULL;
@@ -33,6 +35,249 @@ int xfer_buffer_selected_line = 0;
/*
+ * xfer_buffer_refresh: update a xfer in buffer and update hotlist for xfer buffer
+ */
+
+void
+xfer_buffer_refresh (char *hotlist)
+{
+ struct t_xfer *ptr_xfer;
+ char str_color[256], status[64], date[128], *progress_bar, format[128];
+ char format_per_sec[128], bytes_per_sec[256], eta[128];
+ int i, length, line, progress_bar_size, num_bars, num_unit;
+ int num_unit_per_sec;
+ unsigned long pct_complete;
+ char *unit_name[] = { N_("bytes"), N_("KB"), N_("MB"), N_("GB") };
+ char *unit_format[] = { "%.0f", "%.1f", "%.02f", "%.02f" };
+ float unit_divide[] = { 1, 1024, 1024*1024, 1024*1024*1024 };
+ struct tm *date_tmp;
+
+ if (xfer_buffer)
+ {
+ weechat_buffer_clear (xfer_buffer);
+ line = 0;
+ for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
+ {
+ snprintf (str_color, sizeof (str_color),
+ "%s,%s",
+ weechat_config_string (xfer_config_color_text),
+ weechat_config_string (xfer_config_color_text_bg));
+
+ /* display first line with remote nick and filename */
+ weechat_printf_y (xfer_buffer, line * 2,
+ "%s%s%-25s %s%s%s",
+ weechat_color(str_color),
+ (line == xfer_buffer_selected_line) ?
+ "*** " : " ",
+ ptr_xfer->remote_nick,
+ (XFER_IS_FILE(ptr_xfer->type)) ? "\"" : "",
+ (XFER_IS_FILE(ptr_xfer->type)) ?
+ ptr_xfer->filename : _("xfer chat"),
+ (XFER_IS_FILE(ptr_xfer->type)) ? "\"" : "");
+
+ snprintf (status, sizeof (status),
+ "%s", _(xfer_status_string[ptr_xfer->status]));
+ length = strlen (status);
+ if (length < 20)
+ {
+ for (i = 0; i < 20 - length; i++)
+ {
+ strcat (status, " ");
+ }
+ }
+
+ if (XFER_IS_CHAT(ptr_xfer->type))
+ {
+ /* display second line for chat with status and date */
+ date_tmp = localtime (&(ptr_xfer->start_time));
+ strftime (date, sizeof (date),
+ "%a, %d %b %Y %H:%M:%S", date_tmp);
+ weechat_printf_y (xfer_buffer, (line * 2) + 1,
+ "%s%s%s %s%s %s%s%s",
+ weechat_color(str_color),
+ (line == xfer_buffer_selected_line) ?
+ "*** " : " ",
+ (XFER_IS_SEND(ptr_xfer->type)) ?
+ "<<--" : "-->>",
+ weechat_color(weechat_config_string (xfer_config_color_status[ptr_xfer->status])),
+ status,
+ weechat_color ("reset"),
+ weechat_color (str_color),
+ date);
+ }
+ else
+ {
+ /* build progress bar */
+ progress_bar = NULL;
+ progress_bar_size = weechat_config_integer (xfer_config_look_progress_bar_size);
+ if (progress_bar_size > 0)
+ {
+ progress_bar = malloc (1 + progress_bar_size + 1 + 1);
+ strcpy (progress_bar, "[");
+ if (ptr_xfer->size == 0)
+ {
+ if (ptr_xfer->status == XFER_STATUS_DONE)
+ num_bars = progress_bar_size;
+ else
+ num_bars = 0;
+ }
+ else
+ num_bars = (int)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * (float)progress_bar_size);
+ for (i = 0; i < num_bars - 1; i++)
+ {
+ strcat (progress_bar, "=");
+ }
+ if (num_bars > 0)
+ strcat (progress_bar, ">");
+ for (i = 0; i < progress_bar_size - num_bars; i++)
+ {
+ strcat (progress_bar, " ");
+ }
+ strcat (progress_bar, "]");
+ }
+
+ /* computes pourcentage */
+ if (ptr_xfer->size < 1024*10)
+ num_unit = 0;
+ else if (ptr_xfer->size < 1024*1024)
+ num_unit = 1;
+ else if (ptr_xfer->size < 1024*1024*1024)
+ num_unit = 2;
+ else
+ num_unit = 3;
+ if (ptr_xfer->size == 0)
+ {
+ if (ptr_xfer->status == XFER_STATUS_DONE)
+ pct_complete = 100;
+ else
+ pct_complete = 0;
+ }
+ else
+ pct_complete = (unsigned long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
+
+ snprintf (format, sizeof (format),
+ "%%s%%s%%s %%s%%s%%s%%s %%3lu%%%% %s %%s / %s %%s (%%s%%s)",
+ unit_format[num_unit],
+ unit_format[num_unit]);
+
+ /* bytes per second */
+ bytes_per_sec[0] = '\0';
+ if (ptr_xfer->bytes_per_sec < 1024*10)
+ num_unit_per_sec = 0;
+ else if (ptr_xfer->bytes_per_sec < 1024*1024)
+ num_unit_per_sec = 1;
+ else if (ptr_xfer->bytes_per_sec < 1024*1024*1024)
+ num_unit_per_sec = 2;
+ else
+ num_unit_per_sec = 3;
+ snprintf (format_per_sec, sizeof (format_per_sec),
+ "%s %%s/s",
+ unit_format[num_unit_per_sec]);
+ snprintf (bytes_per_sec, sizeof (bytes_per_sec),
+ format_per_sec,
+ ((float)ptr_xfer->bytes_per_sec) / ((float)(unit_divide[num_unit_per_sec])),
+ _(unit_name[num_unit_per_sec]));
+
+ /* ETA */
+ eta[0] = '\0';
+ if (ptr_xfer->status == XFER_STATUS_ACTIVE)
+ {
+ snprintf (eta, sizeof (eta),
+ "%s: %.2lu:%.2lu:%.2lu - ",
+ _("ETA"),
+ ptr_xfer->eta / 3600,
+ (ptr_xfer->eta / 60) % 60,
+ ptr_xfer->eta % 60);
+ }
+
+ /* display second line for file with status, progress bar and estimated time */
+ weechat_printf_y (xfer_buffer, (line * 2) + 1,
+ format,
+ weechat_color(str_color),
+ (line == xfer_buffer_selected_line) ?
+ "*** " : " ",
+ (XFER_IS_SEND(ptr_xfer->type)) ?
+ "<<--" : "-->>",
+ weechat_color(weechat_config_string (xfer_config_color_status[ptr_xfer->status])),
+ status,
+ weechat_color (str_color),
+ (progress_bar) ? progress_bar : "",
+ pct_complete,
+ ((float)(ptr_xfer->pos)) / unit_divide[num_unit],
+ _(unit_name[num_unit]),
+ ((float)(ptr_xfer->size)) / unit_divide[num_unit],
+ _(unit_name[num_unit]),
+ eta,
+ bytes_per_sec);
+ }
+ line++;
+ }
+ weechat_buffer_set (xfer_buffer, "hotlist", hotlist);
+ }
+}
+
+/*
+ * xfer_buffer_input_cb: callback called when user send data to xfer list
+ * buffer
+ */
+
+int
+xfer_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
+ char *input_data)
+{
+ struct t_xfer *xfer, *ptr_xfer, *next_xfer;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+
+ xfer = xfer_search_by_number (xfer_buffer_selected_line);
+
+ /* accept xfer */
+ if (weechat_strcasecmp (input_data, "a") == 0)
+ {
+ if (xfer && XFER_IS_RECV(xfer->type)
+ && (xfer->status == XFER_STATUS_WAITING))
+ {
+ xfer_network_accept (xfer);
+ }
+ }
+ /* cancel xfer */
+ else if (weechat_strcasecmp (input_data, "c") == 0)
+ {
+ if (xfer && !XFER_HAS_ENDED(xfer->status))
+ {
+ xfer_close (xfer, XFER_STATUS_ABORTED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ }
+ }
+ /* purge old xfer */
+ else if (weechat_strcasecmp (input_data, "p") == 0)
+ {
+ ptr_xfer = xfer_list;
+ while (ptr_xfer)
+ {
+ next_xfer = ptr_xfer->next_xfer;
+ if (XFER_HAS_ENDED(ptr_xfer->status))
+ xfer_free (ptr_xfer);
+ ptr_xfer = next_xfer;
+ }
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ }
+ /* remove xfer */
+ else if (weechat_strcasecmp (input_data, "r") == 0)
+ {
+ if (xfer && XFER_HAS_ENDED(xfer->status))
+ {
+ xfer_free (xfer);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* xfer_buffer_close_cb: callback called when xfer buffer is closed
*/
@@ -57,61 +302,18 @@ xfer_buffer_open ()
{
if (!xfer_buffer)
{
- xfer_buffer = weechat_buffer_new ("xfer", "xfer",
- NULL, NULL,
+ xfer_buffer = weechat_buffer_new ("xfer", "list",
+ &xfer_buffer_input_cb, NULL,
&xfer_buffer_close_cb, NULL);
/* failed to create buffer ? then exit */
if (!xfer_buffer)
return;
-
+
weechat_buffer_set (xfer_buffer, "type", "free");
weechat_buffer_set (xfer_buffer, "title", _("Xfer list"));
- }
-}
-
-/*
- * xfer_buffer_refresh: update a xfer in buffer and update hotlist for xfer buffer
- */
-
-void
-xfer_buffer_refresh (char *hotlist)
-{
- struct t_xfer *ptr_xfer;
- char str_color[256];
- int line;
-
- if (xfer_buffer)
- {
- line = 0;
- for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
- {
- if (XFER_IS_FILE(ptr_xfer->type))
- {
- snprintf (str_color, sizeof (str_color),
- "%s,%s",
- weechat_config_string (xfer_config_color_text),
- weechat_config_string (xfer_config_color_text_bg));
- weechat_printf_y (xfer_buffer, line * 2,
- "%s%s%-20s \"%s\"",
- weechat_color(str_color),
- (line == xfer_buffer_selected_line) ?
- "*** " : " ",
- ptr_xfer->nick, ptr_xfer->filename);
- weechat_printf_y (xfer_buffer, (line * 2) + 1,
- "%s%s%s %s%-15s ",
- weechat_color(str_color),
- (line == xfer_buffer_selected_line) ?
- "*** " : " ",
- (XFER_IS_SEND(ptr_xfer->type)) ?
- "<<--" : "-->>",
- weechat_color(
- weechat_config_string (
- xfer_config_color_status[ptr_xfer->status])),
- _(xfer_status_string[ptr_xfer->status]));
- }
- line++;
- }
- weechat_buffer_set (xfer_buffer, "hotlist", hotlist);
+ weechat_buffer_set (xfer_buffer, "key_bind_meta2-A", "/xfer up");
+ weechat_buffer_set (xfer_buffer, "key_bind_meta2-B", "/xfer down");
+ weechat_buffer_set (xfer_buffer, "display", "1");
}
}
diff --git a/src/plugins/xfer/xfer-buffer.h b/src/plugins/xfer/xfer-buffer.h
index aea4291e1..22f26ce76 100644
--- a/src/plugins/xfer/xfer-buffer.h
+++ b/src/plugins/xfer/xfer-buffer.h
@@ -21,8 +21,9 @@
#define __WEECHAT_XFER_DISPLAY_H 1
extern struct t_gui_buffer *xfer_buffer;
+extern int xfer_buffer_selected_line;
-extern void xfer_buffer_open ();
extern void xfer_buffer_refresh (char *hotlist);
+extern void xfer_buffer_open ();
-#endif /* xfer.h */
+#endif /* xfer-buffer.h */
diff --git a/src/plugins/xfer/xfer-chat.c b/src/plugins/xfer/xfer-chat.c
index 4999817e5..2dab0a2c8 100644
--- a/src/plugins/xfer/xfer-chat.c
+++ b/src/plugins/xfer/xfer-chat.c
@@ -74,37 +74,25 @@ xfer_chat_sendf (struct t_xfer *xfer, char *format, ...)
{
weechat_printf (NULL,
_("%s%s: error sending data to \"%s\" via xfer chat"),
- weechat_prefix ("error"), "xfer", xfer->nick);
+ weechat_prefix ("error"), "xfer", xfer->remote_nick);
xfer_close (xfer, XFER_STATUS_FAILED);
}
}
/*
- * xfer_chat_recv: receive data from xfer chat remote host
+ * xfer_chat_recv_cb: receive data from xfer chat remote host
*/
-void
-xfer_chat_recv (struct t_xfer *xfer)
+int
+xfer_chat_recv_cb (void *arg_xfer)
{
- fd_set read_fd;
- static struct timeval timeout;
+ struct t_xfer *xfer;
static char buffer[4096 + 2];
char *buf2, *pos, *ptr_buf, *next_ptr_buf;
int num_read;
- FD_ZERO (&read_fd);
- FD_SET (xfer->sock, &read_fd);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- /* something to read on socket? */
- if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) <= 0)
- return;
+ xfer = (struct t_xfer *)arg_xfer;
- if (!FD_ISSET (xfer->sock, &read_fd))
- return;
-
- /* there's something to read on socket! */
num_read = recv (xfer->sock, buffer, sizeof (buffer) - 2, 0);
if (num_read > 0)
{
@@ -144,7 +132,7 @@ xfer_chat_recv (struct t_xfer *xfer)
if (ptr_buf)
{
- weechat_printf (xfer->buffer, "%s\t%s", xfer->nick, ptr_buf);
+ weechat_printf (xfer->buffer, "%s\t%s", xfer->remote_nick, ptr_buf);
}
ptr_buf = next_ptr_buf;
@@ -158,4 +146,94 @@ xfer_chat_recv (struct t_xfer *xfer)
xfer_close (xfer, XFER_STATUS_ABORTED);
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_chat_buffer_input_cb: callback called when user send data to xfer chat
+ * buffer
+ */
+
+int
+xfer_chat_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
+ char *input_data)
+{
+ struct t_xfer *xfer;
+
+ xfer = (struct t_xfer *)data;
+
+ if (!XFER_HAS_ENDED(xfer->status))
+ {
+ xfer_chat_sendf (xfer, "%s\n", input_data);
+ if (!XFER_HAS_ENDED(xfer->status))
+ {
+ weechat_printf (buffer,
+ "%s\t%s",
+ xfer->local_nick,
+ input_data);
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_chat_close_buffer_cb: callback called when a buffer with direct chat
+ * is closed
+ */
+
+int
+xfer_chat_buffer_close_cb (void *data, struct t_gui_buffer *buffer)
+{
+ struct t_xfer *xfer;
+
+ /* make C compiler happy */
+ (void) buffer;
+
+ xfer = (struct t_xfer *)data;
+
+ if (!XFER_HAS_ENDED(xfer->status))
+ {
+ xfer_close (xfer, XFER_STATUS_ABORTED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ }
+
+ xfer->buffer = NULL;
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_chat_open_buffer: create channel for DCC chat
+ */
+
+void
+xfer_chat_open_buffer (struct t_xfer *xfer)
+{
+ char *name;
+ int length;
+
+ length = strlen (xfer->plugin_name) + 1 + strlen (xfer->remote_nick) + 1;
+ name = malloc (length);
+ if (name)
+ {
+ snprintf (name, length, "%s_%s", xfer->plugin_name, xfer->remote_nick);
+ xfer->buffer = weechat_buffer_new ("xfer", name,
+ &xfer_chat_buffer_input_cb, xfer,
+ &xfer_chat_buffer_close_cb, xfer);
+ if (xfer->buffer)
+ {
+ weechat_buffer_set (xfer->buffer, "title", _("xfer chat"));
+ weechat_printf (xfer->buffer,
+ _("Connected to %s (%d.%d.%d.%d) via "
+ "xfer chat"),
+ xfer->remote_nick,
+ xfer->address >> 24,
+ (xfer->address >> 16) & 0xff,
+ (xfer->address >> 8) & 0xff,
+ xfer->address & 0xff);
+ }
+ free (name);
+ }
}
diff --git a/src/plugins/xfer/xfer-chat.h b/src/plugins/xfer/xfer-chat.h
index b3470aca5..131a6111f 100644
--- a/src/plugins/xfer/xfer-chat.h
+++ b/src/plugins/xfer/xfer-chat.h
@@ -20,5 +20,7 @@
#ifndef __WEECHAT_XFER_CHAT_H
#define __WEECHAT_XFER_CHAT_H 1
+extern int xfer_chat_recv_cb (void *arg_xfer);
+extern void xfer_chat_open_buffer (struct t_xfer *xfer);
#endif /* xfer-chat.h */
diff --git a/src/plugins/xfer/xfer-command.c b/src/plugins/xfer/xfer-command.c
new file mode 100644
index 000000000..95d5adfff
--- /dev/null
+++ b/src/plugins/xfer/xfer-command.c
@@ -0,0 +1,83 @@
+/*
+ * 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/>.
+ */
+
+/* xfer-command.c: xfer command */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../weechat-plugin.h"
+#include "xfer.h"
+#include "xfer-buffer.h"
+
+
+/*
+ * xfer_command_xfer: command /xfer
+ */
+
+int
+xfer_command_xfer (void *data, struct t_gui_buffer *buffer, int argc,
+ char **argv, char **argv_eol)
+{
+ /* make C compiler happy */
+ (void) data;
+ (void) buffer;
+ (void) argc;
+ (void) argv;
+ (void) argv_eol;
+
+ if (!xfer_buffer)
+ xfer_buffer_open ();
+
+ if (argc > 1)
+ {
+ if (strcmp (argv[1], "up") == 0)
+ {
+ if (xfer_buffer_selected_line > 0)
+ {
+ xfer_buffer_selected_line--;
+ xfer_buffer_refresh (NULL);
+ }
+ }
+ else if (strcmp (argv[1], "down") == 0)
+ {
+ if (xfer_buffer_selected_line < xfer_count - 1)
+ {
+ xfer_buffer_selected_line++;
+ xfer_buffer_refresh (NULL);
+ }
+ }
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_command: xfer command
+ */
+
+void
+xfer_command_init ()
+{
+ weechat_hook_command ("xfer",
+ N_("xfer control"),
+ "",
+ _("Open buffer with xfer list"),
+ NULL, &xfer_command_xfer, NULL);
+}
diff --git a/src/plugins/xfer/xfer-command.h b/src/plugins/xfer/xfer-command.h
new file mode 100644
index 000000000..7b29cafc5
--- /dev/null
+++ b/src/plugins/xfer/xfer-command.h
@@ -0,0 +1,25 @@
+/*
+ * 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_XFER_COMMAND_H
+#define __WEECHAT_XFER_COMMAND_H 1
+
+extern void xfer_command_init ();
+
+#endif /* xfer-command.h */
diff --git a/src/plugins/xfer/xfer-config.c b/src/plugins/xfer/xfer-config.c
index c532c7bc5..3efc0e487 100644
--- a/src/plugins/xfer/xfer-config.c
+++ b/src/plugins/xfer/xfer-config.c
@@ -32,6 +32,7 @@ struct t_config_file *xfer_config_file = NULL;
/* xfer config, look section */
struct t_config_option *xfer_config_look_auto_open_buffer;
+struct t_config_option *xfer_config_look_progress_bar_size;
/* xfer config, color section */
@@ -104,6 +105,12 @@ xfer_config_init ()
N_("auto open xfer buffer and switch to it when a new xfer is added "
"to list"),
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL);
+ xfer_config_look_progress_bar_size = weechat_config_new_option (
+ xfer_config_file, ptr_section,
+ "progress_bar_size", "integer",
+ N_("size of progress bar, in chars (if 0, progress bar is disabled)"),
+ NULL, 0, XFER_CONFIG_PROGRESS_BAR_MAX_SIZE, "20",
+ NULL, NULL, NULL, NULL, NULL, NULL);
ptr_section = weechat_config_new_section (xfer_config_file, "color",
0, 0,
diff --git a/src/plugins/xfer/xfer-config.h b/src/plugins/xfer/xfer-config.h
index a7753d024..3101693a4 100644
--- a/src/plugins/xfer/xfer-config.h
+++ b/src/plugins/xfer/xfer-config.h
@@ -22,9 +22,12 @@
#define XFER_CONFIG_NAME "xfer"
+#define XFER_CONFIG_PROGRESS_BAR_MAX_SIZE 256
+
extern struct t_config_file *xfer_config;
extern struct t_config_option *xfer_config_look_auto_open_buffer;
+extern struct t_config_option *xfer_config_look_progress_bar_size;
extern struct t_config_option *xfer_config_color_text;
extern struct t_config_option *xfer_config_color_text_bg;
diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c
index 5737ce515..4f94b5d1c 100644
--- a/src/plugins/xfer/xfer-dcc.c
+++ b/src/plugins/xfer/xfer-dcc.c
@@ -31,7 +31,6 @@
#include "../weechat-plugin.h"
#include "xfer.h"
-#include "xfer-dcc.h"
#include "xfer-network.h"
diff --git a/src/plugins/xfer/xfer-file.c b/src/plugins/xfer/xfer-file.c
index cc067f1b4..e43729bd7 100644
--- a/src/plugins/xfer/xfer-file.c
+++ b/src/plugins/xfer/xfer-file.c
@@ -101,7 +101,7 @@ xfer_file_find_filename (struct t_xfer *xfer)
}
xfer->local_filename = malloc (strlen (dir2) +
- strlen (xfer->nick) +
+ strlen (xfer->remote_nick) +
strlen (xfer->filename) + 4);
if (!xfer->local_filename)
return;
@@ -111,7 +111,7 @@ xfer_file_find_filename (struct t_xfer *xfer)
if (dir_separator
&& (xfer->local_filename[strlen (xfer->local_filename) - 1] != dir_separator[0]))
strcat (xfer->local_filename, dir_separator);
- strcat (xfer->local_filename, xfer->nick);
+ strcat (xfer->local_filename, xfer->remote_nick);
strcat (xfer->local_filename, ".");
strcat (xfer->local_filename, xfer->filename);
diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c
index 2c9247996..e0f26e0b7 100644
--- a/src/plugins/xfer/xfer-network.c
+++ b/src/plugins/xfer/xfer-network.c
@@ -28,59 +28,18 @@
#include <sys/socket.h>
#include <signal.h>
#include <time.h>
+#include <netdb.h>
#include "../weechat-plugin.h"
#include "xfer.h"
-#include "xfer-network.h"
#include "xfer-buffer.h"
+#include "xfer-chat.h"
+#include "xfer-config.h"
#include "xfer-dcc.h"
#include "xfer-file.h"
/*
- * xfer_network_connect: connect to another host
- */
-
-int
-xfer_network_connect (struct t_xfer *xfer)
-{
- if (xfer->type == XFER_TYPE_CHAT_SEND)
- xfer->status = XFER_STATUS_WAITING;
- else
- xfer->status = XFER_STATUS_CONNECTING;
-
- if (xfer->sock < 0)
- {
- xfer->sock = socket (AF_INET, SOCK_STREAM, 0);
- if (xfer->sock < 0)
- return 0;
- }
-
- /* for chat or file sending, listen to socket for a connection */
- if (XFER_IS_SEND(xfer->type))
- {
- if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
- return 0;
- if (listen (xfer->sock, 1) == -1)
- return 0;
- if (fcntl (xfer->sock, F_SETFL, 0) == -1)
- return 0;
- }
-
- /* for chat receiving, connect to listening host */
- if (xfer->type == XFER_TYPE_CHAT_RECV)
- {
- if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
- return 0;
- weechat_network_connect_to (xfer->sock, xfer->address, xfer->port);
- }
-
- /* for file receiving, connection is made in child process (blocking) */
-
- return 1;
-}
-
-/*
* xfer_network_create_pipe: create pipe for communication with child process
* return 1 if ok, 0 if error
*/
@@ -313,6 +272,239 @@ xfer_network_recv_file_fork (struct t_xfer *xfer)
}
/*
+ * xfer_network_child_kill: kill child process and close pipe
+ */
+
+void
+xfer_network_child_kill (struct t_xfer *xfer)
+{
+ /* kill process */
+ if (xfer->child_pid > 0)
+ {
+ kill (xfer->child_pid, SIGKILL);
+ waitpid (xfer->child_pid, NULL, 0);
+ xfer->child_pid = 0;
+ }
+
+ /* close pipe used with child */
+ if (xfer->child_read != -1)
+ {
+ close (xfer->child_read);
+ xfer->child_read = -1;
+ }
+ if (xfer->child_write != -1)
+ {
+ close (xfer->child_write);
+ xfer->child_write = -1;
+ }
+}
+
+/*
+ * xfer_network_fd_cb: callback called when data is available on xfer socket
+ */
+
+int
+xfer_network_fd_cb (void *arg_xfer)
+{
+ struct t_xfer *xfer;
+ int sock;
+ struct sockaddr_in addr;
+ socklen_t length;
+
+ xfer = (struct t_xfer *)arg_xfer;
+
+ if (xfer->status == XFER_STATUS_CONNECTING)
+ {
+ if (xfer->type == XFER_TYPE_FILE_SEND)
+ {
+ xfer->last_activity = time (NULL);
+ length = sizeof (addr);
+ sock = accept (xfer->sock,
+ (struct sockaddr *) &addr, &length);
+ weechat_unhook (xfer->hook_fd);
+ xfer->hook_fd = NULL;
+ close (xfer->sock);
+ xfer->sock = -1;
+ if (sock < 0)
+ {
+ weechat_printf (NULL,
+ _("%s%s: unable to create socket for sending "
+ "file"),
+ weechat_prefix ("error"), "xfer");
+ xfer_close (xfer, XFER_STATUS_FAILED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ return WEECHAT_RC_OK;
+ }
+ xfer->sock = sock;
+ if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
+ {
+ weechat_printf (NULL,
+ _("%s%s: unable to set option \"nonblock\" "
+ "for socket"),
+ weechat_prefix ("error"), "xfer");
+ xfer_close (xfer, XFER_STATUS_FAILED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ return WEECHAT_RC_OK;
+ }
+ xfer->address = ntohl (addr.sin_addr.s_addr);
+ xfer->status = XFER_STATUS_ACTIVE;
+ xfer->start_transfer = time (NULL);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ xfer_network_send_file_fork (xfer);
+ }
+ /*
+ if (xfer->type == XFER_TYPE_FILE_RECV)
+ {
+ if (xfer->child_read != -1)
+ irc_dcc_file_child_read (dcc);
+ }
+ */
+ }
+
+ if (xfer->status == XFER_STATUS_WAITING)
+ {
+ if (xfer->type == XFER_TYPE_CHAT_SEND)
+ {
+ length = sizeof (addr);
+ sock = accept (xfer->sock, (struct sockaddr *) &addr, &length);
+ weechat_unhook (xfer->hook_fd);
+ xfer->hook_fd = NULL;
+ close (xfer->sock);
+ xfer->sock = -1;
+ if (sock < 0)
+ {
+ weechat_printf (NULL,
+ _("%s%s: unable to create socket for sending "
+ "file"),
+ weechat_prefix ("error"), "xfer");
+ xfer_close (xfer, XFER_STATUS_FAILED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ return WEECHAT_RC_OK;
+ }
+ xfer->sock = sock;
+ if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
+ {
+ weechat_printf (NULL,
+ _("%s%s: unable to set option \"nonblock\" "
+ "for socket"),
+ weechat_prefix ("error"), "xfer");
+ xfer_close (xfer, XFER_STATUS_FAILED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ return WEECHAT_RC_OK;
+ }
+ xfer->address = ntohl (addr.sin_addr.s_addr);
+ xfer->status = XFER_STATUS_ACTIVE;
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ xfer->hook_fd = weechat_hook_fd (xfer->sock,
+ 1, 0, 0,
+ &xfer_chat_recv_cb,
+ xfer);
+ xfer_chat_open_buffer (xfer);
+ }
+ }
+ /*
+ if (xfer->status == XFER_STATUS_ACTIVE)
+ {
+ if (XFER_IS_CHAT(dcc->type))
+ {
+ irc_dcc_chat_recv (dcc);
+ }
+ else
+ irc_dcc_file_child_read (dcc);
+ }
+ */
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_network_timer_cb: callback called to check if there's a timeout for xfer
+ * (called only one time for xfer)
+ */
+
+int
+xfer_network_timer_cb (void *arg_xfer)
+{
+ struct t_xfer *xfer;
+
+ xfer = (struct t_xfer *)arg_xfer;
+
+ if ((xfer->status == XFER_STATUS_WAITING)
+ || (xfer->status == XFER_STATUS_CONNECTING))
+ {
+ weechat_printf (NULL,
+ _("%s%s: timeout for \"%s\" with %s"),
+ weechat_prefix ("error"), "xfer",
+ xfer->filename, xfer->remote_nick);
+ xfer_close (xfer, XFER_STATUS_FAILED);
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
+ * xfer_network_connect: connect to another host
+ */
+
+int
+xfer_network_connect (struct t_xfer *xfer)
+{
+ if (xfer->type == XFER_TYPE_CHAT_SEND)
+ xfer->status = XFER_STATUS_WAITING;
+ else
+ xfer->status = XFER_STATUS_CONNECTING;
+
+ if (xfer->sock < 0)
+ {
+ xfer->sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (xfer->sock < 0)
+ return 0;
+ }
+
+ if (XFER_IS_SEND(xfer->type))
+ {
+ /* listen to socket */
+ if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
+ return 0;
+ if (listen (xfer->sock, 1) == -1)
+ return 0;
+ if (fcntl (xfer->sock, F_SETFL, 0) == -1)
+ return 0;
+
+ xfer->hook_fd = weechat_hook_fd (xfer->sock,
+ 1, 0, 0,
+ &xfer_network_fd_cb,
+ xfer);
+
+ /* add timeout */
+ if (weechat_config_integer (xfer_config_network_timeout) > 0)
+ {
+ xfer->hook_timer = weechat_hook_timer (weechat_config_integer (xfer_config_network_timeout) * 1000,
+ 0, 1,
+ &xfer_network_timer_cb,
+ xfer);
+ }
+ }
+
+ /* for chat receiving, connect to listening host */
+ if (xfer->type == XFER_TYPE_CHAT_RECV)
+ {
+ if (fcntl (xfer->sock, F_SETFL, O_NONBLOCK) == -1)
+ return 0;
+ weechat_network_connect_to (xfer->sock, xfer->address, xfer->port);
+
+ xfer->hook_fd = weechat_hook_fd (xfer->sock,
+ 1, 0, 0,
+ &xfer_chat_recv_cb,
+ xfer);
+ }
+
+ /* for file receiving, connection is made in child process (blocking) */
+
+ return 1;
+}
+
+/*
* xfer_network_connect_init: connect to sender and init file or chat
*/
@@ -336,36 +528,33 @@ xfer_network_connect_init (struct t_xfer *xfer)
{
/* for a chat => associate with buffer */
xfer->status = XFER_STATUS_ACTIVE;
- // TODO: create buffer for xfer chat
+ xfer_chat_open_buffer (xfer);
}
}
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
/*
- * xfer_network_child_kill: kill child process and close pipe
+ * xfer_network_accept: accept a xfer file or chat request
*/
void
-xfer_network_child_kill (struct t_xfer *xfer)
+xfer_network_accept (struct t_xfer *xfer)
{
- /* kill process */
- if (xfer->child_pid > 0)
- {
- kill (xfer->child_pid, SIGKILL);
- waitpid (xfer->child_pid, NULL, 0);
- xfer->child_pid = 0;
- }
-
- /* close pipe used with child */
- if (xfer->child_read != -1)
+ if (XFER_IS_FILE(xfer->type) && (xfer->start_resume > 0))
{
- close (xfer->child_read);
- xfer->child_read = -1;
- }
- if (xfer->child_write != -1)
- {
- close (xfer->child_write);
- xfer->child_write = -1;
+ xfer->status = XFER_STATUS_CONNECTING;
+ xfer_send_signal (xfer, "xfer_accepted");
+ /*
+ irc_server_sendf (dcc->server,
+ (strchr (dcc->filename, ' ')) ?
+ "PRIVMSG %s :\01DCC RESUME \"%s\" %d %u\01\n" :
+ "PRIVMSG %s :\01DCC RESUME %s %d %u\01",
+ dcc->nick, dcc->filename,
+ dcc->port, dcc->start_resume);
+ */
+ xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
+ else
+ xfer_network_connect_init (xfer);
}
diff --git a/src/plugins/xfer/xfer-network.h b/src/plugins/xfer/xfer-network.h
index a542ed542..17b007662 100644
--- a/src/plugins/xfer/xfer-network.h
+++ b/src/plugins/xfer/xfer-network.h
@@ -20,11 +20,12 @@
#ifndef __WEECHAT_XFER_NETWORK_H
#define __WEECHAT_XFER_NETWORK_H 1
-extern int xfer_network_connect (struct t_xfer *xfer);
extern int xfer_network_create_pipe (struct t_xfer *xfer);
extern void xfer_network_write_pipe (struct t_xfer *xfer, int status,
int error);
extern void xfer_network_connect_init (struct t_xfer *xfer);
extern void xfer_network_child_kill (struct t_xfer *xfer);
+extern int xfer_network_connect (struct t_xfer *xfer);
+extern void xfer_network_accept (struct t_xfer *xfer);
#endif /* xfer-network.h */
diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c
index 5df3f2370..86a8cec19 100644
--- a/src/plugins/xfer/xfer.c
+++ b/src/plugins/xfer/xfer.c
@@ -32,6 +32,7 @@
#include "../weechat-plugin.h"
#include "xfer.h"
#include "xfer-buffer.h"
+#include "xfer-command.h"
#include "xfer-config.h"
#include "xfer-file.h"
#include "xfer-network.h"
@@ -64,6 +65,7 @@ char *xfer_status_string[] = /* strings for status */
struct t_xfer *xfer_list = NULL; /* list of files/chats */
struct t_xfer *last_xfer = NULL; /* last file/chat in list */
+int xfer_count = 0; /* number of xfer */
int xfer_debug = 0;
@@ -155,6 +157,114 @@ xfer_search (enum t_xfer_type type, enum t_xfer_status status, int port)
}
/*
+ * xfer_search_by_number: search a xfer by number (first xfer is 0)
+ */
+
+struct t_xfer *
+xfer_search_by_number (int number)
+{
+ struct t_xfer *ptr_xfer;
+ int i;
+
+ i = 0;
+ for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
+ {
+ if (i == number)
+ return ptr_xfer;
+ i++;
+ }
+
+ /* xfer not found */
+ return NULL;
+}
+
+/*
+ * xfer_close: close a xfer
+ */
+
+void
+xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
+{
+ struct stat st;
+
+ xfer->status = status;
+
+ if (XFER_HAS_ENDED(xfer->status))
+ {
+ if (xfer->hook_fd)
+ {
+ weechat_unhook (xfer->hook_fd);
+ xfer->hook_fd = NULL;
+ }
+ if (xfer->hook_timer)
+ {
+ weechat_unhook (xfer->hook_timer);
+ xfer->hook_timer = NULL;
+ }
+ if (XFER_IS_FILE(xfer->type))
+ {
+ weechat_printf (NULL,
+ _("%s%s: file %s %s %s: %s"),
+ (xfer->status == XFER_STATUS_DONE) ?
+ "" : weechat_prefix ("error"),
+ "xfer",
+ xfer->filename,
+ (xfer->type == XFER_TYPE_FILE_SEND) ?
+ _("sent to") : _("received from"),
+ xfer->remote_nick,
+ (xfer->status == XFER_STATUS_DONE) ?
+ _("OK") : _("FAILED"));
+ xfer_network_child_kill (xfer);
+ }
+ }
+ if (xfer->status == XFER_STATUS_ABORTED)
+ {
+ if (XFER_IS_CHAT(xfer->type))
+ {
+ weechat_printf (xfer->buffer,
+ _("%s: chat closed with %s "
+ "(%d.%d.%d.%d)"),
+ "xfer",
+ xfer->remote_nick,
+ xfer->address >> 24,
+ (xfer->address >> 16) & 0xff,
+ (xfer->address >> 8) & 0xff,
+ xfer->address & 0xff);
+ }
+ }
+
+ /* remove empty file if received file failed and nothing was transfered */
+ if (((xfer->status == XFER_STATUS_FAILED)
+ || (xfer->status == XFER_STATUS_ABORTED))
+ && XFER_IS_FILE(xfer->type)
+ && XFER_IS_RECV(xfer->type)
+ && xfer->local_filename
+ && xfer->pos == 0)
+ {
+ /* erase file only if really empty on disk */
+ if (stat (xfer->local_filename, &st) != -1)
+ {
+ if ((unsigned long) st.st_size == 0)
+ unlink (xfer->local_filename);
+ }
+ }
+
+ if (XFER_IS_FILE(xfer->type))
+ xfer_file_calculate_speed (xfer, 1);
+
+ if (xfer->sock >= 0)
+ {
+ close (xfer->sock);
+ xfer->sock = -1;
+ }
+ if (xfer->file >= 0)
+ {
+ close (xfer->file);
+ xfer->file = -1;
+ }
+}
+
+/*
* xfer_port_in_use: return 1 if a port is in used
* (by an active or connecting xfer)
*/
@@ -192,14 +302,18 @@ xfer_send_signal (struct t_xfer *xfer, char *signal)
item = weechat_infolist_new_item (infolist);
if (item)
{
+ weechat_infolist_new_var_string (item, "plugin_name",
+ xfer->plugin_name);
weechat_infolist_new_var_string (item, "plugin_id",
xfer->plugin_id);
weechat_infolist_new_var_string (item, "type",
xfer_type_string[xfer->type]);
weechat_infolist_new_var_string (item, "protocol",
xfer_protocol_string[xfer->protocol]);
- weechat_infolist_new_var_string (item, "nick",
- xfer->nick);
+ weechat_infolist_new_var_string (item, "remote_nick",
+ xfer->remote_nick);
+ weechat_infolist_new_var_string (item, "local_nick",
+ xfer->local_nick);
weechat_infolist_new_var_string (item, "filename",
xfer->filename);
snprintf (str_long, sizeof (str_long), "%lu", xfer->size);
@@ -239,7 +353,8 @@ xfer_alloc ()
new_xfer->size = 0;
new_xfer->address = 0;
new_xfer->port = 0;
- new_xfer->nick = NULL;
+ new_xfer->remote_nick = NULL;
+ new_xfer->local_nick = NULL;
new_xfer->type = 0;
new_xfer->protocol = 0;
@@ -254,6 +369,7 @@ xfer_alloc ()
new_xfer->child_read = -1;
new_xfer->child_write = -1;
new_xfer->hook_fd = NULL;
+ new_xfer->hook_timer = NULL;
new_xfer->unterminated_message = NULL;
new_xfer->file = -1;
new_xfer->local_filename = NULL;
@@ -275,41 +391,19 @@ xfer_alloc ()
last_xfer = new_xfer;
xfer_list = new_xfer;
+ xfer_count++;
+
return new_xfer;
}
/*
- * xfer_accept: accept a xfer file or chat request
- */
-
-void
-xfer_accept (struct t_xfer *xfer)
-{
- if (XFER_IS_FILE(xfer->type) && (xfer->start_resume > 0))
- {
- xfer->status = XFER_STATUS_CONNECTING;
- xfer_send_signal (xfer, "xfer_accepted");
- /*
- irc_server_sendf (dcc->server,
- (strchr (dcc->filename, ' ')) ?
- "PRIVMSG %s :\01DCC RESUME \"%s\" %d %u\01\n" :
- "PRIVMSG %s :\01DCC RESUME %s %d %u\01",
- dcc->nick, dcc->filename,
- dcc->port, dcc->start_resume);
- */
- xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
- }
- else
- xfer_network_connect_init (xfer);
-}
-
-/*
* xfer_new: add a xfer to list
*/
struct t_xfer *
-xfer_new (char *plugin_id, enum t_xfer_type type,
- enum t_xfer_protocol protocol, char *nick, char *filename,
+xfer_new (char *plugin_name, char *plugin_id, enum t_xfer_type type,
+ enum t_xfer_protocol protocol, char *remote_nick, char *local_nick,
+ char *filename,
unsigned long size, unsigned long address, int port, int sock,
char *local_filename)
{
@@ -331,12 +425,16 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
}
/* initialize new xfer */
+ new_xfer->plugin_name = strdup (plugin_name);
new_xfer->plugin_id = strdup (plugin_id);
new_xfer->type = type;
new_xfer->protocol = protocol;
- new_xfer->nick = strdup (nick);
+ new_xfer->remote_nick = strdup (remote_nick);
+ new_xfer->local_nick = (local_nick) ? strdup (local_nick) : NULL;
if (XFER_IS_FILE(type))
new_xfer->filename = (filename) ? strdup (filename) : NULL;
+ else
+ new_xfer->filename = strdup (_("xfer chat"));
new_xfer->size = size;
new_xfer->address = address;
new_xfer->port = port;
@@ -356,7 +454,7 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
_("%s: incoming file from %s "
"(%d.%d.%d.%d): %s, %lu bytes (protocol: %s)"),
"xfer",
- nick,
+ remote_nick,
address >> 24,
(address >> 16) & 0xff,
(address >> 8) & 0xff,
@@ -371,7 +469,7 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
_("%s: sending file to %s: %s "
"(local filename: %s), %lu bytes (protocol: %s)"),
"xfer",
- nick,
+ remote_nick,
filename,
local_filename,
size,
@@ -383,7 +481,7 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
_("%s: incoming chat request from %s "
"(%d.%d.%d.%d)"),
"xfer",
- nick,
+ remote_nick,
address >> 24,
(address >> 16) & 0xff,
(address >> 8) & 0xff,
@@ -394,7 +492,7 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
weechat_printf (NULL,
_("%s: sending chat request to %s"),
"xfer",
- nick);
+ remote_nick);
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
break;
case XFER_NUM_TYPES:
@@ -431,11 +529,11 @@ xfer_new (char *plugin_id, enum t_xfer_type type,
}
}
- if ( ( (type == XFER_TYPE_CHAT_RECV)
- && (weechat_config_boolean (xfer_config_file_auto_accept_chats)) )
- || ( (type == XFER_TYPE_FILE_RECV)
- && (weechat_config_boolean (xfer_config_file_auto_accept_files)) ) )
- xfer_accept (new_xfer);
+ if ( ( (type == XFER_TYPE_FILE_RECV)
+ && (weechat_config_boolean (xfer_config_file_auto_accept_files)) )
+ || ( (type == XFER_TYPE_CHAT_RECV)
+ && (weechat_config_boolean (xfer_config_file_auto_accept_chats)) ) )
+ xfer_network_accept (new_xfer);
else
xfer_buffer_refresh (WEECHAT_HOTLIST_PRIVATE);
@@ -454,10 +552,9 @@ xfer_free (struct t_xfer *xfer)
if (!xfer)
return;
- /* close chat buffer */
if (xfer->buffer)
{
- /* TODO: close chat buffer */
+ weechat_buffer_close (xfer->buffer, 1);
}
/* remove xfer from list */
@@ -472,12 +569,14 @@ xfer_free (struct t_xfer *xfer)
new_xfer_list = xfer->next_xfer;
if (xfer->next_xfer)
(xfer->next_xfer)->prev_xfer = xfer->prev_xfer;
-
+
/* free data */
if (xfer->plugin_id)
free (xfer->plugin_id);
- if (xfer->nick)
- free (xfer->nick);
+ if (xfer->remote_nick)
+ free (xfer->remote_nick);
+ if (xfer->local_nick)
+ free (xfer->local_nick);
if (xfer->filename)
free (xfer->filename);
if (xfer->unterminated_message)
@@ -488,80 +587,10 @@ xfer_free (struct t_xfer *xfer)
free (xfer);
xfer_list = new_xfer_list;
-}
-
-/*
- * xfer_close: close a xfer
- */
-
-void
-xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
-{
- struct stat st;
-
- xfer->status = status;
-
- if (XFER_HAS_ENDED(xfer->status))
- {
- if (XFER_IS_FILE(xfer->type))
- {
- weechat_printf (NULL,
- _("%s: file %s %s %s: %s"),
- "xfer",
- xfer->filename,
- (xfer->type == XFER_TYPE_FILE_SEND) ?
- _("sent to") : _("received from"),
- xfer->nick,
- (xfer->status == XFER_STATUS_DONE) ?
- _("OK") : _("FAILED"));
- xfer_network_child_kill (xfer);
- }
- }
- if (xfer->status == XFER_STATUS_ABORTED)
- {
- if (XFER_IS_CHAT(xfer->type))
- {
- weechat_printf (xfer->buffer,
- _("%s: chat closed with %s "
- "(%d.%d.%d.%d)"),
- "xfer",
- xfer->nick,
- xfer->address >> 24,
- (xfer->address >> 16) & 0xff,
- (xfer->address >> 8) & 0xff,
- xfer->address & 0xff);
- }
- }
- /* remove empty file if received file failed and nothing was transfered */
- if (((xfer->status == XFER_STATUS_FAILED)
- || (xfer->status == XFER_STATUS_ABORTED))
- && XFER_IS_FILE(xfer->type)
- && XFER_IS_RECV(xfer->type)
- && xfer->local_filename
- && xfer->pos == 0)
- {
- /* erase file only if really empty on disk */
- if (stat (xfer->local_filename, &st) != -1)
- {
- if ((unsigned long) st.st_size == 0)
- unlink (xfer->local_filename);
- }
- }
-
- if (XFER_IS_FILE(xfer->type))
- xfer_file_calculate_speed (xfer, 1);
-
- if (xfer->sock >= 0)
- {
- close (xfer->sock);
- xfer->sock = -1;
- }
- if (xfer->file >= 0)
- {
- close (xfer->file);
- xfer->file = -1;
- }
+ xfer_count--;
+ if (xfer_buffer_selected_line >= xfer_count)
+ xfer_buffer_selected_line = (xfer_count == 0) ? 0 : xfer_count - 1;
}
/*
@@ -572,7 +601,8 @@ int
xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
{
struct t_plugin_infolist *infolist;
- char *plugin_id, *str_type, *nick, *filename, *str_protocol;
+ char *plugin_name, *plugin_id, *str_type, *str_protocol;
+ char *remote_nick, *local_nick, *filename;
int type, protocol;
char *weechat_dir, *dir1, *dir2, *filename2, *short_filename, *pos;
int spaces, args, port_start, port_end;
@@ -612,14 +642,16 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
return WEECHAT_RC_ERROR;
}
+ plugin_name = weechat_infolist_string (infolist, "plugin_name");
plugin_id = weechat_infolist_string (infolist, "plugin_id");
str_type = weechat_infolist_string (infolist, "type");
- nick = weechat_infolist_string (infolist, "nick");
- filename = weechat_infolist_string (infolist, "filename");
str_protocol = weechat_infolist_string (infolist, "protocol");
+ remote_nick = weechat_infolist_string (infolist, "remote_nick");
+ local_nick = weechat_infolist_string (infolist, "local_nick");
+ filename = weechat_infolist_string (infolist, "filename");
protocol = XFER_NO_PROTOCOL;
- if (!plugin_id || !str_type || !nick)
+ if (!plugin_name || !plugin_id || !str_type || !remote_nick || !local_nick)
{
weechat_printf (NULL,
_("%s%s: missing arguments"),
@@ -636,19 +668,11 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
return WEECHAT_RC_ERROR;
}
- if (XFER_IS_FILE(type) && !filename)
+ if (XFER_IS_FILE(type) && (!filename || !str_protocol))
{
weechat_printf (NULL,
- _("%s%s: filename missing for type \"%s\""),
- weechat_prefix ("error"), "xfer", str_type);
- return WEECHAT_RC_ERROR;
- }
-
- if (XFER_IS_FILE(type) && !str_protocol)
- {
- weechat_printf (NULL,
- _("%s%s: protocol missing for type \"%s\""),
- weechat_prefix ("error"), "xfer", str_type);
+ _("%s%s: missing arguments"),
+ weechat_prefix ("error"), "xfer");
return WEECHAT_RC_ERROR;
}
@@ -670,11 +694,10 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
if (type == XFER_TYPE_FILE_RECV)
{
- filename2 = weechat_infolist_string (infolist, "filename");
+ filename2 = strdup (filename);
sscanf (weechat_infolist_string (infolist, "size"), "%lu", &file_size);
- port = weechat_infolist_integer (infolist, "port");
}
-
+
if (type == XFER_TYPE_FILE_SEND)
{
/* add home if filename not beginning with '/' or '~' (not for Win32) */
@@ -744,7 +767,7 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
if (XFER_IS_RECV(type))
{
sscanf (weechat_infolist_string (infolist, "address"), "%lu", &local_addr);
- sscanf (weechat_infolist_string (infolist, "size"), "%lu", &file_size);
+ port = weechat_infolist_integer (infolist, "port");
}
else
{
@@ -848,7 +871,7 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
}
}
- if (type == XFER_TYPE_FILE_SEND)
+ if (XFER_IS_FILE(type))
{
/* extract short filename (without path) */
pos = strrchr (filename2, DIR_SEPARATOR_CHAR);
@@ -872,14 +895,25 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
pos++;
}
}
+
+ if (type == XFER_TYPE_FILE_RECV)
+ {
+ if (filename2)
+ {
+ free (filename2);
+ filename2 = NULL;
+ }
+ }
/* add xfer entry and listen to socket if type is file or chat "send" */
if (XFER_IS_FILE(type))
- ptr_xfer = xfer_new (plugin_id, type, protocol, nick, short_filename,
+ ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
+ remote_nick, local_nick, short_filename,
file_size, local_addr, port, sock, filename2);
else
- ptr_xfer = xfer_new (plugin_id, type, protocol, nick, NULL, 0,
- local_addr, port, sock, NULL);
+ ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol,
+ remote_nick, local_nick, NULL, 0, local_addr,
+ port, sock, NULL);
if (!ptr_xfer)
{
@@ -896,7 +930,8 @@ xfer_add_cb (void *data, char *signal, char *type_data, void *signal_data)
}
/* send signal if type is file or chat "send" */
- xfer_send_signal (ptr_xfer, "xfer_send_ready");
+ if (XFER_IS_SEND(ptr_xfer->type))
+ xfer_send_signal (ptr_xfer, "xfer_send_ready");
if (short_filename)
free (short_filename);
@@ -919,11 +954,13 @@ xfer_print_log ()
{
weechat_log_printf ("");
weechat_log_printf ("[xfer (addr:0x%x)]", ptr_xfer);
+ weechat_log_printf (" plugin_name . . . . : '%s'", ptr_xfer->plugin_name);
weechat_log_printf (" plugin_id . . . . . : '%s'", ptr_xfer->plugin_id);
weechat_log_printf (" type. . . . . . . . : %d (%s)",
ptr_xfer->type,
xfer_type_string[ptr_xfer->type]);
- weechat_log_printf (" nick. . . . . . . . : '%s'", ptr_xfer->nick);
+ weechat_log_printf (" remote_nick . . . . : '%s'", ptr_xfer->remote_nick);
+ 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 (" address . . . . . . : %lu", ptr_xfer->address);
@@ -1002,6 +1039,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin)
xfer_create_directories ();
+ xfer_command_init ();
+
weechat_hook_signal ("xfer_add", &xfer_add_cb, NULL);
weechat_hook_signal ("debug_dump", &xfer_debug_dump_cb, NULL);
@@ -1029,10 +1068,10 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
weechat_printf (NULL,
_("%s%s: aborting active xfer: \"%s\" from %s"),
weechat_prefix ("error"), "xfer",
- ptr_xfer->filename, ptr_xfer->nick);
- weechat_log_printf (_("%s: aborting active xfer: \"%s\" from %s"),
- "xfer",
- ptr_xfer->filename, ptr_xfer->nick);
+ ptr_xfer->filename, ptr_xfer->remote_nick);
+ weechat_log_printf (_("%s%s: aborting active xfer: \"%s\" from %s"),
+ "", "xfer",
+ ptr_xfer->filename, ptr_xfer->remote_nick);
}
xfer_close (ptr_xfer, XFER_STATUS_FAILED);
}
diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h
index ac580d5a4..a357fbefa 100644
--- a/src/plugins/xfer/xfer.h
+++ b/src/plugins/xfer/xfer.h
@@ -106,10 +106,12 @@ enum t_xfer_error
struct t_xfer
{
/* data received by xfer to initiate a transfer */
- char *plugin_id; /* plugin identifier */
+ char *plugin_name; /* plugin name */
+ char *plugin_id; /* id used by plugin */
enum t_xfer_type type; /* xfer type (send/recv file) */
enum t_xfer_protocol protocol; /* xfer protocol (for file transfer) */
- char *nick; /* remote nick */
+ char *remote_nick; /* remote nick */
+ char *local_nick; /* local nick */
char *filename; /* filename */
unsigned long size; /* file size */
unsigned long address; /* local or remote IP address */
@@ -127,6 +129,7 @@ struct t_xfer
int child_read; /* to read into child pipe */
int child_write; /* to write into child pipe */
struct t_hook *hook_fd; /* hook for socket or child pipe */
+ struct t_hook *hook_timer; /* timeout for recever accept */
char *unterminated_message; /* beginning of a message */
int file; /* local file (read or write) */
char *local_filename; /* local filename (with path) */
@@ -148,9 +151,12 @@ extern char *xfer_type_string[];
extern char *xfer_protocol_string[];
extern char *xfer_status_string[];
extern struct t_xfer *xfer_list, *last_xfer;
+extern int xfer_count;
extern int xfer_debug;
+extern struct t_xfer *xfer_search_by_number (int number);
extern void xfer_close (struct t_xfer *xfer, enum t_xfer_status status);
-extern struct t_xfer *xfer_alloc ();
+extern void xfer_send_signal (struct t_xfer *xfer, char *signal);
+extern void xfer_free (struct t_xfer *xfer);
#endif /* xfer.h */