mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-25 03:29:58 -07:00
Merge and improve new storage rename/move
This commit is contained in:
@@ -470,91 +470,125 @@ FS_Error storage_common_remove(Storage* storage, const char* path) {
|
||||
return S_RETURN_ERROR;
|
||||
}
|
||||
|
||||
bool storage_is_subdir(const char* a, const char* b) {
|
||||
size_t len = strlen(b) + 2;
|
||||
char test[len];
|
||||
strncpy(test, b, len);
|
||||
if(test[len - 3] != '/') {
|
||||
test[len - 2] = '/';
|
||||
test[len - 1] = '\0';
|
||||
}
|
||||
return strncmp(a, test, len - 1) == 0;
|
||||
}
|
||||
|
||||
FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path) {
|
||||
if(!storage_common_exists(storage, old_path)) {
|
||||
return FSE_NOT_EXIST;
|
||||
}
|
||||
FS_Error error;
|
||||
|
||||
if(storage_is_subdir(new_path, old_path)) {
|
||||
return FSE_INVALID_NAME;
|
||||
}
|
||||
do {
|
||||
if(!storage_common_exists(storage, old_path)) {
|
||||
error = FSE_NOT_EXIST;
|
||||
break;
|
||||
}
|
||||
|
||||
S_API_PROLOGUE;
|
||||
SAData data = {
|
||||
.rename = {
|
||||
.old = old_path,
|
||||
.new = new_path,
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
}};
|
||||
if(storage_common_exists(storage, new_path)) {
|
||||
error = FSE_EXIST;
|
||||
break;
|
||||
}
|
||||
|
||||
S_API_MESSAGE(StorageCommandCommonRename);
|
||||
S_API_EPILOGUE;
|
||||
FS_Error ret = S_RETURN_ERROR;
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
S_API_PROLOGUE;
|
||||
SAData data = {
|
||||
.rename = {
|
||||
.old = old_path,
|
||||
.new = new_path,
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
}};
|
||||
|
||||
S_API_MESSAGE(StorageCommandCommonRename);
|
||||
S_API_EPILOGUE;
|
||||
error = S_RETURN_ERROR;
|
||||
|
||||
if(error == FSE_NOT_IMPLEMENTED) {
|
||||
// Different filesystems, use copy + remove
|
||||
error = storage_common_copy(storage, old_path, new_path);
|
||||
if(error != FSE_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == FSE_NOT_IMPLEMENTED) {
|
||||
// Different filesystems, use copy + remove
|
||||
ret = storage_common_copy(storage, old_path, new_path);
|
||||
if(ret == FSE_OK) {
|
||||
if(!storage_simply_remove_recursive(storage, old_path)) {
|
||||
ret = FSE_INTERNAL;
|
||||
error = FSE_INTERNAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} while(false);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FS_Error storage_common_move(Storage* storage, const char* old_path, const char* new_path) {
|
||||
if(!storage_common_exists(storage, old_path)) {
|
||||
return FSE_NOT_EXIST;
|
||||
}
|
||||
FS_Error error;
|
||||
|
||||
if(storage_is_subdir(new_path, old_path)) {
|
||||
return FSE_INVALID_NAME;
|
||||
}
|
||||
|
||||
if(storage_file_exists(storage, new_path)) {
|
||||
FS_Error error = storage_common_remove(storage, new_path);
|
||||
if(error != FSE_OK) {
|
||||
return error;
|
||||
do {
|
||||
if(!storage_common_exists(storage, old_path)) {
|
||||
error = FSE_NOT_EXIST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
S_API_PROLOGUE;
|
||||
SAData data = {
|
||||
.rename = {
|
||||
.old = old_path,
|
||||
.new = new_path,
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
}};
|
||||
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;
|
||||
}
|
||||
|
||||
S_API_MESSAGE(StorageCommandCommonRename);
|
||||
S_API_EPILOGUE;
|
||||
FS_Error ret = S_RETURN_ERROR;
|
||||
// Cannot move 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;
|
||||
}
|
||||
|
||||
if(ret == FSE_NOT_IMPLEMENTED) {
|
||||
// Different filesystems, use copy + remove
|
||||
ret = storage_common_copy(storage, old_path, new_path);
|
||||
if(ret == FSE_OK) {
|
||||
ret = storage_simply_remove_recursive(storage, old_path);
|
||||
// Moving 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;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
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 = {
|
||||
.old = old_path,
|
||||
.new = new_path,
|
||||
.thread_id = furi_thread_get_current_id(),
|
||||
}};
|
||||
|
||||
S_API_MESSAGE(StorageCommandCommonRename);
|
||||
S_API_EPILOGUE;
|
||||
error = S_RETURN_ERROR;
|
||||
|
||||
if(error == FSE_NOT_IMPLEMENTED) {
|
||||
// Different filesystems, use copy + remove
|
||||
error = storage_common_copy(storage, old_path, new_path);
|
||||
if(error != FSE_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!storage_simply_remove_recursive(storage, old_path)) {
|
||||
error = FSE_INTERNAL;
|
||||
}
|
||||
}
|
||||
} while(false);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static FS_Error
|
||||
storage_copy_recursive(Storage* storage, const char* old_path, const char* new_path) {
|
||||
if(storage_is_subdir(new_path, old_path)) {
|
||||
if(storage_common_equivalent_path(storage, old_path, new_path, true)) {
|
||||
return FSE_INVALID_NAME;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user