summaryrefslogtreecommitdiffstats
path: root/src/idevicerestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r--src/idevicerestore.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 23e49f5..93c6766 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -34,11 +34,14 @@
#include "common.h"
#include "normal.h"
#include "restore.h"
+#include "download.h"
#include "recovery.h"
#include "idevicerestore.h"
#include "limera1n.h"
+#define VERSION_XML "cache/version.xml"
+
int use_apple_server;
static struct option longopts[] = {
@@ -70,6 +73,59 @@ void usage(int argc, char* argv[]) {
printf("\n");
}
+static int load_version_data(struct idevicerestore_client_t* client)
+{
+ if (!client) {
+ return -1;
+ }
+
+ struct stat fst;
+ int cached = 0;
+
+ if ((stat(VERSION_XML, &fst) < 0) || ((time(NULL)-86400) > fst.st_mtime)) {
+ char tmpf[256];
+ tmpf[0] = '\0';
+ if (!tmpnam(tmpf) || (tmpf[0] == '\0')) {
+ error("ERROR: Could not get temporary filename\n");
+ return -1;
+ }
+
+ if (download_to_file("http://itunes.com/version", tmpf) == 0) {
+ __mkdir("cache", 0755);
+ remove(VERSION_XML);
+ if (rename(tmpf, VERSION_XML) < 0) {
+ error("ERROR: Could not update '" VERSION_XML "'\n");
+ } else {
+ info("NOTE: Updated version data.\n");
+ }
+ }
+ } else {
+ cached = 1;
+ }
+
+ char *verbuf = NULL;
+ size_t verlen = 0;
+ read_file(VERSION_XML, (void**)&verbuf, &verlen);
+ if (!verbuf) {
+ error("ERROR: Could not load '" VERSION_XML "'.\n");
+ return -1;
+ }
+
+ client->version_data = NULL;
+ plist_from_xml(verbuf, verlen, &client->version_data);
+
+ if (!client->version_data) {
+ error("ERROR: Cannot parse plist data from '" VERSION_XML "'.\n");
+ return -1;
+ }
+
+ if (cached) {
+ info("NOTE: using cached version data\n");
+ }
+
+ return 0;
+}
+
int main(int argc, char* argv[]) {
int opt = 0;
int optindex = 0;
@@ -151,6 +207,9 @@ int main(int argc, char* argv[]) {
client->uuid = uuid;
client->ipsw = ipsw;
+ // update version data (from cache, or apple if too old)
+ load_version_data(client);
+
// check which mode the device is currently in so we know where to start
if (check_mode(client) < 0 || client->mode->index == MODE_UNKNOWN) {
error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n");
@@ -428,7 +487,7 @@ int main(int argc, char* argv[]) {
if (bin) {
char zfn[512];
sprintf(zfn, "shsh/%lld-%s-%s.shsh", (long long int)client->ecid, client->device->product, client->version);
- mkdir("shsh", 0755);
+ __mkdir("shsh", 0755);
struct stat fst;
if (stat(zfn, &fst) != 0) {
gzFile zf = gzopen(zfn, "wb");