diff options
| -rw-r--r-- | src/idevicerestore.c | 46 | 
1 files changed, 45 insertions, 1 deletions
| diff --git a/src/idevicerestore.c b/src/idevicerestore.c index f1d441a..ca3c94c 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -49,6 +49,7 @@ static struct option longopts[] = {  	{ "custom",  no_argument,       NULL, 'c' },  	{ "cydia",   no_argument,       NULL, 's' },  	{ "exclude", no_argument,       NULL, 'x' }, +	{ "shsh",    no_argument,       NULL, 't' },  	{ NULL, 0, NULL, 0 }  }; @@ -63,6 +64,7 @@ void usage(int argc, char* argv[]) {  	printf("  -c, --custom\t\trestore with a custom firmware\n");  	printf("  -s, --cydia\t\tuse Cydia's signature service instead of Apple's\n");  	printf("  -x, --exclude\t\texclude nor/baseband upgrade\n"); +	printf("  -t, --shsh\t\tfetch TSS record and save to .shsh file, then exit\n");  	printf("\n");  } @@ -72,6 +74,8 @@ int main(int argc, char* argv[]) {  	char* ipsw = NULL;  	char* uuid = NULL;  	int tss_enabled = 0; +	int shsh_only = 0; +	char* shsh_dir = NULL;  	use_apple_server=1;  	// create an instance of our context @@ -82,7 +86,7 @@ int main(int argc, char* argv[]) {  	}  	memset(client, '\0', sizeof(struct idevicerestore_client_t)); -	while ((opt = getopt_long(argc, argv, "dhcesxu:", longopts, &optindex)) > 0) { +	while ((opt = getopt_long(argc, argv, "dhcesxtu:", longopts, &optindex)) > 0) {  		switch (opt) {  		case 'h':  			usage(argc, argv); @@ -112,6 +116,10 @@ int main(int argc, char* argv[]) {  			uuid = optarg;  			break; +		case 't': +			shsh_only = 1; +			break; +  		default:  			usage(argc, argv);  			return -1; @@ -372,6 +380,42 @@ int main(int argc, char* argv[]) {  		}  	} +	if (shsh_only) { +		if (!tss_enabled) { +			info("This device does not require a TSS record"); +			return 0; +		} +		if (!client->tss) { +			error("ERROR: could not fetch TSS record"); +			plist_free(buildmanifest); +			return -1; +		} else { +			char *bin = NULL; +			uint32_t blen = 0; +			plist_to_bin(client->tss, &bin, &blen); +			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); +				struct stat fst; +				if (stat(zfn, &fst) != 0) { +					gzFile zf = gzopen(zfn, "wb"); +					gzwrite(zf, bin, blen); +					gzclose(zf); +					info("SHSH saved to '%s'\n", zfn); +				} else { +					info("SHSH '%s' already present.\n", zfn); +				} +				free(bin); +			} else { +				error("ERROR: could not get TSS record data\n"); +			} +			plist_free(client->tss); +			plist_free(buildmanifest); +			return 0; +		} +	} +  	/* verify if we have tss records if required */  	if ((tss_enabled) && (client->tss == NULL)) {  		error("ERROR: Unable to proceed without a TSS record.\n"); | 
