diff options
Diffstat (limited to 'src/recovery.c')
| -rw-r--r-- | src/recovery.c | 125 | 
1 files changed, 64 insertions, 61 deletions
| diff --git a/src/recovery.c b/src/recovery.c index afda4a9..b843f1e 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -39,14 +39,15 @@  static int recovery_progress_callback(irecv_client_t client, const irecv_event_t* event)  {  	if (event->type == IRECV_PROGRESS) { -		//print_progress_bar(event->progress); +		set_progress('RECV', (double)(event->progress/100.0));  	}  	return 0;  }  void recovery_client_free(struct idevicerestore_client_t* client)  { -	if(client) { +	if (client) { +		finalize_progress('RECV');  		if (client->recovery) {  			if(client->recovery->client) {  				irecv_close(client->recovery->client); @@ -68,7 +69,7 @@ int recovery_client_new(struct idevicerestore_client_t* client)  	if(client->recovery == NULL) {  		client->recovery = (struct recovery_client_t*)malloc(sizeof(struct recovery_client_t));  		if (client->recovery == NULL) { -			error("ERROR: Out of memory\n"); +			logger(LL_ERROR, "Out of memory\n");  			return -1;  		}  		memset(client->recovery, 0, sizeof(struct recovery_client_t)); @@ -81,19 +82,19 @@ int recovery_client_new(struct idevicerestore_client_t* client)  		}  		if (i >= attempts) { -			error("ERROR: Unable to connect to device in recovery mode\n"); +			logger(LL_ERROR, "Unable to connect to device in recovery mode\n");  			return -1;  		}  		sleep(4); -		debug("Retrying connection...\n"); +		logger(LL_DEBUG, "Retrying connection...\n");  	}  	if (client->srnm == NULL) {  		const struct irecv_device_info *device_info = irecv_get_device_info(recovery);  		if (device_info && device_info->srnm) {  			client->srnm = strdup(device_info->srnm); -			info("INFO: device serial number is %s\n", client->srnm); +			logger(LL_INFO, "INFO: device serial number is %s\n", client->srnm);  		}  	} @@ -108,13 +109,13 @@ int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable)  	recovery_error = irecv_send_command(client->recovery->client, (enable) ? "setenv auto-boot true" : "setenv auto-boot false");  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to set auto-boot environmental variable\n"); +		logger(LL_ERROR, "Unable to set auto-boot environmental variable\n");  		return -1;  	}  	recovery_error = irecv_send_command(client->recovery->client, "saveenv");  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to save environmental variable\n"); +		logger(LL_ERROR, "Unable to save environmental variable\n");  		return -1;  	} @@ -123,11 +124,11 @@ int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable)  int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity)  { -	if (client->build_major >= 8) { -		client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress"); -	} else if (client->macos_variant) { -		client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress -restore"); -	} +    if (client->macos_variant) { +        client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress -restore"); +    } else if (client->build_major >= 8) { +        client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress"); +    }  	/* upload data to make device boot restore mode */ @@ -141,21 +142,21 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  		if (!client->image4supported) {  			/* send ApTicket */  			if (recovery_send_ticket(client) < 0) { -				error("ERROR: Unable to send APTicket\n"); +				logger(LL_ERROR, "Unable to send APTicket\n");  				return -1;  			}  		}  	} -	info("Recovery Mode Environment:\n"); +	logger(LL_INFO, "Recovery Mode Environment:\n");  	char* value = NULL;  	irecv_getenv(client->recovery->client, "build-version", &value); -	info("iBoot build-version=%s\n", (value) ? value : "(unknown)"); +	logger(LL_INFO, "iBoot build-version=%s\n", (value) ? value : "(unknown)");  	free(value);  	value = NULL;  	irecv_getenv(client->recovery->client, "build-style", &value); -	info("iBoot build-style=%s\n", (value) ? value : "(unknown)"); +	logger(LL_INFO, "iBoot build-style=%s\n", (value) ? value : "(unknown)");  	free(value);  	value = NULL; @@ -165,11 +166,11 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  		boot_stage = strtoul(value, NULL, 0);  	}  	if (boot_stage > 0) { -		info("iBoot boot-stage=%s\n", value); +		logger(LL_INFO, "iBoot boot-stage=%s\n", value);  		free(value);  		value = NULL;  		if (boot_stage != 2) { -			error("ERROR: iBoot should be at boot stage 2, continuing anyway...\n"); +			logger(LL_ERROR, "iBoot should be at boot stage 2, continuing anyway...\n");  		}  	} @@ -179,12 +180,12 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  		radio_error = strtoul(value, NULL, 0);  	}  	if (radio_error > 0) { -		info("radio-error=%s\n", value); +		logger(LL_INFO, "radio-error=%s\n", value);  		free(value);  		value = NULL;  		irecv_getenv(client->recovery->client, "radio-error-string", &value);  		if (value) { -			info("radio-error-string=%s\n", value); +			logger(LL_INFO, "radio-error-string=%s\n", value);  			free(value);  			value = NULL;  		} @@ -196,32 +197,32 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  	/* send logo and show it */  	if (recovery_send_applelogo(client, build_identity) < 0) { -		error("ERROR: Unable to send AppleLogo\n"); +		logger(LL_ERROR, "Unable to send AppleLogo\n");  		return -1;  	}  	/* send components loaded by iBoot */  	if (recovery_send_loaded_by_iboot(client, build_identity) < 0) { -		error("ERROR: Unable to send components supposed to be loaded by iBoot\n"); +		logger(LL_ERROR, "Unable to send components supposed to be loaded by iBoot\n");  		return -1;  	}  	/* send ramdisk and run it */  	if (recovery_send_ramdisk(client, build_identity) < 0) { -		error("ERROR: Unable to send Ramdisk\n"); +		logger(LL_ERROR, "Unable to send Ramdisk\n");  		return -1;  	}  	/* send devicetree and load it */  	if (recovery_send_component_and_command(client, build_identity, "RestoreDeviceTree", "devicetree") < 0) { -		error("ERROR: Unable to send DeviceTree\n"); +		logger(LL_ERROR, "Unable to send DeviceTree\n");  		return -1;  	}  	if (build_identity_has_component(build_identity, "RestoreSEP")) {  		/* send rsepfirmware and load it */  		if (recovery_send_component_and_command(client, build_identity, "RestoreSEP", "rsepfirmware") < 0) { -			error("ERROR: Unable to send RestoreSEP\n"); +			logger(LL_ERROR, "Unable to send RestoreSEP\n");  			return -1;  		}  	} @@ -229,15 +230,15 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  	mutex_lock(&client->device_event_mutex);  	if (recovery_send_kernelcache(client, build_identity) < 0) {  		mutex_unlock(&client->device_event_mutex); -		error("ERROR: Unable to send KernelCache\n"); +		logger(LL_ERROR, "Unable to send KernelCache\n");  		return -1;  	} -	debug("DEBUG: Waiting for device to disconnect...\n"); +	logger(LL_DEBUG, "Waiting for device to disconnect...\n");  	cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 30000);  	if (client->mode == MODE_RECOVERY || (client->flags & FLAG_QUIT)) {  		mutex_unlock(&client->device_event_mutex); -		error("ERROR: Failed to place device in restore mode\n"); +		logger(LL_ERROR, "Failed to place device in restore mode\n");  		return -1;  	}  	mutex_unlock(&client->device_event_mutex); @@ -248,28 +249,28 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  int recovery_send_ticket(struct idevicerestore_client_t* client)  {  	if (!client->tss) { -		error("ERROR: ApTicket requested but no TSS present\n"); +		logger(LL_ERROR, "ApTicket requested but no TSS present\n");  		return -1;  	}  	unsigned char* data = NULL;  	uint32_t size = 0;  	if (tss_response_get_ap_ticket(client->tss, &data, &size) < 0) { -		error("ERROR: Unable to get ApTicket from TSS request\n"); +		logger(LL_ERROR, "Unable to get ApTicket from TSS request\n");  		return -1;  	} -	info("Sending APTicket (%d bytes)\n", size); +	logger(LL_INFO, "Sending APTicket (%d bytes)\n", size);  	irecv_error_t err = irecv_send_buffer(client->recovery->client, data, size, 0);  	free(data);  	if (err != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send APTicket: %s\n", irecv_strerror(err)); +		logger(LL_ERROR, "Unable to send APTicket: %s\n", irecv_strerror(err));  		return -1;  	}  	err = irecv_send_command(client->recovery->client, "ticket");  	if (err != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send ticket command\n"); +		logger(LL_ERROR, "Unable to send ticket command\n");  		return -1;  	} @@ -278,47 +279,49 @@ int recovery_send_ticket(struct idevicerestore_client_t* client)  int recovery_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component)  { -	unsigned int size = 0; -	unsigned char* data = NULL; +	size_t size = 0; +	void* data = NULL;  	char* path = NULL;  	irecv_error_t err = 0;  	if (client->tss) {  		if (tss_response_get_path_by_entry(client->tss, component, &path) < 0) { -			debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component); +			logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build_identity\n", component);  		}  	}  	if (!path) {  		if (build_identity_get_component_path(build_identity, component, &path) < 0) { -			error("ERROR: Unable to get path for component '%s'\n", component); +			logger(LL_ERROR, "Unable to get path for component '%s'\n", component);  			free(path);  			return -1;  		}  	} -	unsigned char* component_data = NULL; -	unsigned int component_size = 0; +	void* component_data = NULL; +	size_t component_size = 0;  	int ret = extract_component(client->ipsw, path, &component_data, &component_size);  	free(path);  	if (ret < 0) { -		error("ERROR: Unable to extract component: %s\n", component); +		logger(LL_ERROR, "Unable to extract component: %s\n", component);  		return -1;  	} -	ret = personalize_component(component, component_data, component_size, client->tss, &data, &size); +	ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);  	free(component_data);  	if (ret < 0) { -		error("ERROR: Unable to get personalized component: %s\n", component); +		logger(LL_ERROR, "Unable to get personalized component: %s\n", component);  		return -1;  	} -	info("Sending %s (%d bytes)...\n", component, size); +	logger(LL_INFO, "Sending %s (%zu bytes)...\n", component, size);  	// FIXME: Did I do this right???? +	register_progress('RECV', "Uploading");  	err = irecv_send_buffer(client->recovery->client, data, size, 0);  	free(data); +	finalize_progress('RECV');  	if (err != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(err)); +		logger(LL_ERROR, "Unable to send %s component: %s\n", component, irecv_strerror(err));  		return -1;  	} @@ -330,13 +333,13 @@ int recovery_send_component_and_command(struct idevicerestore_client_t* client,  	irecv_error_t recovery_error = IRECV_E_SUCCESS;  	if (recovery_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	}  	recovery_error = irecv_send_command(client->recovery->client, command);  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); +		logger(LL_ERROR, "Unable to execute %s\n", component);  		return -1;  	} @@ -355,13 +358,13 @@ int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_ide  	}  	if (recovery_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	}  	recovery_error = irecv_send_command_breq(client->recovery->client, "go", 1);  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); +		logger(LL_ERROR, "Unable to execute %s\n", component);  		return -1;  	}  	irecv_usb_control_transfer(client->recovery->client, 0x21, 1, 0, 0, 0, 0, 5000); @@ -378,7 +381,7 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t buil  		return 0;  	} -	info("Sending %s...\n", component); +	logger(LL_INFO, "Sending %s...\n", component);  	if (client->recovery == NULL) {  		if (recovery_client_new(client) < 0) {  			return -1; @@ -386,19 +389,19 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t buil  	}  	if (recovery_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	}  	recovery_error = irecv_send_command(client->recovery->client, "setpicture 4");  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to set %s\n", component); +		logger(LL_ERROR, "Unable to set %s\n", component);  		return -1;  	}  	recovery_error = irecv_send_command(client->recovery->client, "bgcolor 0 0 0");  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to display %s\n", component); +		logger(LL_ERROR, "Unable to display %s\n", component);  		return -1;  	} @@ -415,7 +418,7 @@ int recovery_send_loaded_by_iboot(struct idevicerestore_client_t* client, plist_  	plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest");  	if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { -		error("ERROR: Unable to find manifest node\n"); +		logger(LL_ERROR, "Unable to find manifest node\n");  		return -1;  	} @@ -439,9 +442,9 @@ int recovery_send_loaded_by_iboot(struct idevicerestore_client_t* client, plist_  			uint8_t b = 0;  			plist_get_bool_val(iboot_node, &b);  			if (b) { -				debug("DEBUG: %s is loaded by iBoot.\n", key); +				logger(LL_DEBUG, "%s is loaded by iBoot.\n", key);  				if (recovery_send_component_and_command(client, build_identity, key, "firmware") < 0) { -					error("ERROR: Unable to send component '%s' to device.\n", key); +					logger(LL_ERROR, "Unable to send component '%s' to device.\n", key);  					err++;  				}  			} @@ -466,12 +469,12 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_  	char* value = NULL;  	irecv_getenv(client->recovery->client, "ramdisk-size", &value); -	info("ramdisk-size=%s\n", (value ? value : "(unknown)")); +	logger(LL_INFO, "ramdisk-size=%s\n", (value ? value : "(unknown)"));  	free(value);  	value = NULL;  	if (recovery_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	} @@ -479,7 +482,7 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_  	recovery_error = irecv_send_command(client->recovery->client, "ramdisk");  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); +		logger(LL_ERROR, "Unable to execute %s\n", component);  		return -1;  	} @@ -500,7 +503,7 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t bu  	}  	if (recovery_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	} @@ -515,7 +518,7 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t bu  	recovery_error = irecv_send_command_breq(client->recovery->client, "bootx", 1);  	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); +		logger(LL_ERROR, "Unable to execute %s\n", component);  		return -1;  	} | 
