|
version 1.1.1.1, 2012/02/17 15:09:30
|
version 1.1.1.4, 2021/03/17 00:32:36
|
|
Line 4
|
Line 4
|
| * Copyright (C) 1996-2000 Andrew Tridgell |
* Copyright (C) 1996-2000 Andrew Tridgell |
| * Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 1996 Paul Mackerras |
| * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
| * Copyright (C) 2003-2009 Wayne Davison | * Copyright (C) 2003-2020 Wayne Davison |
| * |
* |
| * This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
|
Line 21
|
Line 21
|
| */ |
*/ |
| |
|
| #include "rsync.h" |
#include "rsync.h" |
| |
#include "inums.h" |
| |
|
| extern int am_server; |
extern int am_server; |
| |
extern int flist_eof; |
| |
extern int quiet; |
| extern int need_unsorted_flist; |
extern int need_unsorted_flist; |
| |
extern int output_needs_newline; |
| |
extern int stdout_format_has_i; |
| extern struct stats stats; |
extern struct stats stats; |
| extern struct file_list *cur_flist; |
extern struct file_list *cur_flist; |
| |
|
| |
BOOL want_progress_now = False; |
| |
|
| #define PROGRESS_HISTORY_SECS 5 |
#define PROGRESS_HISTORY_SECS 5 |
| |
|
| #ifdef GETPGRP_VOID |
#ifdef GETPGRP_VOID |
|
Line 40 struct progress_history {
|
Line 47 struct progress_history {
|
| OFF_T ofs; |
OFF_T ofs; |
| }; |
}; |
| |
|
| int progress_is_active = 0; |
|
| |
|
| static struct progress_history ph_start; |
static struct progress_history ph_start; |
| static struct progress_history ph_list[PROGRESS_HISTORY_SECS]; |
static struct progress_history ph_list[PROGRESS_HISTORY_SECS]; |
| static int newest_hpos, oldest_hpos; |
static int newest_hpos, oldest_hpos; |
|
Line 61 static unsigned long msdiff(struct timeval *t1, struct
|
Line 66 static unsigned long msdiff(struct timeval *t1, struct
|
| * printed for this file, so we should output a newline. (Not |
* printed for this file, so we should output a newline. (Not |
| * necessarily the same as all bytes being received.) |
* necessarily the same as all bytes being received.) |
| **/ |
**/ |
| static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, | static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, int is_last) |
| int is_last) | |
| { |
{ |
| char rembuf[64], eol[128]; |
char rembuf[64], eol[128]; |
| const char *units; |
const char *units; |
| int pct = ofs == size ? 100 : (int) (100.0 * ofs / size); |
|
| unsigned long diff; |
unsigned long diff; |
| double rate, remain; |
double rate, remain; |
| |
int pct; |
| |
|
| if (is_last) { |
if (is_last) { |
| |
int len = snprintf(eol, sizeof eol, |
| |
" (xfr#%d, %s-chk=%d/%d)\n", |
| |
stats.xferred_files, flist_eof ? "to" : "ir", |
| |
stats.num_files - current_file_index - 1, |
| |
stats.num_files); |
| |
if (INFO_GTE(PROGRESS, 2)) { |
| |
static int last_len = 0; |
| |
/* Drop \n and pad with spaces if line got shorter. */ |
| |
if (last_len < --len) |
| |
last_len = len; |
| |
eol[last_len] = '\0'; |
| |
while (last_len > len) |
| |
eol[--last_len] = ' '; |
| |
is_last = 0; |
| |
} |
| /* Compute stats based on the starting info. */ |
/* Compute stats based on the starting info. */ |
| if (!ph_start.time.tv_sec | if (!ph_start.time.tv_sec || !(diff = msdiff(&ph_start.time, now))) |
| || !(diff = msdiff(&ph_start.time, now))) | |
| diff = 1; |
diff = 1; |
| rate = (double) (ofs - ph_start.ofs) * 1000.0 / diff / 1024.0; |
rate = (double) (ofs - ph_start.ofs) * 1000.0 / diff / 1024.0; |
| /* Switch to total time taken for our last update. */ |
/* Switch to total time taken for our last update. */ |
| remain = (double) diff / 1000.0; |
remain = (double) diff / 1000.0; |
| } else { |
} else { |
| |
strlcpy(eol, " ", sizeof eol); |
| /* Compute stats based on recent progress. */ |
/* Compute stats based on recent progress. */ |
| if (!(diff = msdiff(&ph_list[oldest_hpos].time, now))) |
if (!(diff = msdiff(&ph_list[oldest_hpos].time, now))) |
| diff = 1; |
diff = 1; |
| rate = (double) (ofs - ph_list[oldest_hpos].ofs) * 1000.0 | rate = (double) (ofs - ph_list[oldest_hpos].ofs) * 1000.0 / diff / 1024.0; |
| / diff / 1024.0; | |
| remain = rate ? (double) (size - ofs) / rate / 1000.0 : 0.0; |
remain = rate ? (double) (size - ofs) / rate / 1000.0 : 0.0; |
| } |
} |
| |
|
|
Line 106 static void rprint_progress(OFF_T ofs, OFF_T size, str
|
Line 124 static void rprint_progress(OFF_T ofs, OFF_T size, str
|
| (int) remain % 60); |
(int) remain % 60); |
| } |
} |
| |
|
| if (is_last) { | output_needs_newline = 0; |
| snprintf(eol, sizeof eol, " (xfer#%d, to-check=%d/%d)\n", | pct = ofs == size ? 100 : (int) (100.0 * ofs / size); |
| stats.num_transferred_files, | rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s", |
| stats.num_files - current_file_index - 1, | |
| stats.num_files); | |
| } else | |
| strlcpy(eol, "\r", sizeof eol); | |
| progress_is_active = 0; | |
| rprintf(FCLIENT, "%12s %3d%% %7.2f%s %s%s", | |
| human_num(ofs), pct, rate, units, rembuf, eol); |
human_num(ofs), pct, rate, units, rembuf, eol); |
| if (!is_last) | if (!is_last && !quiet) { |
| progress_is_active = 1; | output_needs_newline = 1; |
| | rflush(FCLIENT); |
| | } |
| } |
} |
| |
|
| |
void progress_init(void) |
| |
{ |
| |
if (!am_server && !INFO_GTE(PROGRESS, 1)) { |
| |
struct timeval now; |
| |
gettimeofday(&now, NULL); |
| |
ph_start.time.tv_sec = now.tv_sec; |
| |
ph_start.time.tv_usec = now.tv_usec; |
| |
} |
| |
} |
| |
|
| void set_current_file_index(struct file_struct *file, int ndx) |
void set_current_file_index(struct file_struct *file, int ndx) |
| { |
{ |
| if (need_unsorted_flist) | if (!file) |
| | current_file_index = cur_flist->used + cur_flist->ndx_start - 1; |
| | else if (need_unsorted_flist) |
| current_file_index = flist_find(cur_flist, file) + cur_flist->ndx_start; |
current_file_index = flist_find(cur_flist, file) + cur_flist->ndx_start; |
| else |
else |
| current_file_index = ndx; |
current_file_index = ndx; |
| current_file_index -= cur_flist->flist_num; |
current_file_index -= cur_flist->flist_num; |
| } |
} |
| |
|
| |
void instant_progress(const char *fname) |
| |
{ |
| |
/* We only get here if want_progress_now is True */ |
| |
if (!stdout_format_has_i && !INFO_GTE(NAME, 1)) |
| |
rprintf(FINFO, "%s\n", fname); |
| |
end_progress(0); |
| |
want_progress_now = False; |
| |
} |
| |
|
| void end_progress(OFF_T size) |
void end_progress(OFF_T size) |
| { |
{ |
| if (!am_server) { |
if (!am_server) { |
| struct timeval now; |
struct timeval now; |
| gettimeofday(&now, NULL); |
gettimeofday(&now, NULL); |
| rprint_progress(size, size, &now, True); | if (INFO_GTE(PROGRESS, 2) || want_progress_now) { |
| | rprint_progress(stats.total_transferred_size, |
| | stats.total_size, &now, True); |
| | } else { |
| | rprint_progress(size, size, &now, True); |
| | memset(&ph_start, 0, sizeof ph_start); |
| | } |
| } |
} |
| memset(&ph_start, 0, sizeof ph_start); |
|
| } |
} |
| |
|
| void show_progress(OFF_T ofs, OFF_T size) |
void show_progress(OFF_T ofs, OFF_T size) |
|
Line 156 void show_progress(OFF_T ofs, OFF_T size)
|
Line 196 void show_progress(OFF_T ofs, OFF_T size)
|
| #endif |
#endif |
| |
|
| gettimeofday(&now, NULL); |
gettimeofday(&now, NULL); |
| |
|
| |
if (INFO_GTE(PROGRESS, 2)) { |
| |
ofs = stats.total_transferred_size - size + ofs; |
| |
size = stats.total_size; |
| |
} |
| |
|
| if (!ph_start.time.tv_sec) { |
if (!ph_start.time.tv_sec) { |
| int i; |
int i; |