diff options
-rw-r--r-- | src/common.c | 25 | ||||
-rw-r--r-- | src/common.h | 3 | ||||
-rw-r--r-- | src/idevicerestore.c | 58 |
3 files changed, 72 insertions, 14 deletions
diff --git a/src/common.c b/src/common.c index e20bd78..904687e 100644 --- a/src/common.c +++ b/src/common.c @@ -21,6 +21,8 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <errno.h> #include "common.h" @@ -132,3 +134,26 @@ char *generate_guid() guid[36] = '\0'; return guid; } + +int mkdir_with_parents(const char *dir, int mode) +{ + if (!dir) return -1; + if (__mkdir(dir, mode) == 0) { + return 0; + } else { + if (errno == EEXIST) return 0; + } + int res; + char *parent = strdup(dir); + parent = dirname(parent); + if (parent && (strcmp(parent, ".") != 0)) { + res = mkdir_with_parents(parent, mode); + } else { + res = -1; + } + free(parent); + if (res == 0) { + mkdir_with_parents(dir, mode); + } + return res; +} diff --git a/src/common.h b/src/common.h index e0c4b6a..e52c902 100644 --- a/src/common.h +++ b/src/common.h @@ -91,6 +91,7 @@ struct idevicerestore_client_t { char* version; char* build; char* restore_boot_args; + char* cache_dir; }; static struct idevicerestore_mode_t idevicerestore_modes[] = { @@ -123,6 +124,8 @@ char *generate_guid(); #define FMT_qu "%qu" #endif +int mkdir_with_parents(const char *dir, int mode); + extern struct idevicerestore_client_t* idevicerestore; #ifdef __cplusplus diff --git a/src/idevicerestore.c b/src/idevicerestore.c index ab9ddf6..1b4b352 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -42,7 +42,7 @@ #include "locking.h" -#define VERSION_XML "cache/version.xml" +#define VERSION_XML "version.xml" int use_apple_server; @@ -59,6 +59,7 @@ static struct option longopts[] = { { "shsh", no_argument, NULL, 't' }, { "pwn", no_argument, NULL, 'p' }, { "no-action", no_argument, NULL, 'n' }, + { "cache-path", required_argument, NULL, 'C' }, { NULL, 0, NULL, 0 } }; @@ -84,6 +85,8 @@ void usage(int argc, char* argv[]) { printf(" -p|--pwn Put device in pwned DFU mode and exit (limera1n devices only)\n"); printf(" -n|--no-action Do not perform any restore action. If combined with -l option\n"); printf(" the on demand ipsw download is performed before exiting.\n"); + printf(" -C|--cache-path DIR Use specified directory for caching extracted\n"); + printf(" or other reused files.\n"); printf("\n"); } @@ -96,13 +99,28 @@ static int load_version_data(struct idevicerestore_client_t* client) struct stat fst; int cached = 0; - if ((stat(VERSION_XML, &fst) < 0) || ((time(NULL)-86400) > fst.st_mtime)) { - __mkdir("cache", 0755); + char version_xml[1024]; - if (download_to_file("http://ax.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 '" VERSION_XML "'\n"); + if (client->cache_dir) { + if (stat(client->cache_dir, &fst) < 0) { + mkdir_with_parents(client->cache_dir, 0755); + } + strcpy(version_xml, client->cache_dir); + strcat(version_xml, "/"); + strcat(version_xml, VERSION_XML); + } else { + strcpy(version_xml, VERSION_XML); + } + + if ((stat(version_xml, &fst) < 0) || ((time(NULL)-86400) > fst.st_mtime)) { + char version_xml_tmp[1024]; + strcpy(version_xml_tmp, version_xml); + strcat(version_xml_tmp, ".tmp"); + + if (download_to_file("http://ax.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); } else { info("NOTE: Updated version data.\n"); } @@ -113,10 +131,10 @@ static int load_version_data(struct idevicerestore_client_t* client) char *verbuf = NULL; size_t verlen = 0; - read_file(VERSION_XML, (void**)&verbuf, &verlen); + read_file(version_xml, (void**)&verbuf, &verlen); if (!verbuf) { - error("ERROR: Could not load '" VERSION_XML "'.\n"); + error("ERROR: Could not load '%s'\n", version_xml); return -1; } @@ -125,7 +143,7 @@ static int load_version_data(struct idevicerestore_client_t* client) free(verbuf); if (!client->version_data) { - error("ERROR: Cannot parse plist data from '" VERSION_XML "'.\n"); + error("ERROR: Cannot parse plist data from '%s'.\n", version_xml); return -1; } @@ -156,7 +174,7 @@ int main(int argc, char* argv[]) { } memset(client, '\0', sizeof(struct idevicerestore_client_t)); - while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:n", longopts, &optindex)) > 0) { + while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:nC:", longopts, &optindex)) > 0) { switch (opt) { case 'h': usage(argc, argv); @@ -217,6 +235,10 @@ int main(int argc, char* argv[]) { client->flags |= FLAG_NOACTION; break; + case 'C': + client->cache_dir = strdup(optarg); + break; + default: usage(argc, argv); return -1; @@ -289,10 +311,18 @@ int main(int argc, char* argv[]) { fnpart++; } struct stat fst; - char wtfipsw[256]; - sprintf(wtfipsw, "cache/%s", fnpart); + char wtfipsw[1024]; + if (client->cache_dir) { + if (stat(client->cache_dir, &fst) < 0) { + mkdir_with_parents(client->cache_dir, 0755); + } + strcpy(wtfipsw, client->cache_dir); + strcat(wtfipsw, "/"); + strcat(wtfipsw, fnpart); + } else { + strcpy(wtfipsw, fnpart); + } if (stat(wtfipsw, &fst) != 0) { - __mkdir("cache", 0755); download_to_file(s_wtfurl, wtfipsw, 0); } |