packages: coreutils/coreutils-advcopy.patch (NEW) - adds progress bar to cp...
paszczus
paszczus at pld-linux.org
Mon Jan 25 15:47:13 CET 2010
Author: paszczus Date: Mon Jan 25 14:47:13 2010 GMT
Module: packages Tag: HEAD
---- Log message:
- adds progress bar to cp, from http://www.beatex.org/web/advancedcopy.html
---- Files affected:
packages/coreutils:
coreutils-advcopy.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: packages/coreutils/coreutils-advcopy.patch
diff -u /dev/null packages/coreutils/coreutils-advcopy.patch:1.1
--- /dev/null Mon Jan 25 15:47:13 2010
+++ packages/coreutils/coreutils-advcopy.patch Mon Jan 25 15:47:08 2010
@@ -0,0 +1,347 @@
+diff -crB coreutils-8.4/src/copy.c coreutils-8.4-advcopy/src/copy.c
+*** coreutils-8.4/src/copy.c 2010-01-03 18:06:20.000000000 +0100
+--- coreutils-8.4-advcopy/src/copy.c 2010-01-25 10:54:50.000000000 +0100
+***************
+*** 457,462 ****
+--- 457,512 ----
+ return lchmod (name, mode);
+ }
+
++ /* BEGIN progress mod */
++ static void file_progress_bar ( char * _cDest, int _iBarLength, int _iProgress, int _iTotal )
++ {
++ // write number to progress bar
++ float fPercent = ( float ) _iProgress / ( float ) _iTotal * 100.f;
++ sprintf ( _cDest + ( _iBarLength - 6 ), "%4.1f", fPercent );
++ // remove zero
++ _cDest[_iBarLength - 2] = ' ';
++
++ // fill rest with '-'
++ int i;
++ for ( i = 1; i <= _iBarLength - 9; i++ )
++ {
++ if ( fPercent > ( float ) ( i - 1 ) / ( _iBarLength - 10 ) * 100.f )
++ _cDest[i] = '|';
++ else
++ _cDest[i] = '-';
++ }
++ }
++
++ int file_size_format ( char * _cDst, int _iSize, int _iCounter )
++ {
++ int iCounter = _iCounter;
++ double dSize = ( double ) _iSize;
++ while ( dSize >= 1000. )
++ {
++ dSize /= 1024.;
++ iCounter++;
++ }
++
++ /* get unit */
++ char * sUnit;
++ if ( iCounter == 0 )
++ sUnit = "B";
++ else if ( iCounter == 1 )
++ sUnit = "KiB";
++ else if ( iCounter == 2 )
++ sUnit = "MiB";
++ else if ( iCounter == 3 )
++ sUnit = "GiB";
++ else if ( iCounter == 4 )
++ sUnit = "TiB";
++ else
++ sUnit = "N/A";
++
++ /* write number */
++ return sprintf ( _cDst, "%5.1f %s", dSize, sUnit );
++ }
++ /* END progress mod */
++
+ /* Copy a regular file from SRC_NAME to DST_NAME.
+ If the source file contains holes, copies holes and blocks of zeros
+ in the source file as holes in the destination file.
+***************
+*** 630,636 ****
+ return_val = false;
+ goto close_src_and_dst_desc;
+ }
+!
+ if (x->reflink_mode)
+ {
+ bool clone_ok = clone_file (dest_desc, source_desc) == 0;
+--- 680,686 ----
+ return_val = false;
+ goto close_src_and_dst_desc;
+ }
+!
+ if (x->reflink_mode)
+ {
+ bool clone_ok = clone_file (dest_desc, source_desc) == 0;
+***************
+*** 706,713 ****
+--- 756,866 ----
+ buf_alloc = xmalloc (buf_size + buf_alignment_slop);
+ buf = ptr_align (buf_alloc, buf_alignment);
+
++ /* BEGIN progress mod */
++ /* create a field of 6 lines */
++ char ** cProgressField = ( char ** ) calloc ( 6, sizeof ( char * ) );
++ /* get console width */
++ int iBarLength = 80;
++ struct winsize win;
++ if ( ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &win) == 0 && win.ws_col > 0 )
++ iBarLength = win.ws_col;
++ /* create rows */
++ int it;
++ for ( it = 0; it < 6; it++ )
++ {
++ cProgressField[it] = ( char * ) malloc ( iBarLength + 1 );
++ /* init with spaces */
++ int j;
++ for ( j = 0; j < iBarLength; j++ )
++ cProgressField[it][j] = ' ';
++ cProgressField[it][iBarLength] = '\0';
++ }
++
++ /* global progress bar? */
++ if ( g_iTotalSize )
++ {
++ /* init global progress bar */
++ cProgressField[2][0] = '[';
++ cProgressField[2][iBarLength - 8] = ']';
++ cProgressField[2][iBarLength - 7] = ' ';
++ cProgressField[2][iBarLength - 1] = '%';
++
++ /* total size */
++ cProgressField[1][iBarLength - 11] = '/';
++ file_size_format ( cProgressField[1] + iBarLength - 9, g_iTotalSize, 1 );
++
++ /* show how many files were written */
++ int sum_length = sprintf ( cProgressField[1], "%d files copied so far...", g_iFilesCopied );
++ cProgressField[1][sum_length] = ' ';
++ }
++
++ /* truncate filename? */
++ int fn_length;
++ if ( strlen ( src_name ) > iBarLength - 22 )
++ fn_length =
++ sprintf ( cProgressField[4], "...%s", src_name + ( strlen ( src_name ) - iBarLength + 25 ) );
++ else
++ fn_length = sprintf ( cProgressField[4], "%s", src_name );
++ cProgressField[4][fn_length] = ' ';
++
++ /* filesize */
++ cProgressField[4][iBarLength - 11] = '/';
++ file_size_format ( cProgressField[4] + iBarLength - 9, src_open_sb.st_size, 0 );
++
++ int iCountDown = 1;
++ char * sProgressBar = cProgressField[5];
++ sProgressBar[0] = '[';
++ sProgressBar[iBarLength - 8] = ']';
++ sProgressBar[iBarLength - 7] = ' ';
++ sProgressBar[iBarLength - 1] = '%';
++ /* END progress mod */
++
+ for (;;)
+ {
++ /* BEGIN progress mod */
++ /* update countdown */
++ iCountDown--;
++ if ( iCountDown < 0 )
++ iCountDown = 100;
++
++ /* just print one line with the percentage, but not always */
++ if ( iCountDown == 0 )
++ {
++ int fs_len;
++ if ( g_iTotalSize )
++ {
++ /* global progress bar */
++ file_progress_bar ( cProgressField[2], iBarLength,
++ g_iTotalWritten + n_read_total / 1024, g_iTotalSize );
++
++ /* print the global status */
++ fs_len = file_size_format ( cProgressField[1] + iBarLength - 21,
++ g_iTotalWritten + n_read_total / 1024, 1 );
++ cProgressField[1][iBarLength - 21 + fs_len] = ' ';
++ }
++
++ /* current progress bar */
++ file_progress_bar ( sProgressBar, iBarLength, n_read_total, src_open_sb.st_size );
++
++ /* print the status */
++ fs_len = file_size_format ( cProgressField[4] + iBarLength - 21, n_read_total, 0 );
++ cProgressField[4][iBarLength - 21 + fs_len] = ' ';
++
++ /* print the field */
++ for ( it = g_iTotalSize ? 0 : 3; it < 6; it++ )
++ {
++ printf ( "%s\n", cProgressField[it] );
++ if ( strlen ( cProgressField[it] ) < iBarLength )
++ printf ( "" );
++ }
++ if ( g_iTotalSize )
++ printf ( "\r\033[6A" );
++ else
++ printf ( "\r\033[3A" );
++ fflush ( stdout );
++ }
++ /* END progress mod */
++
+ word *wp = NULL;
+
+ ssize_t n_read = read (source_desc, buf, buf_size);
+***************
+*** 788,793 ****
+--- 941,957 ----
+ /proc with linux kernels from at least 2.6.9 .. 2.6.29. */
+ }
+ }
++ /* BEGIN progress mod */
++ /* update total size */
++ g_iTotalWritten += n_read_total / 1024;
++ g_iFilesCopied++;
++
++ int i;
++ for ( i = 0; i < 6; i++ )
++ free ( cProgressField[i] );
++ free ( cProgressField );
++ /* END progress mod */
++
+
+ /* If the file ends with a `hole', we need to do something to record
+ the length of the file. On modern systems, calling ftruncate does
+diff -crB coreutils-8.4/src/copy.h coreutils-8.4-advcopy/src/copy.h
+*** coreutils-8.4/src/copy.h 2010-01-03 18:06:20.000000000 +0100
+--- coreutils-8.4-advcopy/src/copy.h 2010-01-25 10:54:50.000000000 +0100
+***************
+*** 280,283 ****
+--- 280,291 ----
+ bool chown_failure_ok (struct cp_options const *);
+ mode_t cached_umask (void);
+
++ /* BEGIN progress mod */
++ int file_size_format ( char * _cDst, int _iSize, int _iCounter );
++
++ long g_iTotalSize;
++ long g_iTotalWritten;
++ int g_iFilesCopied;
++ /* END progress mod */
++
+ #endif
+diff -crB coreutils-8.4/src/cp.c coreutils-8.4-advcopy/src/cp.c
+*** coreutils-8.4/src/cp.c 2010-01-04 16:46:06.000000000 +0100
+--- coreutils-8.4-advcopy/src/cp.c 2010-01-25 10:54:50.000000000 +0100
+***************
+*** 611,616 ****
+--- 611,626 ----
+ error (EXIT_FAILURE, 0, _("target %s is not a directory"),
+ quote (file[n_files - 1]));
+ }
++
++ /* BEGIN progress mod */
++ g_iTotalSize = 0;
++ g_iFilesCopied = 0;
++ g_iTotalWritten = 0;
++
++ /* save time */
++ struct timeval start_time;
++ gettimeofday ( & start_time, NULL );
++ /* END progress mod */
+
+ if (target_directory)
+ {
+***************
+*** 627,632 ****
+--- 637,680 ----
+ dest_info_init (x);
+ src_info_init (x);
+ }
++
++ /* BEGIN progress mod */
++ printf ( "Calculating total size... \r" );
++ fflush ( stdout );
++ long iTotalSize = 0;
++ for (i = 0; i < n_files; i++)
++ {
++ /* call du -s for each file */
++ /* create command */
++ char command[1024];
++ sprintf ( command, "/usr/bin/du -s \"%s\"", file[i] );
++ /* TODO: replace all quote signs in file[i] */
++
++ FILE *fp;
++ char output[1024];
++
++ /* run command */
++ fp = popen(command, "r");
++ if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) {
++ printf("failed to run du.\n" );
++ }
++ else
++ {
++ /* isolate size */
++ strchr ( output, '\t' )[0] = '\0';
++ iTotalSize += atol ( output );
++
++ printf ( "Calculating total size... %d\r", iTotalSize );
++ fflush ( stdout );
++ }
++
++ /* close */
++ pclose(fp);
++ }
++ g_iTotalSize = iTotalSize;
++ g_iTotalWritten = 0;
++ g_iFilesCopied = 0;
++ /* END progress mod */
+
+ for (i = 0; i < n_files; i++)
+ {
+***************
+*** 753,758 ****
+--- 801,844 ----
+
+ ok = copy (source, new_dest, 0, x, &unused, NULL);
+ }
++
++ /* BEGIN progress mod */
++ /* remove everything */
++ int i;
++ if ( g_iTotalSize )
++ {
++ for ( i = 0; i < 6; i++ )
++ printf ( "\033[K\n" );
++ printf ( "\r\033[6A" );
++ }
++ else
++ {
++ for ( i = 0; i < 3; i++ )
++ printf ( "\033[K\n" );
++ printf ( "\r\033[3A" );
++ }
++
++ /* save time */
++ struct timeval end_time;
++ gettimeofday ( & end_time, NULL );
++ int usec_elapsed = end_time.tv_usec - start_time.tv_usec;
++ double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
++ sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec );
++
++ /* get total size */
++ char sTotalWritten[20];
++ file_size_format ( sTotalWritten, g_iTotalSize, 1 );
++ /* TODO: using g_iTotalWritten would be more correct, but is less accurate */
++
++ /* calculate speed */
++ int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed );
++ char s_copy_speed[20];
++ file_size_format ( s_copy_speed, copy_speed, 1 );
++
++ /* good-bye message */
++ printf ( "%d files (%s) copied in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten,
++ sec_elapsed, s_copy_speed );
++ /* END progress mod */
+
+ return ok;
+ }
================================================================
More information about the pld-cvs-commit
mailing list