diff options
Diffstat (limited to 'firmware/common/file_internal.c')
-rw-r--r-- | firmware/common/file_internal.c | 95 |
1 files changed, 27 insertions, 68 deletions
diff --git a/firmware/common/file_internal.c b/firmware/common/file_internal.c index fe18f90056..45f412e166 100644 --- a/firmware/common/file_internal.c +++ b/firmware/common/file_internal.c @@ -26,9 +26,7 @@ #include "pathfuncs.h" #include "disk_cache.h" #include "fileobj_mgr.h" -#include "dir.h" -#include "dircache_redirect.h" -#include "dircache.h" +#include "rb_namespace.h" #include "string-extra.h" #include "rbunicode.h" @@ -87,9 +85,10 @@ void file_cache_free(struct filestr_cache *cachep) /** Stream base APIs **/ -static inline void filestr_clear(struct filestr_base *stream) +static inline void filestr_clear(struct filestr_base *stream, + unsigned int flags) { - stream->flags = 0; + stream->flags = flags; stream->bindp = NULL; #if 0 stream->mtx = NULL; @@ -153,7 +152,7 @@ void filestr_discard_cache(struct filestr_base *stream) /* Initialize the base descriptor */ void filestr_base_init(struct filestr_base *stream) { - filestr_clear(stream); + filestr_clear(stream, FD_VALID); file_cache_init(&stream->cache); stream->cachep = &stream->cache; } @@ -161,7 +160,7 @@ void filestr_base_init(struct filestr_base *stream) /* free base descriptor resources */ void filestr_base_destroy(struct filestr_base *stream) { - filestr_clear(stream); + filestr_clear(stream, 0); filestr_free_cache(stream); } @@ -293,7 +292,7 @@ struct pathwalk_component #define WALK_RC_NOT_FOUND 0 /* successfully not found (aid for file creation) */ #define WALK_RC_FOUND 1 /* found and opened */ -#define WALK_RC_FOUND_ROOT 2 /* found and opened sys/volume root */ +#define WALK_RC_FOUND_ROOT 2 /* found and opened sys root */ #define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */ /* return another struct pathwalk_component from the pool, or NULL if the @@ -397,10 +396,10 @@ static int walk_open_info(struct pathwalk *walkp, /* make open official if not simply probing for presence - must do it here or compp->info on stack will get destroyed before it was copied */ - if (!(callflags & FF_PROBE)) + if (!(callflags & (FF_PROBE|FF_NOFS))) fileop_onopen_internal(stream, &compp->info, callflags); - return compp->nextp ? WALK_RC_FOUND : WALK_RC_FOUND_ROOT; + return compp->attr == ATTR_SYSTEM_ROOT ? WALK_RC_FOUND_ROOT : WALK_RC_FOUND; } /* check the component against the prefix test info */ @@ -507,6 +506,10 @@ walk_path(struct pathwalk *walkp, struct pathwalk_component *compp, if (len > MAX_COMPNAME) return -ENAMETOOLONG; + /* no filesystem is mounted here */ + if (walkp->callflags & FF_NOFS) + return -ENOENT; + /* check for "." and ".." */ if (name[0] == '.') { @@ -575,7 +578,7 @@ int open_stream_internal(const char *path, unsigned int callflags, callflags &= ~(FF_INFO | FF_PARENTINFO | FF_CHECKPREFIX); /* This lets it be passed quietly to directory scanning */ - stream->flags = callflags & FF_MASK; + stream->flags |= callflags & FF_MASK; struct pathwalk walk; walk.path = path; @@ -585,80 +588,36 @@ int open_stream_internal(const char *path, unsigned int callflags, struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL); rootp->nextp = NULL; - rootp->attr = ATTR_SYSTEM_ROOT; - -#ifdef HAVE_MULTIVOLUME - int volume = 0, rootrc = WALK_RC_FOUND; -#endif /* HAVE_MULTIVOLUME */ while (1) { - const char *pathptr = walk.path; - - #ifdef HAVE_MULTIVOLUME - /* this seamlessly integrates secondary filesystems into the - root namespace (e.g. "/<0>/../../<1>/../foo/." :<=> "/foo") */ - const char *p; - volume = path_strip_volume(pathptr, &p, false); - if (!CHECK_VOL(volume)) - { - DEBUGF("No such device or address: %d\n", volume); - FILE_ERROR(ENXIO, -2); - } - - if (p == pathptr) - { - /* the root of this subpath is the system root */ - rootp->attr = ATTR_SYSTEM_ROOT; - rootrc = WALK_RC_FOUND_ROOT; - } - else - { - /* this subpath specifies a mount point */ - rootp->attr = ATTR_MOUNT_POINT; - rootrc = WALK_RC_FOUND; - } - - walk.path = p; - #endif /* HAVE_MULTIVOLUME */ - - /* set name to start at last leading separator; names of volume - specifiers will be returned as "/<fooN>" */ - rootp->name = GOBBLE_PATH_SEPCH(pathptr) - 1; - rootp->length = - IF_MV( rootrc == WALK_RC_FOUND ? p - rootp->name : ) 1; + rc = ns_parse_root(walk.path, &rootp->name, &rootp->length); + if (rc < 0) + break; - rc = fat_open_rootdir(IF_MV(volume,) &rootp->info.fatfile); + rc = ns_open_root(IF_MV(rc,) &walk.callflags, &rootp->info, &rootp->attr); if (rc < 0) - { - /* not mounted */ - DEBUGF("No such device or address: %d\n", IF_MV_VOL(volume)); - rc = -ENXIO; break; - } - get_rootinfo_internal(&rootp->info); + walk.path = rootp->name + rootp->length; + rc = walk_path(&walk, rootp, stream); if (rc != WALK_RC_CONT_AT_ROOT) break; } - switch (rc) + if (rc >= 0) { - case WALK_RC_FOUND_ROOT: - IF_MV( rc = rootrc; ) - case WALK_RC_NOT_FOUND: - case WALK_RC_FOUND: /* FF_PROBE leaves nothing for caller to clean up */ - if (callflags & FF_PROBE) + if (walk.callflags & FF_PROBE) filestr_base_destroy(stream); - - break; - - default: /* utter, abject failure :`( */ + } + else + { + /* utter, abject failure :`( */ DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno); filestr_base_destroy(stream); - FILE_ERROR(-rc, -3); + FILE_ERROR(-rc, -1); } file_error: |