From c5aef53c60055d9a18349e6fa8b8f135fb89f046 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 17 Oct 2014 00:25:26 +0200 Subject: Fix handling of files larger than 2GB on 32bit systems --- src/asr.c | 33 +++++++++++++++++---------------- src/download.c | 4 ---- src/ipsw.c | 26 +++++++++++++------------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/asr.c b/src/asr.c index 591b908..c82d48c 100644 --- a/src/asr.c +++ b/src/asr.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -207,9 +208,9 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) { return -1; } - fseek(file, 0, SEEK_END); - length = ftell(file); - fseek(file, 0, SEEK_SET); + fseeko(file, 0, SEEK_END); + length = ftello(file); + fseeko(file, 0, SEEK_SET); payload_info = plist_new_dict(); plist_dict_set_item(payload_info, "Port", plist_new_uint(1)); @@ -258,8 +259,10 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) { plist_get_string_val(node, &command); if (!strcmp(command, "OOBData")) { - asr_handle_oob_data_request(asr, packet, file); + int ret = asr_handle_oob_data_request(asr, packet, file); plist_free(packet); + if (ret < 0) + return ret; } else if(!strcmp(command, "Payload")) { plist_free(packet); break; @@ -298,21 +301,19 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) { oob_data = (char*) malloc(oob_length); if (oob_data == NULL) { error("ERROR: Out of memory\n"); - plist_free(packet); return -1; } - fseek(file, oob_offset, SEEK_SET); + fseeko(file, oob_offset, SEEK_SET); if (fread(oob_data, 1, oob_length, file) != oob_length) { - error("ERROR: Unable to read OOB data from filesystem offset\n"); - plist_free(packet); + error("ERROR: Unable to read OOB data from filesystem offset: %s\n", + strerror(errno)); 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"); - plist_free(packet); free(oob_data); return -1; } @@ -321,21 +322,21 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) { } int asr_send_payload(asr_client_t asr, const char* filesystem) { - int i = 0; char data[ASR_PAYLOAD_PACKET_SIZE]; FILE* file = NULL; - uint32_t bytes = 0; - uint32_t length = 0; + off_t i, length, bytes = 0; double progress = 0; file = fopen(filesystem, "rb"); if (file == NULL) { + error("ERROR: Unable to open filesystem image %s: %s\n", + filesystem, strerror(errno)); return -1; } - fseek(file, 0, SEEK_END); - length = ftell(file); - fseek(file, 0, SEEK_SET); + fseeko(file, 0, SEEK_END); + length = ftello(file); + fseeko(file, 0, SEEK_SET); int chunk = 0; int add_checksum = 0; @@ -399,7 +400,7 @@ int asr_send_payload(asr_client_t asr, const char* filesystem) { } bytes += size; - progress = ((double) bytes/ (double) length); + progress = ((double)bytes / (double)length); if (asr->progress_cb && ((int)(progress*100) > asr->lastprogress)) { asr->progress_cb(progress, asr->progress_cb_data); asr->lastprogress = (int)(progress*100); diff --git a/src/download.c b/src/download.c index 6adc523..82087df 100644 --- a/src/download.c +++ b/src/download.c @@ -27,10 +27,6 @@ #include "download.h" #include "common.h" -#ifdef WIN32 -#define ftello(x) ftell(x) -#endif - typedef struct { int length; char* content; diff --git a/src/ipsw.c b/src/ipsw.c index 9f24784..061d00d 100644 --- a/src/ipsw.c +++ b/src/ipsw.c @@ -87,6 +87,7 @@ int ipsw_get_file_size(const char* ipsw, const char* infile, off_t* size) { } int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfile) { + int ret = 0; ipsw_archive* archive = ipsw_open(ipsw); if (archive == NULL || archive->zip == NULL) { error("ERROR: Invalid archive\n"); @@ -125,27 +126,26 @@ int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfi return -1; } - int i = 0; - int size = 0; - int bytes = 0; - int count = 0; - double progress = 0; + off_t i, bytes = 0; + int count, size = BUFSIZE; + double progress; for(i = zstat.size; i > 0; i -= count) { if (i < BUFSIZE) size = i; - else - size = BUFSIZE; count = zip_fread(zfile, buffer, size); if (count < 0) { error("ERROR: zip_fread: %s\n", infile); - zip_fclose(zfile); - free(buffer); - return -1; + ret = -1; + break; + } + if (fwrite(buffer, 1, count, fd) != count) { + error("ERROR: frite: %s\n", outfile); + ret = -1; + break; } - fwrite(buffer, 1, count, fd); bytes += size; - progress = ((double) bytes/ (double) zstat.size) * 100.0; + progress = ((double)bytes / (double)zstat.size) * 100.0; print_progress_bar(progress); } @@ -153,7 +153,7 @@ int ipsw_extract_to_file(const char* ipsw, const char* infile, const char* outfi zip_fclose(zfile); ipsw_close(archive); free(buffer); - return 0; + return ret; } int ipsw_file_exists(const char* ipsw, const char* infile) -- cgit v1.1-32-gdbae