[FL-2675] /int space reservation (#1448)
* storage: added global #defines for /int, /ext & /any * storage: introduced PATH_EXT, PATH_INT& PATH_ANY macros * core apps: moved hardcoded config files names to separate headers; prefixed them with "."; updater: added file name migration to new naming convention on backup extraction * storage: fixed storage_merge_recursive handling of complex directory structures; storage_move_to_sd: changed data migration logic to all non-dot files & all folders * core: added macro aliases for core record names * Bumped protobuf commit pointer * storage: reserved 5 pages in /int; denying write&creation of non-dot files when running out of free space Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		@@ -16,7 +16,7 @@ bool archive_back_event_callback(void* context) {
 | 
			
		||||
ArchiveApp* archive_alloc() {
 | 
			
		||||
    ArchiveApp* archive = malloc(sizeof(ArchiveApp));
 | 
			
		||||
 | 
			
		||||
    archive->gui = furi_record_open("gui");
 | 
			
		||||
    archive->gui = furi_record_open(RECORD_GUI);
 | 
			
		||||
    archive->text_input = text_input_alloc();
 | 
			
		||||
    string_init(archive->fav_move_str);
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +62,7 @@ void archive_free(ArchiveApp* archive) {
 | 
			
		||||
 | 
			
		||||
    text_input_free(archive->text_input);
 | 
			
		||||
 | 
			
		||||
    furi_record_close("gui");
 | 
			
		||||
    furi_record_close(RECORD_GUI);
 | 
			
		||||
    archive->gui = NULL;
 | 
			
		||||
 | 
			
		||||
    free(archive);
 | 
			
		||||
 
 | 
			
		||||
@@ -29,21 +29,22 @@ bool archive_app_is_available(void* context, const char* path) {
 | 
			
		||||
 | 
			
		||||
    if(app == ArchiveAppTypeU2f) {
 | 
			
		||||
        bool file_exists = false;
 | 
			
		||||
        Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
        Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
        File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
        file_exists = storage_file_open(file, "/any/u2f/key.u2f", FSAM_READ, FSOM_OPEN_EXISTING);
 | 
			
		||||
        file_exists =
 | 
			
		||||
            storage_file_open(file, ANY_PATH("u2f/key.u2f"), FSAM_READ, FSOM_OPEN_EXISTING);
 | 
			
		||||
        if(file_exists) {
 | 
			
		||||
            storage_file_close(file);
 | 
			
		||||
            file_exists =
 | 
			
		||||
                storage_file_open(file, "/any/u2f/cnt.u2f", FSAM_READ, FSOM_OPEN_EXISTING);
 | 
			
		||||
                storage_file_open(file, ANY_PATH("u2f/cnt.u2f"), FSAM_READ, FSOM_OPEN_EXISTING);
 | 
			
		||||
            if(file_exists) {
 | 
			
		||||
                storage_file_close(file);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        storage_file_free(file);
 | 
			
		||||
        furi_record_close("storage");
 | 
			
		||||
        furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
        return file_exists;
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -77,10 +78,10 @@ void archive_app_delete_file(void* context, const char* path) {
 | 
			
		||||
    bool res = false;
 | 
			
		||||
 | 
			
		||||
    if(app == ArchiveAppTypeU2f) {
 | 
			
		||||
        Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
        res = (storage_common_remove(fs_api, "/any/u2f/key.u2f") == FSE_OK);
 | 
			
		||||
        res |= (storage_common_remove(fs_api, "/any/u2f/cnt.u2f") == FSE_OK);
 | 
			
		||||
        furi_record_close("storage");
 | 
			
		||||
        Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
        res = (storage_common_remove(fs_api, ANY_PATH("u2f/key.u2f")) == FSE_OK);
 | 
			
		||||
        res |= (storage_common_remove(fs_api, ANY_PATH("u2f/cnt.u2f")) == FSE_OK);
 | 
			
		||||
        furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
        if(archive_is_favorite("/app:u2f/U2F Token")) {
 | 
			
		||||
            archive_favorites_delete("/app:u2f/U2F Token");
 | 
			
		||||
 
 | 
			
		||||
@@ -391,18 +391,18 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool archive_is_dir_exists(string_t path) {
 | 
			
		||||
    if(string_equal_str_p(path, "/any")) {
 | 
			
		||||
    if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    bool state = false;
 | 
			
		||||
    FileInfo file_info;
 | 
			
		||||
    Storage* storage = furi_record_open("storage");
 | 
			
		||||
    Storage* storage = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) {
 | 
			
		||||
        if(file_info.flags & FSF_DIRECTORY) {
 | 
			
		||||
            state = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../archive_i.h"
 | 
			
		||||
#include <storage/storage.h>
 | 
			
		||||
 | 
			
		||||
#define TAB_RIGHT InputKeyRight // Default tab swith direction
 | 
			
		||||
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
 | 
			
		||||
@@ -8,14 +9,14 @@
 | 
			
		||||
 | 
			
		||||
static const char* tab_default_paths[] = {
 | 
			
		||||
    [ArchiveTabFavorites] = "/app:favorites",
 | 
			
		||||
    [ArchiveTabIButton] = "/any/ibutton",
 | 
			
		||||
    [ArchiveTabNFC] = "/any/nfc",
 | 
			
		||||
    [ArchiveTabSubGhz] = "/any/subghz",
 | 
			
		||||
    [ArchiveTabLFRFID] = "/any/lfrfid",
 | 
			
		||||
    [ArchiveTabInfrared] = "/any/infrared",
 | 
			
		||||
    [ArchiveTabBadUsb] = "/any/badusb",
 | 
			
		||||
    [ArchiveTabIButton] = ANY_PATH("ibutton"),
 | 
			
		||||
    [ArchiveTabNFC] = ANY_PATH("nfc"),
 | 
			
		||||
    [ArchiveTabSubGhz] = ANY_PATH("subghz"),
 | 
			
		||||
    [ArchiveTabLFRFID] = ANY_PATH("lfrfid"),
 | 
			
		||||
    [ArchiveTabInfrared] = ANY_PATH("infrared"),
 | 
			
		||||
    [ArchiveTabBadUsb] = ANY_PATH("badusb"),
 | 
			
		||||
    [ArchiveTabU2f] = "/app:u2f",
 | 
			
		||||
    [ArchiveTabBrowser] = "/any",
 | 
			
		||||
    [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* known_ext[] = {
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) {
 | 
			
		||||
uint16_t archive_favorites_count(void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    string_t buffer;
 | 
			
		||||
@@ -74,7 +74,7 @@ uint16_t archive_favorites_count(void* context) {
 | 
			
		||||
 | 
			
		||||
    string_clear(buffer);
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    return lines;
 | 
			
		||||
}
 | 
			
		||||
@@ -82,7 +82,7 @@ uint16_t archive_favorites_count(void* context) {
 | 
			
		||||
static bool archive_favourites_rescan() {
 | 
			
		||||
    string_t buffer;
 | 
			
		||||
    string_init(buffer);
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
    File* fav_item_file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
@@ -122,7 +122,7 @@ static bool archive_favourites_rescan() {
 | 
			
		||||
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    storage_file_free(fav_item_file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -131,7 +131,7 @@ bool archive_favorites_read(void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
 | 
			
		||||
    ArchiveBrowserView* browser = context;
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
    File* fav_item_file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
@@ -184,7 +184,7 @@ bool archive_favorites_read(void* context) {
 | 
			
		||||
    string_clear(buffer);
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    storage_file_free(fav_item_file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    archive_set_item_count(browser, file_count);
 | 
			
		||||
 | 
			
		||||
@@ -204,7 +204,7 @@ bool archive_favorites_delete(const char* format, ...) {
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    string_init(buffer);
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
 | 
			
		||||
@@ -233,7 +233,7 @@ bool archive_favorites_delete(const char* format, ...) {
 | 
			
		||||
    storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
 | 
			
		||||
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -247,7 +247,7 @@ bool archive_is_favorite(const char* format, ...) {
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    string_init(buffer);
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    bool found = false;
 | 
			
		||||
@@ -272,7 +272,7 @@ bool archive_is_favorite(const char* format, ...) {
 | 
			
		||||
    string_clear(buffer);
 | 
			
		||||
    string_clear(filename);
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    return found;
 | 
			
		||||
}
 | 
			
		||||
@@ -281,7 +281,7 @@ bool archive_favorites_rename(const char* src, const char* dst) {
 | 
			
		||||
    furi_assert(src);
 | 
			
		||||
    furi_assert(dst);
 | 
			
		||||
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    string_t path;
 | 
			
		||||
@@ -318,7 +318,7 @@ bool archive_favorites_rename(const char* src, const char* dst) {
 | 
			
		||||
    storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
 | 
			
		||||
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -333,7 +333,7 @@ void archive_favorites_save(void* context) {
 | 
			
		||||
    furi_assert(context);
 | 
			
		||||
 | 
			
		||||
    ArchiveBrowserView* browser = context;
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    for(size_t i = 0; i < archive_file_get_array_size(browser); i++) {
 | 
			
		||||
@@ -346,5 +346,5 @@ void archive_favorites_save(void* context) {
 | 
			
		||||
    storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
 | 
			
		||||
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
#include <storage/storage.h>
 | 
			
		||||
 | 
			
		||||
#define ARCHIVE_FAV_PATH "/any/favorites.txt"
 | 
			
		||||
#define ARCHIVE_FAV_TEMP_PATH "/any/favorites.tmp"
 | 
			
		||||
#define ARCHIVE_FAV_PATH ANY_PATH("favorites.txt")
 | 
			
		||||
#define ARCHIVE_FAV_TEMP_PATH ANY_PATH("favorites.tmp")
 | 
			
		||||
 | 
			
		||||
uint16_t archive_favorites_count(void* context);
 | 
			
		||||
bool archive_favorites_read(void* context);
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ void archive_file_append(const char* path, const char* format, ...) {
 | 
			
		||||
    string_init_vprintf(string, format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
    File* file = storage_file_alloc(fs_api);
 | 
			
		||||
 | 
			
		||||
    bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND);
 | 
			
		||||
@@ -71,7 +71,7 @@ void archive_file_append(const char* path, const char* format, ...) {
 | 
			
		||||
 | 
			
		||||
    storage_file_close(file);
 | 
			
		||||
    storage_file_free(file);
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void archive_delete_file(void* context, const char* format, ...) {
 | 
			
		||||
@@ -84,7 +84,7 @@ void archive_delete_file(void* context, const char* format, ...) {
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    ArchiveBrowserView* browser = context;
 | 
			
		||||
    Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
    Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    FileInfo fileinfo;
 | 
			
		||||
    storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo);
 | 
			
		||||
@@ -97,7 +97,7 @@ void archive_delete_file(void* context, const char* format, ...) {
 | 
			
		||||
        res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    furi_record_close("storage");
 | 
			
		||||
    furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
    if(archive_is_favorite("%s", string_get_cstr(filename))) {
 | 
			
		||||
        archive_favorites_delete("%s", string_get_cstr(filename));
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ static void archive_loader_callback(const void* message, void* context) {
 | 
			
		||||
 | 
			
		||||
static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) {
 | 
			
		||||
    UNUSED(browser);
 | 
			
		||||
    Loader* loader = furi_record_open("loader");
 | 
			
		||||
    Loader* loader = furi_record_open(RECORD_LOADER);
 | 
			
		||||
 | 
			
		||||
    LoaderStatus status;
 | 
			
		||||
    if(selected->is_app) {
 | 
			
		||||
@@ -54,7 +54,7 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec
 | 
			
		||||
        FURI_LOG_E(TAG, "loader_start failed: %d", status);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    furi_record_close("loader");
 | 
			
		||||
    furi_record_close(RECORD_LOADER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void archive_scene_browser_callback(ArchiveBrowserEvent event, void* context) {
 | 
			
		||||
@@ -71,10 +71,10 @@ void archive_scene_browser_on_enter(void* context) {
 | 
			
		||||
    archive_update_focus(browser, archive->text_store);
 | 
			
		||||
    view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewBrowser);
 | 
			
		||||
 | 
			
		||||
    Loader* loader = furi_record_open("loader");
 | 
			
		||||
    Loader* loader = furi_record_open(RECORD_LOADER);
 | 
			
		||||
    archive->loader_stop_subscription =
 | 
			
		||||
        furi_pubsub_subscribe(loader_get_pubsub(loader), archive_loader_callback, archive);
 | 
			
		||||
    furi_record_close("loader");
 | 
			
		||||
    furi_record_close(RECORD_LOADER);
 | 
			
		||||
 | 
			
		||||
    uint32_t state = scene_manager_get_scene_state(archive->scene_manager, ArchiveAppSceneBrowser);
 | 
			
		||||
 | 
			
		||||
@@ -196,10 +196,10 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
            if(!archive_is_home(browser)) {
 | 
			
		||||
                archive_leave_dir(browser);
 | 
			
		||||
            } else {
 | 
			
		||||
                Loader* loader = furi_record_open("loader");
 | 
			
		||||
                Loader* loader = furi_record_open(RECORD_LOADER);
 | 
			
		||||
                furi_pubsub_unsubscribe(
 | 
			
		||||
                    loader_get_pubsub(loader), archive->loader_stop_subscription);
 | 
			
		||||
                furi_record_close("loader");
 | 
			
		||||
                furi_record_close(RECORD_LOADER);
 | 
			
		||||
 | 
			
		||||
                view_dispatcher_stop(archive->view_dispatcher);
 | 
			
		||||
            }
 | 
			
		||||
@@ -216,7 +216,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
void archive_scene_browser_on_exit(void* context) {
 | 
			
		||||
    ArchiveApp* archive = (ArchiveApp*)context;
 | 
			
		||||
 | 
			
		||||
    Loader* loader = furi_record_open("loader");
 | 
			
		||||
    Loader* loader = furi_record_open(RECORD_LOADER);
 | 
			
		||||
    furi_pubsub_unsubscribe(loader_get_pubsub(loader), archive->loader_stop_subscription);
 | 
			
		||||
    furi_record_close("loader");
 | 
			
		||||
    furi_record_close(RECORD_LOADER);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
 | 
			
		||||
    if(event.type == SceneManagerEventTypeCustom) {
 | 
			
		||||
        if(event.event == SCENE_RENAME_CUSTOM_EVENT) {
 | 
			
		||||
            Storage* fs_api = furi_record_open("storage");
 | 
			
		||||
            Storage* fs_api = furi_record_open(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
            const char* path_src = archive_get_name(archive->browser);
 | 
			
		||||
            ArchiveFile_t* file = archive_get_current_file(archive->browser);
 | 
			
		||||
@@ -62,7 +62,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
 | 
			
		||||
            string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]);
 | 
			
		||||
 | 
			
		||||
            storage_common_rename(fs_api, path_src, string_get_cstr(path_dst));
 | 
			
		||||
            furi_record_close("storage");
 | 
			
		||||
            furi_record_close(RECORD_STORAGE);
 | 
			
		||||
 | 
			
		||||
            if(file->fav) {
 | 
			
		||||
                archive_favorites_rename(path_src, string_get_cstr(path_dst));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user