summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/idevicerestore.c120
1 files changed, 59 insertions, 61 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 1b4b352..8c5cf3c 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -26,6 +26,7 @@
#include <getopt.h>
#include <plist/plist.h>
#include <zlib.h>
+#include <libgen.h>
#include "dfu.h"
#include "tss.h"
@@ -683,17 +684,66 @@ int main(int argc, char* argv[]) {
}
}
- // Extract filesystem from IPSW and return its name
- char* filesystem = NULL;
- int ipsw_res = ipsw_extract_filesystem(client->ipsw, build_identity, &filesystem);
- if (ipsw_res < 0) {
- error("ERROR: Unable to extract filesystem from IPSW\n");
- if (client->tss)
- plist_free(client->tss);
- plist_free(buildmanifest);
+ // Get filesystem name from build identity
+ char* fsname = NULL;
+ if (build_identity_get_component_path(build_identity, "OS", &fsname) < 0) {
+ error("ERROR: Unable get path for filesystem component\n");
return -1;
}
- int delete_fs = (ipsw_res == 0);
+
+ // check if we already have an extracted filesystem
+ int delete_fs = 0;
+ char* filesystem = NULL;
+ struct stat st;
+ memset(&st, '\0', sizeof(struct stat));
+ char tmpf[1024];
+ if (client->cache_dir) {
+ if (stat(client->cache_dir, &st) < 0) {
+ mkdir_with_parents(client->cache_dir, 0755);
+ }
+ strcpy(tmpf, client->cache_dir);
+ strcat(tmpf, "/");
+ char *ipswtmp = strdup(client->ipsw);
+ strcat(tmpf, basename(ipswtmp));
+ free(ipswtmp);
+ } else {
+ strcpy(tmpf, ipsw);
+ }
+ char* p = strrchr((const char*)tmpf, '.');
+ if (p) {
+ *p = '\0';
+ }
+ strcat(tmpf, "/");
+ strcat(tmpf, fsname);
+
+ memset(&st, '\0', sizeof(struct stat));
+ if (stat(tmpf, &st) == 0) {
+ off_t fssize = 0;
+ ipsw_get_file_size(client->ipsw, fsname, &fssize);
+ if ((fssize > 0) && (st.st_size == fssize)) {
+ info("Using cached filesystem from '%s'\n", tmpf);
+ filesystem = strdup(tmpf);
+ }
+ }
+
+ if (!filesystem) {
+ filesystem = tempnam(NULL, "ipsw_");
+ if (!filesystem) {
+ error("WARNING: Could not get temporary filename!\n");
+ filesystem = strdup(fsname);
+ }
+ delete_fs = 1;
+
+ // Extract filesystem from IPSW
+ info("Extracting filesystem from IPSW\n");
+ if (ipsw_extract_to_file(client->ipsw, fsname, filesystem) < 0) {
+ error("ERROR: Unable to extract filesystem from IPSW\n");
+ if (client->tss)
+ plist_free(client->tss);
+ plist_free(buildmanifest);
+ return -1;
+ }
+ }
// if the device is in DFU mode, place device into recovery mode
@@ -1276,58 +1326,6 @@ int build_manifest_get_identity_count(plist_t build_manifest) {
return plist_array_get_size(build_identities_array);
}
-int ipsw_extract_filesystem(const char* ipsw, plist_t build_identity, char** filesystem) {
- char* filename = NULL;
-
- if (build_identity_get_component_path(build_identity, "OS", &filename) < 0) {
- error("ERROR: Unable get path for filesystem component\n");
- return -1;
- }
-
- // check if we already have an extracted filesystem
- // for /path/X.ipsw we check /path/X/[filename].dmg
- char tmpf[1024];
- strcpy(tmpf, ipsw);
- char* p = strrchr((const char*)tmpf, '.');
- if (p) {
- *p = '\0';
- }
- strcat(tmpf, "/");
- strcat(tmpf, filename);
-
- struct stat st;
- memset(&st, '\0', sizeof(struct stat));
- if (stat(tmpf, &st) == 0) {
- off_t fssize = 0;
- ipsw_get_file_size(ipsw, filename, &fssize);
- if ((fssize > 0) && (st.st_size == fssize)) {
- info("Using cached filesystem from '%s'\n", tmpf);
- *filesystem = strdup(tmpf);
- free(filename);
- return 1;
- }
- }
-
- char* outfile = tempnam(NULL, "ipsw_");
- if (!outfile) {
- error("WARNING: Could not get temporary filename!\n");
- }
-
- info("Extracting filesystem from IPSW\n");
- if (ipsw_extract_to_file(ipsw, filename, (outfile) ? outfile : filename) < 0) {
- error("ERROR: Unable to extract filesystem\n");
- free(filename);
- if (outfile) {
- free(outfile);
- }
- return -1;
- }
-
- *filesystem = outfile;
- free(filename);
- return 0;
-}
-
int ipsw_get_component_by_path(const char* ipsw, plist_t tss, const char* component, const char* path, char** data, uint32_t* size) {
img3_file* img3 = NULL;
uint32_t component_size = 0;