diff options
Diffstat (limited to 'tools/idevicebackup4.c')
| -rw-r--r-- | tools/idevicebackup4.c | 82 |
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; | |||
| 52 | static afc_client_t afc = NULL; | 52 | static afc_client_t afc = NULL; |
| 53 | static idevice_t phone = NULL; | 53 | static idevice_t phone = NULL; |
| 54 | 54 | ||
| 55 | static int verbose = 1; | ||
| 55 | static int quit_flag = 0; | 56 | static int quit_flag = 0; |
| 56 | 57 | ||
| 58 | #define PRINT_VERBOSE(min_level, ...) if (verbose >= min_level) { printf(__VA_ARGS__); }; | ||
| 59 | |||
| 57 | enum cmd_mode { | 60 | enum cmd_mode { |
| 58 | CMD_BACKUP, | 61 | CMD_BACKUP, |
| 59 | CMD_RESTORE, | 62 | CMD_RESTORE, |
| @@ -70,10 +73,10 @@ enum plist_format_t { | |||
| 70 | static void notify_cb(const char *notification, void *userdata) | 73 | static 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 | ||
| 486 | static void mb2_multi_status_add_file_error(plist_t status_dict, const char *path, int error_code, const char *error_message) | 489 | static 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) { |
