]> git.pld-linux.org Git - packages/coreutils.git/blob - coreutils-advcopy.patch
- install su man page
[packages/coreutils.git] / coreutils-advcopy.patch
1 diff -ru coreutils-8.4.orig/src/copy.c coreutils-8.4/src/copy.c
2 --- coreutils-8.4.orig/src/copy.c       2010-01-25 16:03:29.606930239 +0100
3 +++ coreutils-8.4/src/copy.c    2010-01-26 15:37:24.544158220 +0100
4 @@ -457,6 +457,56 @@
5    return lchmod (name, mode);
6  }
7  
8 +/* BEGIN progress mod */
9 +static void file_progress_bar ( char * _cDest, int _iBarLength, int _iProgress, int _iTotal )
10 +{
11 +  // write number to progress bar
12 +  float fPercent = ( float ) _iProgress / ( float ) _iTotal * 100.f;
13 +  sprintf ( _cDest + ( _iBarLength - 6 ), "%4.1f", fPercent );
14 +  // remove zero
15 +  _cDest[_iBarLength - 2] = ' ';
16 +
17 +  // fill rest with '-'
18 +  int i;
19 +  for ( i = 1; i <= _iBarLength - 9; i++ )
20 +  {
21 +    if ( fPercent > ( float ) ( i - 1 ) / ( _iBarLength - 10 ) * 100.f )
22 +      _cDest[i] = '|';
23 +    else
24 +      _cDest[i] = '-';
25 +  }
26 +}
27 +
28 +int file_size_format ( char * _cDst, int _iSize, int _iCounter )
29 +{
30 +  int iCounter = _iCounter;
31 +  double dSize = ( double ) _iSize;
32 +  while ( dSize >= 1000. )
33 +  {
34 +    dSize /= 1024.;
35 +    iCounter++;
36 +  }
37 +
38 +  /* get unit */
39 +  char * sUnit;
40 +  if ( iCounter == 0 )
41 +    sUnit = "B";
42 +  else if ( iCounter == 1 )
43 +    sUnit = "KiB";
44 +  else if ( iCounter == 2 )
45 +    sUnit = "MiB";
46 +  else if ( iCounter == 3 )
47 +    sUnit = "GiB";
48 +  else if ( iCounter == 4 )
49 +    sUnit = "TiB";
50 +  else
51 +    sUnit = "N/A";
52 +
53 +  /* write number */
54 +  return sprintf ( _cDst, "%5.1f %s", dSize, sUnit );
55 +}
56 +/* END progress mod */
57 +
58  /* Copy a regular file from SRC_NAME to DST_NAME.
59     If the source file contains holes, copies holes and blocks of zeros
60     in the source file as holes in the destination file.
61 @@ -706,8 +756,146 @@
62        buf_alloc = xmalloc (buf_size + buf_alignment_slop);
63        buf = ptr_align (buf_alloc, buf_alignment);
64  
65 +      /* BEGIN progress mod */
66 +      /* create a field of 6 lines */
67 +      char ** cProgressField = ( char ** ) calloc ( 6, sizeof ( char * ) );
68 +      /* get console width */
69 +      int iBarLength = 80;
70 +      struct winsize win;
71 +      if ( ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &win) == 0 && win.ws_col > 0 )
72 +         iBarLength = win.ws_col;
73 +      /* create rows */
74 +      int it;
75 +      for ( it = 0; it < 6; it++ )
76 +      {
77 +        cProgressField[it] = ( char * ) malloc ( iBarLength + 1 );
78 +        /* init with spaces */
79 +        int j;
80 +        for ( j = 0; j < iBarLength; j++ )
81 +          cProgressField[it][j] = ' ';
82 +        cProgressField[it][iBarLength] = '\0';
83 +      }
84 +
85 +      /* global progress bar? */
86 +      if ( g_iTotalSize )
87 +      {
88 +        /* init global progress bar */
89 +        cProgressField[2][0] = '[';
90 +        cProgressField[2][iBarLength - 8] = ']';
91 +        cProgressField[2][iBarLength - 7] = ' ';
92 +        cProgressField[2][iBarLength - 1] = '%';
93 +
94 +        /* total size */
95 +        cProgressField[1][iBarLength - 11] = '/';
96 +        file_size_format ( cProgressField[1] + iBarLength - 9, g_iTotalSize, 1 );
97 +
98 +        /* show how many files were written */
99 +        int sum_length = sprintf ( cProgressField[1], "%d files copied so far...", g_iFilesCopied );
100 +        cProgressField[1][sum_length] = ' ';
101 +      }
102 +
103 +      /* truncate filename? */
104 +      int fn_length;
105 +      if ( strlen ( src_name ) > iBarLength - 22 )
106 +        fn_length =
107 +          sprintf ( cProgressField[4], "...%s", src_name + ( strlen ( src_name ) - iBarLength + 25 ) );
108 +      else
109 +        fn_length = sprintf ( cProgressField[4], "%s", src_name );
110 +      cProgressField[4][fn_length] = ' ';
111 +
112 +      /* filesize */
113 +      cProgressField[4][iBarLength - 11] = '/';
114 +      file_size_format ( cProgressField[4] + iBarLength - 9, src_open_sb.st_size, 0 );
115 +
116 +      int iCountDown = 1;
117 +      char * sProgressBar = cProgressField[5];
118 +      sProgressBar[0] = '[';
119 +      sProgressBar[iBarLength - 8] = ']';
120 +      sProgressBar[iBarLength - 7] = ' ';
121 +      sProgressBar[iBarLength - 1] = '%';
122 +
123 +      /* this will always save the time in between */
124 +      struct timeval last_time;
125 +      gettimeofday ( & last_time, NULL );
126 +      int last_size = g_iTotalWritten;
127 +      /* END progress mod */
128 +
129        while (true)
130          {
131 +          if (progress) {
132 +          /* BEGIN progress mod */
133 +          /* update countdown */
134 +          iCountDown--;
135 +          if ( iCountDown < 0 )
136 +            iCountDown = 100;
137 +
138 +          /* just print one line with the percentage, but not always */
139 +          if ( iCountDown == 0 )
140 +          {
141 +            /* calculate current speed */
142 +            struct timeval cur_time;
143 +            gettimeofday ( & cur_time, NULL );
144 +            int cur_size = g_iTotalWritten + n_read_total / 1024;
145 +            int usec_elapsed = cur_time.tv_usec - last_time.tv_usec;
146 +            double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
147 +            sec_elapsed += ( double ) ( cur_time.tv_sec - last_time.tv_sec );
148 +            int copy_speed = ( int ) ( ( double ) ( cur_size - last_size )
149 +              / sec_elapsed );
150 +            char s_copy_speed[20];
151 +            file_size_format ( s_copy_speed, copy_speed, 1 );
152 +            /* update vars */
153 +            last_time = cur_time;
154 +            last_size = cur_size;
155 +
156 +            /* how many time has passed since the start? */
157 +            int isec_elapsed = cur_time.tv_sec - g_oStartTime.tv_sec;
158 +            int sec_remaining = ( int ) ( ( double ) isec_elapsed / cur_size
159 +              * g_iTotalSize ) - isec_elapsed;
160 +            int min_remaining = sec_remaining / 60;
161 +            sec_remaining -= min_remaining * 60;
162 +            int hours_remaining = min_remaining / 60;
163 +            min_remaining -= hours_remaining * 60;
164 +            /* print out */
165 +            sprintf ( cProgressField[3],
166 +              "Copying at %s/s (about %dh %dm %ds remaining)", s_copy_speed,
167 +              hours_remaining, min_remaining, sec_remaining );
168 +
169 +            int fs_len;
170 +            if ( g_iTotalSize )
171 +            {
172 +              /* global progress bar */
173 +              file_progress_bar ( cProgressField[2], iBarLength,
174 +                                  g_iTotalWritten + n_read_total / 1024, g_iTotalSize );
175 +
176 +              /* print the global status */
177 +              fs_len = file_size_format ( cProgressField[1] + iBarLength - 21,
178 +                                              g_iTotalWritten + n_read_total / 1024, 1 );
179 +              cProgressField[1][iBarLength - 21 + fs_len] = ' ';
180 +            }
181 +
182 +            /* current progress bar */
183 +            file_progress_bar ( sProgressBar, iBarLength, n_read_total, src_open_sb.st_size );
184 +
185 +            /* print the status */
186 +            fs_len = file_size_format ( cProgressField[4] + iBarLength - 21, n_read_total, 0 );
187 +            cProgressField[4][iBarLength - 21 + fs_len] = ' ';
188 +
189 +            /* print the field */
190 +            for ( it = g_iTotalSize ? 0 : 3; it < 6; it++ )
191 +            {
192 +              printf ( "\033[K%s\n", cProgressField[it] );
193 +              if ( strlen ( cProgressField[it] ) < iBarLength )
194 +                printf ( "" );
195 +            }
196 +            if ( g_iTotalSize )
197 +              printf ( "\r\033[6A" );
198 +            else
199 +              printf ( "\r\033[3A" );
200 +            fflush ( stdout );
201 +          }
202 +          /* END progress mod */
203 +          }
204 +
205            word *wp = NULL;
206  
207            ssize_t n_read = read (source_desc, buf, buf_size);
208 @@ -788,6 +976,19 @@
209                   /proc with linux kernels from at least 2.6.9 .. 2.6.29.  */
210              }
211          }
212 +if (progress) {
213 +      /* BEGIN progress mod */
214 +      /* update total size */
215 +      g_iTotalWritten += n_read_total / 1024;
216 +      g_iFilesCopied++;
217 +
218 +      int i;
219 +      for ( i = 0; i < 6; i++ )
220 +        free ( cProgressField[i] );
221 +      free ( cProgressField );
222 +      /* END progress mod */
223 +}
224 +
225  
226        /* If the file ends with a `hole', we need to do something to record
227           the length of the file.  On modern systems, calling ftruncate does
228 diff -ru coreutils-8.4.orig/src/copy.h coreutils-8.4/src/copy.h
229 --- coreutils-8.4.orig/src/copy.h       2010-01-25 16:03:29.606930239 +0100
230 +++ coreutils-8.4/src/copy.h    2010-01-26 15:35:30.934163303 +0100
231 @@ -222,6 +222,9 @@
232       Create destination directories as usual. */
233    bool symbolic_link;
234  
235 +  /* if true, draw a nice progress bar on screen */
236 +  bool progress_bar;
237 +
238    /* If true, do not copy a nondirectory that has an existing destination
239       with the same or newer modification time. */
240    bool update;
241 @@ -280,4 +283,15 @@
242  bool chown_failure_ok (struct cp_options const *);
243  mode_t cached_umask (void);
244  
245 +/* BEGIN progress mod */
246 +int file_size_format ( char * _cDst, int _iSize, int _iCounter );
247 +
248 +long g_iTotalSize;
249 +long g_iTotalWritten;
250 +int g_iFilesCopied;
251 +struct timeval g_oStartTime;
252 +int g_iTotalFiles;
253 +bool progress;
254 +/* END progress mod */
255 +
256  #endif
257 --- coreutils-8.9/src/cp.c.orig 2011-01-01 22:19:23.000000000 +0100
258 +++ coreutils-8.9/src/cp.c      2011-01-09 13:07:02.769898177 +0100
259 @@ -141,6 +141,7 @@
260    {"target-directory", required_argument, NULL, 't'},
261    {"update", no_argument, NULL, 'u'},
262    {"verbose", no_argument, NULL, 'v'},
263 +  {"progress-bar", no_argument, NULL, 'g'},
264    {GETOPT_HELP_OPTION_DECL},
265    {GETOPT_VERSION_OPTION_DECL},
266    {NULL, 0, NULL, 0}
267 @@ -181,6 +182,7 @@
268                                   opened, remove it and try again (redundant if\
269  \n\
270                                   the -n option is used)\n\
271 +  -g, --progress-bar           add progress-bar\n\
272    -i, --interactive            prompt before overwrite (overrides a previous -n\
273  \n\
274                                    option)\n\
275 @@ -621,6 +623,57 @@
276                 quote (file[n_files - 1]));
277      }
278  
279 +    struct timeval start_time;
280 +if (progress) {
281 +    /* BEGIN progress mod */
282 +    g_iTotalSize = 0;
283 +    g_iFilesCopied = 0;
284 +    g_iTotalWritten = 0;
285 +
286 +    /* save time */
287 +    gettimeofday ( & start_time, NULL );
288 +    g_oStartTime = start_time;
289 +
290 +    printf ( "Calculating total size... \r" );
291 +    fflush ( stdout );
292 +    long iTotalSize = 0;
293 +    int iFiles = n_files;
294 +    if ( ! target_directory )
295 +      iFiles = n_files - 1;
296 +    int j;
297 +    for (j = 0; j < iFiles; j++)
298 +    {
299 +      /* call du -s for each file */
300 +      /* create command */
301 +      char command[1024];
302 +      sprintf ( command, "du -s \"%s\"", file[j] );
303 +      /* TODO: replace all quote signs in file[i] */
304 +
305 +      FILE *fp;
306 +      char output[1024];
307 +
308 +      /* run command */
309 +      fp = popen(command, "r");
310 +      if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) {
311 +        printf("failed to run du.\n" );
312 +      }
313 +      else
314 +      {
315 +        /* isolate size */
316 +        strchr ( output, '\t' )[0] = '\0';
317 +        iTotalSize += atol ( output );
318 +
319 +        printf ( "Calculating total size... %d\r", iTotalSize );
320 +        fflush ( stdout );
321 +      }
322 +
323 +      /* close */
324 +      pclose(fp);
325 +    }
326 +    g_iTotalSize = iTotalSize;
327 +    /* END progress mod */
328 +}
329 +
330    if (target_directory)
331      {
332        /* cp file1...filen edir
333 @@ -763,6 +816,46 @@
334        ok = copy (source, new_dest, 0, x, &unused, NULL);
335      }
336  
337 +if (progress) {
338 +    /* BEGIN progress mod */
339 +    /* remove everything */
340 +    int i;
341 +    if ( g_iTotalSize )
342 +    {
343 +      for ( i = 0; i < 6; i++ )
344 +        printf ( "\033[K\n" );
345 +      printf ( "\r\033[6A" );
346 +    }
347 +    else
348 +    {
349 +      for ( i = 0; i < 3; i++ )
350 +        printf ( "\033[K\n" );
351 +      printf ( "\r\033[3A" );
352 +    }
353 +
354 +    /* save time */
355 +    struct timeval end_time;
356 +    gettimeofday ( & end_time, NULL );
357 +    int usec_elapsed = end_time.tv_usec - start_time.tv_usec;
358 +    double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
359 +    sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec );
360 +
361 +    /* get total size */
362 +    char sTotalWritten[20];
363 +    file_size_format ( sTotalWritten, g_iTotalSize, 1 );
364 +    /* TODO: using g_iTotalWritten would be more correct, but is less accurate */
365 +
366 +    /* calculate speed */
367 +    int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed );
368 +    char s_copy_speed[20];
369 +    file_size_format ( s_copy_speed, copy_speed, 1 );
370 +
371 +    /* good-bye message */
372 +    printf ( "%d files (%s) copied in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten,
373 +             sec_elapsed, s_copy_speed );
374 +    /* END progress mod */
375 +}
376 +
377    return ok;
378  }
379  
380 @@ -795,6 +888,7 @@
381    x->recursive = false;
382    x->sparse_mode = SPARSE_AUTO;
383    x->symbolic_link = false;
384 +  x->progress_bar = false;
385    x->set_mode = false;
386    x->mode = 0;
387  
388 @@ -933,7 +1027,7 @@
389       we'll actually use backup_suffix_string.  */
390    backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
391  
392 -  while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T",
393 +  while ((c = getopt_long (argc, argv, "abdfgHilLnprst:uvxPRS:T",
394                             long_opts, NULL))
395           != -1)
396      {
397 @@ -990,6 +1084,10 @@
398            x.unlink_dest_after_failed_open = true;
399            break;
400  
401 +        case 'g':
402 +          progress = true;
403 +          break;
404 +
405          case 'H':
406            x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
407            break;
This page took 0.088269 seconds and 3 git commands to generate.