Exemplo n.º 1
0
afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to)
{
	if (!client || !from || !to || !client->afc_packet || !client->parent)
		return AFC_E_INVALID_ARG;

	char *buffer = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	afc_lock(client);

	/* Send command */
	memcpy(buffer, from, strlen(from) + 1);
	memcpy(buffer + strlen(from) + 1, to, strlen(to) + 1);
	ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, buffer, strlen(to)+1 + strlen(from)+1, NULL, 0, &bytes);
	free(buffer);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 2
0
afc_error_t afc_remove_path(afc_client_t client, const char *path)
{
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !client->afc_packet || !client->parent)
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send command */
	ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, path, strlen(path)+1, NULL, 0, &bytes);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	/* special case; unknown error actually means directory not empty */
	if (ret == AFC_E_UNKNOWN_ERROR)
		ret = AFC_E_DIR_NOT_EMPTY;

	afc_unlock(client);

	return ret;
}
Exemplo n.º 3
0
afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime)
{
	if (!client || !path || !client->afc_packet || !client->parent)
		return AFC_E_INVALID_ARG;

	char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
	uint32_t bytes = 0;
	uint64_t mtime_loc = htole64(mtime);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	afc_lock(client);

	/* Send command */
	memcpy(buffer, &mtime_loc, 8);
	memcpy(buffer + 8, path, strlen(path) + 1);
	ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_TIME, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes);
	free(buffer);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 4
0
/** Creates a directory on the phone.
 * 
 * @param client The client to use to make a directory.
 * @param dir The directory's path. (must be a fully-qualified path, I assume
 *        all other mkdir restrictions apply as well)
 *
 * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT
 *         if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise.
 */
afc_error_t afc_make_directory(afc_client_t client, const char *dir)
{
	int bytes = 0;
	char *response = NULL;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	client->afc_packet->operation = AFC_OP_MAKE_DIR;
	client->afc_packet->this_length = client->afc_packet->entire_length = 0;
	bytes = afc_dispatch_packet(client, dir, strlen(dir)+1);
	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 5
0
/** Gets information about a specific file.
 * 
 * @param client The client to use to get the information of the file.
 * @param path The fully-qualified path to the file. 
 * @param infolist Pointer to a buffer that will be filled with a NULL-terminated
 *                 list of strings with the file information.
 *                 Set to NULL before calling this function.
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value
 *         when something went wrong.
 */
afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***infolist)
{
	char *received = NULL;
	int bytes;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !infolist)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	client->afc_packet->operation = AFC_OP_GET_FILE_INFO;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	afc_dispatch_packet(client, path, strlen(path)+1);

	// Receive data
	ret = afc_receive_data(client, &received, &bytes);
	if (received) {
		*infolist = make_strings_list(received, bytes);
		free(received);
	}

	afc_unlock(client);

	return ret;
}
Exemplo n.º 6
0
afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
{
	uint32_t bytes = 0;
	struct {
		uint64_t handle;
		uint64_t newsize;
	} truncinfo;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send command */
	truncinfo.handle = handle;
	truncinfo.newsize = htole64(newsize);
	ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, (const char*)&truncinfo, sizeof(truncinfo), NULL, 0, &bytes);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 7
0
afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname)
{
	if (!client || !target || !linkname || !client->afc_packet || !client->parent)
		return AFC_E_INVALID_ARG;

	char *buffer = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8));
	uint32_t bytes = 0;
	uint64_t type = htole64(linktype);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	afc_lock(client);

	debug_info("link type: %lld", type);
	debug_info("target: %s, length:%d", target, strlen(target));
	debug_info("linkname: %s, length:%d", linkname, strlen(linkname));

	/* Send command */
	memcpy(buffer, &type, 8);
	memcpy(buffer + 8, target, strlen(target) + 1);
	memcpy(buffer + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1);
	ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, buffer, 8 + strlen(linkname) + 1 + strlen(target) + 1, NULL, 0, &bytes);
	free(buffer);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 8
0
afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence)
{
	uint32_t bytes = 0;
	struct {
		uint64_t handle;
		uint64_t whence;
		int64_t offset;
	} seekinfo;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send the command */
	seekinfo.handle = handle;
	seekinfo.whence = htole64(whence);
	seekinfo.offset = (int64_t)htole64(offset);
	ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, (const char*)&seekinfo, sizeof(seekinfo), NULL, 0, &bytes);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 9
