diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asr.c | 56 | ||||
-rw-r--r-- | src/asr.h | 9 | ||||
-rw-r--r-- | src/common.h | 6 | ||||
-rw-r--r-- | src/idevicerestore.c | 195 | ||||
-rw-r--r-- | src/idevicerestore.h | 7 | ||||
-rw-r--r-- | src/ipsw.c | 269 | ||||
-rw-r--r-- | src/ipsw.h | 43 | ||||
-rw-r--r-- | src/restore.c | 35 | ||||
-rw-r--r-- | src/restore.h | 7 |
9 files changed, 272 insertions, 355 deletions
@@ -43,6 +43,7 @@ #include "asr.h" #include "idevicerestore.h" #include "common.h" +#include "ipsw.h" #define ASR_VERSION 1 #define ASR_STREAM_ID 1 @@ -205,9 +206,8 @@ void asr_free(asr_client_t asr) } } -int asr_perform_validation(asr_client_t asr, const char* filesystem) +int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) { - FILE* file = NULL; uint64_t length = 0; char* command = NULL; plist_t node = NULL; @@ -216,20 +216,9 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) plist_t payload_info = NULL; int attempts = 0; - file = fopen(filesystem, "rb"); - if (file == NULL) { - return -1; - } - -#ifdef WIN32 - length = _lseeki64(fileno(file), 0, SEEK_END); - _lseeki64(fileno(file), 0, SEEK_SET); - rewind(file); -#else - fseeko(file, 0, SEEK_END); - length = ftello(file); - fseeko(file, 0, SEEK_SET); -#endif + ipsw_file_seek(file, 0, SEEK_END); + length = ipsw_file_tell(file); + ipsw_file_seek(file, 0, SEEK_SET); payload_info = plist_new_dict(); plist_dict_set_item(payload_info, "Port", plist_new_uint(1)); @@ -296,7 +285,7 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) return 0; } -int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) +int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, ipsw_file_handle_t file) { char* oob_data = NULL; uint64_t oob_offset = 0; @@ -324,13 +313,8 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) return -1; } -#ifdef WIN32 - rewind(file); - _lseeki64(fileno(file), oob_offset, SEEK_SET); -#else - fseeko(file, oob_offset, SEEK_SET); -#endif - if (fread(oob_data, 1, oob_length, file) != oob_length) { + ipsw_file_seek(file, oob_offset, SEEK_SET); + if (ipsw_file_read(file, oob_data, oob_length) != oob_length) { error("ERROR: Unable to read OOB data from filesystem offset: %s\n", strerror(errno)); free(oob_data); return -1; @@ -345,28 +329,15 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) return 0; } -int asr_send_payload(asr_client_t asr, const char* filesystem) +int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file) { char *data = NULL; - FILE* file = NULL; uint64_t i, length, bytes = 0; double progress = 0; - file = fopen(filesystem, "rb"); - if (file == NULL) { - error("ERROR: Unable to open filesystem image %s: %s\n", filesystem, strerror(errno)); - return -1; - } - -#ifdef WIN32 - length = _lseeki64(fileno(file), 0, SEEK_END); - _lseeki64(fileno(file), 0, SEEK_SET); - rewind(file); -#else - fseeko(file, 0, SEEK_END); - length = ftello(file); - fseeko(file, 0, SEEK_SET); -#endif + ipsw_file_seek(file, 0, SEEK_END); + length = ipsw_file_tell(file); + ipsw_file_seek(file, 0, SEEK_SET); data = (char*)malloc(ASR_PAYLOAD_CHUNK_SIZE + 20); @@ -385,7 +356,7 @@ int asr_send_payload(asr_client_t asr, const char* filesystem) size = i; } - if (fread(data, 1, size, file) != (size_t)size) { + if (ipsw_file_read(file, data, size) != (int64_t)size) { error("Error reading filesystem\n"); retry--; continue; @@ -412,6 +383,5 @@ int asr_send_payload(asr_client_t asr, const char* filesystem) } free(data); - fclose(file); return 0; } @@ -41,15 +41,18 @@ struct asr_client { }; typedef struct asr_client *asr_client_t; +struct ipsw_file_handle; +typedef struct ipsw_file_handle* ipsw_file_handle_t; + int asr_open_with_timeout(idevice_t device, asr_client_t* asr); void asr_set_progress_callback(asr_client_t asr, asr_progress_cb_t, void* userdata); int asr_send(asr_client_t asr, plist_t data); int asr_receive(asr_client_t asr, plist_t* data); int asr_send_buffer(asr_client_t asr, const char* data, uint32_t size); void asr_free(asr_client_t asr); -int asr_perform_validation(asr_client_t asr, const char* filesystem); -int asr_send_payload(asr_client_t asr, const char* filesystem); -int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file); +int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file); +int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file); +int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, ipsw_file_handle_t file); #ifdef __cplusplus diff --git a/src/common.h b/src/common.h index 97d5f96..5afe5ab 100644 --- a/src/common.h +++ b/src/common.h @@ -70,6 +70,9 @@ struct dfu_client_t; struct normal_client_t; struct restore_client_t; struct recovery_client_t; +struct ipsw_archive; + +typedef struct ipsw_archive* ipsw_archive_t; struct idevicerestore_mode_t { int index; @@ -101,8 +104,7 @@ struct idevicerestore_client_t { plist_t preflight_info; char* udid; char* srnm; - char* ipsw; - const char* filesystem; + ipsw_archive_t ipsw; struct dfu_client_t* dfu; struct restore_client_t* restore; struct recovery_client_t* recovery; diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 466cfe2..7b69a9f 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -320,6 +320,8 @@ static void irecv_event_cb(const irecv_device_event_t* event, void *userdata) } } +int build_identity_check_components_in_ipsw(plist_t build_identity, ipsw_archive_t ipsw); + int idevicerestore_start(struct idevicerestore_client_t* client) { int tss_enabled = 0; @@ -424,7 +426,9 @@ int idevicerestore_start(struct idevicerestore_client_t* client) download_to_file(s_wtfurl, wtfipsw, 0); } - ipsw_extract_to_memory(wtfipsw, wtfname, &wtftmp, &wtfsize); + ipsw_archive_t wtf_ipsw = ipsw_open(wtfipsw); + ipsw_extract_to_memory(wtf_ipsw, wtfname, &wtftmp, &wtfsize); + ipsw_close(wtf_ipsw); if (!wtftmp) { error("ERROR: Could not extract WTF\n"); } @@ -601,12 +605,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client) char* ipsw = NULL; res = ipsw_download_fw(fwurl, p_fwsha1, client->cache_dir, &ipsw); if (res != 0) { - if (ipsw) { - free(ipsw); - } + free(ipsw); return res; } else { - client->ipsw = ipsw; + client->ipsw = ipsw_open(ipsw); + if (!client->ipsw) { + error("ERROR: Failed to open ipsw '%s'\n", ipsw); + free(ipsw); + return -1; + } + free(ipsw); } } idevicerestore_progress(client, RESTORE_STEP_DETECT, 0.6); @@ -641,23 +649,17 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } } - // verify if ipsw file exists - if (access(client->ipsw, F_OK) < 0) { - error("ERROR: Firmware file %s does not exist.\n", client->ipsw); - return -1; - } - // extract buildmanifest if (client->flags & FLAG_CUSTOM) { info("Extracting Restore.plist from IPSW\n"); if (ipsw_extract_restore_plist(client->ipsw, &client->build_manifest) < 0) { - error("ERROR: Unable to extract Restore.plist from %s. Firmware file might be corrupt.\n", client->ipsw); + error("ERROR: Unable to extract Restore.plist from %s. Firmware file might be corrupt.\n", client->ipsw->path); return -1; } } else { info("Extracting BuildManifest from IPSW\n"); if (ipsw_extract_build_manifest(client->ipsw, &client->build_manifest, &tss_enabled) < 0) { - error("ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw); + error("ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw->path); return -1; } } @@ -941,115 +943,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client) /* check if all components we need are actually there */ info("Checking IPSW for required components...\n"); if (build_identity_check_components_in_ipsw(build_identity, client->ipsw) < 0) { - error("ERROR: Could not find all required components in IPSW %s\n", client->ipsw); + error("ERROR: Could not find all required components in IPSW %s\n", client->ipsw->path); return -1; } info("All required components found in IPSW\n"); - // Get filesystem name from build identity - char* fsname = NULL; - if (build_identity_get_component_path(build_identity, "OS", &fsname) < 0) { - error("ERROR: Unable to get path for filesystem component\n"); - return -1; - } - - // check if we already have an extracted filesystem - int delete_fs = 0; - char* filesystem = NULL; - struct stat st; - memset(&st, '\0', sizeof(struct stat)); - char tmpf[1024]; - if (client->cache_dir) { - if (stat(client->cache_dir, &st) < 0) { - mkdir_with_parents(client->cache_dir, 0755); - } - strcpy(tmpf, client->cache_dir); - strcat(tmpf, "/"); - char *ipswtmp = strdup(client->ipsw); - strcat(tmpf, basename(ipswtmp)); - free(ipswtmp); - } else { - strcpy(tmpf, client->ipsw); - } - - if (!ipsw_is_directory(client->ipsw)) { - // strip off file extension if given ipsw is not a directory - char* s = tmpf + strlen(tmpf) - 1; - char* p = s; - while (*p != '\0' && *p != '.' && *p != '/' && *p != '\\') p--; - if (s - p < 6) { - if (*p == '.') { - *p = '\0'; - } - } - } - - if (stat(tmpf, &st) < 0) { - __mkdir(tmpf, 0755); - } - strcat(tmpf, "/"); - strcat(tmpf, fsname); - - memset(&st, '\0', sizeof(struct stat)); - if (stat(tmpf, &st) == 0) { - uint64_t fssize = 0; - ipsw_get_file_size(client->ipsw, fsname, &fssize); - if ((fssize > 0) && ((uint64_t)st.st_size == fssize)) { - info("Using cached filesystem from '%s'\n", tmpf); - filesystem = strdup(tmpf); - } - } - - if (!filesystem && !(client->flags & FLAG_SHSHONLY)) { - char extfn[1024]; - strcpy(extfn, tmpf); - strcat(extfn, ".extract"); - char lockfn[1024]; - strcpy(lockfn, tmpf); - strcat(lockfn, ".lock"); - lock_info_t li; - - lock_file(lockfn, &li); - FILE* extf = NULL; - if (access(extfn, F_OK) != 0) { - extf = fopen(extfn, "wb"); - } - unlock_file(&li); - if (!extf) { - // use temp filename - filesystem = get_temp_filename("ipsw_"); - if (!filesystem) { - error("WARNING: Could not get temporary filename, using '%s' in current directory\n", fsname); - filesystem = strdup(fsname); - } - delete_fs = 1; - } else { - // use <fsname>.extract as filename - filesystem = strdup(extfn); - fclose(extf); - } - remove(lockfn); - - // Extract filesystem from IPSW - info("Extracting filesystem from IPSW: %s\n", fsname); - if (ipsw_extract_to_file_with_progress(client->ipsw, fsname, filesystem, 1) < 0) { - error("ERROR: Unable to extract filesystem from IPSW\n"); - if (client->tss) - plist_free(client->tss); - info("Removing %s\n", filesystem); - unlink(filesystem); - return -1; - } - - if (strstr(filesystem, ".extract")) { - // rename <fsname>.extract to <fsname> - remove(tmpf); - rename(filesystem, tmpf); - free(filesystem); - filesystem = strdup(tmpf); - } - } - idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.2); /* retrieve shsh blobs if required */ @@ -1140,8 +1038,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } if (client->flags & FLAG_QUIT) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } if (client->flags & FLAG_SHSHONLY) { @@ -1196,8 +1092,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.25); if (client->flags & FLAG_QUIT) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } @@ -1214,8 +1108,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.3); if (client->flags & FLAG_QUIT) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } @@ -1226,16 +1118,12 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if ((client->flags & FLAG_CUSTOM) && limera1n_is_supported(client->device)) { info("connecting to DFU\n"); if (dfu_client_new(client) < 0) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } info("exploiting with limera1n\n"); if (limera1n_exploit(client->device, &client->dfu->client) != 0) { error("ERROR: limera1n exploit failed\n"); dfu_client_free(client); - if (delete_fs && filesystem) - unlink(filesystem); return -1; } dfu_client_free(client); @@ -1245,8 +1133,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) error("ERROR: Unable to place device into recovery mode from DFU mode\n"); if (client->tss) plist_free(client->tss); - if (delete_fs && filesystem) - unlink(filesystem); return -2; } } else if (client->mode == MODE_RECOVERY) { @@ -1256,8 +1142,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) /* send ApTicket */ if (recovery_send_ticket(client) < 0) { error("ERROR: Unable to send APTicket\n"); - if (delete_fs && filesystem) - unlink(filesystem); return -2; } } @@ -1269,8 +1153,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (recovery_send_ibec(client, build_identity) < 0) { mutex_unlock(&client->device_event_mutex); error("ERROR: Unable to send iBEC\n"); - if (delete_fs && filesystem) - unlink(filesystem); return -2; } recovery_client_free(client); @@ -1283,8 +1165,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (!(client->flags & FLAG_QUIT)) { error("ERROR: Device did not disconnect. Possibly invalid iBEC. Reset device and try again.\n"); } - if (delete_fs && filesystem) - unlink(filesystem); return -2; } debug("Waiting for device to reconnect in recovery mode...\n"); @@ -1294,16 +1174,12 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (!(client->flags & FLAG_QUIT)) { error("ERROR: Device did not reconnect in recovery mode. Possibly invalid iBEC. Reset device and try again.\n"); } - if (delete_fs && filesystem) - unlink(filesystem); return -2; } mutex_unlock(&client->device_event_mutex); } idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.5); if (client->flags & FLAG_QUIT) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } @@ -1315,8 +1191,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (get_ap_nonce(client, &nonce, &nonce_size) < 0) { error("ERROR: Unable to get nonce from device!\n"); recovery_send_reset(client); - if (delete_fs && filesystem) - unlink(filesystem); return -2; } @@ -1336,14 +1210,10 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_free(client->tss); if (get_tss_response(client, build_identity, &client->tss) < 0) { error("ERROR: Unable to get SHSH blobs for this device\n"); - if (delete_fs && filesystem) - unlink(filesystem); return -1; } if (!client->tss) { error("ERROR: can't continue without TSS\n"); - if (delete_fs && filesystem) - unlink(filesystem); return -1; } fixup_tss(client->tss); @@ -1351,8 +1221,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.7); if (client->flags & FLAG_QUIT) { - if (delete_fs && filesystem) - unlink(filesystem); return -1; } @@ -1362,8 +1230,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) error("ERROR: Unable to place device into restore mode\n"); if (client->tss) plist_free(client->tss); - if (delete_fs && filesystem) - unlink(filesystem); return -2; } recovery_client_free(client); @@ -1378,8 +1244,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) mutex_unlock(&client->device_event_mutex); error("ERROR: Device failed to enter restore mode.\n"); error("Please make sure that usbmuxd is running.\n"); - if (delete_fs && filesystem) - unlink(filesystem); return -1; } mutex_unlock(&client->device_event_mutex); @@ -1393,19 +1257,13 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } client->ignore_device_add_events = 1; info("About to restore device... \n"); - result = restore_device(client, build_identity, filesystem); + result = restore_device(client, build_identity); if (result < 0) { error("ERROR: Unable to restore device\n"); - if (delete_fs && filesystem) - unlink(filesystem); return result; } } - info("Cleaning up...\n"); - if (delete_fs && filesystem) - unlink(filesystem); - /* special handling of older AppleTVs as they enter Recovery mode on boot when plugged in to USB */ if ((strncmp(client->device->product_type, "AppleTV", 7) == 0) && (client->device->product_type[7] < '5')) { if (recovery_client_new(client) == 0) { @@ -1476,7 +1334,7 @@ void idevicerestore_client_free(struct idevicerestore_client_t* client) free(client->srnm); } if (client->ipsw) { - free(client->ipsw); + ipsw_close(client->ipsw); } if (client->version) { free(client->version); @@ -1535,11 +1393,11 @@ void idevicerestore_set_ipsw(struct idevicerestore_client_t* client, const char* if (!client) return; if (client->ipsw) { - free(client->ipsw); + ipsw_close(client->ipsw); client->ipsw = NULL; } if (path) { - client->ipsw = strdup(path); + client->ipsw = ipsw_open(path); } } @@ -1795,7 +1653,12 @@ int main(int argc, char* argv[]) { info("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); if (ipsw) { - client->ipsw = strdup(ipsw); + // verify if ipsw file exists + client->ipsw = ipsw_open(ipsw); + if (!client->ipsw) { + error("ERROR: Firmware file %s cannot be opened.\n", ipsw); + return -1; + } } curl_global_init(CURL_GLOBAL_ALL); @@ -2570,7 +2433,7 @@ int build_manifest_get_identity_count(plist_t build_manifest) return plist_array_get_size(build_identities_array); } -int extract_component(const char* ipsw, const char* path, unsigned char** component_data, unsigned int* component_size) +int extract_component(ipsw_archive_t ipsw, const char* path, unsigned char** component_data, unsigned int* component_size) { char* component_name = NULL; if (!ipsw || !path || !component_data || !component_size) { @@ -2585,7 +2448,7 @@ int extract_component(const char* ipsw, const char* path, unsigned char** compon info("Extracting %s (%s)...\n", component_name, path); if (ipsw_extract_to_memory(ipsw, path, component_data, component_size) < 0) { - error("ERROR: Unable to extract %s from %s\n", component_name, ipsw); + error("ERROR: Unable to extract %s from %s\n", component_name, ipsw->path); return -1; } @@ -2718,7 +2581,7 @@ void build_identity_print_information(plist_t build_identity) node = NULL; } -int build_identity_check_components_in_ipsw(plist_t build_identity, const char *ipsw) +int build_identity_check_components_in_ipsw(plist_t build_identity, ipsw_archive_t ipsw) { plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 8a5736f..880562f 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -52,6 +52,8 @@ extern "C" { #define RESTORE_VARIANT_MACOS_RECOVERY_OS "macOS Customer" struct idevicerestore_client_t; +struct ipsw_archive; +typedef struct ipsw_archive* ipsw_archive_t; enum { RESTORE_STEP_DETECT = 0, @@ -108,11 +110,10 @@ plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, cons plist_t build_manifest_get_build_identity_for_model_with_variant(plist_t build_manifest, const char *hardware_model, const char *variant, int exact); int build_manifest_get_build_count(plist_t build_manifest); void build_identity_print_information(plist_t build_identity); -int build_identity_check_components_in_ipsw(plist_t build_identity, const char* ipsw); int build_identity_has_component(plist_t build_identity, const char* component); int build_identity_get_component_path(plist_t build_identity, const char* component, char** path); -int ipsw_extract_filesystem(const char* ipsw, plist_t build_identity, char** filesystem); -int extract_component(const char* ipsw, const char* path, unsigned char** component_data, unsigned int* component_size); +int ipsw_extract_filesystem(ipsw_archive_t ipsw, plist_t build_identity, char** filesystem); +int extract_component(ipsw_archive_t ipsw, const char* path, unsigned char** component_data, unsigned int* component_size); int personalize_component(const char *component, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size); int get_preboard_manifest(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* manifest); @@ -55,16 +55,8 @@ #define BUFSIZE 0x100000 -typedef struct { - struct zip* zip; - char *path; -} ipsw_archive; - static int cancel_flag = 0; -ipsw_archive* ipsw_open(const char* ipsw); -void ipsw_close(ipsw_archive* archive); - static char* build_path(const char* path, const char* file) { size_t plen = strlen(path); @@ -118,11 +110,14 @@ int ipsw_print_info(const char* path) uint32_t plist_len = 0; if (memcmp(&magic, "PK\x03\x04", 4) == 0) { + ipsw_archive_t ipsw = ipsw_open(thepath); unsigned int rlen = 0; - if (ipsw_extract_to_memory(thepath, "BuildManifest.plist", (unsigned char**)&plist_buf, &rlen) < 0) { + if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", (unsigned char**)&plist_buf, &rlen) < 0) { + ipsw_close(ipsw); error("ERROR: Failed to extract BuildManifest.plist from IPSW!\n"); return -1; } + ipsw_close(ipsw); plist_len = (uint32_t)rlen; } else { size_t rlen = 0; @@ -310,10 +305,10 @@ int ipsw_print_info(const char* path) return 0; } -ipsw_archive* ipsw_open(const char* ipsw) +ipsw_archive_t ipsw_open(const char* ipsw) { int err = 0; - ipsw_archive* archive = (ipsw_archive*) malloc(sizeof(ipsw_archive)); + ipsw_archive_t archive = (ipsw_archive_t)malloc(sizeof(struct ipsw_archive)); if (archive == NULL) { error("ERROR: Out of memory\n"); return NULL; @@ -324,7 +319,6 @@ ipsw_archive* ipsw_open(const char* ipsw) error("ERROR: ipsw_open %s: %s\n", ipsw, strerror(errno)); return NULL; } - archive->path = strdup(ipsw); if (S_ISDIR(fst.st_mode)) { archive->zip = NULL; } else { @@ -335,7 +329,20 @@ ipsw_archive* ipsw_open(const char* ipsw) return NULL; } } - return archive; + archive->path = strdup(ipsw); + return (ipsw_archive_t)archive; +} + +void ipsw_close(ipsw_archive_t ipsw) +{ + if (ipsw != NULL) { + free(ipsw->path); + if (ipsw->zip) { + zip_unchange_all(ipsw->zip); + zip_close(ipsw->zip); + } + free(ipsw); + } } int ipsw_is_directory(const char* ipsw) @@ -348,37 +355,33 @@ int ipsw_is_directory(const char* ipsw) return S_ISDIR(fst.st_mode); } -int ipsw_get_file_size(const char* ipsw, const char* infile, uint64_t* size) +int ipsw_get_file_size(ipsw_archive_t ipsw, const char* infile, uint64_t* size) { - ipsw_archive* archive = ipsw_open(ipsw); - if (archive == NULL) { + if (ipsw == NULL) { error("ERROR: Invalid archive\n"); return -1; } - if (archive->zip) { - int zindex = zip_name_locate(archive->zip, infile, 0); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, infile, 0); if (zindex < 0) { error("ERROR: zip_name_locate: %s\n", infile); - ipsw_close(archive); return -1; } struct zip_stat zstat; zip_stat_init(&zstat); - if (zip_stat_index(archive->zip, zindex, 0, &zstat) != 0) { + if (zip_stat_index(ipsw->zip, zindex, 0, &zstat) != 0) { error("ERROR: zip_stat_index: %s\n", infile); - ipsw_close(archive); return -1; } *size = zstat.size; } else { - char *filepath = build_path(archive->path, infile); + char *filepath = build_path(ipsw->path, infile); struct stat fst; if (stat(filepath, &fst) != 0) { free(filepath); - ipsw_close(archive); return -1; } free(filepath); @@ -386,30 +389,22 @@ int ipsw_get_file_size(const char* ipsw, const char* infile, uint64_t* size) *size = fst.st_size; } - ipsw_close(archive); return 0; } -int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, const char* outfile, int print_progress) +int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile, const char* outfile, int print_progress) { int ret = 0; - ipsw_archive* archive = NULL; if (!ipsw || !infile || !outfile) { error("ERROR: Invalid argument\n"); return -1; } - archive = ipsw_open(ipsw); - if (archive == NULL) { - error("ERROR: Invalid archive\n"); - return -1; - } - cancel_flag = 0; - if (archive->zip) { - int zindex = zip_name_locate(archive->zip, infile, 0); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, infile, 0); if (zindex < 0) { error("ERROR: zip_name_locate: %s\n", infile); return -1; @@ -417,7 +412,7 @@ int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, con struct zip_stat zstat; zip_stat_init(&zstat); - if (zip_stat_index(archive->zip, zindex, 0, &zstat) != 0) { + if (zip_stat_index(ipsw->zip, zindex, 0, &zstat) != 0) { error("ERROR: zip_stat_index: %s\n", infile); return -1; } @@ -428,7 +423,7 @@ int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, con return -1; } - struct zip_file* zfile = zip_fopen_index(archive->zip, zindex, 0); + struct zip_file* zfile = zip_fopen_index(ipsw->zip, zindex, 0); if (zfile == NULL) { error("ERROR: zip_fopen_index: %s\n", infile); return -1; @@ -472,7 +467,7 @@ int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, con fclose(fd); zip_fclose(zfile); } else { - char *filepath = build_path(archive->path, infile); + char *filepath = build_path(ipsw->path, infile); char actual_filepath[PATH_MAX+1]; char actual_outfile[PATH_MAX+1]; if (!filepath) { @@ -553,76 +548,66 @@ int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, con leave: free(filepath); } - ipsw_close(archive); if (cancel_flag) { ret = -2; } return ret; } -int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfile) +int ipsw_extract_to_file(ipsw_archive_t ipsw, const char* infile, const char* outfile) { return ipsw_extract_to_file_with_progress(ipsw, infile, outfile, 0); } -int ipsw_file_exists(const char* ipsw, const char* infile) +int ipsw_file_exists(ipsw_archive_t ipsw, const char* infile) { - ipsw_archive* archive = ipsw_open(ipsw); - if (archive == NULL) { + if (!ipsw) { return 0; } - if (archive->zip) { - int zindex = zip_name_locate(archive->zip, infile, 0); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, infile, 0); if (zindex < 0) { - ipsw_close(archive); return 0; } } else { - char *filepath = build_path(archive->path, infile); + char *filepath = build_path(ipsw->path, infile); if (access(filepath, R_OK) != 0) { free(filepath); - ipsw_close(archive); return 0; } free(filepath); } - ipsw_close(archive); - return 1; } -int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** pbuffer, unsigned int* psize) +int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned char** pbuffer, unsigned int* psize) { size_t size = 0; unsigned char* buffer = NULL; - ipsw_archive* archive = ipsw_open(ipsw); - if (archive == NULL) { + if (ipsw == NULL) { error("ERROR: Invalid archive\n"); return -1; } - if (archive->zip) { - int zindex = zip_name_locate(archive->zip, infile, 0); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, infile, 0); if (zindex < 0) { debug("NOTE: zip_name_locate: '%s' not found in archive.\n", infile); - ipsw_close(archive); return -1; } struct zip_stat zstat; zip_stat_init(&zstat); - if (zip_stat_index(archive->zip, zindex, 0, &zstat) != 0) { + if (zip_stat_index(ipsw->zip, zindex, 0, &zstat) != 0) { error("ERROR: zip_stat_index: %s\n", infile); - ipsw_close(archive); return -1; } - struct zip_file* zfile = zip_fopen_index(archive->zip, zindex, 0); + struct zip_file* zfile = zip_fopen_index(ipsw->zip, zindex, 0); if (zfile == NULL) { error("ERROR: zip_fopen_index: %s\n", infile); - ipsw_close(archive); return -1; } @@ -631,7 +616,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** if (buffer == NULL) { error("ERROR: Out of memory\n"); zip_fclose(zfile); - ipsw_close(archive); return -1; } @@ -639,7 +623,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** error("ERROR: zip_fread: %s\n", infile); zip_fclose(zfile); free(buffer); - ipsw_close(archive); return -1; } @@ -647,7 +630,7 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** zip_fclose(zfile); } else { - char *filepath = build_path(archive->path, infile); + char *filepath = build_path(ipsw->path, infile); struct stat fst; #ifdef WIN32 if (stat(filepath, &fst) != 0) { @@ -656,7 +639,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** #endif error("ERROR: %s: stat failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); - ipsw_close(archive); return -1; } size = fst.st_size; @@ -664,7 +646,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** if (buffer == NULL) { error("ERROR: Out of memory\n"); free(filepath); - ipsw_close(archive); return -1; } @@ -674,7 +655,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** error("ERROR: %s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); free(buffer); - ipsw_close(archive); return -1; } } else { @@ -684,7 +664,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** error("ERROR: %s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); free(buffer); - ipsw_close(archive); return -2; } if (fread(buffer, 1, size, f) != size) { @@ -692,7 +671,6 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** error("ERROR: %s: fread failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); free(buffer); - ipsw_close(archive); return -1; } fclose(f); @@ -703,45 +681,40 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** free(filepath); } - ipsw_close(archive); *pbuffer = buffer; *psize = size; return 0; } -int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_send_cb send_callback, void* ctx) +int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ipsw_send_cb send_callback, void* ctx) { unsigned char* buffer = NULL; size_t done = 0; size_t total_size = 0; - ipsw_archive* archive = ipsw_open(ipsw); - if (archive == NULL) { + if (ipsw == NULL) { error("ERROR: Invalid archive\n"); return -1; } - if (archive->zip) { - int zindex = zip_name_locate(archive->zip, infile, 0); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, infile, 0); if (zindex < 0) { debug("NOTE: zip_name_locate: '%s' not found in archive.\n", infile); - ipsw_close(archive); return -1; } struct zip_stat zstat; zip_stat_init(&zstat); - if (zip_stat_index(archive->zip, zindex, 0, &zstat) != 0) { + if (zip_stat_index(ipsw->zip, zindex, 0, &zstat) != 0) { error("ERROR: zip_stat_index: %s\n", infile); - ipsw_close(archive); return -1; } - struct zip_file* zfile = zip_fopen_index(archive->zip, zindex, 0); + struct zip_file* zfile = zip_fopen_index(ipsw->zip, zindex, 0); if (zfile == NULL) { error("ERROR: zip_fopen_index: %s\n", infile); - ipsw_close(archive); return -1; } @@ -750,7 +723,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ if (buffer == NULL) { error("ERROR: Out of memory\n"); zip_fclose(zfile); - ipsw_close(archive); return -1; } @@ -771,10 +743,9 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ } done += zr; } - zip_fclose(zfile); free(buffer); } else { - char *filepath = build_path(archive->path, infile); + char *filepath = build_path(ipsw->path, infile); struct stat fst; #ifdef WIN32 if (stat(filepath, &fst) != 0) { @@ -783,7 +754,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ #endif error("ERROR: %s: stat failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); - ipsw_close(archive); return -1; } total_size = fst.st_size; @@ -791,7 +761,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ if (buffer == NULL) { error("ERROR: Out of memory\n"); free(filepath); - ipsw_close(archive); return -1; } @@ -802,7 +771,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ error("ERROR: %s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); free(buffer); - ipsw_close(archive); return -1; } send_callback(ctx, buffer, (size_t)rl); @@ -813,7 +781,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ error("ERROR: %s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno)); free(filepath); free(buffer); - ipsw_close(archive); return -2; } @@ -838,7 +805,6 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ free(filepath); free(buffer); } - ipsw_close(archive); if (done < total_size) { error("ERROR: %s: Sending file data for %s failed (sent %" PRIu64 "/%" PRIu64 ")\n", __func__, infile, (uint64_t)done, (uint64_t)total_size); @@ -851,7 +817,7 @@ int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_ return 0; } -int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *tss_enabled) +int ipsw_extract_build_manifest(ipsw_archive_t ipsw, plist_t* buildmanifest, int *tss_enabled) { unsigned int size = 0; unsigned char* data = NULL; @@ -881,7 +847,7 @@ int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *t return -1; } -int ipsw_extract_restore_plist(const char* ipsw, plist_t* restore_plist) +int ipsw_extract_restore_plist(ipsw_archive_t ipsw, plist_t* restore_plist) { unsigned int size = 0; unsigned char* data = NULL; @@ -895,10 +861,10 @@ int ipsw_extract_restore_plist(const char* ipsw, plist_t* restore_plist) return -1; } -static int ipsw_list_contents_recurse(ipsw_archive *archive, const char *path, ipsw_list_cb cb, void *ctx) +static int ipsw_list_contents_recurse(ipsw_archive_t ipsw, const char *path, ipsw_list_cb cb, void *ctx) { int ret = 0; - char *base = build_path(archive->path, path); + char *base = build_path(ipsw->path, path); DIR *dirp = opendir(base); @@ -936,10 +902,10 @@ static int ipsw_list_contents_recurse(ipsw_archive *archive, const char *path, i break; } - ret = cb(ctx, archive->path, subpath, &st); + ret = cb(ctx, ipsw, subpath, &st); if (ret >= 0 && S_ISDIR(st.st_mode)) - ipsw_list_contents_recurse(archive, subpath, cb, ctx); + ipsw_list_contents_recurse(ipsw, subpath, cb, ctx); free(fpath); free(subpath); @@ -950,21 +916,19 @@ static int ipsw_list_contents_recurse(ipsw_archive *archive, const char *path, i return ret; } -int ipsw_list_contents(const char* ipsw, ipsw_list_cb cb, void *ctx) +int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx) { int ret = 0; - ipsw_archive* archive = ipsw_open(ipsw); - if (archive == NULL) { - error("ERROR: Invalid archive\n"); + if (ipsw == NULL) { + error("ERROR: Invalid IPSW archive\n"); return -1; } - if (archive->zip) { - int64_t entries = zip_get_num_entries(archive->zip, 0); + if (ipsw->zip) { + int64_t entries = zip_get_num_entries(ipsw->zip, 0); if (entries < 0) { error("ERROR: zip_get_num_entries failed\n"); - ipsw_close(archive); return -1; } @@ -972,7 +936,7 @@ int ipsw_list_contents(const char* ipsw, ipsw_list_cb cb, void *ctx) zip_stat_t stat; zip_stat_init(&stat); - if (zip_stat_index(archive->zip, index, 0, &stat) < 0) { + if (zip_stat_index(ipsw->zip, index, 0, &stat) < 0) { error("ERROR: zip_stat_index failed for %s\n", stat.name); ret = -1; continue; @@ -980,7 +944,7 @@ int ipsw_list_contents(const char* ipsw, ipsw_list_cb cb, void *ctx) uint8_t opsys; uint32_t attributes; - if (zip_file_get_external_attributes(archive->zip, index, 0, &opsys, &attributes) < 0) { + if (zip_file_get_external_attributes(ipsw->zip, index, 0, &opsys, &attributes) < 0) { error("ERROR: zip_file_get_external_attributes failed for %s\n", stat.name); ret = -1; continue; @@ -1010,25 +974,12 @@ int ipsw_list_contents(const char* ipsw, ipsw_list_cb cb, void *ctx) break; } } else { - ret = ipsw_list_contents_recurse(archive, "", cb, ctx); + ret = ipsw_list_contents_recurse(ipsw, "", cb, ctx); } - ipsw_close(archive); return ret; } -void ipsw_close(ipsw_archive* archive) -{ - if (archive != NULL) { - free(archive->path); - if (archive->zip) { - zip_unchange_all(archive->zip); - zip_close(archive->zip); - } - free(archive); - } -} - int ipsw_get_signed_firmwares(const char* product, plist_t* firmwares) { char url[256]; @@ -1352,3 +1303,91 @@ void ipsw_cancel(void) { cancel_flag++; } + +ipsw_file_handle_t ipsw_file_open(ipsw_archive_t ipsw, const char* path) +{ + ipsw_file_handle_t handle = (ipsw_file_handle_t)calloc(1, sizeof(struct ipsw_file_handle)); + if (ipsw->zip) { + int zindex = zip_name_locate(ipsw->zip, path, 0); + if (zindex < 0) { + error("ERROR: zip_name_locate: %s not found\n", path); + free(handle); + return NULL; + } + handle->zfile = zip_fopen_index(ipsw->zip, zindex, 0); + if (handle->zfile == NULL) { + error("ERROR: zip_fopen_index: %s could not be opened\n", path); + free(handle); + return NULL; + } + + } else { + char *filepath = build_path(ipsw->path, path); + handle->file = fopen(filepath, "rb"); + free(filepath); + if (!handle->file) { + error("ERROR: fopen: %s could not be opened\n", path); + free(handle); + return NULL; + } + } + return handle; +} + +void ipsw_file_close(ipsw_file_handle_t handle) +{ + if (handle && handle->zfile) { + zip_fclose(handle->zfile); + } else if (handle && handle->file) { + fclose(handle->file); + } + free(handle); +} + +int64_t ipsw_file_read(ipsw_file_handle_t handle, void* buffer, size_t size) +{ + if (handle && handle->zfile) { + zip_int64_t zr = zip_fread(handle->zfile, buffer, size); + return (int64_t)zr; + } else if (handle && handle->file) { + return fread(buffer, 1, size, handle->file); + } else { + error("ERROR: %s: Invalid file handle\n", __func__); + return -1; + } +} + +int ipsw_file_seek(ipsw_file_handle_t handle, int64_t offset, int whence) +{ + if (handle && handle->zfile) { + return zip_fseek(handle->zfile, offset, whence); + } else if (handle && handle->file) { +#ifdef WIN32 + if (whence == SEEK_SET) { + rewind(handle->file); + } + return (_lseeki64(fileno(handle->file), offset, whence) < 0) ? -1 : 0; +#else + return fseeko(handle->file, offset, whence); +#endif + } else { + error("ERROR: %s: Invalid file handle\n", __func__); + return -1; + } +} + +int64_t ipsw_file_tell(ipsw_file_handle_t handle) +{ + if (handle && handle->zfile) { + return zip_ftell(handle->zfile); + } else if (handle && handle->file) { +#ifdef WIN32 + return _lseeki64(fileno(handle->file), 0, SEEK_CUR); +#else + return ftello(handle->file); +#endif + } else { + error("ERROR: %s: Invalid file handle\n", __func__); + return -1; + } +} @@ -32,21 +32,44 @@ extern "C" { #include <plist/plist.h> #include <sys/stat.h> +struct ipsw_archive { + struct zip* zip; + char *path; +}; +typedef struct ipsw_archive* ipsw_archive_t; + +ipsw_archive_t ipsw_open(const char* ipsw); +void ipsw_close(ipsw_archive_t ipsw); + int ipsw_print_info(const char* ipsw); -typedef int (*ipsw_list_cb)(void *ctx, const char* ipsw, const char *name, struct stat *stat); +typedef int (*ipsw_list_cb)(void *ctx, ipsw_archive_t ipsw, const char *name, struct stat *stat); typedef int (*ipsw_send_cb)(void *ctx, void *data, size_t size); +struct ipsw_file_handle { + FILE* file; + struct zip_file* zfile; +}; +typedef struct ipsw_file_handle* ipsw_file_handle_t; + +ipsw_file_handle_t ipsw_file_open(ipsw_archive_t, const char* path); +void ipsw_file_close(ipsw_file_handle_t handle); + +int64_t ipsw_file_read(ipsw_file_handle_t handle, void* buffer, size_t size); +int ipsw_file_seek(ipsw_file_handle_t handle, int64_t offset, int whence); +int64_t ipsw_file_tell(ipsw_file_handle_t handle); + int ipsw_is_directory(const char* ipsw); -int ipsw_file_exists(const char* ipsw, const char* infile); -int ipsw_get_file_size(const char* ipsw, const char* infile, uint64_t* size); -int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfile); -int ipsw_extract_to_file_with_progress(const char* ipsw, const char* infile, const char* outfile, int print_progress); -int ipsw_extract_to_memory(const char* ipsw, const char* infile, unsigned char** pbuffer, unsigned int* psize); -int ipsw_extract_send(const char* ipsw, const char* infile, int blocksize, ipsw_send_cb send_callback, void* ctx); -int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *tss_enabled); -int ipsw_extract_restore_plist(const char* ipsw, plist_t* restore_plist); -int ipsw_list_contents(const char* ipsw, ipsw_list_cb cb, void *ctx); + +int ipsw_file_exists(ipsw_archive_t ipsw, const char* infile); +int ipsw_get_file_size(ipsw_archive_t ipsw, const char* infile, uint64_t* size); +int ipsw_extract_to_file(ipsw_archive_t ipsw, const char* infile, const char* outfile); +int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile, const char* outfile, int print_progress); +int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned char** pbuffer, unsigned int* psize); +int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ipsw_send_cb send_callback, void* ctx); +int ipsw_extract_build_manifest(ipsw_archive_t ipsw, plist_t* buildmanifest, int *tss_enabled); +int ipsw_extract_restore_plist(ipsw_archive_t ipsw, plist_t* restore_plist); +int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx); int ipsw_get_signed_firmwares(const char* product, plist_t* firmwares); int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir, char** ipswfile); diff --git a/src/restore.c b/src/restore.c index a7072f0..c1dd92d 100644 --- a/src/restore.c +++ b/src/restore.c @@ -896,13 +896,26 @@ static void restore_asr_progress_cb(double progress, void* userdata) } } -int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t device, const char* filesystem) +int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t device, plist_t build_identity) { asr_client_t asr = NULL; info("About to send filesystem...\n"); + ipsw_file_handle_t file = NULL; + char* fsname = NULL; + if (build_identity_get_component_path(build_identity, "OS", &fsname) < 0) { + error("ERROR: Unable to get path for filesystem component\n"); + return -1; + } + file = ipsw_file_open(client->ipsw, fsname); + if (!file) { + error("ERROR: Unable to open '%s' in ipsw\n", fsname); + free(fsname); + } + if (asr_open_with_timeout(device, &asr) < 0) { + ipsw_file_close(file); error("ERROR: Unable to connect to ASR\n"); return -1; } @@ -913,7 +926,8 @@ int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t de // this step sends requested chunks of data from various offsets to asr so // it can validate the filesystem before installing it info("Validating the filesystem\n"); - if (asr_perform_validation(asr, filesystem) < 0) { + if (asr_perform_validation(asr, file) < 0) { + ipsw_file_close(file); error("ERROR: ASR was unable to validate the filesystem\n"); asr_free(asr); return -1; @@ -923,11 +937,14 @@ int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t de // once the target filesystem has been validated, ASR then requests the // entire filesystem to be sent. info("Sending filesystem now...\n"); - if (asr_send_payload(asr, filesystem) < 0) { + if (asr_send_payload(asr, file) < 0) { + ipsw_file_close(file); error("ERROR: Unable to send payload to ASR\n"); asr_free(asr); return -1; } + ipsw_file_close(file); + info("Done sending filesystem\n"); asr_free(asr); @@ -3275,7 +3292,7 @@ static int cpio_send_file(idevice_connection_t connection, const char *name, str return 0; } -static int restore_bootability_send_one(void *ctx, const char *ipsw, const char *name, struct stat *stat) +static int restore_bootability_send_one(void *ctx, ipsw_archive_t ipsw, const char *name, struct stat *stat) { idevice_connection_t connection = (idevice_connection_t)ctx; const char *prefix = "BootabilityBundle/Restore/Bootability/"; @@ -3747,7 +3764,7 @@ int restore_send_buildidentity(restored_client_t restore, struct idevicerestore_ return 0; } -int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity, const char* filesystem) +int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity) { plist_t node = NULL; @@ -3759,7 +3776,7 @@ int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idev // this request is sent when restored is ready to receive the filesystem if (!strcmp(type, "SystemImageData")) { - if(restore_send_filesystem(client, device, filesystem) < 0) { + if(restore_send_filesystem(client, device, build_identity) < 0) { error("ERROR: Unable to send filesystem\n"); return -2; } @@ -3795,7 +3812,7 @@ int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idev // this request is sent when restored is ready to receive the filesystem else if (!strcmp(type, "RecoveryOSASRImage")) { - if(restore_send_filesystem(client, device, filesystem) < 0) { + if(restore_send_filesystem(client, device, build_identity) < 0) { error("ERROR: Unable to send filesystem\n"); return -2; } @@ -4038,7 +4055,7 @@ static void rp_status_cb(reverse_proxy_client_t client, reverse_proxy_status_t s } #endif -int restore_device(struct idevicerestore_client_t* client, plist_t build_identity, const char* filesystem) +int restore_device(struct idevicerestore_client_t* client, plist_t build_identity) { int err = 0; char* type = NULL; @@ -4361,7 +4378,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit // files sent to the server by the client. these data requests include // SystemImageData, RootTicket, KernelCache, NORData and BasebandData requests if (!strcmp(type, "DataRequestMsg")) { - err = restore_handle_data_request_msg(client, device, restore, message, build_identity, filesystem); + err = restore_handle_data_request_msg(client, device, restore, message, build_identity); } // restore logs are available if a previous restore failed diff --git a/src/restore.h b/src/restore.h index ad3b721..765f374 100644 --- a/src/restore.h +++ b/src/restore.h @@ -38,7 +38,6 @@ struct restore_client_t { idevice_t device; char* udid; unsigned int operation; - const char* filesystem; uint64_t protocol_version; restored_client_t client; }; @@ -52,13 +51,13 @@ int restore_reboot(struct idevicerestore_client_t* client); const char* restore_progress_string(unsigned int operation); int restore_handle_status_msg(restored_client_t client, plist_t msg); int restore_handle_progress_msg(struct idevicerestore_client_t* client, plist_t msg); -int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity, const char* filesystem); +int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity); int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, plist_t message); int restore_send_root_ticket(restored_client_t restore, struct idevicerestore_client_t* client); int restore_send_component(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, const char* component, const char* component_name); -int restore_device(struct idevicerestore_client_t* client, plist_t build_identity, const char* filesystem); +int restore_device(struct idevicerestore_client_t* client, plist_t build_identity); int restore_open_with_timeout(struct idevicerestore_client_t* client); -int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t device, const char* filesystem); +int restore_send_filesystem(struct idevicerestore_client_t* client, idevice_t device, plist_t build_identity); int restore_send_fdr_trust_data(restored_client_t restore, idevice_t device); #ifdef __cplusplus |