diff options
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r-- | src/idevicerestore.c | 636 |
1 files changed, 344 insertions, 292 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 9911e9d..3dd4bb9 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -40,6 +40,7 @@ #include <libimobiledevice-glue/sha.h> #include <libimobiledevice-glue/utils.h> +#include <libimobiledevice-glue/termcolors.h> #include <libtatsu/tss.h> #include "ace3.h" @@ -62,7 +63,7 @@ #define VERSION_XML "version.xml" -#ifndef IDEVICERESTORE_NOMAIN +#ifndef IDEVICERESTORE_NOMAIN static struct option longopts[] = { { "ecid", required_argument, NULL, 'i' }, { "udid", required_argument, NULL, 'u' }, @@ -89,6 +90,7 @@ static struct option longopts[] = { { "ipsw-info", no_argument, NULL, 'I' }, { "ignore-errors", no_argument, NULL, 1 }, { "variant", required_argument, NULL, 2 }, + { "logfile", required_argument, NULL, 3 }, { NULL, 0, NULL, 0 } }; @@ -133,7 +135,9 @@ static void usage(int argc, char* argv[], int err) " -h, --help Prints this usage information\n" \ " -C, --cache-path DIR Use specified directory for caching extracted or other\n" \ " reused files.\n" \ - " -d, --debug Enable communication debugging\n" \ + " --logfile=PATH Write logging output to file at PATH. If PATH equals\n" \ + " 'NULL' or 'NONE', no log file will be written.\n" \ + " -d, --debug Print additional debug output\n" \ " -v, --version Print version information\n" \ "\n" \ "Advanced/experimental options:\n" @@ -199,9 +203,9 @@ static int load_version_data(struct idevicerestore_client_t* client) if (download_to_file("http://itunes.apple.com/check/version", version_xml_tmp, 0) == 0) { remove(version_xml); if (rename(version_xml_tmp, version_xml) < 0) { - error("ERROR: Could not update '%s'\n", version_xml); + logger(LL_ERROR, "Could not update '%s'\n", version_xml); } else { - info("NOTE: Updated version data.\n"); + logger(LL_INFO, "Updated version data.\n"); } } } else { @@ -213,7 +217,7 @@ static int load_version_data(struct idevicerestore_client_t* client) read_file(version_xml, (void**)&verbuf, &verlen); if (!verbuf) { - error("ERROR: Could not load '%s'\n", version_xml); + logger(LL_ERROR, "Could not load '%s'\n", version_xml); return -1; } @@ -223,12 +227,12 @@ static int load_version_data(struct idevicerestore_client_t* client) if (!client->version_data) { remove(version_xml); - error("ERROR: Cannot parse plist data from '%s'.\n", version_xml); + logger(LL_ERROR, "Cannot parse plist data from '%s'.\n", version_xml); return -1; } if (cached) { - info("NOTE: using cached version data\n"); + logger(LL_INFO, "Using cached version data\n"); } return 0; @@ -264,21 +268,24 @@ static void idevice_event_cb(const idevice_event_t *event, void *userdata) if (normal_check_mode(client) == 0) { mutex_lock(&client->device_event_mutex); client->mode = MODE_NORMAL; - debug("%s: device %016" PRIx64 " (udid: %s) connected in normal mode\n", __func__, client->ecid, client->udid); + logger(LL_DEBUG, "%s: device %016" PRIx64 " (udid: %s) connected in normal mode\n", __func__, client->ecid, client->udid); cond_signal(&client->device_event_cond); mutex_unlock(&client->device_event_mutex); } else if (client->ecid && restore_check_mode(client) == 0) { mutex_lock(&client->device_event_mutex); client->mode = MODE_RESTORE; - debug("%s: device %016" PRIx64 " (udid: %s) connected in restore mode\n", __func__, client->ecid, client->udid); + logger(LL_DEBUG, "%s: device %016" PRIx64 " (udid: %s) connected in restore mode\n", __func__, client->ecid, client->udid); cond_signal(&client->device_event_cond); mutex_unlock(&client->device_event_mutex); } + if (!client->device) { + client->device = get_irecv_device(client); + } } else if (event->event == IDEVICE_DEVICE_REMOVE) { if (client->udid && !strcmp(event->udid, client->udid)) { mutex_lock(&client->device_event_mutex); client->mode = MODE_UNKNOWN; - debug("%s: device %016" PRIx64 " (udid: %s) disconnected\n", __func__, client->ecid, client->udid); + logger(LL_DEBUG, "%s: device %016" PRIx64 " (udid: %s) disconnected\n", __func__, client->ecid, client->udid); client->ignore_device_add_events = 0; cond_signal(&client->device_event_cond); mutex_unlock(&client->device_event_mutex); @@ -314,7 +321,10 @@ static void irecv_event_cb(const irecv_device_event_t* event, void *userdata) default: client->mode = MODE_UNKNOWN; } - debug("%s: device %016" PRIx64 " (udid: %s) connected in %s mode\n", __func__, client->ecid, (client->udid) ? client->udid : "N/A", client->mode->string); + logger(LL_DEBUG, "%s: device %016" PRIx64 " (udid: %s) connected in %s mode\n", __func__, client->ecid, (client->udid) ? client->udid : "N/A", client->mode->string); + if (!client->device) { + client->device = get_irecv_device(client); + } cond_signal(&client->device_event_cond); mutex_unlock(&client->device_event_mutex); } @@ -322,7 +332,7 @@ static void irecv_event_cb(const irecv_device_event_t* event, void *userdata) if (client->ecid && event->device_info->ecid == client->ecid) { mutex_lock(&client->device_event_mutex); client->mode = MODE_UNKNOWN; - debug("%s: device %016" PRIx64 " (udid: %s) disconnected\n", __func__, client->ecid, (client->udid) ? client->udid : "N/A"); + logger(LL_DEBUG, "%s: device %016" PRIx64 " (udid: %s) disconnected\n", __func__, client->ecid, (client->udid) ? client->udid : "N/A"); if (event->mode == IRECV_K_PORT_DFU_MODE) { // We have to reset the ECID here if a port DFU device disconnects, // because when the device reconnects in a different mode, it will @@ -347,12 +357,12 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } if ((client->flags & FLAG_LATEST) && (client->flags & FLAG_CUSTOM)) { - error("ERROR: FLAG_LATEST cannot be used with FLAG_CUSTOM.\n"); + logger(LL_ERROR, "FLAG_LATEST cannot be used with FLAG_CUSTOM.\n"); return -1; } if (!client->ipsw && !(client->flags & FLAG_PWN) && !(client->flags & FLAG_LATEST)) { - error("ERROR: no ipsw file given\n"); + logger(LL_ERROR, "no ipsw file given\n"); return -1; } @@ -367,12 +377,18 @@ int idevicerestore_start(struct idevicerestore_client_t* client) tss_set_debug_level(client->debug_level); } + progress_reset_tag(); + idevicerestore_progress(client, RESTORE_STEP_DETECT, 0.0); - irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, client); + if (!client->irecv_e_ctx) { + irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, client); + } - idevice_event_subscribe(idevice_event_cb, client); - client->idevice_e_ctx = idevice_event_cb; + if (!client->idevice_e_ctx) { + idevice_event_subscribe(idevice_event_cb, client); + client->idevice_e_ctx = idevice_event_cb; + } // check which mode the device is currently in so we know where to start mutex_lock(&client->device_event_mutex); @@ -380,23 +396,23 @@ int idevicerestore_start(struct idevicerestore_client_t* client) cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000); if (client->mode == MODE_UNKNOWN || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); - error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n"); + logger(LL_ERROR, "Unable to discover device mode. Please make sure a device is attached.\n"); return -1; } } idevicerestore_progress(client, RESTORE_STEP_DETECT, 0.1); - info("Found device in %s mode\n", client->mode->string); + logger(LL_INFO, "Found device in %s mode\n", client->mode->string); mutex_unlock(&client->device_event_mutex); if (client->mode == MODE_WTF) { unsigned int cpid = 0; if (dfu_client_new(client) != 0) { - error("ERROR: Could not open device in WTF mode\n"); + logger(LL_ERROR, "Could not open device in WTF mode\n"); return -1; } if ((dfu_get_cpid(client, &cpid) < 0) || (cpid == 0)) { - error("ERROR: Could not get CPID for WTF mode device\n"); + logger(LL_ERROR, "Could not get CPID for WTF mode device\n"); dfu_client_free(client); return -1; } @@ -419,7 +435,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_get_string_val(wtfurl, &s_wtfurl); } if (!s_wtfurl) { - info("Using hardcoded x12220000_5_Recovery.ipsw URL\n"); + logger(LL_INFO, "Using hardcoded x12220000_5_Recovery.ipsw URL\n"); s_wtfurl = strdup("http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-6618.20090617.Xse7Y/x12220000_5_Recovery.ipsw"); } @@ -450,14 +466,14 @@ int idevicerestore_start(struct idevicerestore_client_t* client) ipsw_extract_to_memory(wtf_ipsw, wtfname, &wtftmp, &wtfsize); ipsw_close(wtf_ipsw); if (!wtftmp) { - error("ERROR: Could not extract WTF\n"); + logger(LL_ERROR, "Could not extract WTF\n"); } } mutex_lock(&client->device_event_mutex); if (wtftmp) { if (dfu_send_buffer(client, wtftmp, wtfsize) != 0) { - error("ERROR: Could not send WTF...\n"); + logger(LL_ERROR, "Could not send WTF...\n"); } } dfu_client_free(client); @@ -468,7 +484,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (client->mode != MODE_DFU || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); /* TODO: verify if it actually goes from 0x1222 -> 0x1227 */ - error("ERROR: Failed to put device into DFU from WTF mode\n"); + logger(LL_ERROR, "Failed to put device into DFU from WTF mode\n"); return -1; } mutex_unlock(&client->device_event_mutex); @@ -477,20 +493,20 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // discover the device type client->device = get_irecv_device(client); if (client->device == NULL) { - error("ERROR: Unable to discover device type\n"); + logger(LL_ERROR, "Unable to discover device type\n"); return -1; } if (client->ecid == 0) { - error("ERROR: Unable to determine ECID\n"); + logger(LL_ERROR, "Unable to determine ECID\n"); return -1; } - info("ECID: %" PRIu64 "\n", client->ecid); + logger(LL_INFO, "ECID: %" PRIu64 "\n", client->ecid); idevicerestore_progress(client, RESTORE_STEP_DETECT, 0.2); - info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type); + logger(LL_INFO, "Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type); if ((client->flags & FLAG_PWN) && (client->mode != MODE_DFU)) { - error("ERROR: you need to put your device into DFU mode to pwn it.\n"); + logger(LL_ERROR, "you need to put your device into DFU mode to pwn it.\n"); return -1; } @@ -506,38 +522,38 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_free(pver); } } - info("Device Product Version: %s\n", (client->device_version) ? client->device_version : "N/A"); - info("Device Product Build: %s\n", (client->device_build) ? client->device_build : "N/A"); + logger(LL_INFO, "Device Product Version: %s\n", (client->device_version) ? client->device_version : "N/A"); + logger(LL_INFO, "Device Product Build: %s\n", (client->device_build) ? client->device_build : "N/A"); if (client->flags & FLAG_PWN) { #ifdef HAVE_LIMERA1N recovery_client_free(client); if (client->mode != MODE_DFU) { - error("ERROR: Device needs to be in DFU mode for this option.\n"); + logger(LL_ERROR, "Device needs to be in DFU mode for this option.\n"); return -1; } - info("connecting to DFU\n"); + logger(LL_INFO, "connecting to DFU\n"); if (dfu_client_new(client) < 0) { return -1; } if (limera1n_is_supported(client->device)) { - info("exploiting with limera1n...\n"); + logger(LL_INFO, "exploiting with limera1n...\n"); if (limera1n_exploit(client->device, &client->dfu->client) != 0) { - error("ERROR: limera1n exploit failed\n"); + logger(LL_ERROR, "limera1n exploit failed\n"); dfu_client_free(client); return -1; } dfu_client_free(client); - info("Device should be in pwned DFU state now.\n"); + logger(LL_INFO, "Device should be in pwned DFU state now.\n"); return 0; } else { dfu_client_free(client); - error("ERROR: This device is not supported by the limera1n exploit"); + logger(LL_ERROR, "This device is not supported by the limera1n exploit"); return -1; } #endif @@ -550,30 +566,24 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_t signed_fws = NULL; int res = ipsw_get_signed_firmwares(client->device->product_type, &signed_fws); if (res < 0) { - error("ERROR: Could not fetch list of signed firmwares.\n"); + logger(LL_ERROR, "Could not fetch list of signed firmwares.\n"); return res; } uint32_t count = plist_array_get_size(signed_fws); if (count == 0) { plist_free(signed_fws); - error("ERROR: No firmwares are currently being signed for %s (REALLY?!)\n", client->device->product_type); + logger(LL_ERROR, "No firmwares are currently being signed for %s (REALLY?!)\n", client->device->product_type); return -1; } plist_t selected_fw = NULL; if (client->flags & FLAG_INTERACTIVE) { uint32_t i = 0; - info("The following firmwares are currently being signed for %s:\n", client->device->product_type); + logger(LL_INFO, "The following firmwares are currently being signed for %s:\n", client->device->product_type); for (i = 0; i < count; i++) { plist_t fw = plist_array_get_item(signed_fws, i); plist_t p_version = plist_dict_get_item(fw, "version"); plist_t p_build = plist_dict_get_item(fw, "buildid"); - char *s_version = NULL; - char *s_build = NULL; - plist_get_string_val(p_version, &s_version); - plist_get_string_val(p_build, &s_build); - info(" [%d] %s (build %s)\n", i+1, s_version, s_build); - free(s_version); - free(s_build); + logger(LL_INFO, " [%d] %s (build %s)\n", i+1, plist_get_string_ptr(p_version, NULL), plist_get_string_ptr(p_build, NULL)); } while (1) { char input[64]; @@ -597,23 +607,17 @@ int idevicerestore_start(struct idevicerestore_client_t* client) break; } } else { - info("NOTE: Running non-interactively, automatically selecting latest available version\n"); + logger(LL_NOTICE, "Running non-interactively, automatically selecting latest available version\n"); selected_fw = plist_array_get_item(signed_fws, 0); } if (!selected_fw) { - error("ERROR: failed to select latest firmware?!\n"); + logger(LL_ERROR, "failed to select latest firmware?!\n"); plist_free(signed_fws); return -1; } else { plist_t p_version = plist_dict_get_item(selected_fw, "version"); plist_t p_build = plist_dict_get_item(selected_fw, "buildid"); - char *s_version = NULL; - char *s_build = NULL; - plist_get_string_val(p_version, &s_version); - plist_get_string_val(p_build, &s_build); - info("Selected firmware %s (build %s)\n", s_version, s_build); - free(s_version); - free(s_build); + logger(LL_NOTICE, "Selected firmware %s (build %s)\n", plist_get_string_ptr(p_version, NULL), plist_get_string_ptr(p_build, NULL)); plist_t p_url = plist_dict_get_item(selected_fw, "url"); plist_t p_sha1 = plist_dict_get_item(selected_fw, "sha1sum"); char *s_sha1 = NULL; @@ -629,13 +633,13 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } p_fwsha1 = &fwsha1[0]; } else { - error("ERROR: unexpected size of sha1sum\n"); + logger(LL_ERROR, "unexpected size of sha1sum\n"); } } plist_free(signed_fws); if (!fwurl || !p_fwsha1) { - error("ERROR: Missing firmware URL or SHA1\n"); + logger(LL_ERROR, "Missing firmware URL or SHA1\n"); return -1; } @@ -647,7 +651,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } else { client->ipsw = ipsw_open(ipsw); if (!client->ipsw) { - error("ERROR: Failed to open ipsw '%s'\n", ipsw); + logger(LL_ERROR, "Failed to open ipsw '%s'\n", ipsw); free(ipsw); return -1; } @@ -662,15 +666,15 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // extract buildmanifest if (client->flags & FLAG_CUSTOM) { - info("Extracting Restore.plist from IPSW\n"); + logger(LL_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->path); + logger(LL_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"); + logger(LL_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->path); + logger(LL_ERROR, "Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw->path); return -1; } } @@ -678,13 +682,13 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (client->flags & FLAG_CUSTOM) { // prevent attempt to sign custom firmware tss_enabled = 0; - info("Custom firmware requested; TSS has been disabled.\n"); + logger(LL_INFO, "Custom firmware requested; TSS has been disabled.\n"); } if (client->mode == MODE_RESTORE) { if (!(client->flags & FLAG_ALLOW_RESTORE_MODE)) { if (restore_reboot(client) < 0) { - error("ERROR: Unable to exit restore mode\n"); + logger(LL_ERROR, "Unable to exit restore mode\n"); return -2; } @@ -693,10 +697,10 @@ int idevicerestore_start(struct idevicerestore_client_t* client) cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 60000); if (client->mode == MODE_UNKNOWN || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); - error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n"); + logger(LL_ERROR, "Unable to discover device mode. Please make sure a device is attached.\n"); return -1; } - info("Found device in %s mode\n", client->mode->string); + logger(LL_INFO, "Found device in %s mode\n", client->mode->string); mutex_unlock(&client->device_event_mutex); } } @@ -707,39 +711,39 @@ int idevicerestore_start(struct idevicerestore_client_t* client) unsigned int prev = 0; if (dfu_get_bdid(client, &pdfu_bdid) < 0) { - error("ERROR: Failed to get bdid for Port DFU device!\n"); + logger(LL_ERROR, "Failed to get bdid for Port DFU device!\n"); return -1; } if (dfu_get_cpid(client, &pdfu_cpid) < 0) { - error("ERROR: Failed to get cpid for Port DFU device!\n"); + logger(LL_ERROR, "Failed to get cpid for Port DFU device!\n"); return -1; } if (dfu_get_prev(client, &prev) < 0) { - error("ERROR: Failed to get PREV for Port DFU device!\n"); + logger(LL_ERROR, "Failed to get PREV for Port DFU device!\n"); return -1; } unsigned char* pdfu_nonce = NULL; unsigned int pdfu_nsize = 0; if (dfu_get_portdfu_nonce(client, &pdfu_nonce, &pdfu_nsize) < 0) { - error("ERROR: Failed to get nonce for Port DFU device!\n"); + logger(LL_ERROR, "Failed to get nonce for Port DFU device!\n"); return -1; } plist_t build_identity = build_manifest_get_build_identity_for_model_with_variant(client->build_manifest, client->device->hardware_model, RESTORE_VARIANT_ERASE_INSTALL, 0); if (!build_identity) { - error("ERORR: Failed to get build identity\n"); + logger(LL_ERROR, "ERORR: Failed to get build identity\n"); return -1; } unsigned int b_pdfu_cpid = (unsigned int)plist_dict_get_uint(build_identity, "USBPortController1,ChipID"); if (b_pdfu_cpid != pdfu_cpid) { - error("ERROR: cpid 0x%02x doesn't match USBPortController1,ChipID in build identity (0x%02x)\n", pdfu_cpid, b_pdfu_cpid); + logger(LL_ERROR, "cpid 0x%02x doesn't match USBPortController1,ChipID in build identity (0x%02x)\n", pdfu_cpid, b_pdfu_cpid); return -1; } unsigned int b_pdfu_bdid = (unsigned int)plist_dict_get_uint(build_identity, "USBPortController1,BoardID"); if (b_pdfu_bdid != pdfu_bdid) { - error("ERROR: bdid 0x%x doesn't match USBPortController1,BoardID in build identity (0x%x)\n", pdfu_bdid, b_pdfu_bdid); + logger(LL_ERROR, "bdid 0x%x doesn't match USBPortController1,BoardID in build identity (0x%x)\n", pdfu_bdid, b_pdfu_bdid); return -1; } @@ -754,26 +758,26 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_t usbf = plist_access_path(build_identity, 2, "Manifest", "USBPortController1,USBFirmware"); if (!usbf) { plist_free(parameters); - error("ERROR: Unable to find USBPortController1,USBFirmware in build identity\n"); + logger(LL_ERROR, "Unable to find USBPortController1,USBFirmware in build identity\n"); return -1; } plist_t p_fwpath = plist_access_path(usbf, 2, "Info", "Path"); if (!p_fwpath) { plist_free(parameters); - error("ERROR: Unable to find path of USBPortController1,USBFirmware component\n"); + logger(LL_ERROR, "Unable to find path of USBPortController1,USBFirmware component\n"); return -1; } const char* fwpath = plist_get_string_ptr(p_fwpath, NULL); if (!fwpath) { plist_free(parameters); - error("ERROR: Unable to get path of USBPortController1,USBFirmware component\n"); + logger(LL_ERROR, "Unable to get path of USBPortController1,USBFirmware component\n"); return -1; } unsigned char* uarp_buf = NULL; unsigned int uarp_size = 0; if (ipsw_extract_to_memory(client->ipsw, fwpath, &uarp_buf, &uarp_size) < 0) { plist_free(parameters); - error("ERROR: Unable to extract '%s' from IPSW\n", fwpath); + logger(LL_ERROR, "Unable to extract '%s' from IPSW\n", fwpath); return -1; } usbf = plist_copy(usbf); @@ -784,7 +788,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_t request = tss_request_new(NULL); if (request == NULL) { plist_free(parameters); - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); return -1; } plist_dict_merge(&request, parameters); @@ -794,16 +798,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_t response = tss_request_send(request, client->tss_url); plist_free(request); if (response == NULL) { - error("ERROR: Unable to send TSS request\n"); + logger(LL_ERROR, "Unable to send TSS request\n"); return -1; } - info("Received USBPortController1,Ticket\n"); + logger(LL_INFO, "Received USBPortController1,Ticket\n"); - info("Creating Ace3Binary\n"); + logger(LL_INFO, "Creating Ace3Binary\n"); unsigned char* ace3bin = NULL; size_t ace3bin_size = 0; if (ace3_create_binary(uarp_buf, uarp_size, pdfu_bdid, prev, response, &ace3bin, &ace3bin_size) < 0) { - error("ERROR: Could not create Ace3Binary\n"); + logger(LL_ERROR, "Could not create Ace3Binary\n"); return -1; } plist_free(response); @@ -814,37 +818,37 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } if (dfu_send_buffer_with_options(client, ace3bin, ace3bin_size, IRECV_SEND_OPT_DFU_NOTIFY_FINISH | IRECV_SEND_OPT_DFU_SMALL_PKT) < 0) { - error("ERROR: Could not send Ace3Buffer to device\n"); + logger(LL_ERROR, "Could not send Ace3Buffer to device\n"); return -1; } - debug("Waiting for device to disconnect...\n"); + logger(LL_DEBUG, "Waiting for device to disconnect...\n"); cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 5000); if (client->mode != MODE_UNKNOWN || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); if (!(client->flags & FLAG_QUIT)) { - error("ERROR: Device did not disconnect. Port DFU failed.\n"); + logger(LL_ERROR, "Device did not disconnect. Port DFU failed.\n"); } return -2; } dfu_client_free(client); - debug("Waiting for device to reconnect in DFU mode...\n"); + logger(LL_DEBUG, "Waiting for device to reconnect in DFU mode...\n"); cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 20000); if (client->mode != MODE_DFU || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); if (!(client->flags & FLAG_QUIT)) { - error("ERROR: Device did not reconnect in DFU mode. Port DFU failed.\n"); + logger(LL_ERROR, "Device did not reconnect in DFU mode. Port DFU failed.\n"); } return -2; } mutex_unlock(&client->device_event_mutex); if (client->flags & FLAG_NOACTION) { - info("Port DFU restore successful.\n"); + logger(LL_INFO, "Port DFU restore successful.\n"); return 0; } else { - info("Port DFU restore successful. Continuing.\n"); + logger(LL_INFO, "Port DFU restore successful. Continuing.\n"); } } @@ -852,18 +856,18 @@ int idevicerestore_start(struct idevicerestore_client_t* client) /* check if device type is supported by the given build manifest */ if (build_manifest_check_compatibility(client->build_manifest, client->device->product_type) < 0) { - error("ERROR: Could not make sure this firmware is suitable for the current device. Refusing to continue.\n"); + logger(LL_ERROR, "Could not make sure this firmware is suitable for the current device. Refusing to continue.\n"); return -1; } /* print iOS information from the manifest */ build_manifest_get_version_information(client->build_manifest, client); - info("IPSW Product Version: %s\n", client->version); - info("IPSW Product Build: %s Major: %d\n", client->build, client->build_major); + logger(LL_INFO, "IPSW Product Version: %s\n", client->version); + logger(LL_INFO, "IPSW Product Build: %s Major: %d\n", client->build, client->build_major); client->image4supported = is_image4_supported(client); - info("Device supports Image4: %s\n", (client->image4supported) ? "true" : "false"); + logger(LL_INFO, "Device supports Image4: %s\n", (client->image4supported) ? "true" : "false"); // choose whether this is an upgrade or a restore (default to upgrade) client->tss = NULL; @@ -897,7 +901,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) char *fmanifest = NULL; uint32_t msize = 0; if (ipsw_extract_to_memory(client->ipsw, tmpstr, (unsigned char**)&fmanifest, &msize) < 0) { - error("ERROR: could not extract %s from IPSW\n", tmpstr); + logger(LL_ERROR, "could not extract %s from IPSW\n", tmpstr); free(build_identity); return -1; } @@ -930,7 +934,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_dict_set_item(manifest, "RestoreDeviceTree", plist_copy(comp)); } } else { - error("WARNING: unhandled component %s\n", files[x]); + logger(LL_WARNING, "Unhandled component %s\n", files[x]); plist_free(comp); } free(files[x]); @@ -1000,11 +1004,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // add OS filesystem node = plist_dict_get_item(client->build_manifest, "SystemRestoreImages"); if (!node) { - error("ERROR: missing SystemRestoreImages in Restore.plist\n"); + logger(LL_ERROR, "missing SystemRestoreImages in Restore.plist\n"); } plist_t os = plist_dict_get_item(node, "User"); if (!os) { - error("ERROR: missing filesystem in Restore.plist\n"); + logger(LL_ERROR, "missing filesystem in Restore.plist\n"); } else { inf = plist_new_dict(); plist_dict_set_item(inf, "Path", plist_copy(os)); @@ -1033,7 +1037,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } } if (build_identity == NULL) { - error("ERROR: Unable to find a matching build identity\n"); + logger(LL_ERROR, "Unable to find a matching build identity\n"); return -1; } @@ -1043,47 +1047,37 @@ int idevicerestore_start(struct idevicerestore_client_t* client) build_identity_print_information(build_identity); if (client->macos_variant) { - info("Performing macOS restore\n"); + logger(LL_INFO, "Performing macOS restore\n"); } if (client->mode == MODE_NORMAL && !(client->flags & FLAG_ERASE) && !(client->flags & FLAG_SHSHONLY)) { if (client->device_version && (compare_versions(client->device_version, client->version) > 0)) { if (client->flags & FLAG_INTERACTIVE) { - char input[64]; - char spaces[16]; - int num_spaces = 13 - strlen(client->version) - strlen(client->device_version); - memset(spaces, ' ', num_spaces); - spaces[num_spaces] = '\0'; - printf("################################ [ WARNING ] #################################\n" - "# You are trying to DOWNGRADE a %s device with an IPSW for %s while%s #\n" - "# trying to preserve the user data (Upgrade restore). This *might* work, but #\n" - "# there is a VERY HIGH chance it might FAIL BADLY with COMPLETE DATA LOSS. #\n" - "# Hit CTRL+C now if you want to abort the restore. #\n" - "# If you want to take the risk (and have a backup of your important data!) #\n" - "# type YES and press ENTER to continue. You have been warned. #\n" - "##############################################################################\n", - client->device_version, client->version, spaces); - while (1) { - printf("> "); - fflush(stdout); - fflush(stdin); - input[0] = '\0'; - get_user_input(input, 63, 0); - if (client->flags & FLAG_QUIT) { - return -1; - } - if (*input != '\0' && !strcmp(input, "YES")) { - break; - } else { - printf("Invalid input. Please type YES or hit CTRL+C to abort.\n"); - continue; - } + char msgtext[512]; + snprintf(msgtext, 512, "You are trying to DOWNGRADE a %s device with an IPSW for %s while\n" + "trying to preserve the user data (Upgrade restore). This *might* work, but\n" + "there is a VERY HIGH chance it might FAIL BADLY with COMPLETE DATA LOSS.\n" + "If you want to take the risk (and have a backup of your important data!) you may continue.\n" + "You have been warned.\n", client->device_version, client->version); + int pres = prompt_user("WARNING", msgtext); + if (pres < 0) { + client->flags |= FLAG_QUIT; + return -1; } } } } if (client->flags & FLAG_ERASE && client->flags & FLAG_INTERACTIVE) { + int pres = prompt_user( + "WARNING", + "You are about to perform an *ERASE* restore. ALL DATA on the target device will be IRREVERSIBLY DESTROYED. If you want to update your device without erasing the user data, cancel now and restart without -e or --erase command line switch.\n" + ); + if (pres < 0) { + client->flags |= FLAG_QUIT; + return -1; + } +#if 0 char input[64]; printf("################################ [ WARNING ] #################################\n" "# You are about to perform an *ERASE* restore. ALL DATA on the target device #\n" @@ -1108,22 +1102,23 @@ int idevicerestore_start(struct idevicerestore_client_t* client) continue; } } +#endif } idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.0); /* check if all components we need are actually there */ - info("Checking IPSW for required components...\n"); + logger(LL_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->path); + logger(LL_ERROR, "Could not find all required components in IPSW %s\n", client->ipsw->path); return -1; } - info("All required components found in IPSW\n"); + logger(LL_INFO, "All required components found in IPSW\n"); /* Get OS (filesystem) name from build identity */ char* os_path = NULL; if (build_identity_get_component_path(build_identity, "OS", &os_path) < 0) { - error("ERROR: Unable to get path for filesystem component\n"); + logger(LL_ERROR, "Unable to get path for filesystem component\n"); return -1; } @@ -1168,16 +1163,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client) memset(&st, '\0', sizeof(struct stat)); if (stat(tmpf, &st) == 0) { if ((fssize > 0) && ((uint64_t)st.st_size == fssize)) { - info("Using cached filesystem from '%s'\n", tmpf); + logger(LL_INFO, "Using cached filesystem from '%s'\n", tmpf); client->filesystem = tmpf; } } if (!client->filesystem) { - info("Extracting filesystem from IPSW: %s\n", os_path); + logger(LL_INFO, "Extracting filesystem from IPSW: %s\n", os_path); if (ipsw_extract_to_file_with_progress(client->ipsw, os_path, tmpf, 1) < 0) { - error("ERROR: Unable to extract filesystem from IPSW\n"); - info("Removing %s\n", tmpf); + logger(LL_ERROR, "Unable to extract filesystem from IPSW\n"); + logger(LL_INFO, "Removing %s\n", tmpf); unlink(tmpf); free(tmpf); return -1; @@ -1199,19 +1194,19 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_get_bool_val(node, &needs_preboard); } if (needs_preboard) { - info("Checking if device requires stashbag...\n"); + logger(LL_INFO, "Checking if device requires stashbag...\n"); plist_t manifest; if (get_preboard_manifest(client, build_identity, &manifest) < 0) { - error("ERROR: Unable to create preboard manifest.\n"); + logger(LL_ERROR, "Unable to create preboard manifest.\n"); return -1; } - debug("DEBUG: creating stashbag...\n"); + logger(LL_DEBUG, "creating stashbag...\n"); int err = normal_handle_create_stashbag(client, manifest); if (err < 0) { if (err == -2) { - error("ERROR: Could not create stashbag (timeout).\n"); + logger(LL_ERROR, "Could not create stashbag (timeout).\n"); } else { - error("ERROR: An error occurred while creating the stashbag.\n"); + logger(LL_ERROR, "An error occurred while creating the stashbag.\n"); } return -1; } else if (err == 1) { @@ -1226,7 +1221,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) unsigned int nonce_size = 0; if (get_ap_nonce(client, &nonce, &nonce_size) < 0) { /* the first nonce request with older firmware releases can fail and it's OK */ - info("NOTE: Unable to get nonce from device\n"); + logger(LL_NOTICE, "Unable to get nonce from device\n"); } if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) { @@ -1248,12 +1243,8 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_t p_sep_nonce = plist_dict_get_item(ap_params, "SepNonce"); uint64_t sep_nonce_size = 0; const char* sep_nonce = plist_get_data_ptr(p_sep_nonce, &sep_nonce_size); - info("Getting SepNonce in normal mode... "); - int i = 0; - for (i = 0; i < sep_nonce_size; i++) { - info("%02x ", (unsigned char)sep_nonce[i]); - } - info("\n"); + logger(LL_INFO, "Getting SepNonce in normal mode... "); + logger_dump_hex(LL_INFO, sep_nonce, sep_nonce_size); plist_free(ap_params); } plist_t req_nonce_slot = plist_access_path(build_identity, 2, "Info", "RequiresNonceSlot"); @@ -1270,27 +1261,27 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (client->mode == MODE_RESTORE && client->root_ticket) { plist_t ap_ticket = plist_new_data((char*)client->root_ticket, client->root_ticket_len); if (!ap_ticket) { - error("ERROR: Failed to create ApImg4Ticket node value.\n"); + logger(LL_ERROR, "Failed to create ApImg4Ticket node value.\n"); return -1; } client->tss = plist_new_dict(); if (!client->tss) { - error("ERROR: Failed to create ApImg4Ticket node.\n"); + logger(LL_ERROR, "Failed to create ApImg4Ticket node.\n"); return -1; } plist_dict_set_item(client->tss, "ApImg4Ticket", ap_ticket); } else { if (get_tss_response(client, build_identity, &client->tss) < 0) { - error("ERROR: Unable to get SHSH blobs for this device\n"); + logger(LL_ERROR, "Unable to get SHSH blobs for this device\n"); return -1; } if (client->macos_variant) { if (get_local_policy_tss_response(client, build_identity, &client->tss_localpolicy) < 0) { - error("ERROR: Unable to get SHSH blobs for this device (local policy)\n"); + logger(LL_ERROR, "Unable to get SHSH blobs for this device (local policy)\n"); return -1; } if (get_recoveryos_root_ticket_tss_response(client, build_identity, &client->tss_recoveryos_root_ticket) < 0) { - error("ERROR: Unable to get SHSH blobs for this device (recovery OS Root Ticket)\n"); + logger(LL_ERROR, "Unable to get SHSH blobs for this device (recovery OS Root Ticket)\n"); return -1; } } else { @@ -1299,11 +1290,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client) const char* recovery_variant_str = plist_get_string_ptr(recovery_variant, NULL); client->recovery_variant = build_manifest_get_build_identity_for_model_with_variant(client->build_manifest, client->device->hardware_model, recovery_variant_str, 1); if (!client->recovery_variant) { - error("ERROR: Variant '%s' not found in BuildManifest\n", recovery_variant_str); + logger(LL_ERROR, "Variant '%s' not found in BuildManifest\n", recovery_variant_str); return -1; } if (get_tss_response(client, client->recovery_variant, &client->tss_recoveryos_root_ticket) < 0) { - error("ERROR: Unable to get SHSH blobs for this device (%s)\n", recovery_variant_str); + logger(LL_ERROR, "Unable to get SHSH blobs for this device (%s)\n", recovery_variant_str); return -1; } } @@ -1313,13 +1304,13 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (stashbag_commit_required) { plist_t ticket = plist_dict_get_item(client->tss, "ApImg4Ticket"); if (!ticket || plist_get_node_type(ticket) != PLIST_DATA) { - error("ERROR: Missing ApImg4Ticket in TSS response for stashbag commit\n"); + logger(LL_ERROR, "Missing ApImg4Ticket in TSS response for stashbag commit\n"); return -1; } - info("Committing stashbag...\n"); + logger(LL_INFO, "Committing stashbag...\n"); int err = normal_handle_commit_stashbag(client, ticket); if (err < 0) { - error("ERROR: Could not commit stashbag (%d). Aborting.\n", err); + logger(LL_ERROR, "Could not commit stashbag (%d). Aborting.\n", err); return -1; } } @@ -1330,11 +1321,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } if (client->flags & FLAG_SHSHONLY) { if (!tss_enabled) { - info("This device does not require a TSS record\n"); + logger(LL_INFO, "This device does not require a TSS record\n"); return 0; } if (!client->tss) { - error("ERROR: could not fetch TSS record\n"); + logger(LL_ERROR, "could not fetch TSS record\n"); return -1; } else { char *bin = NULL; @@ -1355,13 +1346,13 @@ int idevicerestore_start(struct idevicerestore_client_t* client) gzFile zf = gzopen(zfn, "wb"); gzwrite(zf, bin, blen); gzclose(zf); - info("SHSH saved to '%s'\n", zfn); + logger(LL_INFO, "SHSH saved to '%s'\n", zfn); } else { - info("SHSH '%s' already present.\n", zfn); + logger(LL_INFO, "SHSH '%s' already present.\n", zfn); } free(bin); } else { - error("ERROR: could not get TSS record data\n"); + logger(LL_ERROR, "could not get TSS record data\n"); } plist_free(client->tss); return 0; @@ -1370,7 +1361,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) /* verify if we have tss records if required */ if ((tss_enabled) && (client->tss == NULL)) { - error("ERROR: Unable to proceed without a TSS record.\n"); + logger(LL_ERROR, "Unable to proceed without a TSS record.\n"); return -1; } @@ -1385,9 +1376,9 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // if the device is in normal mode, place device into recovery mode if (client->mode == MODE_NORMAL) { - info("Entering recovery mode...\n"); + logger(LL_INFO, "Entering recovery mode...\n"); if (normal_enter_recovery(client) < 0) { - error("ERROR: Unable to place device into recovery mode from normal mode\n"); + logger(LL_ERROR, "Unable to place device into recovery mode from normal mode\n"); if (client->tss) plist_free(client->tss); return -5; @@ -1405,22 +1396,22 @@ int idevicerestore_start(struct idevicerestore_client_t* client) recovery_client_free(client); #ifdef HAVE_LIMERA1N if ((client->flags & FLAG_CUSTOM) && limera1n_is_supported(client->device)) { - info("connecting to DFU\n"); + logger(LL_INFO, "connecting to DFU\n"); if (dfu_client_new(client) < 0) { return -1; } - info("exploiting with limera1n\n"); + logger(LL_INFO, "exploiting with limera1n\n"); if (limera1n_exploit(client->device, &client->dfu->client) != 0) { - error("ERROR: limera1n exploit failed\n"); + logger(LL_ERROR, "limera1n exploit failed\n"); dfu_client_free(client); return -1; } dfu_client_free(client); - info("exploited\n"); + logger(LL_INFO, "exploited\n"); } #endif if (dfu_enter_recovery(client, build_identity) < 0) { - error("ERROR: Unable to place device into recovery mode from DFU mode\n"); + logger(LL_ERROR, "Unable to place device into recovery mode from DFU mode\n"); if (client->tss) plist_free(client->tss); return -2; @@ -1431,7 +1422,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (!client->image4supported) { /* send ApTicket */ if (recovery_send_ticket(client) < 0) { - error("ERROR: Unable to send APTicket\n"); + logger(LL_ERROR, "Unable to send APTicket\n"); return -2; } } @@ -1442,28 +1433,28 @@ int idevicerestore_start(struct idevicerestore_client_t* client) /* now we load the iBEC */ if (recovery_send_ibec(client, build_identity) < 0) { mutex_unlock(&client->device_event_mutex); - error("ERROR: Unable to send iBEC\n"); + logger(LL_ERROR, "Unable to send iBEC\n"); return -2; } recovery_client_free(client); - debug("Waiting for device to disconnect...\n"); + logger(LL_DEBUG, "Waiting for device to disconnect...\n"); cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 60000); if (client->mode != MODE_UNKNOWN || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); if (!(client->flags & FLAG_QUIT)) { - error("ERROR: Device did not disconnect. Possibly invalid iBEC. Reset device and try again.\n"); + logger(LL_ERROR, "Device did not disconnect. Possibly invalid iBEC. Reset device and try again.\n"); } return -2; } recovery_client_free(client); - debug("Waiting for device to reconnect in recovery mode...\n"); + logger(LL_DEBUG, "Waiting for device to reconnect in recovery mode...\n"); cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 60000); if (client->mode != MODE_RECOVERY || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); if (!(client->flags & FLAG_QUIT)) { - error("ERROR: Device did not reconnect in recovery mode. Possibly invalid iBEC. Reset device and try again.\n"); + logger(LL_ERROR, "Device did not reconnect in recovery mode. Possibly invalid iBEC. Reset device and try again.\n"); } return -2; } @@ -1480,7 +1471,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) unsigned int nonce_size = 0; int nonce_changed = 0; if (get_ap_nonce(client, &nonce, &nonce_size) < 0) { - error("ERROR: Unable to get nonce from device!\n"); + logger(LL_ERROR, "Unable to get nonce from device!\n"); recovery_send_reset(client); return -2; } @@ -1500,11 +1491,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // Welcome iOS5. We have to re-request the TSS with our nonce. 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"); + logger(LL_ERROR, "Unable to get SHSH blobs for this device\n"); return -1; } if (!client->tss) { - error("ERROR: can't continue without TSS\n"); + logger(LL_ERROR, "can't continue without TSS\n"); return -1; } fixup_tss(client->tss); @@ -1518,7 +1509,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // now finally do the magic to put the device into restore mode if (client->mode == MODE_RECOVERY) { if (recovery_enter_restore(client, build_identity) < 0) { - error("ERROR: Unable to place device into restore mode\n"); + logger(LL_ERROR, "Unable to place device into restore mode\n"); if (client->tss) plist_free(client->tss); return -2; @@ -1529,15 +1520,15 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (client->mode != MODE_RESTORE) { mutex_lock(&client->device_event_mutex); - info("Waiting for device to enter restore mode...\n"); + logger(LL_INFO, "Waiting for device to enter restore mode...\n"); cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 180000); if (client->mode != MODE_RESTORE || (client->flags & FLAG_QUIT)) { mutex_unlock(&client->device_event_mutex); - error("ERROR: Device failed to enter restore mode.\n"); + logger(LL_ERROR, "Device failed to enter restore mode.\n"); if (client->mode == MODE_UNKNOWN) { - error("Make sure that usbmuxd is running.\n"); - } else if (client->mode == MODE_RECOVERY) { - error("Device reconnected in recovery mode, most likely image personalization failed.\n"); + logger(LL_ERROR, "Make sure that usbmuxd is running.\n"); + } else if (client->mode == MODE_RECOVERY || client->mode == MODE_DFU) { + logger(LL_ERROR, "Device reconnected in %s mode, most likely image personalization failed.\n", client->mode->string); } return -1; } @@ -1547,14 +1538,14 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // device is finally in restore mode, let's do this if (client->mode == MODE_RESTORE) { if ((client->flags & FLAG_NO_RESTORE) != 0) { - info("Device is now in restore mode. Exiting as requested.\n"); + logger(LL_INFO, "Device is now in restore mode. Exiting as requested.\n"); return 0; } client->ignore_device_add_events = 1; - info("About to restore device... \n"); + logger(LL_INFO, "About to restore device... \n"); result = restore_device(client, build_identity); if (result < 0) { - error("ERROR: Unable to restore device\n"); + logger(LL_ERROR, "Unable to restore device\n"); return result; } } @@ -1565,18 +1556,18 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (recovery_set_autoboot(client, 1) == 0) { recovery_send_reset(client); } else { - error("Setting auto-boot failed?!\n"); + logger(LL_ERROR, "Setting auto-boot failed?!\n"); } } else { - error("Could not connect to device in recovery mode.\n"); + logger(LL_ERROR, "Could not connect to device in recovery mode.\n"); } } if (result == 0) { - info("DONE\n"); + logger(LL_INFO, "DONE\n"); idevicerestore_progress(client, RESTORE_NUM_STEPS-1, 1.0); } else { - info("RESTORE FAILED\n"); + logger(LL_INFO, "RESTORE FAILED\n"); } if (build_identity_needs_free) @@ -1589,7 +1580,7 @@ struct idevicerestore_client_t* idevicerestore_client_new(void) { struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t)); if (client == NULL) { - error("ERROR: Out of memory\n"); + logger(LL_ERROR, "Out of memory\n"); return NULL; } memset(client, '\0', sizeof(struct idevicerestore_client_t)); @@ -1732,6 +1723,7 @@ static void handle_signal(int sig) { if (idevicerestore_client) { idevicerestore_client->flags |= FLAG_QUIT; + global_quit_flag++; ipsw_cancel(); } } @@ -1742,16 +1734,52 @@ void plain_progress_cb(int step, double step_progress, void* userdata) fflush(stdout); } -int main(int argc, char* argv[]) { +static void plain_progress_func(struct progress_info_entry** progress_info, int count) +{ + int i = 0; + for (i = 0; i < count; i++) { + if (!progress_info[i]) continue; + printf("%s: %5.1f\n", progress_info[i]->label, progress_info[i]->progress); + fflush(stdout); + } +} + +static void tty_print(int level, const char* format, va_list varglist) +{ + switch (level) { + case 0: + cprintf(FG_RED STYLE_BRIGHT); + break; + case 1: + cprintf(FG_YELLOW STYLE_BRIGHT); + break; + case 2: + cprintf(STYLE_BRIGHT); + break; + default: + break; + } + + cvfprintf(stdout, format, varglist); + + cprintf(COLOR_RESET); +} + +int main(int argc, char* argv[]) +{ int opt = 0; int optindex = 0; char* ipsw = NULL; int ipsw_info = 0; int result = 0; + int is_terminal = 0; + const char* logfile = NULL; + + logger_set_print_func(tty_print); struct idevicerestore_client_t* client = idevicerestore_client_new(); if (client == NULL) { - error("ERROR: could not create idevicerestore client\n"); + logger(LL_ERROR, "Could not create idevicerestore client\n"); return EXIT_FAILURE; } @@ -1776,6 +1804,7 @@ int main(int argc, char* argv[]) { client->flags &= ~FLAG_INTERACTIVE; } else { client->flags |= FLAG_INTERACTIVE; + is_terminal = 1; } #ifdef HAVE_LIMERA1N @@ -1793,6 +1822,9 @@ int main(int argc, char* argv[]) { case 'd': client->flags |= FLAG_DEBUG; client->debug_level++; + if (client->debug_level > 0) { + log_level = LL_DEBUG; + } break; case 'e': @@ -1805,7 +1837,7 @@ int main(int argc, char* argv[]) { case 's': { if (!*optarg) { - error("ERROR: URL argument for --server must not be empty!\n"); + logger(LL_ERROR, "URL argument for --server must not be empty!\n"); usage(argc, argv, 1); return EXIT_FAILURE; } @@ -1828,7 +1860,7 @@ int main(int argc, char* argv[]) { client->tss_url = strdup(optarg); } } else { - error("ERROR: URL argument for --server is invalid, must start with http:// or https://\n"); + logger(LL_ERROR, "URL argument for --server is invalid, must start with http:// or https://\n"); usage(argc, argv, 1); return EXIT_FAILURE; } @@ -1851,7 +1883,7 @@ int main(int argc, char* argv[]) { client->ecid = 0; } if (client->ecid == 0) { - error("ERROR: Could not parse ECID from '%s'\n", optarg); + logger(LL_ERROR, "Could not parse ECID from '%s'\n", optarg); return EXIT_FAILURE; } } @@ -1859,7 +1891,7 @@ int main(int argc, char* argv[]) { case 'u': if (!*optarg) { - error("ERROR: UDID must not be empty!\n"); + logger(LL_ERROR, "UDID must not be empty!\n"); usage(argc, argv, 1); return EXIT_FAILURE; } @@ -1894,6 +1926,8 @@ int main(int argc, char* argv[]) { case 'P': idevicerestore_set_progress_callback(client, plain_progress_cb, NULL); + set_update_progress_func(plain_progress_func); + set_progress_granularity(0.01); // 1% granularity break; case 'R': @@ -1905,7 +1939,7 @@ int main(int argc, char* argv[]) { break; case 'v': - info("%s %s (libirecovery %s, libtatsu %s)\n", PACKAGE_NAME, PACKAGE_VERSION, irecv_version(), libtatsu_version()); + printf("%s %s (libirecovery %s, libtatsu %s)\n", PACKAGE_NAME, PACKAGE_VERSION, irecv_version(), libtatsu_version()); return EXIT_SUCCESS; case 'T': { @@ -1916,7 +1950,7 @@ int main(int argc, char* argv[]) { } client->root_ticket = root_ticket; client->root_ticket_len = (int)root_ticket_len; - info("Using ApTicket found at %s length %u\n", optarg, client->root_ticket_len); + logger(LL_INFO, "Using ApTicket found at %s length %u\n", optarg, client->root_ticket_len); break; } @@ -1933,6 +1967,15 @@ int main(int argc, char* argv[]) { client->restore_variant = strdup(optarg); break; + case 3: + if (!*optarg) { + logger(LL_ERROR, "logfile must not be empty!\n"); + usage(argc, argv, 1); + return EXIT_FAILURE; + } + logfile = optarg; + break; + default: usage(argc, argv, 1); return EXIT_FAILURE; @@ -1941,7 +1984,7 @@ int main(int argc, char* argv[]) { if (ipsw_info) { if (argc-optind != 1) { - error("ERROR: --ipsw-info requires an IPSW path.\n"); + logger(LL_ERROR, "--ipsw-info requires an IPSW path.\n"); usage(argc, argv, 1); return EXIT_FAILURE; } @@ -1959,24 +2002,41 @@ int main(int argc, char* argv[]) { } if ((client->flags & FLAG_LATEST) && (client->flags & FLAG_CUSTOM)) { - error("ERROR: You can't use --custom and --latest options at the same time.\n"); + logger(LL_ERROR, "You can't use --custom and --latest options at the same time.\n"); return EXIT_FAILURE; } - info("%s %s (libirecovery %s, libtatsu %s)\n", PACKAGE_NAME, PACKAGE_VERSION, irecv_version(), libtatsu_version()); + if (!logfile) { + char logfn[256]; + int64_t timestamp = time(NULL); + if (client->ecid) { + snprintf(logfn, sizeof(logfn), "restore_%016" PRIx64 "_%" PRIi64 ".log", client->ecid, timestamp); + } else if (client->udid) { + snprintf(logfn, sizeof(logfn), "restore_%s_%" PRIi64 ".log", client->udid, timestamp); + } else { + snprintf(logfn, sizeof(logfn), "restore_%" PRIi64 ".log", timestamp); + } + logger_set_logfile(logfn); + } else { + logger_set_logfile(logfile); + } + + logger(LL_INFO, "%s %s (libirecovery %s, libtatsu %s)\n", PACKAGE_NAME, PACKAGE_VERSION, irecv_version(), libtatsu_version()); if (ipsw) { // verify if ipsw file exists client->ipsw = ipsw_open(ipsw); if (!client->ipsw) { - error("ERROR: Firmware file %s cannot be opened.\n", ipsw); + logger(LL_ERROR, "Firmware file %s cannot be opened.\n", ipsw); return -1; } } curl_global_init(CURL_GLOBAL_ALL); + client->flags |= FLAG_IN_PROGRESS; result = idevicerestore_start(client); + client->flags &= ~FLAG_IN_PROGRESS; idevicerestore_client_free(client); @@ -2034,7 +2094,7 @@ int is_image4_supported(struct idevicerestore_client_t* client) res = recovery_is_image4_supported(client); break; default: - error("ERROR: Device is in an invalid state\n"); + logger(LL_ERROR, "Device is in an invalid state\n"); return 0; } return res; @@ -2047,7 +2107,7 @@ int get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, *nonce = NULL; *nonce_size = 0; - info("Getting ApNonce "); + logger(LL_INFO, "Getting ApNonce "); if (client->mode) { mode = client->mode->index; @@ -2055,38 +2115,34 @@ int get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, switch (mode) { case _MODE_NORMAL: - info("in normal mode... "); + logger(LL_INFO, "Getting ApNonce in Normal mode... "); if (normal_get_ap_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; case _MODE_DFU: - info("in dfu mode... "); + logger(LL_INFO, "Getting ApNonce in DFU mode... "); if (dfu_get_ap_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; case _MODE_RECOVERY: - info("in recovery mode... "); + logger(LL_INFO, "Getting ApNonce in Recovery mode... "); if (recovery_get_ap_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; default: - info("failed\n"); - error("ERROR: Device is in an invalid state\n"); + logger(LL_INFO, "Getting ApNonce failed\n"); + logger(LL_ERROR, "Device is in an invalid state\n"); return -1; } - int i = 0; - for (i = 0; i < *nonce_size; i++) { - info("%02x ", (*nonce)[i]); - } - info("\n"); + logger_dump_hex(LL_INFO, *nonce, *nonce_size); return 0; } @@ -2098,7 +2154,7 @@ int get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, *nonce = NULL; *nonce_size = 0; - info("Getting SepNonce "); + logger(LL_INFO, "Getting SepNonce "); if (client->mode) { mode = client->mode->index; @@ -2106,38 +2162,34 @@ int get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, switch (mode) { case _MODE_NORMAL: - info("in normal mode... "); + logger(LL_INFO, "in normal mode... "); if (normal_get_sep_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; case _MODE_DFU: - info("in dfu mode... "); + logger(LL_INFO, "in dfu mode... "); if (dfu_get_sep_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; case _MODE_RECOVERY: - info("in recovery mode... "); + logger(LL_INFO, "in recovery mode... "); if (recovery_get_sep_nonce(client, nonce, nonce_size) < 0) { - info("failed\n"); + logger(LL_INFO, "failed\n"); return -1; } break; default: - info("failed\n"); - error("ERROR: Device is in an invalid state\n"); + logger(LL_INFO, "failed\n"); + logger(LL_ERROR, "Device is in an invalid state\n"); return -1; } - int i = 0; - for (i = 0; i < *nonce_size; i++) { - info("%02x ", (*nonce)[i]); - } - info("\n"); + logger_dump_hex(LL_INFO, *nonce, *nonce_size); return 0; } @@ -2146,7 +2198,7 @@ plist_t build_manifest_get_build_identity_for_model_with_variant(plist_t build_m { plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); if (!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { - error("ERROR: Unable to find build identities node\n"); + logger(LL_ERROR, "Unable to find build identities node\n"); return NULL; } @@ -2222,14 +2274,14 @@ int get_preboard_manifest(struct idevicerestore_client_t* client, plist_t build_ /* create basic request */ request = tss_request_new(NULL); if (request == NULL) { - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); plist_free(parameters); return -1; } /* add common tags from manifest */ if (tss_request_add_common_tags(request, parameters, overrides) < 0) { - error("ERROR: Unable to add common tags\n"); + logger(LL_ERROR, "Unable to add common tags\n"); plist_free(request); plist_free(parameters); return -1; @@ -2239,7 +2291,7 @@ int get_preboard_manifest(struct idevicerestore_client_t* client, plist_t build_ /* add tags from manifest */ if (tss_request_add_ap_tags(request, parameters, NULL) < 0) { - error("ERROR: Unable to add ap tags\n"); + logger(LL_ERROR, "Unable to add ap tags\n"); plist_free(request); plist_free(parameters); return -1; @@ -2264,7 +2316,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident *tss = NULL; if ((client->build_major <= 8) || (client->flags & FLAG_CUSTOM)) { - error("checking for local shsh\n"); + logger(LL_ERROR, "checking for local shsh\n"); /* first check for local copy */ char zfn[1024]; @@ -2286,7 +2338,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident do { int bytes_read = gzread(zf, p, readsize); if (bytes_read < 0) { - fprintf(stderr, "Error reading gz compressed data\n"); + logger(LL_ERROR, "Error reading gz compressed data\n"); exit(EXIT_FAILURE); } blen += bytes_read; @@ -2311,18 +2363,18 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident free(bin); } } else { - error("no local file %s\n", zfn); + logger(LL_ERROR, "no local file %s\n", zfn); } } else { - error("No version found?!\n"); + logger(LL_ERROR, "No version found?!\n"); } } if (*tss) { - info("Using cached SHSH\n"); + logger(LL_INFO, "Using cached SHSH\n"); return 0; } else { - info("Trying to fetch new SHSH blob\n"); + logger(LL_INFO, "Trying to fetch new SHSH blob\n"); } /* populate parameters */ @@ -2357,14 +2409,14 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident /* create basic request */ request = tss_request_new(NULL); if (request == NULL) { - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); plist_free(parameters); return -1; } /* add common tags from manifest */ if (tss_request_add_common_tags(request, parameters, NULL) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2372,7 +2424,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident /* add tags from manifest */ if (tss_request_add_ap_tags(request, parameters, NULL) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2381,7 +2433,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident if (client->image4supported) { /* add personalized parameters */ if (tss_request_add_ap_img4_tags(request, parameters) < 0) { - error("ERROR: Unable to add img4 tags to TSS request\n"); + logger(LL_ERROR, "Unable to add img4 tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2389,7 +2441,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident } else { /* add personalized parameters */ if (tss_request_add_ap_img3_tags(request, parameters) < 0) { - error("ERROR: Unable to add img3 tags to TSS request\n"); + logger(LL_ERROR, "Unable to add img3 tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2432,13 +2484,13 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident /* send request and grab response */ response = tss_request_send(request, client->tss_url); if (response == NULL) { - info("ERROR: Unable to send TSS request\n"); + logger(LL_INFO, "ERROR: Unable to send TSS request\n"); plist_free(request); plist_free(parameters); return -1; } - info("Received SHSH blobs\n"); + logger(LL_INFO, "Received SHSH blobs\n"); plist_free(request); plist_free(parameters); @@ -2492,7 +2544,7 @@ int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* clie /* Adds @HostPlatformInfo, @VersionInfo, @UUID */ request = tss_request_new(NULL); if (request == NULL) { - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); plist_free(parameters); return -1; } @@ -2500,7 +2552,7 @@ int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* clie /* add common tags from manifest */ /* Adds Ap,OSLongVersion, ApNonce, @ApImg4Ticket */ if (tss_request_add_ap_img4_tags(request, parameters) < 0) { - error("ERROR: Unable to add AP IMG4 tags to TSS request\n"); + logger(LL_ERROR, "Unable to add AP IMG4 tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2508,7 +2560,7 @@ int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* clie /* add AP tags from manifest */ if (tss_request_add_common_tags(request, parameters, NULL) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2517,7 +2569,7 @@ int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* clie /* add AP tags from manifest */ /* Fills digests & co */ if (tss_request_add_ap_recovery_tags(request, parameters, NULL) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2526,14 +2578,14 @@ int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* clie /* send request and grab response */ response = tss_request_send(request, client->tss_url); if (response == NULL) { - info("ERROR: Unable to send TSS request\n"); + logger(LL_INFO, "ERROR: Unable to send TSS request\n"); plist_free(request); plist_free(parameters); return -1; } // request_add_ap_tags - info("Received SHSH blobs\n"); + logger(LL_INFO, "Received SHSH blobs\n"); plist_free(request); plist_free(parameters); @@ -2585,7 +2637,7 @@ int get_recovery_os_local_policy_tss_response( unsigned int vuuid[16]; unsigned char vol_uuid[16]; if (sscanf(vol_uuid_str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", &vuuid[0], &vuuid[1], &vuuid[2], &vuuid[3], &vuuid[4], &vuuid[5], &vuuid[6], &vuuid[7], &vuuid[8], &vuuid[9], &vuuid[10], &vuuid[11], &vuuid[12], &vuuid[13], &vuuid[14], &vuuid[15]) != 16) { - error("ERROR: Failed to parse Ap,VolumeUUID (%s)\n", vol_uuid_str); + logger(LL_ERROR, "Failed to parse Ap,VolumeUUID (%s)\n", vol_uuid_str); free(vol_uuid_str); return -1; } @@ -2599,14 +2651,14 @@ int get_recovery_os_local_policy_tss_response( /* create basic request */ request = tss_request_new(NULL); if (request == NULL) { - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); plist_free(parameters); return -1; } /* add common tags from manifest */ if (tss_request_add_local_policy_tags(request, parameters) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2615,13 +2667,13 @@ int get_recovery_os_local_policy_tss_response( /* send request and grab response */ response = tss_request_send(request, client->tss_url); if (response == NULL) { - info("ERROR: Unable to send TSS request\n"); + logger(LL_INFO, "ERROR: Unable to send TSS request\n"); plist_free(request); plist_free(parameters); return -1; } - info("Received SHSH blobs\n"); + logger(LL_INFO, "Received SHSH blobs\n"); plist_free(request); plist_free(parameters); @@ -2684,14 +2736,14 @@ int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_ /* create basic request */ request = tss_request_new(NULL); if (request == NULL) { - error("ERROR: Unable to create TSS request\n"); + logger(LL_ERROR, "Unable to create TSS request\n"); plist_free(parameters); return -1; } /* add common tags from manifest */ if (tss_request_add_local_policy_tags(request, parameters) < 0) { - error("ERROR: Unable to add common tags to TSS request\n"); + logger(LL_ERROR, "Unable to add common tags to TSS request\n"); plist_free(request); plist_free(parameters); return -1; @@ -2700,13 +2752,13 @@ int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_ /* send request and grab response */ response = tss_request_send(request, client->tss_url); if (response == NULL) { - info("ERROR: Unable to send TSS request\n"); + logger(LL_INFO, "ERROR: Unable to send TSS request\n"); plist_free(request); plist_free(parameters); return -1; } - info("Received SHSH blobs\n"); + logger(LL_INFO, "Received SHSH blobs\n"); plist_free(request); plist_free(parameters); @@ -2751,7 +2803,7 @@ int build_manifest_get_identity_count(plist_t build_manifest) // fetch build identities array from BuildManifest plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); if (!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { - error("ERROR: Unable to find build identities node\n"); + logger(LL_ERROR, "Unable to find build identities node\n"); return -1; } return plist_array_get_size(build_identities_array); @@ -2770,9 +2822,9 @@ int extract_component(ipsw_archive_t ipsw, const char* path, unsigned char** com else component_name = (char*) path; - info("Extracting %s (%s)...\n", component_name, path); + logger(LL_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->path); + logger(LL_ERROR, "Unable to extract %s from %s\n", component_name, ipsw->path); return -1; } @@ -2792,17 +2844,17 @@ int personalize_component(struct idevicerestore_client_t* client, const char *co } else { /* try to get blob for current component from tss response */ if (tss_response && tss_response_get_blob_by_entry(tss_response, component_name, &component_blob) < 0) { - debug("NOTE: No SHSH blob found for component %s\n", component_name); + logger(LL_DEBUG, "NOTE: No SHSH blob found for component %s\n", component_name); } if (component_blob != NULL) { if (img3_stitch_component(component_name, component_data, component_size, component_blob, 64, &stitched_component, &stitched_component_size) < 0) { - error("ERROR: Unable to replace %s IMG3 signature\n", component_name); + logger(LL_ERROR, "Unable to replace %s IMG3 signature\n", component_name); free(component_blob); return -1; } } else { - info("Not personalizing component %s...\n", component_name); + logger(LL_INFO, "Not personalizing component %s...\n", component_name); stitched_component = (unsigned char*)malloc(component_size); if (stitched_component) { stitched_component_size = component_size; @@ -2826,9 +2878,9 @@ int build_manifest_check_compatibility(plist_t build_manifest, const char* produ int res = -1; plist_t node = plist_dict_get_item(build_manifest, "SupportedProductTypes"); if (!node || (plist_get_node_type(node) != PLIST_ARRAY)) { - debug("%s: ERROR: SupportedProductTypes key missing\n", __func__); - debug("%s: WARNING: If attempting to install iPhoneOS 2.x, be advised that Restore.plist does not contain the", __func__); - debug("%s: WARNING: key 'SupportedProductTypes'. Recommendation is to manually add it to the Restore.plist.", __func__); + logger(LL_DEBUG, "%s: ERROR: SupportedProductTypes key missing\n", __func__); + logger(LL_DEBUG, "%s: WARNING: If attempting to install iPhoneOS 2.x, be advised that Restore.plist does not contain the\n", __func__); + logger(LL_DEBUG, "%s: WARNING: key 'SupportedProductTypes'. Recommendation is to manually add it to the Restore.plist.\n", __func__); return -1; } uint32_t pc = plist_array_get_size(node); @@ -2856,14 +2908,14 @@ void build_manifest_get_version_information(plist_t build_manifest, struct idevi node = plist_dict_get_item(build_manifest, "ProductVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { - error("ERROR: Unable to find ProductVersion node\n"); + logger(LL_ERROR, "Unable to find ProductVersion node\n"); return; } plist_get_string_val(node, &client->version); node = plist_dict_get_item(build_manifest, "ProductBuildVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { - error("ERROR: Unable to find ProductBuildVersion node\n"); + logger(LL_ERROR, "Unable to find ProductBuildVersion node\n"); return; } plist_get_string_val(node, &client->build); @@ -2879,25 +2931,25 @@ void build_identity_print_information(plist_t build_identity) info_node = plist_dict_get_item(build_identity, "Info"); if (!info_node || plist_get_node_type(info_node) != PLIST_DICT) { - error("ERROR: Unable to find Info node\n"); + logger(LL_ERROR, "Unable to find Info node\n"); return; } node = plist_dict_get_item(info_node, "Variant"); if (!node || plist_get_node_type(node) != PLIST_STRING) { - error("ERROR: Unable to find Variant node\n"); + logger(LL_ERROR, "Unable to find Variant node\n"); return; } plist_get_string_val(node, &value); - info("Variant: %s\n", value); + logger(LL_INFO, "Variant: %s\n", value); if (strstr(value, RESTORE_VARIANT_UPGRADE_INSTALL)) - info("This restore will update the device without erasing user data.\n"); + logger(LL_INFO, "This restore will update the device without erasing user data.\n"); else if (strstr(value, RESTORE_VARIANT_ERASE_INSTALL)) - info("This restore will erase all device data.\n"); + logger(LL_INFO, "This restore will erase all device data.\n"); else - info("Unknown Variant '%s'\n", value); + logger(LL_INFO, "Unknown Variant '%s'\n", value); free(value); @@ -2927,7 +2979,7 @@ int build_identity_check_components_in_ipsw(plist_t build_identity, ipsw_archive plist_get_string_val(path, &comp_path); if (comp_path) { if (!ipsw_file_exists(ipsw, comp_path)) { - error("ERROR: %s file %s not found in IPSW\n", key, comp_path); + logger(LL_ERROR, "%s file %s not found in IPSW\n", key, comp_path); res = -1; } free(comp_path); @@ -2960,7 +3012,7 @@ int build_identity_get_component_path(plist_t build_identity, const char* compon plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { - error("ERROR: Unable to find manifest node\n"); + logger(LL_ERROR, "Unable to find manifest node\n"); if (filename) free(filename); return -1; @@ -2968,7 +3020,7 @@ int build_identity_get_component_path(plist_t build_identity, const char* compon plist_t component_node = plist_dict_get_item(manifest_node, component); if (!component_node || plist_get_node_type(component_node) != PLIST_DICT) { - error("ERROR: Unable to find component node for %s\n", component); + logger(LL_ERROR, "Unable to find component node for %s\n", component); if (filename) free(filename); return -1; @@ -2976,7 +3028,7 @@ int build_identity_get_component_path(plist_t build_identity, const char* compon plist_t component_info_node = plist_dict_get_item(component_node, "Info"); if (!component_info_node || plist_get_node_type(component_info_node) != PLIST_DICT) { - error("ERROR: Unable to find component info node for %s\n", component); + logger(LL_ERROR, "Unable to find component info node for %s\n", component); if (filename) free(filename); return -1; @@ -2984,7 +3036,7 @@ int build_identity_get_component_path(plist_t build_identity, const char* compon plist_t component_info_path_node = plist_dict_get_item(component_info_node, "Path"); if (!component_info_path_node || plist_get_node_type(component_info_path_node) != PLIST_STRING) { - error("ERROR: Unable to find component info path node for %s\n", component); + logger(LL_ERROR, "Unable to find component info path node for %s\n", component); if (filename) free(filename); return -1; @@ -3029,6 +3081,6 @@ const char* get_component_name(const char* filename) } i++; } - error("WARNING: Unhandled component '%s'", filename); + logger(LL_WARNING, "Unhandled component '%s'", filename); return NULL; } |