diff options
Diffstat (limited to 'src/ipsw.c')
-rw-r--r-- | src/ipsw.c | 242 |
1 files changed, 135 insertions, 107 deletions
@@ -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; } } |