0
afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position)
{
	char *buffer = NULL;
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send the command */
	ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, (const char*)&handle, 8, NULL, 0, &bytes);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}

	/* Receive the data */
	ret = afc_receive_data(client, &buffer, &bytes);
	if (bytes > 0 && buffer) {
		/* Get the position */
		memcpy(position, buffer, sizeof(uint64_t));
		*position = le64toh(*position);
	}
	free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 10
0
afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
{
	uint32_t bytes = 0;
	struct {
		uint64_t handle;
		uint64_t op;
	} lockinfo;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("file handle %i", handle);

	/* Send command */
	lockinfo.handle = handle;
	lockinfo.op = htole64(operation);
	ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, (const char*)&lockinfo, sizeof(lockinfo), NULL, 0, &bytes);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		debug_info("could not send lock command");
		return AFC_E_UNKNOWN_ERROR;
	}
	/* Receive the response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 11
0
afc_error_t afc_file_close(afc_client_t client, uint64_t handle)
{
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("File handle %i", handle);

	/* Send command */
	ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, (const char*)&handle, 8, NULL, 0, &bytes);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_UNKNOWN_ERROR;
	}

	/* Receive the response */
	ret = afc_receive_data(client, NULL, &bytes);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 12
0
idevice_error_t
afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written)
{
	uint32_t current_count = 0;
	uint32_t bytes_loc = 0;
	afc_error_t ret = AFC_E_SUCCESS;

	if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("Write length: %i", length);

	ret = afc_dispatch_packet(client, AFC_OP_WRITE, (const char*)&handle, 8, data, length, &bytes_loc);

	current_count += bytes_loc - (sizeof(AFCPacket) + 8);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		*bytes_written = current_count;
		return AFC_E_SUCCESS;
	}

	ret = afc_receive_data(client, NULL, &bytes_loc);
	afc_unlock(client);
	if (ret != AFC_E_SUCCESS) {
		debug_info("uh oh?");
	}
	*bytes_written = current_count;
	return ret;
}
Exemplo n.º 13
0
/** Renames a file or directory on the phone.
 * 
 * @param client The client to have rename.
 * @param from The name to rename from. (must be a fully-qualified path)
 * @param to The new name. (must also be a fully-qualified path)
 * 
 * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT
 *         if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise.
 */
afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to)
{
	char *response = NULL;
	char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));
	int bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !from || !to || !client->afc_packet || !client->connection)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	memcpy(send, from, strlen(from) + 1);
	memcpy(send + strlen(from) + 1, to, strlen(to) + 1);
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	client->afc_packet->operation = AFC_OP_RENAME_PATH;
	bytes = afc_dispatch_packet(client, send, strlen(to)+1 + strlen(from)+1);
	free(send);
	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 14
0
/**
 * Closes a file on the device.
 * 
 * @param client The client to close the file with.
 * @param handle File handle of a previously opened file.
 */
afc_error_t afc_file_close(afc_client_t client, uint64_t handle)
{
	char *buffer = (char *)malloc(sizeof(char) * 8);
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("File handle %i", handle);

	/* Send command */
	memcpy(buffer, &handle, sizeof(uint64_t));
	client->afc_packet->operation = AFC_OP_FILE_CLOSE;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	ret = afc_dispatch_packet(client, buffer, 8, &bytes);
	free(buffer);
	buffer = NULL;

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_UNKNOWN_ERROR;
	}

	/* Receive the response */
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer)
		free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 15
0
/** Deletes a file or directory.
 * 
 * @param client The client to use.
 * @param path The path to delete. (must be a fully-qualified path)
 * 
 * @return AFC_E_SUCCESS if everythong went well, AFC_E_INVALID_ARGUMENT
 *         if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise.
 */
afc_error_t afc_remove_path(afc_client_t client, const char *path)
{
	char *response = NULL;
	int bytes;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !client->afc_packet || !client->connection)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	client->afc_packet->this_length = client->afc_packet->entire_length = 0;
	client->afc_packet->operation = AFC_OP_REMOVE_PATH;
	bytes = afc_dispatch_packet(client, path, strlen(path)+1);
	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	/* special case; unknown error actually means directory not empty */
	if (ret == AFC_E_UNKNOWN_ERROR)
		ret = AFC_E_DIR_NOT_EMPTY;

	afc_unlock(client);

	return ret;
}
Exemplo n.º 16
0
/** Sets the size of a file on the phone.
 * 
 * @param client The client to use to set the file size.
 * @param handle File handle of a previously opened file.
 * @param newsize The size to set the file to. 
 * 
 * @return 0 on success, -1 on failure. 
 * 
 * @note This function is more akin to ftruncate than truncate, and truncate
 *       calls would have to open the file before calling this, sadly.
 */
afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
{
	char *buffer = (char *) malloc(sizeof(char) * 16);
	int bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	memcpy(buffer, &handle, sizeof(uint64_t));	// handle
	memcpy(buffer + 8, &newsize, sizeof(uint64_t));	// newsize
	client->afc_packet->operation = AFC_OP_FILE_SET_SIZE;
	client->afc_packet->this_length = client->afc_packet->entire_length = 0;
	bytes = afc_dispatch_packet(client, buffer, 16);
	free(buffer);
	buffer = NULL;

	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer)
		free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 17
0
afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***list)
{
	uint32_t bytes = 0;
	char *data = NULL, **list_loc = NULL;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !dir || !list || (list && *list))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send the command */
	ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, dir, strlen(dir)+1, NULL, 0, &bytes);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive the data */
	ret = afc_receive_data(client, &data, &bytes);
	if (ret != AFC_E_SUCCESS) {
		if (data)
			free(data);
		afc_unlock(client);
		return ret;
	}
	/* Parse the data */
	list_loc = make_strings_list(data, bytes);
	if (data)
		free(data);

	afc_unlock(client);
	*list = list_loc;

	return ret;
}
Exemplo n.º 18
0
/** Sets the size of a file on the phone without prior opening it.
 * 
 * @param client The client to use to set the file size.
 * @param path The path of the file to be truncated.
 * @param newsize The size to set the file to. 
 * 
 * @return AFC_E_SUCCESS if everything went well, AFC_E_INVALID_ARGUMENT
 *         if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise.
 */
afc_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize)
{
	char *response = NULL;
	char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
	int bytes = 0;
	uint64_t size_requested = newsize;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !client->afc_packet || !client->connection)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	memcpy(send, &size_requested, 8);
	memcpy(send + 8, path, strlen(path) + 1);
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	client->afc_packet->operation = AFC_OP_TRUNCATE;
	bytes = afc_dispatch_packet(client, send, 8 + strlen(path) + 1);
	free(send);
	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 19
0
/**
 * Gets information about a specific file.
 * 
 * @param client The client to use to get the information of the file.
 * @param path The fully-qualified path to the file. 
 * @param infolist Pointer to a buffer that will be filled with a NULL-terminated
 *                 list of strings with the file information.
 *                 Set to NULL before calling this function.
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 */
afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***infolist)
{
	char *received = NULL;
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !infolist)
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send command */
	client->afc_packet->operation = AFC_OP_GET_FILE_INFO;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	ret = afc_dispatch_packet(client, path, strlen(path)+1, &bytes);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}

	/* Receive data */
	ret = afc_receive_data(client, &received, &bytes);
	if (received) {
		*infolist = make_strings_list(received, bytes);
		free(received);
	}

	afc_unlock(client);

	return ret;
}
Exemplo n.º 20
0
/**
 * Sets the modification time of a file on the device.
 * 
 * @param client The client to use to set the file size.
 * @param path Path of the file for which the modification time should be set.
 * @param mtime The modification time to set in nanoseconds since epoch.
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 */
afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime)
{
	char *response = NULL;
	char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));
	uint32_t bytes = 0;
	uint64_t mtime_loc = htole64(mtime);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !path || !client->afc_packet || !client->parent)
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send command */
	memcpy(send, &mtime_loc, 8);
	memcpy(send + 8, path, strlen(path) + 1);
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	client->afc_packet->operation = AFC_OP_SET_FILE_TIME;
	ret = afc_dispatch_packet(client, send, 8 + strlen(path) + 1, &bytes);
	free(send);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 21
