diff options
| -rw-r--r-- | configure.ac | 18 | ||||
| -rw-r--r-- | src/ideviceinstaller.c | 345 |
2 files changed, 177 insertions, 186 deletions
diff --git a/configure.ac b/configure.ac index 0060140..ed19a7c 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -15,23 +15,7 @@ AM_PROG_CC_C_O | |||
| 15 | AC_PROG_LIBTOOL | 15 | AC_PROG_LIBTOOL |
| 16 | 16 | ||
| 17 | # Checks for libraries. | 17 | # Checks for libraries. |
| 18 | PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 0.9.7) | 18 | PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= 1.2.0) |
| 19 | PKG_CHECK_MODULES(libimobiledevice100, libimobiledevice-1.0 >= 1.0.0, libimobiledevice_1_0=yes, libimobiledevice_1_0=no) | ||
| 20 | if test x"$libimobiledevice_1_0" = xyes; then | ||
| 21 | AC_DEFINE([HAVE_LIBIMOBILEDEVICE_1_0], 1, [Define if libimobiledevice is using 1.0.0 API]) | ||
| 22 | fi | ||
| 23 | PKG_CHECK_MODULES(libimobiledevice110, libimobiledevice-1.0 >= 1.1.0, libimobiledevice_1_1=yes, libimobiledevice_1_1=no) | ||
| 24 | if test x"$libimobiledevice_1_1" = xyes; then | ||
| 25 | AC_DEFINE([HAVE_LIBIMOBILEDEVICE_1_1], 1, [Define if libimobiledevice is using 1.1.0 API]) | ||
| 26 | fi | ||
| 27 | PKG_CHECK_MODULES(libimobiledevice112, libimobiledevice-1.0 >= 1.1.2, libimobiledevice_1_2=yes, libimobiledevice_1_2=no) | ||
| 28 | if test x"$libimobiledevice_1_2" = xno; then | ||
| 29 | PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1) | ||
| 30 | fi | ||
| 31 | PKG_CHECK_MODULES(libimobiledevice115, libimobiledevice-1.0 >= 1.1.5, libimobiledevice_1_1_5=yes, libimobiledevice_1_1_5=no) | ||
| 32 | if test x"$libimobiledevice_1_1_5" = xyes; then | ||
| 33 | AC_DEFINE([HAVE_LIBIMOBILEDEVICE_1_1_5], 1, [Define if libimobiledevice is using 1.1.5 API]) | ||
| 34 | fi | ||
| 35 | PKG_CHECK_MODULES(libplist, libplist >= 0.15) | 19 | PKG_CHECK_MODULES(libplist, libplist >= 0.15) |
| 36 | PKG_CHECK_MODULES(libzip, libzip >= 0.8) | 20 | PKG_CHECK_MODULES(libzip, libzip >= 0.8) |
| 37 | 21 | ||
diff --git a/src/ideviceinstaller.c b/src/ideviceinstaller.c index 642d547..77650b8 100644 --- a/src/ideviceinstaller.c +++ b/src/ideviceinstaller.c | |||
| @@ -81,69 +81,148 @@ enum cmd_mode { | |||
| 81 | int cmd = CMD_NONE; | 81 | int cmd = CMD_NONE; |
| 82 | 82 | ||
| 83 | char *last_status = NULL; | 83 | char *last_status = NULL; |
| 84 | int wait_for_op_complete = 0; | 84 | int wait_for_command_complete = 0; |
| 85 | int notification_expected = 0; | 85 | int notification_expected = 0; |
| 86 | int is_device_connected = 0; | 86 | int is_device_connected = 0; |
| 87 | int op_completed = 0; | 87 | int command_completed = 0; |
| 88 | int err_occurred = 0; | 88 | int err_occurred = 0; |
| 89 | int notified = 0; | 89 | int notified = 0; |
| 90 | 90 | ||
| 91 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | 91 | static void print_apps_header() |
| 92 | { | ||
| 93 | /* output app details header */ | ||
| 94 | printf("%s", "CFBundleIdentifier"); | ||
| 95 | printf(", %s", "CFBundleVersion"); | ||
| 96 | printf(", %s", "CFBundleDisplayName"); | ||
| 97 | printf("\n"); | ||
| 98 | } | ||
| 99 | |||
| 100 | static void print_apps(plist_t apps) | ||
| 101 | { | ||
| 102 | uint32_t i = 0; | ||
| 103 | for (i = 0; i < plist_array_get_size(apps); i++) { | ||
| 104 | plist_t app = plist_array_get_item(apps, i); | ||
| 105 | plist_t p_bundle_identifier = plist_dict_get_item(app, "CFBundleIdentifier"); | ||
| 106 | char *s_bundle_identifier = NULL; | ||
| 107 | char *s_display_name = NULL; | ||
| 108 | char *s_version = NULL; | ||
| 109 | plist_t display_name = plist_dict_get_item(app, "CFBundleDisplayName"); | ||
| 110 | plist_t version = plist_dict_get_item(app, "CFBundleVersion"); | ||
| 111 | |||
| 112 | if (p_bundle_identifier) { | ||
| 113 | plist_get_string_val(p_bundle_identifier, &s_bundle_identifier); | ||
| 114 | } | ||
| 115 | if (!s_bundle_identifier) { | ||
| 116 | fprintf(stderr, "ERROR: Failed to get APPID!\n"); | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (version) { | ||
| 121 | plist_get_string_val(version, &s_version); | ||
| 122 | } | ||
| 123 | if (display_name) { | ||
| 124 | plist_get_string_val(display_name, &s_display_name); | ||
| 125 | } | ||
| 126 | if (!s_display_name) { | ||
| 127 | s_display_name = strdup(s_bundle_identifier); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* output app details */ | ||
| 131 | printf("%s", s_bundle_identifier); | ||
| 132 | if (s_version) { | ||
| 133 | printf(", \"%s\"", s_version); | ||
| 134 | free(s_version); | ||
| 135 | } | ||
| 136 | printf(", \"%s\"", s_display_name); | ||
| 137 | printf("\n"); | ||
| 138 | free(s_display_name); | ||
| 139 | free(s_bundle_identifier); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 92 | static void notifier(const char *notification, void *unused) | 143 | static void notifier(const char *notification, void *unused) |
| 93 | #else | ||
| 94 | static void notifier(const char *notification) | ||
| 95 | #endif | ||
| 96 | { | 144 | { |
| 97 | notified = 1; | 145 | notified = 1; |
| 98 | } | 146 | } |
| 99 | 147 | ||
| 100 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | 148 | static void status_cb(plist_t command, plist_t status, void *unused) |
| 101 | static void status_cb(const char *operation, plist_t status, void *unused) | ||
| 102 | #else | ||
| 103 | static void status_cb(const char *operation, plist_t status) | ||
| 104 | #endif | ||
| 105 | { | 149 | { |
| 106 | if (status && operation) { | 150 | if (command && status) { |
| 107 | plist_t npercent = plist_dict_get_item(status, "PercentComplete"); | 151 | char* command_name = NULL; |
| 108 | plist_t nstatus = plist_dict_get_item(status, "Status"); | 152 | instproxy_command_get_name(command, &command_name); |
| 109 | plist_t nerror = plist_dict_get_item(status, "Error"); | 153 | |
| 110 | int percent = 0; | 154 | /* get status */ |
| 111 | char *status_msg = NULL; | 155 | char *status_name = NULL; |
| 112 | if (npercent) { | 156 | instproxy_status_get_name(status, &status_name); |
| 113 | uint64_t val = 0; | 157 | |
| 114 | plist_get_uint_val(npercent, &val); | 158 | if (status_name) { |
| 115 | percent = val; | 159 | if (!strcmp(status_name, "Complete")) { |
| 116 | } | 160 | command_completed = 1; |
| 117 | if (nstatus) { | ||
| 118 | plist_get_string_val(nstatus, &status_msg); | ||
| 119 | if (!strcmp(status_msg, "Complete")) { | ||
| 120 | op_completed = 1; | ||
| 121 | } | 161 | } |
| 122 | } | 162 | } |
| 123 | if (!nerror) { | ||
| 124 | if (last_status && (strcmp(last_status, status_msg))) { | ||
| 125 | printf("\r"); | ||
| 126 | } | ||
| 127 | 163 | ||
| 128 | if (!npercent) { | 164 | /* get error if any */ |
| 129 | printf("%s - %s\n", operation, status_msg); | 165 | char* error_name = NULL; |
| 166 | char* error_description = NULL; | ||
| 167 | uint64_t error_code = 0; | ||
| 168 | instproxy_status_get_error(status, &error_name, &error_description, &error_code); | ||
| 169 | |||
| 170 | /* output/handling */ | ||
| 171 | if (!error_name) { | ||
| 172 | if (!strcmp(command_name, "Browse")) { | ||
| 173 | uint64_t total = 0; | ||
| 174 | uint64_t current_index = 0; | ||
| 175 | uint64_t current_amount = 0; | ||
| 176 | plist_t current_list = NULL; | ||
| 177 | instproxy_status_get_current_list(status, &total, ¤t_index, ¤t_amount, ¤t_list); | ||
| 178 | if (current_list) { | ||
| 179 | print_apps(current_list); | ||
| 180 | plist_free(current_list); | ||
| 181 | } | ||
| 130 | } else { | 182 | } else { |
| 131 | printf("%s - %s (%d%%)\n", operation, status_msg, percent); | 183 | /* get progress if any */ |
| 184 | int percent = -1; | ||
| 185 | instproxy_status_get_percent_complete(status, &percent); | ||
| 186 | |||
| 187 | if (last_status && (strcmp(last_status, status_name))) { | ||
| 188 | printf("\r"); | ||
| 189 | } | ||
| 190 | |||
| 191 | if (percent >= 0) { | ||
| 192 | printf("%s: %s (%d%%)\n", command_name, status_name, percent); | ||
| 193 | } else { | ||
| 194 | printf("%s: %s\n", command_name, status_name); | ||
| 195 | } | ||
| 132 | } | 196 | } |
| 133 | } else { | 197 | } else { |
| 134 | char *err_msg = NULL; | 198 | /* report error to the user */ |
| 135 | plist_get_string_val(nerror, &err_msg); | 199 | if (error_description) |
| 136 | printf("%s - Error occurred: %s\n", operation, err_msg); | 200 | fprintf(stderr, "ERROR: %s failed. Got error \"%s\" with code 0x%08"PRIx64": %s\n", command_name, error_name, error_code, error_description ? error_description: "N/A"); |
| 137 | free(err_msg); | 201 | else |
| 202 | fprintf(stderr, "ERROR: %s failed. Got error \"%s\".\n", command_name, error_name); | ||
| 138 | err_occurred = 1; | 203 | err_occurred = 1; |
| 139 | } | 204 | } |
| 205 | |||
| 206 | /* clean up */ | ||
| 207 | if (error_name) | ||
| 208 | free(error_name); | ||
| 209 | |||
| 210 | if (error_description) | ||
| 211 | free(error_description); | ||
| 212 | |||
| 140 | if (last_status) { | 213 | if (last_status) { |
| 141 | free(last_status); | 214 | free(last_status); |
| 142 | last_status = NULL; | 215 | last_status = NULL; |
| 143 | } | 216 | } |
| 144 | if (status_msg) { | 217 | |
| 145 | last_status = strdup(status_msg); | 218 | if (status_name) { |
| 146 | free(status_msg); | 219 | last_status = strdup(status_name); |
| 220 | free(status_name); | ||
| 221 | } | ||
| 222 | |||
| 223 | if (command_name) { | ||
| 224 | free(command_name); | ||
| 225 | command_name = NULL; | ||
| 147 | } | 226 | } |
| 148 | } else { | 227 | } else { |
| 149 | fprintf(stderr, "ERROR: %s was called with invalid arguments!\n", __func__); | 228 | fprintf(stderr, "ERROR: %s was called with invalid arguments!\n", __func__); |
| @@ -250,7 +329,7 @@ static void idevice_event_callback(const idevice_event_t* event, void* userdata) | |||
| 250 | } | 329 | } |
| 251 | } | 330 | } |
| 252 | 331 | ||
| 253 | static void idevice_wait_for_operation_to_complete() | 332 | static void idevice_wait_for_command_to_complete() |
| 254 | { | 333 | { |
| 255 | struct timespec ts; | 334 | struct timespec ts; |
| 256 | ts.tv_sec = 0; | 335 | ts.tv_sec = 0; |
| @@ -260,8 +339,8 @@ static void idevice_wait_for_operation_to_complete() | |||
| 260 | /* subscribe to make sure to exit on device removal */ | 339 | /* subscribe to make sure to exit on device removal */ |
| 261 | idevice_event_subscribe(idevice_event_callback, NULL); | 340 | idevice_event_subscribe(idevice_event_callback, NULL); |
| 262 | 341 | ||
| 263 | /* wait for operation to complete */ | 342 | /* wait for command to complete */ |
| 264 | while (wait_for_op_complete && !op_completed && !err_occurred | 343 | while (wait_for_command_complete && !command_completed && !err_occurred |
| 265 | && !notified && is_device_connected) { | 344 | && !notified && is_device_connected) { |
| 266 | nanosleep(&ts, NULL); | 345 | nanosleep(&ts, NULL); |
| 267 | } | 346 | } |
| @@ -453,7 +532,7 @@ static void parse_opts(int argc, char **argv) | |||
| 453 | } | 532 | } |
| 454 | 533 | ||
| 455 | if (cmd == CMD_NONE) { | 534 | if (cmd == CMD_NONE) { |
| 456 | printf("ERROR: No mode/operation was supplied.\n"); | 535 | printf("ERROR: No mode/command was supplied.\n"); |
| 457 | } | 536 | } |
| 458 | 537 | ||
| 459 | if (cmd == CMD_NONE || optind <= 1 || (argc - optind > 0)) { | 538 | if (cmd == CMD_NONE || optind <= 1 || (argc - optind > 0)) { |
| @@ -565,11 +644,7 @@ int main(int argc, char **argv) | |||
| 565 | instproxy_error_t err; | 644 | instproxy_error_t err; |
| 566 | np_client_t np = NULL; | 645 | np_client_t np = NULL; |
| 567 | afc_client_t afc = NULL; | 646 | afc_client_t afc = NULL; |
| 568 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | ||
| 569 | lockdownd_service_descriptor_t service = NULL; | 647 | lockdownd_service_descriptor_t service = NULL; |
| 570 | #else | ||
| 571 | uint16_t service = 0; | ||
| 572 | #endif | ||
| 573 | int res = 0; | 648 | int res = 0; |
| 574 | char *bundleidentifier = NULL; | 649 | char *bundleidentifier = NULL; |
| 575 | 650 | ||
| @@ -597,38 +672,29 @@ int main(int argc, char **argv) | |||
| 597 | } | 672 | } |
| 598 | 673 | ||
| 599 | np_error_t nperr = np_client_new(phone, service, &np); | 674 | np_error_t nperr = np_client_new(phone, service, &np); |
| 600 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | 675 | |
| 601 | if (service) { | 676 | if (service) { |
| 602 | lockdownd_service_descriptor_free(service); | 677 | lockdownd_service_descriptor_free(service); |
| 603 | } | 678 | } |
| 604 | service = NULL; | 679 | service = NULL; |
| 605 | #else | 680 | |
| 606 | service = 0; | ||
| 607 | #endif | ||
| 608 | if (nperr != NP_E_SUCCESS) { | 681 | if (nperr != NP_E_SUCCESS) { |
| 609 | fprintf(stderr, "Could not connect to notification_proxy!\n"); | 682 | fprintf(stderr, "Could not connect to notification_proxy!\n"); |
| 610 | goto leave_cleanup; | 683 | goto leave_cleanup; |
| 611 | } | 684 | } |
| 612 | 685 | ||
| 613 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 614 | np_set_notify_callback(np, notifier, NULL); | 686 | np_set_notify_callback(np, notifier, NULL); |
| 615 | #else | ||
| 616 | np_set_notify_callback(np, notifier); | ||
| 617 | #endif | ||
| 618 | 687 | ||
| 619 | const char *noties[3] = { NP_APP_INSTALLED, NP_APP_UNINSTALLED, NULL }; | 688 | const char *noties[3] = { NP_APP_INSTALLED, NP_APP_UNINSTALLED, NULL }; |
| 620 | 689 | ||
| 621 | np_observe_notifications(np, noties); | 690 | np_observe_notifications(np, noties); |
| 622 | 691 | ||
| 623 | run_again: | 692 | run_again: |
| 624 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | ||
| 625 | if (service) { | 693 | if (service) { |
| 626 | lockdownd_service_descriptor_free(service); | 694 | lockdownd_service_descriptor_free(service); |
| 627 | } | 695 | } |
| 628 | service = NULL; | 696 | service = NULL; |
| 629 | #else | 697 | |
| 630 | service = 0; | ||
| 631 | #endif | ||
| 632 | if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", | 698 | if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", |
| 633 | &service) != LOCKDOWN_E_SUCCESS) || !service) { | 699 | &service) != LOCKDOWN_E_SUCCESS) || !service) { |
| 634 | fprintf(stderr, | 700 | fprintf(stderr, |
| @@ -637,14 +703,12 @@ run_again: | |||
| 637 | } | 703 | } |
| 638 | 704 | ||
| 639 | err = instproxy_client_new(phone, service, &ipc); | 705 | err = instproxy_client_new(phone, service, &ipc); |
| 640 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | 706 | |
| 641 | if (service) { | 707 | if (service) { |
| 642 | lockdownd_service_descriptor_free(service); | 708 | lockdownd_service_descriptor_free(service); |
| 643 | } | 709 | } |
| 644 | service = NULL; | 710 | service = NULL; |
| 645 | #else | 711 | |
| 646 | service = 0; | ||
| 647 | #endif | ||
| 648 | if (err != INSTPROXY_E_SUCCESS) { | 712 | if (err != INSTPROXY_E_SUCCESS) { |
| 649 | fprintf(stderr, "Could not connect to installation_proxy!\n"); | 713 | fprintf(stderr, "Could not connect to installation_proxy!\n"); |
| 650 | goto leave_cleanup; | 714 | goto leave_cleanup; |
| @@ -670,13 +734,9 @@ run_again: | |||
| 670 | char *elem = strtok(opts, ","); | 734 | char *elem = strtok(opts, ","); |
| 671 | while (elem) { | 735 | while (elem) { |
| 672 | if (!strcmp(elem, "list_system")) { | 736 | if (!strcmp(elem, "list_system")) { |
| 673 | if (!client_opts) { | ||
| 674 | client_opts = instproxy_client_options_new(); | ||
| 675 | } | ||
| 676 | instproxy_client_options_add(client_opts, "ApplicationType", "System", NULL); | 737 | instproxy_client_options_add(client_opts, "ApplicationType", "System", NULL); |
| 677 | } else if (!strcmp(elem, "list_all")) { | 738 | } else if (!strcmp(elem, "list_all")) { |
| 678 | instproxy_client_options_free(client_opts); | 739 | plist_dict_remove_item(client_opts, "ApplicationType"); |
| 679 | client_opts = NULL; | ||
| 680 | } else if (!strcmp(elem, "list_user")) { | 740 | } else if (!strcmp(elem, "list_user")) { |
| 681 | /* do nothing, we're already set */ | 741 | /* do nothing, we're already set */ |
| 682 | } else if (!strcmp(elem, "xml")) { | 742 | } else if (!strcmp(elem, "xml")) { |
| @@ -687,18 +747,26 @@ run_again: | |||
| 687 | free(opts); | 747 | free(opts); |
| 688 | } | 748 | } |
| 689 | 749 | ||
| 690 | err = instproxy_browse(ipc, client_opts, &apps); | 750 | if (!xml_mode) { |
| 691 | instproxy_client_options_free(client_opts); | 751 | instproxy_client_options_set_return_attributes(client_opts, |
| 692 | if (err != INSTPROXY_E_SUCCESS) { | 752 | "CFBundleIdentifier", |
| 693 | fprintf(stderr, "ERROR: instproxy_browse returned %d\n", err); | 753 | "CFBundleDisplayName", |
| 694 | goto leave_cleanup; | 754 | "CFBundleVersion", |
| 695 | } | 755 | "StaticDiskUsage", |
| 696 | if (!apps || (plist_get_node_type(apps) != PLIST_ARRAY)) { | 756 | "DynamicDiskUsage", |
| 697 | fprintf(stderr, | 757 | NULL |
| 698 | "ERROR: instproxy_browse returnd an invalid plist!\n"); | 758 | ); |
| 699 | goto leave_cleanup; | ||
| 700 | } | 759 | } |
| 760 | |||
| 701 | if (xml_mode) { | 761 | if (xml_mode) { |
| 762 | err = instproxy_browse(ipc, client_opts, &apps); | ||
| 763 | |||
| 764 | if (!apps || (plist_get_node_type(apps) != PLIST_ARRAY)) { | ||
| 765 | fprintf(stderr, | ||
| 766 | "ERROR: instproxy_browse returnd an invalid plist!\n"); | ||
| 767 | goto leave_cleanup; | ||
| 768 | } | ||
| 769 | |||
| 702 | char *xml = NULL; | 770 | char *xml = NULL; |
| 703 | uint32_t len = 0; | 771 | uint32_t len = 0; |
| 704 | 772 | ||
| @@ -710,47 +778,22 @@ run_again: | |||
| 710 | plist_free(apps); | 778 | plist_free(apps); |
| 711 | goto leave_cleanup; | 779 | goto leave_cleanup; |
| 712 | } | 780 | } |
| 713 | printf("Total: %d apps\n", plist_array_get_size(apps)); | ||
| 714 | uint32_t i = 0; | ||
| 715 | for (i = 0; i < plist_array_get_size(apps); i++) { | ||
| 716 | plist_t app = plist_array_get_item(apps, i); | ||
| 717 | plist_t p_appid = | ||
| 718 | plist_dict_get_item(app, "CFBundleIdentifier"); | ||
| 719 | char *s_appid = NULL; | ||
| 720 | char *s_dispName = NULL; | ||
| 721 | char *s_version = NULL; | ||
| 722 | plist_t dispName = | ||
| 723 | plist_dict_get_item(app, "CFBundleDisplayName"); | ||
| 724 | plist_t version = plist_dict_get_item(app, "CFBundleVersion"); | ||
| 725 | |||
| 726 | if (p_appid) { | ||
| 727 | plist_get_string_val(p_appid, &s_appid); | ||
| 728 | } | ||
| 729 | if (!s_appid) { | ||
| 730 | fprintf(stderr, "ERROR: Failed to get APPID!\n"); | ||
| 731 | break; | ||
| 732 | } | ||
| 733 | 781 | ||
| 734 | if (dispName) { | 782 | print_apps_header(); |
| 735 | plist_get_string_val(dispName, &s_dispName); | ||
| 736 | } | ||
| 737 | if (version) { | ||
| 738 | plist_get_string_val(version, &s_version); | ||
| 739 | } | ||
| 740 | 783 | ||
| 741 | if (!s_dispName) { | 784 | err = instproxy_browse_with_callback(ipc, client_opts, status_cb, NULL); |
| 742 | s_dispName = strdup(s_appid); | 785 | if (err == INSTPROXY_E_RECEIVE_TIMEOUT) { |
| 743 | } | 786 | fprintf(stderr, "NOTE: timeout waiting for device to browse apps, trying again...\n"); |
| 744 | if (s_version) { | 787 | } |
| 745 | printf("%s - %s %s\n", s_appid, s_dispName, s_version); | 788 | |
| 746 | free(s_version); | 789 | instproxy_client_options_free(client_opts); |
| 747 | } else { | 790 | if (err != INSTPROXY_E_SUCCESS) { |
| 748 | printf("%s - %s\n", s_appid, s_dispName); | 791 | fprintf(stderr, "ERROR: instproxy_browse returned %d\n", err); |
| 749 | } | 792 | goto leave_cleanup; |
| 750 | free(s_dispName); | ||
| 751 | free(s_appid); | ||
| 752 | } | 793 | } |
| 753 | plist_free(apps); | 794 | |
| 795 | wait_for_command_complete = 1; | ||
| 796 | notification_expected = 0; | ||
| 754 | } else if (cmd == CMD_INSTALL || cmd == CMD_UPGRADE) { | 797 | } else if (cmd == CMD_INSTALL || cmd == CMD_UPGRADE) { |
| 755 | plist_t sinf = NULL; | 798 | plist_t sinf = NULL; |
| 756 | plist_t meta = NULL; | 799 | plist_t meta = NULL; |
| @@ -759,14 +802,11 @@ run_again: | |||
| 759 | uint64_t af = 0; | 802 | uint64_t af = 0; |
| 760 | char buf[8192]; | 803 | char buf[8192]; |
| 761 | 804 | ||
| 762 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | ||
| 763 | if (service) { | 805 | if (service) { |
| 764 | lockdownd_service_descriptor_free(service); | 806 | lockdownd_service_descriptor_free(service); |
| 765 | } | 807 | } |
| 766 | service = NULL; | 808 | service = NULL; |
| 767 | #else | 809 | |
| 768 | service = 0; | ||
| 769 | #endif | ||
| 770 | if ((lockdownd_start_service(client, "com.apple.afc", &service) != | 810 | if ((lockdownd_start_service(client, "com.apple.afc", &service) != |
| 771 | LOCKDOWN_E_SUCCESS) || !service) { | 811 | LOCKDOWN_E_SUCCESS) || !service) { |
| 772 | fprintf(stderr, "Could not start com.apple.afc!\n"); | 812 | fprintf(stderr, "Could not start com.apple.afc!\n"); |
| @@ -1053,36 +1093,23 @@ run_again: | |||
| 1053 | /* perform installation or upgrade */ | 1093 | /* perform installation or upgrade */ |
| 1054 | if (cmd == CMD_INSTALL) { | 1094 | if (cmd == CMD_INSTALL) { |
| 1055 | printf("Installing '%s'\n", bundleidentifier); | 1095 | printf("Installing '%s'\n", bundleidentifier); |
| 1056 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1057 | instproxy_install(ipc, pkgname, client_opts, status_cb, NULL); | 1096 | instproxy_install(ipc, pkgname, client_opts, status_cb, NULL); |
| 1058 | #else | ||
| 1059 | instproxy_install(ipc, pkgname, client_opts, status_cb); | ||
| 1060 | #endif | ||
| 1061 | } else { | 1097 | } else { |
| 1062 | printf("Upgrading '%s'\n", bundleidentifier); | 1098 | printf("Upgrading '%s'\n", bundleidentifier); |
| 1063 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1064 | instproxy_upgrade(ipc, pkgname, client_opts, status_cb, NULL); | 1099 | instproxy_upgrade(ipc, pkgname, client_opts, status_cb, NULL); |
| 1065 | #else | ||
| 1066 | instproxy_upgrade(ipc, pkgname, client_opts, status_cb); | ||
| 1067 | #endif | ||
| 1068 | } | 1100 | } |
| 1069 | instproxy_client_options_free(client_opts); | 1101 | instproxy_client_options_free(client_opts); |
| 1070 | free(pkgname); | 1102 | free(pkgname); |
| 1071 | wait_for_op_complete = 1; | 1103 | wait_for_command_complete = 1; |
| 1072 | notification_expected = 1; | 1104 | notification_expected = 1; |
| 1073 | } else if (cmd == CMD_UNINSTALL) { | 1105 | } else if (cmd == CMD_UNINSTALL) { |
| 1074 | printf("Uninstalling '%s'\n", appid); | 1106 | printf("Uninstalling '%s'\n", appid); |
| 1075 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1076 | instproxy_uninstall(ipc, appid, NULL, status_cb, NULL); | 1107 | instproxy_uninstall(ipc, appid, NULL, status_cb, NULL); |
| 1077 | #else | 1108 | wait_for_command_complete = 1; |
| 1078 | instproxy_uninstall(ipc, appid, NULL, status_cb); | ||
| 1079 | #endif | ||
| 1080 | wait_for_op_complete = 1; | ||
| 1081 | notification_expected = 0; | 1109 | notification_expected = 0; |
| 1082 | } else if (cmd == CMD_LIST_ARCHIVES) { | 1110 | } else if (cmd == CMD_LIST_ARCHIVES) { |
| 1083 | int xml_mode = 0; | 1111 | int xml_mode = 0; |
| 1084 | plist_t dict = NULL; | 1112 | plist_t dict = NULL; |
| 1085 | plist_t lres = NULL; | ||
| 1086 | 1113 | ||
| 1087 | /* look for options */ | 1114 | /* look for options */ |
| 1088 | if (options) { | 1115 | if (options) { |
| @@ -1101,24 +1128,18 @@ run_again: | |||
| 1101 | fprintf(stderr, "ERROR: lookup_archives returned %d\n", err); | 1128 | fprintf(stderr, "ERROR: lookup_archives returned %d\n", err); |
| 1102 | goto leave_cleanup; | 1129 | goto leave_cleanup; |
| 1103 | } | 1130 | } |
| 1131 | |||
| 1104 | if (!dict) { | 1132 | if (!dict) { |
| 1105 | fprintf(stderr, | 1133 | fprintf(stderr, |
| 1106 | "ERROR: lookup_archives did not return a plist!?\n"); | 1134 | "ERROR: lookup_archives did not return a plist!?\n"); |
| 1107 | goto leave_cleanup; | 1135 | goto leave_cleanup; |
| 1108 | } | 1136 | } |
| 1109 | 1137 | ||
| 1110 | lres = plist_dict_get_item(dict, "LookupResult"); | ||
| 1111 | if (!lres || (plist_get_node_type(lres) != PLIST_DICT)) { | ||
| 1112 | plist_free(dict); | ||
| 1113 | fprintf(stderr, "ERROR: Could not get dict 'LookupResult'\n"); | ||
| 1114 | goto leave_cleanup; | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | if (xml_mode) { | 1138 | if (xml_mode) { |
| 1118 | char *xml = NULL; | 1139 | char *xml = NULL; |
| 1119 | uint32_t len = 0; | 1140 | uint32_t len = 0; |
| 1120 | 1141 | ||
| 1121 | plist_to_xml(lres, &xml, &len); | 1142 | plist_to_xml(dict, &xml, &len); |
| 1122 | if (xml) { | 1143 | if (xml) { |
| 1123 | puts(xml); | 1144 | puts(xml); |
| 1124 | free(xml); | 1145 | free(xml); |
| @@ -1130,8 +1151,8 @@ run_again: | |||
| 1130 | plist_t node = NULL; | 1151 | plist_t node = NULL; |
| 1131 | char *key = NULL; | 1152 | char *key = NULL; |
| 1132 | 1153 | ||
| 1133 | printf("Total: %d archived apps\n", plist_dict_get_size(lres)); | 1154 | printf("Total: %d archived apps\n", plist_dict_get_size(dict)); |
| 1134 | plist_dict_new_iter(lres, &iter); | 1155 | plist_dict_new_iter(dict, &iter); |
| 1135 | if (!iter) { | 1156 | if (!iter) { |
| 1136 | plist_free(dict); | 1157 | plist_free(dict); |
| 1137 | fprintf(stderr, "ERROR: Could not create plist_dict_iter!\n"); | 1158 | fprintf(stderr, "ERROR: Could not create plist_dict_iter!\n"); |
| @@ -1140,7 +1161,7 @@ run_again: | |||
| 1140 | do { | 1161 | do { |
| 1141 | key = NULL; | 1162 | key = NULL; |
| 1142 | node = NULL; | 1163 | node = NULL; |
| 1143 | plist_dict_next_item(lres, iter, &key, &node); | 1164 | plist_dict_next_item(dict, iter, &key, &node); |
| 1144 | if (key && (plist_get_node_type(node) == PLIST_DICT)) { | 1165 | if (key && (plist_get_node_type(node) == PLIST_DICT)) { |
| 1145 | char *s_dispName = NULL; | 1166 | char *s_dispName = NULL; |
| 1146 | char *s_version = NULL; | 1167 | char *s_version = NULL; |
| @@ -1225,14 +1246,11 @@ run_again: | |||
| 1225 | goto leave_cleanup; | 1246 | goto leave_cleanup; |
| 1226 | } | 1247 | } |
| 1227 | 1248 | ||
| 1228 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1_5 | ||
| 1229 | if (service) { | 1249 | if (service) { |
| 1230 | lockdownd_service_descriptor_free(service); | 1250 | lockdownd_service_descriptor_free(service); |
| 1231 | } | 1251 | } |
| 1232 | service = NULL; | 1252 | service = NULL; |
| 1233 | #else | 1253 | |
| 1234 | service = 0; | ||
| 1235 | #endif | ||
| 1236 | if ((lockdownd_start_service(client, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || !service) { | 1254 | if ((lockdownd_start_service(client, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || !service) { |
| 1237 | fprintf(stderr, "Could not start com.apple.afc!\n"); | 1255 | fprintf(stderr, "Could not start com.apple.afc!\n"); |
| 1238 | free(copy_path); | 1256 | free(copy_path); |
| @@ -1248,20 +1266,17 @@ run_again: | |||
| 1248 | } | 1266 | } |
| 1249 | } | 1267 | } |
| 1250 | 1268 | ||
| 1251 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1252 | instproxy_archive(ipc, appid, client_opts, status_cb, NULL); | 1269 | instproxy_archive(ipc, appid, client_opts, status_cb, NULL); |
| 1253 | #else | 1270 | |
| 1254 | instproxy_archive(ipc, appid, client_opts, status_cb); | ||
| 1255 | #endif | ||
| 1256 | instproxy_client_options_free(client_opts); | 1271 | instproxy_client_options_free(client_opts); |
| 1257 | wait_for_op_complete = 1; | 1272 | wait_for_command_complete = 1; |
| 1258 | if (skip_uninstall) { | 1273 | if (skip_uninstall) { |
| 1259 | notification_expected = 0; | 1274 | notification_expected = 0; |
| 1260 | } else { | 1275 | } else { |
| 1261 | notification_expected = 1; | 1276 | notification_expected = 1; |
| 1262 | } | 1277 | } |
| 1263 | 1278 | ||
| 1264 | idevice_wait_for_operation_to_complete(); | 1279 | idevice_wait_for_command_to_complete(); |
| 1265 | 1280 | ||
| 1266 | if (copy_path) { | 1281 | if (copy_path) { |
| 1267 | if (err_occurred) { | 1282 | if (err_occurred) { |
| @@ -1386,23 +1401,15 @@ run_again: | |||
| 1386 | } | 1401 | } |
| 1387 | goto leave_cleanup; | 1402 | goto leave_cleanup; |
| 1388 | } else if (cmd == CMD_RESTORE) { | 1403 | } else if (cmd == CMD_RESTORE) { |
| 1389 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1390 | instproxy_restore(ipc, appid, NULL, status_cb, NULL); | 1404 | instproxy_restore(ipc, appid, NULL, status_cb, NULL); |
| 1391 | #else | 1405 | wait_for_command_complete = 1; |
| 1392 | instproxy_restore(ipc, appid, NULL, status_cb); | ||
| 1393 | #endif | ||
| 1394 | wait_for_op_complete = 1; | ||
| 1395 | notification_expected = 1; | 1406 | notification_expected = 1; |
| 1396 | } else if (cmd == CMD_REMOVE_ARCHIVE) { | 1407 | } else if (cmd == CMD_REMOVE_ARCHIVE) { |
| 1397 | #ifdef HAVE_LIBIMOBILEDEVICE_1_1 | ||
| 1398 | instproxy_remove_archive(ipc, appid, NULL, status_cb, NULL); | 1408 | instproxy_remove_archive(ipc, appid, NULL, status_cb, NULL); |
| 1399 | #else | 1409 | wait_for_command_complete = 1; |
| 1400 | instproxy_remove_archive(ipc, appid, NULL, status_cb); | ||
| 1401 | #endif | ||
| 1402 | wait_for_op_complete = 1; | ||
| 1403 | } else { | 1410 | } else { |
| 1404 | printf | 1411 | printf |
| 1405 | ("ERROR: no operation selected?! This should not be reached!\n"); | 1412 | ("ERROR: no command selected?! This should not be reached!\n"); |
| 1406 | res = -2; | 1413 | res = -2; |
| 1407 | goto leave_cleanup; | 1414 | goto leave_cleanup; |
| 1408 | } | 1415 | } |
| @@ -1413,7 +1420,7 @@ run_again: | |||
| 1413 | client = NULL; | 1420 | client = NULL; |
| 1414 | } | 1421 | } |
| 1415 | 1422 | ||
| 1416 | idevice_wait_for_operation_to_complete(); | 1423 | idevice_wait_for_command_to_complete(); |
| 1417 | 1424 | ||
| 1418 | leave_cleanup: | 1425 | leave_cleanup: |
| 1419 | if (bundleidentifier) { | 1426 | if (bundleidentifier) { |
