summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/common/dir.c6
-rw-r--r--firmware/common/rb_namespace.c74
-rw-r--r--firmware/include/dir.h6
-rw-r--r--firmware/include/dircache_redirect.h5
-rw-r--r--firmware/include/rb_namespace.h3
-rw-r--r--firmware/target/hosted/filesystem-app.c5
6 files changed, 81 insertions, 18 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index 45749b8474..9a78d910a7 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -344,3 +344,9 @@ struct dirinfo dir_get_info(DIR *dirp, struct dirent *entry)
344file_error: 344file_error:
345 return (struct dirinfo){ .attribute = 0 }; 345 return (struct dirinfo){ .attribute = 0 };
346} 346}
347
348const char* root_realpath(void)
349{
350 /* Native only, for APP and SIM see respective filesystem-.c files */
351 return root_get_realpath(); /* rb_namespace.c */
352}
diff --git a/firmware/common/rb_namespace.c b/firmware/common/rb_namespace.c
index ff5ad0f6db..52b2205f40 100644
--- a/firmware/common/rb_namespace.c
+++ b/firmware/common/rb_namespace.c
@@ -23,6 +23,7 @@
23#include "fileobj_mgr.h" 23#include "fileobj_mgr.h"
24#include "rb_namespace.h" 24#include "rb_namespace.h"
25#include "file_internal.h" 25#include "file_internal.h"
26#include <stdio.h> /*snprintf*/
26 27
27/* Define LOGF_ENABLE to enable logf output in this file */ 28/* Define LOGF_ENABLE to enable logf output in this file */
28//#define LOGF_ENABLE 29//#define LOGF_ENABLE
@@ -82,39 +83,48 @@ static void unmount_item(int item)
82 set_root_item_state(item, 0); 83 set_root_item_state(item, 0);
83} 84}
84 85
86static char *root_realpath_internal(void)
87{
88 static char root_realpath[ROOT_MAX_REALPATH];
89 return root_realpath;
90}
91const char* root_get_realpath(void)
92{
93 return root_realpath_internal();
94}
95
85/* mount the directory that enumerates into the root namespace */ 96/* mount the directory that enumerates into the root namespace */
86int root_mount_path(const char *path, unsigned int flags) 97int root_mount_path(const char *path, unsigned int flags)
87{ 98{
99 const char *folder = NULL; /* is a folder enumerated in the root? */
88#ifdef HAVE_MULTIVOLUME 100#ifdef HAVE_MULTIVOLUME
89 int volume = path_strip_volume(path, NULL, false); 101 int volume = path_strip_volume(path, &folder, false);
90 if (volume == ROOT_VOLUME) 102 if (volume == ROOT_VOLUME)
91 return -EINVAL; 103 return -EINVAL;
92
93 if (!CHECK_VOL(volume)) 104 if (!CHECK_VOL(volume))
94 return -ENOENT; 105 return -ENOENT;
106 char volname[VOL_MAX_LEN+2];
107 make_volume_root(volume, volname);
95#else 108#else
109 const char volname = PATH_ROOTSTR;
96 if (!path_is_absolute(path)) 110 if (!path_is_absolute(path))
97 { 111 {
98 logf("Path not absolute %s", path); 112 logf("Path not absolute %s", path);
99 return -ENOENT; 113 return -ENOENT;
100 } 114 }
115 path_dirname(path, &folder);
101#endif /* HAVE_MULTIVOLUME */ 116#endif /* HAVE_MULTIVOLUME */
102
103 bool contents = flags & NSITEM_CONTENTS; 117 bool contents = flags & NSITEM_CONTENTS;
104 int item = contents ? ROOT_CONTENTS_INDEX : IF_MV_VOL(volume); 118 int item = IF_MV_VOL(volume);
105 unsigned int state = get_root_item_state(item); 119 unsigned int state = get_root_item_state(item);
106
107 logf("%s: item:%d, st:%u, %s", __func__, item, state, path); 120 logf("%s: item:%d, st:%u, %s", __func__, item, state, path);
108 121 if (contents && state) /* volume must be mounted to enumerate into the root namespace */
109 if (state)
110 return -EBUSY;
111
112 if (contents)
113 { 122 {
123 if (get_root_item_state(ROOT_CONTENTS_INDEX))
124 return -EBUSY; /* error something is already enumerated */
114 /* cache information about the target */ 125 /* cache information about the target */
115 struct filestr_base stream; 126 struct filestr_base stream;
116 struct path_component_info compinfo; 127 struct path_component_info compinfo;
117
118 int e = errno; 128 int e = errno;
119 int rc = open_stream_internal(path, FF_DIR | FF_PROBE | FF_INFO | 129 int rc = open_stream_internal(path, FF_DIR | FF_PROBE | FF_INFO |
120 FF_DEVPATH, &stream, &compinfo); 130 FF_DEVPATH, &stream, &compinfo);
@@ -124,17 +134,41 @@ int root_mount_path(const char *path, unsigned int flags)
124 errno = e; 134 errno = e;
125 return rc; 135 return rc;
126 } 136 }
127
128 if (!fileobj_mount(&compinfo.info, FO_DIRECTORY, &root_bindp)) 137 if (!fileobj_mount(&compinfo.info, FO_DIRECTORY, &root_bindp))
129 return -EBUSY; 138 return -EBUSY;
130 } 139 int root_state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS));
140 set_root_item_state(ROOT_CONTENTS_INDEX, root_state);
141 flags |= state; /* preserve the state of the mounted volume */
142 if (!folder)
143 {
144 folder = "";
145 }
146 else
147 {
148 /*if a folder has been enumerated don't mark the whole volume */
149 if (folder[0] != '\0' && folder[1] != '\0')
150 flags &= ~NSITEM_CONTENTS;
131 151
152 }
153 snprintf(root_realpath_internal(), ROOT_MAX_REALPATH,"%s%s", volname, folder);
154 }
155 else if (state) /* error volume already mounted */
156 return -EBUSY;
132 state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS)); 157 state = NSITEM_MOUNTED | (flags & (NSITEM_HIDDEN|NSITEM_CONTENTS));
133 set_root_item_state(item, state); 158 set_root_item_state(item, state);
134
135 return 0; 159 return 0;
136} 160}
137 161
162/* check if volume in path is mounted in the root namespace */
163bool ns_volume_is_visible(IF_MV_NONVOID(int volume))
164{
165 int item = IF_MV_VOL(volume);
166 if ((item == ROOT_VOLUME) || !CHECK_VOL(item))
167 return false;
168 unsigned int state = get_root_item_state(item);
169 return state && (((state & NSITEM_HIDDEN) == 0) || (state & NSITEM_CONTENTS));
170}
171
138/* inform root that an entire volume is being unmounted */ 172/* inform root that an entire volume is being unmounted */
139void root_unmount_volume(IF_MV_NONVOID(int volume)) 173void root_unmount_volume(IF_MV_NONVOID(int volume))
140{ 174{
@@ -154,7 +188,10 @@ void root_unmount_volume(IF_MV_NONVOID(int volume))
154 uint32_t state = get_root_item_state(ROOT_CONTENTS_INDEX); 188 uint32_t state = get_root_item_state(ROOT_CONTENTS_INDEX);
155 if (state && (volume < 0 || BASEINFO_VOL(&root_bindp->info) == volume)) 189 if (state && (volume < 0 || BASEINFO_VOL(&root_bindp->info) == volume))
156#endif 190#endif
191 {
157 unmount_item(ROOT_CONTENTS_INDEX); 192 unmount_item(ROOT_CONTENTS_INDEX);
193 root_realpath_internal()[0] = '\0';
194 }
158} 195}
159 196
160/* parse the root part of a path */ 197/* parse the root part of a path */
@@ -268,8 +305,13 @@ int root_readdir_dirent(struct filestr_base *stream,
268 state = get_root_item_state(item); 305 state = get_root_item_state(item);
269 if ((state & (NSITEM_MOUNTED|NSITEM_HIDDEN)) == NSITEM_MOUNTED) 306 if ((state & (NSITEM_MOUNTED|NSITEM_HIDDEN)) == NSITEM_MOUNTED)
270 { 307 {
271 logf("Found mounted item: %d %s", item, entry->d_name); 308#if 1 /* hide the volume enumerated into the root namespace */
272 break; 309 if (item == ROOT_CONTENTS_INDEX || (state & NSITEM_CONTENTS) == 0)
310 {
311 logf("Found mounted item: %d %s", item, entry->d_name);
312 break;
313 }
314#endif
273 } 315 }
274 316
275 item++; 317 item++;
diff --git a/firmware/include/dir.h b/firmware/include/dir.h
index 2f78b11cf5..4599877ede 100644
--- a/firmware/include/dir.h
+++ b/firmware/include/dir.h
@@ -63,6 +63,9 @@
63#ifndef dir_exists 63#ifndef dir_exists
64#define dir_exists FS_PREFIX(dir_exists) 64#define dir_exists FS_PREFIX(dir_exists)
65#endif 65#endif
66#ifndef root_realpath
67#define root_realpath FS_PREFIX(root_realpath)
68#endif
66#endif /* !DIRFUNCTIONS_DEFINED */ 69#endif /* !DIRFUNCTIONS_DEFINED */
67 70
68#ifndef DIRENT_DEFINED 71#ifndef DIRENT_DEFINED
@@ -83,6 +86,9 @@ struct dirinfo
83#ifndef DIRFUNCTIONS_DECLARED 86#ifndef DIRFUNCTIONS_DECLARED
84/* TIP: set errno to zero before calling to see if anything failed */ 87/* TIP: set errno to zero before calling to see if anything failed */
85struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry); 88struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry);
89const char* root_realpath(void);
86#endif /* !DIRFUNCTIONS_DECLARED */ 90#endif /* !DIRFUNCTIONS_DECLARED */
87 91
92
93
88#endif /* _DIR_H_ */ 94#endif /* _DIR_H_ */
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h
index f51ce70690..36f68b7251 100644
--- a/firmware/include/dircache_redirect.h
+++ b/firmware/include/dircache_redirect.h
@@ -139,8 +139,10 @@ static inline void fileop_onsync_internal(struct filestr_base *stream)
139 139
140static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) 140static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
141{ 141{
142#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) 142#if (defined(HAVE_MULTIVOLUME) || (defined(HAVE_MULTIBOOT) && !defined(BOOTLOADER)))
143 char path[VOL_MAX_LEN+2]; 143 char path[VOL_MAX_LEN+2];
144#endif
145#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER)
144 char rtpath[MAX_PATH / 2]; 146 char rtpath[MAX_PATH / 2];
145 make_volume_root(volume, path); 147 make_volume_root(volume, path);
146 148
@@ -183,7 +185,6 @@ standard_redirect:
183 root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS); 185 root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS);
184 } 186 }
185#elif defined(HAVE_MULTIVOLUME) 187#elif defined(HAVE_MULTIVOLUME)
186 char path[VOL_MAX_LEN+2];
187 make_volume_root(volume, path); 188 make_volume_root(volume, path);
188 root_mount_path(path, RB_ROOT_VOL_HIDDEN(volume) ? NSITEM_HIDDEN : 0); 189 root_mount_path(path, RB_ROOT_VOL_HIDDEN(volume) ? NSITEM_HIDDEN : 0);
189 if (volume == path_strip_volume(RB_ROOT_CONTENTS_DIR, NULL, false)) 190 if (volume == path_strip_volume(RB_ROOT_CONTENTS_DIR, NULL, false))
diff --git a/firmware/include/rb_namespace.h b/firmware/include/rb_namespace.h
index 7bc711b5a6..5cd8c2dd29 100644
--- a/firmware/include/rb_namespace.h
+++ b/firmware/include/rb_namespace.h
@@ -37,6 +37,8 @@ struct ns_scan_info
37}; 37};
38 38
39/* root functions */ 39/* root functions */
40#define ROOT_MAX_REALPATH 80
41const char* root_get_realpath(void);
40int root_mount_path(const char *path, unsigned int flags); 42int root_mount_path(const char *path, unsigned int flags);
41void root_unmount_volume(IF_MV_NONVOID(int volume)); 43void root_unmount_volume(IF_MV_NONVOID(int volume));
42int root_readdir_dirent(struct filestr_base *stream, 44int root_readdir_dirent(struct filestr_base *stream,
@@ -49,6 +51,7 @@ int ns_open_root(IF_MV(int volume,) unsigned int *callflagsp,
49 struct file_base_info *infop, uint16_t *attrp); 51 struct file_base_info *infop, uint16_t *attrp);
50int ns_open_stream(const char *path, unsigned int callflags, 52int ns_open_stream(const char *path, unsigned int callflags,
51 struct filestr_base *stream, struct ns_scan_info *scanp); 53 struct filestr_base *stream, struct ns_scan_info *scanp);
54bool ns_volume_is_visible(IF_MV_NONVOID(int volume));
52 55
53/* closes the namespace stream */ 56/* closes the namespace stream */
54static inline int ns_close_stream(struct filestr_base *stream) 57static inline int ns_close_stream(struct filestr_base *stream)
diff --git a/firmware/target/hosted/filesystem-app.c b/firmware/target/hosted/filesystem-app.c
index cfe4e65fe9..09b3365a9e 100644
--- a/firmware/target/hosted/filesystem-app.c
+++ b/firmware/target/hosted/filesystem-app.c
@@ -600,3 +600,8 @@ int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize)
600 600
601 return 0; 601 return 0;
602} 602}
603
604const char* app_root_realpath(void)
605{
606 return PATH_ROOTSTR;
607}