0
/**
 * Sets the size of a file on the device.
 * 
 * @param client The client to use to set the file size.
 * @param handle File handle of a previously opened file.
 * @param newsize The size to set the file to. 
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 * 
 * @note This function is more akin to ftruncate than truncate, and truncate
 *       calls would have to open the file before calling this, sadly.
 */
afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize)
{
	char *buffer = (char *) malloc(sizeof(char) * 16);
	uint32_t bytes = 0;
	uint64_t newsize_loc = htole64(newsize);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send command */
	memcpy(buffer, &handle, sizeof(uint64_t));	/* handle */
	memcpy(buffer + 8, &newsize_loc, sizeof(uint64_t));	/* newsize */
	client->afc_packet->operation = AFC_OP_FILE_SET_SIZE;
	client->afc_packet->this_length = client->afc_packet->entire_length = 0;
	ret = afc_dispatch_packet(client, buffer, 16, &bytes);
	free(buffer);
	buffer = NULL;

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer)
		free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 22
0
/** Closes a file on the phone. 
 * 
 * @param client The client to close the file with.
 * @param handle File handle of a previously opened file.
 */
afc_error_t afc_file_close(afc_client_t client, uint64_t handle)
{
	char *buffer = malloc(sizeof(char) * 8);
	int bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	log_debug_msg("%s: File handle %i\n", __func__, handle);

	// Send command
	memcpy(buffer, &handle, sizeof(uint64_t));
	client->afc_packet->operation = AFC_OP_FILE_CLOSE;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	bytes = afc_dispatch_packet(client, buffer, 8);
	free(buffer);
	buffer = NULL;

	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_UNKNOWN_ERROR;
	}

	// Receive the response
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer)
		free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 23
0
idevice_error_t
afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read)
{
	char *input = NULL;
	uint32_t current_count = 0, bytes_loc = 0;
	afc_error_t ret = AFC_E_SUCCESS;

	if (!client || !client->afc_packet || !client->parent || handle == 0)
		return AFC_E_INVALID_ARG;
	debug_info("called for length %i", length);

	afc_lock(client);

	/* Send the read command */
	struct {
		uint64_t handle;
		uint64_t size;
	} readinfo;
	readinfo.handle = handle;
	readinfo.size = htole64(length);
	ret = afc_dispatch_packet(client, AFC_OP_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc);

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive the data */
	ret = afc_receive_data(client, &input, &bytes_loc);
	debug_info("afc_receive_data returned error: %d", ret);
	debug_info("bytes returned: %i", bytes_loc);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return ret;
	} else if (bytes_loc == 0) {
		if (input)
			free(input);
		afc_unlock(client);
		*bytes_read = current_count;
		/* FIXME: check that's actually a success */
		return ret;
	} else {
		if (input) {
			debug_info("%d", bytes_loc);
			memcpy(data + current_count, input, (bytes_loc > length) ? length : bytes_loc);
			free(input);
			input = NULL;
			current_count += (bytes_loc > length) ? length : bytes_loc;
		}
	}
	afc_unlock(client);
	*bytes_read = current_count;
	return ret;
}
Exemplo n.º 24
0
/** Opens a file on the phone.
 * 
 * @param client The client to use to open the file. 
 * @param filename The file to open. (must be a fully-qualified path)
 * @param file_mode The mode to use to open the file. Can be AFC_FILE_READ or
 * 		    AFC_FILE_WRITE; the former lets you read and write,
 * 		    however, and the second one will *create* the file,
 * 		    destroying anything previously there.
 * @param handle Pointer to a uint64_t that will hold the handle of the file
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error on failure.
 */
iphone_error_t
afc_file_open(afc_client_t client, const char *filename,
					 afc_file_mode_t file_mode, uint64_t *handle)
{
	uint32_t ag = 0;
	int bytes = 0;
	char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	// set handle to 0 so in case an error occurs, the handle is invalid
	*handle = 0;

	if (!client || !client->connection || !client->afc_packet)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	// Send command
	memcpy(data, &file_mode, 4);
	memcpy(data + 4, &ag, 4);
	memcpy(data + 8, filename, strlen(filename));
	data[8 + strlen(filename)] = '\0';
	client->afc_packet->operation = AFC_OP_FILE_OPEN;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	bytes = afc_dispatch_packet(client, data, 8 + strlen(filename) + 1);
	free(data);

	if (bytes <= 0) {
		log_debug_msg("%s: Didn't receive a response to the command\n", __func__);
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive the data
	ret = afc_receive_data(client, &data, &bytes);
	if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) {
		afc_unlock(client);

		// Get the file handle
		memcpy(handle, data, sizeof(uint64_t));
		free(data);
		return ret;
	}

	log_debug_msg("%s: Didn't get any further data\n", __func__);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 25
0
idevice_error_t
afc_file_open(afc_client_t client, const char *filename,
					 afc_file_mode_t file_mode, uint64_t *handle)
{
	if (!client || !client->parent || !client->afc_packet)
		return AFC_E_INVALID_ARG;

	uint64_t file_mode_loc = htole64(file_mode);
	uint32_t bytes = 0;
	char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	/* set handle to 0 so in case an error occurs, the handle is invalid */
	*handle = 0;

	afc_lock(client);

	/* Send command */
	memcpy(data, &file_mode_loc, 8);
	memcpy(data + 8, filename, strlen(filename));
	data[8 + strlen(filename)] = '\0';
	ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data, 8 + strlen(filename) + 1, NULL, 0, &bytes);
	free(data);

	if (ret != AFC_E_SUCCESS) {
		debug_info("Didn't receive a response to the command");
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive the data */
	data = NULL;
	ret = afc_receive_data(client, &data, &bytes);
	if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) {
		afc_unlock(client);

		/* Get the file handle */
		memcpy(handle, data, sizeof(uint64_t));
		free(data);
		return ret;
	}
	/* in case memory was allocated but no data received or an error occurred */
	free(data);

	debug_info("Didn't get any further data");

	afc_unlock(client);

	return ret;
}
Exemplo n.º 26
0
/**
 * Locks or unlocks a file on the device. 
 *
 * makes use of flock on the device, see
 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html
 *
 * @param client The client to lock the file with.
 * @param handle File handle of a previously opened file.
 * @param operation the lock or unlock operation to perform, this is one of
 *        AFC_LOCK_SH (shared lock), AFC_LOCK_EX (exclusive lock),
 *        or AFC_LOCK_UN (unlock).
 */
afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
{
	char *buffer = (char *)malloc(16);
	uint32_t bytes = 0;
	uint64_t op = htole64(operation);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("file handle %i", handle);

	/* Send command */
	memcpy(buffer, &handle, sizeof(uint64_t));
	memcpy(buffer + 8, &op, 8);

	client->afc_packet->operation = AFC_OP_FILE_LOCK;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	ret = afc_dispatch_packet(client, buffer, 16, &bytes);
	free(buffer);
	buffer = NULL;

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		debug_info("could not send lock command");
		return AFC_E_UNKNOWN_ERROR;
	}
	/* Receive the response */
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer) {
		debug_buffer(buffer, bytes);
		free(buffer);
	}
	afc_unlock(client);

	return ret;
}
Exemplo n.º 27
0
/** Locks or unlocks a file on the phone. 
 *
 * makes use of flock on the device, see
 * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html
 *
 * @param client The client to lock the file with.
 * @param handle File handle of a previously opened file.
 * @param operation the lock or unlock operation to perform, this is one of
 *        AFC_LOCK_SH (shared lock), AFC_LOCK_EX (exclusive lock),
 *        or AFC_LOCK_UN (unlock).
 */
afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation)
{
	char *buffer = malloc(16);
	int bytes = 0;
	uint64_t op = operation;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	log_debug_msg("%s: file handle %i\n", __func__, handle);

	// Send command
	memcpy(buffer, &handle, sizeof(uint64_t));
	memcpy(buffer + 8, &op, 8);

	client->afc_packet->operation = AFC_OP_FILE_LOCK;
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	bytes = afc_dispatch_packet(client, buffer, 16);
	free(buffer);
	buffer = NULL;

	if (bytes <= 0) {
		afc_unlock(client);
		log_debug_msg("%s: could not send lock command\n", __func__);
		return AFC_E_UNKNOWN_ERROR;
	}
	// Receive the response
	ret = afc_receive_data(client, &buffer, &bytes);
	if (buffer) {
		log_debug_buffer(buffer, bytes);
		free(buffer);
	}
	afc_unlock(client);

	return ret;
}
Exemplo n.º 28
0
/**
 * Returns current position in a pre-opened file on the device.
 * 
 * @param client The client to use.
 * @param handle File handle of a previously opened file.
 * @param position Position in bytes of indicator
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 */
afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position)
{
	char *buffer = (char *) malloc(sizeof(char) * 8);
	uint32_t bytes = 0;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || (handle == 0))
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	/* Send the command */
	memcpy(buffer, &handle, sizeof(uint64_t));	/* handle */
	client->afc_packet->operation = AFC_OP_FILE_TELL;
	client->afc_packet->this_length = client->afc_packet->entire_length = 0;
	ret = afc_dispatch_packet(client, buffer, 8, &bytes);
	free(buffer);
	buffer = NULL;

	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}

	/* Receive the data */
	ret = afc_receive_data(client, &buffer, &bytes);
	if (bytes > 0 && buffer) {
		/* Get the position */
		memcpy(position, buffer, sizeof(uint64_t));
		*position = le64toh(*position);
	}
	if (buffer)
		free(buffer);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 29
0
/**
 * Creates a hard link or symbolic link on the device. 
 * 
 * @param client The client to use for making a link
 * @param linktype 1 = hard link, 2 = symlink
 * @param target The file to be linked.
 * @param linkname The name of link.
 * 
 * @return AFC_E_SUCCESS on success or an AFC_E_* error value.
 */
afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname)
{
	char *response = NULL;
	char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8));
	uint32_t bytes = 0;
	uint64_t type = htole64(linktype);
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !target || !linkname || !client->afc_packet || !client->connection)
		return AFC_E_INVALID_ARG;

	afc_lock(client);

	debug_info("link type: %lld", type);
	debug_info("target: %s, length:%d", target, strlen(target));
	debug_info("linkname: %s, length:%d", linkname, strlen(linkname));

	/* Send command */
	memcpy(send, &type, 8);
	memcpy(send + 8, target, strlen(target) + 1);
	memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1);
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	client->afc_packet->operation = AFC_OP_MAKE_LINK;
	ret = afc_dispatch_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1, &bytes);
	free(send);
	if (ret != AFC_E_SUCCESS) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	/* Receive response */
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}
Exemplo n.º 30
0
/** Creates a hard link or symbolic link on the device. 
 * 
 * @param client The client to use for making a link
 * @param type 1 = hard link, 2 = symlink
 * @param target The file to be linked.
 * @param linkname The name of link.
 * 
 * @return AFC_E_SUCCESS if everything went well, AFC_E_INVALID_ARGUMENT
 *         if arguments are NULL or invalid, AFC_E_NOT_ENOUGH_DATA otherwise.
 */
afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname)
{
	char *response = NULL;
	char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8));
	int bytes = 0;
	uint64_t type = linktype;
	afc_error_t ret = AFC_E_UNKNOWN_ERROR;

	if (!client || !target || !linkname || !client->afc_packet || !client->connection)
		return AFC_E_INVALID_ARGUMENT;

	afc_lock(client);

	log_debug_msg("%s: link type: %lld\n", __func__, type);
	log_debug_msg("%s: target: %s, length:%d\n", __func__, target, strlen(target));
	log_debug_msg("%s: linkname: %s, length:%d\n", __func__, linkname, strlen(linkname));

	// Send command
	memcpy(send, &type, 8);
	memcpy(send + 8, target, strlen(target) + 1);
	memcpy(send + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1);
	client->afc_packet->entire_length = client->afc_packet->this_length = 0;
	client->afc_packet->operation = AFC_OP_MAKE_LINK;
	bytes = afc_dispatch_packet(client, send, 8 + strlen(linkname) + 1 + strlen(target) + 1);
	free(send);
	if (bytes <= 0) {
		afc_unlock(client);
		return AFC_E_NOT_ENOUGH_DATA;
	}
	// Receive response
	ret = afc_receive_data(client, &response, &bytes);
	if (response)
		free(response);

	afc_unlock(client);

	return ret;
}