summaryrefslogtreecommitdiff
path: root/firmware/common/file_internal.c
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-08-20 21:54:00 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-08-20 21:54:00 -0400
commitf850bbbbc4b7345bebde241f651bad1c5c28df66 (patch)
tree1574bcca604f0617130aa9f1c426cfcdc097c901 /firmware/common/file_internal.c
parentbd744059cf959c8b9086978b32660efef5925b7d (diff)
downloadrockbox-f850bbbbc4b7345bebde241f651bad1c5c28df66.tar.gz
rockbox-f850bbbbc4b7345bebde241f651bad1c5c28df66.zip
Revert root_redirect :(
This reverts commit 31fc46ded69be7438cca2ba2c2b93c1f200165a6. Change-Id: Ia78618c0e8b25ca65f7c8ae0db1cb9c9b321bad9
Diffstat (limited to 'firmware/common/file_internal.c')
-rw-r--r--firmware/common/file_internal.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/firmware/common/file_internal.c b/firmware/common/file_internal.c
index 45f412e166..fe18f90056 100644
--- a/firmware/common/file_internal.c
+++ b/firmware/common/file_internal.c
@@ -26,7 +26,9 @@
26#include "pathfuncs.h" 26#include "pathfuncs.h"
27#include "disk_cache.h" 27#include "disk_cache.h"
28#include "fileobj_mgr.h" 28#include "fileobj_mgr.h"
29#include "rb_namespace.h" 29#include "dir.h"
30#include "dircache_redirect.h"
31#include "dircache.h"
30#include "string-extra.h" 32#include "string-extra.h"
31#include "rbunicode.h" 33#include "rbunicode.h"
32 34
@@ -85,10 +87,9 @@ void file_cache_free(struct filestr_cache *cachep)
85 87
86/** Stream base APIs **/ 88/** Stream base APIs **/
87 89
88static inline void filestr_clear(struct filestr_base *stream, 90static inline void filestr_clear(struct filestr_base *stream)
89 unsigned int flags)
90{ 91{
91 stream->flags = flags; 92 stream->flags = 0;
92 stream->bindp = NULL; 93 stream->bindp = NULL;
93#if 0 94#if 0
94 stream->mtx = NULL; 95 stream->mtx = NULL;
@@ -152,7 +153,7 @@ void filestr_discard_cache(struct filestr_base *stream)
152/* Initialize the base descriptor */ 153/* Initialize the base descriptor */
153void filestr_base_init(struct filestr_base *stream) 154void filestr_base_init(struct filestr_base *stream)
154{ 155{
155 filestr_clear(stream, FD_VALID); 156 filestr_clear(stream);
156 file_cache_init(&stream->cache); 157 file_cache_init(&stream->cache);
157 stream->cachep = &stream->cache; 158 stream->cachep = &stream->cache;
158} 159}
@@ -160,7 +161,7 @@ void filestr_base_init(struct filestr_base *stream)
160/* free base descriptor resources */ 161/* free base descriptor resources */
161void filestr_base_destroy(struct filestr_base *stream) 162void filestr_base_destroy(struct filestr_base *stream)
162{ 163{
163 filestr_clear(stream, 0); 164 filestr_clear(stream);
164 filestr_free_cache(stream); 165 filestr_free_cache(stream);
165} 166}
166 167
@@ -292,7 +293,7 @@ struct pathwalk_component
292 293
293#define WALK_RC_NOT_FOUND 0 /* successfully not found (aid for file creation) */ 294#define WALK_RC_NOT_FOUND 0 /* successfully not found (aid for file creation) */
294#define WALK_RC_FOUND 1 /* found and opened */ 295#define WALK_RC_FOUND 1 /* found and opened */
295#define WALK_RC_FOUND_ROOT 2 /* found and opened sys root */ 296#define WALK_RC_FOUND_ROOT 2 /* found and opened sys/volume root */
296#define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */ 297#define WALK_RC_CONT_AT_ROOT 3 /* continue at root level */
297 298
298/* return another struct pathwalk_component from the pool, or NULL if the 299/* return another struct pathwalk_component from the pool, or NULL if the
@@ -396,10 +397,10 @@ static int walk_open_info(struct pathwalk *walkp,
396 397
397 /* make open official if not simply probing for presence - must do it here 398 /* make open official if not simply probing for presence - must do it here
398 or compp->info on stack will get destroyed before it was copied */ 399 or compp->info on stack will get destroyed before it was copied */
399 if (!(callflags & (FF_PROBE|FF_NOFS))) 400 if (!(callflags & FF_PROBE))
400 fileop_onopen_internal(stream, &compp->info, callflags); 401 fileop_onopen_internal(stream, &compp->info, callflags);
401 402
402 return compp->attr == ATTR_SYSTEM_ROOT ? WALK_RC_FOUND_ROOT : WALK_RC_FOUND; 403 return compp->nextp ? WALK_RC_FOUND : WALK_RC_FOUND_ROOT;
403} 404}
404 405
405/* check the component against the prefix test info */ 406/* check the component against the prefix test info */
@@ -506,10 +507,6 @@ walk_path(struct pathwalk *walkp, struct pathwalk_component *compp,
506 if (len > MAX_COMPNAME) 507 if (len > MAX_COMPNAME)
507 return -ENAMETOOLONG; 508 return -ENAMETOOLONG;
508 509
509 /* no filesystem is mounted here */
510 if (walkp->callflags & FF_NOFS)
511 return -ENOENT;
512
513 /* check for "." and ".." */ 510 /* check for "." and ".." */
514 if (name[0] == '.') 511 if (name[0] == '.')
515 { 512 {
@@ -578,7 +575,7 @@ int open_stream_internal(const char *path, unsigned int callflags,
578 callflags &= ~(FF_INFO | FF_PARENTINFO | FF_CHECKPREFIX); 575 callflags &= ~(FF_INFO | FF_PARENTINFO | FF_CHECKPREFIX);
579 576
580 /* This lets it be passed quietly to directory scanning */ 577 /* This lets it be passed quietly to directory scanning */
581 stream->flags |= callflags & FF_MASK; 578 stream->flags = callflags & FF_MASK;
582 579
583 struct pathwalk walk; 580 struct pathwalk walk;
584 walk.path = path; 581 walk.path = path;
@@ -588,36 +585,80 @@ int open_stream_internal(const char *path, unsigned int callflags,
588 585
589 struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL); 586 struct pathwalk_component *rootp = pathwalk_comp_alloc(NULL);
590 rootp->nextp = NULL; 587 rootp->nextp = NULL;
588 rootp->attr = ATTR_SYSTEM_ROOT;
589
590#ifdef HAVE_MULTIVOLUME
591 int volume = 0, rootrc = WALK_RC_FOUND;
592#endif /* HAVE_MULTIVOLUME */
591 593
592 while (1) 594 while (1)
593 { 595 {
594 rc = ns_parse_root(walk.path, &rootp->name, &rootp->length); 596 const char *pathptr = walk.path;
595 if (rc < 0) 597
596 break; 598 #ifdef HAVE_MULTIVOLUME
599 /* this seamlessly integrates secondary filesystems into the
600 root namespace (e.g. "/<0>/../../<1>/../foo/." :<=> "/foo") */
601 const char *p;
602 volume = path_strip_volume(pathptr, &p, false);
603 if (!CHECK_VOL(volume))
604 {
605 DEBUGF("No such device or address: %d\n", volume);
606 FILE_ERROR(ENXIO, -2);
607 }
608
609 if (p == pathptr)
610 {
611 /* the root of this subpath is the system root */
612 rootp->attr = ATTR_SYSTEM_ROOT;
613 rootrc = WALK_RC_FOUND_ROOT;
614 }
615 else
616 {
617 /* this subpath specifies a mount point */
618 rootp->attr = ATTR_MOUNT_POINT;
619 rootrc = WALK_RC_FOUND;
620 }
597 621
598 rc = ns_open_root(IF_MV(rc,) &walk.callflags, &rootp->info, &rootp->attr); 622 walk.path = p;
623 #endif /* HAVE_MULTIVOLUME */
624
625 /* set name to start at last leading separator; names of volume
626 specifiers will be returned as "/<fooN>" */
627 rootp->name = GOBBLE_PATH_SEPCH(pathptr) - 1;
628 rootp->length =
629 IF_MV( rootrc == WALK_RC_FOUND ? p - rootp->name : ) 1;
630
631 rc = fat_open_rootdir(IF_MV(volume,) &rootp->info.fatfile);
599 if (rc < 0) 632 if (rc < 0)
633 {
634 /* not mounted */
635 DEBUGF("No such device or address: %d\n", IF_MV_VOL(volume));
636 rc = -ENXIO;
600 break; 637 break;
638 }
601 639
602 walk.path = rootp->name + rootp->length; 640 get_rootinfo_internal(&rootp->info);
603
604 rc = walk_path(&walk, rootp, stream); 641 rc = walk_path(&walk, rootp, stream);
605 if (rc != WALK_RC_CONT_AT_ROOT) 642 if (rc != WALK_RC_CONT_AT_ROOT)
606 break; 643 break;
607 } 644 }
608 645
609 if (rc >= 0) 646 switch (rc)
610 { 647 {
648 case WALK_RC_FOUND_ROOT:
649 IF_MV( rc = rootrc; )
650 case WALK_RC_NOT_FOUND:
651 case WALK_RC_FOUND:
611 /* FF_PROBE leaves nothing for caller to clean up */ 652 /* FF_PROBE leaves nothing for caller to clean up */
612 if (walk.callflags & FF_PROBE) 653 if (callflags & FF_PROBE)
613 filestr_base_destroy(stream); 654 filestr_base_destroy(stream);
614 } 655
615 else 656 break;
616 { 657
617 /* utter, abject failure :`( */ 658 default: /* utter, abject failure :`( */
618 DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno); 659 DEBUGF("Open failed: rc=%d, errno=%d\n", rc, errno);
619 filestr_base_destroy(stream); 660 filestr_base_destroy(stream);
620 FILE_ERROR(-rc, -1); 661 FILE_ERROR(-rc, -3);
621 } 662 }
622 663
623file_error: 664file_error: