advcpmv-8.29.patch 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. diff -rup coreutils-8.24/src/copy.c coreutils-8.24-patched/src/copy.c
  2. --- coreutils-8.24/src/copy.c 2015-06-26 11:05:22.000000000 -0600
  3. +++ coreutils-8.24-patched/src/copy.c 2015-07-09 15:39:58.000000000 -0600
  4. @@ -117,6 +117,71 @@ struct dir_list
  5. dev_t dev;
  6. };
  7. +struct progress_status {
  8. + int iCountDown;
  9. + char ** cProgressField;
  10. + struct timeval last_time;
  11. + int last_size, iBarLength;
  12. + struct stat src_open_sb;
  13. +};
  14. +
  15. +/* Begin progress Mod*/
  16. +static void file_progress_bar ( char * _cDest, int _iBarLength, long _lProgress, long _lTotal )
  17. +{
  18. + double dPercent = (double) _lProgress / (double) _lTotal * 100.f;
  19. + sprintf( _cDest + ( _iBarLength - 6), "%4.1f", dPercent );
  20. + _cDest[_iBarLength - 2] = ' ';
  21. +
  22. + int i;
  23. + for ( i=1; i<=_iBarLength - 9; i++)
  24. + {
  25. + if ( dPercent > (double) (i-1) / (_iBarLength - 10) * 100.f )
  26. + {
  27. + _cDest[i] = '=';
  28. + }
  29. + else
  30. + {
  31. + _cDest[i] = ' ';
  32. + }
  33. + }
  34. + for ( i=1; i<_iBarLength - 9; i++)
  35. + {
  36. + if ( ( _cDest[i+1] == ' ' ) && ( _cDest[i] == '=' ) )
  37. + _cDest[i] = '>' ;
  38. + }
  39. +}
  40. +
  41. +int file_size_format ( char * _cDst, long _lSize, int _iCounter )
  42. +{
  43. + int iCounter = _iCounter;
  44. + double dSize = ( double ) _lSize;
  45. + while ( dSize >= 1000. )
  46. + {
  47. + dSize /= 1024.;
  48. + iCounter++;
  49. + }
  50. +
  51. + /* get unit */
  52. + char * sUnit;
  53. + if ( iCounter == 0 )
  54. + sUnit = "B";
  55. + else if ( iCounter == 1 )
  56. + sUnit = "KiB";
  57. + else if ( iCounter == 2 )
  58. + sUnit = "MiB";
  59. + else if ( iCounter == 3 )
  60. + sUnit = "GiB";
  61. + else if ( iCounter == 4 )
  62. + sUnit = "TiB";
  63. + else
  64. + sUnit = "N/A";
  65. +
  66. + /* write number */
  67. + return sprintf ( _cDst, "%5.1f %s", dSize, sUnit );
  68. +}
  69. +/* END progress mod */
  70. +
  71. +
  72. /* Initial size of the cp.dest_info hash table. */
  73. #define DEST_INFO_INITIAL_CAPACITY 61
  74. @@ -212,7 +277,8 @@ sparse_copy (int src_fd, int dest_fd, ch
  75. size_t hole_size, bool punch_holes,
  76. char const *src_name, char const *dst_name,
  77. uintmax_t max_n_read, off_t *total_n_read,
  78. - bool *last_write_made_hole)
  79. + bool *last_write_made_hole,
  80. + struct progress_status *s_progress)
  81. {
  82. *last_write_made_hole = false;
  83. *total_n_read = 0;
  84. @@ -221,6 +287,83 @@ sparse_copy (int src_fd, int dest_fd, ch
  85. while (max_n_read)
  86. {
  87. +
  88. + if (progress) {
  89. + /* BEGIN progress mod */
  90. + /* update countdown */
  91. + s_progress->iCountDown--;
  92. + char * sProgressBar = s_progress->cProgressField[5];
  93. + if ( s_progress->iCountDown < 0 )
  94. + s_progress->iCountDown = 100;
  95. +
  96. + /* just print one line with the percentage, but not always */
  97. + if ( s_progress->iCountDown == 0 )
  98. + {
  99. + /* calculate current speed */
  100. + struct timeval cur_time;
  101. + gettimeofday ( & cur_time, NULL );
  102. + int cur_size = g_iTotalWritten + *total_n_read / 1024;
  103. + int usec_elapsed = cur_time.tv_usec - s_progress->last_time.tv_usec;
  104. + double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
  105. + sec_elapsed += ( double ) ( cur_time.tv_sec - s_progress->last_time.tv_sec );
  106. + int copy_speed = ( int ) ( ( double ) ( cur_size - s_progress->last_size )
  107. + / sec_elapsed );
  108. + char s_copy_speed[20];
  109. + file_size_format ( s_copy_speed, copy_speed, 1 );
  110. + /* update vars */
  111. + s_progress->last_time = cur_time;
  112. + s_progress->last_size = cur_size;
  113. +
  114. + /* how many time has passed since the start? */
  115. + int isec_elapsed = cur_time.tv_sec - g_oStartTime.tv_sec;
  116. + int sec_remaining = ( int ) ( ( double ) isec_elapsed / cur_size
  117. + * g_iTotalSize ) - isec_elapsed;
  118. + int min_remaining = sec_remaining / 60;
  119. + sec_remaining -= min_remaining * 60;
  120. + int hours_remaining = min_remaining / 60;
  121. + min_remaining -= hours_remaining * 60;
  122. + /* print out */
  123. + sprintf ( s_progress->cProgressField[3],
  124. + "Copying at %s/s (about %uh %um %us remaining)", s_copy_speed,
  125. + hours_remaining, min_remaining, sec_remaining );
  126. +
  127. + int fs_len;
  128. + if ( g_iTotalFiles > 1 )
  129. + {
  130. + /* global progress bar */
  131. + file_progress_bar ( s_progress->cProgressField[2], s_progress->iBarLength,
  132. + g_iTotalWritten + *total_n_read / 1024, g_iTotalSize );
  133. +
  134. + /* print the global status */
  135. + fs_len = file_size_format ( s_progress->cProgressField[1] + s_progress->iBarLength - 21,
  136. + g_iTotalWritten + *total_n_read / 1024, 1 );
  137. + s_progress->cProgressField[1][s_progress->iBarLength - 21 + fs_len] = ' ';
  138. + }
  139. +
  140. + /* current progress bar */
  141. + file_progress_bar ( sProgressBar, s_progress->iBarLength, *total_n_read, s_progress->src_open_sb.st_size );
  142. +
  143. + /* print the status */
  144. + fs_len = file_size_format ( s_progress->cProgressField[4] + s_progress->iBarLength - 21, *total_n_read, 0 );
  145. + s_progress->cProgressField[4][s_progress->iBarLength - 21 + fs_len] = ' ';
  146. +
  147. + /* print the field */
  148. + int it;
  149. + for ( it = g_iTotalFiles>1 ? 0 : 3; it < 6; it++ )
  150. + {
  151. + printf ( "\033[K%s\n", s_progress->cProgressField[it] );
  152. + if ( strlen ( s_progress->cProgressField[it] ) < s_progress->iBarLength )
  153. + printf ( "" );
  154. + }
  155. + if ( g_iTotalFiles > 1 )
  156. + printf ( "\r\033[6A" );
  157. + else
  158. + printf ( "\r\033[3A" );
  159. + fflush ( stdout );
  160. + }
  161. + /* END progress mod */
  162. + }
  163. +
  164. ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size));
  165. if (n_read < 0)
  166. {
  167. @@ -316,6 +459,14 @@ sparse_copy (int src_fd, int dest_fd, ch
  168. certain files in /proc or /sys with linux kernels. */
  169. }
  170. + /* BEGIN progress mod */
  171. + if (progress) {
  172. + /* update total size */
  173. + g_iTotalWritten += *total_n_read / 1024;
  174. + g_iFilesCopied++;
  175. + }
  176. + /* END progress mod */
  177. +
  178. /* Ensure a trailing hole is created, so that subsequent
  179. calls of sparse_copy() start at the correct offset. */
  180. if (make_hole && ! create_hole (dest_fd, dst_name, punch_holes, psize))
  181. @@ -388,7 +539,9 @@ extent_copy (int src_fd, int dest_fd, ch
  182. size_t hole_size, off_t src_total_size,
  183. enum Sparse_type sparse_mode,
  184. char const *src_name, char const *dst_name,
  185. - bool *require_normal_copy)
  186. + bool *require_normal_copy,
  187. + int iCountDown, char ** cProgressField, struct timeval last_time,
  188. + int last_size, int iBarLength, struct stat src_open_sb)
  189. {
  190. struct extent_scan scan;
  191. off_t last_ext_start = 0;
  192. @@ -504,10 +657,15 @@ extent_copy (int src_fd, int dest_fd, ch
  193. empty_extent = false;
  194. last_ext_len = ext_len;
  195. + struct timeval a;
  196. + struct stat b;
  197. +
  198. + struct progress_status s_progress={iCountDown, cProgressField, last_time, last_size, iBarLength, src_open_sb};
  199. +
  200. if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size,
  201. sparse_mode == SPARSE_ALWAYS ? hole_size: 0,
  202. true, src_name, dst_name, ext_len, &n_read,
  203. - &wrote_hole_at_eof))
  204. + &wrote_hole_at_eof, &s_progress))
  205. goto fail;
  206. dest_pos = ext_start + n_read;
  207. @@ -982,7 +1140,6 @@ is_probably_sparse (struct stat const *s
  208. && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE);
  209. }
  210. -
  211. /* Copy a regular file from SRC_NAME to DST_NAME.
  212. If the source file contains holes, copies holes and blocks of zeros
  213. in the source file as holes in the destination file.
  214. @@ -1258,6 +1415,72 @@ copy_reg (char const *src_name, char con
  215. buf_alloc = xmalloc (buf_size + buf_alignment_slop);
  216. buf = ptr_align (buf_alloc, buf_alignment);
  217. + /* BEGIN progress mod */
  218. + /* create a field of 6 lines */
  219. + char ** cProgressField = ( char ** ) calloc ( 6, sizeof ( char * ) );
  220. + /* get console width */
  221. + int iBarLength = 80;
  222. + struct winsize win;
  223. + if ( ioctl (STDOUT_FILENO, TIOCGWINSZ, (char *) &win) == 0 && win.ws_col > 0 )
  224. + iBarLength = win.ws_col;
  225. + /* create rows */
  226. + int it;
  227. + for ( it = 0; it < 6; it++ )
  228. + {
  229. + cProgressField[it] = ( char * ) malloc ( iBarLength + 1 );
  230. + /* init with spaces */
  231. + int j;
  232. + for ( j = 0; j < iBarLength; j++ )
  233. + cProgressField[it][j] = ' ';
  234. + cProgressField[it][iBarLength] = '\0';
  235. + }
  236. +
  237. + /* global progress bar? */
  238. + if ( g_iTotalFiles > 1 )
  239. + {
  240. + /* init global progress bar */
  241. + cProgressField[2][0] = '[';
  242. + cProgressField[2][iBarLength - 8] = ']';
  243. + cProgressField[2][iBarLength - 7] = ' ';
  244. + cProgressField[2][iBarLength - 1] = '%';
  245. +
  246. + /* total size */
  247. + cProgressField[1][iBarLength - 11] = '/';
  248. + file_size_format ( cProgressField[1] + iBarLength - 9, g_iTotalSize, 1 );
  249. +
  250. + /* show how many files were written */
  251. + int sum_length = sprintf ( cProgressField[1], "%d files copied so far...", g_iFilesCopied );
  252. + cProgressField[1][sum_length] = ' ';
  253. + }
  254. +
  255. + /* truncate filename? */
  256. + int fn_length;
  257. + if ( strlen ( src_name ) > iBarLength - 22 )
  258. + fn_length =
  259. + sprintf ( cProgressField[4], "...%s", src_name + ( strlen ( src_name ) - iBarLength + 25 ) );
  260. + else
  261. + fn_length = sprintf ( cProgressField[4], "%s", src_name );
  262. + cProgressField[4][fn_length] = ' ';
  263. +
  264. + /* filesize */
  265. + cProgressField[4][iBarLength - 11] = '/';
  266. + file_size_format ( cProgressField[4] + iBarLength - 9, src_open_sb.st_size, 0 );
  267. +
  268. + int iCountDown = 1;
  269. + char * sProgressBar = cProgressField[5];
  270. + sProgressBar[0] = '[';
  271. + sProgressBar[iBarLength - 8] = ']';
  272. + sProgressBar[iBarLength - 7] = ' ';
  273. + sProgressBar[iBarLength - 1] = '%';
  274. +
  275. + /* this will always save the time in between */
  276. + struct timeval last_time;
  277. + gettimeofday ( & last_time, NULL );
  278. + int last_size = g_iTotalWritten;
  279. + /* END progress mod */
  280. +
  281. +
  282. +
  283. if (sparse_src)
  284. {
  285. bool normal_copy_required;
  286. @@ -1269,7 +1492,9 @@ copy_reg (char const *src_name, char con
  287. if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size,
  288. src_open_sb.st_size,
  289. make_holes ? x->sparse_mode : SPARSE_NEVER,
  290. - src_name, dst_name, &normal_copy_required))
  291. + src_name, dst_name, &normal_copy_required,
  292. + iCountDown, cProgressField, last_time, last_size,
  293. + iBarLength, src_open_sb))
  294. goto preserve_metadata;
  295. if (! normal_copy_required)
  296. @@ -1281,11 +1506,12 @@ copy_reg (char const *src_name, char con
  297. off_t n_read;
  298. bool wrote_hole_at_eof;
  299. + struct progress_status s_progress = { iCountDown, cProgressField, last_time, last_size, iBarLength, src_open_sb};
  300. if (! sparse_copy (source_desc, dest_desc, buf, buf_size,
  301. make_holes ? hole_size : 0,
  302. x->sparse_mode == SPARSE_ALWAYS, src_name, dst_name,
  303. UINTMAX_MAX, &n_read,
  304. - &wrote_hole_at_eof))
  305. + &wrote_hole_at_eof, &s_progress))
  306. {
  307. return_val = false;
  308. goto close_src_and_dst_desc;
  309. @@ -1296,6 +1522,15 @@ copy_reg (char const *src_name, char con
  310. return_val = false;
  311. goto close_src_and_dst_desc;
  312. }
  313. +
  314. + /* BEGIN progress mod */
  315. + if (progress) {
  316. + int i;
  317. + for ( i = 0; i < 6; i++ )
  318. + free ( cProgressField[i] );
  319. + free ( cProgressField );
  320. + }
  321. + /* END progress mod */
  322. }
  323. preserve_metadata:
  324. @@ -1396,6 +1631,7 @@ close_src_desc:
  325. free (buf_alloc);
  326. free (name_alloc);
  327. +
  328. return return_val;
  329. }
  330. diff -rup coreutils-8.24/src/copy.h coreutils-8.24-patched/src/copy.h
  331. --- coreutils-8.24/src/copy.h 2015-06-26 11:04:19.000000000 -0600
  332. +++ coreutils-8.24-patched/src/copy.h 2015-07-09 15:05:07.000000000 -0600
  333. @@ -231,6 +231,9 @@ struct cp_options
  334. Create destination directories as usual. */
  335. bool symbolic_link;
  336. + /* If true, draw a nice progress bar on screen */
  337. + bool progress_bar;
  338. +
  339. /* If true, do not copy a nondirectory that has an existing destination
  340. with the same or newer modification time. */
  341. bool update;
  342. @@ -289,4 +292,16 @@ void cp_options_default (struct cp_optio
  343. bool chown_failure_ok (struct cp_options const *) _GL_ATTRIBUTE_PURE;
  344. mode_t cached_umask (void);
  345. +
  346. +/* BEGIN OF PROGRESS MOD */
  347. +int file_size_format ( char * _cDst, long _lSize, int _iCounter );
  348. +
  349. +long g_iTotalSize;
  350. +long g_iTotalWritten;
  351. +int g_iFilesCopied;
  352. +struct timeval g_oStartTime;
  353. +int g_iTotalFiles;
  354. +bool progress;
  355. +/* END OF PROGRESS MOD */
  356. +
  357. #endif
  358. diff -rup coreutils-8.24/src/cp.c coreutils-8.24-patched/src/cp.c
  359. --- coreutils-8.24/src/cp.c 2015-06-26 11:04:19.000000000 -0600
  360. +++ coreutils-8.24-patched/src/cp.c 2015-07-09 15:05:07.000000000 -0600
  361. @@ -140,6 +140,7 @@ static struct option const long_opts[] =
  362. {"symbolic-link", no_argument, NULL, 's'},
  363. {"target-directory", required_argument, NULL, 't'},
  364. {"update", no_argument, NULL, 'u'},
  365. + {"progress-bar", no_argument, NULL, 'g'},
  366. {"verbose", no_argument, NULL, 'v'},
  367. {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
  368. {GETOPT_HELP_OPTION_DECL},
  369. @@ -179,6 +180,7 @@ Copy SOURCE to DEST, or multiple SOURCE(
  370. -f, --force if an existing destination file cannot be\n\
  371. opened, remove it and try again (this option\n\
  372. is ignored when the -n option is also used)\n\
  373. + -g, --progress-bar add a progress bar\n\
  374. -i, --interactive prompt before overwrite (overrides a previous -n\
  375. \n\
  376. option)\n\
  377. @@ -625,6 +627,72 @@ do_copy (int n_files, char **file, const
  378. quote (file[n_files - 1]));
  379. }
  380. + struct timeval start_time;
  381. + if (progress) {
  382. + /* BEGIN progress mod */
  383. + g_iTotalSize = 0;
  384. + g_iTotalFiles = 0;
  385. + g_iFilesCopied = 0;
  386. + g_iTotalWritten = 0;
  387. +
  388. + /* save time */
  389. + gettimeofday ( & start_time, NULL );
  390. + g_oStartTime = start_time;
  391. +
  392. + printf ( "Calculating total size... \r" );
  393. + fflush ( stdout );
  394. + long iTotalSize = 0;
  395. + int iFiles = n_files;
  396. + if ( ! target_directory )
  397. + iFiles = n_files - 1;
  398. + int j;
  399. +
  400. + /* how many files are we copying */
  401. + char command[1024];
  402. + sprintf( command, "find \"%s\" -type f | wc -l", file[0]);
  403. + FILE *fp ;
  404. + char output[1024];
  405. + fp = popen(command,"r");
  406. + if ( fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL)
  407. + printf("failed to run find.\n");
  408. + else
  409. + g_iTotalFiles = atoi( output ) ;
  410. +
  411. + for (j = 0; j < iFiles; j++)
  412. + {
  413. + /* call du -s for each file */
  414. + /* create command */
  415. + char command[1024];
  416. + sprintf ( command, "du -s \"%s\"", file[j] );
  417. + /* TODO: replace all quote signs in file[i] */
  418. +
  419. + FILE *fp;
  420. + char output[1024];
  421. +
  422. + /* run command */
  423. + fp = popen(command, "r");
  424. + if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) {
  425. + printf("failed to run du.\n" );
  426. + }
  427. + else
  428. + {
  429. + /* isolate size */
  430. + strchr ( output, '\t' )[0] = '\0';
  431. + iTotalSize += atol ( output );
  432. +
  433. + printf ( "Calculating total size... %ld\r", iTotalSize );
  434. + fflush ( stdout );
  435. + }
  436. +
  437. + /* close */
  438. + pclose(fp);
  439. + }
  440. + g_iTotalSize = iTotalSize;
  441. + /* END progress mod */
  442. + }
  443. +
  444. +
  445. +
  446. if (target_directory)
  447. {
  448. /* cp file1...filen edir
  449. @@ -767,6 +835,47 @@ do_copy (int n_files, char **file, const
  450. ok = copy (source, new_dest, 0, x, &unused, NULL);
  451. }
  452. + if (progress) {
  453. + /* BEGIN progress mod */
  454. + /* remove everything */
  455. + int i;
  456. + if ( g_iTotalFiles > 1 )
  457. + {
  458. + for ( i = 0; i < 6; i++ )
  459. + printf ( "\033[K\n" );
  460. + printf ( "\r\033[6A" );
  461. + }
  462. + else
  463. + {
  464. + for ( i = 0; i < 3; i++ )
  465. + printf ( "\033[K\n" );
  466. + printf ( "\r\033[3A" );
  467. + }
  468. +
  469. + /* save time */
  470. + struct timeval end_time;
  471. + gettimeofday ( & end_time, NULL );
  472. + int usec_elapsed = end_time.tv_usec - start_time.tv_usec;
  473. + double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
  474. + sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec );
  475. +
  476. + /* get total size */
  477. + char sTotalWritten[20];
  478. + file_size_format ( sTotalWritten, g_iTotalSize, 1 );
  479. + /* TODO: using g_iTotalWritten would be more correct, but is less accurate */
  480. +
  481. + /* calculate speed */
  482. + int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed );
  483. + char s_copy_speed[20];
  484. + file_size_format ( s_copy_speed, copy_speed, 1 );
  485. +
  486. + /* good-bye message */
  487. + printf ( "%d files (%s) copied in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten,
  488. + sec_elapsed, s_copy_speed );
  489. + /* END progress mod */
  490. + }
  491. +
  492. +
  493. return ok;
  494. }
  495. @@ -801,6 +910,7 @@ cp_option_init (struct cp_options *x)
  496. x->recursive = false;
  497. x->sparse_mode = SPARSE_AUTO;
  498. x->symbolic_link = false;
  499. + x->progress_bar = false;
  500. x->set_mode = false;
  501. x->mode = 0;
  502. @@ -943,7 +1053,7 @@ main (int argc, char **argv)
  503. we'll actually use backup_suffix_string. */
  504. backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
  505. - while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",
  506. + while ((c = getopt_long (argc, argv, "abdfgHilLnprst:uvxPRS:TZ",
  507. long_opts, NULL))
  508. != -1)
  509. {
  510. @@ -1000,6 +1110,10 @@ main (int argc, char **argv)
  511. x.unlink_dest_after_failed_open = true;
  512. break;
  513. + case 'g':
  514. + progress = true;
  515. + break;
  516. +
  517. case 'H':
  518. x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;
  519. break;
  520. diff -rup coreutils-8.24/src/mv.c coreutils-8.24-patched/src/mv.c
  521. --- coreutils-8.24/src/mv.c 2015-06-26 11:04:19.000000000 -0600
  522. +++ coreutils-8.24-patched/src/mv.c 2015-07-09 15:05:07.000000000 -0600
  523. @@ -65,6 +65,7 @@ static struct option const long_options[
  524. {"target-directory", required_argument, NULL, 't'},
  525. {"update", no_argument, NULL, 'u'},
  526. {"verbose", no_argument, NULL, 'v'},
  527. + {"progress-ar", no_argument, NULL, 'g'},
  528. {GETOPT_HELP_OPTION_DECL},
  529. {GETOPT_VERSION_OPTION_DECL},
  530. {NULL, 0, NULL, 0}
  531. @@ -164,10 +165,98 @@ target_directory_operand (char const *fi
  532. static bool
  533. do_move (const char *source, const char *dest, const struct cp_options *x)
  534. {
  535. +
  536. + struct timeval start_time;
  537. +
  538. + if(progress) {
  539. + /* BEGIN progress mod */
  540. + g_iTotalSize = 0;
  541. + g_iFilesCopied = 0;
  542. + g_iTotalWritten = 0;
  543. +
  544. + gettimeofday (& start_time, NULL);
  545. + g_oStartTime = start_time;
  546. +
  547. + printf ("Calculating total size... \r");
  548. + fflush (stdout);
  549. + long iTotalSize = 0;
  550. + /* call du -s for each file */
  551. + /* create command */
  552. + char command[1024];
  553. + sprintf ( command, "du -s \"%s\"", source );
  554. + /* TODO: replace all quote signs in file[i] */
  555. +
  556. + FILE *fp;
  557. + char output[1024];
  558. +
  559. + /* run command */
  560. + fp = popen(command, "r");
  561. + if (fp == NULL || fgets(output, sizeof(output)-1, fp) == NULL) {
  562. + printf("failed to run du.\n" );
  563. + }
  564. + else
  565. + {
  566. + /* isolate size */
  567. + strchr ( output, '\t' )[0] = '\0';
  568. + iTotalSize += atol ( output );
  569. + printf ( "Calculating total size... %ld\r", iTotalSize );
  570. + fflush ( stdout );
  571. + }
  572. +
  573. + /* close */
  574. + pclose(fp);
  575. + g_iTotalSize = iTotalSize;
  576. + /* END progress mod */
  577. +
  578. + }
  579. +
  580. +
  581. +
  582. bool copy_into_self;
  583. bool rename_succeeded;
  584. bool ok = copy (source, dest, false, x, &copy_into_self, &rename_succeeded);
  585. + if (progress) {
  586. + /* BEGIN progress mod */
  587. + /* remove everything */
  588. + int i;
  589. + if ( g_iTotalFiles > 1 )
  590. + {
  591. + for ( i = 0; i < 6; i++ )
  592. + printf ( "\033[K\n" );
  593. + printf ( "\r\033[6A" );
  594. + }
  595. + else
  596. + {
  597. + for ( i = 0; i < 3; i++ )
  598. + printf ( "\033[K\n" );
  599. + printf ( "\r\033[3A" );
  600. + }
  601. +
  602. + /* save time */
  603. + struct timeval end_time;
  604. + gettimeofday ( & end_time, NULL );
  605. + int usec_elapsed = end_time.tv_usec - start_time.tv_usec;
  606. + double sec_elapsed = ( double ) usec_elapsed / 1000000.f;
  607. + sec_elapsed += ( double ) ( end_time.tv_sec - start_time.tv_sec );
  608. +
  609. + /* get total size */
  610. + char sTotalWritten[20];
  611. + file_size_format ( sTotalWritten, g_iTotalSize, 1 );
  612. + /* TODO: using g_iTotalWritten would be more correct, but is less accurate */
  613. +
  614. + /* calculate speed */
  615. + int copy_speed = ( int ) ( ( double ) g_iTotalWritten / sec_elapsed );
  616. + char s_copy_speed[20];
  617. + file_size_format ( s_copy_speed, copy_speed, 1 );
  618. +
  619. + /* good-bye message */
  620. + printf ( "%d files (%s) moved in %.1f seconds (%s/s).\n", g_iFilesCopied, sTotalWritten,
  621. + sec_elapsed, s_copy_speed );
  622. + /* END progress mod */
  623. + }
  624. +
  625. +
  626. if (ok)
  627. {
  628. char const *dir_to_remove;
  629. @@ -302,6 +391,7 @@ Rename SOURCE to DEST, or move SOURCE(s)
  630. \n\
  631. -b like --backup but does not accept an argument\n\
  632. -f, --force do not prompt before overwriting\n\
  633. + -g, --progress-bar add progress-bar\n\
  634. -i, --interactive prompt before overwrite\n\
  635. -n, --no-clobber do not overwrite an existing file\n\
  636. If you specify more than one of -i, -f, -n, only the final one takes effect.\n\
  637. @@ -373,7 +463,7 @@ main (int argc, char **argv)
  638. we'll actually use backup_suffix_string. */
  639. backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
  640. - while ((c = getopt_long (argc, argv, "bfint:uvS:TZ", long_options, NULL))
  641. + while ((c = getopt_long (argc, argv, "bfint:uvgS:TZ", long_options, NULL))
  642. != -1)
  643. {
  644. switch (c)
  645. @@ -419,6 +509,11 @@ main (int argc, char **argv)
  646. case 'v':
  647. x.verbose = true;
  648. break;
  649. +
  650. + case 'g':
  651. + progress = true;
  652. + break;
  653. +
  654. case 'S':
  655. make_backups = true;
  656. backup_suffix_string = optarg;