mirror of
https://github.com/weechat/weechat.git
synced 2026-06-28 22:06:38 +02:00
IRC DCC chat and file (without resume) reintroduced, via xfer plugin (called by /dcc command)
This commit is contained in:
@@ -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);
|
||||
|
||||
+1
-174
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
type = weechat_infolist_string (infolist, "type");
|
||||
if (type)
|
||||
{
|
||||
if (ptr_server == server)
|
||||
break;
|
||||
}
|
||||
if (ptr_server)
|
||||
{
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3290,6 +3290,42 @@ weechat_lua_api_buffer_search (lua_State *L)
|
||||
LUA_RETURN_STRING_FREE(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 },
|
||||
|
||||
@@ -2750,6 +2750,34 @@ static XS (XS_weechat_buffer_search)
|
||||
PERL_RETURN_STRING_FREE(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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");
|
||||
|
||||
@@ -2918,6 +2918,37 @@ weechat_python_api_buffer_search (PyObject *self, PyObject *args)
|
||||
PYTHON_RETURN_STRING_FREE(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, "" },
|
||||
|
||||
@@ -3348,6 +3348,41 @@ weechat_ruby_api_buffer_search (VALUE class, VALUE category, VALUE name)
|
||||
RUBY_RETURN_STRING_FREE(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
+252
-50
@@ -21,17 +21,262 @@
|
||||
|
||||
#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;
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
xfer = (struct t_xfer *)arg_xfer;
|
||||
|
||||
/* something to read on socket? */
|
||||
if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) <= 0)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-dcc.h"
|
||||
#include "xfer-network.h"
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+263
-74
@@ -28,58 +28,17 @@
|
||||
#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
|
||||
@@ -312,36 +271,6 @@ xfer_network_recv_file_fork (struct t_xfer *xfer)
|
||||
xfer);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_connect_init: connect to sender and init file or chat
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_connect_init (struct t_xfer *xfer)
|
||||
{
|
||||
if (!xfer_network_connect (xfer))
|
||||
{
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for a file: launch child process */
|
||||
if (XFER_IS_FILE(xfer->type))
|
||||
{
|
||||
xfer->status = XFER_STATUS_CONNECTING;
|
||||
xfer_network_recv_file_fork (xfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for a chat => associate with buffer */
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
// TODO: create buffer for xfer chat
|
||||
}
|
||||
}
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_child_kill: kill child process and close pipe
|
||||
*/
|
||||
@@ -369,3 +298,263 @@ xfer_network_child_kill (struct t_xfer *xfer)
|
||||
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
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_connect_init (struct t_xfer *xfer)
|
||||
{
|
||||
if (!xfer_network_connect (xfer))
|
||||
{
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for a file: launch child process */
|
||||
if (XFER_IS_FILE(xfer->type))
|
||||
{
|
||||
xfer->status = XFER_STATUS_CONNECTING;
|
||||
xfer_network_recv_file_fork (xfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for a chat => associate with buffer */
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer_chat_open_buffer (xfer);
|
||||
}
|
||||
}
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_accept: accept a xfer file or chat request
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+395
-356
@@ -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,339 +157,25 @@ xfer_search (enum t_xfer_type type, enum t_xfer_status status, int port)
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_port_in_use: return 1 if a port is in used
|
||||
* (by an active or connecting xfer)
|
||||
* xfer_search_by_number: search a xfer by number (first xfer is 0)
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_port_in_use (int port)
|
||||
struct t_xfer *
|
||||
xfer_search_by_number (int number)
|
||||
{
|
||||
struct t_xfer *ptr_xfer;
|
||||
int i;
|
||||
|
||||
/* skip any currently used ports */
|
||||
i = 0;
|
||||
for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
|
||||
{
|
||||
if ((ptr_xfer->port == port) && (!XFER_HAS_ENDED(ptr_xfer->status)))
|
||||
return 1;
|
||||
if (i == number)
|
||||
return ptr_xfer;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* port not in use */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_send_signal: send a signal for a xfer
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_send_signal (struct t_xfer *xfer, char *signal)
|
||||
{
|
||||
struct t_plugin_infolist *infolist;
|
||||
struct t_plugin_infolist_item *item;
|
||||
char str_long[128];
|
||||
|
||||
infolist = weechat_infolist_new ();
|
||||
if (infolist)
|
||||
{
|
||||
item = weechat_infolist_new_item (infolist);
|
||||
if (item)
|
||||
{
|
||||
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, "filename",
|
||||
xfer->filename);
|
||||
snprintf (str_long, sizeof (str_long), "%lu", xfer->size);
|
||||
weechat_infolist_new_var_string (item, "size",
|
||||
str_long);
|
||||
snprintf (str_long, sizeof (str_long), "%lu", xfer->address);
|
||||
weechat_infolist_new_var_string (item, "address",
|
||||
str_long);
|
||||
weechat_infolist_new_var_integer (item, "port",
|
||||
xfer->port);
|
||||
|
||||
weechat_hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_POINTER,
|
||||
infolist);
|
||||
}
|
||||
weechat_infolist_free (infolist);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_alloc: allocate a new xfer
|
||||
*/
|
||||
|
||||
struct t_xfer *
|
||||
xfer_alloc ()
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
time_t time_now;
|
||||
|
||||
/* create new xfer struct */
|
||||
if ((new_xfer = malloc (sizeof (*new_xfer))) == NULL)
|
||||
return NULL;
|
||||
|
||||
time_now = time (NULL);
|
||||
|
||||
/* default values */
|
||||
new_xfer->filename = NULL;
|
||||
new_xfer->size = 0;
|
||||
new_xfer->address = 0;
|
||||
new_xfer->port = 0;
|
||||
new_xfer->nick = NULL;
|
||||
|
||||
new_xfer->type = 0;
|
||||
new_xfer->protocol = 0;
|
||||
new_xfer->status = 0;
|
||||
new_xfer->buffer = NULL;
|
||||
new_xfer->fast_send = weechat_config_boolean (xfer_config_network_fast_send);
|
||||
new_xfer->blocksize = weechat_config_integer (xfer_config_network_blocksize);
|
||||
new_xfer->start_time = time_now;
|
||||
new_xfer->start_transfer = time_now;
|
||||
new_xfer->sock = -1;
|
||||
new_xfer->child_pid = 0;
|
||||
new_xfer->child_read = -1;
|
||||
new_xfer->child_write = -1;
|
||||
new_xfer->hook_fd = NULL;
|
||||
new_xfer->unterminated_message = NULL;
|
||||
new_xfer->file = -1;
|
||||
new_xfer->local_filename = NULL;
|
||||
new_xfer->filename_suffix = -1;
|
||||
new_xfer->pos = 0;
|
||||
new_xfer->ack = 0;
|
||||
new_xfer->start_resume = 0;
|
||||
new_xfer->last_check_time = time_now;
|
||||
new_xfer->last_check_pos = time_now;
|
||||
new_xfer->last_activity = 0;
|
||||
new_xfer->bytes_per_sec = 0;
|
||||
new_xfer->eta = 0;
|
||||
|
||||
new_xfer->prev_xfer = NULL;
|
||||
new_xfer->next_xfer = xfer_list;
|
||||
if (xfer_list)
|
||||
xfer_list->prev_xfer = new_xfer;
|
||||
else
|
||||
last_xfer = new_xfer;
|
||||
xfer_list = new_xfer;
|
||||
|
||||
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,
|
||||
unsigned long size, unsigned long address, int port, int sock,
|
||||
char *local_filename)
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
|
||||
new_xfer = xfer_alloc ();
|
||||
if (!new_xfer)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: not enough memory for new xfer"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!xfer_buffer
|
||||
&& weechat_config_boolean (xfer_config_look_auto_open_buffer))
|
||||
{
|
||||
xfer_buffer_open ();
|
||||
}
|
||||
|
||||
/* initialize new xfer */
|
||||
new_xfer->plugin_id = strdup (plugin_id);
|
||||
new_xfer->type = type;
|
||||
new_xfer->protocol = protocol;
|
||||
new_xfer->nick = strdup (nick);
|
||||
if (XFER_IS_FILE(type))
|
||||
new_xfer->filename = (filename) ? strdup (filename) : NULL;
|
||||
new_xfer->size = size;
|
||||
new_xfer->address = address;
|
||||
new_xfer->port = port;
|
||||
|
||||
new_xfer->status = XFER_STATUS_WAITING;
|
||||
new_xfer->sock = sock;
|
||||
if (local_filename)
|
||||
new_xfer->local_filename = strdup (local_filename);
|
||||
else
|
||||
xfer_file_find_filename (new_xfer);
|
||||
|
||||
/* write info message on server buffer */
|
||||
switch (type)
|
||||
{
|
||||
case XFER_TYPE_FILE_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming file from %s "
|
||||
"(%d.%d.%d.%d): %s, %lu bytes (protocol: %s)"),
|
||||
"xfer",
|
||||
nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff,
|
||||
filename,
|
||||
size,
|
||||
xfer_protocol_string[protocol]);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_FILE_SEND:
|
||||
weechat_printf (NULL,
|
||||
_("%s: sending file to %s: %s "
|
||||
"(local filename: %s), %lu bytes (protocol: %s)"),
|
||||
"xfer",
|
||||
nick,
|
||||
filename,
|
||||
local_filename,
|
||||
size,
|
||||
xfer_protocol_string[protocol]);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_CHAT_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming chat request from %s "
|
||||
"(%d.%d.%d.%d)"),
|
||||
"xfer",
|
||||
nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_CHAT_SEND:
|
||||
weechat_printf (NULL,
|
||||
_("%s: sending chat request to %s"),
|
||||
"xfer",
|
||||
nick);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
|
||||
if (XFER_IS_FILE(type) && (!new_xfer->local_filename))
|
||||
{
|
||||
xfer_close (new_xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (XFER_IS_FILE(type) && (new_xfer->start_resume > 0))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s: file %s (local filename: %s) "
|
||||
"will be resumed at position %u"),
|
||||
"xfer",
|
||||
new_xfer->filename,
|
||||
new_xfer->local_filename,
|
||||
new_xfer->start_resume);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
|
||||
/* connect if needed and display again xfer buffer */
|
||||
if (XFER_IS_SEND(type))
|
||||
{
|
||||
if (!xfer_network_connect (new_xfer))
|
||||
{
|
||||
xfer_close (new_xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_PRIVATE);
|
||||
|
||||
return new_xfer;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_free: free xfer struct and remove it from list
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_free (struct t_xfer *xfer)
|
||||
{
|
||||
struct t_xfer *new_xfer_list;
|
||||
|
||||
if (!xfer)
|
||||
return;
|
||||
|
||||
/* close chat buffer */
|
||||
if (xfer->buffer)
|
||||
{
|
||||
/* TODO: close chat buffer */
|
||||
}
|
||||
|
||||
/* remove xfer from list */
|
||||
if (last_xfer == xfer)
|
||||
last_xfer = xfer->prev_xfer;
|
||||
if (xfer->prev_xfer)
|
||||
{
|
||||
(xfer->prev_xfer)->next_xfer = xfer->next_xfer;
|
||||
new_xfer_list = xfer_list;
|
||||
}
|
||||
else
|
||||
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->filename)
|
||||
free (xfer->filename);
|
||||
if (xfer->unterminated_message)
|
||||
free (xfer->unterminated_message);
|
||||
if (xfer->local_filename)
|
||||
free (xfer->local_filename);
|
||||
|
||||
free (xfer);
|
||||
|
||||
xfer_list = new_xfer_list;
|
||||
/* xfer not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -503,15 +191,27 @@ xfer_close (struct t_xfer *xfer, enum t_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: file %s %s %s: %s"),
|
||||
_("%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->nick,
|
||||
xfer->remote_nick,
|
||||
(xfer->status == XFER_STATUS_DONE) ?
|
||||
_("OK") : _("FAILED"));
|
||||
xfer_network_child_kill (xfer);
|
||||
@@ -525,7 +225,7 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
|
||||
_("%s: chat closed with %s "
|
||||
"(%d.%d.%d.%d)"),
|
||||
"xfer",
|
||||
xfer->nick,
|
||||
xfer->remote_nick,
|
||||
xfer->address >> 24,
|
||||
(xfer->address >> 16) & 0xff,
|
||||
(xfer->address >> 8) & 0xff,
|
||||
@@ -564,6 +264,335 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_port_in_use: return 1 if a port is in used
|
||||
* (by an active or connecting xfer)
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_port_in_use (int port)
|
||||
{
|
||||
struct t_xfer *ptr_xfer;
|
||||
|
||||
/* skip any currently used ports */
|
||||
for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
|
||||
{
|
||||
if ((ptr_xfer->port == port) && (!XFER_HAS_ENDED(ptr_xfer->status)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* port not in use */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_send_signal: send a signal for a xfer
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_send_signal (struct t_xfer *xfer, char *signal)
|
||||
{
|
||||
struct t_plugin_infolist *infolist;
|
||||
struct t_plugin_infolist_item *item;
|
||||
char str_long[128];
|
||||
|
||||
infolist = weechat_infolist_new ();
|
||||
if (infolist)
|
||||
{
|
||||
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, "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);
|
||||
weechat_infolist_new_var_string (item, "size",
|
||||
str_long);
|
||||
snprintf (str_long, sizeof (str_long), "%lu", xfer->address);
|
||||
weechat_infolist_new_var_string (item, "address",
|
||||
str_long);
|
||||
weechat_infolist_new_var_integer (item, "port",
|
||||
xfer->port);
|
||||
|
||||
weechat_hook_signal_send (signal, WEECHAT_HOOK_SIGNAL_POINTER,
|
||||
infolist);
|
||||
}
|
||||
weechat_infolist_free (infolist);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_alloc: allocate a new xfer
|
||||
*/
|
||||
|
||||
struct t_xfer *
|
||||
xfer_alloc ()
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
time_t time_now;
|
||||
|
||||
/* create new xfer struct */
|
||||
if ((new_xfer = malloc (sizeof (*new_xfer))) == NULL)
|
||||
return NULL;
|
||||
|
||||
time_now = time (NULL);
|
||||
|
||||
/* default values */
|
||||
new_xfer->filename = NULL;
|
||||
new_xfer->size = 0;
|
||||
new_xfer->address = 0;
|
||||
new_xfer->port = 0;
|
||||
new_xfer->remote_nick = NULL;
|
||||
new_xfer->local_nick = NULL;
|
||||
|
||||
new_xfer->type = 0;
|
||||
new_xfer->protocol = 0;
|
||||
new_xfer->status = 0;
|
||||
new_xfer->buffer = NULL;
|
||||
new_xfer->fast_send = weechat_config_boolean (xfer_config_network_fast_send);
|
||||
new_xfer->blocksize = weechat_config_integer (xfer_config_network_blocksize);
|
||||
new_xfer->start_time = time_now;
|
||||
new_xfer->start_transfer = time_now;
|
||||
new_xfer->sock = -1;
|
||||
new_xfer->child_pid = 0;
|
||||
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;
|
||||
new_xfer->filename_suffix = -1;
|
||||
new_xfer->pos = 0;
|
||||
new_xfer->ack = 0;
|
||||
new_xfer->start_resume = 0;
|
||||
new_xfer->last_check_time = time_now;
|
||||
new_xfer->last_check_pos = time_now;
|
||||
new_xfer->last_activity = 0;
|
||||
new_xfer->bytes_per_sec = 0;
|
||||
new_xfer->eta = 0;
|
||||
|
||||
new_xfer->prev_xfer = NULL;
|
||||
new_xfer->next_xfer = xfer_list;
|
||||
if (xfer_list)
|
||||
xfer_list->prev_xfer = new_xfer;
|
||||
else
|
||||
last_xfer = new_xfer;
|
||||
xfer_list = new_xfer;
|
||||
|
||||
xfer_count++;
|
||||
|
||||
return new_xfer;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_new: add a xfer to list
|
||||
*/
|
||||
|
||||
struct t_xfer *
|
||||
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)
|
||||
{
|
||||
struct t_xfer *new_xfer;
|
||||
|
||||
new_xfer = xfer_alloc ();
|
||||
if (!new_xfer)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: not enough memory for new xfer"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!xfer_buffer
|
||||
&& weechat_config_boolean (xfer_config_look_auto_open_buffer))
|
||||
{
|
||||
xfer_buffer_open ();
|
||||
}
|
||||
|
||||
/* 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->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;
|
||||
|
||||
new_xfer->status = XFER_STATUS_WAITING;
|
||||
new_xfer->sock = sock;
|
||||
if (local_filename)
|
||||
new_xfer->local_filename = strdup (local_filename);
|
||||
else
|
||||
xfer_file_find_filename (new_xfer);
|
||||
|
||||
/* write info message on server buffer */
|
||||
switch (type)
|
||||
{
|
||||
case XFER_TYPE_FILE_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming file from %s "
|
||||
"(%d.%d.%d.%d): %s, %lu bytes (protocol: %s)"),
|
||||
"xfer",
|
||||
remote_nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff,
|
||||
filename,
|
||||
size,
|
||||
xfer_protocol_string[protocol]);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_FILE_SEND:
|
||||
weechat_printf (NULL,
|
||||
_("%s: sending file to %s: %s "
|
||||
"(local filename: %s), %lu bytes (protocol: %s)"),
|
||||
"xfer",
|
||||
remote_nick,
|
||||
filename,
|
||||
local_filename,
|
||||
size,
|
||||
xfer_protocol_string[protocol]);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_CHAT_RECV:
|
||||
weechat_printf (NULL,
|
||||
_("%s: incoming chat request from %s "
|
||||
"(%d.%d.%d.%d)"),
|
||||
"xfer",
|
||||
remote_nick,
|
||||
address >> 24,
|
||||
(address >> 16) & 0xff,
|
||||
(address >> 8) & 0xff,
|
||||
address & 0xff);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_TYPE_CHAT_SEND:
|
||||
weechat_printf (NULL,
|
||||
_("%s: sending chat request to %s"),
|
||||
"xfer",
|
||||
remote_nick);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
|
||||
if (XFER_IS_FILE(type) && (!new_xfer->local_filename))
|
||||
{
|
||||
xfer_close (new_xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (XFER_IS_FILE(type) && (new_xfer->start_resume > 0))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s: file %s (local filename: %s) "
|
||||
"will be resumed at position %u"),
|
||||
"xfer",
|
||||
new_xfer->filename,
|
||||
new_xfer->local_filename,
|
||||
new_xfer->start_resume);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
|
||||
/* connect if needed and display again xfer buffer */
|
||||
if (XFER_IS_SEND(type))
|
||||
{
|
||||
if (!xfer_network_connect (new_xfer))
|
||||
{
|
||||
xfer_close (new_xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return new_xfer;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_free: free xfer struct and remove it from list
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_free (struct t_xfer *xfer)
|
||||
{
|
||||
struct t_xfer *new_xfer_list;
|
||||
|
||||
if (!xfer)
|
||||
return;
|
||||
|
||||
if (xfer->buffer)
|
||||
{
|
||||
weechat_buffer_close (xfer->buffer, 1);
|
||||
}
|
||||
|
||||
/* remove xfer from list */
|
||||
if (last_xfer == xfer)
|
||||
last_xfer = xfer->prev_xfer;
|
||||
if (xfer->prev_xfer)
|
||||
{
|
||||
(xfer->prev_xfer)->next_xfer = xfer->next_xfer;
|
||||
new_xfer_list = xfer_list;
|
||||
}
|
||||
else
|
||||
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->remote_nick)
|
||||
free (xfer->remote_nick);
|
||||
if (xfer->local_nick)
|
||||
free (xfer->local_nick);
|
||||
if (xfer->filename)
|
||||
free (xfer->filename);
|
||||
if (xfer->unterminated_message)
|
||||
free (xfer->unterminated_message);
|
||||
if (xfer->local_filename)
|
||||
free (xfer->local_filename);
|
||||
|
||||
free (xfer);
|
||||
|
||||
xfer_list = new_xfer_list;
|
||||
|
||||
xfer_count--;
|
||||
if (xfer_buffer_selected_line >= xfer_count)
|
||||
xfer_buffer_selected_line = (xfer_count == 0) ? 0 : xfer_count - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_add_cb: callback for "xfer_add" signal
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user