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