summaryrefslogtreecommitdiffstats
path: root/src/idevicerestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r--src/idevicerestore.c636
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;
}