diff options
| author | 2010-06-01 04:34:40 -0400 | |
|---|---|---|
| committer | 2010-06-01 04:34:40 -0400 | |
| commit | 4de6d38c54d9f641006539a06083e423a5d0c9c9 (patch) | |
| tree | 990a89f501eaee4427ea8104a0bcf0dab438b05b /src/recovery.c | |
| parent | 75a3f5f5c6ec5b89659f4e4aacd5d629a3912f22 (diff) | |
| download | idevicerestore-4de6d38c54d9f641006539a06083e423a5d0c9c9.tar.gz idevicerestore-4de6d38c54d9f641006539a06083e423a5d0c9c9.tar.bz2 | |
Began refactoring of code to simplify and seperate device state logic
Diffstat (limited to 'src/recovery.c')
| -rw-r--r-- | src/recovery.c | 269 | 
1 files changed, 269 insertions, 0 deletions
| diff --git a/src/recovery.c b/src/recovery.c new file mode 100644 index 0000000..4e2e7ad --- /dev/null +++ b/src/recovery.c @@ -0,0 +1,269 @@ +/* + * recovery.c + * Functions for handling idevices in recovery mode + * + * Copyright (c) 2010 Joshua Hill. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <libirecovery.h> + +#include "tss.h" +#include "img3.h" +#include "recovery.h" +#include "idevicerestore.h" + +int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) { +	int size = 0; +	char* data = NULL; +	char* path = NULL; +	char* blob = NULL; +	img3_file* img3 = NULL; +	irecv_error_t error = 0; + +	if (get_signed_component_by_name(ipsw, tss, component, &data, &size) < 0) { +		error("ERROR: Unable to get signed component: %s\n", component); +		return -1; +	} + +	info("Sending %s...\n", component); +	error = irecv_send_buffer(client, data, size); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to send IMG3: %s\n", path); +		img3_free(img3); +		free(data); +		free(path); +		return -1; +	} + +	if (data) { +		free(data); +		data = NULL; +	} + +	return 0; +} + +irecv_error_t recovery_open_with_timeout(irecv_client_t* client) { +	int i = 0; +	irecv_error_t error = 0; +	for (i = 10; i > 0; i--) { +		error = irecv_open(client); +		if (error == IRECV_E_SUCCESS) { +			return error; +		} + +		sleep(2); +		info("Retrying connection...\n"); +	} + +	error("ERROR: Unable to connect to recovery device.\n"); +	return error; +} + +int recovery_send_ibec(char* ipsw, plist_t tss) { +	irecv_error_t error = 0; +	irecv_client_t client = NULL; +	char* component = "iBEC"; + +	error = recovery_open_with_timeout(&client); +	if (error != IRECV_E_SUCCESS) { +		return -1; +	} + +	error = irecv_send_command(client, "setenv auto-boot true"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to set auto-boot environmental variable\n"); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "saveenv"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to save environmental variable\n"); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { +		error("ERROR: Unable to send %s to device.\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "go"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to execute %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (client) { +		irecv_close(client); +		client = NULL; +	} +	return 0; +} + +int recovery_send_applelogo(char* ipsw, plist_t tss) { +	irecv_error_t error = 0; +	irecv_client_t client = NULL; +	char* component = "AppleLogo"; + +	info("Sending %s...\n", component); + +	error = recovery_open_with_timeout(&client); +	if (error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { +		error("ERROR: Unable to send %s to device.\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "setpicture 1"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to set %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "bgcolor 0 0 0"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to display %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (client) { +		irecv_close(client); +		client = NULL; +	} +	return 0; +} + +int recovery_send_devicetree(char* ipsw, plist_t tss) { +	irecv_error_t error = 0; +	irecv_client_t client = NULL; +	char *component = "RestoreDeviceTree"; + +	error = recovery_open_with_timeout(&client); +	if (error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { +		error("ERROR: Unable to send %s to device.\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "devicetree"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to execute %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (client) { +		irecv_close(client); +		client = NULL; +	} +	return 0; +} + +int recovery_send_ramdisk(char* ipsw, plist_t tss) { +	irecv_error_t error = 0; +	irecv_client_t client = NULL; +	char *component = "RestoreRamDisk"; + +	error = recovery_open_with_timeout(&client); +	if (error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { +		error("ERROR: Unable to send %s to device.\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "ramdisk"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to execute %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (client) { +		irecv_close(client); +		client = NULL; +	} +	return 0; +} + +int recovery_send_kernelcache(char* ipsw, plist_t tss) { +	irecv_error_t error = 0; +	irecv_client_t client = NULL; +	char *component = "RestoreKernelCache"; + +	error = recovery_open_with_timeout(&client); +	if (error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { +		error("ERROR: Unable to send %s to device.\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	error = irecv_send_command(client, "bootx"); +	if (error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to execute %s\n", component); +		irecv_close(client); +		client = NULL; +		return -1; +	} + +	if (client) { +		irecv_close(client); +		client = NULL; +	} +	return 0; +} + + +int recovery_get_ecid(uint64_t* ecid) { +	return 0; +} | 
