summaryrefslogtreecommitdiffstats
path: root/src/ipsw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipsw.c')
-rw-r--r--src/ipsw.c242
1 files changed, 135 insertions, 107 deletions
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;
}
}