summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/afcclient.c7
-rw-r--r--tools/idevicebackup2.c322
2 files changed, 277 insertions, 52 deletions
diff --git a/tools/afcclient.c b/tools/afcclient.c
index 2667e52..e71aea4 100644
--- a/tools/afcclient.c
+++ b/tools/afcclient.c
@@ -332,7 +332,9 @@ static char* get_realpath(const char* path)
332 332
333 for (int i = 0; i < c_count; i++) { 333 for (int i = 0; i < c_count; i++) {
334 if (!strcmp(comps[i].str, "..")) { 334 if (!strcmp(comps[i].str, "..")) {
335 o--; 335 if (o > 1) {
336 o--;
337 }
336 continue; 338 continue;
337 } else if (!strcmp(comps[i].str, ".")) { 339 } else if (!strcmp(comps[i].str, ".")) {
338 continue; 340 continue;
@@ -1202,8 +1204,10 @@ static void handle_cd(afc_client_t afc, int argc, char** argv)
1202 } 1204 }
1203 if (p == curdir) { 1205 if (p == curdir) {
1204 *(p+1) = '\0'; 1206 *(p+1) = '\0';
1207 curdir_len = 1;
1205 } else { 1208 } else {
1206 *p = '\0'; 1209 *p = '\0';
1210 curdir_len = strlen(curdir);
1207 } 1211 }
1208 return; 1212 return;
1209 } 1213 }
@@ -1227,7 +1231,6 @@ static void handle_cd(afc_client_t afc, int argc, char** argv)
1227 free(path); 1231 free(path);
1228 return; 1232 return;
1229 } 1233 }
1230
1231 free(curdir); 1234 free(curdir);
1232 curdir = path; 1235 curdir = path;
1233 curdir_len = strlen(curdir); 1236 curdir_len = strlen(curdir);
diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c
index 12d6083..f5eb1e4 100644
--- a/tools/idevicebackup2.c
+++ b/tools/idevicebackup2.c
@@ -29,6 +29,7 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <string.h> 30#include <string.h>
31#include <errno.h> 31#include <errno.h>
32#include <stdarg.h>
32#include <stdlib.h> 33#include <stdlib.h>
33#include <signal.h> 34#include <signal.h>
34#include <unistd.h> 35#include <unistd.h>
@@ -662,6 +663,193 @@ static void do_post_notification(idevice_t device, const char *notification)
662 lockdownd_client_free(lockdown); 663 lockdownd_client_free(lockdown);
663} 664}
664 665
666/* ANSI escape codes for cursor manipulation */
667#define CURSOR_UP "\033[1A"
668#define CURSOR_DOWN "\033[1B"
669#define CURSOR_SAVE "\033[s"
670#define CURSOR_RESTORE "\033[u"
671#define CURSOR_HIDE "\033[?25l"
672#define CURSOR_SHOW "\033[?25h"
673#define CLEAR_LINE "\033[2K"
674#define MOVE_COL_1 "\r"
675
676#define TRANSFER_NONE 0
677#define TRANSFER_SEND 1
678#define TRANSFER_RECEIVE 2
679
680/* Progress state - 4-line reserved area display */
681static double overall_progress = 0;
682static double file_progress = 0;
683static uint64_t file_current = 0;
684static uint64_t file_total = 0;
685static int transfer_status = 0;
686static int progress_mode_active = 0;
687static char progress_status[256] = "";
688static char transfer_info[256] = "";
689
690static void draw_progress_bar(double percent, int width)
691{
692 int i;
693 double ratio = width / 100.0;
694 printf("[");
695 for (i = 0; i < width; i++) {
696 if (i < (int)(percent * ratio)) {
697 printf("#");
698 } else {
699 printf(".");
700 }
701 }
702 printf("]");
703}
704
705static void draw_transfer_bar(double percent, int width)
706{
707 int i;
708 int pos = (int)((percent / 100.0) * width);
709
710 if (pos >= width)
711 pos = width - 1;
712 if (pos < 0)
713 pos = 0;
714
715 printf("[");
716 for (i = 0; i < width; i++) {
717 if (percent >= 100.0) {
718 printf("=");
719 } else if (i < pos) {
720 printf("=");
721 } else if (i == pos) {
722 printf(">");
723 } else {
724 printf(" ");
725 }
726 }
727 printf("]");
728}
729
730/* Initialize the 4-line progress area */
731static void progress_init(void)
732{
733 if (!progress_mode_active) {
734 progress_mode_active = 1;
735 /* Use current line as line 1, and reserve 3 more lines */
736 printf("\n\n\n");
737 /* Save cursor position at line 4 */
738 printf(CURSOR_SAVE);
739 progress_status[0] = '\0';
740 transfer_info[0] = '\0';
741 }
742}
743
744/* Render the 4-line progress display using current global state */
745static void progress_render(void)
746{
747 const int bar_width = 30;
748 const char *direction_label = "Sending";
749 const char *display_name = transfer_info;
750 if (!progress_mode_active) {
751 progress_init();
752 }
753
754 /* Restore saved cursor position for line 4, then move to line 1 */
755 printf(CURSOR_RESTORE);
756 printf(CURSOR_UP CURSOR_UP CURSOR_UP);
757
758 if (transfer_status == TRANSFER_RECEIVE) {
759 direction_label = "Receiving";
760 } else if (transfer_status == TRANSFER_SEND) {
761 direction_label = "Sending";
762 } else {
763 direction_label = "";
764 }
765
766 /* Line 1: Overall backup progress */
767 printf(CLEAR_LINE MOVE_COL_1);
768 printf("%-10s ", "Backup");
769 draw_progress_bar(overall_progress, bar_width);
770 printf(" %3.0f%%", overall_progress);
771
772 /* Line 2: Current file */
773 printf("\n");
774 printf(CLEAR_LINE MOVE_COL_1);
775 printf("%-10s ", direction_label);
776 if (display_name[0]) {
777 //printf("%s%s", direction_arrow, display_name);
778 printf("%s", display_name);
779 }
780
781 /* Line 3: Sending / Receiving progress */
782 printf("\n");
783 printf(CLEAR_LINE MOVE_COL_1);
784 printf("%-10s ", "");
785 draw_transfer_bar(file_progress, bar_width);
786 printf(" %5.1f%%", file_progress);
787 if (file_current > 0 || file_total > 0) {
788 char *format_size_current = string_format_size(file_current);
789 char *format_size_total = string_format_size(file_total);
790 if (format_size_current && format_size_total) {
791 printf(" %s / %s", format_size_current, format_size_total);
792 }
793 free(format_size_current);
794 free(format_size_total);
795 }
796 printf(" ");
797
798 /* Line 4: Status message */
799 printf("\n");
800 printf(CLEAR_LINE MOVE_COL_1);
801 printf("%-10s ", "Status");
802 if (progress_status[0]) {
803 printf("%s", progress_status);
804 }
805
806 /* Save cursor position at line 4 again for the next redraw */
807 printf(CURSOR_SAVE);
808 fflush(stdout);
809}
810
811/*
812 * Print a normal log line without permanently corrupting the reserved
813 * 4-line progress area. If progress mode is active, print the log message
814 * below the progress block, reserve a fresh 4-line area there, and redraw.
815 */
816static void progress_printf(const char *fmt, ...)
817{
818 va_list ap;
819
820 if (progress_mode_active) {
821 /* Go to saved line 4 and move to a fresh line below the block */
822 printf(CURSOR_RESTORE);
823 printf("\n");
824 }
825
826 va_start(ap, fmt);
827 vprintf(fmt, ap);
828 va_end(ap);
829
830 if (progress_mode_active) {
831 /*
832 * Re-anchor the progress block on the current line:
833 * current line becomes line 1, plus 3 reserved lines below it.
834 */
835 printf("\n\n\n");
836 printf(CURSOR_SAVE);
837 progress_render();
838 }
839}
840
841#if 0
842/* Update progress values and render */
843static void progress_update(double overall, double file, uint64_t current, uint64_t total)
844{
845 overall_progress = overall;
846 file_progress = file;
847 file_current = current;
848 file_total = total;
849 progress_render();
850}
851
852/* Legacy single-line progress for simple operations */
665static void print_progress_real(double progress, int flush) 853static void print_progress_real(double progress, int flush)
666{ 854{
667 int i = 0; 855 int i = 0;
@@ -677,42 +865,55 @@ static void print_progress_real(double progress, int flush)
677 865
678 if (flush > 0) { 866 if (flush > 0) {
679 fflush(stdout); 867 fflush(stdout);
680 if (progress == 100) 868 }
681 PRINT_VERBOSE(1, "\n"); 869 if (progress == 100) {
870 PRINT_VERBOSE(1, "\n");
682 } 871 }
683} 872}
873#endif
684 874
685static void print_progress(uint64_t current, uint64_t total) 875/* Called during file transfers - uses 3-line display */
876static void print_progress(uint64_t current, uint64_t total, int sending)
686{ 877{
687 char *format_size = NULL; 878 //double file_progress = 0;
688 double progress = ((double)current/(double)total)*100; 879 /* Don't update file progress if overall backup is complete */
689 if (progress < 0) 880 //if (overall_progress >= 100.0)
690 return; 881 // return;
691 882 file_current = current;
692 if (progress > 100) 883 file_total = total;
693 progress = 100; 884 if (total > 0) {
694 885 file_progress = ((double)current / (double)total) * 100;
695 print_progress_real((double)progress, 0); 886 if (file_progress > 100) file_progress = 100;
696 887 } else {
697 format_size = string_format_size(current); 888 file_progress = 0;
698 PRINT_VERBOSE(1, " (%s", format_size); 889 }
699 free(format_size); 890 //progress_update(overall_progress, file_progress, current, total);
700 format_size = string_format_size(total); 891 transfer_status = sending;
701 PRINT_VERBOSE(1, "/%s) ", format_size); 892 progress_render();
702 free(format_size);
703
704 fflush(stdout);
705 if (progress == 100)
706 PRINT_VERBOSE(1, "\n");
707} 893}
708 894
709static double overall_progress = 0; 895/* Exit progress mode - print final newline */
896static void progress_finish(void)
897{
898 if (progress_mode_active) {
899 overall_progress = 100;
900 //transfer_status = TRANSFER_NONE;
901 progress_render();
902 progress_mode_active = 0;
903 printf("\n");
904 fflush(stdout);
905 progress_status[0] = '\0';
906 //transfer_info[0] = '\0';
907 }
908}
710 909
910#if 0
711static void mb2_set_overall_progress(double progress) 911static void mb2_set_overall_progress(double progress)
712{ 912{
713 if (progress > 0.0) 913 if (progress > 0.0)
714 overall_progress = progress; 914 overall_progress = progress;
715} 915}
916#endif
716 917
717static void mb2_set_overall_progress_from_message(plist_t message, char* identifier) 918static void mb2_set_overall_progress_from_message(plist_t message, char* identifier)
718{ 919{
@@ -731,7 +932,8 @@ static void mb2_set_overall_progress_from_message(plist_t message, char* identif
731 932
732 if (node != NULL) { 933 if (node != NULL) {
733 plist_get_real_val(node, &progress); 934 plist_get_real_val(node, &progress);
734 mb2_set_overall_progress(progress); 935 //mb2_set_overall_progress(progress);
936 overall_progress = progress;
735 } 937 }
736} 938}
737 939
@@ -822,16 +1024,17 @@ static int mb2_handle_send_file(mobilebackup2_client_t mobilebackup2, const char
822#endif 1024#endif
823 { 1025 {
824 if (errno != ENOENT) 1026 if (errno != ENOENT)
825 printf("%s: stat failed on '%s': %d\n", __func__, localfile, errno); 1027 progress_printf("%s: stat failed on '%s': %d\n", __func__, localfile, errno);
826 errcode = errno; 1028 errcode = errno;
827 goto leave; 1029 goto leave;
828 } 1030 }
829 1031
830 total = fst.st_size; 1032 total = fst.st_size;
831 1033
832 char *format_size = string_format_size(total); 1034 //char *format_size = string_format_size(total);
833 PRINT_VERBOSE(1, "Sending '%s' (%s)\n", path, format_size); 1035 snprintf(transfer_info, sizeof(transfer_info), "%s", path); //"'%s' (%s)", path, format_size);
834 free(format_size); 1036 //free(format_size);
1037 progress_render();
835 1038
836 if (total == 0) { 1039 if (total == 0) {
837 errcode = 0; 1040 errcode = 0;
@@ -840,7 +1043,7 @@ static int mb2_handle_send_file(mobilebackup2_client_t mobilebackup2, const char
840 1043
841 f = fopen(localfile, "rb"); 1044 f = fopen(localfile, "rb");
842 if (!f) { 1045 if (!f) {
843 printf("%s: Error opening local file '%s': %d\n", __func__, localfile, errno); 1046 progress_printf("%s: Error opening local file '%s': %d\n", __func__, localfile, errno);
844 errcode = errno; 1047 errcode = errno;
845 goto leave; 1048 goto leave;
846 } 1049 }
@@ -863,7 +1066,7 @@ static int mb2_handle_send_file(mobilebackup2_client_t mobilebackup2, const char
863 /* send file contents */ 1066 /* send file contents */
864 size_t r = fread(buf, 1, sizeof(buf), f); 1067 size_t r = fread(buf, 1, sizeof(buf), f);
865 if (r <= 0) { 1068 if (r <= 0) {
866 printf("%s: read error\n", __func__); 1069 progress_printf("%s: read error\n", __func__);
867 errcode = errno; 1070 errcode = errno;
868 goto leave; 1071 goto leave;
869 } 1072 }
@@ -872,10 +1075,11 @@ static int mb2_handle_send_file(mobilebackup2_client_t mobilebackup2, const char
872 goto leave_proto_err; 1075 goto leave_proto_err;
873 } 1076 }
874 if (bytes != (uint32_t)r) { 1077 if (bytes != (uint32_t)r) {
875 printf("Error: sent only %d of %d bytes\n", bytes, (int)r); 1078 progress_printf("Error: sent only %d of %d bytes\n", bytes, (int)r);
876 goto leave_proto_err; 1079 goto leave_proto_err;
877 } 1080 }
878 sent += r; 1081 sent += r;
1082 print_progress(sent, total, 1);
879 } while (sent < total); 1083 } while (sent < total);
880 fclose(f); 1084 fclose(f);
881 f = NULL; 1085 f = NULL;
@@ -905,10 +1109,10 @@ leave:
905 slen += length; 1109 slen += length;
906 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, &bytes); 1110 err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, slen, &bytes);
907 if (err != MOBILEBACKUP2_E_SUCCESS) { 1111 if (err != MOBILEBACKUP2_E_SUCCESS) {
908 printf("could not send message\n"); 1112 progress_printf("could not send message\n");
909 } 1113 }
910 if (bytes != slen) { 1114 if (bytes != slen) {
911 printf("could only send %d from %d\n", bytes, slen); 1115 progress_printf("could only send %d from %d\n", bytes, slen);
912 } 1116 }
913 } 1117 }
914 1118
@@ -931,6 +1135,8 @@ static void mb2_handle_send_files(mobilebackup2_client_t mobilebackup2, plist_t
931 plist_t files = plist_array_get_item(message, 1); 1135 plist_t files = plist_array_get_item(message, 1);
932 cnt = plist_array_get_size(files); 1136 cnt = plist_array_get_size(files);
933 1137
1138 //snprintf(progress_status, sizeof(progress_status), "Sending files");
1139
934 for (i = 0; i < cnt; i++) { 1140 for (i = 0; i < cnt; i++) {
935 plist_t val = plist_array_get_item(files, i); 1141 plist_t val = plist_array_get_item(files, i);
936 if (plist_get_node_type(val) != PLIST_STRING) { 1142 if (plist_get_node_type(val) != PLIST_STRING) {
@@ -985,7 +1191,7 @@ static int mb2_receive_filename(mobilebackup2_client_t mobilebackup2, char** fil
985 } 1191 }
986 if (nlen > 4096) { 1192 if (nlen > 4096) {
987 // filename length is too large 1193 // filename length is too large
988 printf("ERROR: %s: too large filename length (%d)!\n", __func__, nlen); 1194 progress_printf("ERROR: %s: too large filename length (%d)!\n", __func__, nlen);
989 return 0; 1195 return 0;
990 } 1196 }
991 1197
@@ -999,7 +1205,7 @@ static int mb2_receive_filename(mobilebackup2_client_t mobilebackup2, char** fil
999 rlen = 0; 1205 rlen = 0;
1000 mobilebackup2_receive_raw(mobilebackup2, *filename, nlen, &rlen); 1206 mobilebackup2_receive_raw(mobilebackup2, *filename, nlen, &rlen);
1001 if (rlen != nlen) { 1207 if (rlen != nlen) {
1002 printf("ERROR: %s: could not read filename\n", __func__); 1208 progress_printf("ERROR: %s: could not read filename\n", __func__);
1003 return 0; 1209 return 0;
1004 } 1210 }
1005 1211
@@ -1040,17 +1246,24 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1040 plist_get_uint_val(node, &backup_total_size); 1246 plist_get_uint_val(node, &backup_total_size);
1041 } 1247 }
1042 if (backup_total_size > 0) { 1248 if (backup_total_size > 0) {
1043 PRINT_VERBOSE(1, "Receiving files\n"); 1249 //progress_printf("Receiving files\n");
1250 snprintf(progress_status, sizeof(progress_status), "Receiving files"); /* Clear status when starting file transfers */
1251 //transfer_info[0] = '\0'; /* Clear transfer info */
1044 } 1252 }
1045 1253
1046 do { 1254 do {
1047 if (quit_flag) 1255 if (quit_flag)
1048 break; 1256 break;
1049 1257
1050 nlen = mb2_receive_filename(mobilebackup2, &dname); 1258 nlen = mb2_receive_filename(mobilebackup2, &dname);
1051 if (nlen == 0) { 1259 if (nlen == 0) {
1052 break; 1260 break;
1053 } 1261 }
1262 if (nlen > 68) {
1263 snprintf(transfer_info, sizeof(transfer_info), "...%s", dname + (nlen - 65));
1264 } else {
1265 snprintf(transfer_info, sizeof(transfer_info), "%s", dname);
1266 }
1054 1267
1055 nlen = mb2_receive_filename(mobilebackup2, &fname); 1268 nlen = mb2_receive_filename(mobilebackup2, &fname);
1056 if (!nlen) { 1269 if (!nlen) {
@@ -1073,7 +1286,7 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1073 nlen = 0; 1286 nlen = 0;
1074 mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r); 1287 mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r);
1075 if (r != 4) { 1288 if (r != 4) {
1076 printf("ERROR: %s: could not receive code length!\n", __func__); 1289 progress_printf("ERROR: %s: could not receive code length!\n", __func__);
1077 break; 1290 break;
1078 } 1291 }
1079 nlen = be32toh(nlen); 1292 nlen = be32toh(nlen);
@@ -1083,13 +1296,13 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1083 1296
1084 mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r); 1297 mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r);
1085 if (r != 1) { 1298 if (r != 1) {
1086 printf("ERROR: %s: could not receive code!\n", __func__); 1299 progress_printf("ERROR: %s: could not receive code!\n", __func__);
1087 break; 1300 break;
1088 } 1301 }
1089 1302
1090 /* TODO remove this */ 1303 /* TODO remove this */
1091 if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) { 1304 if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) {
1092 PRINT_VERBOSE(1, "Found new flag %02x\n", code); 1305 progress_printf("Found new flag %02x\n", code);
1093 } 1306 }
1094 1307
1095 remove_file(bname); 1308 remove_file(bname);
@@ -1115,7 +1328,7 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1115 backup_real_size += blocksize; 1328 backup_real_size += blocksize;
1116 } 1329 }
1117 if (backup_total_size > 0) { 1330 if (backup_total_size > 0) {
1118 print_progress(backup_real_size, backup_total_size); 1331 print_progress(backup_real_size, backup_total_size, TRANSFER_RECEIVE);
1119 } 1332 }
1120 if (quit_flag) 1333 if (quit_flag)
1121 break; 1334 break;
@@ -1135,7 +1348,7 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1135 } else { 1348 } else {
1136 errcode = errno_to_device_error(errno); 1349 errcode = errno_to_device_error(errno);
1137 errdesc = strerror(errno); 1350 errdesc = strerror(errno);
1138 printf("Error opening '%s' for writing: %s\n", bname, errdesc); 1351 progress_printf("Error opening '%s' for writing: %s\n", bname, errdesc);
1139 break; 1352 break;
1140 } 1353 }
1141 if (nlen == 0) { 1354 if (nlen == 0) {
@@ -1150,7 +1363,7 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1150 msg[r] = 0; 1363 msg[r] = 0;
1151 /* If sent using CODE_FILE_DATA, end marker will be CODE_ERROR_REMOTE which is not an error! */ 1364 /* If sent using CODE_FILE_DATA, end marker will be CODE_ERROR_REMOTE which is not an error! */
1152 if (last_code != CODE_FILE_DATA) { 1365 if (last_code != CODE_FILE_DATA) {
1153 fprintf(stdout, "\nReceived an error message from device: %s\n", msg); 1366 progress_printf("Received an error message from device: %s\n", msg);
1154 } 1367 }
1155 free(msg); 1368 free(msg);
1156 } 1369 }
@@ -1161,7 +1374,7 @@ static int mb2_handle_receive_files(mobilebackup2_client_t mobilebackup2, plist_
1161 1374
1162 /* if there are leftovers to read, finish up cleanly */ 1375 /* if there are leftovers to read, finish up cleanly */
1163 if ((int)nlen-1 > 0) { 1376 if ((int)nlen-1 > 0) {
1164 PRINT_VERBOSE(1, "\nDiscarding current data hunk.\n"); 1377 progress_printf("Discarding current data hunk.\n");
1165 fname = (char*)malloc(nlen-1); 1378 fname = (char*)malloc(nlen-1);
1166 mobilebackup2_receive_raw(mobilebackup2, fname, nlen-1, &r); 1379 mobilebackup2_receive_raw(mobilebackup2, fname, nlen-1, &r);
1167 free(fname); 1380 free(fname);
@@ -1425,7 +1638,9 @@ static char* ask_for_password(const char* msg, int type_again)
1425 */ 1638 */
1426static void clean_exit(int sig) 1639static void clean_exit(int sig)
1427{ 1640{
1428 fprintf(stderr, "Exiting...\n"); 1641 snprintf(progress_status, sizeof(progress_status), "Abort requested, hold on...");
1642 progress_render();
1643 //fprintf(stderr, "Exiting...\n");
1429 quit_flag++; 1644 quit_flag++;
1430} 1645}
1431 1646
@@ -2303,6 +2518,8 @@ checkpoint:
2303 /* device wants to download files from the computer */ 2518 /* device wants to download files from the computer */
2304 mb2_set_overall_progress_from_message(message, dlmsg); 2519 mb2_set_overall_progress_from_message(message, dlmsg);
2305 mb2_handle_send_files(mobilebackup2, message, backup_directory); 2520 mb2_handle_send_files(mobilebackup2, message, backup_directory);
2521 //snprintf(progress_status, sizeof(progress_status), "Waiting for device...");
2522 //progress_render();
2306 } else if (!strcmp(dlmsg, "DLMessageUploadFiles")) { 2523 } else if (!strcmp(dlmsg, "DLMessageUploadFiles")) {
2307 /* device wants to send files to the computer */ 2524 /* device wants to send files to the computer */
2308 mb2_set_overall_progress_from_message(message, dlmsg); 2525 mb2_set_overall_progress_from_message(message, dlmsg);
@@ -2342,7 +2559,8 @@ checkpoint:
2342 mb2_set_overall_progress_from_message(message, dlmsg); 2559 mb2_set_overall_progress_from_message(message, dlmsg);
2343 plist_t moves = plist_array_get_item(message, 1); 2560 plist_t moves = plist_array_get_item(message, 1);
2344 uint32_t cnt = plist_dict_get_size(moves); 2561 uint32_t cnt = plist_dict_get_size(moves);
2345 PRINT_VERBOSE(1, "Moving %d file%s\n", cnt, (cnt == 1) ? "" : "s"); 2562 snprintf(progress_status, sizeof(progress_status), "Moving %d file%s", cnt, (cnt == 1) ? "" : "s");
2563 progress_render();
2346 plist_dict_iter iter = NULL; 2564 plist_dict_iter iter = NULL;
2347 plist_dict_new_iter(moves, &iter); 2565 plist_dict_new_iter(moves, &iter);
2348 errcode = 0; 2566 errcode = 0;
@@ -2393,7 +2611,8 @@ checkpoint:
2393 mb2_set_overall_progress_from_message(message, dlmsg); 2611 mb2_set_overall_progress_from_message(message, dlmsg);
2394 plist_t removes = plist_array_get_item(message, 1); 2612 plist_t removes = plist_array_get_item(message, 1);
2395 uint32_t cnt = plist_array_get_size(removes); 2613 uint32_t cnt = plist_array_get_size(removes);
2396 PRINT_VERBOSE(1, "Removing %d file%s\n", cnt, (cnt == 1) ? "" : "s"); 2614 snprintf(progress_status, sizeof(progress_status), "Removing %d file%s", cnt, (cnt == 1) ? "" : "s");
2615 progress_render();
2397 uint32_t ii = 0; 2616 uint32_t ii = 0;
2398 errcode = 0; 2617 errcode = 0;
2399 errdesc = NULL; 2618 errdesc = NULL;
@@ -2520,9 +2739,10 @@ checkpoint:
2520 if ((overall_progress > 0) && !progress_finished) { 2739 if ((overall_progress > 0) && !progress_finished) {
2521 if (overall_progress >= 100.0F) { 2740 if (overall_progress >= 100.0F) {
2522 progress_finished = 1; 2741 progress_finished = 1;
2742 //progress_finish();
2743 //} else {
2744 // print_progress_real(overall_progress, 0);
2523 } 2745 }
2524 print_progress_real(overall_progress, 0);
2525 PRINT_VERBOSE(1, " Finished\n");
2526 } 2746 }
2527 2747
2528files_out: 2748files_out:
@@ -2547,6 +2767,8 @@ files_out:
2547 plist_free(message); 2767 plist_free(message);
2548 free(dlmsg); 2768 free(dlmsg);
2549 2769
2770 progress_finish();
2771
2550 /* report operation status to user */ 2772 /* report operation status to user */
2551 switch (cmd) { 2773 switch (cmd) {
2552 case CMD_CLOUD: 2774 case CMD_CLOUD: