]>
Commit | Line | Data |
---|---|---|
7b540678 MK |
1 | diff -crB coreutils-8.21/src/copy.c coreutils-8.21-patch0.5/src/copy.c |
2 | *** coreutils-8.21/src/copy.c 2013-02-07 10:37:05.000000000 +0100 | |
3 | --- coreutils-8.21-patch0.5/src/copy.c 2013-02-23 12:53:51.000000000 +0100 | |
4 | *************** | |
5 | *** 135,140 **** | |
6 | --- 135,190 ---- | |
7 | return err; | |
8 | } | |
9 | ||
10 | + /* BEGIN progress mod */ | |
11 | + static void file_progress_bar ( char * _cDest, int _iBarLength, int _iProgress, int _iTotal ) | |
12 | + { | |
13 | + // write number to progress bar | |
14 | + float fPercent = ( float ) _iProgress / ( float ) _iTotal * 100.f; | |
15 | + sprintf ( _cDest + ( _iBarLength - 6 ), "%4.1f", fPercent ); | |
16 | + // remove zero | |
17 | + _cDest[_iBarLength - 2] = ' '; | |
18 | + | |
19 | + // fill rest with '-' | |
20 | + int i; | |
21 | + for ( i = 1; i <= _iBarLength - 9; i++ ) | |
22 | + { | |
23 | + if ( fPercent > ( float ) ( i - 1 ) / ( _iBarLength - 10 ) * 100.f ) | |
24 | + _cDest[i] = '|'; | |
25 | + else | |
26 | + _cDest[i] = '-'; | |
27 | + } | |
28 | + } | |
29 | + | |
30 | + int file_size_format ( char * _cDst, int _iSize, int _iCounter ) | |
31 | + { | |
32 | + int iCounter = _iCounter; | |
33 | + double dSize = ( double ) _iSize; | |
34 | + while ( dSize >= 1000. ) | |
35 | + { | |
36 | + dSize /= 1024.; | |
37 | + iCounter++; | |
38 | + } | |
39 | + | |
40 | + /* get unit */ | |
41 | + char * sUnit; | |
42 | + if ( iCounter == 0 ) | |
43 | + sUnit = "B"; | |
44 | + else if ( iCounter == 1 ) | |
45 | + sUnit = "KiB"; | |
46 | + else if ( iCounter == 2 ) | |
47 | + sUnit = "MiB"; | |
48 | + else if ( iCounter == 3 ) | |
49 | + sUnit = "GiB"; | |
50 | + else if ( iCounter == 4 ) | |
51 | + sUnit = "TiB"; | |
52 | + else | |
53 | + sUnit = "N/A"; | |
54 | + | |
55 | + /* write number */ | |
56 | + return sprintf ( _cDst, "%5.1f %s", dSize, sUnit ); | |
57 | + } | |
58 | + /* END progress mod */ | |
59 | + | |
60 | /* Copy the regular file open on SRC_FD/SRC_NAME to DST_FD/DST_NAME, | |
61 | honoring the MAKE_HOLES setting and using the BUF_SIZE-byte buffer | |
62 | BUF for temporary storage. Copy no more than MAX_N_READ bytes. | |
63 | *************** | |
64 | *** 151,163 **** | |
65 | bool make_holes, | |
66 | char const *src_name, char const *dst_name, | |
67 | uintmax_t max_n_read, off_t *total_n_read, | |
68 | ! bool *last_write_made_hole) | |
69 | { | |
70 | *last_write_made_hole = false; | |
71 | *total_n_read = 0; | |
72 | ||
73 | while (max_n_read) | |
74 | { | |
75 | bool make_hole = false; | |
76 | ||
77 | ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size)); | |
78 | --- 201,369 ---- | |
79 | bool make_holes, | |
80 | char const *src_name, char const *dst_name, | |
81 | uintmax_t max_n_read, off_t *total_n_read, | |
82 | ! bool *last_write_made_hole | |
83 | ! ) | |
84 | { | |
85 | + /* BEGIN progress mod */ | |
86 | + /* create a field of 6 lines */ | |
87 | + char ** cProgressField = ( char ** ) calloc ( 6, sizeof ( char * ) ); | |
88 | + /* get console width */ | |
89 | + int iBarLength = 80; | |
90 | + struct winsize win; | |
91 | + if ( ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &win) == 0 && win.ws_col > 0 ) | |
92 | + iBarLength = win.ws_col; | |
93 | + /* create rows */ | |
94 | + int it; | |
95 | + for ( it = 0; it < 6; it++ ) | |
96 | + { | |
97 | + cProgressField[it] = ( char * ) malloc ( iBarLength + 1 ); | |
98 | + /* init with spaces */ | |
99 | + int j; | |
100 | + for ( j = 0; j < iBarLength; j++ ) | |
101 | + cProgressField[it][j] = ' '; | |
102 | + cProgressField[it][iBarLength] = '\0'; | |
103 | + } | |
104 | + | |
105 | + /* global progress bar? */ | |
106 | + if ( g_iTotalSize ) | |
107 | + { | |
108 | + /* init global progress bar */ | |
109 | + cProgressField[2][0] = '['; | |
110 | + cProgressField[2][iBarLength - 8] = ']'; | |
111 | + cProgressField[2][iBarLength - 7] = ' '; | |
112 | + cProgressField[2][iBarLength - 1] = '%'; | |
113 | + | |
114 | + /* total size */ | |
115 | + cProgressField[1][iBarLength - 11] = '/'; | |
116 | + file_size_format ( cProgressField[1] + iBarLength - 9, g_iTotalSize, 1 ); | |
117 | + | |
118 | + /* show how many files were written */ | |
119 | + int sum_length = sprintf ( cProgressField[1], "%d files copied so far...", g_iFilesCopied ); | |
120 | + cProgressField[1][sum_length] = ' '; | |
121 | + } | |
122 | + | |
123 | + /* truncate filename? */ | |
124 | + int fn_length; | |
125 | + if ( strlen ( src_name ) > iBarLength - 22 ) | |
126 | + fn_length = | |
127 | + sprintf ( cProgressField[4], "...%s", src_name + ( strlen ( src_name ) - iBarLength + 25 ) ); | |
128 | + else | |
129 | + fn_length = sprintf ( cProgressField[4], "%s", src_name ); | |
130 | + cProgressField[4][fn_length] = ' '; | |
131 | + | |
132 | + /* filesize */ | |
133 | + int file_size = max_n_read; | |
134 | + struct stat file_stat; | |
135 | + if (fstat(src_fd, & file_stat) == 0) | |
136 | + file_size = file_stat.st_size; | |
137 | + cProgressField[4][iBarLength - 11] = '/'; | |
138 | + file_size_format ( cProgressField[4] + iBarLength - 9, file_size, 0 ); | |
139 | + | |
140 | + int iCountDown = 1; | |
141 | + char * sProgressBar = cProgressField[5]; | |
142 | + sProgressBar[0] = '['; | |
143 | + sProgressBar[iBarLength - 8] = ']'; | |
144 | + sProgressBar[iBarLength - 7] = ' '; | |
145 | + sProgressBar[iBarLength - 1] = '%'; | |
146 | + | |
147 | + /* this will always save the time in between */ | |
148 | + struct timeval last_time; | |
149 | + gettimeofday ( & last_time, NULL ); | |
150 | + int last_size = g_iTotalWritten; | |
151 | + /* END progress mod */ | |
152 | + | |
153 | *last_write_made_hole = false; | |
154 | *total_n_read = 0; | |
155 | ||
156 | while (max_n_read) | |
157 | { | |
158 | + /* BEGIN progress mod */ | |
159 | + if (progress) { | |
160 | + /* update countdown */ | |
161 | + iCountDown--; | |
162 | + if ( iCountDown < 0 ) | |
163 | + { | |
164 | + /* average copy speed is assumed to be around 10 MiB/s, just to be safe. | |
165 | + * the status should be updated about 10 times per second, or approximately | |
166 | + * once per 1 MiB transferred. */ | |
167 | + iCountDown = 1024 * 1024 / buf_size; | |
168 | + /* must be greater than 0 */ | |
169 | + if (iCountDown < 1) | |
170 | + iCountDown = 1; | |
171 | + /* limit */ | |
172 | + if (iCountDown > 100) | |
173 | + iCountDown = 100; | |
174 | + } | |
175 | + | |
176 | + /* just print one line with the percentage, but not always */ | |
177 | + if ( iCountDown == 0 ) | |
178 | + { | |
179 | + /* calculate current speed */ | |
180 | + struct timeval cur_time; | |
181 | + gettimeofday ( & cur_time, NULL ); | |
182 | + int cur_size = g_iTotalWritten + *total_n_read / 1024; | |
183 | + int usec_elapsed = cur_time.tv_usec - last_time.tv_usec; | |
184 | + double sec_elapsed = ( double ) usec_elapsed / 1000000.f; | |
185 | + sec_elapsed += ( double ) ( cur_time.tv_sec - last_time.tv_sec ); | |
186 | + int copy_speed = ( int ) ( ( double ) ( cur_size - last_size ) | |
187 | + / sec_elapsed ); | |
188 | + if (copy_speed < 0) | |
189 | + copy_speed = 0; | |
190 | + char s_copy_speed[20]; | |
191 | + file_size_format ( s_copy_speed, copy_speed, 1 ); | |
192 | + /* update vars */ | |
193 | + last_time = cur_time; | |
194 | + last_size = cur_size; | |
195 | + | |
196 | + /* how much time has passed since the start? */ | |
197 | + int isec_elapsed = cur_time.tv_sec - g_oStartTime.tv_sec; | |
198 | + int sec_remaining = ( int ) ( ( double ) isec_elapsed / cur_size | |
199 | + * g_iTotalSize ) - isec_elapsed; | |
200 | + int min_remaining = sec_remaining / 60; | |
201 | + sec_remaining -= min_remaining * 60; | |
202 | + int hours_remaining = min_remaining / 60; | |
203 | + min_remaining -= hours_remaining * 60; | |
204 | + /* print out */ | |
205 | + sprintf ( cProgressField[3], | |
206 | + "Copying at %s/s (about %dh %dm %ds remaining)", s_copy_speed, | |
207 | + hours_remaining, min_remaining, sec_remaining ); | |
208 | + | |
209 | + int fs_len; | |
210 | + if ( g_iTotalSize ) | |
211 | + { | |
212 | + /* global progress bar */ | |
213 | + file_progress_bar ( cProgressField[2], iBarLength, | |
214 | + g_iTotalWritten + *total_n_read / 1024, g_iTotalSize ); | |
215 | + | |
216 | + /* print the global status */ | |
217 | + fs_len = file_size_format ( cProgressField[1] + iBarLength - 21, | |
218 | + g_iTotalWritten + *total_n_read / 1024, 1 ); | |
219 | + cProgressField[1][iBarLength - 21 + fs_len] = ' '; | |
220 | + } | |
221 | + | |
222 | + /* current progress bar */ | |
223 | + file_progress_bar ( sProgressBar, iBarLength, *total_n_read, file_size ); | |
224 | + | |
225 | + /* print the status */ | |
226 | + fs_len = file_size_format ( cProgressField[4] + iBarLength - 21, *total_n_read, 0 ); | |
227 | + cProgressField[4][iBarLength - 21 + fs_len] = ' '; | |
228 | + | |
229 | + /* print the field */ | |
230 | + for ( it = g_iTotalSize ? 0 : 3; it < 6; it++ ) | |
231 | + { | |
232 | + printf ( "\033[K%s\n", cProgressField[it] ); | |
233 | + if ( strlen ( cProgressField[it] ) < iBarLength ) | |
234 | + printf ( "" ); | |
235 | + } | |
236 | + if ( g_iTotalSize ) | |
237 | + printf ( "\r\033[6A" ); | |
238 | + else | |
239 | + printf ( "\r\033[3A" ); | |
240 | + fflush ( stdout ); | |
241 | + } | |
242 | + } | |
243 | + /* END progress mod */ | |
244 | + | |
245 | bool make_hole = false; | |
246 | ||
247 | ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size)); | |
248 | *************** | |
249 | *** 215,220 **** | |
250 | --- 421,439 ---- | |
251 | ||
252 | *last_write_made_hole = make_hole; | |
253 | } | |
254 | + | |
255 | + if (progress) { | |
256 | + /* BEGIN progress mod */ | |
257 | + /* update total size */ | |
258 | + g_iTotalWritten += *total_n_read / 1024; | |
259 | + g_iFilesCopied++; | |
260 | + | |
261 | + int i; | |
262 | + for ( i = 0; i < 6; i++ ) | |
263 | + free ( cProgressField[i] ); | |
264 | + free ( cProgressField ); | |
265 | + /* END progress mod */ | |
266 | + } | |
267 | ||
268 | return true; | |
269 | } | |
270 | diff -crB coreutils-8.21/src/copy.h coreutils-8.21-patch0.5/src/copy.h | |
271 | *** coreutils-8.21/src/copy.h 2013-01-31 01:46:24.000000000 +0100 | |
272 | --- coreutils-8.21-patch0.5/src/copy.h 2013-02-23 12:53:51.000000000 +0100 | |
273 | *************** | |
274 | *** 227,232 **** | |
275 | --- 227,235 ---- | |
276 | /* If true, create symbolic links instead of copying files. | |
277 | Create destination directories as usual. */ | |
278 | bool symbolic_link; | |
279 | + | |
280 | + /* If true, draw a nice progress bar on screen */ | |
281 | + bool progress_bar; | |
282 | ||
283 | /* If true, do not copy a nondirectory that has an existing destination | |
284 | with the same or newer modification time. */ | |
285 | *************** | |
286 | *** 286,289 **** | |
287 | --- 289,303 ---- | |
288 | bool chown_failure_ok (struct cp_options const *) _GL_ATTRIBUTE_PURE; | |
289 | mode_t cached_umask (void); | |
290 | ||
291 | + /* BEGIN progress mod */ | |
292 | + int file_size_format ( char * _cDst, int _iSize, int _iCounter ); | |
293 | + | |
294 | + long g_iTotalSize; | |
295 | + long g_iTotalWritten; | |
296 | + int g_iFilesCopied; | |
297 | + struct timeval g_oStartTime; | |
298 | + int g_iTotalFiles; | |
299 | + bool progress; | |
300 | + /* END progress mod */ | |
301 | + | |
302 | #endif | |
303 | diff -crB coreutils-8.21/src/cp.c coreutils-8.21-patch0.5/src/cp.c | |
304 | *** coreutils-8.21/src/cp.c 2013-02-07 10:37:05.000000000 +0100 | |
305 | --- coreutils-8.21-patch0.5/src/cp.c 2013-02-23 12:53:51.000000000 +0100 | |
306 | *************** | |
307 | *** 141,146 **** | |
308 | --- 141,147 ---- | |
309 | {"target-directory", required_argument, NULL, 't'}, | |
310 | {"update", no_argument, NULL, 'u'}, | |
311 | {"verbose", no_argument, NULL, 'v'}, | |
312 | + {"progress-bar", no_argument, NULL, 'g'}, | |
313 | {GETOPT_HELP_OPTION_DECL}, | |
314 | {GETOPT_VERSION_OPTION_DECL}, | |
315 | {NULL, 0, NULL, 0} | |
316 | *************** | |
317 | *** 178,183 **** | |
318 | --- 179,185 ---- | |
319 | -f, --force if an existing destination file cannot be\n\ | |
320 | opened, remove it and try again (this option\n\ | |
321 | is ignored when the -n option is also used)\n\ | |
322 | + -g, --progress-bar add progress-bar\n\ | |
323 | -i, --interactive prompt before overwrite (overrides a previous -n\ | |
324 | \n\ | |
325 | option)\n\ | |
326 | *************** | |
327 | *** 617,622 **** | |
328 | --- 619,675 ---- | |
329 | error (EXIT_FAILURE, 0, _("target %s is not a directory"), | |
330 | quote (file[n_files - 1])); | |
331 | } | |
332 | + | |
333 | + /* BEGIN progress mod */ | |
334 | + struct timeval start_time; | |
335 | + if (progress) { | |
336 | + g_iTotalSize = 0; | |
337 | + g_iFilesCopied = 0; | |
338 | + g_iTotalWritten = 0; | |
339 | + | |
340 | + /* save time */ | |
341 | + gettimeofday ( & start_time, NULL ); | |
342 | + g_oStartTime = start_time; | |
343 | + | |
344 | + printf ( "Calculating total size... \r" ); | |
345 | + fflush ( stdout ); | |
346 | + long iTotalSize = 0; | |
347 | + int iFiles = n_files; | |
348 | + if ( ! target_directory ) | |
349 | + iFiles = n_files - 1; | |
350 | + int j; | |
351 | + for (j = 0; j < iFiles; j++) | |
352 | + { | |
353 | + /* call du -s for each file */ | |
354 | + /* create command */ | |
355 | + char command[1024]; | |
356 | + sprintf ( command, "du -s \"%s\"", file[j] ); | |
357 | + /* TODO: replace all quote signs in file[i] */ | |
358 | + | |
359 | + FILE *fp; | |
360 | + char output[1024]; | |
361 | + | |
362 | + /* run command */ | |
363 | + fp = popen(command, "r"); | |
364 | + if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) { | |
365 | + printf("failed to run du.\n" ); | |
366 | + } | |
367 | + else | |
368 | + { | |
369 | + /* isolate size */ | |
370 | + strchr ( output, '\t' )[0] = '\0'; | |
371 | + iTotalSize += atol ( output ); | |
372 | + | |
373 | + printf ( "Calculating total size... %ld\r", iTotalSize ); | |
374 | + fflush ( stdout ); | |
375 | + } | |
376 | + | |
377 | + /* close */ | |
378 | + pclose(fp); | |
379 | + } | |
380 | + g_iTotalSize = iTotalSize; | |
381 | + } | |
382 | + /* END progress mod */ | |
383 | ||
384 | if (target_directory) | |
385 | { | |
386 | *************** | |
387 | *** 759,764 **** | |
388 | --- 812,857 ---- | |
389 | ||
390 | ok = copy (source, new_dest, 0, x, &unused, NULL); | |
391 | } | |
392 | + | |
393 | + /* BEGIN progress mod */ | |
394 | + if (progress) { | |
395 | + /* remove everything */ | |
396 | + int i; | |
397 | + if ( g_iTotalSize ) | |
398 | + { | |
399 | + for ( i = 0; i < 6; i++ ) | |
400 | + printf ( "\033[K\n" ); | |
401 | + printf ( "\r\033[6A" ); | |
402 | + } | |
403 | + else | |
404 | + { | |
405 | + for ( i = 0; i < 3; i++ ) | |
406 | + printf ( "\033[K\n" ); | |
407 | + printf ( "\r\033[3A" ); | |
408 | + } | |
409 | + | |
410 | + /* save time */ | |
411 | + struct timeval end_time; | |
412 | + gettimeofday ( & end_time, NULL ); | |
413 | + int usec_elapsed = end_time.tv_usec - start_time.tv_usec; | |
414 | + double sec_elapsed = ( double ) usec_elapsed / 1000000.f; | |
415 | + sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec ); | |
416 | + | |
417 | + /* get total size */ | |
418 | + char sTotalWritten[20]; | |
419 | + file_size_format ( sTotalWritten, g_iTotalSize, 1 ); | |
420 | + /* TODO: using g_iTotalWritten would be more correct, but is less accurate */ | |
421 | + | |
422 | + /* calculate speed */ | |
423 | + int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed ); | |
424 | + char s_copy_speed[20]; | |
425 | + file_size_format ( s_copy_speed, copy_speed, 1 ); | |
426 | + | |
427 | + /* good-bye message */ | |
428 | + printf ( "%d files (%s) copied in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten, | |
429 | + sec_elapsed, s_copy_speed ); | |
430 | + } | |
431 | + /* END progress mod */ | |
432 | ||
433 | return ok; | |
434 | } | |
435 | *************** | |
436 | *** 793,798 **** | |
437 | --- 886,892 ---- | |
438 | x->recursive = false; | |
439 | x->sparse_mode = SPARSE_AUTO; | |
440 | x->symbolic_link = false; | |
441 | + x->progress_bar = false; | |
442 | x->set_mode = false; | |
443 | x->mode = 0; | |
444 | ||
445 | *************** | |
446 | *** 933,939 **** | |
447 | we'll actually use backup_suffix_string. */ | |
448 | backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); | |
449 | ||
450 | ! while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", | |
451 | long_opts, NULL)) | |
452 | != -1) | |
453 | { | |
454 | --- 1027,1033 ---- | |
455 | we'll actually use backup_suffix_string. */ | |
456 | backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); | |
457 | ||
458 | ! while ((c = getopt_long (argc, argv, "abdfgHilLnprst:uvxPRS:T", | |
459 | long_opts, NULL)) | |
460 | != -1) | |
461 | { | |
462 | *************** | |
463 | *** 990,995 **** | |
464 | --- 1084,1093 ---- | |
465 | x.unlink_dest_after_failed_open = true; | |
466 | break; | |
467 | ||
468 | + case 'g': | |
469 | + progress = true; | |
470 | + break; | |
471 | + | |
472 | case 'H': | |
473 | x.dereference = DEREF_COMMAND_LINE_ARGUMENTS; | |
474 | break; | |
475 | diff -crB coreutils-8.21/src/mv.c coreutils-8.21-patch0.5/src/mv.c | |
476 | *** coreutils-8.21/src/mv.c 2013-02-07 10:37:05.000000000 +0100 | |
477 | --- coreutils-8.21-patch0.5/src/mv.c 2013-03-12 21:23:58.000000000 +0100 | |
478 | *************** | |
479 | *** 64,69 **** | |
480 | --- 64,70 ---- | |
481 | {"target-directory", required_argument, NULL, 't'}, | |
482 | {"update", no_argument, NULL, 'u'}, | |
483 | {"verbose", no_argument, NULL, 'v'}, | |
484 | + {"progress-bar", no_argument, NULL, 'g'}, | |
485 | {GETOPT_HELP_OPTION_DECL}, | |
486 | {GETOPT_VERSION_OPTION_DECL}, | |
487 | {NULL, 0, NULL, 0} | |
488 | *************** | |
489 | *** 165,171 **** | |
490 | bool copy_into_self; | |
491 | bool rename_succeeded; | |
492 | bool ok = copy (source, dest, false, x, ©_into_self, &rename_succeeded); | |
493 | ! | |
494 | if (ok) | |
495 | { | |
496 | char const *dir_to_remove; | |
497 | --- 166,172 ---- | |
498 | bool copy_into_self; | |
499 | bool rename_succeeded; | |
500 | bool ok = copy (source, dest, false, x, ©_into_self, &rename_succeeded); | |
501 | ! | |
502 | if (ok) | |
503 | { | |
504 | char const *dir_to_remove; | |
505 | *************** | |
506 | *** 300,305 **** | |
507 | --- 301,307 ---- | |
508 | \n\ | |
509 | -b like --backup but does not accept an argument\n\ | |
510 | -f, --force do not prompt before overwriting\n\ | |
511 | + -g, --progress-bar add progress-bar\n\ | |
512 | -i, --interactive prompt before overwrite\n\ | |
513 | -n, --no-clobber do not overwrite an existing file\n\ | |
514 | If you specify more than one of -i, -f, -n, only the final one takes effect.\n\ | |
515 | *************** | |
516 | *** 368,374 **** | |
517 | we'll actually use backup_suffix_string. */ | |
518 | backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); | |
519 | ||
520 | ! while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL)) | |
521 | != -1) | |
522 | { | |
523 | switch (c) | |
524 | --- 370,376 ---- | |
525 | we'll actually use backup_suffix_string. */ | |
526 | backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); | |
527 | ||
528 | ! while ((c = getopt_long (argc, argv, "bfint:uvgS:T", long_options, NULL)) | |
529 | != -1) | |
530 | { | |
531 | switch (c) | |
532 | *************** | |
533 | *** 414,419 **** | |
534 | --- 416,424 ---- | |
535 | case 'v': | |
536 | x.verbose = true; | |
537 | break; | |
538 | + case 'g': | |
539 | + progress = true; | |
540 | + break; | |
541 | case 'S': | |
542 | make_backups = true; | |
543 | backup_suffix_string = optarg; | |
544 | *************** | |
545 | *** 476,481 **** | |
546 | --- 481,537 ---- | |
547 | : no_backups); | |
548 | ||
549 | hash_init (); | |
550 | + | |
551 | + /* BEGIN progress mod */ | |
552 | + struct timeval start_time; | |
553 | + | |
554 | + if(progress) { | |
555 | + g_iTotalSize = 0; | |
556 | + g_iFilesCopied = 0; | |
557 | + g_iTotalWritten = 0; | |
558 | + | |
559 | + gettimeofday (& start_time, NULL); | |
560 | + g_oStartTime = start_time; | |
561 | + | |
562 | + printf ("Calculating total size... \r"); | |
563 | + fflush (stdout); | |
564 | + long iTotalSize = 0; | |
565 | + int iFiles = n_files; | |
566 | + if ( !target_directory ) | |
567 | + iFiles = 1; | |
568 | + int j; | |
569 | + for (j = 0; j < iFiles; j++) | |
570 | + { | |
571 | + /* call du -s for each file */ | |
572 | + /* create command */ | |
573 | + char command[1024]; | |
574 | + sprintf ( command, "du -s \"%s\"", file[j] ); | |
575 | + /* TODO: replace all quote signs in file[i] */ | |
576 | + | |
577 | + FILE *fp; | |
578 | + char output[1024]; | |
579 | + | |
580 | + /* run command */ | |
581 | + fp = popen(command, "r"); | |
582 | + if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) { | |
583 | + printf("failed to run du.\n" ); | |
584 | + } | |
585 | + else | |
586 | + { | |
587 | + /* isolate size */ | |
588 | + strchr ( output, '\t' )[0] = '\0'; | |
589 | + iTotalSize += atol ( output ); | |
590 | + | |
591 | + printf ( "Calculating total size... %ld\r", iTotalSize ); | |
592 | + fflush ( stdout ); | |
593 | + } | |
594 | + | |
595 | + /* close */ | |
596 | + pclose(fp); | |
597 | + } | |
598 | + g_iTotalSize = iTotalSize; | |
599 | + } | |
600 | + /* END progress mod */ | |
601 | ||
602 | if (target_directory) | |
603 | { | |
604 | *************** | |
605 | *** 493,498 **** | |
606 | --- 549,594 ---- | |
607 | } | |
608 | else | |
609 | ok = movefile (file[0], file[1], false, &x); | |
610 | + | |
611 | + /* BEGIN progress mod */ | |
612 | + if (progress) { | |
613 | + /* remove everything */ | |
614 | + int i; | |
615 | + if ( g_iTotalSize ) | |
616 | + { | |
617 | + for ( i = 0; i < 6; i++ ) | |
618 | + printf ( "\033[K\n" ); | |
619 | + printf ( "\r\033[6A" ); | |
620 | + } | |
621 | + else | |
622 | + { | |
623 | + for ( i = 0; i < 3; i++ ) | |
624 | + printf ( "\033[K\n" ); | |
625 | + printf ( "\r\033[3A" ); | |
626 | + } | |
627 | + | |
628 | + /* save time */ | |
629 | + struct timeval end_time; | |
630 | + gettimeofday ( & end_time, NULL ); | |
631 | + int usec_elapsed = end_time.tv_usec - start_time.tv_usec; | |
632 | + double sec_elapsed = ( double ) usec_elapsed / 1000000.f; | |
633 | + sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec ); | |
634 | + | |
635 | + /* get total size */ | |
636 | + char sTotalWritten[20]; | |
637 | + file_size_format ( sTotalWritten, g_iTotalSize, 1 ); | |
638 | + /* TODO: using g_iTotalWritten would be more correct, but is less accurate */ | |
639 | + | |
640 | + /* calculate speed */ | |
641 | + int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed ); | |
642 | + char s_copy_speed[20]; | |
643 | + file_size_format ( s_copy_speed, copy_speed, 1 ); | |
644 | + | |
645 | + /* good-bye message */ | |
646 | + printf ( "%d files (%s) moved in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten, | |
647 | + sec_elapsed, s_copy_speed ); | |
648 | + } | |
649 | + /* END progress mod */ | |
650 | ||
651 | exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); | |
652 | } |