summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common.c25
-rw-r--r--src/common.h3
-rw-r--r--src/idevicerestore.c58
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);
}