diff options
| -rw-r--r-- | src/InstallationProxy.c | 138 |
1 files changed, 27 insertions, 111 deletions
diff --git a/src/InstallationProxy.c b/src/InstallationProxy.c index 917886d..387f9ca 100644 --- a/src/InstallationProxy.c +++ b/src/InstallationProxy.c | |||
| @@ -56,112 +56,28 @@ static void instproxy_unlock(instproxy_client_t client) | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | * Sends an xml plist to the device using the connection specified in client. | 59 | * Convert an iphone_error_t value to an instproxy_error_t value. |
| 60 | * This function is only used internally. | 60 | * Used internally to get correct error codes when using plist helper |
| 61 | * functions. | ||
| 61 | * | 62 | * |
| 62 | * @param client The installation_proxy to send data to | 63 | * @param err An iphone_error_t error code |
| 63 | * @param plist plist to send | ||
| 64 | * | 64 | * |
| 65 | * @return INSTPROXY_E_SUCCESS on success, INSTPROXY_E_INVALID_ARG when client | 65 | * @return A matching instproxy_error_t error code, |
| 66 | * or plist are NULL, INSTPROXY_E_PLIST_ERROR when dict is not a valid | 66 | * INSTPROXY_E_UNKNOWN_ERROR otherwise. |
| 67 | * plist, or INSTPROXY_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
| 68 | */ | 67 | */ |
| 69 | static instproxy_error_t instproxy_plist_send(instproxy_client_t client, plist_t plist) | 68 | static instproxy_error_t iphone_to_instproxy_error(iphone_error_t err) |
| 70 | { | 69 | { |
| 71 | instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; | 70 | switch (err) { |
| 72 | char *XML_content = NULL; | 71 | case IPHONE_E_SUCCESS: |
| 73 | uint32_t length = 0; | 72 | return INSTPROXY_E_SUCCESS; |
| 74 | uint32_t nlen = 0; | 73 | case IPHONE_E_INVALID_ARG: |
| 75 | int bytes = 0; | 74 | return INSTPROXY_E_INVALID_ARG; |
| 76 | 75 | case IPHONE_E_PLIST_ERROR: | |
| 77 | if (!client || !plist) { | 76 | return INSTPROXY_E_PLIST_ERROR; |
| 78 | return INSTPROXY_E_INVALID_ARG; | 77 | default: |
| 79 | } | 78 | break; |
| 80 | |||
| 81 | plist_to_xml(plist, &XML_content, &length); | ||
| 82 | |||
| 83 | if (!XML_content || length == 0) { | ||
| 84 | return INSTPROXY_E_PLIST_ERROR; | ||
| 85 | } | ||
| 86 | |||
| 87 | nlen = htonl(length); | ||
| 88 | log_debug_msg("%s: sending %d bytes\n", __func__, length); | ||
| 89 | iphone_device_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); | ||
| 90 | if (bytes == sizeof(nlen)) { | ||
| 91 | iphone_device_send(client->connection, XML_content, length, (uint32_t*)&bytes); | ||
| 92 | if (bytes > 0) { | ||
| 93 | log_debug_msg("%s: received %d bytes\n", __func__, bytes); | ||
| 94 | log_debug_buffer(XML_content, bytes); | ||
| 95 | if ((uint32_t)bytes == length) { | ||
| 96 | res = INSTPROXY_E_SUCCESS; | ||
| 97 | } else { | ||
| 98 | log_debug_msg("%s: ERROR: Could not send all data (%d of %d)!\n", __func__, bytes, length); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | if (bytes <= 0) { | ||
| 103 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: ERROR: sending to device failed.\n", __func__); | ||
| 104 | } | ||
| 105 | |||
| 106 | free(XML_content); | ||
| 107 | |||
| 108 | return res; | ||
| 109 | } | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Receives an xml plist from the device using the connection specified in | ||
| 113 | * client. | ||
| 114 | * This function is only used internally. | ||
| 115 | * | ||
| 116 | * @param client The installation_proxy to receive data from | ||
| 117 | * @param plist pointer to a plist_t that will point to the received plist | ||
| 118 | * upon successful return | ||
| 119 | * | ||
| 120 | * @return INSTPROXY_E_SUCCESS on success, INSTPROXY_E_INVALID_ARG when client | ||
| 121 | * or *plist are NULL, INSTPROXY_E_PLIST_ERROR when dict is not a valid | ||
| 122 | * plist, or INSTPROXY_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
| 123 | */ | ||
| 124 | static instproxy_error_t instproxy_plist_recv(instproxy_client_t client, plist_t *plist) | ||
| 125 | { | ||
| 126 | instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; | ||
| 127 | char *XML_content = NULL; | ||
| 128 | uint32_t pktlen = 0; | ||
| 129 | uint32_t bytes = 0; | ||
| 130 | |||
| 131 | if (!client || !plist) { | ||
| 132 | return INSTPROXY_E_INVALID_ARG; | ||
| 133 | } | ||
| 134 | |||
| 135 | iphone_device_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, 300000); /* 5 minute timeout should be enough */ | ||
| 136 | log_debug_msg("%s: initial read=%i\n", __func__, bytes); | ||
| 137 | if (bytes < 4) { | ||
| 138 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: initial read failed!\n"); | ||
| 139 | } else { | ||
| 140 | if ((char)pktlen == 0) { | ||
| 141 | uint32_t curlen = 0; | ||
| 142 | pktlen = ntohl(pktlen); | ||
| 143 | log_debug_msg("%s: %d bytes following\n", __func__, pktlen); | ||
| 144 | XML_content = (char*)malloc(pktlen); | ||
| 145 | |||
| 146 | while (curlen < pktlen) { | ||
| 147 | iphone_device_recv(client->connection, XML_content+curlen, pktlen-curlen, &bytes); | ||
| 148 | if (bytes <= 0) { | ||
| 149 | res = INSTPROXY_E_UNKNOWN_ERROR; | ||
| 150 | break; | ||
| 151 | } | ||
| 152 | log_debug_msg("%s: received %d bytes\n", __func__, bytes); | ||
| 153 | curlen += bytes; | ||
| 154 | } | ||
| 155 | log_debug_buffer(XML_content, pktlen); | ||
| 156 | plist_from_xml(XML_content, pktlen, plist); | ||
| 157 | res = INSTPROXY_E_SUCCESS; | ||
| 158 | free(XML_content); | ||
| 159 | XML_content = NULL; | ||
| 160 | } else { | ||
| 161 | res = INSTPROXY_E_UNKNOWN_ERROR; | ||
| 162 | } | ||
| 163 | } | 79 | } |
| 164 | return res; | 80 | return INSTPROXY_E_UNKNOWN_ERROR; |
| 165 | } | 81 | } |
| 166 | 82 | ||
| 167 | /** | 83 | /** |
| @@ -268,7 +184,7 @@ instproxy_error_t instproxy_browse(instproxy_client_t client, instproxy_apptype_ | |||
| 268 | plist_dict_insert_item(dict, "Command", plist_new_string("Browse")); | 184 | plist_dict_insert_item(dict, "Command", plist_new_string("Browse")); |
| 269 | 185 | ||
| 270 | instproxy_lock(client); | 186 | instproxy_lock(client); |
| 271 | res = instproxy_plist_send(client, dict); | 187 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 272 | plist_free(dict); | 188 | plist_free(dict); |
| 273 | if (res != INSTPROXY_E_SUCCESS) { | 189 | if (res != INSTPROXY_E_SUCCESS) { |
| 274 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not send plist\n", __func__); | 190 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not send plist\n", __func__); |
| @@ -280,7 +196,7 @@ instproxy_error_t instproxy_browse(instproxy_client_t client, instproxy_apptype_ | |||
| 280 | do { | 196 | do { |
| 281 | browsing = 0; | 197 | browsing = 0; |
| 282 | dict = NULL; | 198 | dict = NULL; |
| 283 | res = instproxy_plist_recv(client, &dict); | 199 | res = iphone_to_instproxy_error(iphone_device_receive_plist(client->connection, &dict)); |
| 284 | if (res != INSTPROXY_E_SUCCESS) { | 200 | if (res != INSTPROXY_E_SUCCESS) { |
| 285 | break; | 201 | break; |
| 286 | } | 202 | } |
| @@ -345,7 +261,7 @@ static instproxy_error_t instproxy_perform_operation(instproxy_client_t client, | |||
| 345 | 261 | ||
| 346 | do { | 262 | do { |
| 347 | instproxy_lock(client); | 263 | instproxy_lock(client); |
| 348 | res = instproxy_plist_recv(client, &dict); | 264 | res = iphone_to_instproxy_error(iphone_device_receive_plist_with_timeout(client->connection, &dict, 30000)); |
| 349 | instproxy_unlock(client); | 265 | instproxy_unlock(client); |
| 350 | if (res != INSTPROXY_E_SUCCESS) { | 266 | if (res != INSTPROXY_E_SUCCESS) { |
| 351 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not receive plist, error %d\n", __func__, res); | 267 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not receive plist, error %d\n", __func__, res); |
| @@ -517,7 +433,7 @@ static instproxy_error_t instproxy_install_or_upgrade(instproxy_client_t client, | |||
| 517 | plist_dict_insert_item(dict, "PackagePath", plist_new_string(pkg_path)); | 433 | plist_dict_insert_item(dict, "PackagePath", plist_new_string(pkg_path)); |
| 518 | 434 | ||
| 519 | instproxy_lock(client); | 435 | instproxy_lock(client); |
| 520 | res = instproxy_plist_send(client, dict); | 436 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 521 | instproxy_unlock(client); | 437 | instproxy_unlock(client); |
| 522 | 438 | ||
| 523 | plist_free(dict); | 439 | plist_free(dict); |
| @@ -610,7 +526,7 @@ instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *app | |||
| 610 | plist_dict_insert_item(dict, "Command", plist_new_string("Uninstall")); | 526 | plist_dict_insert_item(dict, "Command", plist_new_string("Uninstall")); |
| 611 | 527 | ||
| 612 | instproxy_lock(client); | 528 | instproxy_lock(client); |
| 613 | res = instproxy_plist_send(client, dict); | 529 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 614 | instproxy_unlock(client); | 530 | instproxy_unlock(client); |
| 615 | 531 | ||
| 616 | plist_free(dict); | 532 | plist_free(dict); |
| @@ -647,7 +563,7 @@ instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t * | |||
| 647 | 563 | ||
| 648 | instproxy_lock(client); | 564 | instproxy_lock(client); |
| 649 | 565 | ||
| 650 | res = instproxy_plist_send(client, dict); | 566 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 651 | plist_free(dict); | 567 | plist_free(dict); |
| 652 | 568 | ||
| 653 | if (res != INSTPROXY_E_SUCCESS) { | 569 | if (res != INSTPROXY_E_SUCCESS) { |
| @@ -655,7 +571,7 @@ instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t * | |||
| 655 | goto leave_unlock; | 571 | goto leave_unlock; |
| 656 | } | 572 | } |
| 657 | 573 | ||
| 658 | res = instproxy_plist_recv(client, result); | 574 | res = iphone_to_instproxy_error(iphone_device_receive_plist(client->connection, result)); |
| 659 | if (res != INSTPROXY_E_SUCCESS) { | 575 | if (res != INSTPROXY_E_SUCCESS) { |
| 660 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not receive plist, error %d\n", __func__, res); | 576 | log_dbg_msg(DBGMASK_INSTPROXY, "%s: could not receive plist, error %d\n", __func__, res); |
| 661 | goto leave_unlock; | 577 | goto leave_unlock; |
| @@ -718,7 +634,7 @@ instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid | |||
| 718 | plist_dict_insert_item(dict, "Command", plist_new_string("Archive")); | 634 | plist_dict_insert_item(dict, "Command", plist_new_string("Archive")); |
| 719 | 635 | ||
| 720 | instproxy_lock(client); | 636 | instproxy_lock(client); |
| 721 | res = instproxy_plist_send(client, dict); | 637 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 722 | instproxy_unlock(client); | 638 | instproxy_unlock(client); |
| 723 | 639 | ||
| 724 | plist_free(dict); | 640 | plist_free(dict); |
| @@ -764,7 +680,7 @@ instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid | |||
| 764 | plist_dict_insert_item(dict, "Command", plist_new_string("Restore")); | 680 | plist_dict_insert_item(dict, "Command", plist_new_string("Restore")); |
| 765 | 681 | ||
| 766 | instproxy_lock(client); | 682 | instproxy_lock(client); |
| 767 | res = instproxy_plist_send(client, dict); | 683 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 768 | instproxy_unlock(client); | 684 | instproxy_unlock(client); |
| 769 | 685 | ||
| 770 | plist_free(dict); | 686 | plist_free(dict); |
| @@ -810,7 +726,7 @@ instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char | |||
| 810 | plist_dict_insert_item(dict, "Command", plist_new_string("RemoveArchive")); | 726 | plist_dict_insert_item(dict, "Command", plist_new_string("RemoveArchive")); |
| 811 | 727 | ||
| 812 | instproxy_lock(client); | 728 | instproxy_lock(client); |
| 813 | res = instproxy_plist_send(client, dict); | 729 | res = iphone_to_instproxy_error(iphone_device_send_xml_plist(client->connection, dict)); |
| 814 | instproxy_unlock(client); | 730 | instproxy_unlock(client); |
| 815 | 731 | ||
| 816 | plist_free(dict); | 732 | plist_free(dict); |
