mirror of
https://github.com/weechat/weechat.git
synced 2026-07-02 15:53:12 +02:00
Added new plugin "xfer" (used by irc plugin for DCC file and chat) (warning: initial commit, not working yet)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Copyright (c) 2003-2008 FlashCode <flashcode@flashtux.org>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
ADD_LIBRARY(xfer MODULE
|
||||
xfer.c xfer.h
|
||||
xfer-buffer.c xfer-buffer.h
|
||||
xfer-chat.c xfer-chat.h
|
||||
xfer-config.c xfer-config.h
|
||||
xfer-dcc.c xfer-dcc.h
|
||||
xfer-file.c xfer-file.h
|
||||
xfer-network.c xfer-network.h)
|
||||
SET_TARGET_PROPERTIES(xfer PROPERTIES PREFIX "")
|
||||
|
||||
TARGET_LINK_LIBRARIES(xfer)
|
||||
|
||||
INSTALL(TARGETS xfer LIBRARY DESTINATION lib/${PROJECT_NAME}/plugins)
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2003-2008 FlashCode <flashcode@flashtux.org>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
|
||||
libdir = ${weechat_libdir}/plugins
|
||||
|
||||
lib_LTLIBRARIES = xfer.la
|
||||
|
||||
xfer_la_SOURCES = xfer.c \
|
||||
xfer.h \
|
||||
xfer-buffer.c \
|
||||
xfer-buffer.h \
|
||||
xfer-chat.c \
|
||||
xfer-chat.h \
|
||||
xfer-config.c \
|
||||
xfer-config.h \
|
||||
xfer-dcc.c \
|
||||
xfer-dcc.h \
|
||||
xfer-file.c \
|
||||
xfer-file.h \
|
||||
xfer-network.c \
|
||||
xfer-network.h
|
||||
|
||||
xfer_la_LDFLAGS = -module
|
||||
xfer_la_LIBADD = $(XFER_LFLAGS)
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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-buffer.c: display xfer list on xfer buffer */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-buffer.h"
|
||||
#include "xfer-config.h"
|
||||
|
||||
|
||||
struct t_gui_buffer *xfer_buffer = NULL;
|
||||
int xfer_buffer_selected_line = 0;
|
||||
|
||||
|
||||
/*
|
||||
* xfer_buffer_close_cb: callback called when xfer buffer is closed
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_buffer_close_cb (void *data, struct t_gui_buffer *buffer)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
|
||||
xfer_buffer = NULL;
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_buffer_open: open xfer buffer (to display list of xfer)
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_buffer_open ()
|
||||
{
|
||||
if (!xfer_buffer)
|
||||
{
|
||||
xfer_buffer = weechat_buffer_new ("xfer", "xfer",
|
||||
NULL, 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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_DISPLAY_H
|
||||
#define __WEECHAT_XFER_DISPLAY_H 1
|
||||
|
||||
extern struct t_gui_buffer *xfer_buffer;
|
||||
|
||||
extern void xfer_buffer_open ();
|
||||
extern void xfer_buffer_refresh (char *hotlist);
|
||||
|
||||
#endif /* xfer.h */
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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-chat.c: chat with direct connection to remote host */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-chat.h"
|
||||
#include "xfer-buffer.h"
|
||||
|
||||
|
||||
/*
|
||||
* xfer_chat_send: send data to remote host via xfer chat
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_chat_send (struct t_xfer *xfer, char *buffer, int size_buf)
|
||||
{
|
||||
if (!xfer)
|
||||
return -1;
|
||||
|
||||
return send (xfer->sock, buffer, size_buf, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_chat_sendf: send formatted data to remote host via DCC CHAT
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_chat_sendf (struct t_xfer *xfer, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
static char buffer[4096];
|
||||
int size_buf;
|
||||
|
||||
if (!xfer || (xfer->sock < 0))
|
||||
return;
|
||||
|
||||
va_start (args, format);
|
||||
size_buf = vsnprintf (buffer, sizeof (buffer) - 1, format, args);
|
||||
va_end (args);
|
||||
|
||||
if (size_buf == 0)
|
||||
return;
|
||||
|
||||
buffer[sizeof (buffer) - 1] = '\0';
|
||||
if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))
|
||||
size_buf = strlen (buffer);
|
||||
|
||||
if (xfer_chat_send (xfer, buffer, strlen (buffer)) <= 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: error sending data to \"%s\" via xfer chat"),
|
||||
weechat_prefix ("error"), "xfer", xfer->nick);
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_chat_recv: receive data from xfer chat remote host
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_chat_recv (struct t_xfer *xfer)
|
||||
{
|
||||
fd_set read_fd;
|
||||
static struct timeval timeout;
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
buffer[num_read] = '\0';
|
||||
|
||||
buf2 = NULL;
|
||||
ptr_buf = buffer;
|
||||
if (xfer->unterminated_message)
|
||||
{
|
||||
buf2 = malloc (strlen (xfer->unterminated_message) +
|
||||
strlen (buffer) + 1);
|
||||
if (buf2)
|
||||
{
|
||||
strcpy (buf2, xfer->unterminated_message);
|
||||
strcat (buf2, buffer);
|
||||
}
|
||||
ptr_buf = buf2;
|
||||
free (xfer->unterminated_message);
|
||||
xfer->unterminated_message = NULL;
|
||||
}
|
||||
|
||||
while (ptr_buf && ptr_buf[0])
|
||||
{
|
||||
next_ptr_buf = NULL;
|
||||
pos = strstr (ptr_buf, "\n");
|
||||
if (pos)
|
||||
{
|
||||
pos[0] = '\0';
|
||||
next_ptr_buf = pos + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xfer->unterminated_message = strdup (ptr_buf);
|
||||
ptr_buf = NULL;
|
||||
next_ptr_buf = NULL;
|
||||
}
|
||||
|
||||
if (ptr_buf)
|
||||
{
|
||||
weechat_printf (xfer->buffer, "%s\t%s", xfer->nick, ptr_buf);
|
||||
}
|
||||
|
||||
ptr_buf = next_ptr_buf;
|
||||
}
|
||||
|
||||
if (buf2)
|
||||
free (buf2);
|
||||
}
|
||||
else
|
||||
{
|
||||
xfer_close (xfer, XFER_STATUS_ABORTED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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_CHAT_H
|
||||
#define __WEECHAT_XFER_CHAT_H 1
|
||||
|
||||
|
||||
#endif /* xfer-chat.h */
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* 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-config.c: xfer configuration options */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-config.h"
|
||||
|
||||
|
||||
struct t_config_file *xfer_config_file = NULL;
|
||||
|
||||
/* xfer config, look section */
|
||||
|
||||
struct t_config_option *xfer_config_look_auto_open_buffer;
|
||||
|
||||
/* xfer config, color section */
|
||||
|
||||
struct t_config_option *xfer_config_color_text;
|
||||
struct t_config_option *xfer_config_color_text_bg;
|
||||
struct t_config_option *xfer_config_color_selected_bg;
|
||||
struct t_config_option *xfer_config_color_status[XFER_NUM_STATUS];
|
||||
|
||||
/* xfer config, network section */
|
||||
|
||||
struct t_config_option *xfer_config_network_timeout;
|
||||
struct t_config_option *xfer_config_network_blocksize;
|
||||
struct t_config_option *xfer_config_network_fast_send;
|
||||
struct t_config_option *xfer_config_network_port_range;
|
||||
struct t_config_option *xfer_config_network_own_ip;
|
||||
|
||||
/* xfer config, file section */
|
||||
|
||||
struct t_config_option *xfer_config_file_download_path;
|
||||
struct t_config_option *xfer_config_file_upload_path;
|
||||
struct t_config_option *xfer_config_file_convert_spaces;
|
||||
struct t_config_option *xfer_config_file_auto_rename;
|
||||
struct t_config_option *xfer_config_file_auto_resume;
|
||||
struct t_config_option *xfer_config_file_auto_accept_files;
|
||||
struct t_config_option *xfer_config_file_auto_accept_chats;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* xfer_config_reload: reload xfer configuration file
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_config_reload (void *data, struct t_config_file *config_file)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
|
||||
return weechat_config_reload (config_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_config_init: init xfer configuration file
|
||||
* return: 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_config_init ()
|
||||
{
|
||||
struct t_config_section *ptr_section;
|
||||
|
||||
xfer_config_file = weechat_config_new (XFER_CONFIG_NAME,
|
||||
&xfer_config_reload, NULL);
|
||||
if (!xfer_config_file)
|
||||
return 0;
|
||||
|
||||
ptr_section = weechat_config_new_section (xfer_config_file, "look",
|
||||
0, 0,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ptr_section)
|
||||
{
|
||||
weechat_config_free (xfer_config_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfer_config_look_auto_open_buffer = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"auto_open_buffer", "boolean",
|
||||
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);
|
||||
|
||||
ptr_section = weechat_config_new_section (xfer_config_file, "color",
|
||||
0, 0,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ptr_section)
|
||||
{
|
||||
weechat_config_free (xfer_config_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfer_config_color_text = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"text", "color",
|
||||
N_("text color"),
|
||||
NULL, 0, 0, "default",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_text_bg = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"text_bg", "color",
|
||||
N_("background color"),
|
||||
NULL, 0, 0, "default",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_selected_bg = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"selected_bg", "color",
|
||||
N_("background color for selected line"),
|
||||
NULL, 0, 0, "magenta",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_WAITING] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_waiting", "color",
|
||||
N_("text color for \"waiting\" status"),
|
||||
NULL, 0, 0, "lightcyan",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_CONNECTING] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_connecting", "color",
|
||||
N_("text color for \"connecting\" status"),
|
||||
NULL, 0, 0, "yellow",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_ACTIVE] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_active", "color",
|
||||
N_("text color for \"active\" status"),
|
||||
NULL, 0, 0, "lightblue",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_DONE] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_done", "color",
|
||||
N_("text color for \"done\" status"),
|
||||
NULL, 0, 0, "lightgreen",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_FAILED] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_failed", "color",
|
||||
N_("text color for \"failed\" status"),
|
||||
NULL, 0, 0, "lightred",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_color_status[XFER_STATUS_ABORTED] = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"status_aborted", "color",
|
||||
N_("text color for \"aborted\" status"),
|
||||
NULL, 0, 0, "lightred",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ptr_section = weechat_config_new_section (xfer_config_file, "network",
|
||||
0, 0,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ptr_section)
|
||||
{
|
||||
weechat_config_free (xfer_config_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfer_config_network_timeout = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"timeout", "integer",
|
||||
N_("timeout for xfer request (in seconds)"),
|
||||
NULL, 5, INT_MAX, "300", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_network_blocksize = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"blocksize", "integer",
|
||||
N_("block size for sending packets, in bytes"),
|
||||
NULL, XFER_BLOCKSIZE_MIN, XFER_BLOCKSIZE_MAX, "65536",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_network_fast_send = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"fast_send", "boolean",
|
||||
N_("does not wait for ACK when sending file"),
|
||||
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_network_port_range = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"port_range", "string",
|
||||
N_("restricts outgoing files/chats to use only ports in the given "
|
||||
"range (useful for NAT) (syntax: a single port, ie. 5000 or a port "
|
||||
"range, ie. 5000-5015, empty value means any port)"),
|
||||
NULL, 0, 0, "", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_network_own_ip = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"own_ip", "string",
|
||||
N_("IP or DNS address used for sending files/chats "
|
||||
"(if empty, local interface IP is used)"),
|
||||
NULL, 0, 0, "", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ptr_section = weechat_config_new_section (xfer_config_file, "file",
|
||||
0, 0,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ptr_section)
|
||||
{
|
||||
weechat_config_free (xfer_config_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfer_config_file_download_path = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"download_path", "string",
|
||||
N_("path for writing incoming files"),
|
||||
NULL, 0, 0, "%h/xfer", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_upload_path = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"upload_path", "string",
|
||||
N_("path for reading files when sending (when no path is "
|
||||
"specified by user)"),
|
||||
NULL, 0, 0, "~", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_convert_spaces = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"convert_spaces", "boolean",
|
||||
N_("convert spaces to underscores when sending files"),
|
||||
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_auto_rename = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"auto_rename", "boolean",
|
||||
N_("rename incoming files if already exists (add '.1', '.2', ...)"),
|
||||
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_auto_resume = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"auto_resume", "boolean",
|
||||
N_("automatically resume file transfer if connection with remote host "
|
||||
"is lost"),
|
||||
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_auto_accept_files = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"auto_accept_files", "boolean",
|
||||
N_("automatically accept incoming files (use carefully!)"),
|
||||
NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfer_config_file_auto_accept_chats = weechat_config_new_option (
|
||||
xfer_config_file, ptr_section,
|
||||
"auto_accept_chats", "boolean",
|
||||
N_("automatically accept chat requests (use carefully!)"),
|
||||
NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_config_read: read xfer configuration file
|
||||
* return: 0 = successful
|
||||
* -1 = configuration file file not found
|
||||
* -2 = error in configuration file
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_config_read ()
|
||||
{
|
||||
return weechat_config_read (xfer_config_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_config_write: write xfer configuration file
|
||||
* return: 0 if ok
|
||||
* < 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_config_write ()
|
||||
{
|
||||
return weechat_config_write (xfer_config_file);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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_CONFIG_H
|
||||
#define __WEECHAT_XFER_CONFIG_H 1
|
||||
|
||||
#define XFER_CONFIG_NAME "xfer"
|
||||
|
||||
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_color_text;
|
||||
extern struct t_config_option *xfer_config_color_text_bg;
|
||||
extern struct t_config_option *xfer_config_color_selected_bg;
|
||||
extern struct t_config_option *xfer_config_color_status[];
|
||||
|
||||
extern struct t_config_option *xfer_config_network_timeout;
|
||||
extern struct t_config_option *xfer_config_network_blocksize;
|
||||
extern struct t_config_option *xfer_config_network_fast_send;
|
||||
extern struct t_config_option *xfer_config_network_port_range;
|
||||
extern struct t_config_option *xfer_config_network_own_ip;
|
||||
|
||||
extern struct t_config_option *xfer_config_file_download_path;
|
||||
extern struct t_config_option *xfer_config_file_upload_path;
|
||||
extern struct t_config_option *xfer_config_file_convert_spaces;
|
||||
extern struct t_config_option *xfer_config_file_auto_rename;
|
||||
extern struct t_config_option *xfer_config_file_auto_resume;
|
||||
extern struct t_config_option *xfer_config_file_auto_accept_files;
|
||||
extern struct t_config_option *xfer_config_file_auto_accept_chats;
|
||||
|
||||
extern int xfer_config_init ();
|
||||
extern int xfer_config_read ();
|
||||
extern int xfer_config_write ();
|
||||
|
||||
#endif /* xfer-config.h */
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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-dcc.c: file transfert via DCC protocol */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-dcc.h"
|
||||
#include "xfer-network.h"
|
||||
|
||||
|
||||
/*
|
||||
* xfer_dcc_send_file_child: child process for sending file with DCC protocol
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_dcc_send_file_child (struct t_xfer *xfer)
|
||||
{
|
||||
int num_read, num_sent;
|
||||
static char buffer[XFER_BLOCKSIZE_MAX];
|
||||
uint32_t ack;
|
||||
time_t last_sent, new_time;
|
||||
|
||||
last_sent = time (NULL);
|
||||
while (1)
|
||||
{
|
||||
/* read DCC ACK (sent by receiver) */
|
||||
if (xfer->pos > xfer->ack)
|
||||
{
|
||||
/* we should receive ACK for packets sent previously */
|
||||
while (1)
|
||||
{
|
||||
num_read = recv (xfer->sock, (char *) &ack, 4, MSG_PEEK);
|
||||
if ((num_read < 1) &&
|
||||
((num_read != -1) || (errno != EAGAIN)))
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_SEND_BLOCK);
|
||||
return;
|
||||
}
|
||||
if (num_read == 4)
|
||||
{
|
||||
recv (xfer->sock, (char *) &ack, 4, 0);
|
||||
xfer->ack = ntohl (ack);
|
||||
|
||||
/* DCC send ok? */
|
||||
if ((xfer->pos >= xfer->size)
|
||||
&& (xfer->ack >= xfer->size))
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
|
||||
XFER_NO_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* send a block to receiver */
|
||||
if ((xfer->pos < xfer->size) &&
|
||||
(xfer->fast_send || (xfer->pos <= xfer->ack)))
|
||||
{
|
||||
lseek (xfer->file, xfer->pos, SEEK_SET);
|
||||
num_read = read (xfer->file, buffer, xfer->blocksize);
|
||||
if (num_read < 1)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_READ_LOCAL);
|
||||
return;
|
||||
}
|
||||
num_sent = send (xfer->sock, buffer, num_read, 0);
|
||||
if (num_sent < 0)
|
||||
{
|
||||
/* socket is temporarily not available (receiver can't receive
|
||||
amount of data we sent ?!) */
|
||||
if (errno == EAGAIN)
|
||||
usleep (1000);
|
||||
else
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_SEND_BLOCK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (num_sent > 0)
|
||||
{
|
||||
xfer->pos += (unsigned long) num_sent;
|
||||
new_time = time (NULL);
|
||||
if (last_sent != new_time)
|
||||
{
|
||||
last_sent = new_time;
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
|
||||
XFER_NO_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
usleep (1000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_dcc_recv_file_child: child process for receiving file
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_dcc_recv_file_child (struct t_xfer *xfer)
|
||||
{
|
||||
int num_read;
|
||||
static char buffer[XFER_BLOCKSIZE_MAX];
|
||||
uint32_t pos;
|
||||
time_t last_sent, new_time;
|
||||
|
||||
/* first connect to sender (blocking) */
|
||||
if (!weechat_network_connect_to (xfer->sock, xfer->address, xfer->port))
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_CONNECT_SENDER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* connection is ok, change DCC status (inform parent process) */
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
|
||||
XFER_NO_ERROR);
|
||||
|
||||
last_sent = time (NULL);
|
||||
while (1)
|
||||
{
|
||||
num_read = recv (xfer->sock, buffer, sizeof (buffer), 0);
|
||||
if (num_read == -1)
|
||||
{
|
||||
/* socket is temporarily not available (sender is not fast ?!) */
|
||||
if (errno == EAGAIN)
|
||||
usleep (1000);
|
||||
else
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_RECV_BLOCK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num_read == 0)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_RECV_BLOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
if (write (xfer->file, buffer, num_read) == -1)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
|
||||
XFER_ERROR_WRITE_LOCAL);
|
||||
return;
|
||||
}
|
||||
|
||||
xfer->pos += (unsigned long) num_read;
|
||||
pos = htonl (xfer->pos);
|
||||
|
||||
/* we don't check return code, not a problem if an ACK send failed */
|
||||
send (xfer->sock, (char *) &pos, 4, 0);
|
||||
|
||||
/* file received ok? */
|
||||
if (xfer->pos >= xfer->size)
|
||||
{
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
|
||||
XFER_NO_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
new_time = time (NULL);
|
||||
if (last_sent != new_time)
|
||||
{
|
||||
last_sent = new_time;
|
||||
xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
|
||||
XFER_NO_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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_DCC_H
|
||||
#define __WEECHAT_XFER_DCC_H 1
|
||||
|
||||
extern void xfer_dcc_send_file_child (struct t_xfer *xfer);
|
||||
extern void xfer_dcc_recv_file_child (struct t_xfer *xfer);
|
||||
|
||||
#endif /* xfer-dcc.h */
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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-file.c: file functions for xfer plugin */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-file.h"
|
||||
#include "xfer-buffer.h"
|
||||
#include "xfer-config.h"
|
||||
|
||||
|
||||
/*
|
||||
* xfer_file_resume: resume a download
|
||||
* return 1 if ok, 0 if not resumable
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_file_resume (struct t_xfer *xfer, char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!weechat_config_boolean (xfer_config_file_auto_resume))
|
||||
return 0;
|
||||
|
||||
if (access (filename, W_OK) == 0)
|
||||
{
|
||||
if (stat (filename, &st) != -1)
|
||||
{
|
||||
if ((unsigned long) st.st_size < xfer->size)
|
||||
{
|
||||
xfer->start_resume = (unsigned long) st.st_size;
|
||||
xfer->pos = st.st_size;
|
||||
xfer->last_check_pos = st.st_size;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* not resumable */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_file_find_filename: find local filename for a xfer
|
||||
* if type if file/recv, add a suffix (like .1) if needed
|
||||
* if download is resumable, set "start_resume" to good value
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_file_find_filename (struct t_xfer *xfer)
|
||||
{
|
||||
char *weechat_home, *dir1, *dir2, *filename2, *dir_separator;
|
||||
|
||||
if (!XFER_IS_FILE(xfer->type))
|
||||
return;
|
||||
|
||||
dir1 = weechat_string_replace (weechat_config_string (xfer_config_file_download_path),
|
||||
"~",
|
||||
getenv ("HOME"));
|
||||
if (!dir1)
|
||||
return;
|
||||
|
||||
weechat_home = weechat_info_get ("weechat_dir");
|
||||
if (!weechat_home)
|
||||
{
|
||||
free (dir1);
|
||||
return;
|
||||
}
|
||||
dir2 = weechat_string_replace (dir1, "%h", weechat_home);
|
||||
if (!dir2)
|
||||
{
|
||||
free (dir1);
|
||||
return;
|
||||
}
|
||||
|
||||
xfer->local_filename = malloc (strlen (dir2) +
|
||||
strlen (xfer->nick) +
|
||||
strlen (xfer->filename) + 4);
|
||||
if (!xfer->local_filename)
|
||||
return;
|
||||
|
||||
strcpy (xfer->local_filename, dir2);
|
||||
dir_separator = weechat_info_get("dir_separator");
|
||||
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, ".");
|
||||
strcat (xfer->local_filename, xfer->filename);
|
||||
|
||||
if (dir1)
|
||||
free (dir1);
|
||||
if (dir2 )
|
||||
free (dir2);
|
||||
|
||||
/* file already exists? */
|
||||
if (access (xfer->local_filename, F_OK) == 0)
|
||||
{
|
||||
if (xfer_file_resume (xfer, xfer->local_filename))
|
||||
return;
|
||||
|
||||
/* if auto rename is not set, then abort xfer */
|
||||
if (!xfer_config_file_auto_rename)
|
||||
{
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
filename2 = malloc (strlen (xfer->local_filename) + 16);
|
||||
if (!filename2)
|
||||
{
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return;
|
||||
}
|
||||
xfer->filename_suffix = 0;
|
||||
do
|
||||
{
|
||||
xfer->filename_suffix++;
|
||||
sprintf (filename2, "%s.%d",
|
||||
xfer->local_filename,
|
||||
xfer->filename_suffix);
|
||||
if (access (filename2, F_OK) == 0)
|
||||
{
|
||||
if (xfer_file_resume (xfer, filename2))
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (1);
|
||||
|
||||
free (xfer->local_filename);
|
||||
xfer->local_filename = strdup (filename2);
|
||||
free (filename2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_file_calculate_speed: calculate xfer speed (for files only)
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_file_calculate_speed (struct t_xfer *xfer, int ended)
|
||||
{
|
||||
time_t local_time, elapsed;
|
||||
unsigned long bytes_per_sec_total;
|
||||
|
||||
local_time = time (NULL);
|
||||
if (ended || local_time > xfer->last_check_time)
|
||||
{
|
||||
if (ended)
|
||||
{
|
||||
/* calculate bytes per second (global) */
|
||||
elapsed = local_time - xfer->start_transfer;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
xfer->bytes_per_sec = (xfer->pos - xfer->start_resume) / elapsed;
|
||||
xfer->eta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* calculate ETA */
|
||||
elapsed = local_time - xfer->start_transfer;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
bytes_per_sec_total = (xfer->pos - xfer->start_resume) / elapsed;
|
||||
if (bytes_per_sec_total == 0)
|
||||
bytes_per_sec_total = 1;
|
||||
xfer->eta = (xfer->size - xfer->pos) / bytes_per_sec_total;
|
||||
|
||||
/* calculate bytes per second (since last check time) */
|
||||
elapsed = local_time - xfer->last_check_time;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
xfer->bytes_per_sec = (xfer->pos - xfer->last_check_pos) / elapsed;
|
||||
}
|
||||
xfer->last_check_time = local_time;
|
||||
xfer->last_check_pos = xfer->pos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_FILE_H
|
||||
#define __WEECHAT_XFER_FILE_H 1
|
||||
|
||||
extern int xfer_file_resume (struct t_xfer *xfer, char *filename);
|
||||
extern void xfer_file_find_filename (struct t_xfer *xfer);
|
||||
extern void xfer_file_calculate_speed (struct t_xfer *xfer, int ended);
|
||||
|
||||
#endif /* xfer-file.h */
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* 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-network.c: network functions for xfer plugin */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
#include "xfer-network.h"
|
||||
#include "xfer-buffer.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
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_network_create_pipe (struct t_xfer *xfer)
|
||||
{
|
||||
int child_pipe[2];
|
||||
|
||||
if (pipe (child_pipe) < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to create pipe"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfer->child_read = child_pipe[0];
|
||||
xfer->child_write = child_pipe[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_write_pipe: write data into pipe
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_write_pipe (struct t_xfer *xfer, int status, int error)
|
||||
{
|
||||
char buffer[1 + 1 + 12 + 1]; /* status + error + pos + \0 */
|
||||
|
||||
snprintf (buffer, sizeof (buffer), "%c%c%012lu",
|
||||
status + '0', error + '0', xfer->pos);
|
||||
write (xfer->child_write, buffer, sizeof (buffer));
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_child_read_cb: read data from child via pipe
|
||||
*/
|
||||
|
||||
int
|
||||
xfer_network_child_read_cb (void *arg_xfer)
|
||||
{
|
||||
struct t_xfer *xfer;
|
||||
char bufpipe[1 + 1 + 12 + 1];
|
||||
int num_read;
|
||||
char *error;
|
||||
|
||||
xfer = (struct t_xfer *)arg_xfer;
|
||||
|
||||
num_read = read (xfer->child_read, bufpipe, sizeof (bufpipe));
|
||||
if (num_read > 0)
|
||||
{
|
||||
error = NULL;
|
||||
xfer->pos = strtol (bufpipe + 2, &error, 10);
|
||||
xfer->last_activity = time (NULL);
|
||||
xfer_file_calculate_speed (xfer, 0);
|
||||
|
||||
/* read error code */
|
||||
switch (bufpipe[1] - '0')
|
||||
{
|
||||
/* errors for sender */
|
||||
case XFER_ERROR_READ_LOCAL:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to read local file"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
case XFER_ERROR_SEND_BLOCK:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to send block to receiver"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
case XFER_ERROR_READ_ACK:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to read ACK from receiver"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
/* errors for receiver */
|
||||
case XFER_ERROR_CONNECT_SENDER:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to connect to sender"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
case XFER_ERROR_RECV_BLOCK:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to receive block from sender"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
case XFER_ERROR_WRITE_LOCAL:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to write local file"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
break;
|
||||
}
|
||||
|
||||
/* read new DCC status */
|
||||
switch (bufpipe[0] - '0')
|
||||
{
|
||||
case XFER_STATUS_ACTIVE:
|
||||
if (xfer->status == XFER_STATUS_CONNECTING)
|
||||
{
|
||||
/* connection was successful by child, init transfert times */
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer->start_transfer = time (NULL);
|
||||
xfer->last_check_time = time (NULL);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
else
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_LOW);
|
||||
break;
|
||||
case XFER_STATUS_DONE:
|
||||
xfer_close (xfer, XFER_STATUS_DONE);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
case XFER_STATUS_FAILED:
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_send_file_fork: fork process for sending file
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_send_file_fork (struct t_xfer *xfer)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
if (!xfer_network_create_pipe (xfer))
|
||||
return;
|
||||
|
||||
xfer->file = open (xfer->local_filename, O_RDONLY | O_NONBLOCK, 0644);
|
||||
|
||||
switch (pid = fork ())
|
||||
{
|
||||
/* fork failed */
|
||||
case -1:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to fork"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return;
|
||||
/* child process */
|
||||
case 0:
|
||||
setuid (getuid ());
|
||||
switch (xfer->protocol)
|
||||
{
|
||||
case XFER_NO_PROTOCOL:
|
||||
_exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case XFER_PROTOCOL_DCC:
|
||||
xfer_dcc_send_file_child (xfer);
|
||||
break;
|
||||
case XFER_NUM_PROTOCOLS:
|
||||
break;
|
||||
}
|
||||
_exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* parent process */
|
||||
xfer->child_pid = pid;
|
||||
xfer->hook_fd = weechat_hook_fd (xfer->child_read,
|
||||
1, 0, 0,
|
||||
xfer_network_child_read_cb,
|
||||
xfer);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_network_recv_file_fork: fork process for receiving file
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_network_recv_file_fork (struct t_xfer *xfer)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
if (!xfer_network_create_pipe (xfer))
|
||||
return;
|
||||
|
||||
if (xfer->start_resume > 0)
|
||||
xfer->file = open (xfer->local_filename,
|
||||
O_APPEND | O_WRONLY | O_NONBLOCK);
|
||||
else
|
||||
xfer->file = open (xfer->local_filename,
|
||||
O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
|
||||
0644);
|
||||
|
||||
switch (pid = fork ())
|
||||
{
|
||||
/* fork failed */
|
||||
case -1:
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: unable to fork"),
|
||||
weechat_prefix ("error"), "xfer");
|
||||
xfer_close (xfer, XFER_STATUS_FAILED);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
return;
|
||||
/* child process */
|
||||
case 0:
|
||||
setuid (getuid ());
|
||||
switch (xfer->protocol)
|
||||
{
|
||||
case XFER_NO_PROTOCOL:
|
||||
_exit (EXIT_SUCCESS);
|
||||
break;
|
||||
case XFER_PROTOCOL_DCC:
|
||||
xfer_dcc_recv_file_child (xfer);
|
||||
break;
|
||||
case XFER_NUM_PROTOCOLS:
|
||||
break;
|
||||
}
|
||||
_exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* parent process */
|
||||
xfer->child_pid = pid;
|
||||
xfer->hook_fd = weechat_hook_fd (xfer->child_read,
|
||||
1, 0, 0,
|
||||
xfer_network_child_read_cb,
|
||||
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
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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_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);
|
||||
|
||||
#endif /* xfer-network.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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_H
|
||||
#define __WEECHAT_XFER_H 1
|
||||
|
||||
#define weechat_plugin weechat_xfer_plugin
|
||||
|
||||
/* xfer types */
|
||||
|
||||
enum t_xfer_type
|
||||
{
|
||||
XFER_TYPE_FILE_RECV = 0,
|
||||
XFER_TYPE_FILE_SEND,
|
||||
XFER_TYPE_CHAT_RECV,
|
||||
XFER_TYPE_CHAT_SEND,
|
||||
/* number of xfer types */
|
||||
XFER_NUM_TYPES,
|
||||
};
|
||||
|
||||
/* xfer protocol (for file transfert) */
|
||||
|
||||
enum t_xfer_protocol
|
||||
{
|
||||
XFER_NO_PROTOCOL = 0,
|
||||
XFER_PROTOCOL_DCC,
|
||||
/* number of xfer protocols */
|
||||
XFER_NUM_PROTOCOLS,
|
||||
};
|
||||
|
||||
/* xfer status */
|
||||
|
||||
enum t_xfer_status
|
||||
{
|
||||
XFER_STATUS_WAITING = 0, /* waiting for host answer */
|
||||
XFER_STATUS_CONNECTING, /* connecting to host */
|
||||
XFER_STATUS_ACTIVE, /* sending/receiving data */
|
||||
XFER_STATUS_DONE, /* transfer done */
|
||||
XFER_STATUS_FAILED, /* transfer failed */
|
||||
XFER_STATUS_ABORTED, /* transfer aborded by user */
|
||||
/* number of xfer status */
|
||||
XFER_NUM_STATUS,
|
||||
};
|
||||
|
||||
/* xfer errors */
|
||||
|
||||
enum t_xfer_error
|
||||
{
|
||||
XFER_NO_ERROR = 0, /* no error to report, all ok! */
|
||||
XFER_ERROR_READ_LOCAL, /* unable to read local file */
|
||||
XFER_ERROR_SEND_BLOCK, /* unable to send block to receiver */
|
||||
XFER_ERROR_READ_ACK, /* unable to read ACK from receiver */
|
||||
XFER_ERROR_CONNECT_SENDER, /* unable to connect to sender */
|
||||
XFER_ERROR_RECV_BLOCK, /* unable to recv block from sender */
|
||||
XFER_ERROR_WRITE_LOCAL, /* unable to write to local file */
|
||||
/* number of errors */
|
||||
XFER_NUM_ERRORS,
|
||||
};
|
||||
|
||||
/* xfer blocksize */
|
||||
|
||||
#define XFER_BLOCKSIZE_MIN 1024 /* min blocksize when sending file */
|
||||
#define XFER_BLOCKSIZE_MAX 102400 /* max blocksize when sending file */
|
||||
|
||||
/* separator in filenames */
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DIR_SEPARATOR "\\"
|
||||
#define DIR_SEPARATOR_CHAR '\\'
|
||||
#else
|
||||
#define DIR_SEPARATOR "/"
|
||||
#define DIR_SEPARATOR_CHAR '/'
|
||||
#endif
|
||||
|
||||
/* macros for type/status */
|
||||
|
||||
#define XFER_IS_FILE(type) ((type == XFER_TYPE_FILE_RECV) || \
|
||||
(type == XFER_TYPE_FILE_SEND))
|
||||
#define XFER_IS_CHAT(type) ((type == XFER_TYPE_CHAT_RECV) || \
|
||||
(type == XFER_TYPE_CHAT_SEND))
|
||||
#define XFER_IS_RECV(type) ((type == XFER_TYPE_FILE_RECV) || \
|
||||
(type == XFER_TYPE_CHAT_RECV))
|
||||
#define XFER_IS_SEND(type) ((type == XFER_TYPE_FILE_SEND) || \
|
||||
(type == XFER_TYPE_CHAT_SEND))
|
||||
|
||||
#define XFER_HAS_ENDED(status) ((status == XFER_STATUS_DONE) || \
|
||||
(status == XFER_STATUS_FAILED) || \
|
||||
(status == XFER_STATUS_ABORTED))
|
||||
|
||||
struct t_xfer
|
||||
{
|
||||
/* data received by xfer to initiate a transfer */
|
||||
char *plugin_id; /* plugin identifier */
|
||||
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 *filename; /* filename */
|
||||
unsigned long size; /* file size */
|
||||
unsigned long address; /* local or remote IP address */
|
||||
int port; /* remote port */
|
||||
|
||||
/* internal data */
|
||||
enum t_xfer_status status; /* xfer status (waiting, sending,..) */
|
||||
struct t_gui_buffer *buffer; /* buffer (for chat only) */
|
||||
int fast_send; /* fast send file: does not wait ACK */
|
||||
int blocksize; /* block size for sending file */
|
||||
time_t start_time; /* time when xfer started */
|
||||
time_t start_transfer; /* time when xfer transfer started */
|
||||
int sock; /* socket for connection */
|
||||
pid_t child_pid; /* pid of child process (send/recv) */
|
||||
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 */
|
||||
char *unterminated_message; /* beginning of a message */
|
||||
int file; /* local file (read or write) */
|
||||
char *local_filename; /* local filename (with path) */
|
||||
int filename_suffix; /* suffix (like .1) if renaming file */
|
||||
unsigned long pos; /* number of bytes received/sent */
|
||||
unsigned long ack; /* number of bytes received OK */
|
||||
unsigned long start_resume; /* start of resume (in bytes) */
|
||||
time_t last_check_time; /* last time we checked bytes snt/rcv*/
|
||||
unsigned long last_check_pos; /* bytes sent/recv at last check */
|
||||
time_t last_activity; /* time of last byte received/sent */
|
||||
unsigned long bytes_per_sec; /* bytes per second */
|
||||
unsigned long eta; /* estimated time of arrival */
|
||||
struct t_xfer *prev_xfer; /* link to previous xfer */
|
||||
struct t_xfer *next_xfer; /* link to next xfer */
|
||||
};
|
||||
|
||||
extern struct t_weechat_plugin *weechat_xfer_plugin;
|
||||
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_debug;
|
||||
|
||||
extern void xfer_close (struct t_xfer *xfer, enum t_xfer_status status);
|
||||
extern struct t_xfer *xfer_alloc ();
|
||||
|
||||
#endif /* xfer.h */
|
||||
Reference in New Issue
Block a user