]> git.pld-linux.org Git - packages/coreutils.git/blame - coreutils-advcopy.patch
Updated advancedcopy url.
[packages/coreutils.git] / coreutils-advcopy.patch
CommitLineData
7b540678
MK
1diff -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 }
270diff -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
303diff -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;
475diff -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, &copy_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, &copy_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 }
This page took 0.152914 seconds and 4 git commands to generate.