diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/iphonebackup.c | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/tools/iphonebackup.c b/tools/iphonebackup.c index 781f9d3..f212fc8 100644 --- a/tools/iphonebackup.c +++ b/tools/iphonebackup.c | |||
| @@ -2,7 +2,8 @@ | |||
| 2 | * iphonebackup.c | 2 | * iphonebackup.c |
| 3 | * Command line interface to use the device's backup and restore service | 3 | * Command line interface to use the device's backup and restore service |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2009 Martin Szulecki All Rights Reserved. | 5 | * Copyright (c) 2009-2010 Martin Szulecki All Rights Reserved. |
| 6 | * Copyright (c) 2010 Nikias Bassen All Rights Reserved. | ||
| 6 | * | 7 | * |
| 7 | * This library is free software; you can redistribute it and/or | 8 | * This library is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Lesser General Public | 9 | * modify it under the terms of the GNU Lesser General Public |
| @@ -29,8 +30,11 @@ | |||
| 29 | #include <libiphone/libiphone.h> | 30 | #include <libiphone/libiphone.h> |
| 30 | #include <libiphone/lockdown.h> | 31 | #include <libiphone/lockdown.h> |
| 31 | #include <libiphone/mobilebackup.h> | 32 | #include <libiphone/mobilebackup.h> |
| 33 | #include <libiphone/notification_proxy.h> | ||
| 34 | #include <libiphone/afc.h> | ||
| 32 | 35 | ||
| 33 | #define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" | 36 | #define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" |
| 37 | #define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" | ||
| 34 | 38 | ||
| 35 | static mobilebackup_client_t mobilebackup = NULL; | 39 | static mobilebackup_client_t mobilebackup = NULL; |
| 36 | static lockdownd_client_t client = NULL; | 40 | static lockdownd_client_t client = NULL; |
| @@ -55,6 +59,16 @@ enum device_link_file_status_t { | |||
| 55 | DEVICE_LINK_FILE_STATUS_LAST_HUNK | 59 | DEVICE_LINK_FILE_STATUS_LAST_HUNK |
| 56 | }; | 60 | }; |
| 57 | 61 | ||
| 62 | static void notify_cb(const char *notification) | ||
| 63 | { | ||
| 64 | if (!strcmp(notification, NP_SYNC_CANCEL_REQUEST)) { | ||
| 65 | printf("User has aborted on-device\n"); | ||
| 66 | quit_flag++; | ||
| 67 | } else { | ||
| 68 | printf("unhandled notification '%s' (TODO: implement)\n", notification); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 58 | static plist_t mobilebackup_factory_info_plist_new() | 72 | static plist_t mobilebackup_factory_info_plist_new() |
| 59 | { | 73 | { |
| 60 | /* gather data from lockdown */ | 74 | /* gather data from lockdown */ |
| @@ -345,6 +359,29 @@ static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, | |||
| 345 | return ret; | 359 | return ret; |
| 346 | } | 360 | } |
| 347 | 361 | ||
| 362 | static void do_post_notification(const char *notification) | ||
| 363 | { | ||
| 364 | uint16_t nport = 0; | ||
| 365 | np_client_t np; | ||
| 366 | |||
| 367 | if (!client) { | ||
| 368 | if (lockdownd_client_new_with_handshake(phone, &client, "iphonebackup") != LOCKDOWN_E_SUCCESS) { | ||
| 369 | return; | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | lockdownd_start_service(client, NP_SERVICE_NAME, &nport); | ||
| 374 | if (nport) { | ||
| 375 | np_client_new(phone, nport, &np); | ||
| 376 | if (np) { | ||
| 377 | np_post_notification(np, notification); | ||
| 378 | np_client_free(np); | ||
| 379 | } | ||
| 380 | } else { | ||
| 381 | printf("Could not start %s\n", NP_SERVICE_NAME); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 348 | /** | 385 | /** |
| 349 | * signal handler function for cleaning up properly | 386 | * signal handler function for cleaning up properly |
| 350 | */ | 387 | */ |
| @@ -483,7 +520,34 @@ int main(int argc, char *argv[]) | |||
| 483 | return -1; | 520 | return -1; |
| 484 | } | 521 | } |
| 485 | 522 | ||
| 523 | /* start notification_proxy */ | ||
| 524 | np_client_t np = NULL; | ||
| 525 | ret = lockdownd_start_service(client, NP_SERVICE_NAME, &port); | ||
| 526 | if ((ret == LOCKDOWN_E_SUCCESS) && port) { | ||
| 527 | np_client_new(phone, port, &np); | ||
| 528 | np_set_notify_callback(np, notify_cb); | ||
| 529 | const char *noties[5] = { | ||
| 530 | NP_SYNC_CANCEL_REQUEST, | ||
| 531 | NP_SYNC_SUSPEND_REQUEST, | ||
| 532 | NP_SYNC_RESUME_REQUEST, | ||
| 533 | NP_BACKUP_DOMAIN_CHANGED, | ||
| 534 | NULL | ||
| 535 | }; | ||
| 536 | np_observe_notifications(np, noties); | ||
| 537 | } else { | ||
| 538 | printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME); | ||
| 539 | } | ||
| 540 | |||
| 541 | /* start AFC, we need this for the lock file */ | ||
| 542 | afc_client_t afc = NULL; | ||
| 543 | port = 0; | ||
| 544 | ret = lockdownd_start_service(client, "com.apple.afc", &port); | ||
| 545 | if ((ret == LOCKDOWN_E_SUCCESS) && port) { | ||
| 546 | afc_client_new(phone, port, &afc); | ||
| 547 | } | ||
| 548 | |||
| 486 | /* start syslog_relay service and retrieve port */ | 549 | /* start syslog_relay service and retrieve port */ |
| 550 | port = 0; | ||
| 487 | ret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &port); | 551 | ret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &port); |
| 488 | if ((ret == LOCKDOWN_E_SUCCESS) && port) { | 552 | if ((ret == LOCKDOWN_E_SUCCESS) && port) { |
| 489 | printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); | 553 | printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); |
| @@ -494,11 +558,23 @@ int main(int argc, char *argv[]) | |||
| 494 | cmd = CMD_LEAVE; | 558 | cmd = CMD_LEAVE; |
| 495 | } | 559 | } |
| 496 | 560 | ||
| 561 | do_post_notification(NP_SYNC_WILL_START); | ||
| 562 | uint64_t lockfile = 0; | ||
| 563 | afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); | ||
| 564 | if (lockfile) { | ||
| 565 | do_post_notification(NP_SYNC_LOCK_REQUEST); | ||
| 566 | if (afc_file_lock(afc, lockfile, AFC_LOCK_EX) == AFC_E_SUCCESS) { | ||
| 567 | do_post_notification(NP_SYNC_DID_START); | ||
| 568 | } else { | ||
| 569 | afc_file_close(afc, lockfile); | ||
| 570 | lockfile = 0; | ||
| 571 | } | ||
| 572 | } | ||
| 497 | switch(cmd) { | 573 | switch(cmd) { |
| 498 | case CMD_BACKUP: | 574 | case CMD_BACKUP: |
| 499 | printf("Starting backup...\n"); | 575 | printf("Starting backup...\n"); |
| 500 | /* TODO: check domain com.apple.mobile.backup key RequiresEncrypt and WillEncrypt with lockdown */ | 576 | /* TODO: check domain com.apple.mobile.backup key RequiresEncrypt and WillEncrypt with lockdown */ |
| 501 | /* TODO: verify battery on AC enough battery remaining */ | 577 | /* TODO: verify battery on AC enough battery remaining */ |
| 502 | 578 | ||
| 503 | /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ | 579 | /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ |
| 504 | 580 | ||
| @@ -815,6 +891,12 @@ int main(int argc, char *argv[]) | |||
| 815 | default: | 891 | default: |
| 816 | break; | 892 | break; |
| 817 | } | 893 | } |
| 894 | if (lockfile) { | ||
| 895 | afc_file_lock(afc, lockfile, AFC_LOCK_UN); | ||
| 896 | afc_file_close(afc, lockfile); | ||
| 897 | lockfile = 0; | ||
| 898 | do_post_notification(NP_SYNC_DID_FINISH); | ||
| 899 | } | ||
| 818 | } else { | 900 | } else { |
| 819 | printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); | 901 | printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); |
| 820 | lockdownd_client_free(client); | 902 | lockdownd_client_free(client); |
| @@ -826,6 +908,12 @@ int main(int argc, char *argv[]) | |||
| 826 | client = NULL; | 908 | client = NULL; |
| 827 | } | 909 | } |
| 828 | 910 | ||
| 911 | if (afc) | ||
| 912 | afc_client_free(afc); | ||
| 913 | |||
| 914 | if (np) | ||
| 915 | np_client_free(np); | ||
| 916 | |||
| 829 | if (mobilebackup) | 917 | if (mobilebackup) |
| 830 | mobilebackup_client_free(mobilebackup); | 918 | mobilebackup_client_free(mobilebackup); |
| 831 | 919 | ||
