summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/idevicebackup4.c82
1 files changed, 45 insertions, 37 deletions
diff --git a/tools/idevicebackup4.c b/tools/idevicebackup4.c
index 3f06a97..4aa0d46 100644
--- a/tools/idevicebackup4.c
+++ b/tools/idevicebackup4.c
@@ -52,8 +52,11 @@ static lockdownd_client_t client = NULL;
52static afc_client_t afc = NULL; 52static afc_client_t afc = NULL;
53static idevice_t phone = NULL; 53static idevice_t phone = NULL;
54 54
55static int verbose = 1;
55static int quit_flag = 0; 56static int quit_flag = 0;
56 57
58#define PRINT_VERBOSE(min_level, ...) if (verbose >= min_level) { printf(__VA_ARGS__); };
59
57enum cmd_mode { 60enum cmd_mode {
58 CMD_BACKUP, 61 CMD_BACKUP,
59 CMD_RESTORE, 62 CMD_RESTORE,
@@ -70,10 +73,10 @@ enum plist_format_t {
70static void notify_cb(const char *notification, void *userdata) 73static void notify_cb(const char *notification, void *userdata)
71{ 74{
72 if (!strcmp(notification, NP_SYNC_CANCEL_REQUEST)) { 75 if (!strcmp(notification, NP_SYNC_CANCEL_REQUEST)) {
73 printf("User has cancelled the backup process on the device.\n"); 76 PRINT_VERBOSE(1, "User has cancelled the backup process on the device.\n");
74 quit_flag++; 77 quit_flag++;
75 } else { 78 } else {
76 printf("Unhandled notification '%s' (TODO: implement)\n", notification); 79 PRINT_VERBOSE(1, "Unhandled notification '%s' (TODO: implement)\n", notification);
77 } 80 }
78} 81}
79 82
@@ -461,26 +464,26 @@ static void print_progress(uint64_t current, uint64_t total)
461 if (progress > 100) 464 if (progress > 100)
462 progress = 100; 465 progress = 100;
463 466
464 printf("\r["); 467 PRINT_VERBOSE(1, "\r[");
465 for(i = 0; i < 50; i++) { 468 for(i = 0; i < 50; i++) {
466 if(i < progress / 2) { 469 if(i < progress / 2) {
467 printf("="); 470 PRINT_VERBOSE(1, "=");
468 } else { 471 } else {
469 printf(" "); 472 PRINT_VERBOSE(1, " ");
470 } 473 }
471 } 474 }
472 printf("] %3.0f%%", progress); 475 PRINT_VERBOSE(1, "] %3.0f%%", progress);
473 476
474 format_size = g_format_size_for_display(current); 477 format_size = g_format_size_for_display(current);
475 printf(" (%s", format_size); 478 PRINT_VERBOSE(1, " (%s", format_size);
476 g_free(format_size); 479 g_free(format_size);
477 format_size = g_format_size_for_display(total); 480 format_size = g_format_size_for_display(total);
478 printf("/%s) ", format_size); 481 PRINT_VERBOSE(1, "/%s) ", format_size);
479 g_free(format_size); 482 g_free(format_size);
480 483
481 fflush(stdout); 484 fflush(stdout);
482 if (progress == 100) 485 if (progress == 100)
483 printf("\n"); 486 PRINT_VERBOSE(1, "\n");
484} 487}
485 488
486static void mb2_multi_status_add_file_error(plist_t status_dict, const char *path, int error_code, const char *error_message) 489static void mb2_multi_status_add_file_error(plist_t status_dict, const char *path, int error_code, const char *error_message)
@@ -553,7 +556,7 @@ static int mb2_handle_send_file(const char *backup_dir, const char *path, plist_
553 total = fst.st_size; 556 total = fst.st_size;
554 557
555 gchar *format_size = g_format_size_for_display(total); 558 gchar *format_size = g_format_size_for_display(total);
556 printf("Sending file '%s': (%s)\n", path, format_size); 559 PRINT_VERBOSE(1, "Sending file '%s': (%s)\n", path, format_size);
557 g_free(format_size); 560 g_free(format_size);
558 561
559 if (total == 0) { 562 if (total == 0) {
@@ -710,7 +713,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir)
710 plist_get_uint_val(node, &backup_total_size); 713 plist_get_uint_val(node, &backup_total_size);
711 } 714 }
712 if (backup_total_size > 0) { 715 if (backup_total_size > 0) {
713 printf("Receiving backup data\n"); 716 PRINT_VERBOSE(1, "Receiving backup data\n");
714 } 717 }
715 718
716 do { 719 do {
@@ -775,7 +778,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir)
775 778
776 /* TODO remove this */ 779 /* TODO remove this */
777 if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) { 780 if ((code != CODE_SUCCESS) && (code != CODE_FILE_DATA) && (code != CODE_ERROR_REMOTE)) {
778 printf("Found new flag %02x\n", code); 781 PRINT_VERBOSE(1, "Found new flag %02x\n", code);
779 } 782 }
780 783
781 remove(bname); 784 remove(bname);
@@ -843,7 +846,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir)
843 846
844 /* if there are leftovers to read, finish up cleanly */ 847 /* if there are leftovers to read, finish up cleanly */
845 if ((int)nlen-1 > 0) { 848 if ((int)nlen-1 > 0) {
846 printf("\nDiscarding current data hunk.\n"); 849 PRINT_VERBOSE(1, "\nDiscarding current data hunk.\n");
847 fname = (char*)malloc(nlen-1); 850 fname = (char*)malloc(nlen-1);
848 mobilebackup2_receive_raw(mobilebackup2, fname, nlen-1, &r); 851 mobilebackup2_receive_raw(mobilebackup2, fname, nlen-1, &r);
849 free(fname); 852 free(fname);
@@ -1019,9 +1022,11 @@ int main(int argc, char *argv[])
1019 } 1022 }
1020 else if (!strcmp(argv[i], "info")) { 1023 else if (!strcmp(argv[i], "info")) {
1021 cmd = CMD_INFO; 1024 cmd = CMD_INFO;
1025 verbose = 0;
1022 } 1026 }
1023 else if (!strcmp(argv[i], "list")) { 1027 else if (!strcmp(argv[i], "list")) {
1024 cmd = CMD_LIST; 1028 cmd = CMD_LIST;
1029 verbose = 0;
1025 } 1030 }
1026 else if (backup_directory == NULL) { 1031 else if (backup_directory == NULL) {
1027 backup_directory = argv[i]; 1032 backup_directory = argv[i];
@@ -1081,7 +1086,7 @@ int main(int argc, char *argv[])
1081 } 1086 }
1082 } 1087 }
1083 1088
1084 printf("Backup directory is \"%s\"\n", backup_directory); 1089 PRINT_VERBOSE(1, "Backup directory is \"%s\"\n", backup_directory);
1085 1090
1086 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicebackup")) { 1091 if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicebackup")) {
1087 idevice_free(phone); 1092 idevice_free(phone);
@@ -1120,7 +1125,7 @@ int main(int argc, char *argv[])
1120 port = 0; 1125 port = 0;
1121 ret = lockdownd_start_service(client, MOBILEBACKUP2_SERVICE_NAME, &port); 1126 ret = lockdownd_start_service(client, MOBILEBACKUP2_SERVICE_NAME, &port);
1122 if ((ret == LOCKDOWN_E_SUCCESS) && port) { 1127 if ((ret == LOCKDOWN_E_SUCCESS) && port) {
1123 printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP2_SERVICE_NAME, port); 1128 PRINT_VERBOSE(1, "Started \"%s\" service on port %d.\n", MOBILEBACKUP2_SERVICE_NAME, port);
1124 mobilebackup2_client_new(phone, port, &mobilebackup2); 1129 mobilebackup2_client_new(phone, port, &mobilebackup2);
1125 1130
1126 /* send Hello message */ 1131 /* send Hello message */
@@ -1133,14 +1138,14 @@ int main(int argc, char *argv[])
1133 1138
1134 /* check abort conditions */ 1139 /* check abort conditions */
1135 if (quit_flag > 0) { 1140 if (quit_flag > 0) {
1136 printf("Aborting backup. Cancelled by user.\n"); 1141 PRINT_VERBOSE(1, "Aborting as requested by user...\n");
1137 cmd = CMD_LEAVE; 1142 cmd = CMD_LEAVE;
1138 goto checkpoint; 1143 goto checkpoint;
1139 } 1144 }
1140 1145
1141 /* verify existing Info.plist */ 1146 /* verify existing Info.plist */
1142 if (stat(info_path, &st) == 0) { 1147 if (stat(info_path, &st) == 0) {
1143 printf("Reading Info.plist from backup.\n"); 1148 PRINT_VERBOSE(1, "Reading Info.plist from backup.\n");
1144 plist_read_from_filename(&info_plist, info_path); 1149 plist_read_from_filename(&info_plist, info_path);
1145 1150
1146 if (!info_plist) { 1151 if (!info_plist) {
@@ -1207,7 +1212,7 @@ checkpoint:
1207 1212
1208 switch(cmd) { 1213 switch(cmd) {
1209 case CMD_BACKUP: 1214 case CMD_BACKUP:
1210 printf("Starting backup...\n"); 1215 PRINT_VERBOSE(1, "Starting backup...\n");
1211 1216
1212 /* make sure backup device sub-directory exists */ 1217 /* make sure backup device sub-directory exists */
1213 gchar *devbackupdir = g_build_path(G_DIR_SEPARATOR_S, backup_directory, uuid, NULL); 1218 gchar *devbackupdir = g_build_path(G_DIR_SEPARATOR_S, backup_directory, uuid, NULL);
@@ -1231,14 +1236,15 @@ checkpoint:
1231 info_plist = NULL; 1236 info_plist = NULL;
1232 1237
1233 /* request backup from device with manifest from last backup */ 1238 /* request backup from device with manifest from last backup */
1234 printf("Requesting backup from device...\n"); 1239 PRINT_VERBOSE(1, "Requesting backup from device...\n");
1235 1240
1236 err = mobilebackup2_send_request(mobilebackup2, "Backup", uuid, NULL, NULL); 1241 err = mobilebackup2_send_request(mobilebackup2, "Backup", uuid, NULL, NULL);
1237 if (err == MOBILEBACKUP2_E_SUCCESS) { 1242 if (err == MOBILEBACKUP2_E_SUCCESS) {
1238 if (is_full_backup) 1243 if (is_full_backup) {
1239 printf("Full backup mode.\n"); 1244 PRINT_VERBOSE(1, "Full backup mode.\n");
1240 else 1245 } else {
1241 printf("Incremental backup mode.\n"); 1246 PRINT_VERBOSE(1, "Incremental backup mode.\n");
1247 }
1242 } else { 1248 } else {
1243 if (err == MOBILEBACKUP2_E_BAD_VERSION) { 1249 if (err == MOBILEBACKUP2_E_BAD_VERSION) {
1244 printf("ERROR: Could not start backup process: backup protocol version mismatch!\n"); 1250 printf("ERROR: Could not start backup process: backup protocol version mismatch!\n");
@@ -1260,7 +1266,7 @@ checkpoint:
1260 break; 1266 break;
1261 } 1267 }
1262 1268
1263 printf("Starting Restore...\n"); 1269 PRINT_VERBOSE(1, "Starting Restore...\n");
1264 1270
1265 plist_t opts = plist_new_dict(); 1271 plist_t opts = plist_new_dict();
1266 plist_dict_insert_item(opts, "shouldRestoreSystemFiles", plist_new_bool(0)); 1272 plist_dict_insert_item(opts, "shouldRestoreSystemFiles", plist_new_bool(0));
@@ -1278,7 +1284,7 @@ checkpoint:
1278 } 1284 }
1279 break; 1285 break;
1280 case CMD_INFO: 1286 case CMD_INFO:
1281 printf("Requesting backup info from device...\n"); 1287 PRINT_VERBOSE(1, "Requesting backup info from device...\n");
1282 err = mobilebackup2_send_request(mobilebackup2, "Info", uuid, NULL, NULL); 1288 err = mobilebackup2_send_request(mobilebackup2, "Info", uuid, NULL, NULL);
1283 if (err != MOBILEBACKUP2_E_SUCCESS) { 1289 if (err != MOBILEBACKUP2_E_SUCCESS) {
1284 printf("Error requesting backup info from device, error code %d\n", err); 1290 printf("Error requesting backup info from device, error code %d\n", err);
@@ -1286,7 +1292,7 @@ checkpoint:
1286 } 1292 }
1287 break; 1293 break;
1288 case CMD_LIST: 1294 case CMD_LIST:
1289 printf("Requesting backup list from device...\n"); 1295 PRINT_VERBOSE(1, "Requesting backup list from device...\n");
1290 err = mobilebackup2_send_request(mobilebackup2, "List", uuid, NULL, NULL); 1296 err = mobilebackup2_send_request(mobilebackup2, "List", uuid, NULL, NULL);
1291 if (err != MOBILEBACKUP2_E_SUCCESS) { 1297 if (err != MOBILEBACKUP2_E_SUCCESS) {
1292 printf("Error requesting backup list from device, error code %d\n", err); 1298 printf("Error requesting backup list from device, error code %d\n", err);
@@ -1321,7 +1327,7 @@ checkpoint:
1321 } 1327 }
1322 mobilebackup2_receive_message(mobilebackup2, &message, &dlmsg); 1328 mobilebackup2_receive_message(mobilebackup2, &message, &dlmsg);
1323 if (!message || !dlmsg) { 1329 if (!message || !dlmsg) {
1324 printf("Device is not ready yet. Going to try again in 2 seconds...\n"); 1330 PRINT_VERBOSE(1, "Device is not ready yet. Going to try again in 2 seconds...\n");
1325 sleep(2); 1331 sleep(2);
1326 goto files_out; 1332 goto files_out;
1327 } 1333 }
@@ -1342,7 +1348,7 @@ checkpoint:
1342 /* perform a series of rename operations */ 1348 /* perform a series of rename operations */
1343 plist_t moves = plist_array_get_item(message, 1); 1349 plist_t moves = plist_array_get_item(message, 1);
1344 uint32_t cnt = plist_dict_get_size(moves); 1350 uint32_t cnt = plist_dict_get_size(moves);
1345 printf("Moving %d file%s\n", cnt, (cnt == 1) ? "" : "s"); 1351 PRINT_VERBOSE(1, "Moving %d file%s\n", cnt, (cnt == 1) ? "" : "s");
1346 plist_dict_iter iter = NULL; 1352 plist_dict_iter iter = NULL;
1347 plist_dict_new_iter(moves, &iter); 1353 plist_dict_new_iter(moves, &iter);
1348 errcode = 0; 1354 errcode = 0;
@@ -1388,7 +1394,7 @@ checkpoint:
1388 } else if (!strcmp(dlmsg, "DLMessageRemoveFiles")) { 1394 } else if (!strcmp(dlmsg, "DLMessageRemoveFiles")) {
1389 plist_t removes = plist_array_get_item(message, 1); 1395 plist_t removes = plist_array_get_item(message, 1);
1390 uint32_t cnt = plist_array_get_size(removes); 1396 uint32_t cnt = plist_array_get_size(removes);
1391 printf("Removing %d file%s\n", cnt, (cnt == 1) ? "" : "s"); 1397 PRINT_VERBOSE(1, "Removing %d file%s\n", cnt, (cnt == 1) ? "" : "s");
1392 uint32_t ii = 0; 1398 uint32_t ii = 0;
1393 errcode = 0; 1399 errcode = 0;
1394 errdesc = NULL; 1400 errdesc = NULL;
@@ -1470,7 +1476,8 @@ checkpoint:
1470 if (nn && (plist_get_node_type(nn) == PLIST_STRING)) { 1476 if (nn && (plist_get_node_type(nn) == PLIST_STRING)) {
1471 str = NULL; 1477 str = NULL;
1472 plist_get_string_val(nn, &str); 1478 plist_get_string_val(nn, &str);
1473 printf("Content:\n%s\n", str); 1479 PRINT_VERBOSE(1, "Content:\n");
1480 printf("%s", str);
1474 free(str); 1481 free(str);
1475 } 1482 }
1476 break; 1483 break;
@@ -1505,18 +1512,19 @@ files_out:
1505 } while (1); 1512 } while (1);
1506 1513
1507 if (cmd == CMD_BACKUP) { 1514 if (cmd == CMD_BACKUP) {
1508 printf("Received %d files from device.\n", file_count); 1515 PRINT_VERBOSE(1, "Received %d files from device.\n", file_count);
1509 if (mb2_status_check_snapshot_state(backup_directory, uuid, "finished")) { 1516 if (mb2_status_check_snapshot_state(backup_directory, uuid, "finished")) {
1510 printf("Backup Successful.\n"); 1517 PRINT_VERBOSE(1, "Backup Successful.\n");
1511 } else { 1518 } else {
1512 if (quit_flag) 1519 if (quit_flag) {
1513 printf("Backup Aborted.\n"); 1520 PRINT_VERBOSE(1, "Backup Aborted.\n");
1514 else 1521 } else {
1515 printf("Backup Failed.\n"); 1522 PRINT_VERBOSE(1, "Backup Failed.\n");
1523 }
1516 } 1524 }
1517 } else if (cmd == CMD_RESTORE) { 1525 } else if (cmd == CMD_RESTORE) {
1518 // TODO: check for success/failure 1526 // TODO: check for success/failure
1519 printf("Restore operation finished. The device should reboot now to complete the process.\n"); 1527 PRINT_VERBOSE(1, "Restore operation finished. The device should reboot now to complete the process.\n");
1520 } 1528 }
1521 } 1529 }
1522 if (lockfile) { 1530 if (lockfile) {