37 void* directory_workspace,
38 uint32_t directory_workspace_bytes)
40 if ((workspace ==
nullptr) || (directory_workspace ==
nullptr) ||
41 (directory_workspace_bytes == 0U)) {
45 .directory_workspace_bytes = directory_workspace_bytes};
68 workspace->
depth = 0U;
131 (strpbrk(entry->
name,
"/\\") !=
nullptr)) {
134 *out_length = length;
158 *out_continue =
true;
170 err =
fw_fs_stat(&walk->storage->fs->names, series, &node);
177 bool tracked =
false;
179 if ((err !=
k_ra8_ok) || !tracked) {
180 *out_continue = !tracked && (err ==
k_ra8_ok);
187 bool user_continue =
false;
188 err = walk->callback(series, state, walk->state, walk->callback_ctx, &user_continue);
192 *out_continue = user_continue;
217 return (first ==
k_ra8_ok) ? closed : first;
284 bool present =
false;
286 if ((err !=
k_ra8_ok) || !present) {
295 bool keep_going =
false;
297 if ((err !=
k_ra8_ok) || !keep_going) {
312 if ((storage ==
nullptr) || (storage->
fs ==
nullptr) || (out_dir ==
nullptr) ||
313 (state_scratch ==
nullptr) || (workspace ==
nullptr) || (callback ==
nullptr) ||
320 bool root_exists =
false;
324 if ((err !=
k_ra8_ok) || !root_exists) {
329 .state = state_scratch,
330 .callback = callback,
331 .callback_ctx = callback_ctx};
389 if (remaining < 3U) {
532 if ((dir[0] ==
'/') && (dir[1] ==
'\0')) {
549 const size_t root_length =
strnlen(dir,
sizeof(workspace->
paths[0]));
550 if (root_length >=
sizeof(workspace->
paths[0])) {
553 memcpy(workspace->
paths[0], dir, root_length + 1U);
581 bool present =
false;
614 if ((storage ==
nullptr) || (storage->
fs ==
nullptr) || (dir ==
nullptr) ||
623 return ((err ==
k_ra8_ok) && (workspace->
paths[0][0] !=
'\0'))
ra8_err_t fw_fs_stat(const fw_fs_namespace_t *names, const char *path, fw_fs_stat_t *out)
Query a path; a miss is success with out->exists == false.
ra8_err_t fw_fs_rmdir(const fw_fs_namespace_t *names, const char *path)
Remove one empty directory; recursive deletion is deliberately absent.
ra8_err_t fw_fs_dir_next(fw_fs_dir_t *directory, fw_fs_dirent_value_t *out, bool *out_entry)
Copy one stable directory entry from an open cursor.
ra8_err_t fw_fs_dir_close(fw_fs_dir_t *directory)
Close and consume an open directory cursor, including on close error.
ra8_err_t fw_fs_unlink(const fw_fs_namespace_t *names, const char *path)
Remove one regular file; directories require fw_fs_rmdir.
ra8_err_t fw_fs_dir_open(const fw_fs_namespace_t *names, const char *path, fw_fs_dir_t *directory, void *workspace, uint32_t workspace_size)
Open one directory cursor into caller-owned backend workspace.
@ k_fw_fs_node_directory
Directory.
@ k_fw_fs_node_file
Regular byte stream.
@ k_fw_fs_node_symlink
Symbolic link, if observable.
@ k_fw_fs_path_cap
Largest portable path including its NUL.
static ra8_err_t internal_library_remove_walk(mdl_storage_t *storage, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace)
Execute iterative post-order removal from a retained valid root.
static ra8_err_t internal_library_close(fw_fs_dir_t *directory, ra8_err_t first)
Preserve the first traversal error while always consuming a cursor.
static ra8_err_t internal_library_remove_child(mdl_storage_t *storage, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace, const fw_fs_dirent_value_t *child)
Remove or descend into one captured child.
static ra8_err_t internal_library_visit(mdl_library_enumeration_t *walk, const fw_fs_dirent_value_t *entry, bool *out_continue)
Authenticate and deliver one stable cursor entry.
static ra8_err_t internal_library_policy(const mdl_library_policy_t *policy)
Validate a caller-selected policy against hard ceilings.
ra8_err_t mdl_library_workspace_init(mdl_library_workspace_t *workspace, void *directory_workspace, uint32_t directory_workspace_bytes)
Bind caller-owned directory storage to a reusable library workspace.
ra8_err_t mdl_library_for_each(mdl_storage_t *storage, const char *out_dir, mdl_state_t *state_scratch, mdl_library_workspace_t *workspace, const mdl_library_policy_t *policy, mdl_library_fn callback, void *callback_ctx)
Visit every authenticated tracked series under a library root.
static ra8_err_t internal_library_take_operation(const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace)
Consume one removal namespace-operation budget unit.
static ra8_err_t internal_library_act_on_node(mdl_storage_t *storage, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace, const char *path, fw_fs_stat_t node)
Act on one revalidated child node according to its type.
static ra8_err_t internal_library_leaf(const mdl_storage_t *storage, const fw_fs_dirent_value_t *entry, size_t *out_length)
Validate and measure one borrowed backend leaf name.
static void internal_library_workspace_reset(mdl_library_workspace_t *workspace)
Clear traversal state while preserving caller cursor storage.
static const char s_state_basename[]
Logical marker basename within one tracked series.
static ra8_err_t internal_library_root(mdl_storage_t *storage, const char *root_path, bool *out_exists)
Validate one library root before cursor open.
static ra8_err_t internal_library_first_child(mdl_storage_t *storage, const char *path, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace, fw_fs_dirent_value_t *out, bool *out_present)
Copy at most one child then close before any namespace mutation.
static ra8_err_t internal_library_remove_root(mdl_storage_t *storage, const char *dir, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace)
Validate and retain the root of one removal traversal.
static ra8_err_t internal_library_enumerate(mdl_library_enumeration_t *walk, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace)
Advance one cursor while authenticating entries between next calls.
mdl_library_policy_t mdl_library_policy_default(void)
Return the production library traversal policy.
ra8_err_t mdl_library_remove_tree(mdl_storage_t *storage, const char *dir, const mdl_library_policy_t *policy, mdl_library_workspace_t *workspace)
Remove one canonical directory tree through portable namespace calls.
Portable bounded operations over a tracked media library.
@ k_mdl_library_entry_limit
Maximum discovered entries.
@ k_mdl_library_operation_limit
Maximum namespace calls.
@ k_mdl_library_depth_limit
Maximum child-dir nesting.
ra8_err_t(* mdl_library_fn)(const char *series_dir, const char *state_path, const mdl_state_t *state, void *ctx, bool *out_continue)
Per-series visitor callback for mdl_library_for_each.
Neutralise untrusted names before they reach a filesystem or XML sink.
bool mdl_path_join(const char *parent, const char *seg, char *out, size_t cap)
Join one safe child segment under a parent directory path.
ra8_err_t mdl_state_load_authenticated(mdl_storage_t *storage, const char *path, mdl_state_t *st)
Load only an authenticated checksummed state generation.
ra8_err_t mdl_state_probe(mdl_storage_t *storage, const char *path, bool *out_exists)
Probe the complete two-generation state marker through portable storage.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_access_denied
Operation refused because the target is protected against it.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
size_t strnlen(const char *s, size_t maxlen)
Calculate bounded string length.
uint16_t name_max_bytes
Component bytes excluding NUL.
Caller-owned open directory cursor; fields are private to the facade.
bool is_open
Facade lifecycle guard.
Stable caller-owned value returned by fw_fs_dir_next.
uint16_t name_bytes
Bytes excluding the NUL.
fw_fs_node_type_t type
Entry kind.
char name[k_fw_fs_path_cap]
Copied NUL-terminated leaf.
Result of a portable metadata query.
bool exists
False means a clean lookup miss.
fw_fs_node_type_t type
Kind of node at the path.
fw_fs_caps_t caps
Shared capabilities.
fw_fs_namespace_t names
Namespace operations.
State threaded through one immediate-library enumeration.
void * callback_ctx
Opaque visitor context.
mdl_library_fn callback
Authenticated visitor.
mdl_storage_t * storage
Portable dependency bundle.
mdl_state_t * state
Authentication scratch.
const char * root
Canonical library root.
Caller-selected limits within the compile-time hard ceilings.
uint32_t max_operations
Namespace calls permitted for removal.
uint32_t max_entries
Entries accepted before fail-closed stop.
uint16_t max_depth
Child-directory nesting below the root.
Caller-owned directory cursor storage and iterative traversal stack.
uint32_t required_entries
Entries observed through cap+1.
uint16_t depth
Current stack depth, root is zero.
char paths[(size_t) k_mdl_library_depth_limit+1U][k_fw_fs_path_cap]
DFS path stack, one canonical path at each permitted depth.
void * directory_workspace
Backend cursor workspace.
uint32_t entry_limit
Active explicit traversal limit.
uint32_t entries
Entries accepted by the traversal.
uint32_t operations
Namespace calls attempted.
uint32_t directory_workspace_bytes
Cursor workspace extent.
One series' complete persistent state (declare at file scope).
One non-reentrant downloader filesystem dependency bundle.
const fw_fs_t * fs
Injected portable filesystem.