Implement rename.

This commit is contained in:
Michael Jumper 2013-10-25 16:28:09 -07:00
parent a72fbe5745
commit 77db391a12
3 changed files with 78 additions and 7 deletions

View File

@ -283,6 +283,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
file->dir = NULL; file->dir = NULL;
file->dir_pattern[0] = '\0'; file->dir_pattern[0] = '\0';
file->absolute_path = strdup(normalized_path); file->absolute_path = strdup(normalized_path);
file->real_path = strdup(real_path);
GUAC_RDP_DEBUG(2, "Opened \"%s\" as file_id=%i", normalized_path, file_id); GUAC_RDP_DEBUG(2, "Opened \"%s\" as file_id=%i", normalized_path, file_id);
@ -325,14 +326,47 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
} }
int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id,
const char* new_path) {
char real_path[GUAC_RDPDR_FS_MAX_PATH];
char normalized_path[GUAC_RDPDR_FS_MAX_PATH];
guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id);
if (file == NULL) {
GUAC_RDP_DEBUG(1, "Rename of bad file_id: %i", file_id);
return GUAC_RDPDR_FS_EINVAL;
}
/* Normalize path, return no-such-file if invalid */
if (guac_rdpdr_fs_normalize_path(new_path, normalized_path)) {
GUAC_RDP_DEBUG(1, "Normalization of path \"%s\" failed.", new_path);
return GUAC_RDPDR_FS_ENOENT;
}
/* Translate normalized path to real path */
__guac_rdpdr_fs_translate_path(device, normalized_path, real_path);
GUAC_RDP_DEBUG(2, "Renaming \"%s\" -> \"%s\"", file->real_path, real_path);
/* Perform rename */
if (rename(file->real_path, real_path)) {
GUAC_RDP_DEBUG(1, "rename() failed: \"%s\" -> \"%s\"",
file->real_path, real_path);
return guac_rdpdr_fs_get_errorcode(errno);
}
return 0;
}
void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) { void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) {
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
guac_rdpdr_fs_file* file;
/* Only close if file ID is valid */ guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id);
if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES) { if (file == NULL) {
GUAC_RDP_DEBUG(2, "Ignoring close for out-of-range file_id: %i", GUAC_RDP_DEBUG(2, "Ignoring close for bad file_id: %i",
file_id); file_id);
return; return;
} }
@ -351,6 +385,7 @@ void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) {
/* Free name */ /* Free name */
free(file->absolute_path); free(file->absolute_path);
free(file->real_path);
/* Free ID back to pool */ /* Free ID back to pool */
guac_pool_free_int(data->file_id_pool, file_id); guac_pool_free_int(data->file_id_pool, file_id);

View File

@ -208,6 +208,11 @@ typedef struct guac_rdpdr_fs_file {
*/ */
char* absolute_path; char* absolute_path;
/**
* The real path of this file on the local filesystem.
*/
char* real_path;
/** /**
* Associated local file descriptor. * Associated local file descriptor.
*/ */
@ -309,6 +314,13 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
int access, int file_attributes, int create_disposition, int access, int file_attributes, int create_disposition,
int create_options); int create_options);
/**
* Renames (moves) the file with the given ID to the new path specified.
* Returns zero on success, or an error code if an error occurs.
*/
int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id,
const char* new_path);
/** /**
* Frees the given file ID, allowing future open operations to reuse it. * Frees the given file ID, allowing future open operations to reuse it.
*/ */

View File

@ -143,9 +143,33 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device,
void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device,
wStream* input_stream, int file_id, int completion_id, int length) { wStream* input_stream, int file_id, int completion_id, int length) {
/* STUB */
guac_client_log_error(device->rdpdr->client, int result;
"Unimplemented stub: %s", __func__); int filename_length;
wStream* output_stream;
char destination_path[GUAC_RDPDR_FS_MAX_PATH];
/* Read structure */
Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */
Stream_Seek_UINT8(input_stream); /* RootDirectory */
Stream_Read_UINT32(input_stream, filename_length); /* FileNameLength */
/* Convert name to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream),
destination_path, filename_length/2);
/* Perform rename */
result = guac_rdpdr_fs_rename(device, file_id, destination_path);
if (result < 0)
output_stream = guac_rdpdr_new_io_completion(device,
completion_id, guac_rdpdr_fs_get_status(result), 4);
else
output_stream = guac_rdpdr_new_io_completion(device,
completion_id, STATUS_SUCCESS, 4);
Stream_Write_UINT32(output_stream, length);
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
} }
void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device,