Lines 170-175
Link Here
|
170 |
return ok; |
170 |
return ok; |
171 |
} |
171 |
} |
172 |
|
172 |
|
|
|
173 |
/* This function displays a progress bar |
174 |
if the progress flag is set. |
175 |
It uses a 1:2 scales. */ |
176 |
|
177 |
void |
178 |
progress_bar_print(size_t dim_tot, size_t dim_cur) |
179 |
{ |
180 |
int i; |
181 |
size_t per_tot, per_cur, per_tot_scl, per_cur_scl; |
182 |
|
183 |
/* Check: |
184 |
if filesize is less than 1 KiB, exit */ |
185 |
if (! (dim_tot / 1024)) |
186 |
return; |
187 |
/* display size in KiB */ |
188 |
dim_tot /= 1024; |
189 |
dim_cur /= 1024; |
190 |
|
191 |
per_tot = 100; |
192 |
/* total percentage */ |
193 |
per_cur = (per_tot * dim_cur) / dim_tot; |
194 |
/* current percentage */ |
195 |
|
196 |
/* 1:2 scale */ |
197 |
per_tot_scl = per_tot / 2; |
198 |
per_cur_scl = per_cur / 2; |
199 |
|
200 |
/* Refresh the bar indicator */ |
201 |
printf("\r ["); |
202 |
|
203 |
/* Display the bar indicator: |
204 |
- = : indicates a part the bar |
205 |
- > : indicates the end of the bar |
206 |
(if it's finish, convert '>' to '='*/ |
207 |
for (i = 0; i < per_cur_scl; i++) |
208 |
if ((i + 1) == per_cur_scl) |
209 |
if (per_cur_scl == 50) |
210 |
putchar('='); |
211 |
else |
212 |
putchar('>'); |
213 |
else |
214 |
putchar('='); |
215 |
|
216 |
for (i = per_cur_scl; i < per_tot_scl; i++) |
217 |
putchar(' '); |
218 |
|
219 |
printf("] %3d\% | ", per_cur); |
220 |
fflush(stdout); |
221 |
} |
222 |
|
223 |
size_t speed = 0; |
224 |
float speed_last = 0; |
225 |
|
226 |
/* This function displays speed copy |
227 |
if the progress flag is set. */ |
228 |
|
229 |
void |
230 |
progress_bar_print_speed(struct tm *tm_init) |
231 |
{ |
232 |
time_t time_cur; |
233 |
struct tm tm_cur; |
234 |
float speed_, speed_si = (float) 1024; |
235 |
|
236 |
time_cur = time(NULL); |
237 |
tm_cur = *(struct tm *) localtime(&time_cur); |
238 |
|
239 |
speed_ = (float) speed; |
240 |
|
241 |
if (tm_init->tm_sec == tm_cur.tm_sec) |
242 |
{ |
243 |
if (tm_init->tm_sec == 60) |
244 |
tm_init->tm_sec = 0; |
245 |
else |
246 |
tm_init->tm_sec += 1; |
247 |
|
248 |
speed_last = speed_; |
249 |
speed = 0; |
250 |
} |
251 |
else if (tm_init->tm_sec != tm_cur.tm_sec + 1) |
252 |
/* If the disk crashes, again */ |
253 |
tm_init->tm_sec = tm_cur.tm_sec + 1; |
254 |
|
255 |
if (speed_last == 0) |
256 |
speed_last = speed_; |
257 |
|
258 |
/* bytes in KiB */ |
259 |
printf("%12.02f KiB/s | ", speed_last / speed_si, |
260 |
tm_init->tm_hour, tm_init->tm_min, tm_init->tm_sec, |
261 |
tm_cur.tm_hour, tm_cur.tm_min, tm_cur.tm_sec); |
262 |
|
263 |
|
264 |
fflush(stdout); |
265 |
} |
266 |
|
267 |
/* This function displays size source/dest files copy |
268 |
if the progress flag is set. */ |
269 |
|
270 |
void |
271 |
progress_bar_print_size(size_t dim_tot, size_t dim_cur) |
272 |
{ |
273 |
char dim_type; |
274 |
float dim_tot_, dim_cur_, dim_si = (float) 1024; |
275 |
|
276 |
dim_tot_ = (float) dim_tot; |
277 |
dim_cur_ = (float) dim_cur; |
278 |
|
279 |
/* display size in KiB */ |
280 |
dim_tot_ /= dim_si; |
281 |
dim_cur_ /= dim_si; |
282 |
dim_type = 'k'; |
283 |
/* If possible, convert in MiB */ |
284 |
if (dim_tot / (1024 * 1024)) |
285 |
{ |
286 |
dim_tot_ /= dim_si; |
287 |
dim_cur_ /= dim_si; |
288 |
dim_type = 'M'; |
289 |
|
290 |
/* If possible, convert in GiB */ |
291 |
if (dim_tot / (1024 * 1024 * 1024)) |
292 |
{ |
293 |
dim_tot_ /= dim_si; |
294 |
dim_cur_ /= dim_si; |
295 |
dim_type = 'G'; |
296 |
} |
297 |
} |
298 |
|
299 |
printf("%10.02f/%.02f %s | ", dim_cur_, dim_tot_, |
300 |
dim_type == 'k' ? "KiB" : dim_type == 'M' ? "MiB" : "GiB"); |
301 |
|
302 |
fflush(stdout); |
303 |
} |
304 |
|
305 |
/* This function displays ETA copy |
306 |
if the progress flag is set. */ |
307 |
|
308 |
void |
309 |
progress_bar_print_eta(size_t dim_tot, size_t dim_cur) |
310 |
{ |
311 |
size_t dim_diff = 0, |
312 |
speed_last_ = (size_t) speed_last, |
313 |
eta = 0; |
314 |
int sec, min, hour; |
315 |
|
316 |
/* Convert in KiB */ |
317 |
dim_tot /= 1024; |
318 |
dim_cur /= 1024; |
319 |
|
320 |
dim_diff = dim_tot - dim_cur; |
321 |
speed_last_ /= 1024; |
322 |
|
323 |
/* speed_last_ : 1 sec = dim_diff : eta |
324 |
|
325 |
eta = 1 * dim_diff |
326 |
------------ |
327 |
speed_last_ */ |
328 |
|
329 |
eta = dim_diff / speed_last_; |
330 |
|
331 |
min = eta / 60; |
332 |
sec = eta - (min * 60); |
333 |
hour = min / 60; |
334 |
|
335 |
printf("ETA: %02d:%02d:%02d", hour, min, sec); |
336 |
|
337 |
fflush(stdout); |
338 |
} |
339 |
|
173 |
/* Set the owner and owning group of DEST_DESC to the st_uid and |
340 |
/* Set the owner and owning group of DEST_DESC to the st_uid and |
174 |
st_gid fields of SRC_SB. If DEST_DESC is undefined (-1), set |
341 |
st_gid fields of SRC_SB. If DEST_DESC is undefined (-1), set |
175 |
the owner and owning group of DST_NAME instead; for |
342 |
the owner and owning group of DST_NAME instead; for |
Lines 482-487
Link Here
|
482 |
bool last_write_made_hole = false; |
649 |
bool last_write_made_hole = false; |
483 |
bool make_holes = false; |
650 |
bool make_holes = false; |
484 |
|
651 |
|
|
|
652 |
/* Progress bar */ |
653 |
size_t dim_tot = 0, |
654 |
dim_cur = 0; |
655 |
/* speed time */ |
656 |
time_t time_init; |
657 |
struct tm tm_init; |
658 |
|
485 |
if (S_ISREG (sb.st_mode)) |
659 |
if (S_ISREG (sb.st_mode)) |
486 |
{ |
660 |
{ |
487 |
/* Even with --sparse=always, try to create holes only |
661 |
/* Even with --sparse=always, try to create holes only |
Lines 537-542
Link Here
|
537 |
buf_alloc = xmalloc (buf_size + buf_alignment_slop); |
711 |
buf_alloc = xmalloc (buf_size + buf_alignment_slop); |
538 |
buf = ptr_align (buf_alloc, buf_alignment); |
712 |
buf = ptr_align (buf_alloc, buf_alignment); |
539 |
|
713 |
|
|
|
714 |
if (x->progress) |
715 |
{ |
716 |
time_init = time(NULL); |
717 |
tm_init = *(struct tm *) localtime(&time_init); |
718 |
tm_init.tm_sec += 1; |
719 |
} |
720 |
|
540 |
for (;;) |
721 |
for (;;) |
541 |
{ |
722 |
{ |
542 |
word *wp = NULL; |
723 |
word *wp = NULL; |
Lines 552-557
Link Here
|
552 |
return_val = false; |
733 |
return_val = false; |
553 |
goto close_src_and_dst_desc; |
734 |
goto close_src_and_dst_desc; |
554 |
} |
735 |
} |
|
|
736 |
|
555 |
if (n_read == 0) |
737 |
if (n_read == 0) |
556 |
break; |
738 |
break; |
557 |
|
739 |
|
Lines 611-616
Link Here
|
611 |
return_val = false; |
793 |
return_val = false; |
612 |
goto close_src_and_dst_desc; |
794 |
goto close_src_and_dst_desc; |
613 |
} |
795 |
} |
|
|
796 |
|
797 |
/* if the progress flag is set, it uses a progress bar */ |
798 |
if (x->progress) |
799 |
{ |
800 |
dim_tot = src_sb->st_size; |
801 |
dim_cur += n; |
802 |
|
803 |
/* print progress bar */ |
804 |
progress_bar_print(dim_tot, dim_cur); |
805 |
|
806 |
speed += n; |
807 |
|
808 |
/* print progress bar speed */ |
809 |
progress_bar_print_speed(&tm_init); |
810 |
|
811 |
/* print progress bar size */ |
812 |
progress_bar_print_size(dim_tot, dim_cur); |
813 |
|
814 |
/* print progress bar ETA */ |
815 |
progress_bar_print_eta(dim_tot, dim_cur); |
816 |
} |
817 |
|
614 |
last_write_made_hole = false; |
818 |
last_write_made_hole = false; |
615 |
|
819 |
|
616 |
/* A short read on a regular file means EOF. */ |
820 |
/* A short read on a regular file means EOF. */ |
Lines 619-624
Link Here
|
619 |
} |
823 |
} |
620 |
} |
824 |
} |
621 |
|
825 |
|
|
|
826 |
if (x->progress) |
827 |
putchar('\n'); |
828 |
|
622 |
/* If the file ends with a `hole', we need to do something to record |
829 |
/* If the file ends with a `hole', we need to do something to record |
623 |
the length of the file. On modern systems, calling ftruncate does |
830 |
the length of the file. On modern systems, calling ftruncate does |
624 |
the job. On systems without native ftruncate support, we have to |
831 |
the job. On systems without native ftruncate support, we have to |