diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-buffer.c | 8 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-command.c | 10 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-dcc.c | 34 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-file.c | 6 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-network.c | 8 | ||||
-rw-r--r-- | src/plugins/xfer/xfer.c | 61 | ||||
-rw-r--r-- | src/plugins/xfer/xfer.h | 14 |
8 files changed, 83 insertions, 62 deletions
@@ -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 */ }; |