Fix rename/move API, now rename/rename_safe (#468)

On OFW "rename" acts like "move", it replaces the destination
XFW had an extra "move" like that, and "rename" errored if dest exists
Now for compatibility "rename" acts as OFW, and new "rename_safe" errors
Tweaked all usages to work properly
Decided for CLI and RPC to use "rename_safe" so user cant lose files
This commit is contained in:
Willy-JL
2023-11-28 00:00:40 +00:00
parent c4675afa5e
commit e0fa360640
9 changed files with 47 additions and 47 deletions

View File

@@ -651,7 +651,7 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont
Storage* fs_api = furi_record_open(RECORD_STORAGE);
if(path_contains_only_ascii(request->content.storage_rename_request.new_path)) {
FS_Error error = storage_common_rename(
FS_Error error = storage_common_rename_safe(
fs_api,
request->content.storage_rename_request.old_path,
request->content.storage_rename_request.new_path);

View File

@@ -312,6 +312,7 @@ FS_Error storage_common_remove(Storage* storage, const char* path);
* @brief Rename a file or a directory.
*
* The file or the directory must NOT be open.
* Will overwrite the destination file if it already exists.
*
* Renaming a regular file to itself does nothing and always succeeds.
* Renaming a directory to itself or to a subdirectory of itself always fails.
@@ -324,20 +325,20 @@ FS_Error storage_common_remove(Storage* storage, const char* path);
FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path);
/**
* @brief Move a file or a directory.
* @brief Rename a file or a directory.
*
* The file or the directory must NOT be open.
* Will overwrite the destination file if it already exists.
* Will error FSE_EXIST if the destination file already exists.
*
* Moving a regular file to itself does nothing and always succeeds.
* Moving a directory to itself or to a subdirectory of itself always fails.
* Renaming a regular file to itself does nothing and always succeeds.
* Renaming a directory to itself or to a subdirectory of itself always fails.
*
* @param storage pointer to a storage API instance.
* @param old_path pointer to a zero-terminated string containing the source path.
* @param new_path pointer to a zero-terminated string containing the destination path.
* @return FSE_OK if the file or directory has been successfully moved, any other error code on failure.
* @return FSE_OK if the file or directory has been successfully renamed, any other error code on failure.
*/
FS_Error storage_common_move(Storage* storage, const char* old_path, const char* new_path);
FS_Error storage_common_rename_safe(Storage* storage, const char* old_path, const char* new_path);
/**
* @brief Copy the file to a new location.

View File

@@ -454,7 +454,7 @@ static void storage_cli_rename(Cli* cli, FuriString* old_path, FuriString* args)
if(!args_read_probably_quoted_string_and_trim(args, new_path)) {
storage_cli_print_usage();
} else {
FS_Error error = storage_common_rename(
FS_Error error = storage_common_rename_safe(
api, furi_string_get_cstr(old_path), furi_string_get_cstr(new_path));
if(error != FSE_OK) {

View File

@@ -479,12 +479,13 @@ FS_Error storage_common_rename(Storage* storage, const char* old_path, const cha
break;
}
if(storage_common_exists(storage, new_path)) {
error = FSE_EXIST;
break;
}
if(storage_dir_exists(storage, old_path)) {
// Cannot overwrite a file with a directory
if(storage_file_exists(storage, new_path)) {
error = FSE_INVALID_NAME;
break;
}
// Cannot rename a directory to itself or to a nested directory
if(storage_common_equivalent_path(storage, old_path, new_path, true)) {
error = FSE_INVALID_NAME;
@@ -497,6 +498,10 @@ FS_Error storage_common_rename(Storage* storage, const char* old_path, const cha
break;
}
if(storage_file_exists(storage, new_path)) {
storage_common_remove(storage, new_path);
}
S_API_PROLOGUE;
SAData data = {
.rename = {
@@ -525,7 +530,7 @@ FS_Error storage_common_rename(Storage* storage, const char* old_path, const cha
return error;
}
FS_Error storage_common_move(Storage* storage, const char* old_path, const char* new_path) {
FS_Error storage_common_rename_safe(Storage* storage, const char* old_path, const char* new_path) {
FS_Error error;
do {
@@ -534,30 +539,24 @@ FS_Error storage_common_move(Storage* storage, const char* old_path, const char*
break;
}
if(storage_dir_exists(storage, old_path)) {
// Cannot overwrite a file with a directory
if(storage_file_exists(storage, new_path)) {
error = FSE_INVALID_NAME;
break;
}
if(storage_common_exists(storage, new_path)) {
error = FSE_EXIST;
break;
}
// Cannot move a directory to itself or to a nested directory
if(storage_dir_exists(storage, old_path)) {
// Cannot rename a directory to itself or to a nested directory
if(storage_common_equivalent_path(storage, old_path, new_path, true)) {
error = FSE_INVALID_NAME;
break;
}
// Moving a regular file to itself does nothing and always succeeds
// Renaming a regular file to itself does nothing and always succeeds
} else if(storage_common_equivalent_path(storage, old_path, new_path, false)) {
error = FSE_OK;
break;
}
if(storage_common_exists(storage, new_path)) {
error = storage_simply_remove_recursive(storage, new_path);
if(error != FSE_OK) break;
}
S_API_PROLOGUE;
SAData data = {
.rename = {
@@ -756,7 +755,7 @@ static FS_Error
if(error == FSE_OK) {
if(file_info_is_dir(&fileinfo)) {
if(!copy) {
error = storage_common_rename(storage, old_path, new_path);
error = storage_common_rename_safe(storage, old_path, new_path);
}
if(copy || error != FSE_OK) {
error = storage_merge_recursive(storage, old_path, new_path, copy);
@@ -814,7 +813,7 @@ static FS_Error
stream_free(stream_from);
stream_free(stream_to);
} else {
error = storage_common_rename(storage, old_path, new_path_tmp);
error = storage_common_rename_safe(storage, old_path, new_path_tmp);
}
}
}