diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/dir.c | 6 | ||||
-rw-r--r-- | firmware/common/rb_namespace.c | 74 | ||||
-rw-r--r-- | firmware/include/dir.h | 6 | ||||
-rw-r--r-- | firmware/include/dircache_redirect.h | 5 | ||||
-rw-r--r-- | firmware/include/rb_namespace.h | 3 | ||||
-rw-r--r-- | firmware/target/hosted/filesystem-app.c | 5 |
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) | |||
344 | file_error: | 344 | file_error: |
345 | return (struct dirinfo){ .attribute = 0 }; | 345 | return (struct dirinfo){ .attribute = 0 }; |
346 | } | 346 | } |
347 | |||
348 | const 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 | ||
86 | static char *root_realpath_internal(void) | ||
87 | { | ||
88 | static char root_realpath[ROOT_MAX_REALPATH]; | ||
89 | return root_realpath; | ||
90 | } | ||
91 | const 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 */ |
86 | int root_mount_path(const char *path, unsigned int flags) | 97 | int 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 */ | ||
163 | bool 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 */ |
139 | void root_unmount_volume(IF_MV_NONVOID(int volume)) | 173 | void 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 */ |
85 | struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry); | 88 | struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry); |
89 | const 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 | ||
140 | static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) | 140 | static 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 | ||
41 | const char* root_get_realpath(void); | ||
40 | int root_mount_path(const char *path, unsigned int flags); | 42 | int root_mount_path(const char *path, unsigned int flags); |
41 | void root_unmount_volume(IF_MV_NONVOID(int volume)); | 43 | void root_unmount_volume(IF_MV_NONVOID(int volume)); |
42 | int root_readdir_dirent(struct filestr_base *stream, | 44 | int 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); |
50 | int ns_open_stream(const char *path, unsigned int callflags, | 52 | int 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); |
54 | bool ns_volume_is_visible(IF_MV_NONVOID(int volume)); | ||
52 | 55 | ||
53 | /* closes the namespace stream */ | 56 | /* closes the namespace stream */ |
54 | static inline int ns_close_stream(struct filestr_base *stream) | 57 | static 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 | |||
604 | const char* app_root_realpath(void) | ||
605 | { | ||
606 | return PATH_ROOTSTR; | ||
607 | } | ||