Пример #1
0
LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_send_request(mobilebackup2_client_t client, const char *request, const char *target_identifier, const char *source_identifier, plist_t options)
{
	if (!client || !client->parent || !request || !target_identifier)
		return MOBILEBACKUP2_E_INVALID_ARG;

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "TargetIdentifier", plist_new_string(target_identifier));
	if (source_identifier) {
		plist_dict_set_item(dict, "SourceIdentifier", plist_new_string(source_identifier));
	}
	if (options) {
		plist_dict_set_item(dict, "Options", plist_copy(options));
	}
	if (!strcmp(request, "Unback") && options) {
		plist_t node = plist_dict_get_item(options, "Password");
		if (node) {
			plist_dict_set_item(dict, "Password", plist_copy(node));
		}
	}
	if (!strcmp(request, "EnableCloudBackup") && options) {
		plist_t node = plist_dict_get_item(options, "CloudBackupState");
		if (node) {
			plist_dict_set_item(dict, "CloudBackupState", plist_copy(node));
		}
	}
	mobilebackup2_error_t err = mobilebackup2_send_message(client, request, dict);
	plist_free(dict);

	return err;
}
/**
 * Performs the mobilebackup2 protocol version exchange.
 * 
 * @param client The MobileBackup client to use.
 * @param local_versions An array of supported versions to send to the remote.
 * @param count The number of items in local_versions.
 * @param remote_version Holds the protocol version of the remote on success.
 * 
 * @return MOBILEBACKUP2_E_SUCCESS on success, or a MOBILEBACKUP2_E_* error
 *     code otherwise.
 */
mobilebackup2_error_t mobilebackup2_version_exchange(mobilebackup2_client_t client, double local_versions[], char count, double *remote_version)
{
	int i;

	if (!client || !client->parent)
		return MOBILEBACKUP2_E_INVALID_ARG;

	plist_t dict = plist_new_dict();
	plist_t array = plist_new_array();
	for (i = 0; i < count; i++) {
		plist_array_append_item(array, plist_new_real(local_versions[i]));
	}
	plist_dict_insert_item(dict, "SupportedProtocolVersions", array);

	mobilebackup2_error_t err = mobilebackup2_send_message(client, "Hello", dict);
	plist_free(dict);

	if (err != MOBILEBACKUP2_E_SUCCESS)
		goto leave;

	dict = NULL;
	err = internal_mobilebackup2_receive_message(client, "Response", &dict);
	if (err != MOBILEBACKUP2_E_SUCCESS)
		goto leave;

	/* check if we received an error */
	plist_t node = plist_dict_get_item(dict, "ErrorCode");
	if (!node || (plist_get_node_type(node) != PLIST_UINT)) {
		err = MOBILEBACKUP2_E_PLIST_ERROR;
		goto leave;
	}

	uint64_t val = 0;
	plist_get_uint_val(node, &val);
	if (val != 0) {
		if (val == 1) {
			err = MOBILEBACKUP2_E_NO_COMMON_VERSION;
		} else {
			err = MOBILEBACKUP2_E_REPLY_NOT_OK;
		}
		goto leave;
	}

	/* retrieve the protocol version of the device */
	node = plist_dict_get_item(dict, "ProtocolVersion");
	if (!node || (plist_get_node_type(node) != PLIST_REAL)) {
		err = MOBILEBACKUP2_E_PLIST_ERROR;
		goto leave;
	}

	*remote_version = 0.0;
	plist_get_real_val(node, remote_version);
leave:
	if (dict)
		plist_free(dict);
	return err;
}
/**
 * Send a request to the connected mobilebackup2 service.
 *
 * @param client
 * @param request The request to send to the backup service.
 *     Currently, this is one of "Backup", "Restore", "Info", or "List".
 * @param target_identifier UDID of the target device.
 * @param source_identifier UDID of backup data?
 * @param options Additional options in a plist of type PLIST_DICT.
 *
 * @return MOBILEBACKUP2_E_SUCCESS if the request was successfully sent,
 *     or a MOBILEBACKUP2_E_* error value otherwise.
 */
mobilebackup2_error_t mobilebackup2_send_request(mobilebackup2_client_t client, const char *request, const char *target_identifier, const char *source_identifier, plist_t options)
{
	if (!client || !client->parent || !request || !target_identifier)
		return MOBILEBACKUP2_E_INVALID_ARG;

	plist_t dict = plist_new_dict();
	plist_dict_insert_item(dict, "TargetIdentifier", plist_new_string(target_identifier));
	if (source_identifier) {
		plist_dict_insert_item(dict, "SourceIdentifier", plist_new_string(source_identifier));
	}
	if (options) {
		plist_dict_insert_item(dict, "Options", plist_copy(options));
	}
	mobilebackup2_error_t err = mobilebackup2_send_message(client, request, dict);
	plist_free(dict);

	return err;
}