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; |