]> git.pld-linux.org Git - packages/coreutils.git/blob - coreutils-advcopy.patch
89c41cd422a2c7b8794f3bed5c59853c2ae30713
[packages/coreutils.git] / coreutils-advcopy.patch
1 diff -crB coreutils-8.4/src/copy.c coreutils-8.4-dst/src/copy.c
2 *** coreutils-8.4/src/copy.c    2010-01-03 18:06:20.000000000 +0100
3 --- coreutils-8.4-dst/src/copy.c        2010-01-25 22:37:04.000000000 +0100
4 ***************
5 *** 457,462 ****
6 --- 457,512 ----
7     return lchmod (name, mode);
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 a regular file from SRC_NAME to DST_NAME.
61      If the source file contains holes, copies holes and blocks of zeros
62      in the source file as holes in the destination file.
63 ***************
64 *** 706,713 ****
65 --- 756,899 ----
66         buf_alloc = xmalloc (buf_size + buf_alignment_slop);
67         buf = ptr_align (buf_alloc, buf_alignment);
68   
69 +       /* BEGIN progress mod */
70 +       /* create a field of 6 lines */
71 +       char ** cProgressField = ( char ** ) calloc ( 6, sizeof ( char * ) );
72 +       /* get console width */
73 +       int iBarLength = 80;
74 +       struct winsize win;
75 +       if ( ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &win) == 0 && win.ws_col > 0 )
76 +          iBarLength = win.ws_col;
77 +       /* create rows */
78 +       int it;
79 +       for ( it = 0; it < 6; it++ )
80 +       {
81 +         cProgressField[it] = ( char * ) malloc ( iBarLength + 1 );
82 +         /* init with spaces */
83 +         int j;
84 +         for ( j = 0; j < iBarLength; j++ )
85 +           cProgressField[it][j] = ' ';
86 +         cProgressField[it][iBarLength] = '\0';
87 +       }
88
89 +       /* global progress bar? */
90 +       if ( g_iTotalSize )
91 +       {
92 +         /* init global progress bar */
93 +         cProgressField[2][0] = '[';
94 +         cProgressField[2][iBarLength - 8] = ']';
95 +         cProgressField[2][iBarLength - 7] = ' ';
96 +         cProgressField[2][iBarLength - 1] = '%';
97
98 +         /* total size */
99 +         cProgressField[1][iBarLength - 11] = '/';
100 +         file_size_format ( cProgressField[1] + iBarLength - 9, g_iTotalSize, 1 );
101
102 +         /* show how many files were written */
103 +         int sum_length = sprintf ( cProgressField[1], "%d files copied so far...", g_iFilesCopied );
104 +         cProgressField[1][sum_length] = ' ';
105 +       }
106
107 +       /* truncate filename? */
108 +       int fn_length;
109 +       if ( strlen ( src_name ) > iBarLength - 22 )
110 +         fn_length =
111 +           sprintf ( cProgressField[4], "...%s", src_name + ( strlen ( src_name ) - iBarLength + 25 ) );
112 +       else
113 +         fn_length = sprintf ( cProgressField[4], "%s", src_name );
114 +       cProgressField[4][fn_length] = ' ';
115
116 +       /* filesize */
117 +       cProgressField[4][iBarLength - 11] = '/';
118 +       file_size_format ( cProgressField[4] + iBarLength - 9, src_open_sb.st_size, 0 );
119
120 +       int iCountDown = 1;
121 +       char * sProgressBar = cProgressField[5];
122 +       sProgressBar[0] = '[';
123 +       sProgressBar[iBarLength - 8] = ']';
124 +       sProgressBar[iBarLength - 7] = ' ';
125 +       sProgressBar[iBarLength - 1] = '%';
126
127 +       /* this will always save the time in between */
128 +       struct timeval last_time;
129 +       gettimeofday ( & last_time, NULL );
130 +       int last_size = g_iTotalWritten;
131 +       /* END progress mod */
132
133         for (;;)
134           {
135 +           /* BEGIN progress mod */
136 +           /* update countdown */
137 +           iCountDown--;
138 +           if ( iCountDown < 0 )
139 +             iCountDown = 100;
140
141 +           /* just print one line with the percentage, but not always */
142 +           if ( iCountDown == 0 )
143 +           {
144 +             /* calculate current speed */
145 +             struct timeval cur_time;
146 +             gettimeofday ( & cur_time, NULL );
147 +             int cur_size = g_iTotalWritten + n_read_total / 1024;
148 +             int usec_elapsed = cur_time.tv_usec - last_time.tv_usec;
149 +             double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
150 +             sec_elapsed += ( double ) ( cur_time.tv_sec - last_time.tv_sec );
151 +             int copy_speed = ( int ) ( ( double ) ( cur_size - last_size )
152 +               / sec_elapsed );
153 +             char s_copy_speed[20];
154 +             file_size_format ( s_copy_speed, copy_speed, 1 );
155 +             /* update vars */
156 +             last_time = cur_time;
157 +             last_size = cur_size;
158
159 +             /* how many time has passed since the start? */
160 +             int isec_elapsed = cur_time.tv_sec - g_oStartTime.tv_sec;
161 +             int sec_remaining = ( int ) ( ( double ) isec_elapsed / cur_size
162 +               * g_iTotalSize ) - isec_elapsed;
163 +             int min_remaining = sec_remaining / 60;
164 +             sec_remaining -= min_remaining * 60;
165 +             int hours_remaining = min_remaining / 60;
166 +             min_remaining -= hours_remaining * 60;
167 +             /* print out */
168 +             sprintf ( cProgressField[3],
169 +               "Copying at %s/s (about %dh %dm %ds remaining)", s_copy_speed,
170 +               hours_remaining, min_remaining, sec_remaining );
171
172 +             int fs_len;
173 +             if ( g_iTotalSize )
174 +             {
175 +               /* global progress bar */
176 +               file_progress_bar ( cProgressField[2], iBarLength,
177 +                                   g_iTotalWritten + n_read_total / 1024, g_iTotalSize );
178
179 +               /* print the global status */
180 +               fs_len = file_size_format ( cProgressField[1] + iBarLength - 21,
181 +                                               g_iTotalWritten + n_read_total / 1024, 1 );
182 +               cProgressField[1][iBarLength - 21 + fs_len] = ' ';
183 +             }
184
185 +             /* current progress bar */
186 +             file_progress_bar ( sProgressBar, iBarLength, n_read_total, src_open_sb.st_size );
187
188 +             /* print the status */
189 +             fs_len = file_size_format ( cProgressField[4] + iBarLength - 21, n_read_total, 0 );
190 +             cProgressField[4][iBarLength - 21 + fs_len] = ' ';
191
192 +             /* print the field */
193 +             for ( it = g_iTotalSize ? 0 : 3; it < 6; it++ )
194 +             {
195 +               printf ( "\033[K%s\n", cProgressField[it] );
196 +               if ( strlen ( cProgressField[it] ) < iBarLength )
197 +                 printf ( "" );
198 +             }
199 +             if ( g_iTotalSize )
200 +               printf ( "\r\033[6A" );
201 +             else
202 +               printf ( "\r\033[3A" );
203 +             fflush ( stdout );
204 +           }
205 +           /* END progress mod */
206
207             word *wp = NULL;
208   
209             ssize_t n_read = read (source_desc, buf, buf_size);
210 ***************
211 *** 788,793 ****
212 --- 974,990 ----
213                    /proc with linux kernels from at least 2.6.9 .. 2.6.29.  */
214               }
215           }
216 +       /* BEGIN progress mod */
217 +       /* update total size */
218 +       g_iTotalWritten += n_read_total / 1024;
219 +       g_iFilesCopied++;
220
221 +       int i;
222 +       for ( i = 0; i < 6; i++ )
223 +         free ( cProgressField[i] );
224 +       free ( cProgressField );
225 +       /* END progress mod */
226
227   
228         /* If the file ends with a `hole', we need to do something to record
229            the length of the file.  On modern systems, calling ftruncate does
230 diff -crB coreutils-8.4/src/copy.h coreutils-8.4-dst/src/copy.h
231 *** coreutils-8.4/src/copy.h    2010-01-03 18:06:20.000000000 +0100
232 --- coreutils-8.4-dst/src/copy.h        2010-01-25 22:37:06.000000000 +0100
233 ***************
234 *** 280,283 ****
235 --- 280,293 ----
236   bool chown_failure_ok (struct cp_options const *);
237   mode_t cached_umask (void);
238   
239 + /* BEGIN progress mod */
240 + int file_size_format ( char * _cDst, int _iSize, int _iCounter );
241
242 + long g_iTotalSize;
243 + long g_iTotalWritten;
244 + int g_iFilesCopied;
245 + struct timeval g_oStartTime;
246 + int g_iTotalFiles;
247 + /* END progress mod */
248
249   #endif
250 diff -crB coreutils-8.4/src/cp.c coreutils-8.4-dst/src/cp.c
251 *** coreutils-8.4/src/cp.c      2010-01-04 16:46:06.000000000 +0100
252 --- coreutils-8.4-dst/src/cp.c  2010-01-25 22:36:58.000000000 +0100
253 ***************
254 *** 612,617 ****
255 --- 612,666 ----
256                  quote (file[n_files - 1]));
257       }
258   
259 +     /* BEGIN progress mod */
260 +     g_iTotalSize = 0;
261 +     g_iFilesCopied = 0;
262 +     g_iTotalWritten = 0;
263
264 +     /* save time */
265 +     struct timeval start_time;
266 +     gettimeofday ( & start_time, NULL );
267 +     g_oStartTime = start_time;
268
269 +     printf ( "Calculating total size... \r" );
270 +     fflush ( stdout );
271 +     long iTotalSize = 0;
272 +     int iFiles = n_files;
273 +     if ( ! target_directory )
274 +       iFiles = n_files - 1;
275 +     int j;
276 +     for (j = 0; j < iFiles; j++)
277 +     {
278 +       /* call du -s for each file */
279 +       /* create command */
280 +       char command[1024];
281 +       sprintf ( command, "du -s \"%s\"", file[j] );
282 +       /* TODO: replace all quote signs in file[i] */
283
284 +       FILE *fp;
285 +       char output[1024];
286
287 +       /* run command */
288 +       fp = popen(command, "r");
289 +       if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) {
290 +         printf("failed to run du.\n" );
291 +       }
292 +       else
293 +       {
294 +         /* isolate size */
295 +         strchr ( output, '\t' )[0] = '\0';
296 +         iTotalSize += atol ( output );
297
298 +         printf ( "Calculating total size... %d\r", iTotalSize );
299 +         fflush ( stdout );
300 +       }
301
302 +       /* close */
303 +       pclose(fp);
304 +     }
305 +     g_iTotalSize = iTotalSize;
306 +     /* END progress mod */
307
308     if (target_directory)
309       {
310         /* cp file1...filen edir
311 ***************
312 *** 754,759 ****
313 --- 803,846 ----
314         ok = copy (source, new_dest, 0, x, &unused, NULL);
315       }
316   
317 +     /* BEGIN progress mod */
318 +     /* remove everything */
319 +     int i;
320 +     if ( g_iTotalSize )
321 +     {
322 +       for ( i = 0; i < 6; i++ )
323 +         printf ( "\033[K\n" );
324 +       printf ( "\r\033[6A" );
325 +     }
326 +     else
327 +     {
328 +       for ( i = 0; i < 3; i++ )
329 +         printf ( "\033[K\n" );
330 +       printf ( "\r\033[3A" );
331 +     }
332
333 +     /* save time */
334 +     struct timeval end_time;
335 +     gettimeofday ( & end_time, NULL );
336 +     int usec_elapsed = end_time.tv_usec - start_time.tv_usec;
337 +     double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
338 +     sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec );
339
340 +     /* get total size */
341 +     char sTotalWritten[20];
342 +     file_size_format ( sTotalWritten, g_iTotalSize, 1 );
343 +     /* TODO: using g_iTotalWritten would be more correct, but is less accurate */
344
345 +     /* calculate speed */
346 +     int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed );
347 +     char s_copy_speed[20];
348 +     file_size_format ( s_copy_speed, copy_speed, 1 );
349
350 +     /* good-bye message */
351 +     printf ( "%d files (%s) copied in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten,
352 +              sec_elapsed, s_copy_speed );
353 +     /* END progress mod */
354
355     return ok;
356   }
357   
This page took 0.174237 seconds and 2 git commands to generate.