summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2025-06-23 14:00:10 +0200
committerGravatar Nikias Bassen2025-06-23 14:00:10 +0200
commit8061f08b4e0a8f0ab5d1548b7e9978f3cc8647a2 (patch)
tree5e01ac6e10a00c065dc5edf80adbd2ee4ce273e3 /src
parenta5905b7f905fc3cc83033ebd963f0dcba071e512 (diff)
downloadidevicerestore-8061f08b4e0a8f0ab5d1548b7e9978f3cc8647a2.tar.gz
idevicerestore-8061f08b4e0a8f0ab5d1548b7e9978f3cc8647a2.tar.bz2
Refactor logging and add logfile support
idevicerestore will now also create a logfile automatically, unless disabled with --logfile=NONE.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/ace3.c8
-rw-r--r--src/asr.c53
-rw-r--r--src/common.c461
-rw-r--r--src/common.h40
-rw-r--r--src/dfu.c110
-rw-r--r--src/download.c37
-rw-r--r--src/fdr.c130
-rw-r--r--src/fls.c18
-rw-r--r--src/ftab.c10
-rw-r--r--src/idevicerestore.c636
-rw-r--r--src/idevicerestore.h4
-rw-r--r--src/img3.c78
-rw-r--r--src/img4.c24
-rw-r--r--src/ipsw.c242
-rw-r--r--src/limera1n.c22
-rw-r--r--src/locking.c12
-rw-r--r--src/log.c210
-rw-r--r--src/log.h41
-rw-r--r--src/mbn.c8
-rw-r--r--src/normal.c116
-rw-r--r--src/recovery.c106
-rw-r--r--src/restore.c1102
23 files changed, 2010 insertions, 1459 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a717b45..2b7084e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ bin_PROGRAMS = idevicerestore
idevicerestore_SOURCES = \
idevicerestore.c idevicerestore.h \
+ log.c log.h \
endianness.h \
common.c common.h \
fls.c fls.h \
diff --git a/src/ace3.c b/src/ace3.c
index a482f6f..9bbc8b6 100644
--- a/src/ace3.c
+++ b/src/ace3.c
@@ -167,7 +167,7 @@ int ace3_create_binary(const unsigned char* uarp_fw, size_t uarp_size, uint64_t
uint64_t boardid = 0;
plist_get_uint_val(p_boardid, &boardid);
if (boardid == bdid) {
- debug("DEBUG: %s: Found Board ID 0x%" PRIx64 "\n", __func__, bdid);
+ logger(LL_DEBUG, "%s: Found Board ID 0x%" PRIx64 "\n", __func__, bdid);
plist_t p4cc = plist_dict_get_item(payload, "Payload 4CC");
plist_get_string_val(p4cc, &payload_4cc);
plist_t matching = plist_dict_get_item(meta, "Personalization Matching Data");
@@ -189,7 +189,7 @@ int ace3_create_binary(const unsigned char* uarp_fw, size_t uarp_size, uint64_t
if (prev >= minrev && prev <= maxrev) {
plist_t tags = plist_dict_get_item(match, "Personalization Matching Data Payload Tags");
plist_get_string_val(tags, &data_payload_4ccs);
- debug("DEBUG: %s: Found matching tags %s\n", __func__, data_payload_4ccs);
+ logger(LL_DEBUG, "%s: Found matching tags %s\n", __func__, data_payload_4ccs);
break;
}
} while (match);
@@ -201,11 +201,11 @@ int ace3_create_binary(const unsigned char* uarp_fw, size_t uarp_size, uint64_t
plist_mem_free(iter);
}
if (!payload_4cc) {
- printf("Failed to get payload 4cc\n");
+ logger(LL_ERROR, "Failed to get payload 4cc\n");
return -1;
}
if (!data_payload_4ccs) {
- printf("Failed to get data payload 4ccs\n");
+ logger(LL_ERROR, "Failed to get data payload 4ccs\n");
return -1;
}
diff --git a/src/asr.c b/src/asr.c
index 15396c4..fba59d9 100644
--- a/src/asr.c
+++ b/src/asr.c
@@ -63,7 +63,7 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port)
if (port == 0) {
port = ASR_DEFAULT_PORT;
}
- debug("Connecting to ASR on port %u\n", port);
+ logger(LL_VERBOSE, "Connecting to ASR on port %u\n", port);
for (i = 1; i <= attempts; i++) {
device_error = idevice_connect(device, port, &connection);
@@ -72,12 +72,12 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port)
}
if (i >= attempts) {
- error("ERROR: Unable to connect to ASR client\n");
+ logger(LL_ERROR, "Unable to connect to ASR client\n");
return -1;
}
sleep(2);
- debug("Retrying connection...\n");
+ logger(LL_VERBOSE, "Retrying connection...\n");
}
asr_client_t asr_loc = (asr_client_t)malloc(sizeof(struct asr_client));
@@ -88,7 +88,7 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port)
plist_t data = NULL;
asr_loc->checksum_chunks = 0;
if (asr_receive(asr_loc, &data) < 0) {
- error("ERROR: Unable to receive data from ASR\n");
+ logger(LL_ERROR, "Unable to receive data from ASR\n");
asr_free(asr_loc);
plist_free(data);
return -1;
@@ -99,8 +99,8 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port)
char* strval = NULL;
plist_get_string_val(node, &strval);
if (strval && (strcmp(strval, "Initiate") != 0)) {
- error("ERROR: unexpected ASR plist received:\n");
- debug_plist(data);
+ logger(LL_ERROR, "Unexpected ASR plist received\n");
+ logger_dump_plist(LL_VERBOSE, data, 1);
plist_free(data);
asr_free(asr_loc);
return -1;
@@ -138,13 +138,13 @@ int asr_receive(asr_client_t asr, plist_t* data)
buffer = (char*)malloc(ASR_BUFFER_SIZE);
if (buffer == NULL) {
- error("ERROR: Unable to allocate memory for ASR receive buffer\n");
+ logger(LL_ERROR, "Unable to allocate memory for ASR receive buffer\n");
return -1;
}
device_error = idevice_connection_receive(asr->connection, buffer, ASR_BUFFER_SIZE, &size);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to receive data from ASR\n");
+ logger(LL_ERROR, "Unable to receive data from ASR\n");
free(buffer);
return -1;
}
@@ -152,9 +152,8 @@ int asr_receive(asr_client_t asr, plist_t* data)
*data = request;
- debug("Received %d bytes:\n", size);
- if (idevicerestore_debug)
- debug_plist(request);
+ logger(LL_DEBUG, "Received %d bytes:\n", size);
+ logger_dump_plist(LL_DEBUG, request, 1);
free(buffer);
return 0;
}
@@ -166,7 +165,7 @@ int asr_send(asr_client_t asr, plist_t data)
plist_to_xml(data, &buffer, &size);
if (asr_send_buffer(asr, buffer, size) < 0) {
- error("ERROR: Unable to send plist to ASR\n");
+ logger(LL_ERROR, "Unable to send plist to ASR\n");
free(buffer);
return -1;
}
@@ -183,7 +182,7 @@ int asr_send_buffer(asr_client_t asr, const char* data, uint32_t size)
device_error = idevice_connection_send(asr->connection, data, size, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != size) {
- error("ERROR: Unable to send data to ASR. Sent %u of %u bytes.\n", bytes, size);
+ logger(LL_ERROR, "Unable to send data to ASR. Sent %u of %u bytes.\n", bytes, size);
return -1;
}
@@ -240,19 +239,19 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file)
// Expected by device after every initiate
if (asr_send_validation_packet_info(asr, length) < 0) {
- error("ERROR: Unable to send validation packet info to ASR\n");
+ logger(LL_ERROR, "Unable to send validation packet info to ASR\n");
return -1;
}
while (1) {
if (asr_receive(asr, &packet) < 0) {
- error("ERROR: Unable to receive validation packet\n");
+ logger(LL_ERROR, "Unable to receive validation packet\n");
return -1;
}
if (packet == NULL) {
if (attempts < 5) {
- info("Retrying to receive validation packet... %d\n", attempts);
+ logger(LL_INFO, "Retrying to receive validation packet... %d\n", attempts);
attempts++;
sleep(1);
continue;
@@ -263,7 +262,7 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file)
node = plist_dict_get_item(packet, "Command");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- error("ERROR: Unable to find command node in validation request\n");
+ logger(LL_ERROR, "Unable to find command node in validation request\n");
return -1;
}
plist_get_string_val(node, &command);
@@ -279,7 +278,7 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file)
// Expected by device after every Initiate
if (asr_send_validation_packet_info(asr, length) < 0) {
- error("ERROR: Unable to send validation packet info to ASR\n");
+ logger(LL_ERROR, "Unable to send validation packet info to ASR\n");
return -1;
}
@@ -297,7 +296,7 @@ int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file)
break;
} else {
- error("ERROR: Unknown command received from ASR\n");
+ logger(LL_ERROR, "Unknown command received from ASR\n");
plist_free(packet);
return -1;
}
@@ -316,38 +315,38 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, ipsw_file_hand
oob_length_node = plist_dict_get_item(packet, "OOB Length");
if (!oob_length_node || PLIST_UINT != plist_get_node_type(oob_length_node)) {
- error("ERROR: Unable to find OOB data length\n");
+ logger(LL_ERROR, "Unable to find OOB data length\n");
return -1;
}
plist_get_uint_val(oob_length_node, &oob_length);
oob_offset_node = plist_dict_get_item(packet, "OOB Offset");
if (!oob_offset_node || PLIST_UINT != plist_get_node_type(oob_offset_node)) {
- error("ERROR: Unable to find OOB data offset\n");
+ logger(LL_ERROR, "Unable to find OOB data offset\n");
return -1;
}
plist_get_uint_val(oob_offset_node, &oob_offset);
oob_data = (char*) malloc(oob_length);
if (oob_data == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
if (ipsw_file_seek(file, oob_offset, SEEK_SET) < 0) {
- error("ERROR: Unable to seek to OOB offset 0x%" PRIx64 "\n", oob_offset);
+ logger(LL_ERROR, "Unable to seek to OOB offset 0x%" PRIx64 "\n", oob_offset);
free(oob_data);
return -1;
}
int64_t ir = ipsw_file_read(file, oob_data, oob_length);
if (ir != oob_length) {
- error("ERROR: Unable to read OOB data from filesystem offset 0x%" PRIx64 ", oob_length %" PRIu64 ", read returned %" PRIi64"\n", oob_offset, oob_length, ir);
+ logger(LL_ERROR, "Unable to read OOB data from filesystem offset 0x%" PRIx64 ", oob_length %" PRIu64 ", read returned %" PRIi64"\n", oob_offset, oob_length, ir);
free(oob_data);
return -1;
}
if (asr_send_buffer(asr, oob_data, oob_length) < 0) {
- error("ERROR: Unable to send OOB data to ASR\n");
+ logger(LL_ERROR, "Unable to send OOB data to ASR\n");
free(oob_data);
return -1;
}
@@ -377,7 +376,7 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file)
}
if (ipsw_file_read(file, data, size) != (int64_t)size) {
- error("Error reading filesystem\n");
+ logger(LL_ERROR, "Error reading filesystem\n");
retry--;
continue;
}
@@ -388,7 +387,7 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file)
sendsize += 20;
}
if (asr_send_buffer(asr, data, sendsize) < 0) {
- error("Unable to send filesystem payload chunk, retrying...\n");
+ logger(LL_ERROR, "Unable to send filesystem payload chunk, retrying...\n");
retry--;
continue;
}
diff --git a/src/common.c b/src/common.c
index c7be4f6..4c99a3a 100644
--- a/src/common.c
+++ b/src/common.c
@@ -36,6 +36,7 @@
#include <fcntl.h>
#include <ctype.h>
#include <libimobiledevice-glue/thread.h>
+#include <libimobiledevice-glue/collection.h>
#ifdef WIN32
#include <windows.h>
@@ -57,6 +58,13 @@
#define MAX_PRINT_LEN 64*1024
+int global_quit_flag = 0;
+static const char* STARS = "******************************************************************************";
+static const char* SPACES = " ";
+static const char* POUNDS = "##############################################################################";
+
+static uint32_t progress_unique_tag = 1;
+
struct idevicerestore_mode_t idevicerestore_modes[] = {
{ 0, "Unknown" },
{ 1, "WTF" },
@@ -69,122 +77,17 @@ struct idevicerestore_mode_t idevicerestore_modes[] = {
int idevicerestore_debug = 0;
-#define idevicerestore_err_buff_size 256
-static char idevicerestore_err_buff[idevicerestore_err_buff_size] = {0, };
-
-static FILE* info_stream = NULL;
-static FILE* error_stream = NULL;
-static FILE* debug_stream = NULL;
-
-static int info_disabled = 0;
-static int error_disabled = 0;
-static int debug_disabled = 0;
-
-static mutex_t log_mutex;
-static thread_once_t init_once = THREAD_ONCE_INIT;
-
-static void _log_init(void)
-{
- mutex_init(&log_mutex);
-}
-
-void info(const char* format, ...)
-{
- if (info_disabled) return;
- thread_once(&init_once, _log_init);
- mutex_lock(&log_mutex);
- va_list vargs;
- va_start(vargs, format);
- vfprintf((info_stream) ? info_stream : stdout, format, vargs);
- va_end(vargs);
- fflush(info_stream?info_stream:stdout);
- mutex_unlock(&log_mutex);
-}
-
-void error(const char* format, ...)
-{
- thread_once(&init_once, _log_init);
- mutex_lock(&log_mutex);
- va_list vargs, vargs2;
- va_start(vargs, format);
- va_copy(vargs2, vargs);
- vsnprintf(idevicerestore_err_buff, idevicerestore_err_buff_size, format, vargs);
- va_end(vargs);
- if (!error_disabled) {
- vfprintf((error_stream) ? error_stream : stderr, format, vargs2);
- }
- va_end(vargs2);
- fflush(error_stream?error_stream:stderr);
- mutex_unlock(&log_mutex);
-}
-
-void debug(const char* format, ...)
-{
- if (debug_disabled) return;
- if (!idevicerestore_debug) {
- return;
- }
- thread_once(&init_once, _log_init);
- mutex_lock(&log_mutex);
- va_list vargs;
- va_start(vargs, format);
- vfprintf((debug_stream) ? debug_stream : stderr, format, vargs);
- va_end(vargs);
- fflush(debug_stream?debug_stream:stderr);
- mutex_unlock(&log_mutex);
-}
-
-void idevicerestore_set_info_stream(FILE* strm)
-{
- if (strm) {
- info_disabled = 0;
- info_stream = strm;
- } else {
- info_disabled = 1;
- }
-}
-
-void idevicerestore_set_error_stream(FILE* strm)
-{
- if (strm) {
- error_disabled = 0;
- error_stream = strm;
- } else {
- error_disabled = 1;
- }
-}
-
-void idevicerestore_set_debug_stream(FILE* strm)
-{
- if (strm) {
- debug_disabled = 0;
- debug_stream = strm;
- } else {
- debug_disabled = 1;
- }
-}
-
-const char* idevicerestore_get_error(void)
-{
- if (idevicerestore_err_buff[0] == 0) {
- return NULL;
- } else {
- char* p = NULL;
- while ((strlen(idevicerestore_err_buff) > 0) && (p = strrchr(idevicerestore_err_buff, '\n'))) {
- p[0] = '\0';
- }
- return (const char*)idevicerestore_err_buff;
- }
-}
+static void (*banner_func)(const char*) = NULL;
+static void (*banner_hide_func)(void) = NULL;
int write_file(const char* filename, const void* data, size_t size) {
size_t bytes = 0;
FILE* file = NULL;
- debug("Writing data to %s\n", filename);
+ logger(LL_DEBUG, "Writing data to %s\n", filename);
file = fopen(filename, "wb");
if (file == NULL) {
- error("write_file: Unable to open file %s\n", filename);
+ logger(LL_ERROR, "write_file: Unable to open file %s\n", filename);
return -1;
}
@@ -192,7 +95,7 @@ int write_file(const char* filename, const void* data, size_t size) {
fclose(file);
if (bytes != size) {
- error("ERROR: Unable to write entire file: %s: %d of %d\n", filename, (int)bytes, (int)size);
+ logger(LL_ERROR, "Unable to write entire file: %s: %d of %d\n", filename, (int)bytes, (int)size);
return -1;
}
@@ -206,26 +109,26 @@ int read_file(const char* filename, void** data, size_t* size) {
char* buffer = NULL;
struct stat fst;
- debug("Reading data from %s\n", filename);
+ logger(LL_DEBUG, "Reading data from %s\n", filename);
*size = 0;
*data = NULL;
file = fopen(filename, "rb");
if (file == NULL) {
- error("read_file: cannot open %s: %s\n", filename, strerror(errno));
+ logger(LL_ERROR, "read_file: cannot open %s: %s\n", filename, strerror(errno));
return -1;
}
if (fstat(fileno(file), &fst) < 0) {
- error("read_file: fstat: %s\n", strerror(errno));
+ logger(LL_ERROR, "read_file: fstat: %s\n", strerror(errno));
return -1;
}
length = fst.st_size;
buffer = (char*) malloc(length);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
fclose(file);
return -1;
}
@@ -233,7 +136,7 @@ int read_file(const char* filename, void** data, size_t* size) {
fclose(file);
if (bytes != length) {
- error("ERROR: Unable to read entire file\n");
+ logger(LL_ERROR, "Unable to read entire file\n");
free(buffer);
return -1;
}
@@ -243,32 +146,309 @@ int read_file(const char* filename, void** data, size_t* size) {
return 0;
}
-void debug_plist(plist_t plist) {
- uint32_t size = 0;
- char* data = NULL;
- plist_to_xml(plist, &data, &size);
- if (size <= MAX_PRINT_LEN)
- info("printing %i bytes plist:\n%s", size, data);
- else
- info("supressed printing %i bytes plist...\n", size);
- free(data);
+int process_text_lines(const char* text, int maxwidth, struct tuple** lines_out, int* maxlen_out)
+{
+ if (!text) return 0;
+ int len = strlen(text);
+ int numlines = 0;
+ int maxlen = 0;
+ int linestart = 0;
+ int linelen = 0;
+ int lastspace = 0;
+ int maxlines = 8;
+ int count = 0;
+ struct tuple* lines = (struct tuple*)malloc(sizeof(struct tuple) * maxlines);
+ int i = 0;
+ while (i <= len) {
+ int split_line = 0;
+ if ((text[i] & 0xE0) == 0xC0) i += 1;
+ else if ((text[i] & 0xF0) == 0xE0) i += 2;
+ else if ((text[i] & 0xF8) == 0xF0) i += 3;
+ if (i > len) i = len;
+ linelen = i - linestart;
+ if (text[i] == '\0') {
+ split_line = 1;
+ }
+ if (linelen > maxwidth) {
+ if (lastspace > linestart+maxwidth/2+6) {
+ count -= i-lastspace;
+ i = lastspace;
+ linelen = i - linestart;
+ split_line = 1;
+ } else {
+ split_line = 1;
+ }
+ }
+ if ((linelen > 0 && split_line) || text[i] == '\n') {
+ split_line = 0;
+ if (numlines == maxlines) {
+ maxlines += 8;
+ struct tuple* newlines = (struct tuple*)realloc(lines, sizeof(struct tuple) * maxlines);
+ if (!newlines) {
+ printf("FATAL: Out of memory\n");
+ return -1;
+ }
+ lines = newlines;
+ }
+ lines[numlines].idx = linestart;
+ lines[numlines].len = linelen;
+ lines[numlines].plen = count;
+ if (count > maxlen) maxlen = count;
+ numlines++;
+ linestart = i+1;
+ count = 0;
+ }
+ else if (text[i] == ' ') {
+ lastspace = i;
+ count++;
+ } else {
+ count++;
+ }
+ i++;
+ }
+ *lines_out = lines;
+ *maxlen_out = maxlen;
+ return numlines;
+}
+
+void set_banner_funcs(void (*showfunc)(const char*), void (*hidefunc)(void))
+{
+ banner_func = showfunc;
+ banner_hide_func = hidefunc;
+}
+
+void show_banner(const char* text)
+{
+ if (banner_func) {
+ banner_func(text);
+ } else {
+ int i;
+ int maxlen = 0;
+ struct tuple* lines = NULL;
+ int numlines = process_text_lines(text, 74, &lines, &maxlen);
+ printf("%.*s\n", maxlen + 4, STARS);
+ for (i = 0; i < numlines; i++) {
+ printf("* %.*s%.*s *\n", lines[i].len, text + lines[i].idx, maxlen-lines[i].plen, SPACES);
+ }
+ printf("%.*s\n", maxlen + 4, STARS);
+ free(lines);
+ }
+}
+
+void hide_banner()
+{
+ if (banner_hide_func) {
+ banner_hide_func();
+ }
+}
+
+static int (*prompt_func)(const char* title, const char* text) = NULL;
+
+void set_prompt_func(int (*func)(const char* title, const char* text))
+{
+ prompt_func = func;
+}
+
+int prompt_user(const char* title, const char* text)
+{
+ if (!text) return -1;
+ if (prompt_func) {
+ return prompt_func(title, text);
+ }
+ int i;
+ int result = 0;
+ int maxlen = 0;
+ struct tuple* lines = NULL;
+ int numlines = process_text_lines(text, 74, &lines, &maxlen);
+ int outerlen = maxlen+4;
+ int titlelen = (title) ? strlen(title) : 0;
+ if (titlelen > 0) {
+ int lefttitlelen = (titlelen+4)/2;
+ int righttitlelen = titlelen+4 - lefttitlelen;
+ int leftpounds = outerlen/2 - lefttitlelen;
+ int rightpounds = outerlen-(titlelen+4) - leftpounds;
+ printf("%.*s[ %.*s ]%.*s\n", leftpounds, POUNDS, titlelen, title, rightpounds, POUNDS);
+ } else {
+ printf("%.*s\n", outerlen, POUNDS);
+ }
+ for (i = 0; i < numlines; i++) {
+ printf("%c %.*s%.*s %c\n", *POUNDS, lines[i].len, text + lines[i].idx, maxlen-lines[i].plen, SPACES, *POUNDS);
+ }
+ free(lines);
+ const char* yesmsg = "Type YES and press ENTER to continue, or hit CTRL+C to cancel.";
+ int ylen = strlen(yesmsg);
+ printf("%c %.*s%.*s %c\n", *POUNDS, ylen, yesmsg, maxlen-ylen, SPACES, *POUNDS);
+ printf("%.*s\n", outerlen, POUNDS);
+
+ char input[64];
+ while (1) {
+ printf("> ");
+ fflush(stdout);
+ fflush(stdin);
+ input[0] = '\0';
+ get_user_input(input, 63, 0);
+ if (global_quit_flag) {
+ result = -1;
+ break;
+ }
+ if (*input != '\0' && !strcmp(input, "YES")) {
+ result = 1;
+ break;
+ } else {
+ printf("Invalid input. Please type YES or hit CTRL+C to abort.\n");
+ continue;
+ }
+ }
+ return result;
+}
+
+static void (*update_progress_func)(struct progress_info_entry** list, int count) = NULL;
+static double progress_granularity = 0.001;
+
+void set_update_progress_func(void (*func)(struct progress_info_entry** list, int count))
+{
+ update_progress_func = func;
+}
+
+void set_progress_granularity(double granularity)
+{
+ progress_granularity = granularity;
+}
+
+mutex_t prog_mutex;
+struct collection progress_info;
+thread_once_t progress_info_once = THREAD_ONCE_INIT;
+static void _init_progress_info(void)
+{
+ mutex_init(&prog_mutex);
+ collection_init(&progress_info);
+}
+
+uint32_t progress_get_next_tag(void)
+{
+ mutex_lock(&prog_mutex);
+ uint32_t newtag = ++progress_unique_tag;
+ mutex_unlock(&prog_mutex);
+ return newtag;
+}
+
+void progress_reset_tag(void)
+{
+ progress_unique_tag = 1;
+}
+
+void register_progress(uint32_t tag, const char* label)
+{
+ thread_once(&progress_info_once, _init_progress_info);
+ if (!label) {
+ return;
+ }
+ mutex_lock(&prog_mutex);
+ struct progress_info_entry* found = NULL;
+ FOREACH(struct progress_info_entry* e, &progress_info) {
+ if (e->tag == tag) {
+ found = e;
+ break;
+ }
+ } ENDFOREACH
+ if (found) {
+ if (strcmp(found->label, label) != 0) {
+ free(found->label);
+ found->label = strdup(label);
+ if (update_progress_func) {
+ update_progress_func((struct progress_info_entry**)(&progress_info)->list, progress_info.capacity);
+ } else {
+ print_progress_bar(found->label, found->progress);
+ }
+ }
+ mutex_unlock(&prog_mutex);
+ return;
+ }
+ struct progress_info_entry* newinfo = (struct progress_info_entry*)calloc(1, sizeof(struct progress_info_entry));
+ if (!newinfo) {
+ logger(LL_ERROR, "Out of memory?!\n");
+ exit(1);
+ }
+ newinfo->tag = tag;
+ newinfo->label = strdup(label);
+ newinfo->progress = 0;
+ collection_add(&progress_info, newinfo);
+ if (update_progress_func) {
+ update_progress_func((struct progress_info_entry**)(&progress_info)->list, progress_info.capacity);
+ } else {
+ print_progress_bar(newinfo->label, newinfo->progress);
+ }
+ mutex_unlock(&prog_mutex);
}
-void print_progress_bar(double progress) {
-#ifndef WIN32
- if (info_disabled) return;
+void finalize_progress(uint32_t tag)
+{
+ mutex_lock(&prog_mutex);
+ struct progress_info_entry* found = NULL;
+ FOREACH(struct progress_info_entry* e, &progress_info) {
+ if (e->tag == tag) {
+ found = e;
+ break;
+ }
+ } ENDFOREACH
+ if (!found) {
+ mutex_unlock(&prog_mutex);
+ return;
+ }
+ collection_remove(&progress_info, found);
+ free(found->label);
+ free(found);
+ if (update_progress_func) {
+ update_progress_func((struct progress_info_entry**)(&progress_info)->list, progress_info.capacity);
+ }
+ mutex_unlock(&prog_mutex);
+}
+
+void print_progress_bar(const char* prefix, double progress)
+{
int i = 0;
- if(progress < 0) return;
- if(progress > 100) progress = 100;
- fprintf((info_stream) ? info_stream : stdout, "\r[");
- for(i = 0; i < 50; i++) {
- if(i < progress / 2) fprintf((info_stream) ? info_stream : stdout, "=");
- else fprintf((info_stream) ? info_stream : stdout, " ");
- }
- fprintf((info_stream) ? info_stream : stdout, "] %5.1f%%", progress);
- if(progress >= 100) fprintf((info_stream) ? info_stream : stdout, "\n");
- fflush((info_stream) ? info_stream : stdout);
-#endif
+ if (progress < 0) return;
+ if (progress > 1) progress = 1;
+ if (prefix) {
+ printf("\r%s [", prefix);
+ } else {
+ printf("\r[");
+ }
+ for (i = 0; i < 50; i++) {
+ if (i < (int)(progress*50.0)) printf("=");
+ else printf(" ");
+ }
+ printf("] %5.1f%% ", progress*100.0);
+ if (progress >= 1) printf("\n");
+ fflush(stdout);
+}
+
+void set_progress(uint32_t tag, double progress)
+{
+ mutex_lock(&prog_mutex);
+ struct progress_info_entry* found = NULL;
+ FOREACH(struct progress_info_entry* e, &progress_info) {
+ if (e->tag == tag) {
+ found = e;
+ break;
+ }
+ } ENDFOREACH
+ if (!found) {
+ mutex_unlock(&prog_mutex);
+ return;
+ }
+ if (progress < 0) progress = 0;
+ if (progress > 1.0) progress = 1.0;
+ found->progress = progress;
+ if ((progress == 0) || (found->progress - found->lastprog >= progress_granularity)) {
+ if (update_progress_func) {
+ update_progress_func((struct progress_info_entry**)(&progress_info)->list, progress_info.capacity);
+ } else {
+ print_progress_bar(found->label, found->progress);
+ }
+ found->lastprog = found->progress;
+ }
+ mutex_unlock(&prog_mutex);
}
#define GET_RAND(min, max) ((rand() % (max - min)) + min)
@@ -485,17 +665,14 @@ char *get_temp_filename(const char *prefix)
void idevicerestore_progress(struct idevicerestore_client_t* client, int step, double progress)
{
- thread_once(&init_once, _log_init);
- mutex_lock(&log_mutex);
if(client && client->progress_cb) {
client->progress_cb(step, progress, client->progress_cb_data);
} else {
// we don't want to be too verbose in regular idevicerestore.
if ((step == RESTORE_STEP_UPLOAD_FS) || (step == RESTORE_STEP_VERIFY_FS) || (step == RESTORE_STEP_FLASH_FW) || (step == RESTORE_STEP_UPLOAD_IMG)) {
- print_progress_bar(100.0 * progress);
+ print_progress_bar(NULL, progress);
}
}
- mutex_unlock(&log_mutex);
}
#ifndef HAVE_STRSEP
diff --git a/src/common.h b/src/common.h
index 872d2f9..08675a2 100644
--- a/src/common.h
+++ b/src/common.h
@@ -40,6 +40,7 @@ extern "C" {
#include <libimobiledevice-glue/thread.h>
#include "idevicerestore.h"
+#include "log.h"
#define _MODE_UNKNOWN 0
#define _MODE_WTF 1
@@ -140,19 +141,42 @@ struct idevicerestore_client_t {
int async_err;
};
+extern int global_quit_flag;
+
extern struct idevicerestore_mode_t idevicerestore_modes[];
extern int idevicerestore_debug;
-__attribute__((format(printf, 1, 2)))
-void info(const char* format, ...);
-__attribute__((format(printf, 1, 2)))
-void error(const char* format, ...);
-__attribute__((format(printf, 1, 2)))
-void debug(const char* format, ...);
+void set_banner_funcs(void (*showfunc)(const char*), void (*hidefunc)(void));
+void show_banner(const char* text);
+void hide_banner();
+
+struct progress_info_entry {
+ uint32_t tag;
+ char* label;
+ double progress;
+ int lastprog;
+};
+void set_update_progress_func(void (*func)(struct progress_info_entry** list, int count));
+void set_progress_granularity(double granularity);
+uint32_t progress_get_next_tag(void);
+void progress_reset_tag(void);
+void register_progress(uint32_t tag, const char* label);
+void set_progress(uint32_t tag, double progress);
+void finalize_progress(uint32_t tag);
+void print_progress_bar(const char* prefix, double progress);
+
+struct tuple {
+ int idx;
+ int len;
+ int plen;
+};
+
+int process_text_lines(const char* text, int maxwidth, struct tuple** lines_out, int* maxlen_out);
+
+void set_prompt_func(int (*func)(const char* title, const char* text));
+int prompt_user(const char* title, const char* message);
-void debug_plist(plist_t plist);
-void print_progress_bar(double progress);
int read_file(const char* filename, void** data, size_t* size);
int write_file(const char* filename, const void* data, size_t size);
diff --git a/src/dfu.c b/src/dfu.c
index 508b4f6..83046b9 100644
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -36,7 +36,7 @@
static int dfu_progress_callback(irecv_client_t client, const irecv_event_t* event) {
if (event->type == IRECV_PROGRESS) {
- print_progress_bar(event->progress);
+ set_progress('DFUP', (double)event->progress/100.0);
}
return 0;
}
@@ -49,24 +49,26 @@ int dfu_client_new(struct idevicerestore_client_t* client)
client->dfu = (struct dfu_client_t*)malloc(sizeof(struct dfu_client_t));
memset(client->dfu, 0, sizeof(struct dfu_client_t));
if (client->dfu == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
}
if (irecv_open_with_ecid_and_attempts(&dfu, client->ecid, 10) != IRECV_E_SUCCESS) {
- error("ERROR: Unable to connect to device in DFU mode\n");
+ logger(LL_ERROR, "Unable to connect to device in DFU mode\n");
return -1;
}
irecv_event_subscribe(dfu, IRECV_PROGRESS, &dfu_progress_callback, NULL);
client->dfu->client = dfu;
+ register_progress('DFUP', "Uploading");
return 0;
}
void dfu_client_free(struct idevicerestore_client_t* client)
{
if(client != NULL) {
+ finalize_progress('DFUP');
if (client->dfu != NULL) {
if(client->dfu->client != NULL) {
irecv_close(client->dfu->client);
@@ -107,11 +109,11 @@ int dfu_send_buffer_with_options(struct idevicerestore_client_t* client, unsigne
{
irecv_error_t err = 0;
- info("Sending data (%d bytes)...\n", size);
+ logger(LL_INFO, "Sending data (%d bytes)...\n", size);
err = irecv_send_buffer(client->dfu->client, buffer, size, irecv_options);
if (err != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send data: %s\n", irecv_strerror(err));
+ logger(LL_ERROR, "Unable to send data: %s\n", irecv_strerror(err));
return -1;
}
@@ -144,19 +146,19 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
} else {
if (tss) {
if (tss_response_get_path_by_entry(tss, component, &path) < 0) {
- debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component);
+ logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build_identity\n", component);
}
}
if (!path) {
if (build_identity_get_component_path(build_identity, component, &path) < 0) {
- error("ERROR: Unable to get path for component '%s'\n", component);
+ logger(LL_ERROR, "Unable to get path for component '%s'\n", component);
free(path);
return -1;
}
}
if (extract_component(client->ipsw, path, &component_data, &component_size) < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
free(path);
return -1;
}
@@ -168,7 +170,7 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
uint32_t size = 0;
if (personalize_component(client, component, component_data, component_size, tss, &data, &size) < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
free(component_data);
return -1;
}
@@ -179,14 +181,14 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
unsigned char* ticket = NULL;
unsigned int tsize = 0;
if (tss_response_get_ap_ticket(client->tss, &ticket, &tsize) < 0) {
- error("ERROR: Unable to get ApTicket from TSS request\n");
+ logger(LL_ERROR, "Unable to get ApTicket from TSS request\n");
return -1;
}
uint32_t fillsize = 0;
if (tsize % 64 != 0) {
fillsize = ((tsize / 64) + 1) * 64;
}
- debug("ticket size = %d\nfillsize = %d\n", tsize, fillsize);
+ logger(LL_DEBUG, "ticket size = %d\nfillsize = %d\n", tsize, fillsize);
unsigned char* newdata = (unsigned char*)malloc(size + fillsize);
memcpy(newdata, ticket, tsize);
memset(newdata + tsize, '\xFF', fillsize - tsize);
@@ -196,11 +198,11 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
size += fillsize;
}
- info("Sending %s (%d bytes)...\n", component, size);
+ logger(LL_INFO, "Sending %s (%d bytes)...\n", component, size);
irecv_error_t err = irecv_send_buffer(client->dfu->client, data, size, IRECV_SEND_OPT_DFU_NOTIFY_FINISH);
if (err != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(err));
+ logger(LL_ERROR, "Unable to send %s component: %s\n", component, irecv_strerror(err));
free(data);
return -1;
}
@@ -366,14 +368,14 @@ int dfu_send_component_and_command(struct idevicerestore_client_t* client, plist
irecv_error_t dfu_error = IRECV_E_SUCCESS;
if (dfu_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
- info("INFO: executing command: %s\n", command);
+ logger(LL_INFO, "INFO: executing command: %s\n", command);
dfu_error = irecv_send_command(client->dfu->client, command);
if (dfu_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", command);
+ logger(LL_ERROR, "Unable to execute %s\n", command);
return -1;
}
@@ -384,10 +386,10 @@ int dfu_send_command(struct idevicerestore_client_t* client, const char* command
{
irecv_error_t dfu_error = IRECV_E_SUCCESS;
- info("INFO: executing command: %s\n", command);
+ logger(LL_INFO, "INFO: executing command: %s\n", command);
dfu_error = irecv_send_command(client->dfu->client, command);
if (dfu_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", command);
+ logger(LL_ERROR, "Unable to execute %s\n", command);
return -1;
}
@@ -398,7 +400,7 @@ int dfu_send_iboot_stage1_components(struct idevicerestore_client_t* client, pli
{
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");
return -1;
}
@@ -422,12 +424,12 @@ int dfu_send_iboot_stage1_components(struct idevicerestore_client_t* client, pli
uint8_t b = 0;
plist_get_bool_val(iboot_node, &b);
if (b) {
- debug("DEBUG: %s is loaded by iBoot Stage 1 and iBoot.\n", key);
+ logger(LL_DEBUG, "%s is loaded by iBoot Stage 1 and iBoot.\n", key);
} else {
- debug("DEBUG: %s is loaded by iBoot Stage 1 but not iBoot...\n", key);
+ logger(LL_DEBUG, "%s is loaded by iBoot Stage 1 but not iBoot...\n", key);
}
if (dfu_send_component_and_command(client, build_identity, key, "firmware") < 0) {
- error("ERROR: Unable to send component '%s' to device.\n", key);
+ logger(LL_ERROR, "Unable to send component '%s' to device.\n", key);
err++;
}
}
@@ -443,14 +445,14 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
int mode = 0;
if (dfu_client_new(client) < 0) {
- error("ERROR: Unable to connect to DFU device\n");
+ logger(LL_ERROR, "Unable to connect to DFU device\n");
return -1;
}
irecv_get_mode(client->dfu->client, &mode);
if (mode != IRECV_K_DFU_MODE) {
- info("NOTE: device is not in DFU mode, assuming recovery mode.\n");
+ logger(LL_NOTICE, "device is not in DFU mode, assuming recovery mode.\n");
client->mode = MODE_RECOVERY;
return 0;
}
@@ -458,7 +460,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
mutex_lock(&client->device_event_mutex);
if (dfu_send_component(client, build_identity, "iBSS") < 0) {
- error("ERROR: Unable to send iBSS to device\n");
+ logger(LL_ERROR, "Unable to send iBSS to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -467,21 +469,21 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (client->build_major > 8) {
/* reconnect */
- 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, 10000);
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 iBSS. Reset device and try again.\n");
+ logger(LL_ERROR, "Device did not disconnect. Possibly invalid iBSS. Reset device and try again.\n");
}
return -1;
}
- debug("Waiting for device to reconnect...\n");
+ logger(LL_DEBUG, "Waiting for device to reconnect...\n");
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
if ((client->mode != MODE_DFU && 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 DFU or recovery mode. Possibly invalid iBSS. Reset device and try again.\n");
+ logger(LL_ERROR, "Device did not reconnect in DFU or recovery mode. Possibly invalid iBSS. Reset device and try again.\n");
}
return -1;
}
@@ -493,7 +495,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
unsigned int nonce_size = 0;
int nonce_changed = 0;
if (dfu_get_ap_nonce(client, &nonce, &nonce_size) < 0) {
- error("ERROR: Unable to get ApNonce from device!\n");
+ logger(LL_ERROR, "Unable to get ApNonce from device!\n");
return -1;
}
@@ -508,29 +510,25 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
free(nonce);
}
- info("Nonce: ");
- int i;
- for (i = 0; i < client->nonce_size; i++) {
- info("%02x ", client->nonce[i]);
- }
- info("\n");
+ logger(LL_INFO, "Nonce: ");
+ logger_dump_hex(LL_INFO, client->nonce, client->nonce_size);
if (nonce_changed && !(client->flags & FLAG_CUSTOM)) {
// 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);
}
if (irecv_usb_set_configuration(client->dfu->client, 1) < 0) {
- error("ERROR: set configuration failed\n");
+ logger(LL_ERROR, "set configuration failed\n");
}
mutex_lock(&client->device_event_mutex);
@@ -540,7 +538,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
// Without this empty policy file & its special signature, iBEC won't start.
if (dfu_send_component_and_command(client, build_identity, "Ap,LocalPolicy", "lpolrestore") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send Ap,LocalPolicy to device\n");
+ logger(LL_ERROR, "Unable to send Ap,LocalPolicy to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -553,17 +551,17 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
boot_stage = strtoul(value, NULL, 0);
}
if (boot_stage > 0) {
- info("iBoot boot-stage=%s\n", value);
+ logger(LL_INFO, "iBoot boot-stage=%s\n", value);
free(value);
value = NULL;
if (boot_stage != 1) {
- error("ERROR: iBoot should be at boot stage 1, continuing anyway...\n");
+ logger(LL_ERROR, "iBoot should be at boot stage 1, continuing anyway...\n");
}
}
if (dfu_send_iboot_stage1_components(client, build_identity) < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send iBoot stage 1 components to device\n");
+ logger(LL_ERROR, "Unable to send iBoot stage 1 components to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -571,7 +569,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_command(client, "setenv auto-boot false") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send command to device\n");
+ logger(LL_ERROR, "Unable to send command to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -579,7 +577,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_command(client, "saveenv") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send command to device\n");
+ logger(LL_ERROR, "Unable to send command to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -587,7 +585,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_command(client, "setenvnp boot-args rd=md0 nand-enable-reformat=1 -progress -restore") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send command to device\n");
+ logger(LL_ERROR, "Unable to send command to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -595,7 +593,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_component(client, build_identity, "RestoreLogo") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send RestoreDCP to device\n");
+ logger(LL_ERROR, "Unable to send RestoreDCP to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -603,7 +601,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_command(client, "setpicture 4") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send command to device\n");
+ logger(LL_ERROR, "Unable to send command to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -611,7 +609,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
if (dfu_send_command(client, "bgcolor 0 0 0") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send command to device\n");
+ logger(LL_ERROR, "Unable to send command to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -621,7 +619,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
/* send iBEC */
if (dfu_send_component(client, build_identity, "iBEC") < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send iBEC to device\n");
+ logger(LL_ERROR, "Unable to send iBEC to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
@@ -631,7 +629,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
sleep(1);
if (irecv_send_command_breq(client->dfu->client, "go", 1) != IRECV_E_SUCCESS) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to execute iBEC\n");
+ logger(LL_ERROR, "Unable to execute iBEC\n");
return -1;
}
@@ -642,28 +640,28 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
dfu_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, 10000);
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 %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");
+ logger(LL_ERROR, "Device did not disconnect. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");
}
return -1;
}
- 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, 10000);
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 %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");
+ logger(LL_ERROR, "Device did not reconnect in recovery mode. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");
}
return -1;
}
mutex_unlock(&client->device_event_mutex);
if (recovery_client_new(client) < 0) {
- error("ERROR: Unable to connect to recovery device\n");
+ logger(LL_ERROR, "Unable to connect to recovery device\n");
if (client->recovery->client) {
irecv_close(client->recovery->client);
client->recovery->client = NULL;
diff --git a/src/download.c b/src/download.c
index a258da2..d9fac45 100644
--- a/src/download.c
+++ b/src/download.c
@@ -48,7 +48,7 @@ int download_to_buffer(const char* url, char** buf, uint32_t* length)
int res = 0;
CURL* handle = curl_easy_init();
if (handle == NULL) {
- error("ERROR: could not initialize CURL\n");
+ logger(LL_ERROR, "could not initialize CURL\n");
return -1;
}
@@ -57,7 +57,7 @@ int download_to_buffer(const char* url, char** buf, uint32_t* length)
response.content = malloc(1);
response.content[0] = '\0';
- if (idevicerestore_debug)
+ if (log_level >= LL_DEBUG)
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
/* disable SSL verification to allow download from untrusted https locations */
@@ -86,17 +86,14 @@ int download_to_buffer(const char* url, char** buf, uint32_t* length)
return res;
}
-static int lastprogress = 0;
-
static int download_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
- double p = (dlnow / dltotal) * 100;
+ double p = (dlnow / dltotal);
+
+ set_progress('DNLD', p);
- if (p < 100.0) {
- if ((int)p > lastprogress) {
- info("downloading: %d%%\n", (int)p);
- lastprogress = (int)p;
- }
+ if (global_quit_flag > 0) {
+ return 1;
}
return 0;
@@ -107,19 +104,17 @@ int download_to_file(const char* url, const char* filename, int enable_progress)
int res = 0;
CURL* handle = curl_easy_init();
if (handle == NULL) {
- error("ERROR: could not initialize CURL\n");
+ logger(LL_ERROR, "Could not initialize CURL\n");
return -1;
}
FILE* f = fopen(filename, "wb");
if (!f) {
- error("ERROR: cannot open '%s' for writing\n", filename);
+ logger(LL_ERROR, "Cannot open '%s' for writing\n", filename);
return -1;
}
- lastprogress = 0;
-
- if (idevicerestore_debug)
+ if (log_level >= LL_DEBUG)
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
/* disable SSL verification to allow download from untrusted https locations */
@@ -128,8 +123,10 @@ int download_to_file(const char* url, const char* filename, int enable_progress)
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, f);
- if (enable_progress > 0)
+ if (enable_progress > 0) {
+ register_progress('DNLD', "Downloading");
curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&download_progress);
+ }
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, enable_progress > 0 ? 0: 1);
curl_easy_setopt(handle, CURLOPT_USERAGENT, USER_AGENT_STRING);
@@ -137,6 +134,11 @@ int download_to_file(const char* url, const char* filename, int enable_progress)
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_perform(handle);
+
+ if (enable_progress) {
+ finalize_progress('DNLD');
+ }
+
curl_easy_cleanup(handle);
#ifdef WIN32
@@ -151,6 +153,9 @@ int download_to_file(const char* url, const char* filename, int enable_progress)
res = -1;
remove(filename);
}
+ if (global_quit_flag > 0) {
+ res = -2;
+ }
return res;
}
diff --git a/src/fdr.c b/src/fdr.c
index ca9b7c7..378d4f9 100644
--- a/src/fdr.c
+++ b/src/fdr.c
@@ -66,7 +66,7 @@ int fdr_connect(idevice_t device, fdr_type_t type, fdr_client_t* fdr)
*fdr = NULL;
- debug("Connecting to FDR client at port %u\n", port);
+ logger(LL_DEBUG, "Connecting to FDR client at port %u\n", port);
for (i = 1; i <= attempts; i++) {
device_error = idevice_connect(device, port, &connection);
@@ -75,17 +75,17 @@ int fdr_connect(idevice_t device, fdr_type_t type, fdr_client_t* fdr)
}
if (i >= attempts) {
- error("ERROR: Unable to connect to FDR client (%d)\n", device_error);
+ logger(LL_ERROR, "Unable to connect to FDR client (%d)\n", device_error);
return -1;
}
sleep(2);
- debug("Retrying connection...\n");
+ logger(LL_DEBUG, "Retrying connection...\n");
}
fdr_client_t fdr_loc = calloc(1, sizeof(struct fdr_client));
if (!fdr_loc) {
- error("ERROR: Unable to allocate memory\n");
+ logger(LL_ERROR, "Unable to allocate memory\n");
return -1;
}
fdr_loc->connection = connection;
@@ -138,7 +138,7 @@ int fdr_poll_and_handle_message(fdr_client_t fdr)
uint16_t cmd;
if (!fdr) {
- error("ERROR: Invalid FDR client\n");
+ logger(LL_ERROR, "Invalid FDR client\n");
return -1;
}
@@ -149,32 +149,32 @@ int fdr_poll_and_handle_message(fdr_client_t fdr)
if (device_error == IDEVICE_E_SUCCESS && bytes != sizeof(cmd))
#endif
{
- debug("FDR %p timeout waiting for command\n", fdr);
+ logger(LL_DEBUG, "FDR %p timeout waiting for command\n", fdr);
return 0;
}
else if (device_error != IDEVICE_E_SUCCESS) {
if (fdr->connection) {
- error("ERROR: Unable to receive message from FDR %p (%d). %u/%u bytes\n", fdr, device_error, bytes, (uint32_t)sizeof(cmd));
+ logger(LL_ERROR, "Unable to receive message from FDR %p (%d). %u/%u bytes\n", fdr, device_error, bytes, (uint32_t)sizeof(cmd));
}
return -1;
}
if (cmd == FDR_SYNC_MSG) {
- debug("FDR %p got sync message\n", fdr);
+ logger(LL_DEBUG, "FDR %p got sync message\n", fdr);
return fdr_handle_sync_cmd(fdr);
}
if (cmd == FDR_PROXY_MSG) {
- debug("FDR %p got proxy message\n", fdr);
+ logger(LL_DEBUG, "FDR %p got proxy message\n", fdr);
return fdr_handle_proxy_cmd(fdr);
}
if (cmd == FDR_PLIST_MSG) {
- debug("FDR %p got plist message\n", fdr);
+ logger(LL_DEBUG, "FDR %p got plist message\n", fdr);
return fdr_handle_plist_cmd(fdr);
}
- error("WARNING: FDR %p received unknown packet %#x of size %u\n", fdr, cmd, bytes);
+ logger(LL_WARNING, "FDR %p received unknown packet %#x of size %u\n", fdr, cmd, bytes);
return 0;
}
@@ -184,14 +184,14 @@ void *fdr_listener_thread(void *cdata)
int res;
while (fdr && fdr->connection) {
- debug("FDR %p waiting for message...\n", fdr);
+ logger(LL_DEBUG, "FDR %p waiting for message...\n", fdr);
res = fdr_poll_and_handle_message(fdr);
if (fdr->type == FDR_CTRL && res >= 0)
continue; // main thread should always retry
if (res != 0)
break;
}
- debug("FDR %p terminating...\n", fdr);
+ logger(LL_DEBUG, "FDR %p terminating...\n", fdr);
fdr_free(fdr);
return (void *)(intptr_t)res;
}
@@ -204,26 +204,26 @@ static int fdr_receive_plist(fdr_client_t fdr, plist_t* data)
device_error = idevice_connection_receive(fdr->connection, (char*)&len, sizeof(len), &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to receive packet length from FDR (%d)\n", device_error);
+ logger(LL_ERROR, "Unable to receive packet length from FDR (%d)\n", device_error);
return -1;
}
buf = calloc(1, len);
if (!buf) {
- error("ERROR: Unable to allocate memory for FDR receive buffer\n");
+ logger(LL_ERROR, "Unable to allocate memory for FDR receive buffer\n");
return -1;
}
device_error = idevice_connection_receive(fdr->connection, buf, len, &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to receive data from FDR\n");
+ logger(LL_ERROR, "Unable to receive data from FDR\n");
free(buf);
return -1;
}
plist_from_bin(buf, bytes, data);
free(buf);
- debug("FDR Received %d bytes\n", bytes);
+ logger(LL_DEBUG, "FDR Received %d bytes\n", bytes);
return 0;
}
@@ -241,12 +241,11 @@ static int fdr_send_plist(fdr_client_t fdr, plist_t data)
if (!buf)
return -1;
- debug("FDR sending %d bytes:\n", len);
- if (idevicerestore_debug)
- debug_plist(data);
+ logger(LL_DEBUG, "FDR sending %d bytes:\n", len);
+ logger_dump_plist(LL_DEBUG, data, 1);
device_error = idevice_connection_send(fdr->connection, (char *)&len, sizeof(len), &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != sizeof(len)) {
- error("ERROR: FDR unable to send data length. (%d) Sent %u of %u bytes.\n",
+ logger(LL_ERROR, "FDR unable to send data length. (%d) Sent %u of %u bytes.\n",
device_error, bytes, (uint32_t)sizeof(len));
free(buf);
return -1;
@@ -254,12 +253,12 @@ static int fdr_send_plist(fdr_client_t fdr, plist_t data)
device_error = idevice_connection_send(fdr->connection, buf, len, &bytes);
free(buf);
if (device_error != IDEVICE_E_SUCCESS || bytes != len) {
- error("ERROR: FDR unable to send data (%d). Sent %u of %u bytes.\n",
+ logger(LL_ERROR, "FDR unable to send data (%d). Sent %u of %u bytes.\n",
device_error, bytes, len);
return -1;
}
- debug("FDR Sent %d bytes\n", bytes);
+ logger(LL_DEBUG, "FDR Sent %d bytes\n", bytes);
return 0;
}
@@ -270,18 +269,18 @@ static int fdr_ctrl_handshake(fdr_client_t fdr)
plist_t dict, node;
int res;
- debug("About to do ctrl handshake\n");
+ logger(LL_DEBUG, "About to do ctrl handshake\n");
ctrlprotoversion = 2;
device_error = idevice_connection_send(fdr->connection, CTRLCMD, len, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != len) {
- debug("Hmm... looks like the device doesn't like the newer protocol, using the old one\n");
+ logger(LL_DEBUG, "Hmm... looks like the device doesn't like the newer protocol, using the old one\n");
ctrlprotoversion = 1;
len = sizeof(HELLOCTRLCMD);
device_error = idevice_connection_send(fdr->connection, HELLOCTRLCMD, len, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != len) {
- error("ERROR: FDR unable to send BeginCtrl. Sent %u of %u bytes.\n", bytes, len);
+ logger(LL_ERROR, "FDR unable to send BeginCtrl. Sent %u of %u bytes.\n", bytes, len);
return -1;
}
}
@@ -293,21 +292,20 @@ static int fdr_ctrl_handshake(fdr_client_t fdr)
res = fdr_send_plist(fdr, dict);
plist_free(dict);
if (res) {
- error("ERROR: FDR could not send Begin command.\n");
+ logger(LL_ERROR, "FDR could not send Begin command.\n");
return -1;
}
if (fdr_receive_plist(fdr, &dict)) {
- error("ERROR: FDR did not get Begin command reply.\n");
+ logger(LL_ERROR, "FDR did not get Begin command reply.\n");
return -1;
}
- if (idevicerestore_debug)
- debug_plist(dict);
+ logger_dump_plist(LL_DEBUG, dict, 1);
node = plist_dict_get_item(dict, "ConnPort");
if (node && plist_get_node_type(node) == PLIST_UINT) {
plist_get_uint_val(node, &conn_port);
} else {
- error("ERROR: Could not get FDR ConnPort value\n");
+ logger(LL_ERROR, "Could not get FDR ConnPort value\n");
return -1;
}
@@ -321,26 +319,26 @@ static int fdr_ctrl_handshake(fdr_client_t fdr)
bytes = 0;
device_error = idevice_connection_receive(fdr->connection, buf, 10, &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Could not receive reply to HelloCtrl command\n");
+ logger(LL_ERROR, "Could not receive reply to HelloCtrl command\n");
return -1;
}
if (memcmp(buf, "HelloCtrl", 10) != 0) {
buf[9] = '\0';
- error("ERROR: Did not receive HelloCtrl as reply, but %s\n", buf);
+ logger(LL_ERROR, "Did not receive HelloCtrl as reply, but %s\n", buf);
return -1;
}
bytes = 0;
device_error = idevice_connection_receive(fdr->connection, (char*)&cport, 2, &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Failed to receive conn port\n");
+ logger(LL_ERROR, "Failed to receive conn port\n");
return -1;
}
conn_port = le16toh(cport);
}
- debug("Ctrl handshake done (ConnPort = %" PRIu64 ")\n", (uint64_t)conn_port);
+ logger(LL_DEBUG, "Ctrl handshake done (ConnPort = %" PRIu64 ")\n", (uint64_t)conn_port);
return 0;
}
@@ -353,13 +351,13 @@ static int fdr_sync_handshake(fdr_client_t fdr)
device_error = idevice_connection_send(fdr->connection, HELLOCMD, len, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != len) {
- error("ERROR: FDR unable to send Hello. Sent %u of %u bytes.\n", bytes, len);
+ logger(LL_ERROR, "FDR unable to send Hello. Sent %u of %u bytes.\n", bytes, len);
return -1;
}
if (ctrlprotoversion == 2) {
if (fdr_receive_plist(fdr, &reply)) {
- error("ERROR: FDR did not get HelloConn reply.\n");
+ logger(LL_ERROR, "FDR did not get HelloConn reply.\n");
return -1;
}
char* identifier = NULL;
@@ -382,13 +380,13 @@ static int fdr_sync_handshake(fdr_client_t fdr)
if (identifier) {
free(identifier);
}
- error("ERROR: Did not receive HelloConn reply...\n");
+ logger(LL_ERROR, "Did not receive HelloConn reply...\n");
return -1;
}
free(cmd);
if (identifier) {
- debug("Got device identifier %s\n", identifier);
+ logger(LL_DEBUG, "Got device identifier %s\n", identifier);
free(identifier);
}
@@ -398,12 +396,12 @@ static int fdr_sync_handshake(fdr_client_t fdr)
bytes = 0;
device_error = idevice_connection_receive(fdr->connection, buf, 10, &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Could not receive reply to HelloConn command\n");
+ logger(LL_ERROR, "Could not receive reply to HelloConn command\n");
return -1;
}
if (memcmp(buf, "HelloConn", 10) != 0) {
buf[9] = '\0';
- error("ERROR: Did not receive HelloConn as reply, but %s\n", buf);
+ logger(LL_ERROR, "Did not receive HelloConn as reply, but %s\n", buf);
return -1;
}
}
@@ -422,18 +420,18 @@ static int fdr_handle_sync_cmd(fdr_client_t fdr_ctrl)
device_error = idevice_connection_receive(fdr_ctrl->connection, buf, sizeof(buf), &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != 2) {
- error("ERROR: Unexpected data from FDR\n");
+ logger(LL_ERROR, "Unexpected data from FDR\n");
return -1;
}
/* Open a new connection and wait for messages on it */
if (fdr_connect(fdr_ctrl->device, FDR_CONN, &fdr)) {
- error("ERROR: Failed to connect to FDR port\n");
+ logger(LL_ERROR, "Failed to connect to FDR port\n");
return -1;
}
- debug("FDR connected in reply to sync message, starting command thread\n");
+ logger(LL_DEBUG, "FDR connected in reply to sync message, starting command thread\n");
res = thread_new(&fdr_thread, fdr_listener_thread, fdr);
if(res) {
- error("ERROR: Failed to start FDR command thread\n");
+ logger(LL_ERROR, "Failed to start FDR command thread\n");
fdr_free(fdr);
}
return res;
@@ -445,12 +443,12 @@ static int fdr_handle_plist_cmd(fdr_client_t fdr)
plist_t dict;
if (fdr_receive_plist(fdr, &dict)) {
- error("ERROR: FDR %p could not receive plist command.\n", fdr);
+ logger(LL_ERROR, "FDR %p could not receive plist command.\n", fdr);
return -1;
}
plist_t node = plist_dict_get_item(dict, "Command");
if (!node || (plist_get_node_type(node) != PLIST_STRING)) {
- error("ERROR: FDR %p Could not find Command in plist command\n", fdr);
+ logger(LL_ERROR, "FDR %p Could not find Command in plist command\n", fdr);
plist_free(dict);
return -1;
}
@@ -459,7 +457,7 @@ static int fdr_handle_plist_cmd(fdr_client_t fdr)
plist_free(dict);
if (!command) {
- info("FDR %p received empty plist command\n", fdr);
+ logger(LL_INFO, "FDR %p received empty plist command\n", fdr);
return -1;
}
@@ -469,12 +467,12 @@ static int fdr_handle_plist_cmd(fdr_client_t fdr)
res = fdr_send_plist(fdr, dict);
plist_free(dict);
if (res) {
- error("ERROR: FDR %p could not send Ping command reply.\n", fdr);
+ logger(LL_ERROR, "FDR %p could not send Ping command reply.\n", fdr);
free(command);
return -1;
}
} else {
- error("WARNING: FDR %p received unknown plist command: %s\n", fdr, command);
+ logger(LL_WARNING, "FDR %p received unknown plist command: %s\n", fdr, command);
free(command);
return -1;
}
@@ -495,17 +493,17 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
buf = malloc(bufsize);
if (!buf) {
- error("ERROR: %s: malloc failed\n", __func__);
+ logger(LL_ERROR, "%s: malloc failed\n", __func__);
return -1;
}
device_error = idevice_connection_receive(fdr->connection, buf, bufsize, &bytes);
if (device_error != IDEVICE_E_SUCCESS) {
free(buf);
- error("ERROR: FDR %p failed to read data for proxy command\n", fdr);
+ logger(LL_ERROR, "FDR %p failed to read data for proxy command\n", fdr);
return -1;
}
- debug("Got proxy command with %u bytes\n", bytes);
+ logger(LL_DEBUG, "Got proxy command with %u bytes\n", bytes);
/* Just return success here unconditionally because we don't know
* anything else and we will eventually abort on failure anyway */
@@ -513,13 +511,13 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
device_error = idevice_connection_send(fdr->connection, (char *)&ack, sizeof(ack), &sent);
if (device_error != IDEVICE_E_SUCCESS || sent != sizeof(ack)) {
free(buf);
- error("ERROR: FDR %p unable to send ack. Sent %u of %u bytes.\n",
+ logger(LL_ERROR, "FDR %p unable to send ack. Sent %u of %u bytes.\n",
fdr, sent, (uint32_t)sizeof(ack));
return -1;
}
if (bytes < 3) {
- debug("FDR %p proxy command data too short, retrying\n", fdr);
+ logger(LL_DEBUG, "FDR %p proxy command data too short, retrying\n", fdr);
return fdr_poll_and_handle_message(fdr);
}
@@ -527,7 +525,7 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
device_error = idevice_connection_send(fdr->connection, buf, bytes, &sent);
if (device_error != IDEVICE_E_SUCCESS || sent != bytes) {
free(buf);
- error("ERROR: FDR %p unable to send data. Sent %u of %u bytes.\n",
+ logger(LL_ERROR, "FDR %p unable to send data. Sent %u of %u bytes.\n",
fdr, sent, bytes);
return -1;
}
@@ -539,7 +537,7 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
port = be16toh(*p);
buf[bytes - 2] = '\0';
host = strdup(&buf[3]);
- debug("FDR %p Proxy connect request to %s:%u\n", fdr, host, port);
+ logger(LL_DEBUG, "FDR %p Proxy connect request to %s:%u\n", fdr, host, port);
}
if (!host || !buf[2]) {
@@ -553,7 +551,7 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
free(host);
if (sockfd < 0) {
free(buf);
- error("ERROR: Failed to connect socket: %s\n", strerror(errno));
+ logger(LL_ERROR, "Failed to connect socket: %s\n", strerror(errno));
return -1;
}
@@ -567,16 +565,16 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
if (device_error == IDEVICE_E_SUCCESS && !bytes)
#endif
{
- //debug("WARNING: Timeout waiting for proxy payload. %p\n", fdr);
+ //logger(LL_DEBUG, "Timeout waiting for proxy payload. %p\n", fdr);
}
else if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: FDR %p Unable to receive proxy payload (%d)\n", fdr, device_error);
+ logger(LL_ERROR, "FDR %p Unable to receive proxy payload (%d)\n", fdr, device_error);
res = -1;
break;
}
if (bytes) {
- debug("FDR %p got payload of %u bytes, now trying to proxy it\n", fdr, bytes);
- debug("Sending %u bytes of data\n", bytes);
+ logger(LL_DEBUG, "FDR %p got payload of %u bytes, now trying to proxy it\n", fdr, bytes);
+ logger(LL_DEBUG, "Sending %u bytes of data\n", bytes);
sent = 0;
while (sent < bytes) {
int s = socket_send(sockfd, buf + sent, bytes - sent);
@@ -586,7 +584,7 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
sent += s;
}
if (sent != bytes) {
- error("ERROR: Sending proxy payload failed: %s. Sent %u of %u bytes. \n", strerror(errno), sent, bytes);
+ logger(LL_ERROR, "Sending proxy payload failed: %s. Sent %u of %u bytes. \n", strerror(errno), sent, bytes);
socket_close(sockfd);
res = -1;
break;
@@ -599,14 +597,14 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
res = 1;
break;
} else if (bytes_ret < 0) {
- error("ERROR: FDR %p receiving proxy payload failed: %d (%s)\n",
+ logger(LL_ERROR, "FDR %p receiving proxy payload failed: %d (%s)\n",
fdr, bytes_ret, strerror(-bytes_ret));
break;
}
bytes = bytes_ret;
if (bytes) {
- debug("FDR %p Received %u bytes reply data,%s sending to device\n",
+ logger(LL_DEBUG, "FDR %p Received %u bytes reply data,%s sending to device\n",
fdr, bytes, (bytes ? "" : " not"));
sent = 0;
@@ -619,7 +617,7 @@ static int fdr_handle_proxy_cmd(fdr_client_t fdr)
sent += s;
}
if (device_error != IDEVICE_E_SUCCESS || bytes != sent) {
- error("ERROR: FDR %p unable to send data (%d). Sent %u of %u bytes.\n", fdr, device_error, sent, bytes);
+ logger(LL_ERROR, "FDR %p unable to send data (%d). Sent %u of %u bytes.\n", fdr, device_error, sent, bytes);
res = -1;
break;
}
diff --git a/src/fls.c b/src/fls.c
index f422447..cc75c54 100644
--- a/src/fls.c
+++ b/src/fls.c
@@ -96,7 +96,7 @@ static void fls_parse_elements(fls_file* fls)
offset += cur->size;
} while (offset < fls->size);
if (offset != fls->size) {
- error("ERROR: %s: error parsing elements\n", __func__);
+ logger(LL_ERROR, "%s: error parsing elements\n", __func__);
return;
}
}
@@ -136,22 +136,22 @@ int fls_update_sig_blob(fls_file* fls, const unsigned char* sigdata, unsigned in
{
/* FIXME: the code in this function is not big endian safe */
if (!fls || !fls->num_elements) {
- error("ERROR: %s: no data\n", __func__);
+ logger(LL_ERROR, "%s: no data\n", __func__);
return -1;
}
if (!fls->c_element) {
- error("ERROR: %s: no fls_0c_element in fls data\n", __func__);
+ logger(LL_ERROR, "%s: no fls_0c_element in fls data\n", __func__);
return -1;
}
uint32_t datasize = *(uint32_t*)(fls->c_element->data + 0x10);
if (datasize != fls->c_element->data_size) {
- error("ERROR: %s: data size mismatch (0x%x != 0x%x)\n", __func__, datasize, fls->c_element->data_size);
+ logger(LL_ERROR, "%s: data size mismatch (0x%x != 0x%x)\n", __func__, datasize, fls->c_element->data_size);
return -1;
}
uint32_t sigoffset = *(uint32_t*)(fls->c_element->data + 0x14);
if (sigoffset > datasize) {
- error("ERROR: %s: signature offset greater than data size (0x%x > 0x%x)\n", __func__, sigoffset, datasize);
+ logger(LL_ERROR, "%s: signature offset greater than data size (0x%x > 0x%x)\n", __func__, sigoffset, datasize);
return -1;
}
@@ -162,7 +162,7 @@ int fls_update_sig_blob(fls_file* fls, const unsigned char* sigdata, unsigned in
uint32_t offset = 0;
void* newdata = malloc(newsize);
if (!newdata) {
- error("ERROR: %s: out of memory\n", __func__);
+ logger(LL_ERROR, "%s: out of memory\n", __func__);
return -1;
}
uint32_t hdrsize = 0;
@@ -243,11 +243,11 @@ int fls_insert_ticket(fls_file* fls, const unsigned char* data, unsigned int siz
{
/* FIXME: the code in this function is not big endian safe */
if (!fls || !fls->num_elements) {
- error("ERROR: %s: no data\n", __func__);
+ logger(LL_ERROR, "%s: no data\n", __func__);
return -1;
}
if (!fls->c_element) {
- error("ERROR: %s: no fls_0c_element in fls data\n", __func__);
+ logger(LL_ERROR, "%s: no fls_0c_element in fls data\n", __func__);
return -1;
}
@@ -260,7 +260,7 @@ int fls_insert_ticket(fls_file* fls, const unsigned char* data, unsigned int siz
uint32_t offset = 0;
void* newdata = malloc(newsize);
if (!newdata) {
- error("ERROR: %s: out of memory\n", __func__);
+ logger(LL_ERROR, "%s: out of memory\n", __func__);
return -1;
}
uint32_t hdrsize = 0;
diff --git a/src/ftab.c b/src/ftab.c
index 8515d1f..cc74251 100644
--- a/src/ftab.c
+++ b/src/ftab.c
@@ -35,13 +35,13 @@ int ftab_parse(unsigned char *data, unsigned int data_size, ftab_t *ftab, uint32
}
if (data_size < sizeof(struct ftab_header)) {
- error("ERROR: %s: Buffer too small for ftab data\n", __func__);
+ logger(LL_ERROR, "%s: Buffer too small for ftab data\n", __func__);
return -1;
}
struct ftab_header *hdr_ptr = (struct ftab_header*)data;
if (be32toh(hdr_ptr->magic) != 'ftab') {
- error("ERROR: %s: Unexpected magic value 0x%08x\n", __func__, le32toh(hdr_ptr->magic));
+ logger(LL_ERROR, "%s: Unexpected magic value 0x%08x\n", __func__, le32toh(hdr_ptr->magic));
return -1;
}
@@ -108,13 +108,13 @@ int ftab_add_entry(ftab_t ftab, uint32_t tag, unsigned char *data, unsigned int
uint32_t new_index = ftab->header.num_entries;
struct ftab_entry *new_entries = realloc(ftab->entries, sizeof(struct ftab_entry) * (ftab->header.num_entries + 1));
if (!new_entries) {
- error("ERROR: %s: realloc failed!\n", __func__);
+ logger(LL_ERROR, "%s: realloc failed!\n", __func__);
return -1;
}
ftab->entries = new_entries;
unsigned char **new_storage = realloc(ftab->storage, sizeof(unsigned char*) * (ftab->header.num_entries + 1));
if (!new_storage) {
- error("ERROR: %s: realloc failed!\n", __func__);
+ logger(LL_ERROR, "%s: realloc failed!\n", __func__);
return -1;
}
ftab->storage = new_storage;
@@ -151,7 +151,7 @@ int ftab_write(ftab_t ftab, unsigned char **data, unsigned int *data_size)
unsigned char *data_out = (unsigned char*)malloc(total_size);
if (!data_out) {
- error("ERROR: %s: Out of memory?!\n", __func__);
+ logger(LL_ERROR, "%s: Out of memory?!\n", __func__);
return -1;
}
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;
}
diff --git a/src/idevicerestore.h b/src/idevicerestore.h
index fe9d11f..1e01672 100644
--- a/src/idevicerestore.h
+++ b/src/idevicerestore.h
@@ -46,6 +46,7 @@ extern "C" {
#define FLAG_ALLOW_RESTORE_MODE (1 << 10)
#define FLAG_NO_RESTORE (1 << 11)
#define FLAG_IGNORE_ERRORS (1 << 12)
+#define FLAG_IN_PROGRESS (1 << 30)
#define RESTORE_VARIANT_ERASE_INSTALL "Erase Install (IPSW)"
#define RESTORE_VARIANT_UPGRADE_INSTALL "Upgrade Install (IPSW)"
@@ -83,9 +84,6 @@ void idevicerestore_set_flags(struct idevicerestore_client_t* client, int flags)
void idevicerestore_set_ipsw(struct idevicerestore_client_t* client, const char* path);
void idevicerestore_set_cache_path(struct idevicerestore_client_t* client, const char* path);
void idevicerestore_set_progress_callback(struct idevicerestore_client_t* client, idevicerestore_progress_cb_t cbfunc, void* userdata);
-void idevicerestore_set_info_stream(FILE* strm);
-void idevicerestore_set_error_stream(FILE* strm);
-void idevicerestore_set_debug_stream(FILE* strm);
int idevicerestore_start(struct idevicerestore_client_t* client);
const char* idevicerestore_get_error(void);
diff --git a/src/img3.c b/src/img3.c
index fb8d49e..a700839 100644
--- a/src/img3.c
+++ b/src/img3.c
@@ -38,13 +38,13 @@ static img3_file* img3_parse_file(const unsigned char* data, unsigned int size)
img3_element* element;
img3_header* header = (img3_header*) data;
if (header->signature != kImg3Container) {
- error("ERROR: Invalid IMG3 file\n");
+ logger(LL_ERROR, "Invalid IMG3 file\n");
return NULL;
}
img3_file* image = (img3_file*) malloc(sizeof(img3_file));
if (image == NULL) {
- error("ERROR: Unable to allocate memory for IMG3 file\n");
+ logger(LL_ERROR, "Unable to allocate memory for IMG3 file\n");
return NULL;
}
memset(image, '\0', sizeof(img3_file));
@@ -54,7 +54,7 @@ static img3_file* img3_parse_file(const unsigned char* data, unsigned int size)
image->header = (img3_header*) malloc(sizeof(img3_header));
if (image->header == NULL) {
- error("ERROR: Unable to allocate memory for IMG3 header\n");
+ logger(LL_ERROR, "Unable to allocate memory for IMG3 header\n");
img3_free(image);
return NULL;
}
@@ -68,129 +68,129 @@ static img3_file* img3_parse_file(const unsigned char* data, unsigned int size)
case kTypeElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse TYPE element\n");
+ logger(LL_ERROR, "Unable to parse TYPE element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed TYPE element\n");
+ logger(LL_DEBUG, "Parsed TYPE element\n");
break;
case kDataElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse DATA element\n");
+ logger(LL_ERROR, "Unable to parse DATA element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed DATA element\n");
+ logger(LL_DEBUG, "Parsed DATA element\n");
break;
case kVersElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse VERS element\n");
+ logger(LL_ERROR, "Unable to parse VERS element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed VERS element\n");
+ logger(LL_DEBUG, "Parsed VERS element\n");
break;
case kSepoElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse SEPO element\n");
+ logger(LL_ERROR, "Unable to parse SEPO element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed SEPO element\n");
+ logger(LL_DEBUG, "Parsed SEPO element\n");
break;
case kBordElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse BORD element\n");
+ logger(LL_ERROR, "Unable to parse BORD element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed BORD element\n");
+ logger(LL_DEBUG, "Parsed BORD element\n");
break;
case kChipElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse CHIP element\n");
+ logger(LL_ERROR, "Unable to parse CHIP element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed CHIP element\n");
+ logger(LL_DEBUG, "Parsed CHIP element\n");
break;
case kKbagElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse first KBAG element\n");
+ logger(LL_ERROR, "Unable to parse first KBAG element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed KBAG element\n");
+ logger(LL_DEBUG, "Parsed KBAG element\n");
break;
case kEcidElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse ECID element\n");
+ logger(LL_ERROR, "Unable to parse ECID element\n");
img3_free(image);
return NULL;
}
image->idx_ecid_element = image->num_elements;
image->elements[image->num_elements++] = element;
- debug("Parsed ECID element\n");
+ logger(LL_DEBUG, "Parsed ECID element\n");
break;
case kShshElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse SHSH element\n");
+ logger(LL_ERROR, "Unable to parse SHSH element\n");
img3_free(image);
return NULL;
}
image->idx_shsh_element = image->num_elements;
image->elements[image->num_elements++] = element;
- debug("Parsed SHSH element\n");
+ logger(LL_DEBUG, "Parsed SHSH element\n");
break;
case kCertElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse CERT element\n");
+ logger(LL_ERROR, "Unable to parse CERT element\n");
img3_free(image);
return NULL;
}
image->idx_cert_element = image->num_elements;
image->elements[image->num_elements++] = element;
- debug("Parsed CERT element\n");
+ logger(LL_DEBUG, "Parsed CERT element\n");
break;
case kUnknElement:
element = img3_parse_element(&data[data_offset]);
if (element == NULL) {
- error("ERROR: Unable to parse UNKN element\n");
+ logger(LL_ERROR, "Unable to parse UNKN element\n");
img3_free(image);
return NULL;
}
image->elements[image->num_elements++] = element;
- debug("Parsed UNKN element\n");
+ logger(LL_DEBUG, "Parsed UNKN element\n");
break;
default:
- error("ERROR: Unknown IMG3 element type %08x\n", current->signature);
+ logger(LL_ERROR, "Unknown IMG3 element type %08x\n", current->signature);
img3_free(image);
return NULL;
}
@@ -204,14 +204,14 @@ static img3_element* img3_parse_element(const unsigned char* data) {
img3_element_header* element_header = (img3_element_header*) data;
img3_element* element = (img3_element*) malloc(sizeof(img3_element));
if (element == NULL) {
- error("ERROR: Unable to allocate memory for IMG3 element\n");
+ logger(LL_ERROR, "Unable to allocate memory for IMG3 element\n");
return NULL;
}
memset(element, '\0', sizeof(img3_element));
element->data = (unsigned char*) malloc(element_header->full_size);
if (element->data == NULL) {
- error("ERROR: Unable to allocate memory for IMG3 element data\n");
+ logger(LL_ERROR, "Unable to allocate memory for IMG3 element data\n");
free(element);
return NULL;
}
@@ -254,21 +254,21 @@ static int img3_replace_signature(img3_file* image, const unsigned char* signatu
int offset = 0;
img3_element* ecid = img3_parse_element(&signature[offset]);
if (ecid == NULL || ecid->type != kEcidElement) {
- error("ERROR: Unable to find ECID element in signature\n");
+ logger(LL_ERROR, "Unable to find ECID element in signature\n");
return -1;
}
offset += ecid->header->full_size;
img3_element* shsh = img3_parse_element(&signature[offset]);
if (shsh == NULL || shsh->type != kShshElement) {
- error("ERROR: Unable to find SHSH element in signature\n");
+ logger(LL_ERROR, "Unable to find SHSH element in signature\n");
return -1;
}
offset += shsh->header->full_size;
img3_element* cert = img3_parse_element(&signature[offset]);
if (cert == NULL || cert->type != kCertElement) {
- error("ERROR: Unable to find CERT element in signature\n");
+ logger(LL_ERROR, "Unable to find CERT element in signature\n");
return -1;
}
offset += cert->header->full_size;
@@ -364,11 +364,11 @@ static int img3_get_data(img3_file* image, unsigned char** pdata, unsigned int*
size += image->elements[i]->header->full_size;
}
- info("reconstructed size: %d\n", size);
+ logger(LL_INFO, "reconstructed size: %d\n", size);
unsigned char* data = (unsigned char*) malloc(size);
if (data == NULL) {
- error("ERROR: Unable to allocate memory for IMG3 data\n");
+ logger(LL_ERROR, "Unable to allocate memory for IMG3 data\n");
return -1;
}
@@ -390,7 +390,7 @@ static int img3_get_data(img3_file* image, unsigned char** pdata, unsigned int*
}
if (offset != size) {
- error("ERROR: Incorrectly sized image data\n");
+ logger(LL_ERROR, "Incorrectly sized image data\n");
free(data);
*pdata = 0;
*psize = 0;
@@ -412,31 +412,31 @@ int img3_stitch_component(const char* component_name, const unsigned char* compo
return -1;
}
- info("Personalizing IMG3 component %s...\n", component_name);
+ logger(LL_INFO, "Personalizing IMG3 component %s...\n", component_name);
/* parse current component as img3 */
img3 = img3_parse_file(component_data, component_size);
if (img3 == NULL) {
- error("ERROR: Unable to parse %s IMG3 file\n", component_name);
+ logger(LL_ERROR, "Unable to parse %s IMG3 file\n", component_name);
return -1;
}
if (((img3_element_header*)blob)->full_size != blob_size) {
- error("ERROR: Invalid blob passed for %s IMG3: The size %d embedded in the blob does not match the passed size of %d\n", component_name, ((img3_element_header*)blob)->full_size, blob_size);
+ logger(LL_ERROR, "Invalid blob passed for %s IMG3: The size %d embedded in the blob does not match the passed size of %d\n", component_name, ((img3_element_header*)blob)->full_size, blob_size);
img3_free(img3);
return -1;
}
/* personalize the component using the blob */
if (img3_replace_signature(img3, blob) < 0) {
- error("ERROR: Unable to replace %s IMG3 signature\n", component_name);
+ logger(LL_ERROR, "Unable to replace %s IMG3 signature\n", component_name);
img3_free(img3);
return -1;
}
/* get the img3 file as data */
if (img3_get_data(img3, &outbuf, &outsize) < 0) {
- error("ERROR: Unable to reconstruct %s IMG3\n", component_name);
+ logger(LL_ERROR, "Unable to reconstruct %s IMG3\n", component_name);
img3_free(img3);
return -1;
}
diff --git a/src/img4.c b/src/img4.c
index e9d4cca..b23775a 100644
--- a/src/img4.c
+++ b/src/img4.c
@@ -204,7 +204,7 @@ static void asn1_write_element(unsigned char **p, unsigned int *length, unsigned
}
} break;
default:
- fprintf(stderr, "ERROR: %s: type %02x is not implemented\n", __func__, type);
+ logger(LL_ERROR, "%s: type %02x is not implemented\n", __func__, type);
return;
}
}
@@ -415,15 +415,15 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
}
if (tss_response_get_ap_img4_ticket(tss_response, &blob, &blob_size) != 0) {
- error("ERROR: %s: Failed to get ApImg4Ticket from TSS response\n", __func__);
+ logger(LL_ERROR, "%s: Failed to get ApImg4Ticket from TSS response\n", __func__);
return -1;
}
- info("Personalizing IMG4 component %s...\n", component_name);
+ logger(LL_INFO, "Personalizing IMG4 component %s...\n", component_name);
/* first we need check if we have to change the tag for the given component */
const void *tag = asn1_find_element(1, ASN1_IA5_STRING, component_data);
if (tag) {
- debug("Tag found\n");
+ logger(LL_DEBUG, "Tag found\n");
if (strcmp(component_name, "RestoreKernelCache") == 0) {
memcpy((void*)tag, "rkrn", 4);
} else if (strcmp(component_name, "RestoreDeviceTree") == 0) {
@@ -467,22 +467,22 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
if (tbm_dict) {
plist_t dt = plist_dict_get_item(tbm_dict, "ucon");
if (!dt) {
- error("ERROR: %s: Missing ucon node in %s-TBM dictionary\n", __func__, component_name);
+ logger(LL_ERROR, "%s: Missing ucon node in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
ucon_data = plist_get_data_ptr(dt, &ucon_size);
if (!ucon_data) {
- error("ERROR: %s: Missing ucon data in %s-TBM dictionary\n", __func__, component_name);
+ logger(LL_ERROR, "%s: Missing ucon data in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
dt = plist_dict_get_item(tbm_dict, "ucer");
if (!dt) {
- error("ERROR: %s: Missing ucer data node in %s-TBM dictionary\n", __func__, component_name);
+ logger(LL_ERROR, "%s: Missing ucer data node in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
ucer_data = plist_get_data_ptr(dt, &ucer_size);
if (!ucer_data) {
- error("ERROR: %s: Missing ucer data in %s-TBM dictionary\n", __func__, component_name);
+ logger(LL_ERROR, "%s: Missing ucer data in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
}
@@ -683,7 +683,7 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
free(img4header);
}
free(additional_data);
- error("ERROR: out of memory when personalizing IMG4 component %s\n", component_name);
+ logger(LL_ERROR, "out of memory when personalizing IMG4 component %s\n", component_name);
return -1;
}
p = outbuf;
@@ -825,7 +825,7 @@ static void _manifest_write_component(unsigned char **p, unsigned int *length, c
tbmtag = "tbmr";
}
if (!tbmtag) {
- error("ERROR: Unexpected TMBDigests for comp '%s'\n", tag);
+ logger(LL_ERROR, "Unexpected TMBDigests for comp '%s'\n", tag);
} else {
_manifest_write_key_value(&tmp, &tmp_len, tbmtag, ASN1_OCTET_STRING, (void*)data, datalen);
}
@@ -918,10 +918,10 @@ int img4_create_local_manifest(plist_t request, plist_t build_identity, plist_t*
comp = _img4_get_component_tag(key);
}
if (!comp) {
- debug("DEBUG: %s: Unhandled component '%s'\n", __func__, key);
+ logger(LL_DEBUG, "%s: Unhandled component '%s'\n", __func__, key);
_manifest_write_component(&p, &length, key, val);
} else {
- debug("DEBUG: found component %s (%s)\n", comp, key);
+ logger(LL_DEBUG, "found component %s (%s)\n", comp, key);
_manifest_write_component(&p, &length, comp, val);
}
}
diff --git a/src/ipsw.c b/src/ipsw.c
index da7528d..201f9cd 100644
--- a/src/ipsw.c
+++ b/src/ipsw.c
@@ -69,7 +69,7 @@ int ipsw_print_info(const char* path)
struct stat fst;
if (stat(path, &fst) != 0) {
- error("ERROR: '%s': %s\n", path, strerror(errno));
+ logger(LL_ERROR, "'%s': %s\n", path, strerror(errno));
return -1;
}
@@ -78,7 +78,7 @@ int ipsw_print_info(const char* path)
if (S_ISDIR(fst.st_mode)) {
snprintf(thepath, sizeof(thepath), "%s/BuildManifest.plist", path);
if (stat(thepath, &fst) != 0) {
- error("ERROR: '%s': %s\n", thepath, strerror(errno));
+ logger(LL_ERROR, "'%s': %s\n", thepath, strerror(errno));
return -1;
}
} else {
@@ -87,13 +87,13 @@ int ipsw_print_info(const char* path)
FILE* f = fopen(thepath, "r");
if (!f) {
- error("ERROR: Can't open '%s': %s\n", thepath, strerror(errno));
+ logger(LL_ERROR, "Can't open '%s': %s\n", thepath, strerror(errno));
return -1;
}
uint32_t magic;
if (fread(&magic, 1, 4, f) != 4) {
fclose(f);
- fprintf(stderr, "Failed to read from '%s'\n", path);
+ logger(LL_ERROR, "Failed to read from '%s'\n", path);
return -1;
}
fclose(f);
@@ -106,7 +106,7 @@ int ipsw_print_info(const char* path)
unsigned int rlen = 0;
if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", (unsigned char**)&plist_buf, &rlen) < 0) {
ipsw_close(ipsw);
- error("ERROR: Failed to extract BuildManifest.plist from IPSW!\n");
+ logger(LL_ERROR, "Failed to extract BuildManifest.plist from IPSW!\n");
return -1;
}
ipsw_close(ipsw);
@@ -114,7 +114,7 @@ int ipsw_print_info(const char* path)
} else {
size_t rlen = 0;
if (read_file(thepath, (void**)&plist_buf, &rlen) < 0) {
- error("ERROR: Failed to read BuildManifest.plist!\n");
+ logger(LL_ERROR, "Failed to read BuildManifest.plist!\n");
return -1;
}
plist_len = (uint32_t)rlen;
@@ -302,13 +302,13 @@ ipsw_archive_t ipsw_open(const char* ipsw)
int err = 0;
ipsw_archive_t archive = (ipsw_archive_t)calloc(1, sizeof(struct ipsw_archive));
if (archive == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return NULL;
}
struct stat fst;
if (stat(ipsw, &fst) != 0) {
- error("ERROR: ipsw_open %s: %s\n", ipsw, strerror(errno));
+ logger(LL_ERROR, "ipsw_open %s: %s\n", ipsw, strerror(errno));
return NULL;
}
if (S_ISDIR(fst.st_mode)) {
@@ -316,7 +316,7 @@ ipsw_archive_t ipsw_open(const char* ipsw)
} else {
struct zip *zip = zip_open(ipsw, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw, err);
free(archive);
return NULL;
}
@@ -347,7 +347,7 @@ int ipsw_is_directory(const char* ipsw)
int ipsw_get_file_size(ipsw_archive_t ipsw, const char* infile, uint64_t* size)
{
if (ipsw == NULL) {
- error("ERROR: Invalid archive\n");
+ logger(LL_ERROR, "Invalid archive\n");
return -1;
}
@@ -355,12 +355,12 @@ int ipsw_get_file_size(ipsw_archive_t ipsw, const char* infile, uint64_t* size)
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return -1;
}
int zindex = zip_name_locate(zip, infile, 0);
if (zindex < 0) {
- error("ERROR: zip_name_locate: %s\n", infile);
+ logger(LL_ERROR, "zip_name_locate: %s\n", infile);
zip_unchange_all(zip);
zip_close(zip);
return -1;
@@ -369,7 +369,7 @@ int ipsw_get_file_size(ipsw_archive_t ipsw, const char* infile, uint64_t* size)
struct zip_stat zstat;
zip_stat_init(&zstat);
if (zip_stat_index(zip, zindex, 0, &zstat) != 0) {
- error("ERROR: zip_stat_index: %s\n", infile);
+ logger(LL_ERROR, "zip_stat_index: %s\n", infile);
zip_unchange_all(zip);
zip_close(zip);
return -1;
@@ -398,7 +398,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
int ret = 0;
if (!ipsw || !infile || !outfile) {
- error("ERROR: Invalid argument\n");
+ logger(LL_ERROR, "Invalid argument\n");
return -1;
}
@@ -408,7 +408,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return -1;
}
@@ -416,7 +416,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
if (zindex < 0) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_name_locate: %s\n", infile);
+ logger(LL_ERROR, "zip_name_locate: %s\n", infile);
return -1;
}
@@ -425,7 +425,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
if (zip_stat_index(zip, zindex, 0, &zstat) != 0) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_stat_index: %s\n", infile);
+ logger(LL_ERROR, "zip_stat_index: %s\n", infile);
return -1;
}
@@ -433,7 +433,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
if (buffer == NULL) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: Unable to allocate memory\n");
+ logger(LL_ERROR, "Unable to allocate memory\n");
return -1;
}
@@ -441,7 +441,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
if (zfile == NULL) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_fopen_index: %s\n", infile);
+ logger(LL_ERROR, "zip_fopen_index: %s\n", infile);
return -1;
}
@@ -450,13 +450,15 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
zip_fclose(zfile);
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: Unable to open output file: %s\n", outfile);
+ logger(LL_ERROR, "Unable to open output file: %s\n", outfile);
return -1;
}
+ if (print_progress) {
+ register_progress('IPSW', "Extracting");
+ }
uint64_t i, bytes = 0;
int count, size = BUFSIZE;
- double progress;
for(i = zstat.size; i > 0; i -= count) {
if (cancel_flag) {
break;
@@ -468,23 +470,26 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
int zep = 0;
int sep = 0;
zip_file_error_get(zfile, &zep, &sep);
- error("ERROR: zip_fread: %s %d %d\n", infile, zep, sep);
+ logger(LL_ERROR, "zip_fread: %s %d %d\n", infile, zep, sep);
ret = -1;
break;
}
if (fwrite(buffer, 1, count, fd) != count) {
- error("ERROR: Writing to '%s' failed: %s\n", outfile, strerror(errno));
+ logger(LL_ERROR, "Writing to '%s' failed: %s\n", outfile, strerror(errno));
ret = -1;
break;
}
bytes += size;
if (print_progress) {
- progress = ((double)bytes / (double)zstat.size) * 100.0;
- print_progress_bar(progress);
+ double progress = ((double)bytes / (double)zstat.size);
+ set_progress('IPSW', progress);
}
}
free(buffer);
+ if (print_progress) {
+ finalize_progress('IPSW');
+ }
fclose(fd);
zip_fclose(zfile);
zip_unchange_all(zip);
@@ -498,7 +503,7 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
goto leave;
}
if (!realpath(filepath, actual_filepath)) {
- error("ERROR: realpath failed on %s: %s\n", filepath, strerror(errno));
+ logger(LL_ERROR, "realpath failed on %s: %s\n", filepath, strerror(errno));
ret = -1;
goto leave;
} else {
@@ -512,21 +517,21 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
}
FILE *fi = fopen(actual_filepath, "rb");
if (!fi) {
- error("ERROR: fopen: %s: %s\n", actual_filepath, strerror(errno));
+ logger(LL_ERROR, "fopen: %s: %s\n", actual_filepath, strerror(errno));
ret = -1;
goto leave;
}
struct stat fst;
if (fstat(fileno(fi), &fst) != 0) {
fclose(fi);
- error("ERROR: fstat: %s: %s\n", actual_filepath, strerror(errno));
+ logger(LL_ERROR, "fstat: %s: %s\n", actual_filepath, strerror(errno));
ret = -1;
goto leave;
}
FILE *fo = fopen(actual_outfile, "wb");
if (!fo) {
fclose(fi);
- error("ERROR: fopen: %s: %s\n", actual_outfile, strerror(errno));
+ logger(LL_ERROR, "fopen: %s: %s\n", actual_outfile, strerror(errno));
ret = -1;
goto leave;
}
@@ -534,34 +539,39 @@ int ipsw_extract_to_file_with_progress(ipsw_archive_t ipsw, const char* infile,
if (buffer == NULL) {
fclose(fi);
fclose(fo);
- error("ERROR: Unable to allocate memory\n");
+ logger(LL_ERROR, "Unable to allocate memory\n");
ret = -1;
goto leave;;
}
+ if (print_progress) {
+ register_progress('IPSW', "Extracting");
+ }
uint64_t bytes = 0;
- double progress;
while (!feof(fi)) {
if (cancel_flag) {
break;
}
ssize_t r = fread(buffer, 1, BUFSIZE, fi);
if (r < 0) {
- error("ERROR: fread failed: %s\n", strerror(errno));
+ logger(LL_ERROR, "fread failed: %s\n", strerror(errno));
ret = -1;
break;
}
if (fwrite(buffer, 1, r, fo) != r) {
- error("ERROR: Writing to '%s' failed: %s\n", actual_outfile, strerror(errno));
+ logger(LL_ERROR, "Writing to '%s' failed: %s\n", actual_outfile, strerror(errno));
ret = -1;
break;
}
bytes += r;
if (print_progress) {
- progress = ((double)bytes / (double)fst.st_size) * 100.0;
- print_progress_bar(progress);
+ double progress = ((double)bytes / (double)fst.st_size);
+ set_progress('IPSW', progress);
}
}
+ if (print_progress) {
+ finalize_progress('IPSW');
+ }
free(buffer);
fclose(fi);
@@ -592,7 +602,7 @@ int ipsw_file_exists(ipsw_archive_t ipsw, const char* infile)
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return 0;
}
int zindex = zip_name_locate(zip, infile, 0);
@@ -618,7 +628,7 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
size_t size = 0;
unsigned char* buffer = NULL;
if (ipsw == NULL) {
- error("ERROR: Invalid archive\n");
+ logger(LL_ERROR, "Invalid archive\n");
return -1;
}
@@ -626,7 +636,7 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return -1;
}
@@ -634,7 +644,7 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
if (zindex < 0) {
zip_unchange_all(zip);
zip_close(zip);
- debug("NOTE: zip_name_locate: '%s' not found in archive.\n", infile);
+ logger(LL_DEBUG, "zip_name_locate: '%s' not found in archive.\n", infile);
return -1;
}
@@ -643,7 +653,7 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
if (zip_stat_index(zip, zindex, 0, &zstat) != 0) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_stat_index: %s\n", infile);
+ logger(LL_ERROR, "zip_stat_index: %s\n", infile);
return -1;
}
@@ -651,14 +661,14 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
if (zfile == NULL) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_fopen_index: %s\n", infile);
+ logger(LL_ERROR, "zip_fopen_index: %s\n", infile);
return -1;
}
size = zstat.size;
buffer = (unsigned char*) malloc(size+1);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
zip_fclose(zfile);
zip_unchange_all(zip);
zip_close(zip);
@@ -673,11 +683,11 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
int zep = 0;
int sep = 0;
zip_file_error_get(zfile, &zep, &sep);
- error("ERROR: zip_fread: %s %d %d\n", infile, zep, sep);
+ logger(LL_ERROR, "zip_fread: %s %d %d\n", infile, zep, sep);
free(buffer);
return -1;
} else if (zr != size) {
- error("ERROR: zip_fread: %s got only %lld of %zu\n", infile, zr, size);
+ logger(LL_ERROR, "zip_fread: %s got only %lld of %zu\n", infile, zr, size);
free(buffer);
return -1;
}
@@ -691,14 +701,14 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
#else
if (lstat(filepath, &fst) != 0) {
#endif
- error("ERROR: %s: stat failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: stat failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
return -1;
}
size = fst.st_size;
buffer = (unsigned char*)malloc(size+1);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
free(filepath);
return -1;
}
@@ -706,7 +716,7 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
#ifndef WIN32
if (S_ISLNK(fst.st_mode)) {
if (readlink(filepath, (char*)buffer, size) < 0) {
- error("ERROR: %s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
free(buffer);
return -1;
@@ -715,14 +725,14 @@ int ipsw_extract_to_memory(ipsw_archive_t ipsw, const char* infile, unsigned cha
#endif
FILE *f = fopen(filepath, "rb");
if (!f) {
- error("ERROR: %s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
free(buffer);
return -2;
}
if (fread(buffer, 1, size, f) != size) {
fclose(f);
- error("ERROR: %s: fread failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: fread failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
free(buffer);
return -1;
@@ -748,7 +758,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
size_t total_size = 0;
if (ipsw == NULL) {
- error("ERROR: Invalid archive\n");
+ logger(LL_ERROR, "Invalid archive\n");
return -1;
}
@@ -756,7 +766,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return -1;
}
@@ -764,7 +774,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (zindex < 0) {
zip_unchange_all(zip);
zip_close(zip);
- debug("NOTE: zip_name_locate: '%s' not found in archive.\n", infile);
+ logger(LL_DEBUG, "zip_name_locate: '%s' not found in archive.\n", infile);
return -1;
}
@@ -773,7 +783,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (zip_stat_index(zip, zindex, 0, &zstat) != 0) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_stat_index: %s\n", infile);
+ logger(LL_ERROR, "zip_stat_index: %s\n", infile);
return -1;
}
@@ -781,7 +791,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (zfile == NULL) {
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: zip_fopen_index: %s\n", infile);
+ logger(LL_ERROR, "zip_fopen_index: %s\n", infile);
return -1;
}
@@ -791,7 +801,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
zip_fclose(zfile);
zip_unchange_all(zip);
zip_close(zip);
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
@@ -800,14 +810,14 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (size > blocksize) size = blocksize;
zip_int64_t zr = zip_fread(zfile, buffer, size);
if (zr < 0) {
- error("ERROR: %s: zip_fread: %s\n", __func__, infile);
+ logger(LL_ERROR, "%s: zip_fread: %s\n", __func__, infile);
break;
} else if (zr == 0) {
// EOF
break;
}
if (send_callback(ctx, buffer, zr, done, total_size) < 0) {
- error("ERROR: %s: send failed\n", __func__);
+ logger(LL_ERROR, "%s: send failed\n", __func__);
break;
}
done += zr;
@@ -824,14 +834,14 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
#else
if (lstat(filepath, &fst) != 0) {
#endif
- error("ERROR: %s: stat failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: stat failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
return -1;
}
total_size = fst.st_size;
buffer = (unsigned char*)malloc(blocksize);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
free(filepath);
return -1;
}
@@ -840,7 +850,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (S_ISLNK(fst.st_mode)) {
ssize_t rl = readlink(filepath, (char*)buffer, (total_size > blocksize) ? blocksize : total_size);
if (rl < 0) {
- error("ERROR: %s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: readlink failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
free(buffer);
return -1;
@@ -850,7 +860,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
#endif
FILE *f = fopen(filepath, "rb");
if (!f) {
- error("ERROR: %s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: fopen failed for %s: %s\n", __func__, filepath, strerror(errno));
free(filepath);
free(buffer);
return -2;
@@ -861,11 +871,11 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
if (size > blocksize) size = blocksize;
size_t fr = fread(buffer, 1, size, f);
if (fr != size) {
- error("ERROR: %s: fread failed for %s: %s\n", __func__, filepath, strerror(errno));
+ logger(LL_ERROR, "%s: fread failed for %s: %s\n", __func__, filepath, strerror(errno));
break;
}
if (send_callback(ctx, buffer, fr, done, total_size) < 0) {
- error("ERROR: %s: send failed\n", __func__);
+ logger(LL_ERROR, "%s: send failed\n", __func__);
break;
}
done += fr;
@@ -879,7 +889,7 @@ int ipsw_extract_send(ipsw_archive_t ipsw, const char* infile, int blocksize, ip
}
if (done < total_size) {
- error("ERROR: %s: Sending file data for %s failed (sent %" PRIu64 "/%" PRIu64 ")\n", __func__, infile, (uint64_t)done, (uint64_t)total_size);
+ logger(LL_ERROR, "%s: Sending file data for %s failed (sent %" PRIu64 "/%" PRIu64 ")\n", __func__, infile, (uint64_t)done, (uint64_t)total_size);
return -1;
}
@@ -941,7 +951,7 @@ static int ipsw_list_contents_recurse(ipsw_archive_t ipsw, const char *path, ips
DIR *dirp = opendir(base);
if (!dirp) {
- error("ERROR: failed to open directory %s\n", base);
+ logger(LL_ERROR, "failed to open directory %s\n", base);
free(base);
return -1;
}
@@ -968,7 +978,7 @@ static int ipsw_list_contents_recurse(ipsw_archive_t ipsw, const char *path, ips
ret = lstat(fpath, &st);
#endif
if (ret != 0) {
- error("ERROR: %s: stat failed for %s: %s\n", __func__, fpath, strerror(errno));
+ logger(LL_ERROR, "%s: stat failed for %s: %s\n", __func__, fpath, strerror(errno));
free(fpath);
free(subpath);
break;
@@ -993,7 +1003,7 @@ int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx)
int ret = 0;
if (ipsw == NULL) {
- error("ERROR: Invalid IPSW archive\n");
+ logger(LL_ERROR, "Invalid IPSW archive\n");
return -1;
}
@@ -1001,13 +1011,13 @@ int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx)
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return -1;
}
int64_t entries = zip_get_num_entries(zip, 0);
if (entries < 0) {
- error("ERROR: zip_get_num_entries failed\n");
+ logger(LL_ERROR, "zip_get_num_entries failed\n");
return -1;
}
@@ -1016,7 +1026,7 @@ int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx)
zip_stat_init(&stat);
if (zip_stat_index(zip, index, 0, &stat) < 0) {
- error("ERROR: zip_stat_index failed for %s\n", stat.name);
+ logger(LL_ERROR, "zip_stat_index failed for %s\n", stat.name);
ret = -1;
continue;
}
@@ -1024,12 +1034,12 @@ int ipsw_list_contents(ipsw_archive_t ipsw, ipsw_list_cb cb, void *ctx)
uint8_t opsys;
uint32_t attributes;
if (zip_file_get_external_attributes(zip, index, 0, &opsys, &attributes) < 0) {
- error("ERROR: zip_file_get_external_attributes failed for %s\n", stat.name);
+ logger(LL_ERROR, "zip_file_get_external_attributes failed for %s\n", stat.name);
ret = -1;
continue;
}
if (opsys != ZIP_OPSYS_UNIX) {
- error("ERROR: File %s does not have UNIX attributes\n", stat.name);
+ logger(LL_ERROR, "File %s does not have UNIX attributes\n", stat.name);
ret = -1;
continue;
}
@@ -1079,32 +1089,32 @@ int ipsw_get_signed_firmwares(const char* product, plist_t* firmwares)
snprintf(url, sizeof(url), "https://api.ipsw.me/v4/device/%s", product);
if (download_to_buffer(url, &jdata, &jsize) < 0) {
- error("ERROR: Download from %s failed.\n", url);
+ logger(LL_ERROR, "Download from %s failed.\n", url);
return -1;
}
plist_from_json(jdata, jsize, &dict);
free(jdata);
if (!dict || plist_get_node_type(dict) != PLIST_DICT) {
- error("ERROR: Failed to parse json data.\n");
+ logger(LL_ERROR, "Failed to parse json data.\n");
plist_free(dict);
return -1;
}
node = plist_dict_get_item(dict, "identifier");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- error("ERROR: Unexpected json data returned - missing 'identifier'\n");
+ logger(LL_ERROR, "Unexpected json data returned - missing 'identifier'\n");
plist_free(dict);
return -1;
}
product_type = plist_get_string_ptr(node, NULL);
if (!product_type || strcmp(product_type, product) != 0) {
- error("ERROR: Unexpected json data returned - failed to read identifier\n");
+ logger(LL_ERROR, "Unexpected json data returned - failed to read identifier\n");
plist_free(dict);
return -1;
}
fws = plist_dict_get_item(dict, "firmwares");
if (!fws || plist_get_node_type(fws) != PLIST_ARRAY) {
- error("ERROR: Unexpected json data returned - missing 'firmwares'\n");
+ logger(LL_ERROR, "Unexpected json data returned - missing 'firmwares'\n");
plist_free(dict);
return -1;
}
@@ -1136,14 +1146,14 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
plist_t n1 = plist_dict_get_item(version_data, "MobileDeviceSoftwareVersionsByVersion");
if (!n1) {
- error("%s: ERROR: Can't find MobileDeviceSoftwareVersionsByVersion dict in version data\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't find MobileDeviceSoftwareVersionsByVersion dict in version data\n", __func__);
return -1;
}
plist_dict_iter iter = NULL;
plist_dict_new_iter(n1, &iter);
if (!iter) {
- error("%s: ERROR: Can't get dict iter\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't get dict iter\n", __func__);
return -1;
}
char* key = NULL;
@@ -1164,7 +1174,7 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
free(iter);
if (major == 0) {
- error("%s: ERROR: Can't find major version?!\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't find major version?!\n", __func__);
return -1;
}
@@ -1172,13 +1182,13 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
snprintf(majstr, sizeof(majstr), "%"PRIu64, (uint64_t)major);
n1 = plist_access_path(version_data, 7, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", product, "Unknown", "Universal", "Restore");
if (!n1) {
- error("%s: ERROR: Can't get Unknown/Universal/Restore node?!\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't get Unknown/Universal/Restore node?!\n", __func__);
return -1;
}
plist_t n2 = plist_dict_get_item(n1, "BuildVersion");
if (!n2 || (plist_get_node_type(n2) != PLIST_STRING)) {
- error("%s: ERROR: Can't get build version node?!\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't get build version node?!\n", __func__);
return -1;
}
@@ -1187,7 +1197,7 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
n1 = plist_access_path(version_data, 5, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", product, strval);
if (!n1) {
- error("%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s node?!\n", __func__, strval);
+ logger(LL_ERROR, "%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s node?!\n", __func__, strval);
free(strval);
return -1;
}
@@ -1203,7 +1213,7 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
free(strval);
strval = NULL;
if (!n1 || (plist_dict_get_size(n1) == 0)) {
- error("%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s dict\n", __func__, product);
+ logger(LL_ERROR, "%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s dict\n", __func__, product);
return -1;
}
}
@@ -1221,7 +1231,7 @@ int ipsw_get_latest_fw(plist_t version_data, const char* product, char** fwurl,
n2 = plist_access_path(n1, 2, "Restore", "FirmwareURL");
if (!n2 || (plist_get_node_type(n2) != PLIST_STRING)) {
- error("%s: ERROR: Can't get FirmwareURL node\n", __func__);
+ logger(LL_ERROR, "%s: ERROR: Can't get FirmwareURL node\n", __func__);
return -1;
}
@@ -1254,13 +1264,23 @@ static int sha1_verify_fp(FILE* f, unsigned char* expected_sha1)
{
unsigned char tsha1[20];
char buf[8192];
+ size_t total = 0;
+ struct stat fst;
+ int lastprog = 0;
if (!f) return 0;
sha1_context sha1ctx;
sha1_init(&sha1ctx);
rewind(f);
+ fstat(fileno(f), &fst);
while (!feof(f)) {
size_t sz = fread(buf, 1, 8192, f);
sha1_update(&sha1ctx, buf, sz);
+ total += sz;
+ double p = (double)total / (double)fst.st_size;
+ if ((int)(p*100) > lastprog) {
+ set_progress('SHA1', p);
+ lastprog = (int)(p*100);
+ }
}
sha1_final(&sha1ctx, tsha1);
return (memcmp(expected_sha1, tsha1, 20) == 0) ? 1 : 0;
@@ -1270,7 +1290,7 @@ int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir,
{
char* fwfn = strrchr(fwurl, '/');
if (!fwfn) {
- error("ERROR: can't get local filename for firmware ipsw\n");
+ logger(LL_ERROR, "can't get local filename for firmware ipsw\n");
return -2;
}
fwfn++;
@@ -1288,7 +1308,7 @@ int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir,
lock_info_t lockinfo;
if (lock_file(fwlock, &lockinfo) != 0) {
- error("WARNING: Could not lock file '%s'\n", fwlock);
+ logger(LL_WARNING, "Could not lock file '%s'\n", fwlock);
}
int need_dl = 0;
@@ -1296,13 +1316,15 @@ int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir,
FILE* f = fopen(fwlfn, "rb");
if (f) {
if (memcmp(zsha1, isha1, 20) != 0) {
- info("Verifying '%s'...\n", fwlfn);
+ logger(LL_INFO, "Verifying '%s'...\n", fwlfn);
+ register_progress('SHA1', "Verifying");
if (sha1_verify_fp(f, isha1)) {
- info("Checksum matches.\n");
+ logger(LL_INFO, "Checksum matches.\n");
} else {
- info("Checksum does not match.\n");
+ logger(LL_INFO, "Checksum does not match.\n");
need_dl = 1;
}
+ finalize_progress('SHA1');
}
fclose(f);
} else {
@@ -1312,29 +1334,35 @@ int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir,
int res = 0;
if (need_dl) {
if (strncmp(fwurl, "protected:", 10) == 0) {
- error("ERROR: Can't download '%s' because it needs a purchase.\n", fwfn);
+ logger(LL_ERROR, "Can't download '%s' because it needs a purchase.\n", fwfn);
res = -3;
} else {
remove(fwlfn);
- info("Downloading firmware (%s)\n", fwurl);
+ logger(LL_INFO, "Downloading firmware (%s)\n", fwurl);
download_to_file(fwurl, fwlfn, 1);
+ if (global_quit_flag > 0) {
+ logger(LL_NOTICE, "Download aborted by user\n");
+ return -1;
+ }
if (memcmp(isha1, zsha1, 20) != 0) {
- info("\nVerifying '%s'...\n", fwlfn);
+ logger(LL_INFO, "Verifying '%s'...\n", fwlfn);
FILE* f = fopen(fwlfn, "rb");
if (f) {
+ register_progress('SHA1', "Verifying");
if (sha1_verify_fp(f, isha1)) {
- info("Checksum matches.\n");
+ logger(LL_INFO, "Checksum matches.\n");
} else {
- error("ERROR: File download failed (checksum mismatch).\n");
+ logger(LL_ERROR, "File download failed (checksum mismatch).\n");
res = -4;
}
+ finalize_progress('SHA1');
fclose(f);
// make sure to remove invalid files
if (res < 0)
remove(fwlfn);
} else {
- error("ERROR: Can't open '%s' for checksum verification\n", fwlfn);
+ logger(LL_ERROR, "Can't open '%s' for checksum verification\n", fwlfn);
res = -5;
}
}
@@ -1345,7 +1373,7 @@ int ipsw_download_fw(const char *fwurl, unsigned char* isha1, const char* todir,
}
if (unlock_file(&lockinfo) != 0) {
- error("WARNING: Could not unlock file '%s'\n", fwlock);
+ logger(LL_WARNING, "Could not unlock file '%s'\n", fwlock);
}
return res;
@@ -1359,17 +1387,17 @@ int ipsw_download_latest_fw(plist_t version_data, const char* product, const cha
*ipswfile = NULL;
if ((ipsw_get_latest_fw(version_data, product, &fwurl, isha1) < 0) || !fwurl) {
- error("ERROR: can't get URL for latest firmware\n");
+ logger(LL_ERROR, "can't get URL for latest firmware\n");
return -1;
}
char* fwfn = strrchr(fwurl, '/');
if (!fwfn) {
- error("ERROR: can't get local filename for firmware ipsw\n");
+ logger(LL_ERROR, "can't get local filename for firmware ipsw\n");
return -2;
}
fwfn++;
- info("Latest firmware is %s\n", fwfn);
+ logger(LL_INFO, "Latest firmware is %s\n", fwfn);
int res = ipsw_download_fw(fwurl, isha1, todir, ipswfile);
@@ -1390,14 +1418,14 @@ ipsw_file_handle_t ipsw_file_open(ipsw_archive_t ipsw, const char* path)
int err = 0;
struct zip *zip = zip_open(ipsw->path, 0, &err);
if (zip == NULL) {
- error("ERROR: zip_open: %s: %d\n", ipsw->path, err);
+ logger(LL_ERROR, "zip_open: %s: %d\n", ipsw->path, err);
return NULL;
}
zip_stat_t zst;
zip_int64_t zindex = zip_name_locate(zip, path, 0);
if (zindex < 0) {
- error("ERROR: zip_name_locate: %s not found\n", path);
+ logger(LL_ERROR, "zip_name_locate: %s not found\n", path);
zip_unchange_all(zip);
zip_close(zip);
free(handle);
@@ -1405,7 +1433,7 @@ ipsw_file_handle_t ipsw_file_open(ipsw_archive_t ipsw, const char* path)
}
handle->zfile = zip_fopen_index(zip, zindex, 0);
if (handle->zfile == NULL) {
- error("ERROR: zip_fopen_index: %s could not be opened\n", path);
+ logger(LL_ERROR, "zip_fopen_index: %s could not be opened\n", path);
zip_unchange_all(zip);
zip_close(zip);
free(handle);
@@ -1422,7 +1450,7 @@ ipsw_file_handle_t ipsw_file_open(ipsw_archive_t ipsw, const char* path)
handle->file = fopen(filepath, "rb");
free(filepath);
if (!handle->file) {
- error("ERROR: fopen: %s could not be opened\n", path);
+ logger(LL_ERROR, "fopen: %s could not be opened\n", path);
free(handle);
return NULL;
}
@@ -1461,7 +1489,7 @@ int64_t ipsw_file_read(ipsw_file_handle_t handle, void* buffer, size_t size)
} else if (handle && handle->file) {
return fread(buffer, 1, size, handle->file);
} else {
- error("ERROR: %s: Invalid file handle\n", __func__);
+ logger(LL_ERROR, "%s: Invalid file handle\n", __func__);
return -1;
}
}
@@ -1480,7 +1508,7 @@ int ipsw_file_seek(ipsw_file_handle_t handle, int64_t offset, int whence)
return fseeko(handle->file, offset, whence);
#endif
} else {
- error("ERROR: %s: Invalid file handle\n", __func__);
+ logger(LL_ERROR, "%s: Invalid file handle\n", __func__);
return -1;
}
}
@@ -1496,7 +1524,7 @@ int64_t ipsw_file_tell(ipsw_file_handle_t handle)
return ftello(handle->file);
#endif
} else {
- error("ERROR: %s: Invalid file handle\n", __func__);
+ logger(LL_ERROR, "%s: Invalid file handle\n", __func__);
return -1;
}
}
diff --git a/src/limera1n.c b/src/limera1n.c
index da4a7d5..f205287 100644
--- a/src/limera1n.c
+++ b/src/limera1n.c
@@ -78,7 +78,7 @@ int limera1n_exploit(struct irecv_device *device, irecv_client_t *pclient)
stack_address = 0x84033F98;
shellcode_address = 0x84023001;
} else {
- error("Unsupported ChipID 0x%04x. Can't exploit with limera1n.\n", device->chip_id);
+ logger(LL_ERROR, "Unsupported ChipID 0x%04x. Can't exploit with limera1n.\n", device->chip_id);
return -1;
}
@@ -87,10 +87,10 @@ int limera1n_exploit(struct irecv_device *device, irecv_client_t *pclient)
irecv_client_t client = *pclient;
- debug("Resetting device counters\n");
+ logger(LL_DEBUG, "Resetting device counters\n");
err = irecv_reset_counters(client);
if (err != IRECV_E_SUCCESS) {
- error("%s\n", irecv_strerror(err));
+ logger(LL_ERROR, "%s\n", irecv_strerror(err));
return -1;
}
@@ -103,7 +103,7 @@ int limera1n_exploit(struct irecv_device *device, irecv_client_t *pclient)
heap[3] = stack_address;
}
- debug("Sending chunk headers\n");
+ logger(LL_DEBUG, "Sending chunk headers\n");
irecv_usb_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 1000);
memset(buf, 0xCC, 0x800);
@@ -111,32 +111,32 @@ int limera1n_exploit(struct irecv_device *device, irecv_client_t *pclient)
irecv_usb_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 1000);
}
- debug("Sending exploit payload\n");
+ logger(LL_DEBUG, "Sending exploit payload\n");
irecv_usb_control_transfer(client, 0x21, 1, 0, 0, shellcode, 0x800, 1000);
- debug("Sending fake data\n");
+ logger(LL_DEBUG, "Sending fake data\n");
memset(buf, 0xBB, 0x800);
irecv_usb_control_transfer(client, 0xA1, 1, 0, 0, buf, 0x800, 1000);
irecv_usb_control_transfer(client, 0x21, 1, 0, 0, buf, 0x800, 10);
- //debug("Executing exploit\n");
+ //logger(LL_DEBUG, "Executing exploit\n");
irecv_usb_control_transfer(client, 0x21, 2, 0, 0, buf, 0, 1000);
irecv_reset(client);
irecv_finish_transfer(client);
- debug("Exploit sent\n");
+ logger(LL_DEBUG, "Exploit sent\n");
- debug("Reconnecting to device\n");
+ logger(LL_DEBUG, "Reconnecting to device\n");
*pclient = irecv_reconnect(client, 7);
if (*pclient == NULL) {
- error("Unable to reconnect\n");
+ logger(LL_ERROR, "Unable to reconnect\n");
return -1;
}
irecv_get_mode((*pclient), &mode);
if (mode != IRECV_K_DFU_MODE) {
- error("Device reconnected in non-DFU mode\n");
+ logger(LL_ERROR, "Device reconnected in non-DFU mode\n");
return -1;
}
diff --git a/src/locking.c b/src/locking.c
index dbbbd7c..05f0e4f 100644
--- a/src/locking.c
+++ b/src/locking.c
@@ -35,7 +35,7 @@ int lock_file(const char* filename, lock_info_t* lockinfo)
#ifdef WIN32
lockinfo->fp = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (lockinfo->fp == INVALID_HANDLE_VALUE) {
- debug("ERROR: could not open or create lockfile '%s'\n", filename);
+ logger(LL_DEBUG, "ERROR: could not open or create lockfile '%s'\n", filename);
return -1;
}
@@ -43,7 +43,7 @@ int lock_file(const char* filename, lock_info_t* lockinfo)
lockinfo->ldata.OffsetHigh = 0;
if (!LockFileEx(lockinfo->fp, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &lockinfo->ldata)) {
- debug("ERROR: can't lock file, error %d\n", GetLastError());
+ logger(LL_DEBUG, "ERROR: can't lock file, error %d\n", GetLastError());
CloseHandle(lockinfo->fp);
lockinfo->fp = INVALID_HANDLE_VALUE;
return -1;
@@ -52,7 +52,7 @@ int lock_file(const char* filename, lock_info_t* lockinfo)
lockinfo->fp = fopen(filename, "a+");
if (!lockinfo->fp) {
- debug("ERROR: could not open or create lockfile '%s'\n", filename);
+ logger(LL_DEBUG, "ERROR: could not open or create lockfile '%s'\n", filename);
return -1;
}
@@ -62,7 +62,7 @@ int lock_file(const char* filename, lock_info_t* lockinfo)
lockinfo->ldata.l_len = 0;
if (fcntl(fileno(lockinfo->fp), F_SETLKW, &lockinfo->ldata) < 0) {
- debug("ERROR: can't lock file, error %d\n", errno);
+ logger(LL_DEBUG, "ERROR: can't lock file, error %d\n", errno);
fclose(lockinfo->fp);
lockinfo->fp = NULL;
return -1;
@@ -85,7 +85,7 @@ int unlock_file(lock_info_t* lockinfo)
lockinfo->ldata.OffsetHigh = 0;
if (!UnlockFileEx(lockinfo->fp, 0, 1, 0, &lockinfo->ldata)) {
- debug("ERROR: can't unlock file, error %d\n", GetLastError());
+ logger(LL_DEBUG, "ERROR: can't unlock file, error %d\n", GetLastError());
CloseHandle(lockinfo->fp);
lockinfo->fp = INVALID_HANDLE_VALUE;
return -1;
@@ -103,7 +103,7 @@ int unlock_file(lock_info_t* lockinfo)
lockinfo->ldata.l_len = 0;
if (fcntl(fileno(lockinfo->fp), F_SETLK, &lockinfo->ldata) < 0) {
- debug("ERROR: can't unlock file, error %d\n", errno);
+ logger(LL_DEBUG, "ERROR: can't unlock file, error %d\n", errno);
fclose(lockinfo->fp);
lockinfo->fp = NULL;
return -1;
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000..e6a3c8a
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,210 @@
+/*
+ * log.c
+ *
+ * Copyright (c) 2024 Nikias Bassen. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+#include <errno.h>
+
+#include <libimobiledevice-glue/thread.h>
+#include <plist/plist.h>
+
+#include "log.h"
+
+static int stderr_enabled = 1;
+
+int log_level = LL_VERBOSE;
+int print_level = LL_INFO;
+
+static void (*print_func)(int level, const char* fmt, va_list) = NULL;
+
+const char *_level_label[6] = {
+ " <Error>",
+ "<Warning>",
+ " <Notice>",
+ " <Info>",
+ "<Verbose>",
+ " <Debug>"
+};
+
+// Reference: https://stackoverflow.com/a/2390626/1806760
+// Initializer/finalizer sample for MSVC and GCC/Clang.
+// 2010-2016 Joe Lowe. Released into the public domain.
+
+#ifdef __cplusplus
+ #define INITIALIZER(f) \
+ static void f(void); \
+ struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
+ static void f(void)
+#elif defined(_MSC_VER)
+ #pragma section(".CRT$XCU",read)
+ #define INITIALIZER2_(f,p) \
+ static void f(void); \
+ __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
+ __pragma(comment(linker,"/include:" p #f "_")) \
+ static void f(void)
+ #ifdef _WIN64
+ #define INITIALIZER(f) INITIALIZER2_(f,"")
+ #else
+ #define INITIALIZER(f) INITIALIZER2_(f,"_")
+ #endif
+#else
+ #define INITIALIZER(f) \
+ static void f(void) __attribute__((__constructor__)); \
+ static void f(void)
+#endif
+
+static mutex_t log_mutex;
+
+static void logger_deinit(void)
+{
+ mutex_destroy(&log_mutex);
+}
+
+INITIALIZER(logger_init)
+{
+ mutex_init(&log_mutex);
+ atexit(logger_deinit);
+}
+
+void logger(enum loglevel level, const char *fmt, ...)
+{
+ va_list ap;
+ char *fs;
+
+ if (level > log_level)
+ return;
+
+ mutex_lock(&log_mutex);
+
+ size_t fslen = 24 + strlen(fmt);
+ fs = malloc(fslen);
+
+#ifdef _WIN32
+ SYSTEMTIME lt;
+ GetLocalTime(&lt);
+ snprintf(fs, 24, "%02d:%02d:%02d.%03d", lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
+#else
+ struct timeval ts;
+ struct tm tp_;
+ struct tm *tp;
+
+ gettimeofday(&ts, NULL);
+#ifdef HAVE_LOCALTIME_R
+ tp = localtime_r(&ts.tv_sec, &tp_);
+#else
+ tp = localtime(&ts.tv_sec);
+#endif
+
+ strftime(fs, 9, "%H:%M:%S", tp);
+ snprintf(fs+8, fslen-8, ".%03d %s %s", (int)(ts.tv_usec / 1000), _level_label[level], fmt);
+#endif
+
+ va_start(ap, fmt);
+ if (print_func) {
+ if (stderr_enabled) {
+ vfprintf(stderr, fs, ap);
+ fflush(stderr);
+ }
+ if (level <= print_level) {
+ // skip the timestamp and log level string
+ print_func(level, fs+23, ap);
+ }
+ } else {
+ vprintf(fs, ap);
+ }
+
+ va_end(ap);
+
+ free(fs);
+
+ mutex_unlock(&log_mutex);
+}
+
+void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len)
+{
+ char *fs;
+
+ if (level > log_level)
+ return;
+
+ mutex_lock(&log_mutex);
+
+ fs = (char*)malloc(len * 3 + 1);
+ for (unsigned int i = 0; i < len; i++) {
+ snprintf(fs + i*3, 3, "%02x%c", ((unsigned char*)buf)[i], (i < len-1) ? ' ' : '\n');
+ }
+ if (print_func) {
+ if (stderr_enabled) {
+ fprintf(stderr, "%s", fs);
+ fflush(stderr);
+ }
+ if (level <= print_level) {
+ print_func(level, "%s", fs);
+ }
+ } else {
+ printf("%s", fs);
+ }
+ free(fs);
+
+ mutex_unlock(&log_mutex);
+}
+
+void logger_dump_plist(enum loglevel level, plist_t plist, int human_readable)
+{
+ if (level > log_level)
+ return;
+ mutex_lock(&log_mutex);
+ plist_write_to_stream(plist, stderr_enabled ? stderr : stdout, (human_readable) ? PLIST_FORMAT_PRINT : PLIST_FORMAT_XML, PLIST_OPT_NONE);
+ mutex_unlock(&log_mutex);
+}
+
+int logger_set_logfile(const char* path)
+{
+ if (!path || !strcasecmp(path, "NULL") || !strcasecmp(path, "NONE")) {
+ stderr_enabled = 0;
+ return 0;
+ }
+ stderr_enabled = 1;
+ if (strcmp(path, "-")) {
+ FILE* newf = freopen(path, "w", stderr);
+ if (!newf) {
+ logger(LL_ERROR, "Could not open logfile '%s': %s\n", path, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void logger_set_print_func(void (*func)(int, const char*, va_list))
+{
+ print_func = func;
+}
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 0000000..80642c0
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,41 @@
+/*
+ * log.h
+ *
+ * Copyright (c) 2024 Nikias Bassen. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LOG_H
+#define LOG_H
+
+enum loglevel {
+ LL_ERROR = 0,
+ LL_WARNING,
+ LL_NOTICE,
+ LL_INFO,
+ LL_VERBOSE,
+ LL_DEBUG
+};
+
+extern int log_level;
+
+void logger(enum loglevel level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+int logger_set_logfile(const char* path);
+void logger_set_print_func(void (*func)(int level, const char*, va_list));
+void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len);
+void logger_dump_plist(enum loglevel level, plist_t plist, int human_readable);
+
+#endif
diff --git a/src/mbn.c b/src/mbn.c
index 101e29f..b7d3527 100644
--- a/src/mbn.c
+++ b/src/mbn.c
@@ -54,10 +54,10 @@ mbn_file* mbn_parse(unsigned char* data, unsigned int size)
// we cheat here since we don't parse the actual ELF file
mbn->parsed_size = mbn->size;
} else {
- debug("DEBUG: Unknown file format passed to %s\n", __func__);
+ logger(LL_DEBUG, "Unknown file format passed to %s\n", __func__);
}
if (mbn->parsed_size != mbn->size) {
- info("WARNING: size mismatch when parsing MBN file. Continuing anyway.\n");
+ logger(LL_WARNING, "Size mismatch when parsing MBN file. Continuing anyway.\n");
}
return mbn;
}
@@ -75,12 +75,12 @@ void mbn_free(mbn_file* mbn)
int mbn_update_sig_blob(mbn_file* mbn, const unsigned char* sigdata, unsigned int siglen)
{
if (!mbn) {
- error("ERROR: %s: no data\n", __func__);
+ logger(LL_ERROR, "%s: no data\n", __func__);
return -1;
}
mbn->parsed_sig_offset = mbn->size - siglen;
if ((mbn->parsed_sig_offset + siglen) > mbn->size) {
- error("ERROR: %s: signature is larger than mbn file size\n", __func__);
+ logger(LL_ERROR, "%s: signature is larger than mbn file size\n", __func__);
return -1;
}
diff --git a/src/normal.c b/src/normal.c
index 9e46080..7d689e1 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -49,12 +49,12 @@ static int normal_idevice_new(struct idevicerestore_client_t* client, idevice_t*
if (client->udid) {
device_error = idevice_new(&dev, client->udid);
if (device_error != IDEVICE_E_SUCCESS) {
- debug("%s: can't open device with UDID %s\n", __func__, client->udid);
+ logger(LL_DEBUG, "%s: can't open device with UDID %s\n", __func__, client->udid);
return -1;
}
if (lockdownd_client_new(dev, &lockdown, "idevicerestore") != LOCKDOWN_E_SUCCESS) {
- error("ERROR: %s: can't connect to lockdownd on device with UDID %s\n", __func__, client->udid);
+ logger(LL_ERROR, "%s: can't connect to lockdownd on device with UDID %s\n", __func__, client->udid);
return -1;
}
@@ -94,12 +94,12 @@ static int normal_idevice_new(struct idevicerestore_client_t* client, idevice_t*
}
device_error = idevice_new(&dev, devices[j]);
if (device_error != IDEVICE_E_SUCCESS) {
- debug("%s: can't open device with UDID %s\n", __func__, devices[j]);
+ logger(LL_DEBUG, "%s: can't open device with UDID %s\n", __func__, devices[j]);
continue;
}
if (lockdownd_client_new(dev, &lockdown, "idevicerestore") != LOCKDOWN_E_SUCCESS) {
- error("ERROR: %s: can't connect to lockdownd on device with UDID %s\n", __func__, devices[j]);
+ logger(LL_ERROR, "%s: can't connect to lockdownd on device with UDID %s\n", __func__, devices[j]);
continue;
}
@@ -170,10 +170,7 @@ irecv_device_t normal_get_irecv_device(struct idevicerestore_client_t* client)
lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
if (!(client->flags & FLAG_ERASE) && lockdown_error == LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING) {
- info("*** Device is not paired with this computer. Please trust this computer on the device to continue. ***\n");
- if (client->flags & FLAG_DEBUG) {
- idevice_set_debug_level(0);
- }
+ show_banner("Device is not paired with this computer. Please trust this computer on the device to continue.\n");
while (!(client->flags & FLAG_QUIT)) {
lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
if (lockdown_error != LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING) {
@@ -181,9 +178,7 @@ irecv_device_t normal_get_irecv_device(struct idevicerestore_client_t* client)
}
sleep(1);
}
- if (client->flags & FLAG_DEBUG) {
- idevice_set_debug_level(1);
- }
+ hide_banner();
if (client->flags & FLAG_QUIT) {
return NULL;
}
@@ -223,13 +218,13 @@ int normal_enter_recovery(struct idevicerestore_client_t* client)
device_error = idevice_new(&device, client->udid);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to find device\n");
+ logger(LL_ERROR, "Unable to find device\n");
return -1;
}
lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore");
if (lockdown_error != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Unable to connect to lockdownd: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
+ logger(LL_ERROR, "Unable to connect to lockdownd: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
idevice_free(device);
return -1;
}
@@ -239,14 +234,14 @@ int normal_enter_recovery(struct idevicerestore_client_t* client)
lockdownd_client_free(lockdown);
lockdown = NULL;
if (LOCKDOWN_E_SUCCESS != (lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"))) {
- error("ERROR: Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
+ logger(LL_ERROR, "Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
idevice_free(device);
return -1;
}
lockdown_error = lockdownd_enter_recovery(lockdown);
}
if (lockdown_error != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Unable to place device in recovery mode: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
+ logger(LL_ERROR, "Unable to place device in recovery mode: %s (%d)\n", lockdownd_strerror(lockdown_error), lockdown_error);
lockdownd_client_free(lockdown);
idevice_free(device);
return -1;
@@ -258,25 +253,25 @@ int normal_enter_recovery(struct idevicerestore_client_t* client)
device = NULL;
mutex_lock(&client->device_event_mutex);
- debug("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_NORMAL || (client->flags & FLAG_QUIT)) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Failed to place device in recovery mode\n");
+ logger(LL_ERROR, "Failed to place device in recovery mode\n");
return -1;
}
- debug("DEBUG: Waiting for device to connect in recovery mode...\n");
+ logger(LL_DEBUG, "Waiting for device to connect 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);
- error("ERROR: Failed to enter recovery mode\n");
+ logger(LL_ERROR, "Failed to enter recovery mode\n");
return -1;
}
mutex_unlock(&client->device_event_mutex);
if (recovery_client_new(client) < 0) {
- error("ERROR: Unable to enter recovery mode\n");
+ logger(LL_ERROR, "Unable to enter recovery mode\n");
return -1;
}
@@ -296,20 +291,20 @@ plist_t normal_get_lockdown_value(struct idevicerestore_client_t* client, const
device_error = idevice_new(&device, client->udid);
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to connect to device?!\n");
+ logger(LL_ERROR, "Unable to connect to device?!\n");
return NULL;
}
lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore");
if (lockdown_error != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Unable to connect to lockdownd\n");
+ logger(LL_ERROR, "Unable to connect to lockdownd\n");
idevice_free(device);
return NULL;
}
lockdown_error = lockdownd_get_value(lockdown, domain, key, &node);
if (lockdown_error != LOCKDOWN_E_SUCCESS) {
- debug("ERROR: Unable to get %s-%s from lockdownd\n", domain, key);
+ logger(LL_DEBUG, "ERROR: Unable to get %s-%s from lockdownd\n", domain, key);
lockdownd_client_free(lockdown);
idevice_free(device);
return NULL;
@@ -328,7 +323,7 @@ static int normal_get_nonce_by_key(struct idevicerestore_client_t* client, const
plist_t nonce_node = normal_get_lockdown_value(client, NULL, key);
if (!nonce_node || plist_get_node_type(nonce_node) != PLIST_DATA) {
- error("Unable to get %s\n", key);
+ logger(LL_ERROR, "Unable to get %s\n", key);
return -1;
}
@@ -389,12 +384,12 @@ int normal_get_firmware_preflight_info(struct idevicerestore_client_t* client, p
if (has_telephony_capability) {
node = normal_get_lockdown_value(client, NULL, "FirmwarePreflightInfo");
if (!node || plist_get_node_type(node) != PLIST_DICT) {
- error("ERROR: Unable to get FirmwarePreflightInfo\n");
+ logger(LL_ERROR, "Unable to get FirmwarePreflightInfo\n");
return -1;
}
*preflight_info = node;
} else {
- debug("DEBUG: Device does not have TelephonyCapability, no FirmwarePreflightInfo\n");
+ logger(LL_DEBUG, "Device does not have TelephonyCapability, no FirmwarePreflightInfo\n");
*preflight_info = NULL;
}
@@ -407,7 +402,7 @@ int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *p
if (PLIST_IS_DICT(node)) {
*preflight_info = node;
} else {
- debug("DEBUG: No PreflightInfo available.\n");
+ logger(LL_DEBUG, "No PreflightInfo available.\n");
*preflight_info = NULL;
}
return 0;
@@ -427,20 +422,25 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
device_err = idevice_new(&device, client->udid);
if (device_err != IDEVICE_E_SUCCESS) {
- error("ERROR: Could not connect to device (%d)\n", device_err);
+ logger(LL_ERROR, "Could not connect to device (%d)\n", device_err);
return -1;
}
lerr = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
+ if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) {
+ logger(LL_ERROR, "Device is locked. Unlock device and try again.\n");
+ idevice_free(device);
+ return -1;
+ }
if (lerr != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Could not connect to lockdownd (%d)\n", lerr);
+ logger(LL_ERROR, "Could not connect to lockdownd (%d)\n", lerr);
idevice_free(device);
return -1;
}
lerr = lockdownd_start_service(lockdown, PREBOARD_SERVICE_NAME, &service);
if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) {
- info("*** Device is locked. Please unlock the device to continue. ***\n");
+ show_banner("Device is locked. Please unlock the device to continue.\n");
while (1) {
lerr = lockdownd_start_service(lockdown, PREBOARD_SERVICE_NAME, &service);
if (lerr != LOCKDOWN_E_PASSWORD_PROTECTED) {
@@ -451,7 +451,7 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
}
if (lerr != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Could not start preboard service (%d)\n", lerr);
+ logger(LL_ERROR, "Could not start preboard service (%d)\n", lerr);
lockdownd_client_free(lockdown);
idevice_free(device);
return -1;
@@ -461,14 +461,14 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
lockdownd_service_descriptor_free(service);
lockdownd_client_free(lockdown);
if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: Could not connect to preboard service (%d)\n", perr);
+ logger(LL_ERROR, "Could not connect to preboard service (%d)\n", perr);
idevice_free(device);
return -1;
}
perr = preboard_create_stashbag(preboard, manifest, NULL, NULL);
if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: Failed to trigger stashbag creation (%d)\n", perr);
+ logger(LL_ERROR, "Failed to trigger stashbag creation (%d)\n", perr);
preboard_client_free(preboard);
idevice_free(device);
return -1;
@@ -481,25 +481,25 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
if (perr == PREBOARD_E_TIMEOUT) {
continue;
} else if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: could not receive from preboard service\n");
+ logger(LL_ERROR, "could not receive from preboard service\n");
break;
} else {
plist_t node;
if (plist_dict_get_bool(pl, "Skip")) {
result = 0;
- info("Device does not require stashbag.\n");
+ logger(LL_INFO, "Device does not require stashbag.\n");
break;
}
if (plist_dict_get_bool(pl, "ShowDialog")) {
- info("Device requires stashbag.\n");
- printf("******************************************************************************\n"
- "* Please enter your passcode on the device. The device will store a token *\n"
- "* that will be used after restore to access the user data partition. This *\n"
- "* prevents an 'Attempting data recovery' process occurring after reboot that *\n"
- "* may take a long time to complete and will _also_ require the passcode. *\n"
- "******************************************************************************\n");
+ logger(LL_INFO, "Device requires stashbag.\n");
+ show_banner(
+ "Please enter your passcode on the device. The device will store a token\n"
+ "that will be used after restore to access the user data partition. This\n"
+ "prevents an 'Attempting data recovery' process occurring after reboot that\n"
+ "may take a long time to complete and will _also_ require the passcode."
+ );
plist_free(pl);
continue;
}
@@ -510,13 +510,13 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
if (node) {
plist_get_string_val(node, &strval);
}
- error("ERROR: Could not create stashbag: %s\n", (strval) ? strval : "(Unknown error)");
+ logger(LL_ERROR, "Could not create stashbag: %s\n", (strval) ? strval : "(Unknown error)");
free(strval);
plist_free(pl);
break;
}
if (plist_dict_get_bool(pl, "Timeout")) {
- error("ERROR: Timeout while waiting for user to enter passcode.\n");
+ logger(LL_ERROR, "Timeout while waiting for user to enter passcode.\n");
result = -2;
plist_free(pl);
break;
@@ -525,12 +525,15 @@ int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_
plist_free(pl);
/* hide dialog */
result = 1;
- info("Stashbag created.\n");
+ logger(LL_INFO, "Stashbag created.\n");
break;
}
}
plist_free(pl);
}
+
+ hide_banner();
+
preboard_client_free(preboard);
idevice_free(device);
@@ -552,20 +555,20 @@ int normal_handle_commit_stashbag(struct idevicerestore_client_t* client, plist_
device_err = idevice_new(&device, client->udid);
if (device_err != IDEVICE_E_SUCCESS) {
- error("ERROR: Could not connect to device (%d)\n", device_err);
+ logger(LL_ERROR, "Could not connect to device (%d)\n", device_err);
return -1;
}
lerr = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
if (lerr != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Could not connect to lockdownd (%d)\n", lerr);
+ logger(LL_ERROR, "Could not connect to lockdownd (%d)\n", lerr);
idevice_free(device);
return -1;
}
lerr = lockdownd_start_service(lockdown, PREBOARD_SERVICE_NAME, &service);
if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) {
- info("*** Device is locked. Please unlock the device to continue. ***\n");
+ show_banner("Device is locked. Please unlock the device to continue.\n");
while (1) {
lerr = lockdownd_start_service(lockdown, PREBOARD_SERVICE_NAME, &service);
if (lerr != LOCKDOWN_E_PASSWORD_PROTECTED) {
@@ -573,10 +576,11 @@ int normal_handle_commit_stashbag(struct idevicerestore_client_t* client, plist_
}
sleep(1);
}
+ hide_banner();
}
if (lerr != LOCKDOWN_E_SUCCESS) {
- error("ERROR: Could not start preboard service (%d)\n", lerr);
+ logger(LL_ERROR, "Could not start preboard service (%d)\n", lerr);
lockdownd_client_free(lockdown);
idevice_free(device);
return -1;
@@ -586,14 +590,14 @@ int normal_handle_commit_stashbag(struct idevicerestore_client_t* client, plist_
lockdownd_service_descriptor_free(service);
lockdownd_client_free(lockdown);
if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: Could not connect to preboard service (%d)\n", perr);
+ logger(LL_ERROR, "Could not connect to preboard service (%d)\n", perr);
idevice_free(device);
return -1;
}
perr = preboard_commit_stashbag(preboard, manifest, NULL, NULL);
if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: Failed to trigger stashbag creation (%d)\n", perr);
+ logger(LL_ERROR, "Failed to trigger stashbag creation (%d)\n", perr);
preboard_client_free(preboard);
idevice_free(device);
return -1;
@@ -601,7 +605,7 @@ int normal_handle_commit_stashbag(struct idevicerestore_client_t* client, plist_
perr = preboard_receive_with_timeout(preboard, &pl, 30000);
if (perr != PREBOARD_E_SUCCESS) {
- error("ERROR: could not receive from preboard service (%d)\n", perr);
+ logger(LL_ERROR, "could not receive from preboard service (%d)\n", perr);
} else {
plist_t node = plist_dict_get_item(pl, "Error");
if (node) {
@@ -610,14 +614,14 @@ int normal_handle_commit_stashbag(struct idevicerestore_client_t* client, plist_
if (node) {
plist_get_string_val(node, &strval);
}
- error("ERROR: Could not commit stashbag: %s\n", (strval) ? strval : "(Unknown error)");
+ logger(LL_ERROR, "Could not commit stashbag: %s\n", (strval) ? strval : "(Unknown error)");
free(strval);
} else if (plist_dict_get_bool(pl, "StashbagCommitComplete")) {
- info("Stashbag committed!\n");
+ logger(LL_INFO, "Stashbag committed!\n");
result = 0;
} else {
- error("ERROR: Unexpected reply from preboard service\n");
- debug_plist(pl);
+ logger(LL_ERROR, "Unexpected reply from preboard service\n");
+ logger_dump_plist(LL_VERBOSE, pl, 1);
}
plist_free(pl);
}
diff --git a/src/recovery.c b/src/recovery.c
index c451350..3c0027f 100644
--- a/src/recovery.c
+++ b/src/recovery.c
@@ -39,14 +39,15 @@
static int recovery_progress_callback(irecv_client_t client, const irecv_event_t* event)
{
if (event->type == IRECV_PROGRESS) {
- //print_progress_bar(event->progress);
+ set_progress('RECV', (double)(event->progress/100.0));
}
return 0;
}
void recovery_client_free(struct idevicerestore_client_t* client)
{
- if(client) {
+ if (client) {
+ finalize_progress('RECV');
if (client->recovery) {
if(client->recovery->client) {
irecv_close(client->recovery->client);
@@ -68,7 +69,7 @@ int recovery_client_new(struct idevicerestore_client_t* client)
if(client->recovery == NULL) {
client->recovery = (struct recovery_client_t*)malloc(sizeof(struct recovery_client_t));
if (client->recovery == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
memset(client->recovery, 0, sizeof(struct recovery_client_t));
@@ -81,23 +82,24 @@ int recovery_client_new(struct idevicerestore_client_t* client)
}
if (i >= attempts) {
- error("ERROR: Unable to connect to device in recovery mode\n");
+ logger(LL_ERROR, "Unable to connect to device in recovery mode\n");
return -1;
}
sleep(4);
- debug("Retrying connection...\n");
+ logger(LL_DEBUG, "Retrying connection...\n");
}
if (client->srnm == NULL) {
const struct irecv_device_info *device_info = irecv_get_device_info(recovery);
if (device_info && device_info->srnm) {
client->srnm = strdup(device_info->srnm);
- info("INFO: device serial number is %s\n", client->srnm);
+ logger(LL_INFO, "INFO: device serial number is %s\n", client->srnm);
}
}
irecv_event_subscribe(recovery, IRECV_PROGRESS, &recovery_progress_callback, NULL);
+ register_progress('RECV', "Uploading");
client->recovery->client = recovery;
return 0;
}
@@ -108,13 +110,13 @@ int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable)
recovery_error = irecv_send_command(client->recovery->client, (enable) ? "setenv auto-boot true" : "setenv auto-boot false");
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to set auto-boot environmental variable\n");
+ logger(LL_ERROR, "Unable to set auto-boot environmental variable\n");
return -1;
}
recovery_error = irecv_send_command(client->recovery->client, "saveenv");
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to save environmental variable\n");
+ logger(LL_ERROR, "Unable to save environmental variable\n");
return -1;
}
@@ -124,7 +126,7 @@ int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable)
int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity)
{
if (client->build_major >= 8) {
- client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress");
+ client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1rogress");
} else if (client->macos_variant) {
client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress -restore");
}
@@ -141,21 +143,21 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
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 -1;
}
}
}
- info("Recovery Mode Environment:\n");
+ logger(LL_INFO, "Recovery Mode Environment:\n");
char* value = NULL;
irecv_getenv(client->recovery->client, "build-version", &value);
- info("iBoot build-version=%s\n", (value) ? value : "(unknown)");
+ logger(LL_INFO, "iBoot build-version=%s\n", (value) ? value : "(unknown)");
free(value);
value = NULL;
irecv_getenv(client->recovery->client, "build-style", &value);
- info("iBoot build-style=%s\n", (value) ? value : "(unknown)");
+ logger(LL_INFO, "iBoot build-style=%s\n", (value) ? value : "(unknown)");
free(value);
value = NULL;
@@ -165,11 +167,11 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
boot_stage = strtoul(value, NULL, 0);
}
if (boot_stage > 0) {
- info("iBoot boot-stage=%s\n", value);
+ logger(LL_INFO, "iBoot boot-stage=%s\n", value);
free(value);
value = NULL;
if (boot_stage != 2) {
- error("ERROR: iBoot should be at boot stage 2, continuing anyway...\n");
+ logger(LL_ERROR, "iBoot should be at boot stage 2, continuing anyway...\n");
}
}
@@ -179,12 +181,12 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
radio_error = strtoul(value, NULL, 0);
}
if (radio_error > 0) {
- info("radio-error=%s\n", value);
+ logger(LL_INFO, "radio-error=%s\n", value);
free(value);
value = NULL;
irecv_getenv(client->recovery->client, "radio-error-string", &value);
if (value) {
- info("radio-error-string=%s\n", value);
+ logger(LL_INFO, "radio-error-string=%s\n", value);
free(value);
value = NULL;
}
@@ -196,32 +198,32 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
/* send logo and show it */
if (recovery_send_applelogo(client, build_identity) < 0) {
- error("ERROR: Unable to send AppleLogo\n");
+ logger(LL_ERROR, "Unable to send AppleLogo\n");
return -1;
}
/* send components loaded by iBoot */
if (recovery_send_loaded_by_iboot(client, build_identity) < 0) {
- error("ERROR: Unable to send components supposed to be loaded by iBoot\n");
+ logger(LL_ERROR, "Unable to send components supposed to be loaded by iBoot\n");
return -1;
}
/* send ramdisk and run it */
if (recovery_send_ramdisk(client, build_identity) < 0) {
- error("ERROR: Unable to send Ramdisk\n");
+ logger(LL_ERROR, "Unable to send Ramdisk\n");
return -1;
}
/* send devicetree and load it */
if (recovery_send_component_and_command(client, build_identity, "RestoreDeviceTree", "devicetree") < 0) {
- error("ERROR: Unable to send DeviceTree\n");
+ logger(LL_ERROR, "Unable to send DeviceTree\n");
return -1;
}
if (build_identity_has_component(build_identity, "RestoreSEP")) {
/* send rsepfirmware and load it */
if (recovery_send_component_and_command(client, build_identity, "RestoreSEP", "rsepfirmware") < 0) {
- error("ERROR: Unable to send RestoreSEP\n");
+ logger(LL_ERROR, "Unable to send RestoreSEP\n");
return -1;
}
}
@@ -229,15 +231,15 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
mutex_lock(&client->device_event_mutex);
if (recovery_send_kernelcache(client, build_identity) < 0) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Unable to send KernelCache\n");
+ logger(LL_ERROR, "Unable to send KernelCache\n");
return -1;
}
- debug("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, 30000);
if (client->mode == MODE_RECOVERY || (client->flags & FLAG_QUIT)) {
mutex_unlock(&client->device_event_mutex);
- error("ERROR: Failed to place device in restore mode\n");
+ logger(LL_ERROR, "Failed to place device in restore mode\n");
return -1;
}
mutex_unlock(&client->device_event_mutex);
@@ -248,28 +250,28 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build
int recovery_send_ticket(struct idevicerestore_client_t* client)
{
if (!client->tss) {
- error("ERROR: ApTicket requested but no TSS present\n");
+ logger(LL_ERROR, "ApTicket requested but no TSS present\n");
return -1;
}
unsigned char* data = NULL;
uint32_t size = 0;
if (tss_response_get_ap_ticket(client->tss, &data, &size) < 0) {
- error("ERROR: Unable to get ApTicket from TSS request\n");
+ logger(LL_ERROR, "Unable to get ApTicket from TSS request\n");
return -1;
}
- info("Sending APTicket (%d bytes)\n", size);
+ logger(LL_INFO, "Sending APTicket (%d bytes)\n", size);
irecv_error_t err = irecv_send_buffer(client->recovery->client, data, size, 0);
free(data);
if (err != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send APTicket: %s\n", irecv_strerror(err));
+ logger(LL_ERROR, "Unable to send APTicket: %s\n", irecv_strerror(err));
return -1;
}
err = irecv_send_command(client->recovery->client, "ticket");
if (err != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send ticket command\n");
+ logger(LL_ERROR, "Unable to send ticket command\n");
return -1;
}
@@ -285,12 +287,12 @@ int recovery_send_component(struct idevicerestore_client_t* client, plist_t buil
if (client->tss) {
if (tss_response_get_path_by_entry(client->tss, component, &path) < 0) {
- debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component);
+ logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build_identity\n", component);
}
}
if (!path) {
if (build_identity_get_component_path(build_identity, component, &path) < 0) {
- error("ERROR: Unable to get path for component '%s'\n", component);
+ logger(LL_ERROR, "Unable to get path for component '%s'\n", component);
free(path);
return -1;
}
@@ -301,24 +303,24 @@ int recovery_send_component(struct idevicerestore_client_t* client, plist_t buil
int ret = extract_component(client->ipsw, path, &component_data, &component_size);
free(path);
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
- info("Sending %s (%d bytes)...\n", component, size);
+ logger(LL_INFO, "Sending %s (%d bytes)...\n", component, size);
// FIXME: Did I do this right????
err = irecv_send_buffer(client->recovery->client, data, size, 0);
free(data);
if (err != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(err));
+ logger(LL_ERROR, "Unable to send %s component: %s\n", component, irecv_strerror(err));
return -1;
}
@@ -330,13 +332,13 @@ int recovery_send_component_and_command(struct idevicerestore_client_t* client,
irecv_error_t recovery_error = IRECV_E_SUCCESS;
if (recovery_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
recovery_error = irecv_send_command(client->recovery->client, command);
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", component);
+ logger(LL_ERROR, "Unable to execute %s\n", component);
return -1;
}
@@ -355,13 +357,13 @@ int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_ide
}
if (recovery_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
recovery_error = irecv_send_command_breq(client->recovery->client, "go", 1);
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", component);
+ logger(LL_ERROR, "Unable to execute %s\n", component);
return -1;
}
irecv_usb_control_transfer(client->recovery->client, 0x21, 1, 0, 0, 0, 0, 5000);
@@ -378,7 +380,7 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t buil
return 0;
}
- info("Sending %s...\n", component);
+ logger(LL_INFO, "Sending %s...\n", component);
if (client->recovery == NULL) {
if (recovery_client_new(client) < 0) {
return -1;
@@ -386,19 +388,19 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t buil
}
if (recovery_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
recovery_error = irecv_send_command(client->recovery->client, "setpicture 4");
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to set %s\n", component);
+ logger(LL_ERROR, "Unable to set %s\n", component);
return -1;
}
recovery_error = irecv_send_command(client->recovery->client, "bgcolor 0 0 0");
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to display %s\n", component);
+ logger(LL_ERROR, "Unable to display %s\n", component);
return -1;
}
@@ -415,7 +417,7 @@ int recovery_send_loaded_by_iboot(struct idevicerestore_client_t* client, plist_
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");
return -1;
}
@@ -439,9 +441,9 @@ int recovery_send_loaded_by_iboot(struct idevicerestore_client_t* client, plist_
uint8_t b = 0;
plist_get_bool_val(iboot_node, &b);
if (b) {
- debug("DEBUG: %s is loaded by iBoot.\n", key);
+ logger(LL_DEBUG, "%s is loaded by iBoot.\n", key);
if (recovery_send_component_and_command(client, build_identity, key, "firmware") < 0) {
- error("ERROR: Unable to send component '%s' to device.\n", key);
+ logger(LL_ERROR, "Unable to send component '%s' to device.\n", key);
err++;
}
}
@@ -466,12 +468,12 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_
char* value = NULL;
irecv_getenv(client->recovery->client, "ramdisk-size", &value);
- info("ramdisk-size=%s\n", (value ? value : "(unknown)"));
+ logger(LL_INFO, "ramdisk-size=%s\n", (value ? value : "(unknown)"));
free(value);
value = NULL;
if (recovery_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
@@ -479,7 +481,7 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_
recovery_error = irecv_send_command(client->recovery->client, "ramdisk");
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", component);
+ logger(LL_ERROR, "Unable to execute %s\n", component);
return -1;
}
@@ -500,7 +502,7 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t bu
}
if (recovery_send_component(client, build_identity, component) < 0) {
- error("ERROR: Unable to send %s to device.\n", component);
+ logger(LL_ERROR, "Unable to send %s to device.\n", component);
return -1;
}
@@ -515,7 +517,7 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t bu
recovery_error = irecv_send_command_breq(client->recovery->client, "bootx", 1);
if (recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute %s\n", component);
+ logger(LL_ERROR, "Unable to execute %s\n", component);
return -1;
}
diff --git a/src/restore.c b/src/restore.c
index 2daeea2..8f4e023 100644
--- a/src/restore.c
+++ b/src/restore.c
@@ -127,7 +127,7 @@ int restore_client_new(struct idevicerestore_client_t* client)
{
struct restore_client_t* restore = (struct restore_client_t*) malloc(sizeof(struct restore_client_t));
if (restore == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
@@ -184,12 +184,12 @@ static int restore_idevice_new(struct idevicerestore_client_t* client, idevice_t
}
device_error = idevice_new(&dev, devices[j]);
if (device_error != IDEVICE_E_SUCCESS) {
- debug("%s: can't open device with UDID %s\n", __func__, devices[j]);
+ logger(LL_DEBUG, "%s: can't open device with UDID %s\n", __func__, devices[j]);
continue;
}
if (restored_client_new(dev, &restore, "idevicerestore") != RESTORE_E_SUCCESS) {
- debug("%s: can't connect to restored on device with UDID %s\n", __func__, devices[j]);
+ logger(LL_DEBUG, "%s: can't connect to restored on device with UDID %s\n", __func__, devices[j]);
continue;
}
@@ -285,7 +285,7 @@ irecv_device_t restore_get_irecv_device(struct idevicerestore_client_t* client)
if (client->srnm == NULL) {
if (restored_get_value(restore, "SerialNumber", &node) == RESTORE_E_SUCCESS) {
plist_get_string_val(node, &client->srnm);
- info("INFO: device serial number is %s\n", client->srnm);
+ logger(LL_INFO, "INFO: device serial number is %s\n", client->srnm);
plist_free(node);
node = NULL;
}
@@ -295,7 +295,7 @@ irecv_device_t restore_get_irecv_device(struct idevicerestore_client_t* client)
restored_client_free(restore);
idevice_free(device);
if (restore_error != RESTORE_E_SUCCESS || !node || plist_get_node_type(node) != PLIST_STRING) {
- error("ERROR: Unable to get HardwareModel from restored\n");
+ logger(LL_ERROR, "Unable to get HardwareModel from restored\n");
plist_free(node);
return NULL;
}
@@ -316,7 +316,7 @@ int restore_is_image4_supported(struct idevicerestore_client_t* client)
restored_error_t restore_error = RESTORE_E_SUCCESS;
if (idevice_new(&device, client->udid) != IDEVICE_E_SUCCESS) {
- error("ERROR: Could not connect to device %s\n", client->udid);
+ logger(LL_ERROR, "Could not connect to device %s\n", client->udid);
return -1;
}
@@ -351,14 +351,14 @@ int restore_reboot(struct idevicerestore_client_t* client)
{
if(client->restore == NULL) {
if (restore_open_with_timeout(client) < 0) {
- error("ERROR: Unable to open device in restore mode\n");
+ logger(LL_ERROR, "Unable to open device in restore mode\n");
return -1;
}
}
mutex_lock(&client->device_event_mutex);
- info("Rebooting restore mode device...\n");
+ logger(LL_INFO, "Rebooting restore mode device...\n");
restored_reboot(client->restore->client);
restored_client_free(client->restore->client);
@@ -379,7 +379,7 @@ static int restore_is_current_device(struct idevicerestore_client_t* client, con
return 0;
}
if (!client->ecid) {
- error("ERROR: %s: no ECID given in client data\n", __func__);
+ logger(LL_ERROR, "%s: no ECID given in client data\n", __func__);
return 0;
}
@@ -392,21 +392,21 @@ static int restore_is_current_device(struct idevicerestore_client_t* client, con
device_error = idevice_new(&device, udid);
if (device_error != IDEVICE_E_SUCCESS) {
- debug("%s: can't open device with UDID %s\n", __func__, udid);
+ logger(LL_DEBUG, "%s: can't open device with UDID %s\n", __func__, udid);
return 0;
}
restore_error = restored_client_new(device, &restored, "idevicerestore");
if (restore_error != RESTORE_E_SUCCESS) {
- debug("%s: can't connect to restored\n", __func__);
+ logger(LL_DEBUG, "%s: can't connect to restored\n", __func__);
idevice_free(device);
return 0;
}
restore_error = restored_query_type(restored, &type, &version);
if ((restore_error == RESTORE_E_SUCCESS) && type && (strcmp(type, "com.apple.mobile.restored") == 0)) {
- debug("%s: Connected to %s, version %d\n", __func__, type, (int)version);
+ logger(LL_DEBUG, "%s: Connected to %s, version %d\n", __func__, type, (int)version);
} else {
- debug("%s: device %s is not in restore mode\n", __func__, udid);
+ logger(LL_DEBUG, "%s: device %s is not in restore mode\n", __func__, udid);
restored_client_free(restored);
idevice_free(device);
return 0;
@@ -415,7 +415,7 @@ static int restore_is_current_device(struct idevicerestore_client_t* client, con
plist_t hwinfo = NULL;
restore_error = restored_query_value(restored, "HardwareInfo", &hwinfo);
if ((restore_error != RESTORE_E_SUCCESS) || !hwinfo) {
- error("ERROR: %s: Unable to get HardwareInfo from restored\n", __func__);
+ logger(LL_ERROR, "%s: Unable to get HardwareInfo from restored\n", __func__);
restored_client_free(restored);
idevice_free(device);
plist_free(hwinfo);
@@ -432,7 +432,7 @@ static int restore_is_current_device(struct idevicerestore_client_t* client, con
plist_free(hwinfo);
if (this_ecid == 0) {
- error("ERROR: %s: Unable to get ECID from restored\n", __func__);
+ logger(LL_ERROR, "%s: Unable to get ECID from restored\n", __func__);
return 0;
}
@@ -454,7 +454,7 @@ int restore_open_with_timeout(struct idevicerestore_client_t* client)
}
if (client->ecid == 0) {
- error("ERROR: no ECID in client data!\n");
+ logger(LL_ERROR, "no ECID in client data!\n");
return -1;
}
@@ -462,7 +462,7 @@ int restore_open_with_timeout(struct idevicerestore_client_t* client)
if (client->restore == NULL) {
client->restore = (struct restore_client_t*) malloc(sizeof(struct restore_client_t));
if(client->restore == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
return -1;
}
memset(client->restore, '\0', sizeof(struct restore_client_t));
@@ -471,11 +471,11 @@ int restore_open_with_timeout(struct idevicerestore_client_t* client)
restore_device_connected = 0;
if (!restore_is_current_device(client, client->udid)) {
- error("ERROR: Unable to connect to device in restore mode\n");
+ logger(LL_ERROR, "Unable to connect to device in restore mode\n");
return -1;
}
- info("Connecting now...\n");
+ logger(LL_INFO, "Connecting now...\n");
device_error = idevice_new(&device, client->udid);
if (device_error != IDEVICE_E_SUCCESS) {
return -1;
@@ -490,9 +490,9 @@ int restore_open_with_timeout(struct idevicerestore_client_t* client)
restore_error = restored_query_type(restored, &type, &version);
if ((restore_error == RESTORE_E_SUCCESS) && type && (strcmp(type, "com.apple.mobile.restored") == 0)) {
client->restore->protocol_version = version;
- info("Connected to %s, version %d\n", type, (int)version);
+ logger(LL_INFO, "Connected to %s, version %d\n", type, (int)version);
} else {
- error("ERROR: Unable to connect to restored, error=%d\n", restore_error);
+ logger(LL_ERROR, "Unable to connect to restored, error=%d\n", restore_error);
restored_client_free(restored);
idevice_free(device);
return -1;
@@ -668,9 +668,9 @@ static void* _restore_get_service_client_for_data_request(struct idevicerestore_
(char*)data_type_str
};
property_list_service_client_t plclient = NULL;
- info("Connecting to %s data port %u\n", data_type_str, data_port);
+ logger(LL_INFO, "Connecting to %s data port %u\n", data_type_str, data_port);
if (property_list_service_client_new(client->restore->device, &svcdesc, &plclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
- error("ERROR: Failed to start service connection for %s on port %u\n", data_type_str, data_port);
+ logger(LL_ERROR, "Failed to start service connection for %s on port %u\n", data_type_str, data_port);
free(service);
return NULL;
}
@@ -747,12 +747,12 @@ static int restore_handle_previous_restore_log_msg(restored_client_t client, pli
node = plist_dict_get_item(msg, "PreviousRestoreLog");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- debug("Failed to parse restore log from PreviousRestoreLog plist\n");
+ logger(LL_DEBUG, "Failed to parse restore log from PreviousRestoreLog plist\n");
return -1;
}
plist_get_string_val(node, &restorelog);
- info("Previous Restore Log Received:\n%s\n", restorelog);
+ logger(LL_INFO, "Previous Restore Log Received:\n%s\n", restorelog);
free(restorelog);
return 0;
@@ -766,14 +766,14 @@ int restore_handle_progress_msg(struct idevicerestore_client_t* client, plist_t
node = plist_dict_get_item(msg, "Operation");
if (!node || plist_get_node_type(node) != PLIST_UINT) {
- debug("Failed to parse operation from ProgressMsg plist\n");
+ logger(LL_DEBUG, "Failed to parse operation from ProgressMsg plist\n");
return -1;
}
plist_get_uint_val(node, &operation);
node = plist_dict_get_item(msg, "Progress");
if (!node || plist_get_node_type(node) != PLIST_UINT) {
- debug("Failed to parse progress from ProgressMsg plist \n");
+ logger(LL_DEBUG, "Failed to parse progress from ProgressMsg plist \n");
return -1;
}
plist_get_uint_val(node, &progress);
@@ -788,7 +788,7 @@ int restore_handle_progress_msg(struct idevicerestore_client_t* client, plist_t
if ((progress > 0) && (progress <= 100)) {
if ((int)operation != lastop) {
- info("%s (%d)\n", restore_progress_string(adapted_operation), (int)operation);
+ logger(LL_INFO, "%s (%d)\n", restore_progress_string(adapted_operation), (int)operation);
}
switch (adapted_operation) {
case RESTORE_IMAGE:
@@ -812,11 +812,11 @@ int restore_handle_progress_msg(struct idevicerestore_client_t* client, plist_t
case REQUESTING_EAN_DATA:
break;
default:
- debug("Unhandled progress operation %d (%d)\n", adapted_operation, (int)operation);
+ logger(LL_DEBUG, "Unhandled progress operation %d (%d)\n", adapted_operation, (int)operation);
break;
}
} else {
- info("%s (%d)\n", restore_progress_string(adapted_operation), (int)operation);
+ logger(LL_INFO, "%s (%d)\n", restore_progress_string(adapted_operation), (int)operation);
}
lastop = (int)operation;
@@ -828,7 +828,7 @@ int restore_handle_status_msg(struct idevicerestore_client_t* client, plist_t ms
int result = 0;
uint64_t value = 0;
char* log = NULL;
- info("Got status message\n");
+ logger(LL_INFO, "Got status message\n");
// read status code
plist_t node = plist_dict_get_item(msg, "Status");
@@ -836,34 +836,34 @@ int restore_handle_status_msg(struct idevicerestore_client_t* client, plist_t ms
switch(value) {
case 0:
- info("Status: Restore Finished\n");
+ logger(LL_INFO, "Status: Restore Finished\n");
restore_finished = 1;
break;
case 0xFFFFFFFFFFFFFFFFLL:
- info("Status: Verification Error\n");
+ logger(LL_INFO, "Status: Verification Error\n");
break;
case 6:
- info("Status: Disk Failure\n");
+ logger(LL_INFO, "Status: Disk Failure\n");
break;
case 14:
- info("Status: Fail\n");
+ logger(LL_INFO, "Status: Fail\n");
break;
case 27:
- info("Status: Failed to mount filesystems.\n");
+ logger(LL_INFO, "Status: Failed to mount filesystems.\n");
break;
case 50:
case 51:
- info("Status: Failed to load SEP Firmware.\n");
+ logger(LL_INFO, "Status: Failed to load SEP Firmware.\n");
break;
case 53:
- info("Status: Failed to recover FDR data.\n");
+ logger(LL_INFO, "Status: Failed to recover FDR data.\n");
break;
case 1015:
- info("Status: X-Gold Baseband Update Failed. Defective Unit?\n");
+ logger(LL_INFO, "Status: X-Gold Baseband Update Failed. Defective Unit?\n");
break;
default:
- info("Unhandled status message (%" PRIu64 ")\n", value);
- debug_plist(msg);
+ logger(LL_INFO, "Unhandled status message (%" PRIu64 ")\n", value);
+ logger_dump_plist(LL_VERBOSE, msg, 1);
break;
}
@@ -881,7 +881,7 @@ int restore_handle_status_msg(struct idevicerestore_client_t* client, plist_t ms
node = plist_dict_get_item(msg, "Log");
if (node && plist_get_node_type(node) == PLIST_STRING) {
plist_get_string_val(node, &log);
- info("Log is available:\n%s\n", log);
+ logger(LL_INFO, "Log is available:\n%s\n", log);
free(log);
log = NULL;
}
@@ -902,47 +902,47 @@ static int restore_handle_baseband_updater_output_data(struct idevicerestore_cli
idevice_error_t device_error = IDEVICE_E_SUCCESS;
if (!client || !client->restore || !client->restore->build_identity || !client->restore->device) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- debug("Connecting to baseband updater data port\n");
+ logger(LL_DEBUG, "Connecting to baseband updater data port\n");
while (--attempts > 0) {
device_error = idevice_connect(client->restore->device, data_port, &connection);
if (device_error == IDEVICE_E_SUCCESS) {
break;
}
sleep(1);
- debug("Retrying connection...\n");
+ logger(LL_DEBUG, "Retrying connection...\n");
}
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to connect to baseband updater data port\n");
+ logger(LL_ERROR, "Unable to connect to baseband updater data port\n");
return result;
}
int fl = snprintf(NULL, 0, "updater_output-%s.cpio", client->udid);
if (fl < 0) {
idevice_disconnect(connection);
- error("ERROR: snprintf failed?!\n");
+ logger(LL_ERROR, "snprintf failed?!\n");
return result;
}
char* updater_out_fn = malloc(fl+1);
if (!updater_out_fn) {
idevice_disconnect(connection);
- error("ERROR: Could not allocate buffer for filename\n");
+ logger(LL_ERROR, "Could not allocate buffer for filename\n");
return result;
}
snprintf(updater_out_fn, fl+1, "updater_output-%s.cpio", client->udid);
FILE* f = fopen(updater_out_fn, "wb");
if (!f) {
- error("Could not open %s for writing, will not write baseband updater output data.\n", updater_out_fn);
+ logger(LL_ERROR, "Could not open %s for writing, will not write baseband updater output data.\n", updater_out_fn);
}
const int bufsize = 65536;
char* buf = malloc(bufsize);
if (!buf) {
free(updater_out_fn);
idevice_disconnect(connection);
- error("ERROR: Could not allocate buffer\n");
+ logger(LL_ERROR, "Could not allocate buffer\n");
return result;
}
uint32_t size = 0;
@@ -953,7 +953,7 @@ static int restore_handle_baseband_updater_output_data(struct idevicerestore_cli
}
if (f) {
fclose(f);
- info("Wrote baseband updater output data to %s\n", updater_out_fn);
+ logger(LL_INFO, "Wrote baseband updater output data to %s\n", updater_out_fn);
}
free(updater_out_fn);
free(buf);
@@ -971,7 +971,7 @@ static int restore_handle_bb_update_status_msg(struct idevicerestore_client_t* c
plist_get_bool_val(node, &accepted);
if (!accepted) {
- error("ERROR: device didn't accept BasebandData\n");
+ logger(LL_ERROR, "device didn't accept BasebandData\n");
return result;
}
@@ -982,27 +982,32 @@ static int restore_handle_bb_update_status_msg(struct idevicerestore_client_t* c
}
if (done) {
- info("Updating Baseband completed.\n");
+ logger(LL_INFO, "Updating Baseband completed.\n");
plist_t provisioning = plist_access_path(message, 2, "Output", "provisioning");
if (provisioning && plist_get_node_type(provisioning) == PLIST_DICT) {
char* sval = NULL;
node = plist_dict_get_item(provisioning, "IMEI");
if (node && plist_get_node_type(node) == PLIST_STRING) {
plist_get_string_val(node, &sval);
- info("Provisioning:\n");
- info("IMEI:%s\n", sval);
+ logger(LL_INFO, "Provisioning:\n");
+ logger(LL_INFO, "IMEI:%s\n", sval);
free(sval);
sval = NULL;
}
}
} else {
- info("Updating Baseband in progress...\n");
+ logger(LL_INFO, "Updating Baseband in progress...\n");
}
result = 0;
return result;
}
+struct _restore_asr_progress_data {
+ struct idevicerestore_client_t* client;
+ uint32_t tag;
+};
+
static void restore_asr_progress_cb(double progress, void* userdata)
{
struct idevicerestore_client_t* client = (struct idevicerestore_client_t*)userdata;
@@ -1019,14 +1024,14 @@ int restore_send_filesystem(struct idevicerestore_client_t* client, plist_t mess
char* fsname = NULL;
if (!client || !client->restore || !client->restore->build_identity || !client->restore->device) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- info("About to send filesystem...\n");
+ logger(LL_INFO, "About to send filesystem...\n");
if (build_identity_get_component_path(client->restore->build_identity, "OS", &fsname) < 0) {
- error("ERROR: Unable to get path for filesystem component\n");
+ logger(LL_ERROR, "Unable to get path for filesystem component\n");
return -1;
}
if (client->filesystem) {
@@ -1040,7 +1045,7 @@ int restore_send_filesystem(struct idevicerestore_client_t* client, plist_t mess
file = ipsw_file_open(client->ipsw, fsname);
}
if (!file) {
- error("ERROR: Unable to open '%s' in ipsw\n", fsname);
+ logger(LL_ERROR, "Unable to open '%s' in ipsw\n", fsname);
free(fsname);
}
@@ -1051,41 +1056,41 @@ int restore_send_filesystem(struct idevicerestore_client_t* client, plist_t mess
if (asr_open_with_timeout(client->restore->device, &asr, asr_port) < 0) {
ipsw_file_close(file);
ipsw_close(ipsw_dummy);
- error("ERROR: Unable to connect to ASR\n");
+ logger(LL_ERROR, "Unable to connect to ASR\n");
return -1;
}
- info("Connected to ASR\n");
-
- if (asr_port == ASR_DEFAULT_PORT) {
- asr_set_progress_callback(asr, restore_asr_progress_cb, (void*)client);
- }
+ logger(LL_INFO, "Connected to ASR\n");
// this step sends requested chunks of data from various offsets to asr so
// it can validate the filesystem before installing it
- info("Validating the filesystem\n");
+ logger(LL_INFO, "Validating the filesystem\n");
if (asr_perform_validation(asr, file) < 0) {
ipsw_file_close(file);
ipsw_close(ipsw_dummy);
- error("ERROR: ASR was unable to validate the filesystem\n");
+ logger(LL_ERROR, "ASR was unable to validate the filesystem\n");
asr_free(asr);
return -1;
}
- info("Filesystem validated\n");
+ logger(LL_INFO, "Filesystem validated\n");
+
+ if (asr_port == ASR_DEFAULT_PORT) {
+ asr_set_progress_callback(asr, restore_asr_progress_cb, client);
+ }
// once the target filesystem has been validated, ASR then requests the
// entire filesystem to be sent.
- info("Sending filesystem now...\n");
+ logger(LL_INFO, "Sending filesystem now...\n");
if (asr_send_payload(asr, file) < 0) {
ipsw_file_close(file);
ipsw_close(ipsw_dummy);
- error("ERROR: Unable to send payload to ASR\n");
+ logger(LL_ERROR, "Unable to send payload to ASR\n");
asr_free(asr);
return -1;
}
ipsw_file_close(file);
ipsw_close(ipsw_dummy);
- info("Done sending filesystem\n");
+ logger(LL_INFO, "Done sending filesystem\n");
asr_free(asr);
return 0;
@@ -1096,7 +1101,7 @@ int restore_send_recovery_os_root_ticket(struct idevicerestore_client_t* client,
restored_error_t restore_error;
plist_t dict;
- info("About to send RecoveryOSRootTicket...\n");
+ logger(LL_INFO, "About to send RecoveryOSRootTicket...\n");
if (client->root_ticket) {
dict = plist_new_dict();
@@ -1106,18 +1111,18 @@ int restore_send_recovery_os_root_ticket(struct idevicerestore_client_t* client,
unsigned int len = 0;
if (!client->tss_recoveryos_root_ticket && !(client->flags & FLAG_CUSTOM)) {
- error("ERROR: Cannot send RootTicket without TSS\n");
+ logger(LL_ERROR, "Cannot send RootTicket without TSS\n");
return -1;
}
if (client->image4supported) {
if (tss_response_get_ap_img4_ticket(client->tss_recoveryos_root_ticket, &data, &len) < 0) {
- error("ERROR: Unable to get ApImg4Ticket from TSS\n");
+ logger(LL_ERROR, "Unable to get ApImg4Ticket from TSS\n");
return -1;
}
} else {
if (!(client->flags & FLAG_CUSTOM) && (tss_response_get_ap_ticket(client->tss, &data, &len) < 0)) {
- error("ERROR: Unable to get ticket from TSS\n");
+ logger(LL_ERROR, "Unable to get ticket from TSS\n");
return -1;
}
}
@@ -1126,27 +1131,27 @@ int restore_send_recovery_os_root_ticket(struct idevicerestore_client_t* client,
if (data && (len > 0)) {
plist_dict_set_item(dict, "RootTicketData", plist_new_data((char*)data, len));
} else {
- info("NOTE: not sending RootTicketData (no data present)\n");
+ logger(LL_NOTICE, "Not sending RootTicketData (no data present)\n");
}
free(data);
}
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending RecoveryOSRootTicket now...\n");
+ logger(LL_INFO, "Sending RecoveryOSRootTicket now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send RootTicket (%d)\n", restore_error);
+ logger(LL_ERROR, "Unable to send RootTicket (%d)\n", restore_error);
return -1;
}
- info("Done sending RecoveryOS RootTicket\n");
+ logger(LL_INFO, "Done sending RecoveryOS RootTicket\n");
return 0;
}
@@ -1156,7 +1161,7 @@ int restore_send_root_ticket(struct idevicerestore_client_t* client, plist_t mes
restored_error_t restore_error;
plist_t dict;
- info("About to send RootTicket...\n");
+ logger(LL_INFO, "About to send RootTicket...\n");
if (client->root_ticket) {
dict = plist_new_dict();
@@ -1166,18 +1171,18 @@ int restore_send_root_ticket(struct idevicerestore_client_t* client, plist_t mes
unsigned int len = 0;
if (!client->tss && !(client->flags & FLAG_CUSTOM)) {
- error("ERROR: Cannot send RootTicket without TSS\n");
+ logger(LL_ERROR, "Cannot send RootTicket without TSS\n");
return -1;
}
if (client->image4supported) {
if (tss_response_get_ap_img4_ticket(client->tss, &data, &len) < 0) {
- error("ERROR: Unable to get ApImg4Ticket from TSS\n");
+ logger(LL_ERROR, "Unable to get ApImg4Ticket from TSS\n");
return -1;
}
} else {
if (!(client->flags & FLAG_CUSTOM) && (tss_response_get_ap_ticket(client->tss, &data, &len) < 0)) {
- error("ERROR: Unable to get ticket from TSS\n");
+ logger(LL_ERROR, "Unable to get ticket from TSS\n");
return -1;
}
}
@@ -1186,27 +1191,27 @@ int restore_send_root_ticket(struct idevicerestore_client_t* client, plist_t mes
if (data && (len > 0)) {
plist_dict_set_item(dict, "RootTicketData", plist_new_data((char*)data, len));
} else {
- info("NOTE: not sending RootTicketData (no data present)\n");
+ logger(LL_INFO, "Not sending RootTicketData (no data present)\n");
}
free(data);
}
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending RootTicket now...\n");
+ logger(LL_INFO, "Sending RootTicket now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send RootTicket (%d)\n", restore_error);
+ logger(LL_ERROR, "Unable to send RootTicket (%d)\n", restore_error);
return -1;
}
- info("Done sending RootTicket\n");
+ logger(LL_INFO, "Done sending RootTicket\n");
return 0;
}
@@ -1259,29 +1264,29 @@ static size_t _curl_header_callback(char* buffer, size_t size, size_t nitems, vo
int restore_send_url_asset(struct idevicerestore_client_t* client, plist_t message)
{
- debug("DEBUG: %s\n", __func__);
+ logger(LL_DEBUG, "%s\n", __func__);
plist_t arguments = plist_dict_get_item(message, "Arguments");
if (!PLIST_IS_DICT(arguments)) {
- error("ERROR: %s: Unexpected arguments\n", __func__);
- debug_plist(arguments);
+ logger(LL_ERROR, "%s: Unexpected arguments\n", __func__);
+ logger_dump_plist(LL_VERBOSE, arguments, 1);
return -1;
}
const char* request_method = plist_get_string_ptr(plist_dict_get_item(arguments, "RequestMethod"), NULL);
if (!request_method) {
- error("ERROR: %s: Unable to extract RequestMethod from Arguments\n", __func__);
+ logger(LL_ERROR, "%s: Unable to extract RequestMethod from Arguments\n", __func__);
return -1;
}
if (strcmp(request_method, "GET")) {
- error("ERROR: %s: Unexpected RequestMethod '%s' in message\n", __func__, request_method);
+ logger(LL_ERROR, "%s: Unexpected RequestMethod '%s' in message\n", __func__, request_method);
return -1;
}
const char* request_url = plist_get_string_ptr(plist_dict_get_item(arguments, "RequestURL"), NULL);
if (!request_url) {
- error("ERROR: %s: Unable to extract RequestURL from Arguments\n", __func__);
+ logger(LL_ERROR, "%s: Unable to extract RequestURL from Arguments\n", __func__);
return -1;
}
- info("Requesting URLAsset from %s\n", request_url);
+ logger(LL_INFO, "Requesting URLAsset from %s\n", request_url);
char curl_error_message[CURL_ERROR_SIZE];
CURL* handle = curl_easy_init();
@@ -1290,7 +1295,7 @@ int restore_send_url_asset(struct idevicerestore_client_t* client, plist_t messa
query_response* response = malloc(sizeof(query_response));
if (response == NULL) {
- error("ERROR: %s: Unable to allocate sufficient memory\n", __func__);
+ logger(LL_ERROR, "%s: Unable to allocate sufficient memory\n", __func__);
return -1;
}
@@ -1305,7 +1310,7 @@ int restore_send_url_asset(struct idevicerestore_client_t* client, plist_t messa
plist_t response_headers = plist_new_dict();
curl_easy_setopt(handle, CURLOPT_HEADERDATA, response_headers);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
- if (idevicerestore_debug) {
+ if (client->debug_level > 0) {
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
}
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
@@ -1327,7 +1332,7 @@ int restore_send_url_asset(struct idevicerestore_client_t* client, plist_t messa
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
@@ -1339,26 +1344,26 @@ int restore_send_url_asset(struct idevicerestore_client_t* client, plist_t messa
int restore_send_streamed_image_decryption_key(struct idevicerestore_client_t* client, plist_t message)
{
- debug("DEBUG: %s\n", __func__);
+ logger(LL_DEBUG, "%s\n", __func__);
plist_t arguments = plist_dict_get_item(message, "Arguments");
if (!PLIST_IS_DICT(arguments)) {
- error("ERROR: %s: Unexpected arguments\n", __func__);
- debug_plist(arguments);
+ logger(LL_ERROR, "%s: Unexpected arguments\n", __func__);
+ logger_dump_plist(LL_VERBOSE, arguments, 1);
return -1;
}
const char* request_method = plist_get_string_ptr(plist_dict_get_item(arguments, "RequestMethod"), NULL);
if (!request_method) {
- error("ERROR: %s: Unable to extract RequestMethod from Arguments\n", __func__);
+ logger(LL_ERROR, "%s: Unable to extract RequestMethod from Arguments\n", __func__);
return -1;
}
if (strcmp(request_method, "POST")) {
- error("ERROR: %s: Unexpected RequestMethod '%s' in message\n", __func__, request_method);
+ logger(LL_ERROR, "%s: Unexpected RequestMethod '%s' in message\n", __func__, request_method);
return -1;
}
const char* request_url = plist_get_string_ptr(plist_dict_get_item(arguments, "RequestURL"), NULL);
if (!request_url) {
- error("ERROR: %s: Unable to extract RequestURL from Arguments\n", __func__);
+ logger(LL_ERROR, "%s: Unable to extract RequestURL from Arguments\n", __func__);
return -1;
}
@@ -1366,18 +1371,18 @@ int restore_send_streamed_image_decryption_key(struct idevicerestore_client_t* c
plist_t headers = plist_dict_get_item(arguments, "RequestAdditionalHeaders");
if (!headers) {
- error("ERROR: %s: Missing 'RequestAdditionalHeaders'\n", __func__);
+ logger(LL_ERROR, "%s: Missing 'RequestAdditionalHeaders'\n", __func__);
return -1;
}
uint64_t request_body_size = 0;
const char* request_body = plist_get_data_ptr(plist_dict_get_item(arguments, "RequestBody"), &request_body_size);
if (!request_body) {
- error("ERROR: %s: Missing 'RequestBody'\n", __func__);
+ logger(LL_ERROR, "%s: Missing 'RequestBody'\n", __func__);
return -1;
}
- info("Requesting image decryption key from %s\n", request_url);
+ logger(LL_INFO, "Requesting image decryption key from %s\n", request_url);
char curl_error_message[CURL_ERROR_SIZE];
char header_tmp[1024];
@@ -1399,7 +1404,7 @@ int restore_send_streamed_image_decryption_key(struct idevicerestore_client_t* c
query_response* response = malloc(sizeof(query_response));
if (response == NULL) {
- error("ERROR: %s: Unable to allocate sufficient memory\n", __func__);
+ logger(LL_ERROR, "%s: Unable to allocate sufficient memory\n", __func__);
return -1;
}
@@ -1416,7 +1421,7 @@ int restore_send_streamed_image_decryption_key(struct idevicerestore_client_t* c
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, request_body);
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, request_body_size);
- if (idevicerestore_debug) {
+ if (client->debug_level > 0) {
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
}
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
@@ -1439,7 +1444,7 @@ int restore_send_streamed_image_decryption_key(struct idevicerestore_client_t* c
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
@@ -1459,7 +1464,7 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
restored_error_t restore_error = RESTORE_E_SUCCESS;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
@@ -1467,16 +1472,16 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
component_name = component;
}
- info("About to send %s...\n", component_name);
+ logger(LL_INFO, "About to send %s...\n", component_name);
if (client->tss) {
if (tss_response_get_path_by_entry(client->tss, component, &path) < 0) {
- debug("NOTE: No path for component %s in TSS, will fetch from build identity\n", component);
+ logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build identity\n", component);
}
}
if (!path) {
if (build_identity_get_component_path(client->restore->build_identity, component, &path) < 0) {
- error("ERROR: Unable to find %s path from build identity\n", component);
+ logger(LL_ERROR, "Unable to find %s path from build identity\n", component);
return -1;
}
}
@@ -1487,7 +1492,7 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
free(path);
path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract component %s\n", component);
+ logger(LL_ERROR, "Unable to extract component %s\n", component);
return -1;
}
@@ -1495,7 +1500,7 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
free(component_data);
component_data = NULL;
if (ret < 0) {
- error("ERROR: Unable to get personalized component %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component %s\n", component);
return -1;
}
@@ -1508,20 +1513,20 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending %s now...\n", component_name);
+ logger(LL_INFO, "Sending %s now...\n", component_name);
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send component %s data\n", component_name);
+ logger(LL_ERROR, "Unable to send component %s data\n", component_name);
return -1;
}
- info("Done sending %s\n", component_name);
+ logger(LL_INFO, "Done sending %s\n", component_name);
return 0;
}
@@ -1546,11 +1551,11 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
int flash_version_1 = 0;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- info("About to send NORData...\n");
+ logger(LL_INFO, "About to send NORData...\n");
plist_t arguments = plist_dict_get_item(message, "Arguments");
if (arguments && plist_get_node_type(arguments) == PLIST_DICT) {
@@ -1559,26 +1564,26 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
if (client->tss) {
if (tss_response_get_path_by_entry(client->tss, "LLB", &llb_path) < 0) {
- debug("NOTE: Could not get LLB path from TSS data, will fetch from build identity\n");
+ logger(LL_DEBUG, "Could not get LLB path from TSS data, will fetch from build identity\n");
}
}
if (llb_path == NULL) {
if (build_identity_get_component_path(client->restore->build_identity, "LLB", &llb_path) < 0) {
- error("ERROR: Unable to get component path for LLB\n");
+ logger(LL_ERROR, "Unable to get component path for LLB\n");
return -1;
}
}
llb_filename = strstr(llb_path, "LLB");
if (llb_filename == NULL) {
- error("ERROR: Unable to extract firmware path from LLB filename\n");
+ logger(LL_ERROR, "Unable to extract firmware path from LLB filename\n");
free(llb_path);
return -1;
}
memset(firmware_path, '\0', sizeof(firmware_path));
memcpy(firmware_path, llb_path, (llb_filename - 1) - llb_path);
- info("Found firmware path %s\n", firmware_path);
+ logger(LL_INFO, "Found firmware path %s\n", firmware_path);
memset(manifest_file, '\0', sizeof(manifest_file));
snprintf(manifest_file, sizeof(manifest_file), "%s/manifest", firmware_path);
@@ -1588,7 +1593,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
ipsw_extract_to_memory(client->ipsw, manifest_file, &manifest_data, &manifest_size);
}
if (manifest_data && manifest_size > 0) {
- info("Getting firmware manifest from %s\n", manifest_file);
+ logger(LL_INFO, "Getting firmware manifest from %s\n", manifest_file);
char *manifest_p = (char*)manifest_data;
char *filename = NULL;
while ((filename = strsep(&manifest_p, "\r\n")) != NULL) {
@@ -1601,7 +1606,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
}
free(manifest_data);
} else {
- info("Getting firmware manifest from build identity\n");
+ logger(LL_INFO, "Getting firmware manifest from build identity\n");
plist_dict_iter iter = NULL;
plist_t build_id_manifest = plist_dict_get_item(client->restore->build_identity, "Manifest");
if (build_id_manifest) {
@@ -1649,7 +1654,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
}
if (plist_dict_get_size(firmware_files) == 0) {
- error("ERROR: Unable to get list of firmware files.\n");
+ logger(LL_ERROR, "Unable to get list of firmware files.\n");
return -1;
}
@@ -1659,7 +1664,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
int ret = extract_component(client->ipsw, llb_path, &component_data, &component_size);
free(llb_path);
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
@@ -1668,7 +1673,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
component_data = NULL;
component_size = 0;
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
@@ -1715,7 +1720,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
free(comp);
free(comppath);
plist_free(firmware_files);
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
@@ -1725,7 +1730,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
free(comppath);
free(component_data);
plist_free(firmware_files);
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
free(component_data);
@@ -1762,7 +1767,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
ret = extract_component(client->ipsw, restore_sep_path, &component_data, &component_size);
free(restore_sep_path);
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
@@ -1771,7 +1776,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
component_data = NULL;
component_size = 0;
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
@@ -1787,7 +1792,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
ret = extract_component(client->ipsw, sep_path, &component_data, &component_size);
free(sep_path);
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
@@ -1796,7 +1801,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
component_data = NULL;
component_size = 0;
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
@@ -1812,7 +1817,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
ret = extract_component(client->ipsw, sep_path, &component_data, &component_size);
free(sep_path);
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
return -1;
}
@@ -1821,7 +1826,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
component_data = NULL;
component_size = 0;
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
return -1;
}
@@ -1831,25 +1836,25 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
personalized_size = 0;
}
- if (idevicerestore_debug)
- debug_plist(dict);
+ if (client->debug_level > 1)
+ logger_dump_plist(LL_DEBUG, dict, 0);
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending NORData now...\n");
+ logger(LL_INFO, "Sending NORData now...\n");
restored_error_t restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send NORData\n");
+ logger(LL_ERROR, "Unable to send NORData\n");
return -1;
}
- info("Done sending NORData\n");
+ logger(LL_INFO, "Done sending NORData\n");
return 0;
}
@@ -1900,13 +1905,13 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
// check for BBTicket in result
plist_t bbticket = plist_dict_get_item(bbtss, "BBTicket");
if (!bbticket || plist_get_node_type(bbticket) != PLIST_DATA) {
- error("ERROR: Could not find BBTicket in Baseband TSS response\n");
+ logger(LL_ERROR, "Could not find BBTicket in Baseband TSS response\n");
return -1;
}
plist_t bbfw_dict = plist_dict_get_item(bbtss, "BasebandFirmware");
if (!bbfw_dict || plist_get_node_type(bbfw_dict) != PLIST_DICT) {
- error("ERROR: Could not find BasebandFirmware Dictionary node in Baseband TSS response\n");
+ logger(LL_ERROR, "Could not find BasebandFirmware Dictionary node in Baseband TSS response\n");
return -1;
}
@@ -1926,14 +1931,14 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
za = zip_open(bbfwtmp, 0, &zerr);
if (!za) {
- error("ERROR: Could not open ZIP archive '%s': %d\n", bbfwtmp, zerr);
+ logger(LL_ERROR, "Could not open ZIP archive '%s': %d\n", bbfwtmp, zerr);
goto leave;
}
plist_dict_iter iter = NULL;
plist_dict_new_iter(bbfw_dict, &iter);
if (!iter) {
- error("ERROR: Could not create dict iter for BasebandFirmware Dictionary\n");
+ logger(LL_ERROR, "Could not create dict iter for BasebandFirmware Dictionary\n");
return -1;
}
@@ -1951,7 +1956,7 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
*ptr = '\0';
const char* signfn = restore_get_bbfw_fn_for_element(key);
if (!signfn) {
- error("ERROR: can't match element name '%s' to baseband firmware file name.\n", key);
+ logger(LL_ERROR, "can't match element name '%s' to baseband firmware file name.\n", key);
goto leave;
}
char* ext = strrchr(signfn, '.');
@@ -1961,30 +1966,30 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
zindex = zip_name_locate(za, signfn, 0);
if (zindex < 0) {
- error("ERROR: can't locate '%s' in '%s'\n", signfn, bbfwtmp);
+ logger(LL_ERROR, "can't locate '%s' in '%s'\n", signfn, bbfwtmp);
goto leave;
}
zip_stat_init(&zstat);
if (zip_stat_index(za, zindex, 0, &zstat) != 0) {
- error("ERROR: zip_stat_index failed for index %" PRIi64 "\n", zindex);
+ logger(LL_ERROR, "zip_stat_index failed for index %" PRIi64 "\n", zindex);
goto leave;
}
zfile = zip_fopen_index(za, zindex, 0);
if (zfile == NULL) {
- error("ERROR: zip_fopen_index failed for index %" PRIi64 "\n", zindex);
+ logger(LL_ERROR, "zip_fopen_index failed for index %" PRIi64 "\n", zindex);
goto leave;
}
buffer = (unsigned char*) malloc(zstat.size + 1);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
goto leave;
}
if (zip_fread(zfile, buffer, zstat.size) != zstat.size) {
- error("ERROR: zip_fread: failed\n");
+ logger(LL_ERROR, "zip_fread: failed\n");
goto leave;
}
buffer[zstat.size] = '\0';
@@ -1995,13 +2000,13 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
if (is_fls) {
fls = fls_parse(buffer, zstat.size);
if (!fls) {
- error("ERROR: could not parse fls file\n");
+ logger(LL_ERROR, "could not parse fls file\n");
goto leave;
}
} else {
mbn = mbn_parse(buffer, zstat.size);
if (!mbn) {
- error("ERROR: could not parse mbn file\n");
+ logger(LL_ERROR, "could not parse mbn file\n");
goto leave;
}
}
@@ -2011,18 +2016,18 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
blob_size = 0;
blob = (const unsigned char*)plist_get_data_ptr(node, &blob_size);
if (!blob) {
- error("ERROR: could not get %s-Blob data\n", key);
+ logger(LL_ERROR, "could not get %s-Blob data\n", key);
goto leave;
}
if (is_fls) {
if (fls_update_sig_blob(fls, blob, (unsigned int)blob_size) != 0) {
- error("ERROR: could not sign %s\n", signfn);
+ logger(LL_ERROR, "could not sign %s\n", signfn);
goto leave;
}
} else {
if (mbn_update_sig_blob(mbn, blob, (unsigned int)blob_size) != 0) {
- error("ERROR: could not sign %s\n", signfn);
+ logger(LL_ERROR, "could not sign %s\n", signfn);
goto leave;
}
}
@@ -2030,7 +2035,7 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
fsize = (is_fls ? fls->size : mbn->size);
fdata = (unsigned char*)malloc(fsize);
if (fdata == NULL) {
- error("ERROR: out of memory\n");
+ logger(LL_ERROR, "out of memory\n");
goto leave;
}
if (is_fls) {
@@ -2045,13 +2050,13 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
zs = zip_source_buffer(za, fdata, fsize, 1);
if (!zs) {
- error("ERROR: out of memory\n");
+ logger(LL_ERROR, "out of memory\n");
free(fdata);
goto leave;
}
if (zip_file_replace(za, zindex, zs, 0) == -1) {
- error("ERROR: could not update signed '%s' in archive\n", signfn);
+ logger(LL_ERROR, "could not update signed '%s' in archive\n", signfn);
goto leave;
}
@@ -2099,30 +2104,30 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
// add BBTicket to file ebl.fls
zindex = zip_name_locate(za, "ebl.fls", 0);
if (zindex < 0) {
- error("ERROR: can't locate 'ebl.fls' in '%s'\n", bbfwtmp);
+ logger(LL_ERROR, "can't locate 'ebl.fls' in '%s'\n", bbfwtmp);
goto leave;
}
zip_stat_init(&zstat);
if (zip_stat_index(za, zindex, 0, &zstat) != 0) {
- error("ERROR: zip_stat_index failed for index %" PRIi64 "\n", zindex);
+ logger(LL_ERROR, "zip_stat_index failed for index %" PRIi64 "\n", zindex);
goto leave;
}
zfile = zip_fopen_index(za, zindex, 0);
if (zfile == NULL) {
- error("ERROR: zip_fopen_index failed for index %" PRIi64 "\n", zindex);
+ logger(LL_ERROR, "zip_fopen_index failed for index %" PRIi64 "\n", zindex);
goto leave;
}
buffer = (unsigned char*) malloc(zstat.size + 1);
if (buffer == NULL) {
- error("ERROR: Out of memory\n");
+ logger(LL_ERROR, "Out of memory\n");
goto leave;
}
if (zip_fread(zfile, buffer, zstat.size) != zstat.size) {
- error("ERROR: zip_fread: failed\n");
+ logger(LL_ERROR, "zip_fread: failed\n");
goto leave;
}
buffer[zstat.size] = '\0';
@@ -2134,26 +2139,26 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
free(buffer);
buffer = NULL;
if (!fls) {
- error("ERROR: could not parse fls file\n");
+ logger(LL_ERROR, "could not parse fls file\n");
goto leave;
}
blob_size = 0;
blob = (const unsigned char*)plist_get_data_ptr(bbticket, &blob_size);
if (!blob) {
- error("ERROR: could not get BBTicket data\n");
+ logger(LL_ERROR, "could not get BBTicket data\n");
goto leave;
}
if (fls_insert_ticket(fls, blob, (unsigned int)blob_size) != 0) {
- error("ERROR: could not insert BBTicket to ebl.fls\n");
+ logger(LL_ERROR, "could not insert BBTicket to ebl.fls\n");
goto leave;
}
fsize = fls->size;
fdata = (unsigned char*)malloc(fsize);
if (!fdata) {
- error("ERROR: out of memory\n");
+ logger(LL_ERROR, "out of memory\n");
goto leave;
}
memcpy(fdata, fls->data, fsize);
@@ -2162,13 +2167,13 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
zs = zip_source_buffer(za, fdata, fsize, 1);
if (!zs) {
- error("ERROR: out of memory\n");
+ logger(LL_ERROR, "out of memory\n");
free(fdata);
goto leave;
}
if (zip_file_replace(za, zindex, zs, 0) == -1) {
- error("ERROR: could not update archive with ticketed ebl.fls\n");
+ logger(LL_ERROR, "could not update archive with ticketed ebl.fls\n");
goto leave;
}
} else {
@@ -2176,18 +2181,18 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
blob_size = 0;
blob = (const unsigned char*)plist_get_data_ptr(bbticket, &blob_size);
if (!blob) {
- error("ERROR: could not get BBTicket data\n");
+ logger(LL_ERROR, "could not get BBTicket data\n");
goto leave;
}
zs = zip_source_buffer(za, blob, blob_size, 0);
if (!zs) {
- error("ERROR: out of memory\n");
+ logger(LL_ERROR, "out of memory\n");
goto leave;
}
if (zip_file_add(za, "bbticket.der", zs, ZIP_FL_OVERWRITE) == -1) {
- error("ERROR: could not add bbticket.der to archive\n");
+ logger(LL_ERROR, "could not add bbticket.der to archive\n");
goto leave;
}
}
@@ -2195,7 +2200,7 @@ static int restore_sign_bbfw(const char* bbfwtmp, plist_t bbtss, const unsigned
// this will write out the modified zip
if (zip_close(za) == -1) {
- error("ERROR: could not close and write modified archive: %s\n", zip_strerror(za));
+ logger(LL_ERROR, "could not close and write modified archive: %s\n", zip_strerror(za));
res = -1;
} else {
res = 0;
@@ -2236,11 +2241,11 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
plist_t dict = NULL;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- info("About to send BasebandData...\n");
+ logger(LL_INFO, "About to send BasebandData...\n");
// NOTE: this function is called 2 or 3 times!
@@ -2281,7 +2286,7 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
/* create baseband request */
plist_t request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Baseband TSS request\n");
+ logger(LL_ERROR, "Unable to create Baseband TSS request\n");
plist_free(parameters);
return -1;
}
@@ -2299,34 +2304,31 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
plist_dict_set_item(request, "ApSecurityMode", plist_new_bool(1));
}
}
- if (idevicerestore_debug)
- debug_plist(request);
+ logger_dump_plist(LL_DEBUG, request, 0);
- info("Sending Baseband TSS request...\n");
+ logger(LL_INFO, "Sending Baseband TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
plist_free(parameters);
if (response == NULL) {
- error("ERROR: Unable to fetch Baseband TSS\n");
+ logger(LL_ERROR, "Unable to fetch Baseband TSS\n");
return -1;
}
- info("Received Baseband SHSH blobs\n");
-
- if (idevicerestore_debug)
- debug_plist(response);
+ logger(LL_INFO, "Received Baseband SHSH blobs\n");
+ logger_dump_plist(LL_DEBUG, response, 0);
}
// get baseband firmware file path from build identity
plist_t bbfw_path = plist_access_path(client->restore->build_identity, 4, "Manifest", "BasebandFirmware", "Info", "Path");
if (!bbfw_path || plist_get_node_type(bbfw_path) != PLIST_STRING) {
- error("ERROR: Unable to get BasebandFirmware/Info/Path node\n");
+ logger(LL_ERROR, "Unable to get BasebandFirmware/Info/Path node\n");
plist_free(response);
return -1;
}
char* bbfwpath = NULL;
plist_get_string_val(bbfw_path, &bbfwpath);
if (!bbfwpath) {
- error("ERROR: Unable to get baseband path\n");
+ logger(LL_ERROR, "Unable to get baseband path\n");
plist_free(response);
return -1;
}
@@ -2339,10 +2341,10 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
strcpy(bbfwtmp, "bbfw_");
strncpy(bbfwtmp + 5, client->udid, l);
strcpy(bbfwtmp + 5 + l, ".tmp");
- error("WARNING: Could not generate temporary filename, using %s in current directory\n", bbfwtmp);
+ logger(LL_WARNING, "Could not generate temporary filename, using %s in current directory\n", bbfwtmp);
}
if (ipsw_extract_to_file(client->ipsw, bbfwpath, bbfwtmp) != 0) {
- error("ERROR: Unable to extract baseband firmware from ipsw\n");
+ logger(LL_ERROR, "Unable to extract baseband firmware from ipsw\n");
goto leave;
}
@@ -2361,7 +2363,7 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
size_t sz = 0;
if (read_file(bbfwtmp, (void**)&buffer, &sz) < 0) {
- error("ERROR: could not read updated bbfw archive\n");
+ logger(LL_ERROR, "could not read updated bbfw archive\n");
goto leave;
}
@@ -2373,19 +2375,19 @@ static int restore_send_baseband_data(struct idevicerestore_client_t* client, pl
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending BasebandData now...\n");
+ logger(LL_INFO, "Sending BasebandData now...\n");
if (_restore_service_send(service, dict, 0) != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send BasebandData data\n");
+ logger(LL_ERROR, "Unable to send BasebandData data\n");
goto leave;
}
_restore_service_free(service);
- info("Done sending BasebandData\n");
+ logger(LL_INFO, "Done sending BasebandData\n");
res = 0;
leave:
@@ -2405,7 +2407,7 @@ int restore_send_fdr_trust_data(struct idevicerestore_client_t* client, plist_t
restored_error_t restore_error;
plist_t dict;
- info("About to send FDR Trust data...\n");
+ logger(LL_INFO, "About to send FDR Trust data...\n");
// FIXME: What should we send here?
/* Sending an empty dict makes it continue with FDR
@@ -2414,20 +2416,20 @@ int restore_send_fdr_trust_data(struct idevicerestore_client_t* client, plist_t
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending FDR Trust data now...\n");
+ logger(LL_INFO, "Sending FDR Trust data now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: During sending FDR Trust data (%d)\n", restore_error);
+ logger(LL_ERROR, "During sending FDR Trust data (%d)\n", restore_error);
return -1;
}
- info("Done sending FDR Trust Data\n");
+ logger(LL_INFO, "Done sending FDR Trust Data\n");
return 0;
}
@@ -2446,7 +2448,7 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
int want_image_list = 0;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
@@ -2463,12 +2465,12 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
}
}
if (!image_type_k) {
- error("ERROR: missing ImageType");
+ logger(LL_ERROR, "Missing ImageType\n");
return -1;
}
if (!want_image_list && !image_name) {
- info("About to send %s...\n", image_data_k);
+ logger(LL_INFO, "About to send %s...\n", image_data_k);
}
if (want_image_list) {
@@ -2496,7 +2498,7 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
}
if (is_image_type) {
if (want_image_list) {
- info("Found %s component %s\n", image_type_k, component);
+ logger(LL_INFO, "Found %s component %s\n", image_type_k, component);
plist_array_append_item(matched_images, plist_new_string(component));
} else if (!image_name || !strcmp(image_name, component)) {
char *path = NULL;
@@ -2507,7 +2509,7 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
int ret = -1;
if (!image_name) {
- info("Found %s component '%s'\n", image_type_k, component);
+ logger(LL_INFO, "Found %s component '%s'\n", image_type_k, component);
}
build_identity_get_component_path(client->restore->build_identity, component, &path);
if (path) {
@@ -2516,14 +2518,14 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
free(path);
path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract component: %s\n", component);
+ logger(LL_ERROR, "Unable to extract component: %s\n", component);
}
ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
component_data = NULL;
if (ret < 0) {
- error("ERROR: Unable to get personalized component: %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
}
plist_dict_set_item(data_dict, component, plist_new_data((const char*)data, size));
@@ -2538,14 +2540,14 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
dict = plist_new_dict();
if (want_image_list) {
plist_dict_set_item(dict, image_list_k, matched_images);
- info("Sending %s image list\n", image_type_k);
+ logger(LL_INFO, "Sending %s image list\n", image_type_k);
} else {
if (image_name) {
node = plist_dict_get_item(data_dict, image_name);
@@ -2553,10 +2555,10 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
plist_dict_set_item(dict, image_data_k, plist_copy(node));
}
plist_dict_set_item(dict, "ImageName", plist_new_string(image_name));
- info("Sending %s for %s...\n", image_type_k, image_name);
+ logger(LL_INFO, "Sending %s for %s...\n", image_type_k, image_name);
} else {
plist_dict_set_item(dict, image_data_k, data_dict);
- info("Sending %s now...\n", image_type_k);
+ logger(LL_INFO, "Sending %s now...\n", image_type_k);
}
}
@@ -2565,13 +2567,13 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
if (want_image_list) {
- error("ERROR: Failed to send %s image list (%d)\n", image_type_k, restore_error);
+ logger(LL_ERROR, "Failed to send %s image list (%d)\n", image_type_k, restore_error);
} else {
if (image_name) {
- error("ERROR: Failed to send %s for %s (%d)\n", image_type_k, image_name, restore_error);
+ logger(LL_ERROR, "Failed to send %s for %s (%d)\n", image_type_k, image_name, restore_error);
free(image_name);
} else {
- error("ERROR: Failed to send %s (%d)\n", image_type_k, restore_error);
+ logger(LL_ERROR, "Failed to send %s (%d)\n", image_type_k, restore_error);
}
}
return -1;
@@ -2581,7 +2583,7 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
if (image_name) {
free(image_name);
} else {
- info("Done sending %s\n", image_type_k);
+ logger(LL_INFO, "Done sending %s\n", image_type_k);
}
}
@@ -2624,7 +2626,7 @@ static plist_t restore_get_se_firmware_data(struct idevicerestore_client_t* clie
uint64_t chip_id = 0;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
@@ -2637,30 +2639,30 @@ static plist_t restore_get_se_firmware_data(struct idevicerestore_client_t* clie
} else if (chip_id == 0x73 || chip_id == 0x64 || chip_id == 0xC8 || chip_id == 0xD2 || chip_id == 0x2C || chip_id == 0x36) {
comp_name = "SE,UpdatePayload";
} else {
- info("WARNING: Unknown SE,ChipID 0x%" PRIx64 " detected. Restore might fail.\n", (uint64_t)chip_id);
+ logger(LL_WARNING, "Unknown SE,ChipID 0x%" PRIx64 " detected. Restore might fail.\n", (uint64_t)chip_id);
if (build_identity_has_component(client->restore->build_identity, "SE,UpdatePayload"))
comp_name = "SE,UpdatePayload";
else if (build_identity_has_component(client->restore->build_identity, "SE,Firmware"))
comp_name = "SE,Firmware";
else {
- error("ERROR: Neither 'SE,Firmware' nor 'SE,UpdatePayload' found in build identity.\n");
+ logger(LL_ERROR, "Neither 'SE,Firmware' nor 'SE,UpdatePayload' found in build identity.\n");
return NULL;
}
- debug("DEBUG: %s: using %s\n", __func__, comp_name);
+ logger(LL_DEBUG, "%s: using %s\n", __func__, comp_name);
}
p_dgr = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (!p_dgr) {
- info("NOTE: %s: No DeviceGeneratedRequest in firmware updater data request. Continuing anyway.\n", __func__);
+ logger(LL_NOTICE, "%s: No DeviceGeneratedRequest in firmware updater data request. Continuing anyway.\n", __func__);
} else if (!PLIST_IS_DICT(p_dgr)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create SE request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create SE TSS request\n");
+ logger(LL_ERROR, "Unable to create SE TSS request\n");
free(component_data);
return NULL;
}
@@ -2678,32 +2680,32 @@ static plist_t restore_get_se_firmware_data(struct idevicerestore_client_t* clie
plist_free(parameters);
- info("Sending SE TSS request...\n");
+ logger(LL_INFO, "Sending SE TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch SE ticket\n");
+ logger(LL_ERROR, "Unable to fetch SE ticket\n");
free(component_data);
return NULL;
}
if (plist_dict_get_item(response, "SE2,Ticket")) {
- info("Received SE2,Ticket\n");
+ logger(LL_INFO, "Received SE2,Ticket\n");
} else if (plist_dict_get_item(response, "SE,Ticket")) {
- info("Received SE,Ticket\n");
+ logger(LL_INFO, "Received SE,Ticket\n");
} else {
- error("ERROR: No 'SE ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'SE ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
@@ -2712,7 +2714,7 @@ static plist_t restore_get_se_firmware_data(struct idevicerestore_client_t* clie
comp_path = NULL;
if (ret < 0) {
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
return NULL;
}
@@ -2737,20 +2739,20 @@ static plist_t restore_get_savage_firmware_data(struct idevicerestore_client_t*
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (device_generated_request && !PLIST_IS_DICT(device_generated_request)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create Savage request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Savage TSS request\n");
+ logger(LL_ERROR, "Unable to create Savage TSS request\n");
return NULL;
}
@@ -2768,37 +2770,37 @@ static plist_t restore_get_savage_firmware_data(struct idevicerestore_client_t*
plist_free(parameters);
if (!comp_name) {
- error("ERROR: Could not determine Savage firmware component\n");
+ logger(LL_ERROR, "Could not determine Savage firmware component\n");
plist_free(request);
return NULL;
}
- debug("DEBUG: %s: using %s\n", __func__, comp_name);
+ logger(LL_DEBUG, "%s: using %s\n", __func__, comp_name);
- info("Sending Savage TSS request...\n");
+ logger(LL_INFO, "Sending Savage TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch Savage ticket\n");
+ logger(LL_ERROR, "Unable to fetch Savage ticket\n");
free(comp_name);
return NULL;
}
if (plist_dict_get_item(response, "Savage,Ticket")) {
- info("Received Savage ticket\n");
+ logger(LL_INFO, "Received Savage ticket\n");
} else {
- error("ERROR: No 'Savage,Ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'Savage,Ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
/* now get actual component data */
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
free(comp_name);
return NULL;
}
@@ -2808,7 +2810,7 @@ static plist_t restore_get_savage_firmware_data(struct idevicerestore_client_t*
comp_path = NULL;
if (ret < 0) {
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
free(comp_name);
return NULL;
}
@@ -2847,20 +2849,20 @@ static plist_t restore_get_yonkers_firmware_data(struct idevicerestore_client_t*
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (device_generated_request && !PLIST_IS_DICT(device_generated_request)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create Yonkers request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Yonkers TSS request\n");
+ logger(LL_ERROR, "Unable to create Yonkers TSS request\n");
return NULL;
}
@@ -2878,37 +2880,37 @@ static plist_t restore_get_yonkers_firmware_data(struct idevicerestore_client_t*
plist_free(parameters);
if (!comp_name) {
- error("ERROR: Could not determine Yonkers firmware component\n");
+ logger(LL_ERROR, "Could not determine Yonkers firmware component\n");
plist_free(request);
return NULL;
}
- debug("DEBUG: %s: using %s\n", __func__, comp_name);
+ logger(LL_DEBUG, "%s: using %s\n", __func__, comp_name);
- info("Sending Yonkers TSS request...\n");
+ logger(LL_INFO, "Sending Yonkers TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch Yonkers ticket\n");
+ logger(LL_ERROR, "Unable to fetch Yonkers ticket\n");
free(comp_name);
return NULL;
}
if (plist_dict_get_item(response, "Yonkers,Ticket")) {
- info("Received Yonkers ticket\n");
+ logger(LL_INFO, "Received Yonkers ticket\n");
} else {
- error("ERROR: No 'Yonkers,Ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'Yonkers,Ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
free(comp_name);
return response;
}
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
free(comp_name);
return NULL;
}
@@ -2919,7 +2921,7 @@ static plist_t restore_get_yonkers_firmware_data(struct idevicerestore_client_t*
comp_path = NULL;
if (ret < 0) {
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
free(comp_name);
return NULL;
}
@@ -2952,14 +2954,14 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
/* create Rose request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Rose TSS request\n");
+ logger(LL_ERROR, "Unable to create Rose TSS request\n");
return NULL;
}
@@ -2990,30 +2992,30 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
plist_free(parameters);
- info("Sending Rose TSS request...\n");
+ logger(LL_INFO, "Sending Rose TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch Rose ticket\n");
+ logger(LL_ERROR, "Unable to fetch Rose ticket\n");
return NULL;
}
if (plist_dict_get_item(response, "Rap,Ticket")) {
- info("Received Rose ticket\n");
+ logger(LL_INFO, "Received Rose ticket\n");
} else {
- error("ERROR: No 'Rap,Ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'Rap,Ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
comp_name = "Rap,RTKitOS";
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
ret = extract_component(client->ipsw, comp_path, &component_data, &component_size);
@@ -3021,20 +3023,20 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
comp_path = NULL;
if (ret < 0) {
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
return NULL;
}
if (ftab_parse(component_data, component_size, &ftab, &ftag) != 0) {
plist_free(response);
free(component_data);
- error("ERROR: Failed to parse '%s' component data.\n", comp_name);
+ logger(LL_ERROR, "Failed to parse '%s' component data.\n", comp_name);
return NULL;
}
free(component_data);
component_data = NULL;
component_size = 0;
if (ftag != 'rkos') {
- error("WARNING: Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
+ logger(LL_WARNING, "Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
}
comp_name = "Rap,RestoreRTKitOS";
@@ -3042,7 +3044,7 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
ftab_free(ftab);
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
ret = extract_component(client->ipsw, comp_path, &component_data, &component_size);
@@ -3051,7 +3053,7 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
if (ret < 0) {
ftab_free(ftab);
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
return NULL;
}
@@ -3060,26 +3062,26 @@ static plist_t restore_get_rose_firmware_data(struct idevicerestore_client_t* cl
free(component_data);
ftab_free(ftab);
plist_free(response);
- error("ERROR: Failed to parse '%s' component data.\n", comp_name);
+ logger(LL_ERROR, "Failed to parse '%s' component data.\n", comp_name);
return NULL;
}
free(component_data);
component_data = NULL;
component_size = 0;
if (ftag != 'rkos') {
- error("WARNING: Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
+ logger(LL_WARNING, "Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
}
if (ftab_get_entry_ptr(rftab, 'rrko', &component_data, &component_size) == 0) {
ftab_add_entry(ftab, 'rrko', component_data, component_size);
} else {
- error("ERROR: Could not find 'rrko' entry in ftab. This will probably break things.\n");
+ logger(LL_ERROR, "Could not find 'rrko' entry in ftab. This will probably break things.\n");
}
ftab_free(rftab);
component_data = NULL;
component_size = 0;
} else {
- info("NOTE: Build identity does not have a '%s' component.\n", comp_name);
+ logger(LL_NOTICE, "Build identity does not have a '%s' component.\n", comp_name);
}
ftab_write(ftab, &component_data, &component_size);
@@ -3105,20 +3107,20 @@ static plist_t restore_get_veridian_firmware_data(struct idevicerestore_client_t
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (device_generated_request && !PLIST_IS_DICT(device_generated_request)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create Veridian request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Veridian TSS request\n");
+ logger(LL_ERROR, "Unable to create Veridian TSS request\n");
free(component_data);
return NULL;
}
@@ -3136,30 +3138,30 @@ static plist_t restore_get_veridian_firmware_data(struct idevicerestore_client_t
plist_free(parameters);
- info("Sending Veridian TSS request...\n");
+ logger(LL_INFO, "Sending Veridian TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch Veridian ticket\n");
+ logger(LL_ERROR, "Unable to fetch Veridian ticket\n");
free(component_data);
return NULL;
}
if (plist_dict_get_item(response, "BMU,Ticket")) {
- info("Received Veridian ticket\n");
+ logger(LL_INFO, "Received Veridian ticket\n");
} else {
- error("ERROR: No 'BMU,Ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'BMU,Ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
@@ -3169,7 +3171,7 @@ static plist_t restore_get_veridian_firmware_data(struct idevicerestore_client_t
comp_path = NULL;
if (ret < 0) {
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
return NULL;
}
@@ -3185,7 +3187,7 @@ static plist_t restore_get_veridian_firmware_data(struct idevicerestore_client_t
if (!fw_map) {
plist_free(response);
- error("ERROR: Unable to parse '%s' component data as plist\n", comp_name);
+ logger(LL_ERROR, "Unable to parse '%s' component data as plist\n", comp_name);
return NULL;
}
@@ -3193,7 +3195,7 @@ static plist_t restore_get_veridian_firmware_data(struct idevicerestore_client_t
if (!fw_map_digest) {
plist_free(fw_map);
plist_free(response);
- error("ERROR: Unable to get Digest for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get Digest for '%s' component\n", comp_name);
return NULL;
}
@@ -3227,39 +3229,39 @@ static plist_t restore_get_generic_firmware_data(struct idevicerestore_client_t*
}
}
if (response_ticket == NULL) {
- error("ERROR: Unable to determine response ticket from device generated tags");
+ logger(LL_ERROR, "Unable to determine response ticket from device generated tags\n");
return NULL;
}
/* create TSS request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create %s TSS request\n", s_updater_name);
+ logger(LL_ERROR, "Unable to create %s TSS request\n", s_updater_name);
return NULL;
}
/* add device generated request data to request */
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (!device_generated_request) {
- error("ERROR: Could not find DeviceGeneratedRequest in arguments dictionary\n");
+ logger(LL_ERROR, "Could not find DeviceGeneratedRequest in arguments dictionary\n");
plist_free(request);
return NULL;
}
plist_dict_merge(&request, device_generated_request);
- info("Sending %s TSS request...\n", s_updater_name);
+ logger(LL_INFO, "Sending %s TSS request...\n", s_updater_name);
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch %s ticket\n", s_updater_name);
+ logger(LL_ERROR, "Unable to fetch %s ticket\n", s_updater_name);
return NULL;
}
if (plist_dict_get_item(response, response_ticket)) {
- info("Received %s\n", response_ticket);
+ logger(LL_INFO, "Received %s\n", response_ticket);
} else {
- error("ERROR: No '%s' in TSS response, this might not work\n", response_ticket);
- debug_plist(response);
+ logger(LL_ERROR, "No '%s' in TSS response, this might not work\n", response_ticket);
+ logger_dump_plist(LL_VERBOSE, response, 0);
}
return response;
@@ -3277,20 +3279,20 @@ static plist_t restore_get_tcon_firmware_data(struct idevicerestore_client_t* cl
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (device_generated_request && !PLIST_IS_DICT(device_generated_request)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create Baobab request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Baobab TSS request\n");
+ logger(LL_ERROR, "Unable to create Baobab TSS request\n");
free(component_data);
return NULL;
}
@@ -3308,29 +3310,29 @@ static plist_t restore_get_tcon_firmware_data(struct idevicerestore_client_t* cl
plist_free(parameters);
- info("Sending Baobab TSS request...\n");
+ logger(LL_INFO, "Sending Baobab TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch Baobab ticket\n");
+ logger(LL_ERROR, "Unable to fetch Baobab ticket\n");
free(component_data);
return NULL;
}
if (plist_dict_get_item(response, "Baobab,Ticket")) {
- info("Received Baobab ticket\n");
+ logger(LL_INFO, "Received Baobab ticket\n");
} else {
- error("ERROR: No 'Baobab,Ticket' in TSS response, this might not work\n");
+ logger(LL_ERROR, "No 'Baobab,Ticket' in TSS response, this might not work\n");
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
plist_free(response);
return NULL;
}
@@ -3340,7 +3342,7 @@ static plist_t restore_get_tcon_firmware_data(struct idevicerestore_client_t* cl
free(comp_path);
comp_path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
plist_free(response);
return NULL;
}
@@ -3370,20 +3372,20 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
int ret;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (device_generated_request && !PLIST_IS_DICT(device_generated_request)) {
- error("ERROR: %s: DeviceGeneratedRequest has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: DeviceGeneratedRequest has invalid type!\n", __func__);
return NULL;
}
/* create Timer request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create Timer TSS request\n");
+ logger(LL_ERROR, "Unable to create Timer TSS request\n");
return NULL;
}
@@ -3403,7 +3405,7 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
/* add Timer,* tags from info dictionary to parameters */
plist_t info_array = plist_dict_get_item(p_info, "InfoArray");
if (!info_array) {
- error("ERROR: Could not find InfoArray in info dictionary\n");
+ logger(LL_ERROR, "Could not find InfoArray in info dictionary\n");
plist_free(parameters);
return NULL;
} else {
@@ -3442,7 +3444,7 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
}
plist_t ap_info = plist_dict_get_item(p_info, "APInfo");
if (!ap_info) {
- error("ERROR: Could not find APInfo in info dictionary\n");
+ logger(LL_ERROR, "Could not find APInfo in info dictionary\n");
plist_free(parameters);
return NULL;
} else {
@@ -3454,23 +3456,23 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
plist_free(parameters);
- info("Sending %s TSS request...\n", ticket_name);
+ logger(LL_INFO, "Sending %s TSS request...\n", ticket_name);
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch %s\n", ticket_name);
+ logger(LL_ERROR, "Unable to fetch %s\n", ticket_name);
return NULL;
}
if (plist_dict_get_item(response, ticket_name)) {
- info("Received %s\n", ticket_name);
+ logger(LL_INFO, "Received %s\n", ticket_name);
} else {
- error("ERROR: No '%s' in TSS response, this might not work\n", ticket_name);
+ logger(LL_ERROR, "No '%s' in TSS response, this might not work\n", ticket_name);
}
/* don't add FirmwareData if not requested via ResponseTags */
if (!_wants_firmware_data(arguments)) {
- debug("DEBUG: Not adding FirmwareData as it was not requested\n");
+ logger(LL_DEBUG, "Not adding FirmwareData as it was not requested\n");
return response;
}
@@ -3478,31 +3480,31 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
if (build_identity_has_component(client->restore->build_identity, comp_name)) {
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
ret = extract_component(client->ipsw, comp_path, &component_data, &component_size);
free(comp_path);
comp_path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
plist_free(response);
return NULL;
}
if (ftab_parse(component_data, component_size, &ftab, &ftag) != 0) {
free(component_data);
plist_free(response);
- error("ERROR: Failed to parse '%s' component data.\n", comp_name);
+ logger(LL_ERROR, "Failed to parse '%s' component data.\n", comp_name);
return NULL;
}
free(component_data);
component_data = NULL;
component_size = 0;
if (ftag != 'rkos') {
- error("WARNING: Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
+ logger(LL_WARNING, "Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
}
} else {
- info("NOTE: Build identity does not have a '%s' component.\n", comp_name);
+ logger(LL_NOTICE, "Build identity does not have a '%s' component.\n", comp_name);
}
snprintf(comp_name, sizeof(comp_name), "Timer,RestoreRTKitOS,%u", tag);
@@ -3510,7 +3512,7 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
if (build_identity_get_component_path(client->restore->build_identity, comp_name, &comp_path) < 0) {
ftab_free(ftab);
plist_free(response);
- error("ERROR: Unable to get path for '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to get path for '%s' component\n", comp_name);
return NULL;
}
ret = extract_component(client->ipsw, comp_path, &component_data, &component_size);
@@ -3519,7 +3521,7 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
if (ret < 0) {
ftab_free(ftab);
plist_free(response);
- error("ERROR: Unable to extract '%s' component\n", comp_name);
+ logger(LL_ERROR, "Unable to extract '%s' component\n", comp_name);
return NULL;
}
@@ -3528,26 +3530,26 @@ static plist_t restore_get_timer_firmware_data(struct idevicerestore_client_t* c
free(component_data);
ftab_free(ftab);
plist_free(response);
- error("ERROR: Failed to parse '%s' component data.\n", comp_name);
+ logger(LL_ERROR, "Failed to parse '%s' component data.\n", comp_name);
return NULL;
}
free(component_data);
component_data = NULL;
component_size = 0;
if (ftag != 'rkos') {
- error("WARNING: Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
+ logger(LL_WARNING, "Unexpected tag 0x%08x, expected 0x%08x; continuing anyway.\n", ftag, 'rkos');
}
if (ftab_get_entry_ptr(rftab, 'rrko', &component_data, &component_size) == 0) {
ftab_add_entry(ftab, 'rrko', component_data, component_size);
} else {
- error("ERROR: Could not find 'rrko' entry in ftab. This will probably break things.\n");
+ logger(LL_ERROR, "Could not find 'rrko' entry in ftab. This will probably break things.\n");
}
ftab_free(rftab);
component_data = NULL;
component_size = 0;
} else {
- info("NOTE: Build identity does not have a '%s' component.\n", comp_name);
+ logger(LL_NOTICE, "Build identity does not have a '%s' component.\n", comp_name);
}
ftab_write(ftab, &component_data, &component_size);
@@ -3568,7 +3570,7 @@ static plist_t restore_get_cryptex1_firmware_data(struct idevicerestore_client_t
plist_t response = NULL;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return NULL;
}
@@ -3587,7 +3589,7 @@ static plist_t restore_get_cryptex1_firmware_data(struct idevicerestore_client_t
/* create Cryptex1 request */
request = tss_request_new(NULL);
if (request == NULL) {
- error("ERROR: Unable to create %s TSS request\n", s_updater_name);
+ logger(LL_ERROR, "Unable to create %s TSS request\n", s_updater_name);
return NULL;
}
@@ -3627,7 +3629,7 @@ static plist_t restore_get_cryptex1_firmware_data(struct idevicerestore_client_t
/* add device generated request data to parameters */
plist_t device_generated_request = plist_dict_get_item(arguments, "DeviceGeneratedRequest");
if (!device_generated_request) {
- error("ERROR: Could not find DeviceGeneratedRequest in arguments dictionary\n");
+ logger(LL_ERROR, "Could not find DeviceGeneratedRequest in arguments dictionary\n");
plist_free(parameters);
return NULL;
}
@@ -3638,19 +3640,19 @@ static plist_t restore_get_cryptex1_firmware_data(struct idevicerestore_client_t
plist_free(parameters);
- info("Sending %s TSS request...\n", s_updater_name);
+ logger(LL_INFO, "Sending %s TSS request...\n", s_updater_name);
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
- error("ERROR: Unable to fetch %s ticket\n", s_updater_name);
+ logger(LL_ERROR, "Unable to fetch %s ticket\n", s_updater_name);
return NULL;
}
if (plist_dict_get_item(response, response_ticket)) {
- info("Received %s\n", response_ticket);
+ logger(LL_INFO, "Received %s\n", response_ticket);
} else {
- error("ERROR: No '%s' in TSS response, this might not work\n", response_ticket);
- debug_plist(response);
+ logger(LL_ERROR, "No '%s' in TSS response, this might not work\n", response_ticket);
+ logger_dump_plist(LL_VERBOSE, response, 0);
}
return response;
@@ -3661,29 +3663,29 @@ static int restore_send_firmware_updater_preflight(struct idevicerestore_client_
plist_t dict = NULL;
int restore_error;
- if (idevicerestore_debug) {
- debug("DEBUG: %s: Got FirmwareUpdaterPreflight request:\n", __func__);
- debug_plist(message);
+ if (client->debug_level > 1) {
+ logger(LL_DEBUG, "%s: Got FirmwareUpdaterPreflight request:\n", __func__);
+ logger_dump_plist(LL_DEBUG, message, 1);
}
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
dict = plist_new_dict();
- info("Sending FirmwareResponsePreflight now...\n");
+ logger(LL_INFO, "Sending FirmwareResponsePreflight now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Couldn't send FirmwareResponsePreflight data (%d)\n", restore_error);
+ logger(LL_ERROR, "Couldn't send FirmwareResponsePreflight data (%d)\n", restore_error);
return -1;
}
- info("Done sending FirmwareUpdaterPreflight response\n");
+ logger(LL_INFO, "Done sending FirmwareUpdaterPreflight response\n");
return 0;
}
@@ -3699,30 +3701,30 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
int restore_error;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- if (idevicerestore_debug) {
- debug("DEBUG: %s: Got FirmwareUpdaterData request:\n", __func__);
- debug_plist(message);
+ if (client->debug_level > 1) {
+ logger(LL_DEBUG, "%s: Got FirmwareUpdaterData request:\n", __func__);
+ logger_dump_plist(LL_DEBUG, message, 1);
}
arguments = plist_dict_get_item(message, "Arguments");
if (!arguments || plist_get_node_type(arguments) != PLIST_DICT) {
- error("ERROR: %s: Arguments missing or has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: Arguments missing or has invalid type!\n", __func__);
goto error_out;
}
p_type = plist_dict_get_item(arguments, "MessageArgType");
if (!p_type || (plist_get_node_type(p_type) != PLIST_STRING)) {
- error("ERROR: %s: MessageArgType missing or has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: MessageArgType missing or has invalid type!\n", __func__);
goto error_out;
}
p_updater_name = plist_dict_get_item(arguments, "MessageArgUpdaterName");
if (!p_updater_name || (plist_get_node_type(p_updater_name) != PLIST_STRING)) {
- error("ERROR: %s: MessageArgUpdaterName missing or has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: MessageArgUpdaterName missing or has invalid type!\n", __func__);
goto error_out;
}
@@ -3734,7 +3736,7 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
plist_get_string_val(p_type, &s_type);
if (!s_type || strcmp(s_type, "FirmwareResponseData")) {
- error("ERROR: %s: MessageArgType has unexpected value '%s'\n", __func__, s_type);
+ logger(LL_ERROR, "%s: MessageArgType has unexpected value '%s'\n", __func__, s_type);
goto error_out;
}
free(s_type);
@@ -3742,7 +3744,7 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
p_info = plist_dict_get_item(arguments, "MessageArgInfo");
if (!p_info || (plist_get_node_type(p_info) != PLIST_DICT)) {
- error("ERROR: %s: MessageArgInfo missing or has invalid type!\n", __func__);
+ logger(LL_ERROR, "%s: MessageArgInfo missing or has invalid type!\n", __func__);
goto error_out;
}
@@ -3751,7 +3753,7 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
if (strcmp(s_updater_name, "SE") == 0) {
fwdict = restore_get_se_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get SE firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get SE firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "Savage") == 0) {
@@ -3764,56 +3766,56 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
fwdict = restore_get_savage_firmware_data(client, p_info, arguments);
}
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get %s firmware data\n", __func__, fwtype);
+ logger(LL_ERROR, "%s: Couldn't get %s firmware data\n", __func__, fwtype);
goto error_out;
}
} else if (strcmp(s_updater_name, "Rose") == 0) {
fwdict = restore_get_rose_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get Rose firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get Rose firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "T200") == 0) {
fwdict = restore_get_veridian_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get Veridian firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get Veridian firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "AppleTCON") == 0) {
fwdict = restore_get_tcon_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get AppleTCON firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get AppleTCON firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "PS190") == 0) {
fwdict = restore_get_generic_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get PCON1 firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get PCON1 firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "AppleTypeCRetimer") == 0) {
fwdict = restore_get_timer_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get AppleTypeCRetimer firmware data\n", __func__);
+ logger(LL_ERROR, "%s: Couldn't get AppleTypeCRetimer firmware data\n", __func__);
goto error_out;
}
} else if ((strcmp(s_updater_name, "Cryptex1") == 0) || (strcmp(s_updater_name, "Cryptex1LocalPolicy") == 0)) {
fwdict = restore_get_cryptex1_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get %s firmware data\n", __func__, s_updater_name);
+ logger(LL_ERROR, "%s: Couldn't get %s firmware data\n", __func__, s_updater_name);
goto error_out;
}
} else if (strcmp(s_updater_name, "Ace3") == 0) {
fwdict = restore_get_generic_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get %s firmware data\n", __func__, s_updater_name);
+ logger(LL_ERROR, "%s: Couldn't get %s firmware data\n", __func__, s_updater_name);
goto error_out;
}
} else {
- error("ERROR: %s: Got unknown updater name '%s', trying to discover from device generated request.\n", __func__, s_updater_name);
+ logger(LL_ERROR, "%s: Got unknown updater name '%s', trying to discover from device generated request.\n", __func__, s_updater_name);
fwdict = restore_get_generic_firmware_data(client, p_info, arguments);
if (fwdict == NULL) {
- error("ERROR: %s: Couldn't get %s firmware data\n", __func__, s_updater_name);
+ logger(LL_ERROR, "%s: Couldn't get %s firmware data\n", __func__, s_updater_name);
goto error_out;
}
}
@@ -3822,23 +3824,23 @@ static int restore_send_firmware_updater_data(struct idevicerestore_client_t* cl
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
dict = plist_new_dict();
plist_dict_set_item(dict, "FirmwareResponseData", fwdict);
- info("Sending FirmwareResponse data now...\n");
+ logger(LL_INFO, "Sending FirmwareResponse data now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Couldn't send FirmwareResponse data (%d)\n", restore_error);
+ logger(LL_ERROR, "Couldn't send FirmwareResponse data (%d)\n", restore_error);
goto error_out;
}
- info("Done sending FirmwareUpdater data\n");
+ logger(LL_INFO, "Done sending FirmwareUpdater data\n");
return 0;
@@ -3855,35 +3857,35 @@ static int restore_send_receipt_manifest(struct idevicerestore_client_t* client,
int restore_error;
if (!client || !client->restore || !client->restore->build_identity) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
plist_t manifest = plist_dict_get_item(client->restore->build_identity, "Manifest");
if (!manifest) {
- error("failed to get Manifest node from build_identity");
+ logger(LL_ERROR, "%s: Failed to get Manifest node from build_identity\n", __func__);
goto error_out;
}
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
dict = plist_new_dict();
plist_dict_set_item(dict, "ReceiptManifest", plist_copy(manifest));
- info("Sending ReceiptManifest data now...\n");
+ logger(LL_INFO, "Sending ReceiptManifest data now...\n");
restore_error = _restore_service_send(service, dict, 0);
plist_free(dict);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Couldn't send ReceiptManifest data (%d)\n", restore_error);
+ logger(LL_ERROR, "Couldn't send ReceiptManifest data (%d)\n", restore_error);
goto error_out;
}
- info("Done sending ReceiptManifest data\n");
+ logger(LL_INFO, "Done sending ReceiptManifest data\n");
return 0;
@@ -3937,20 +3939,20 @@ static int cpio_send_file(idevice_connection_t connection, const char *name, str
device_error = idevice_connection_send(connection, (void *)&hdr, sizeof(hdr), &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != sizeof(hdr)) {
- error("ERROR: BootabilityBundle unable to send header. (%d) Sent %u of %lu bytes.\n", device_error, bytes, (long)sizeof(hdr));
+ logger(LL_ERROR, "BootabilityBundle unable to send header. (%d) Sent %u of %lu bytes.\n", device_error, bytes, (long)sizeof(hdr));
return -1;
}
device_error = idevice_connection_send(connection, (void *)name, name_len, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != name_len) {
- error("ERROR: BootabilityBundle unable to send filename. (%d) Sent %u of %u bytes.\n", device_error, bytes, name_len);
+ logger(LL_ERROR, "BootabilityBundle unable to send filename. (%d) Sent %u of %u bytes.\n", device_error, bytes, name_len);
return -1;
}
if (st->st_size && data) {
device_error = idevice_connection_send(connection, data, st->st_size, &bytes);
if (device_error != IDEVICE_E_SUCCESS || bytes != st->st_size) {
- error("ERROR: BootabilityBundle unable to send data. (%d) Sent %u of %lu bytes.\n", device_error, bytes, (long)st->st_size);
+ logger(LL_ERROR, "BootabilityBundle unable to send data. (%d) Sent %u of %lu bytes.\n", device_error, bytes, (long)st->st_size);
return -1;
}
}
@@ -3972,7 +3974,7 @@ static int restore_bootability_send_one(void *ctx, ipsw_archive_t ipsw, const ch
subpath = name + strlen(prefix);
}
- debug("DEBUG: BootabilityBundle send m=%07o s=%10ld %s\n", stat->st_mode, (long)stat->st_size, subpath);
+ logger(LL_DEBUG, "BootabilityBundle send m=%07o s=%10ld %s\n", stat->st_mode, (long)stat->st_size, subpath);
unsigned char *buf = NULL;
unsigned int size = 0;
@@ -3980,7 +3982,7 @@ static int restore_bootability_send_one(void *ctx, ipsw_archive_t ipsw, const ch
if ((S_ISLNK(stat->st_mode) || S_ISREG(stat->st_mode)) && stat->st_size != 0) {
ipsw_extract_to_memory(ipsw, name, &buf, &size);
if (size != stat->st_size) {
- error("ERROR: expected %ld bytes but got %d for file %s\n", (long)stat->st_size, size, name);
+ logger(LL_ERROR, "expected %ld bytes but got %d for file %s\n", (long)stat->st_size, size, name);
free(buf);
return -1;
}
@@ -3996,9 +3998,9 @@ static int restore_bootability_send_one(void *ctx, ipsw_archive_t ipsw, const ch
static int restore_send_bootability_bundle_data(struct idevicerestore_client_t* client, plist_t message)
{
- if (idevicerestore_debug) {
- debug("DEBUG: %s: Got BootabilityBundle request:\n", __func__);
- debug_plist(message);
+ if (client->debug_level > 1) {
+ logger(LL_DEBUG, "%s: Got BootabilityBundle request:\n", __func__);
+ logger_dump_plist(LL_DEBUG, message, 1);
}
plist_t node = plist_dict_get_item(message, "DataPort");
@@ -4011,28 +4013,28 @@ static int restore_send_bootability_bundle_data(struct idevicerestore_client_t*
idevice_error_t device_error = IDEVICE_E_SUCCESS;
if (!client || !client->restore || !client->restore->build_identity || !client->restore->device) {
- error("ERROR: %s: idevicerestore client not initialized?!\n", __func__);
+ logger(LL_ERROR, "%s: idevicerestore client not initialized?!\n", __func__);
return -1;
}
- debug("Connecting to BootabilityBundle data port\n");
+ logger(LL_DEBUG, "Connecting to BootabilityBundle data port\n");
while (--attempts > 0) {
device_error = idevice_connect(client->restore->device, data_port, &connection);
if (device_error == IDEVICE_E_SUCCESS) {
break;
}
sleep(1);
- debug("Retrying connection...\n");
+ logger(LL_DEBUG, "Retrying connection...\n");
}
if (device_error != IDEVICE_E_SUCCESS) {
- error("ERROR: Unable to connect to BootabilityBundle data port\n");
+ logger(LL_ERROR, "Unable to connect to BootabilityBundle data port\n");
return -1;
}
int ret = ipsw_list_contents(client->ipsw, restore_bootability_send_one, connection);
if (ret < 0) {
- error("ERROR: Failed to send BootabilityBundle\n");
+ logger(LL_ERROR, "Failed to send BootabilityBundle\n");
return ret;
}
@@ -4062,7 +4064,7 @@ plist_t restore_get_build_identity(struct idevicerestore_client_t* client, uint8
plist_t unique_id_node = plist_dict_get_item(client->build_manifest, "UniqueBuildID");
if (unique_id_node) {
- info("UniqueBuildID: ");
+ logger(LL_INFO, "UniqueBuildID: ");
plist_write_to_stream(unique_id_node, stdout, PLIST_FORMAT_PRINT, PLIST_OPT_NONE);
}
@@ -4079,13 +4081,13 @@ int extract_macos_variant(plist_t build_identity, char** output)
{
plist_t build_info = plist_dict_get_item(build_identity, "Info");
if (!build_info) {
- error("ERROR: build identity does not contain an 'Info' element\n");
+ logger(LL_ERROR, "build identity does not contain an 'Info' element\n");
return -1;
}
plist_t macos_variant_node = plist_dict_get_item(build_info, "MacOSVariant");
if (!macos_variant_node) {
- error("ERROR: build identity info does not contain a MacOSVariant\n");
+ logger(LL_ERROR, "build identity info does not contain a MacOSVariant\n");
return -1;
}
plist_get_string_val(macos_variant_node, output);
@@ -4097,13 +4099,13 @@ static char* extract_global_manifest_path(plist_t build_identity, char *variant)
{
plist_t build_info = plist_dict_get_item(build_identity, "Info");
if (!build_info) {
- error("ERROR: build identity does not contain an 'Info' element\n");
+ logger(LL_ERROR, "build identity does not contain an 'Info' element\n");
return NULL;
}
plist_t device_class_node = plist_dict_get_item(build_info, "DeviceClass");
if (!device_class_node) {
- error("ERROR: build identity info does not contain a DeviceClass\n");
+ logger(LL_ERROR, "build identity info does not contain a DeviceClass\n");
return NULL;
}
char *device_class = NULL;
@@ -4136,13 +4138,13 @@ int extract_global_manifest(struct idevicerestore_client_t* client, plist_t buil
{
char* ticket_path = extract_global_manifest_path(build_identity, variant);
if (!ticket_path) {
- error("ERROR: failed to get global manifest path\n");
+ logger(LL_ERROR, "failed to get global manifest path\n");
return -1;
}
int ret = ipsw_extract_to_memory(client->ipsw, ticket_path, pbuffer, psize);
if (ret != 0) {
free(ticket_path);
- error("ERROR: failed to read global manifest\n");
+ logger(LL_ERROR, "failed to read global manifest\n");
return -1;
}
free(ticket_path);
@@ -4154,6 +4156,7 @@ struct _restore_send_file_data_ctx {
struct idevicerestore_client_t* client;
restore_service_client_t service;
int last_progress;
+ uint32_t tag;
};
static int _restore_send_file_data(struct _restore_send_file_data_ctx* rctx, void* data, size_t size, size_t done, size_t total_size)
@@ -4169,18 +4172,18 @@ static int _restore_send_file_data(struct _restore_send_file_data_ctx* rctx, voi
restored_error_t restore_error = _restore_service_send(rctx->service, dict, 0);
if (restore_error != RESTORE_E_SUCCESS) {
plist_free(dict);
- error("ERROR: %s: Failed to send data (%d)\n", __func__, restore_error);
+ logger(LL_ERROR, "%s: Failed to send data (%d)\n", __func__, restore_error);
return -1;
}
plist_free(dict);
/* special handling for AEA image format */
if (done == 0 && (memcmp(data, "AEA1", 4) == 0)) {
- info("Encountered First Chunk in AEA image\n");
+ logger(LL_INFO, "Encountered First Chunk in AEA image\n");
plist_t message = NULL;
property_list_service_error_t err = _restore_service_recv_timeout(rctx->service, &message, 3000);
if (err == PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT) {
- info("NOTE: No URLAsset requested, assuming it is not necessary.");
+ logger(LL_INFO, "No URLAsset requested, assuming it is not necessary.\n");
} else if (err == PROPERTY_LIST_SERVICE_E_SUCCESS) {
restore_send_url_asset(rctx->client, message);
}
@@ -4188,6 +4191,7 @@ static int _restore_send_file_data(struct _restore_send_file_data_ctx* rctx, voi
if (total_size > 0x1000000) {
double progress = (double)done / (double)total_size;
+ set_progress(rctx->tag, progress);
int progress_int = (int)(progress*100.0);
if (progress_int > rctx->last_progress) {
idevicerestore_progress(rctx->client, RESTORE_STEP_UPLOAD_IMG, progress);
@@ -4199,20 +4203,20 @@ static int _restore_send_file_data(struct _restore_send_file_data_ctx* rctx, voi
int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* client, plist_t message)
{
- if (idevicerestore_debug) {
- debug("DEBUG: %s: Got PersonalizedBootObjectV3 request:\n", __func__);
- debug_plist(message);
+ if (client->debug_level > 1) {
+ logger(LL_DEBUG, "%s: Got PersonalizedBootObjectV3 request:\n", __func__);
+ logger_dump_plist(LL_DEBUG, message, 1);
}
char *image_name = NULL;
plist_t node = plist_access_path(message, 2, "Arguments", "ImageName");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- debug("Failed to parse arguments from PersonalizedBootObjectV3 plist\n");
+ logger(LL_DEBUG, "Failed to parse arguments from PersonalizedBootObjectV3 plist\n");
return -1;
}
plist_get_string_val(node, &image_name);
if (!image_name) {
- debug("Failed to parse arguments from PersonalizedBootObjectV3 as string\n");
+ logger(LL_DEBUG, "Failed to parse arguments from PersonalizedBootObjectV3 as string\n");
return -1;
}
@@ -4224,7 +4228,7 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
plist_t dict = NULL;
restored_error_t restore_error = RESTORE_E_SUCCESS;
- info("About to send %s...\n", component);
+ logger(LL_INFO, "About to send %s...\n", component);
if (strcmp(image_name, "__GlobalManifest__") == 0) {
int ret = extract_global_manifest(client, client->restore->build_identity, NULL, &data, &size);
@@ -4234,30 +4238,30 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
} else if (strcmp(image_name, "__RestoreVersion__") == 0) {
int ret = ipsw_extract_to_memory(client->ipsw, "RestoreVersion.plist", &data, &size);
if (ret != 0) {
- error("ERROR: failed to read global manifest\n");
+ logger(LL_ERROR, "failed to read global manifest\n");
return -1;
}
} else if (strcmp(image_name, "__SystemVersion__") == 0) {
int ret = ipsw_extract_to_memory(client->ipsw, "SystemVersion.plist", &data, &size);
if (ret != 0) {
- error("ERROR: failed to read global manifest\n");
+ logger(LL_ERROR, "failed to read global manifest\n");
return -1;
}
} else {
// Get component path
if (client->tss) {
if (tss_response_get_path_by_entry(client->tss, component, &path) < 0) {
- debug("NOTE: No path for component %s in TSS, will fetch from build identity\n", component);
+ logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build identity\n", component);
}
}
if (!path) {
plist_t build_identity = restore_get_build_identity_from_request(client, message);
if (!build_identity) {
- error("ERROR: Unable to find a matching build identity\n");
+ logger(LL_ERROR, "Unable to find a matching build identity\n");
return -1;
}
if (build_identity_get_component_path(build_identity, component, &path) < 0) {
- error("ERROR: Unable to find %s path from build identity\n", component);
+ logger(LL_ERROR, "Unable to find %s path from build identity\n", component);
return -1;
}
}
@@ -4269,7 +4273,7 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
free(path);
path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract component %s\n", component);
+ logger(LL_ERROR, "Unable to extract component %s\n", component);
return -1;
}
@@ -4278,23 +4282,26 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
free(component_data);
component_data = NULL;
if (ret < 0) {
- error("ERROR: Unable to get personalized component %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component %s\n", component);
return -1;
}
}
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending %s now (%" PRIu64 " bytes)...\n", component, (uint64_t)size);
+ logger(LL_INFO, "Sending %s now (%" PRIu64 " bytes)...\n", component, (uint64_t)size);
struct _restore_send_file_data_ctx rctx;
rctx.client = client;
rctx.service = service;
rctx.last_progress = 0;
+ rctx.tag = progress_get_next_tag();
+
+ register_progress(rctx.tag, component);
int64_t i = size;
while (i > 0) {
@@ -4302,7 +4309,8 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
if (_restore_send_file_data(&rctx, (data + size - i), blob_size, size-i, size) < 0) {
free(data);
_restore_service_free(service);
- error("ERROR: Unable to send component %s data\n", component);
+ finalize_progress(rctx.tag);
+ logger(LL_ERROR, "Unable to send component %s data\n", component);
return -1;
}
i -= blob_size;
@@ -4310,29 +4318,30 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
free(data);
_restore_send_file_data(&rctx, NULL, 0, size-i, size);
+ finalize_progress(rctx.tag);
_restore_service_free(service);
- info("Done sending %s\n", component);
+ logger(LL_INFO, "Done sending %s\n", component);
return 0;
}
int restore_send_source_boot_object_v4(struct idevicerestore_client_t* client, plist_t message)
{
- if (idevicerestore_debug) {
- debug("DEBUG: %s: Got SourceBootObjectV4 request:\n", __func__);
- debug_plist(message);
+ if (client->debug_level > 1) {
+ logger(LL_DEBUG, "%s: Got SourceBootObjectV4 request:\n", __func__);
+ logger_dump_plist(LL_DEBUG, message, 1);
}
char *image_name = NULL;
plist_t node = plist_access_path(message, 2, "Arguments", "ImageName");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- debug("Failed to parse arguments from SourceBootObjectV4 plist\n");
+ logger(LL_DEBUG, "Failed to parse arguments from SourceBootObjectV4 plist\n");
return -1;
}
plist_get_string_val(node, &image_name);
if (!image_name) {
- debug("Failed to parse arguments from SourceBootObjectV4 as string\n");
+ logger(LL_DEBUG, "Failed to parse arguments from SourceBootObjectV4 as string\n");
return -1;
}
@@ -4346,18 +4355,18 @@ int restore_send_source_boot_object_v4(struct idevicerestore_client_t* client, p
plist_t dict = NULL;
restored_error_t restore_error = RESTORE_E_SUCCESS;
- info("About to send %s...\n", component);
+ logger(LL_INFO, "About to send %s...\n", component);
if (strcmp(image_name, "__GlobalManifest__") == 0) {
char *variant = NULL;
plist_t node = plist_access_path(message, 2, "Arguments", "Variant");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- debug("Failed to parse arguments from SourceBootObjectV4 plist\n");
+ logger(LL_DEBUG, "Failed to parse arguments from SourceBootObjectV4 plist\n");
return -1;
}
plist_get_string_val(node, &variant);
if (!variant) {
- debug("Failed to parse arguments from SourceBootObjectV4 as string\n");
+ logger(LL_DEBUG, "Failed to parse arguments from SourceBootObjectV4 as string\n");
return -1;
}
@@ -4370,20 +4379,20 @@ int restore_send_source_boot_object_v4(struct idevicerestore_client_t* client, p
// Get component path
if (client->tss) {
if (tss_response_get_path_by_entry(client->tss, component, &path) < 0) {
- debug("NOTE: No path for component %s in TSS, will fetch from build identity\n", component);
+ logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build identity\n", component);
}
}
if (!path) {
plist_t build_identity = restore_get_build_identity_from_request(client, message);
if (build_identity_get_component_path(build_identity, component, &path) < 0) {
- error("ERROR: Unable to find %s path from build identity\n", component);
+ logger(LL_ERROR, "Unable to find %s path from build identity\n", component);
return -1;
}
}
}
if (!path) {
- error("ERROR: Failed to get path for component %s\n", component);
+ logger(LL_ERROR, "Failed to get path for component %s\n", component);
return -1;
}
@@ -4392,28 +4401,33 @@ int restore_send_source_boot_object_v4(struct idevicerestore_client_t* client, p
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending %s now (%" PRIu64 " bytes)\n", component, fsize);
+ logger(LL_INFO, "Sending %s now (%" PRIu64 " bytes)\n", component, fsize);
struct _restore_send_file_data_ctx rctx;
rctx.client = client;
rctx.service = service;
rctx.last_progress = 0;
+ rctx.tag = progress_get_next_tag();
+
+ register_progress(rctx.tag, component);
if (ipsw_extract_send(client->ipsw, path, 8192, (ipsw_send_cb)_restore_send_file_data, &rctx) < 0) {
free(path);
_restore_service_free(service);
- error("ERROR: Failed to send component %s\n", component);
+ finalize_progress(rctx.tag);
+ logger(LL_ERROR, "Failed to send component %s\n", component);
return -1;
}
free(path);
_restore_service_free(service);
+ finalize_progress(rctx.tag);
- info("Done sending %s\n", component);
+ logger(LL_INFO, "Done sending %s\n", component);
return 0;
}
@@ -4436,7 +4450,7 @@ int restore_send_restore_local_policy(struct idevicerestore_client_t* client, pl
int ret = get_recovery_os_local_policy_tss_response(client, build_identity, &client->tss_localpolicy, plist_dict_get_item(message, "Arguments"));
if (ret < 0) {
- error("ERROR: Unable to get recovery os local policy tss response\n");
+ logger(LL_ERROR, "Unable to get recovery os local policy tss response\n");
return -1;
}
@@ -4444,7 +4458,7 @@ int restore_send_restore_local_policy(struct idevicerestore_client_t* client, pl
free(component_data);
component_data = NULL;
if (ret < 0) {
- error("ERROR: Unable to get personalized component %s\n", component);
+ logger(LL_ERROR, "Unable to get personalized component %s\n", component);
return -1;
}
@@ -4453,7 +4467,7 @@ int restore_send_restore_local_policy(struct idevicerestore_client_t* client, pl
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
@@ -4461,7 +4475,7 @@ int restore_send_restore_local_policy(struct idevicerestore_client_t* client, pl
restore_error = _restore_service_send(service, dict, 0);
_restore_service_free(service);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send component %s data\n", component);
+ logger(LL_ERROR, "Unable to send component %s data\n", component);
return -1;
}
@@ -4478,11 +4492,11 @@ int restore_send_buildidentity(struct idevicerestore_client_t* client, plist_t m
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("About to send BuildIdentity Dict...\n");
+ logger(LL_INFO, "About to send BuildIdentity Dict...\n");
plist_t build_identity = restore_get_build_identity_from_request(client, message);
@@ -4496,16 +4510,16 @@ int restore_send_buildidentity(struct idevicerestore_client_t* client, plist_t m
plist_dict_set_item(dict, "Variant", plist_new_string("Erase"));
}
- info("Sending BuildIdentityDict now...\n");
+ logger(LL_INFO, "Sending BuildIdentityDict now...\n");
restore_error = _restore_service_send(service, dict, 0);
_restore_service_free(service);
plist_free(dict);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send BuildIdentityDict (%d)\n", restore_error);
+ logger(LL_ERROR, "Unable to send BuildIdentityDict (%d)\n", restore_error);
return -1;
}
- info("Done sending BuildIdentityDict\n");
+ logger(LL_INFO, "Done sending BuildIdentityDict\n");
return 0;
}
@@ -4517,13 +4531,13 @@ int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* cl
plist_get_string_val(node, &fw_override_key);
}
if (!fw_override_key) {
- error("ERROR: Failed to get FWOverrideKey from arguments. Trying to continue anyway.\n");
+ logger(LL_ERROR, "Failed to get FWOverrideKey from arguments. Trying to continue anyway.\n");
return -1;
}
plist_t dict = plist_new_dict();
if (!client->recovery_variant) {
- error("ERROR: no RecoveryOS variant in BuildManifest. Trying to continue anyway.\n");
+ logger(LL_ERROR, "no RecoveryOS variant in BuildManifest. Trying to continue anyway.\n");
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
@@ -4531,7 +4545,7 @@ int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* cl
}
if (strncmp(fw_override_key, "RecoveryOS", 10) != 0) {
- error("ERROR: FWOVerrideKey has unexpected prefix\n");
+ logger(LL_ERROR, "FWOVerrideKey has unexpected prefix\n");
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
@@ -4541,7 +4555,7 @@ int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* cl
const char* component = fw_override_key+10;
char* path = NULL;
if (build_identity_get_component_path(client->recovery_variant, component, &path) < 0) {
- error("ERROR: Unable to find %s path from recovery build identity. Trying to continue anyway.\n", component);
+ logger(LL_ERROR, "Unable to find %s path from recovery build identity. Trying to continue anyway.\n", component);
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
@@ -4554,7 +4568,7 @@ int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* cl
free(path);
path = NULL;
if (ret < 0) {
- error("ERROR: Unable to extract component %s. Trying to continue anyway.\n", component);
+ logger(LL_ERROR, "Unable to extract component %s. Trying to continue anyway.\n", component);
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
@@ -4567,14 +4581,14 @@ int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* cl
free(component_data);
component_data = NULL;
if (ret < 0) {
- error("ERROR: Unable to get personalized component %s. Trying to continue anyway.\n", component);
+ logger(LL_ERROR, "Unable to get personalized component %s. Trying to continue anyway.\n", component);
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
return 0;
}
- info("Sending %s\n", fw_override_key);
+ logger(LL_INFO, "Sending %s\n", fw_override_key);
plist_dict_set_item(dict, "AdditionalBootImages", plist_new_data((char*)data, size));
free(data);
@@ -4588,7 +4602,7 @@ int restore_send_recovery_os_iboot_fw_files_images(struct idevicerestore_client_
{
plist_t build_id_manifest = plist_dict_get_item(client->recovery_variant, "Manifest");
if (!build_id_manifest) {
- error("ERROR: Missing Manifest dictionary in build identity?!\n");
+ logger(LL_ERROR, "Missing Manifest dictionary in build identity?!\n");
return -1;
}
@@ -4646,7 +4660,7 @@ int restore_send_recovery_os_iboot_fw_files_images(struct idevicerestore_client_
if (plist_dict_get_size(firmware_files) == 0) {
plist_free(firmware_files);
- info("NOTE: No iBoot firmware files. Continuing.\n");
+ logger(LL_NOTICE, "No iBoot firmware files. Continuing.\n");
plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
restored_send(client->restore->client, dict);
plist_free(dict);
@@ -4654,7 +4668,7 @@ int restore_send_recovery_os_iboot_fw_files_images(struct idevicerestore_client_
}
- info("Sending iBoot additional firmware files\n");
+ logger(LL_INFO, "Sending iBoot additional firmware files\n");
plist_dict_set_item(dict, "AdditionalBootImages", firmware_files);
restored_send(client->restore->client, dict);
@@ -4668,11 +4682,11 @@ int restore_send_recovery_os_image(struct idevicerestore_client_t* client, plist
const char* component = "OS";
char* path = NULL;
if (build_identity_get_component_path(client->recovery_variant, component, &path) < 0) {
- error("ERROR: Unable to find %s path from build identity\n", component);
+ logger(LL_ERROR, "Unable to find %s path from build identity\n", component);
return -1;
}
if (!path) {
- error("ERROR: Failed to get path for component %s\n", component);
+ logger(LL_ERROR, "Failed to get path for component %s\n", component);
return -1;
}
@@ -4681,28 +4695,33 @@ int restore_send_recovery_os_image(struct idevicerestore_client_t* client, plist
restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
if (!service) {
- error("ERROR: %s: Unable to connect to service client\n", __func__);
+ logger(LL_ERROR, "%s: Unable to connect to service client\n", __func__);
return -1;
}
- info("Sending %s now (%" PRIu64 " bytes)\n", component, fsize);
+ logger(LL_INFO, "Sending %s now (%" PRIu64 " bytes)\n", component, fsize);
struct _restore_send_file_data_ctx rctx;
rctx.client = client;
rctx.service = service;
rctx.last_progress = 0;
+ rctx.tag = progress_get_next_tag();
+
+ register_progress(rctx.tag, component);
if (ipsw_extract_send(client->ipsw, path, 8192, (ipsw_send_cb)_restore_send_file_data, &rctx) < 0) {
free(path);
_restore_service_free(service);
- error("ERROR: Failed to send component %s\n", component);
+ finalize_progress(rctx.tag);
+ logger(LL_ERROR, "Failed to send component %s\n", component);
return -1;
}
free(path);
_restore_service_free(service);
+ finalize_progress(rctx.tag);
- info("Done sending %s\n", component);
+ logger(LL_INFO, "Done sending %s\n", component);
return 0;
}
@@ -4711,7 +4730,7 @@ int restore_send_recovery_os_version_data(struct idevicerestore_client_t* client
{
plist_t build_id_info = plist_dict_get_item(client->recovery_variant, "Info");
if (!build_id_info) {
- error("ERROR: Missing Info dictionary in build identity?!\n");
+ logger(LL_ERROR, "Missing Info dictionary in build identity?!\n");
return -1;
}
plist_t version_data = plist_new_dict();
@@ -4724,7 +4743,7 @@ int restore_send_recovery_os_version_data(struct idevicerestore_client_t* client
plist_to_xml(version_data, &xml, &xml_len);
plist_free(version_data);
- info("Sending RecoveryOS version data\n");
+ logger(LL_INFO, "Sending RecoveryOS version data\n");
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "RecoveryOSVersionData", plist_new_data(xml, xml_len));
@@ -4744,39 +4763,39 @@ int restore_handle_data_request_msg(struct idevicerestore_client_t* client, plis
node = plist_dict_get_item(message, "DataType");
if (node && PLIST_STRING == plist_get_node_type(node)) {
const char *type = plist_get_string_ptr(node, NULL);
-debug("%s: type = %s\n", __func__, type);
+logger(LL_DEBUG, "%s: type = %s\n", __func__, type);
// this request is sent when restored is ready to receive the filesystem
if (!strcmp(type, "SystemImageData")) {
if (restore_send_filesystem(client, message) < 0) {
- error("ERROR: Unable to send filesystem\n");
+ logger(LL_ERROR, "Unable to send filesystem\n");
return -2;
}
}
else if (!strcmp(type, "BuildIdentityDict")) {
if (restore_send_buildidentity(client, message) < 0) {
- error("ERROR: Unable to send RootTicket\n");
+ logger(LL_ERROR, "Unable to send RootTicket\n");
return -1;
}
}
else if (!strcmp(type, "PersonalizedBootObjectV3")) {
if (restore_send_personalized_boot_object_v3(client, message) < 0) {
- error("ERROR: Unable to send PersonalizedBootObjectV3\n");
+ logger(LL_ERROR, "Unable to send PersonalizedBootObjectV3\n");
return -1;
}
}
else if (!strcmp(type, "SourceBootObjectV4")) {
if (restore_send_source_boot_object_v4(client, message) < 0) {
- error("ERROR: Unable to send SourceBootObjectV4\n");
+ logger(LL_ERROR, "Unable to send SourceBootObjectV4\n");
return -1;
}
}
else if (!strcmp(type, "RecoveryOSLocalPolicy")) {
if (restore_send_restore_local_policy(client, message) < 0) {
- error("ERROR: Unable to send RecoveryOSLocalPolicy\n");
+ logger(LL_ERROR, "Unable to send RecoveryOSLocalPolicy\n");
return -1;
}
}
@@ -4784,7 +4803,7 @@ debug("%s: type = %s\n", __func__, type);
// this request is sent when restored is ready to receive the filesystem
else if (!strcmp(type, "RecoveryOSASRImage")) {
if (restore_send_filesystem(client, message) < 0) {
- error("ERROR: Unable to send filesystem\n");
+ logger(LL_ERROR, "Unable to send filesystem\n");
return -2;
}
}
@@ -4792,7 +4811,7 @@ debug("%s: type = %s\n", __func__, type);
// Send RecoveryOS RTD
else if(!strcmp(type, "RecoveryOSRootTicketData")) {
if (restore_send_recovery_os_root_ticket(client, message) < 0) {
- error("ERROR: Unable to send RootTicket\n");
+ logger(LL_ERROR, "Unable to send RootTicket\n");
return -1;
}
}
@@ -4800,35 +4819,35 @@ debug("%s: type = %s\n", __func__, type);
// send RootTicket (== APTicket from the TSS request)
else if (!strcmp(type, "RootTicket")) {
if (restore_send_root_ticket(client, message) < 0) {
- error("ERROR: Unable to send RootTicket\n");
+ logger(LL_ERROR, "Unable to send RootTicket\n");
return -1;
}
}
// send KernelCache
else if (!strcmp(type, "KernelCache")) {
if (restore_send_component(client, message, "KernelCache", NULL) < 0) {
- error("ERROR: Unable to send kernelcache\n");
+ logger(LL_ERROR, "Unable to send kernelcache\n");
return -1;
}
}
else if (!strcmp(type, "DeviceTree")) {
if (restore_send_component(client, message, "DeviceTree", NULL) < 0) {
- error("ERROR: Unable to send DeviceTree\n");
+ logger(LL_ERROR, "Unable to send DeviceTree\n");
return -1;
}
}
else if (!strcmp(type, "SystemImageRootHash")) {
if (restore_send_component(client, message, "SystemVolume", type) < 0) {
- error("ERROR: Unable to send SystemImageRootHash data\n");
+ logger(LL_ERROR, "Unable to send SystemImageRootHash data\n");
return -1;
}
}
else if (!strcmp(type, "SystemImageCanonicalMetadata")) {
if (restore_send_component(client, message, "Ap,SystemVolumeCanonicalMetadata", type) < 0) {
- error("ERROR: Unable to send SystemImageCanonicalMetadata data\n");
+ logger(LL_ERROR, "Unable to send SystemImageCanonicalMetadata data\n");
return -1;
}
}
@@ -4836,132 +4855,131 @@ debug("%s: type = %s\n", __func__, type);
else if (!strcmp(type, "NORData")) {
if((client->flags & FLAG_EXCLUDE) == 0) {
if(restore_send_nor(client, message) < 0) {
- error("ERROR: Unable to send NOR data\n");
+ logger(LL_ERROR, "Unable to send NOR data\n");
return -1;
}
} else {
- info("Not sending NORData... Quitting...\n");
+ logger(LL_INFO, "Not sending NORData... Quitting...\n");
client->flags |= FLAG_QUIT;
}
}
else if (!strcmp(type, "BasebandData")) {
if(restore_send_baseband_data(client, message) < 0) {
- error("ERROR: Unable to send baseband data\n");
+ logger(LL_ERROR, "Unable to send baseband data\n");
return -1;
}
}
else if (!strcmp(type, "FDRTrustData")) {
if(restore_send_fdr_trust_data(client, message) < 0) {
- error("ERROR: Unable to send FDR Trust data\n");
+ logger(LL_ERROR, "Unable to send FDR Trust data\n");
return -1;
}
}
else if (!strcmp(type, "FUDData")) {
if(restore_send_image_data(client, message, "FUDImageList", "IsFUDFirmware", "FUDImageData") < 0) {
- error("ERROR: Unable to send FUD data\n");
+ logger(LL_ERROR, "Unable to send FUD data\n");
return -1;
}
}
else if (!strcmp(type, "FirmwareUpdaterPreflight")) {
if(restore_send_firmware_updater_preflight(client, message) < 0) {
- error("ERROR: Unable to send FirmwareUpdaterPreflight\n");
+ logger(LL_ERROR, "Unable to send FirmwareUpdaterPreflight\n");
return -1;
}
}
else if (!strcmp(type, "FirmwareUpdaterData")) {
if(restore_send_firmware_updater_data(client, message) < 0) {
- error("ERROR: Unable to send FirmwareUpdater data\n");
+ logger(LL_ERROR, "Unable to send FirmwareUpdater data\n");
return -1;
}
}
else if (!strcmp(type, "PersonalizedData")) {
if(restore_send_image_data(client, message, "ImageList", NULL, "ImageData") < 0) {
- error("ERROR: Unable to send Personalized data\n");
+ logger(LL_ERROR, "Unable to send Personalized data\n");
return -1;
}
}
else if (!strcmp(type, "EANData")) {
if(restore_send_image_data(client, message, "EANImageList", "IsEarlyAccessFirmware", "EANData") < 0) {
- error("ERROR: Unable to send Personalized data\n");
+ logger(LL_ERROR, "Unable to send Personalized data\n");
return -1;
}
}
else if (!strcmp(type, "BootabilityBundle")) {
if (restore_send_bootability_bundle_data(client, message) < 0) {
- error("ERROR: Unable to send BootabilityBundle data\n");
+ logger(LL_ERROR, "Unable to send BootabilityBundle data\n");
return -1;
}
}
else if (!strcmp(type, "ReceiptManifest")) {
if (restore_send_receipt_manifest(client, message) < 0) {
- error("ERROR: Unable to send ReceiptManifest data\n");
+ logger(LL_ERROR, "Unable to send ReceiptManifest data\n");
return -1;
}
}
else if (!strcmp(type, "BasebandUpdaterOutputData")) {
if (restore_handle_baseband_updater_output_data(client, message) < 0) {
- error("ERROR: Unable to send BasebandUpdaterOutputData data\n");
+ logger(LL_ERROR, "Unable to send BasebandUpdaterOutputData data\n");
return -1;
}
}
else if (!strcmp(type, "URLAsset")) {
if (restore_send_url_asset(client, message) < 0) {
- error("ERROR: Unable to send URLAsset data\n");
+ logger(LL_ERROR, "Unable to send URLAsset data\n");
return -1;
}
}
else if (!strcmp(type, "StreamedImageDecryptionKey")) {
if (restore_send_streamed_image_decryption_key(client, message) < 0) {
- error("ERROR: Unable to send StreamedImageDecryptionKey data\n");
+ logger(LL_ERROR, "Unable to send StreamedImageDecryptionKey data\n");
return -1;
}
}
else if (!strcmp(type, "RecoveryOSFileAssetImage")) {
if (restore_send_recovery_os_file_asset_image(client, message) < 0) {
- error("ERROR: Unable to send RecoveryOSFileImageAssetImage data\n");
+ logger(LL_ERROR, "Unable to send RecoveryOSFileImageAssetImage data\n");
return -1;
}
}
else if (!strcmp(type, "RecoveryOSIBootFWFilesImages")) {
if (restore_send_recovery_os_iboot_fw_files_images(client, message) < 0) {
- error("ERROR: Unable to send RecoveryOSIBootFWFilesImages data\n");
+ logger(LL_ERROR, "Unable to send RecoveryOSIBootFWFilesImages data\n");
return -1;
}
}
else if (!strcmp(type, "RecoveryOSImage")) {
if (restore_send_recovery_os_image(client, message) < 0) {
- error("ERROR: Unable to send RecoveryOSImage data\n");
+ logger(LL_ERROR, "Unable to send RecoveryOSImage data\n");
return -1;
}
}
else if (!strcmp(type, "RecoveryOSVersionData")) {
if (restore_send_recovery_os_version_data(client, message) < 0) {
- error("ERROR: Unable to send RecoveryOSVersionData data\n");
+ logger(LL_ERROR, "Unable to send RecoveryOSVersionData data\n");
return -1;
}
}
else {
// Unknown DataType!!
- error("Unknown data request '%s' received\n", type);
- if (idevicerestore_debug)
- debug_plist(message);
+ logger(LL_ERROR, "Unknown data request '%s' received\n", type);
+ logger_dump_plist(LL_VERBOSE, message, 1);
}
}
return 0;
@@ -4992,40 +5010,38 @@ static void* _restore_handle_async_data_request(void* args)
static int restore_handle_restored_crash(struct idevicerestore_client_t* client, plist_t message)
{
plist_t backtrace = plist_dict_get_item(message, "RestoredBacktrace");
- info("*** restored crashed, backtrace following ***");
+ logger(LL_INFO, "*** restored crashed, backtrace following ***\n");
if (PLIST_IS_STRING(backtrace)) {
- info("%s\n", plist_get_string_ptr(backtrace, NULL));
+ logger(LL_INFO, "%s\n", plist_get_string_ptr(backtrace, NULL));
} else if (PLIST_IS_ARRAY(backtrace)) {
uint32_t i = 0;
for (i = 0; i < plist_array_get_size(backtrace); i++) {
plist_t line = plist_array_get_item(backtrace, i);
- info("\t%s\n", plist_get_string_ptr(line, NULL));
+ logger(LL_INFO, "\t%s\n", plist_get_string_ptr(line, NULL));
}
} else {
- debug_plist(message);
+ logger_dump_plist(LL_VERBOSE, message, 1);
}
return 0;
}
static int restore_handle_async_wait(struct idevicerestore_client_t* client, plist_t message)
{
- debug("AsyncWait\n");
- if (idevicerestore_debug)
- debug_plist(message);
+ logger(LL_DEBUG, "AsyncWait\n");
+ logger_dump_plist(LL_DEBUG, message, 1);
return 0;
}
static int restore_handle_restore_attestation(struct idevicerestore_client_t* client, plist_t message)
{
- if (idevicerestore_debug)
- debug_plist(message);
- debug("Sending RestoreShouldAttest: false\n");
+ logger_dump_plist(LL_DEBUG, message, 1);
+ logger(LL_DEBUG, "Sending RestoreShouldAttest: false\n");
plist_t dict = plist_new_dict();
plist_dict_set_item(dict, "RestoreShouldAttest", plist_new_bool(0));
restored_error_t restore_error = restored_send(client->restore->client, dict);
plist_free(dict);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to send RestoreShouldAttest (%d)\n", restore_error);
+ logger(LL_ERROR, "Unable to send RestoreShouldAttest (%d)\n", restore_error);
return -1;
}
return 0;
@@ -5075,7 +5091,7 @@ static void _restore_calculate_recovery_os_partition_size(struct idevicerestore_
const char* path = plist_get_string_ptr(p_path, NULL);
uint64_t fsize = 0;
if (ipsw_get_file_size(client->ipsw, path, &fsize) == 0) {
- debug("%s: Adding %s (%s, %llu bytes)\n", __func__, component, path, fsize);
+ logger(LL_DEBUG, "%s: Adding %s (%s, %llu bytes)\n", __func__, component, path, fsize);
total_size += (double)fsize / 0x100000;
}
}
@@ -5190,12 +5206,12 @@ plist_t restore_supported_message_types()
#ifdef HAVE_REVERSE_PROXY
static void rp_log_cb(reverse_proxy_client_t client, const char* log_msg, void* user_data)
{
- info("ReverseProxy[%s]: %s\n", (reverse_proxy_get_type(client) == RP_TYPE_CTRL) ? "Ctrl" : "Conn", log_msg);
+ logger(LL_INFO, "ReverseProxy[%s]: %s\n", (reverse_proxy_get_type(client) == RP_TYPE_CTRL) ? "Ctrl" : "Conn", log_msg);
}
static void rp_status_cb(reverse_proxy_client_t client, reverse_proxy_status_t status, const char* status_msg, void* user_data)
{
- info("ReverseProxy[%s]: (status=%d) %s\n", (reverse_proxy_get_type(client) == RP_TYPE_CTRL) ? "Ctrl" : "Conn", status, status_msg);
+ logger(LL_INFO, "ReverseProxy[%s]: (status=%d) %s\n", (reverse_proxy_get_type(client) == RP_TYPE_CTRL) ? "Ctrl" : "Conn", status, status_msg);
}
#endif
@@ -5218,10 +5234,10 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// open our connection to the device and verify we're in restore mode
err = restore_open_with_timeout(client);
if (err < 0) {
- error("ERROR: Unable to open device in restore mode\n");
+ logger(LL_ERROR, "Unable to open device in restore mode\n");
return (err == -2) ? -1: -2;
}
- info("Device %s has successfully entered restore mode\n", client->udid);
+ logger(LL_INFO, "Device %s has successfully entered restore mode\n", client->udid);
client->restore->build_identity = build_identity;
restore = client->restore->client;
@@ -5231,30 +5247,30 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
if (restore_error == RESTORE_E_SUCCESS) {
uint64_t i = 0;
uint8_t b = 0;
- info("Hardware Information:\n");
+ logger(LL_INFO, "Hardware Information:\n");
node = plist_dict_get_item(hwinfo, "BoardID");
if (node && plist_get_node_type(node) == PLIST_UINT) {
plist_get_uint_val(node, &i);
- info("BoardID: %d\n", (int)i);
+ logger(LL_INFO, "BoardID: %d\n", (int)i);
}
node = plist_dict_get_item(hwinfo, "ChipID");
if (node && plist_get_node_type(node) == PLIST_UINT) {
plist_get_uint_val(node, &i);
- info("ChipID: %d\n", (int)i);
+ logger(LL_INFO, "ChipID: %d\n", (int)i);
}
node = plist_dict_get_item(hwinfo, "UniqueChipID");
if (node && plist_get_node_type(node) == PLIST_UINT) {
plist_get_uint_val(node, &i);
- info("UniqueChipID: %" PRIu64 "\n", i);
+ logger(LL_INFO, "UniqueChipID: %" PRIu64 "\n", i);
}
node = plist_dict_get_item(hwinfo, "ProductionMode");
if (node && plist_get_node_type(node) == PLIST_BOOLEAN) {
plist_get_bool_val(node, &b);
- info("ProductionMode: %s\n", (b==1) ? "true":"false");
+ logger(LL_INFO, "ProductionMode: %s\n", (b==1) ? "true":"false");
}
plist_free(hwinfo);
}
@@ -5266,7 +5282,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
node = plist_dict_get_item(hwinfo, "PreviousExitStatus");
if (node && plist_get_node_type(node) == PLIST_STRING) {
plist_get_string_val(node, &sval);
- info("Previous restore exit status: %s\n", sval);
+ logger(LL_INFO, "Previous restore exit status: %s\n", sval);
free(sval);
sval = NULL;
}
@@ -5274,7 +5290,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
node = plist_dict_get_item(hwinfo, "USBLog");
if (node && plist_get_node_type(node) == PLIST_STRING) {
plist_get_string_val(node, &sval);
- info("USB log is available:\n%s\n", sval);
+ logger(LL_INFO, "USB log is available:\n%s\n", sval);
free(sval);
sval = NULL;
}
@@ -5282,7 +5298,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
node = plist_dict_get_item(hwinfo, "PanicLog");
if (node && plist_get_node_type(node) == PLIST_STRING) {
plist_get_string_val(node, &sval);
- info("Panic log is available:\n%s\n", sval);
+ logger(LL_INFO, "Panic log is available:\n%s\n", sval);
free(sval);
sval = NULL;
}
@@ -5294,42 +5310,42 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
}
#ifdef HAVE_REVERSE_PROXY
- info("Starting Reverse Proxy\n");
+ logger(LL_INFO, "Starting Reverse Proxy\n");
reverse_proxy_client_t rproxy = NULL;
if (reverse_proxy_client_create_with_port(device, &rproxy, REVERSE_PROXY_DEFAULT_PORT) != REVERSE_PROXY_E_SUCCESS) {
- error("Could not create Reverse Proxy\n");
+ logger(LL_ERROR, "Could not create Reverse Proxy\n");
} else {
if (client->flags & FLAG_DEBUG) {
reverse_proxy_client_set_log_callback(rproxy, rp_log_cb, NULL);
}
reverse_proxy_client_set_status_callback(rproxy, rp_status_cb, NULL);
if (reverse_proxy_client_start_proxy(rproxy, 2) != REVERSE_PROXY_E_SUCCESS) {
- error("Device didn't accept new reverse proxy protocol, trying to use old one\n");
+ logger(LL_ERROR, "Device didn't accept new reverse proxy protocol, trying to use old one\n");
reverse_proxy_client_free(rproxy);
rproxy = NULL;
if (reverse_proxy_client_create_with_port(device, &rproxy, REVERSE_PROXY_DEFAULT_PORT) != REVERSE_PROXY_E_SUCCESS) {
- error("Could not create Reverse Proxy\n");
+ logger(LL_ERROR, "Could not create Reverse Proxy\n");
} else {
if (client->flags & FLAG_DEBUG) {
reverse_proxy_client_set_log_callback(rproxy, rp_log_cb, NULL);
}
reverse_proxy_client_set_status_callback(rproxy, rp_status_cb, NULL);
if (reverse_proxy_client_start_proxy(rproxy, 1) != REVERSE_PROXY_E_SUCCESS) {
- error("ReverseProxy: Device didn't accept old protocol, giving up\n");
+ logger(LL_ERROR, "ReverseProxy: Device didn't accept old protocol, giving up\n");
}
}
}
}
#else
fdr_client_t fdr_control_channel = NULL;
- info("Starting FDR listener thread\n");
+ logger(LL_INFO, "Starting FDR listener thread\n");
if (!fdr_connect(device, FDR_CTRL, &fdr_control_channel)) {
if(thread_new(&fdr_thread, fdr_listener_thread, fdr_control_channel)) {
- error("ERROR: Failed to start FDR listener thread\n");
+ logger(LL_ERROR, "Failed to start FDR listener thread\n");
fdr_thread = THREAD_T_NULL; /* undefined after failure */
}
} else {
- error("ERROR: Failed to start FDR Ctrl channel\n");
+ logger(LL_ERROR, "Failed to start FDR Ctrl channel\n");
// FIXME: We might want to return failure here as it will likely fail
}
#endif
@@ -5429,16 +5445,16 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
uint64_t max_size = 0;
uint64_t min_size = 0;
_restore_calculate_recovery_os_partition_size(client, &min_size, &max_size);
- info("Calculated recoveryOSPartitionSize as %" PRIu64 " MB\n", min_size);
- info("Calculated recoveryOSMaxPartitionSize as %" PRIu64 " MB\n", max_size);
+ logger(LL_INFO, "Calculated recoveryOSPartitionSize as %" PRIu64 " MB\n", min_size);
+ logger(LL_INFO, "Calculated recoveryOSMaxPartitionSize as %" PRIu64 " MB\n", max_size);
plist_dict_set_item(opts, "recoveryOSMaxPartitionSize", plist_new_uint(max_size));
plist_dict_set_item(opts, "recoveryOSPartitionSize", plist_new_uint(min_size));
}
if (plist_dict_get_bool(client->parameters, "RequiresNonceSlot")) {
- info("Device will use nonce slots.\n");
+ logger(LL_INFO, "Device will use nonce slots.\n");
} else {
- info("Device will not use nonce slots.\n");
+ logger(LL_INFO, "Device will not use nonce slots.\n");
}
// Added for iOS 18.0 beta 1
@@ -5452,7 +5468,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
if (node && plist_get_node_type(node) == PLIST_STRING) {
char* sval = NULL;
plist_get_string_val(node, &sval);
- debug("TZ0RequiredCapacity: %s\n", sval);
+ logger(LL_DEBUG, "TZ0RequiredCapacity: %s\n", sval);
plist_dict_set_item(opts, "TZ0RequiredCapacity", plist_copy(node));
free(sval);
sval = NULL;
@@ -5504,7 +5520,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// start the restore process
restore_error = restored_start_restore(restore, opts, client->restore->protocol_version);
if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Unable to start the restore process\n");
+ logger(LL_ERROR, "Unable to start the restore process\n");
plist_free(opts);
restore_client_free(client);
return -1;
@@ -5516,30 +5532,30 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// restored and passes that data on to it's specific handler
while (!(client->flags & FLAG_QUIT)) {
if (err != 0 && client->flags & FLAG_IGNORE_ERRORS) {
- error("WARNING: Attempting to continue after critical error, restore might fail...\n");
+ logger(LL_WARNING, "Attempting to continue after critical error, restore might fail...\n");
err = 0;
}
// finally, if any of these message handlers returned -1 then we encountered
// an unrecoverable error, so we need to bail.
if (err < 0) {
- error("ERROR: Unable to successfully restore device\n");
+ logger(LL_ERROR, "Unable to successfully restore device\n");
client->flags |= FLAG_QUIT;
}
restore_error = restored_receive(restore, &message);
#ifdef HAVE_RESTORE_E_RECEIVE_TIMEOUT
if (restore_error == RESTORE_E_RECEIVE_TIMEOUT) {
- debug("No data to read (timeout)\n");
+ logger(LL_DEBUG, "No data to read (timeout)\n");
message = NULL;
continue;
} else if (restore_error != RESTORE_E_SUCCESS) {
- error("ERROR: Could not read data (%d). Aborting.\n", restore_error);
+ logger(LL_ERROR, "Could not read data (%d). Aborting.\n", restore_error);
err = -11;
break;
}
#else
if (restore_error != RESTORE_E_SUCCESS) {
- debug("No data to read\n");
+ logger(LL_DEBUG, "No data to read\n");
message = NULL;
continue;
}
@@ -5548,9 +5564,8 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// discover what kind of message has been received
node = plist_dict_get_item(message, "MsgType");
if (!node || plist_get_node_type(node) != PLIST_STRING) {
- debug("Unknown message received:\n");
- //if (idevicerestore_debug)
- debug_plist(message);
+ logger(LL_DEBUG, "Unknown message received:\n");
+ logger_dump_plist(LL_DEBUG, message, 1);
plist_free(message);
message = NULL;
continue;
@@ -5572,7 +5587,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
args->message = plist_copy(message);
if (thread_new(&t, _restore_handle_async_data_request, args) < 0) {
free(args);
- error("ERROR: Failed to start async data request handler thread!\n");
+ logger(LL_ERROR, "Failed to start async data request handler thread!\n");
err = -1;
if (client->flags & FLAG_IGNORE_ERRORS) {
client->flags &= ~FLAG_IGNORE_ERRORS;
@@ -5614,7 +5629,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// Get checkpoint id
node = plist_dict_get_item(message, "CHECKPOINT_ID");
if (!node || plist_get_node_type(node) != PLIST_INT) {
- debug("Failed to parse checkpoint id from checkpoint plist\n");
+ logger(LL_DEBUG, "Failed to parse checkpoint id from checkpoint plist\n");
err = -1;
break;
}
@@ -5625,7 +5640,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// Get checkpoint result
node = plist_dict_get_item(message, "CHECKPOINT_RESULT");
if (!node || plist_get_node_type(node) != PLIST_INT) {
- debug("Failed to parse checkpoint result from checkpoint plist\n");
+ logger(LL_DEBUG, "Failed to parse checkpoint result from checkpoint plist\n");
err = -1;
break;
}
@@ -5637,17 +5652,17 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
}
if (ckpt_complete) {
- info("Checkpoint completed id: 0x%" PRIX64 " (%s) result=%" PRIi64 "\n", ckpt_id, ckpt_name, ckpt_res);
+ logger(LL_VERBOSE, "Checkpoint completed id: 0x%" PRIX64 " (%s) result=%" PRIi64 "\n", ckpt_id, ckpt_name, ckpt_res);
} else {
- info("Checkpoint started id: 0x%" PRIX64 " (%s)\n", ckpt_id, ckpt_name);
+ logger(LL_VERBOSE, "Checkpoint started id: 0x%" PRIX64 " (%s)\n", ckpt_id, ckpt_name);
}
node = plist_dict_get_item(message, "CHECKPOINT_WARNING");
if (node) {
- info("Checkpoint WARNING id: 0x%" PRIX64 " result=%" PRIi64 ": %s\n", ckpt_id, ckpt_res, plist_get_string_ptr(node, NULL));
+ logger(LL_VERBOSE, "Checkpoint WARNING id: 0x%" PRIX64 " result=%" PRIi64 ": %s\n", ckpt_id, ckpt_res, plist_get_string_ptr(node, NULL));
}
node = plist_dict_get_item(message, "CHECKPOINT_ERROR");
if (node) {
- info("Checkpoint FAILURE id: 0x%" PRIX64 " result=%" PRIi64 ": %s\n", ckpt_id, ckpt_res, plist_get_string_ptr(node, NULL));
+ logger(LL_VERBOSE, "Checkpoint FAILURE id: 0x%" PRIX64 " result=%" PRIi64 ": %s\n", ckpt_id, ckpt_res, plist_get_string_ptr(node, NULL));
}
}
@@ -5678,9 +5693,8 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// there might be some other message types i'm not aware of, but I think
// at least the "previous error logs" messages usually end up here
else {
- debug("Unknown message type received\n");
- //if (idevicerestore_debug)
- debug_plist(message);
+ logger(LL_DEBUG, "Unknown message type received\n");
+ logger_dump_plist(LL_DEBUG, message, 1);
}
free(type);