diff options
| author | 2012-07-29 05:56:00 +0200 | |
|---|---|---|
| committer | 2012-07-29 05:56:00 +0200 | |
| commit | 0f7af902dc07f3487f0d540923f0956fbcd30ebd (patch) | |
| tree | 6b1719d89947c4343723420f681de66cfc567998 | |
| parent | c6110de59aa435d26ae93078c88c45215e1e8056 (diff) | |
| download | idevicerestore-0f7af902dc07f3487f0d540923f0956fbcd30ebd.tar.gz idevicerestore-0f7af902dc07f3487f0d540923f0956fbcd30ebd.tar.bz2 | |
move main() code after option parsing to separate function
| -rw-r--r-- | src/common.h | 4 | ||||
| -rw-r--r-- | src/idevicerestore.c | 324 | ||||
| -rw-r--r-- | src/idevicerestore.h | 12 | 
3 files changed, 233 insertions, 107 deletions
| diff --git a/src/common.h b/src/common.h index 3f7d20e..d6be6bb 100644 --- a/src/common.h +++ b/src/common.h @@ -80,7 +80,7 @@ struct idevicerestore_client_t {  	int nonce_size;  	char* udid;  	char* srnm; -	const char* ipsw; +	char* ipsw;  	const char* filesystem;  	struct dfu_client_t* dfu;  	struct normal_client_t* normal; @@ -127,8 +127,6 @@ char *generate_guid();  int mkdir_with_parents(const char *dir, int mode); -extern struct idevicerestore_client_t* idevicerestore; -  #ifdef __cplusplus  }  #endif diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 059ae08..02c1bc1 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -153,108 +153,23 @@ static int load_version_data(struct idevicerestore_client_t* client)  	return 0;  } -int main(int argc, char* argv[]) { -	int opt = 0; -	int optindex = 0; -	char* ipsw = NULL; -	char* udid = NULL; +int idevicerestore_start(struct idevicerestore_client_t* client) +{  	int tss_enabled = 0;  	int result = 0; -	// create an instance of our context -	struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t)); -	if (client == NULL) { -		error("ERROR: Out of memory\n"); +	if (!client) {  		return -1;  	} -	memset(client, '\0', sizeof(struct idevicerestore_client_t)); -	while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:nC:", longopts, &optindex)) > 0) { -		switch (opt) { -		case 'h': -			usage(argc, argv); -			return 0; - -		case 'd': -			client->flags |= FLAG_DEBUG; -			idevicerestore_debug = 1; -			break; - -		case 'e': -			client->flags |= FLAG_ERASE; -			break; - -		case 'c': -			client->flags |= FLAG_CUSTOM; -			break; - -		case 's': -			client->tss_url = strdup("http://cydia.saurik.com/TSS/controller?action=2"); -			break; - -		case 'x': -			client->flags |= FLAG_EXCLUDE; -			break; - -		case 'l': -			client->flags |= FLAG_LATEST; -			break; - -		case 'i': -			if (optarg) { -				char* tail = NULL; -				client->ecid = strtoull(optarg, &tail, 16); -				if (tail && (tail[0] != '\0')) { -					client->ecid = 0; -				} -				if (client->ecid == 0) { -					error("ERROR: Could not parse ECID from '%s'\n", optarg); -					return -1; -				} -			} -			break; - -		case 'u': -			udid = optarg; -			break; - -		case 't': -			client->flags |= FLAG_SHSHONLY; -			break; - -		case 'p': -			client->flags |= FLAG_PWN; -			break; - -		case 'n': -			client->flags |= FLAG_NOACTION; -			break; - -		case 'C': -			client->cache_dir = strdup(optarg); -			break; - -		default: -			usage(argc, argv); -			return -1; -		} -	} - -	if (((argc-optind) == 1) || (client->flags & FLAG_PWN) || (client->flags & FLAG_LATEST)) { -		argc -= optind; -		argv += optind; - -		ipsw = argv[0]; -	} else { -		usage(argc, argv); +	if ((client->flags & FLAG_LATEST) && (client->flags & FLAG_CUSTOM)) { +		error("ERROR: FLAG_LATEST cannot be used with FLAG_CUSTOM.\n");  		return -1;  	} -	if (client->flags & FLAG_LATEST) { -		if (client->flags & FLAG_CUSTOM) { -			error("ERROR: You can't use --custom and --latest options at the same time.\n"); -			return -1; -		} +	if (!client->ipsw && !(client->flags & FLAG_PWN) && !(client->flags & FLAG_LATEST)) { +		error("ERROR: no ipsw file given\n"); +		return -1;  	}  	if (client->flags & FLAG_DEBUG) { @@ -262,9 +177,6 @@ int main(int argc, char* argv[]) {  		irecv_set_debug_level(1);  	} -	client->udid = udid; -	client->ipsw = ipsw; -  	// update version data (from cache, or apple if too old)  	load_version_data(client); @@ -374,8 +286,12 @@ int main(int argc, char* argv[]) {  	}  	if (client->flags & FLAG_LATEST) { +		char* ipsw = NULL;  		int res = ipsw_download_latest_fw(client->version_data, client->device->product, "cache", &ipsw);  		if (res != 0) { +			if (ipsw) { +				free(ipsw); +			}  			return res;  		} else {  			client->ipsw = ipsw; @@ -398,8 +314,8 @@ int main(int argc, char* argv[]) {  	}  	// verify if ipsw file exists -	if (access(ipsw, F_OK) < 0) { -		error("ERROR: Firmware file %s does not exist.\n", ipsw); +	if (access(client->ipsw, F_OK) < 0) { +		error("ERROR: Firmware file %s does not exist.\n", client->ipsw);  		return -1;  	} @@ -407,14 +323,14 @@ int main(int argc, char* argv[]) {  	plist_t buildmanifest = NULL;  	if (client->flags & FLAG_CUSTOM) {  		info("Extracting Restore.plist from IPSW\n"); -		if (ipsw_extract_restore_plist(ipsw, &buildmanifest) < 0) { -			error("ERROR: Unable to extract Restore.plist from %s. Firmware file might be corrupt.\n", ipsw); +		if (ipsw_extract_restore_plist(client->ipsw, &buildmanifest) < 0) { +			error("ERROR: Unable to extract Restore.plist from %s. Firmware file might be corrupt.\n", client->ipsw);  			return -1;  		}  	} else {  		info("Extracting BuildManifest from IPSW\n"); -		if (ipsw_extract_build_manifest(ipsw, &buildmanifest, &tss_enabled) < 0) { -			error("ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", ipsw); +		if (ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &tss_enabled) < 0) { +			error("ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw);  			return -1;  		}  	} @@ -473,7 +389,7 @@ int main(int argc, char* argv[]) {  			char *files[16];  			char *fmanifest = NULL;  			uint32_t msize = 0; -			if (ipsw_extract_to_memory(ipsw, tmpstr, &fmanifest, &msize) < 0) { +			if (ipsw_extract_to_memory(client->ipsw, tmpstr, &fmanifest, &msize) < 0) {  				error("ERROR: could not extract %s from IPSW\n", tmpstr);  				return -1;  			} @@ -707,7 +623,7 @@ int main(int argc, char* argv[]) {  		strcat(tmpf, basename(ipswtmp));  		free(ipswtmp);  	} else { -		strcpy(tmpf, ipsw); +		strcpy(tmpf, client->ipsw);  	}  	char* p = strrchr((const char*)tmpf, '.');  	if (p) { @@ -918,6 +834,206 @@ int main(int argc, char* argv[]) {  	return result;  } +struct idevicerestore_client_t* idevicerestore_client_new() +{ +	struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t)); +	if (client == NULL) { +		error("ERROR: Out of memory\n"); +		return NULL; +	} +	memset(client, '\0', sizeof(struct idevicerestore_client_t)); +	return client; +} + +void idevicerestore_client_free(struct idevicerestore_client_t* client) +{ +	if (!client) { +		return; +	} + +	if (client->tss_url) { +		free(client->tss_url); +	} +	if (client->version_data) { +		plist_free(client->version_data); +	} +	if (client->nonce) { +		free(client->nonce); +	} +	if (client->udid) { +		free(client->udid); +	} +	if (client->srnm) { +		free(client->srnm); +	} +	if (client->ipsw) { +		free(client->ipsw); +	} +	if (client->version) { +		free(client->version); +	} +	if (client->build) { +		free(client->build); +	} +	if (client->restore_boot_args) { +		free(client->restore_boot_args); +	} +	if (client->cache_dir) { +		free(client->cache_dir); +	} +	free(client); +} + +void idevicerestore_set_ecid(struct idevicerestore_client_t* client, unsigned long long ecid) +{ +	if (!client) +		return; +	client->ecid = ecid; +} + +void idevicerestore_set_udid(struct idevicerestore_client_t* client, const char* udid) +{ +	if (!client) +		return; +	if (client->udid) { +		free(client->udid); +		client->udid = NULL; +	} +	if (udid) { +		client->udid = strdup(udid); +	} +} + +void idevicerestore_set_flags(struct idevicerestore_client_t* client, int flags) +{ +	if (!client) +		return; +	client->flags = flags; +} + +void idevicerestore_set_ipsw(struct idevicerestore_client_t* client, const char* path) +{ +	if (!client) +		return; +	if (client->ipsw) { +		free(client->ipsw); +		client->ipsw = NULL; +	} +	if (path) { +		client->ipsw = strdup(path); +	} +} + +#ifndef IDEVICERESTORE_NOMAIN +int main(int argc, char* argv[]) { +	int opt = 0; +	int optindex = 0; +	char* ipsw = NULL; +	char* udid = NULL; +	int result = 0; + +	struct idevicerestore_client_t* client = idevicerestore_client_new(); +	if (client == NULL) { +		error("ERROR: could not create idevicerestore client\n"); +		return -1; +	} + +	while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:nC:", longopts, &optindex)) > 0) { +		switch (opt) { +		case 'h': +			usage(argc, argv); +			return 0; + +		case 'd': +			client->flags |= FLAG_DEBUG; +			idevicerestore_debug = 1; +			break; + +		case 'e': +			client->flags |= FLAG_ERASE; +			break; + +		case 'c': +			client->flags |= FLAG_CUSTOM; +			break; + +		case 's': +			client->tss_url = strdup("http://cydia.saurik.com/TSS/controller?action=2"); +			break; + +		case 'x': +			client->flags |= FLAG_EXCLUDE; +			break; + +		case 'l': +			client->flags |= FLAG_LATEST; +			break; + +		case 'i': +			if (optarg) { +				char* tail = NULL; +				client->ecid = strtoull(optarg, &tail, 16); +				if (tail && (tail[0] != '\0')) { +					client->ecid = 0; +				} +				if (client->ecid == 0) { +					error("ERROR: Could not parse ECID from '%s'\n", optarg); +					return -1; +				} +			} +			break; + +		case 'u': +			client->udid = strdup(optarg); +			break; + +		case 't': +			client->flags |= FLAG_SHSHONLY; +			break; + +		case 'p': +			client->flags |= FLAG_PWN; +			break; + +		case 'n': +			client->flags |= FLAG_NOACTION; +			break; + +		case 'C': +			client->cache_dir = strdup(optarg); +			break; + +		default: +			usage(argc, argv); +			return -1; +		} +	} + +	if (((argc-optind) == 1) || (client->flags & FLAG_PWN) || (client->flags & FLAG_LATEST)) { +		argc -= optind; +		argv += optind; + +		ipsw = argv[0]; +	} else { +		usage(argc, argv); +		return -1; +	} + +	if ((client->flags & FLAG_LATEST) && (client->flags & FLAG_CUSTOM)) { +		error("ERROR: You can't use --custom and --latest options at the same time.\n"); +		return -1; +	} + +	client->ipsw = strdup(ipsw); + +	result = idevicerestore_start(client); + +	idevicerestore_client_free(client); + +	return result; +} +#endif +  int check_mode(struct idevicerestore_client_t* client) {  	int mode = MODE_UNKNOWN;  	int dfumode = MODE_UNKNOWN; diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 4d25428..446edf4 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -31,6 +31,18 @@ extern "C" {  #include "common.h" +struct idevicerestore_client_t; + +struct idevicerestore_client_t* idevicerestore_client_new(); +void idevicerestore_client_free(struct idevicerestore_client_t* client); + +void idevicerestore_set_ecid(struct idevicerestore_client_t* client, unsigned long long ecid); +void idevicerestore_set_udid(struct idevicerestore_client_t* client, const char* udid); +void idevicerestore_set_flags(struct idevicerestore_client_t* client, int flags); +void idevicerestore_set_ipsw(struct idevicerestore_client_t* client, const char* path); + +int idevicerestore_start(struct idevicerestore_client_t* client); +  void usage(int argc, char* argv[]);  int check_mode(struct idevicerestore_client_t* client);  int check_device(struct idevicerestore_client_t* client); | 
