summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/plugins/xfer/xfer-buffer.c8
-rw-r--r--src/plugins/xfer/xfer-command.c10
-rw-r--r--src/plugins/xfer/xfer-dcc.c34
-rw-r--r--src/plugins/xfer/xfer-file.c6
-rw-r--r--src/plugins/xfer/xfer-network.c8
-rw-r--r--src/plugins/xfer/xfer.c61
-rw-r--r--src/plugins/xfer/xfer.h14
8 files changed, 83 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c5f70d39..e34adb400 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -67,6 +67,10 @@ Version 0.3.4 (under dev!)
* python: add info "python2_bin" (path to python 2.x interpreter)
* lua: fix crash when unloading script
* ruby: fix compilation with Ruby 1.9.2 (patch #7316)
+* xfer: fix dcc file transfer for large files (more than 4 GB) on 32-bit systems
+ (bug #31531)
+* xfer: fix bug at end of file sent, sometimes transfer is still active although
+ file was successfully sent
Version 0.3.3 (2010-08-07)
--------------------------
diff --git a/src/plugins/xfer/xfer-buffer.c b/src/plugins/xfer/xfer-buffer.c
index 161f27fa7..45bf64db8 100644
--- a/src/plugins/xfer/xfer-buffer.c
+++ b/src/plugins/xfer/xfer-buffer.c
@@ -48,7 +48,7 @@ xfer_buffer_refresh (const char *hotlist)
char str_color[256], suffix[32], status[64], date[128], eta[128];
char *progress_bar, *str_pos, *str_total, *str_bytes_per_sec;
int i, length, line, progress_bar_size, num_bars;
- unsigned long pct_complete;
+ unsigned long long pct_complete;
struct tm *date_tmp;
if (xfer_buffer)
@@ -177,7 +177,7 @@ xfer_buffer_refresh (const char *hotlist)
pct_complete = 0;
}
else
- pct_complete = (unsigned long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
+ pct_complete = (unsigned long long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
/* position, total and bytes per second */
str_pos = weechat_string_format_size (ptr_xfer->pos);
@@ -189,7 +189,7 @@ xfer_buffer_refresh (const char *hotlist)
if (ptr_xfer->status == XFER_STATUS_ACTIVE)
{
snprintf (eta, sizeof (eta),
- "%s: %.2lu:%.2lu:%.2lu - ",
+ "%s: %.2llu:%.2llu:%.2llu - ",
_("ETA"),
ptr_xfer->eta / 3600,
(ptr_xfer->eta / 60) % 60,
@@ -198,7 +198,7 @@ xfer_buffer_refresh (const char *hotlist)
/* display second line for file with status, progress bar and estimated time */
weechat_printf_y (xfer_buffer, (line * 2) + 3,
- "%s%s%s %s%s%s%s%3lu%% %s / %s (%s%s/s)",
+ "%s%s%s %s%s%s%s%3llu%% %s / %s (%s%s/s)",
weechat_color(str_color),
(line == xfer_buffer_selected_line) ? "*** " : " ",
(XFER_IS_SEND(ptr_xfer->type)) ? "<<--" : "-->>",
diff --git a/src/plugins/xfer/xfer-command.c b/src/plugins/xfer/xfer-command.c
index ee30e9a4a..6d44f5e85 100644
--- a/src/plugins/xfer/xfer-command.c
+++ b/src/plugins/xfer/xfer-command.c
@@ -85,7 +85,7 @@ xfer_command_xfer_list (int full)
struct t_xfer *ptr_xfer;
int i;
char date[128];
- unsigned long pct_complete;
+ unsigned long long pct_complete;
struct tm *date_tmp;
if (xfer_list)
@@ -106,12 +106,12 @@ xfer_command_xfer_list (int full)
pct_complete = 0;
}
else
- pct_complete = (unsigned long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
+ pct_complete = (unsigned long long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
weechat_printf (NULL,
_("%3d. %s (%s), file: \"%s\" (local: "
"\"%s\"), %s %s, status: %s%s%s "
- "(%lu %%)"),
+ "(%llu %%)"),
i,
xfer_type_string[ptr_xfer->type],
xfer_protocol_string[ptr_xfer->protocol],
@@ -153,8 +153,8 @@ xfer_command_xfer_list (int full)
if (XFER_IS_FILE(ptr_xfer->type))
{
weechat_printf (NULL,
- _(" plugin: %s (id: %s), file: %lu "
- "bytes (position: %lu), address: "
+ _(" plugin: %s (id: %s), file: %llu "
+ "bytes (position: %llu), address: "
"%d.%d.%d.%d (port %d)"),
ptr_xfer->plugin_name,
ptr_xfer->plugin_id,
diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c
index 2185a84e2..9eca48ce0 100644
--- a/src/plugins/xfer/xfer-dcc.c
+++ b/src/plugins/xfer/xfer-dcc.c
@@ -49,8 +49,8 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
int num_read, num_sent, blocksize;
static char buffer[XFER_BLOCKSIZE_MAX];
uint32_t ack;
- time_t last_sent, new_time, last_second;
- long sent_last_second;
+ time_t last_sent, new_time, last_second, sent_ok;
+ unsigned long long sent_last_second;
blocksize = xfer->blocksize;
if (weechat_config_integer (xfer_config_network_speed_limit) > 0)
@@ -61,6 +61,7 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
last_sent = time (NULL);
last_second = time (NULL);
+ sent_ok = 0;
sent_last_second = 0;
while (1)
{
@@ -102,7 +103,7 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
(xfer->fast_send || (xfer->pos <= xfer->ack)))
{
if ((weechat_config_integer (xfer_config_network_speed_limit) > 0)
- && (sent_last_second >= weechat_config_integer (xfer_config_network_speed_limit) * 1024))
+ && (sent_last_second >= (unsigned long long)weechat_config_integer (xfer_config_network_speed_limit) * 1024))
{
/* we're sending too fast (according to speed limit set by user) */
usleep (100);
@@ -135,14 +136,17 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
}
if (num_sent > 0)
{
- xfer->pos += (unsigned long) num_sent;
- sent_last_second += (unsigned long) num_sent;
+ xfer->pos += (unsigned long long) num_sent;
+ sent_last_second += (unsigned long long) num_sent;
new_time = time (NULL);
- if (last_sent != new_time)
+ if ((last_sent != new_time)
+ || ((sent_ok == 0) && (xfer->pos >= xfer->size)))
{
last_sent = new_time;
xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
XFER_NO_ERROR);
+ if (xfer->pos >= xfer->size)
+ sent_ok = new_time;
}
}
}
@@ -150,11 +154,23 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
else
usleep (1000);
- if (time (NULL) > last_second)
+ new_time = time (NULL);
+ if (new_time > last_second)
{
- last_second = time (NULL);
+ last_second = new_time;
sent_last_second = 0;
}
+
+ /*
+ * if send if ok since 2 seconds or more, and that no ack was received,
+ * then consider it's ok
+ */
+ if ((sent_ok != 0) && (new_time > sent_ok + 2))
+ {
+ xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
+ XFER_NO_ERROR);
+ return;
+ }
}
}
@@ -215,7 +231,7 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
return;
}
- xfer->pos += (unsigned long) num_read;
+ xfer->pos += (unsigned long long) num_read;
pos = htonl (xfer->pos);
/* we don't check return code, not a problem if an ACK send failed */
diff --git a/src/plugins/xfer/xfer-file.c b/src/plugins/xfer/xfer-file.c
index 74b7f1378..3744d3c76 100644
--- a/src/plugins/xfer/xfer-file.c
+++ b/src/plugins/xfer/xfer-file.c
@@ -55,9 +55,9 @@ xfer_file_resume (struct t_xfer *xfer, const char *filename)
{
if (stat (filename, &st) != -1)
{
- if ((unsigned long) st.st_size < xfer->size)
+ if ((unsigned long long) st.st_size < xfer->size)
{
- xfer->start_resume = (unsigned long) st.st_size;
+ xfer->start_resume = (unsigned long long) st.st_size;
xfer->pos = xfer->start_resume;
xfer->last_check_pos = xfer->start_resume;
return 1;
@@ -176,7 +176,7 @@ void
xfer_file_calculate_speed (struct t_xfer *xfer, int ended)
{
time_t local_time, elapsed;
- unsigned long bytes_per_sec_total;
+ unsigned long long bytes_per_sec_total;
local_time = time (NULL);
if (ended || local_time > xfer->last_check_time)
diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c
index 1afef1d6c..addedbbf1 100644
--- a/src/plugins/xfer/xfer-network.c
+++ b/src/plugins/xfer/xfer-network.c
@@ -75,9 +75,9 @@ xfer_network_create_pipe (struct t_xfer *xfer)
void
xfer_network_write_pipe (struct t_xfer *xfer, int status, int error)
{
- char buffer[1 + 1 + 12 + 1]; /* status + error + pos + \0 */
+ char buffer[1 + 1 + 32 + 1]; /* status + error + pos + \0 */
- snprintf (buffer, sizeof (buffer), "%c%c%012lu",
+ snprintf (buffer, sizeof (buffer), "%c%c%032llu",
status + '0', error + '0', xfer->pos);
write (xfer->child_write, buffer, sizeof (buffer));
}
@@ -90,7 +90,7 @@ int
xfer_network_child_read_cb (void *arg_xfer, int fd)
{
struct t_xfer *xfer;
- char bufpipe[1 + 1 + 12 + 1];
+ char bufpipe[1 + 1 + 32 + 1];
int num_read;
char *error;
@@ -103,7 +103,7 @@ xfer_network_child_read_cb (void *arg_xfer, int fd)
if (num_read > 0)
{
error = NULL;
- xfer->pos = (unsigned long)(strtoll (bufpipe + 2, &error, 10));
+ sscanf (bufpipe + 2, "%llu", &xfer->pos);
xfer->last_activity = time (NULL);
xfer_file_calculate_speed (xfer, 0);
diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c
index fa15b0064..505a5ad04 100644
--- a/src/plugins/xfer/xfer.c
+++ b/src/plugins/xfer/xfer.c
@@ -321,7 +321,7 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
/* erase file only if really empty on disk */
if (stat (xfer->local_filename, &st) != -1)
{
- if ((unsigned long) st.st_size == 0)
+ if ((unsigned long long) st.st_size == 0)
unlink (xfer->local_filename);
}
}
@@ -395,10 +395,10 @@ xfer_send_signal (struct t_xfer *xfer, const char *signal)
xfer->charset_modifier);
weechat_infolist_new_var_string (item, "filename",
xfer->filename);
- snprintf (str_long, sizeof (str_long), "%lu", xfer->size);
+ snprintf (str_long, sizeof (str_long), "%llu", xfer->size);
weechat_infolist_new_var_string (item, "size",
str_long);
- snprintf (str_long, sizeof (str_long), "%lu", xfer->start_resume);
+ snprintf (str_long, sizeof (str_long), "%llu", xfer->start_resume);
weechat_infolist_new_var_string (item, "start_resume",
str_long);
snprintf (str_long, sizeof (str_long), "%lu", xfer->address);
@@ -489,7 +489,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
enum t_xfer_type type, enum t_xfer_protocol protocol,
const char *remote_nick, const char *local_nick,
const char *charset_modifier, const char *filename,
- unsigned long size, const char *proxy, unsigned long address,
+ unsigned long long size, const char *proxy, unsigned long address,
int port, int sock, const char *local_filename)
{
struct t_xfer *new_xfer;
@@ -542,7 +542,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
case XFER_TYPE_FILE_RECV:
weechat_printf (NULL,
_("%s: incoming file from %s "
- "(%d.%d.%d.%d): %s, %lu bytes (protocol: %s)"),
+ "(%d.%d.%d.%d): %s, %llu bytes (protocol: %s)"),
XFER_PLUGIN_NAME,
remote_nick,
address >> 24,
@@ -557,7 +557,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
case XFER_TYPE_FILE_SEND:
weechat_printf (NULL,
_("%s: sending file to %s: %s "
- "(local filename: %s), %lu bytes (protocol: %s)"),
+ "(local filename: %s), %llu bytes (protocol: %s)"),
XFER_PLUGIN_NAME,
remote_nick,
filename,
@@ -600,7 +600,7 @@ xfer_new (const char *plugin_name, const char *plugin_id,
{
weechat_printf (NULL,
_("%s: file %s (local filename: %s) "
- "will be resumed at position %lu"),
+ "will be resumed at position %llu"),
XFER_PLUGIN_NAME,
new_xfer->filename,
new_xfer->local_filename,
@@ -713,7 +713,8 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
struct sockaddr_in addr;
socklen_t length;
struct in_addr tmpaddr;
- unsigned long local_addr, file_size;
+ unsigned long local_addr;
+ unsigned long long file_size;
struct t_xfer *ptr_xfer;
/* make C compiler happy */
@@ -801,7 +802,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data,
if (type == XFER_TYPE_FILE_RECV)
{
filename2 = strdup (filename);
- sscanf (weechat_infolist_string (infolist, "size"), "%lu", &file_size);
+ sscanf (weechat_infolist_string (infolist, "size"), "%llu", &file_size);
}
if (type == XFER_TYPE_FILE_SEND)
@@ -1068,7 +1069,7 @@ xfer_start_resume_cb (void *data, const char *signal, const char *type_data,
struct t_xfer *ptr_xfer;
const char *plugin_name, *plugin_id, *filename, *str_start_resume;
int port;
- unsigned long start_resume;
+ unsigned long long start_resume;
/* make C compiler happy */
(void) data;
@@ -1110,7 +1111,7 @@ xfer_start_resume_cb (void *data, const char *signal, const char *type_data,
goto error;
}
- sscanf (str_start_resume, "%lu", &start_resume);
+ sscanf (str_start_resume, "%llu", &start_resume);
ptr_xfer = xfer_search (plugin_name, plugin_id, XFER_TYPE_FILE_RECV,
XFER_STATUS_CONNECTING, port);
@@ -1126,7 +1127,7 @@ xfer_start_resume_cb (void *data, const char *signal, const char *type_data,
{
weechat_printf (NULL,
_("%s%s: unable to resume file \"%s\" (port: %d, "
- "start position: %lu): xfer not found or not ready "
+ "start position: %llu): xfer not found or not ready "
"for transfer"),
weechat_prefix ("error"), XFER_PLUGIN_NAME, filename,
port, start_resume);
@@ -1153,7 +1154,7 @@ xfer_accept_resume_cb (void *data, const char *signal, const char *type_data,
struct t_xfer *ptr_xfer;
const char *plugin_name, *plugin_id, *filename, *str_start_resume;
int port;
- unsigned long start_resume;
+ unsigned long long start_resume;
/* make C compiler happy */
(void) data;
@@ -1195,7 +1196,7 @@ xfer_accept_resume_cb (void *data, const char *signal, const char *type_data,
goto error;
}
- sscanf (str_start_resume, "%lu", &start_resume);
+ sscanf (str_start_resume, "%llu", &start_resume);
ptr_xfer = xfer_search (plugin_name, plugin_id, XFER_TYPE_FILE_SEND,
XFER_STATUS_CONNECTING, port);
@@ -1208,7 +1209,7 @@ xfer_accept_resume_cb (void *data, const char *signal, const char *type_data,
xfer_send_signal (ptr_xfer, "xfer_send_accept_resume");
weechat_printf (NULL,
- _("%s: file %s resumed at position %lu"),
+ _("%s: file %s resumed at position %llu"),
XFER_PLUGIN_NAME,
ptr_xfer->filename,
ptr_xfer->start_resume);
@@ -1218,7 +1219,7 @@ xfer_accept_resume_cb (void *data, const char *signal, const char *type_data,
{
weechat_printf (NULL,
_("%s%s: unable to accept resume file \"%s\" (port: %d, "
- "start position: %lu): xfer not found or not ready "
+ "start position: %llu): xfer not found or not ready "
"for transfer"),
weechat_prefix ("error"), XFER_PLUGIN_NAME, filename,
port, start_resume);
@@ -1270,7 +1271,7 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "filename", xfer->filename))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->size);
+ snprintf (value, sizeof (value), "%llu", xfer->size);
if (!weechat_infolist_new_var_string (ptr_item, "size", value))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "proxy", xfer->proxy))
@@ -1317,26 +1318,26 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "filename_suffix", xfer->filename_suffix))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->pos);
+ snprintf (value, sizeof (value), "%llu", xfer->pos);
if (!weechat_infolist_new_var_string (ptr_item, "pos", value))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->ack);
+ snprintf (value, sizeof (value), "%llu", xfer->ack);
if (!weechat_infolist_new_var_string (ptr_item, "ack", value))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->start_resume);
+ snprintf (value, sizeof (value), "%llu", xfer->start_resume);
if (!weechat_infolist_new_var_string (ptr_item, "start_resume", value))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "last_check_time", xfer->last_check_time))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->last_check_pos);
+ snprintf (value, sizeof (value), "%llu", xfer->last_check_pos);
if (!weechat_infolist_new_var_string (ptr_item, "last_check_pos", value))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "last_activity", xfer->last_activity))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->bytes_per_sec);
+ snprintf (value, sizeof (value), "%llu", xfer->bytes_per_sec);
if (!weechat_infolist_new_var_string (ptr_item, "bytes_per_sec", value))
return 0;
- snprintf (value, sizeof (value), "%lu", xfer->eta);
+ snprintf (value, sizeof (value), "%llu", xfer->eta);
if (!weechat_infolist_new_var_string (ptr_item, "eta", value))
return 0;
@@ -1368,7 +1369,7 @@ xfer_print_log ()
weechat_log_printf (" local_nick. . . . . : '%s'", ptr_xfer->local_nick);
weechat_log_printf (" charset_modifier. . : '%s'", ptr_xfer->charset_modifier);
weechat_log_printf (" filename. . . . . . : '%s'", ptr_xfer->filename);
- weechat_log_printf (" size. . . . . . . . : %lu", ptr_xfer->size);
+ weechat_log_printf (" size. . . . . . . . : %llu", ptr_xfer->size);
weechat_log_printf (" proxy . . . . . . . : '%s'", ptr_xfer->proxy);
weechat_log_printf (" address . . . . . . : %lu", ptr_xfer->address);
weechat_log_printf (" port. . . . . . . . : %d", ptr_xfer->port);
@@ -1392,14 +1393,14 @@ xfer_print_log ()
weechat_log_printf (" file. . . . . . . . : %d", ptr_xfer->file);
weechat_log_printf (" local_filename. . . : '%s'", ptr_xfer->local_filename);
weechat_log_printf (" filename_suffix . . : %d", ptr_xfer->filename_suffix);
- weechat_log_printf (" pos . . . . . . . . : %lu", ptr_xfer->pos);
- weechat_log_printf (" ack . . . . . . . . : %lu", ptr_xfer->ack);
- weechat_log_printf (" start_resume. . . . : %lu", ptr_xfer->start_resume);
+ weechat_log_printf (" pos . . . . . . . . : %llu", ptr_xfer->pos);
+ weechat_log_printf (" ack . . . . . . . . : %llu", ptr_xfer->ack);
+ weechat_log_printf (" start_resume. . . . : %llu", ptr_xfer->start_resume);
weechat_log_printf (" last_check_time . . : %ld", ptr_xfer->last_check_time);
- weechat_log_printf (" last_check_pos. . . : %lu", ptr_xfer->last_check_pos);
+ weechat_log_printf (" last_check_pos. . . : %llu", ptr_xfer->last_check_pos);
weechat_log_printf (" last_activity . . . : %ld", ptr_xfer->last_activity);
- weechat_log_printf (" bytes_per_sec . . . : %lu", ptr_xfer->bytes_per_sec);
- weechat_log_printf (" eta . . . . . . . . : %lu", ptr_xfer->eta);
+ weechat_log_printf (" bytes_per_sec . . . : %llu", ptr_xfer->bytes_per_sec);
+ weechat_log_printf (" eta . . . . . . . . : %llu", ptr_xfer->eta);
weechat_log_printf (" prev_xfer . . . . . : 0x%lx", ptr_xfer->prev_xfer);
weechat_log_printf (" next_xfer . . . . . : 0x%lx", ptr_xfer->next_xfer);
}
diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h
index 694ded453..5fbc8b315 100644
--- a/src/plugins/xfer/xfer.h
+++ b/src/plugins/xfer/xfer.h
@@ -115,7 +115,7 @@ struct t_xfer
char *local_nick; /* local nick */
char *charset_modifier; /* string for charset modifier_data */
char *filename; /* filename */
- unsigned long size; /* file size */
+ unsigned long long size; /* file size */
char *proxy; /* proxy to use (optional) */
unsigned long address; /* local or remote IP address */
int port; /* remote port */
@@ -139,14 +139,14 @@ struct t_xfer
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) */
+ unsigned long long pos; /* number of bytes received/sent */
+ unsigned long long ack; /* number of bytes received OK */
+ unsigned long 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 */
+ unsigned long 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 */
+ unsigned long long bytes_per_sec; /* bytes per second */
+ unsigned long long eta; /* estimated time of arrival */
struct t_xfer *prev_xfer; /* link to previous xfer */
struct t_xfer *next_xfer; /* link to next xfer */
};