summaryrefslogtreecommitdiff
path: root/firmware/common/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/dir.c')
-rw-r--r--firmware/common/dir.c92
1 files changed, 12 insertions, 80 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index f89129ae34..85e6ff316b 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -27,17 +27,14 @@
27#include "dir.h" 27#include "dir.h"
28#include "pathfuncs.h" 28#include "pathfuncs.h"
29#include "fileobj_mgr.h" 29#include "fileobj_mgr.h"
30#include "dircache_redirect.h" 30#include "rb_namespace.h"
31 31
32/* structure used for open directory streams */ 32/* structure used for open directory streams */
33static struct dirstr_desc 33static struct dirstr_desc
34{ 34{
35 struct filestr_base stream; /* basic stream info (first!) */ 35 struct filestr_base stream; /* basic stream info (first!) */
36 struct dirscan_info scan; /* directory scan cursor */ 36 struct ns_scan_info scan; /* directory scan cursor */
37 struct dirent entry; /* current parsed entry information */ 37 struct dirent entry; /* current parsed entry information */
38#ifdef HAVE_MULTIVOLUME
39 int volumecounter; /* counter for root volume entries */
40#endif
41} open_streams[MAX_OPEN_DIRS]; 38} open_streams[MAX_OPEN_DIRS];
42 39
43/* check and return a struct dirstr_desc* from a DIR* */ 40/* check and return a struct dirstr_desc* from a DIR* */
@@ -47,7 +44,7 @@ static struct dirstr_desc * get_dirstr(DIR *dirp)
47 44
48 if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS)) 45 if (!PTR_IN_ARRAY(open_streams, dir, MAX_OPEN_DIRS))
49 dir = NULL; 46 dir = NULL;
50 else if (dir->stream.flags & FDO_BUSY) 47 else if (dir->stream.flags & (FDO_BUSY|FD_VALID))
51 return dir; 48 return dir;
52 49
53 int errnum; 50 int errnum;
@@ -104,49 +101,6 @@ static struct dirstr_desc * alloc_dirstr(void)
104 return NULL; 101 return NULL;
105} 102}
106 103
107#ifdef HAVE_MULTIVOLUME
108static int readdir_volume_inner(struct dirstr_desc *dir, struct dirent *entry)
109{
110 /* Volumes (secondary file systems) get inserted into the system root
111 * directory. If the path specified volume 0, enumeration will not
112 * include other volumes, but just its own files and directories.
113 *
114 * Fake special directories, which don't really exist, that will get
115 * redirected upon opendir()
116 */
117 while (++dir->volumecounter < NUM_VOLUMES)
118 {
119 /* on the system root */
120 if (!fat_ismounted(dir->volumecounter))
121 continue;
122
123 get_volume_name(dir->volumecounter, entry->d_name);
124 dir->entry.info.attr = ATTR_MOUNT_POINT;
125 dir->entry.info.size = 0;
126 dir->entry.info.wrtdate = 0;
127 dir->entry.info.wrttime = 0;
128 return 1;
129 }
130
131 /* do normal directory entry fetching */
132 return 0;
133}
134#endif /* HAVE_MULTIVOLUME */
135
136static inline int readdir_volume(struct dirstr_desc *dir,
137 struct dirent *entry)
138{
139#ifdef HAVE_MULTIVOLUME
140 /* fetch virtual volume entries? */
141 if (dir->volumecounter < NUM_VOLUMES)
142 return readdir_volume_inner(dir, entry);
143#endif /* HAVE_MULTIVOLUME */
144
145 /* do normal directory entry fetching */
146 return 0;
147 (void)dir; (void)entry;
148}
149
150 104
151/** POSIX interface **/ 105/** POSIX interface **/
152 106
@@ -165,21 +119,13 @@ DIR * opendir(const char *dirname)
165 if (!dir) 119 if (!dir)
166 FILE_ERROR(EMFILE, RC); 120 FILE_ERROR(EMFILE, RC);
167 121
168 rc = open_stream_internal(dirname, FF_DIR, &dir->stream, NULL); 122 rc = ns_open_stream(dirname, FF_DIR, &dir->stream, &dir->scan);
169 if (rc < 0) 123 if (rc < 0)
170 { 124 {
171 DEBUGF("Open failed: %d\n", rc); 125 DEBUGF("Open failed: %d\n", rc);
172 FILE_ERROR(ERRNO, RC); 126 FILE_ERROR(ERRNO, RC);
173 } 127 }
174 128
175#ifdef HAVE_MULTIVOLUME
176 /* volume counter is relevant only to the system root */
177 dir->volumecounter = rc > 1 ? 0 : INT_MAX;
178#endif /* HAVE_MULTIVOLUME */
179
180 fat_rewind(&dir->stream.fatstr);
181 rewinddir_dirent(&dir->scan);
182
183 dirp = (DIR *)dir; 129 dirp = (DIR *)dir;
184file_error: 130file_error:
185 file_internal_unlock_WRITER(); 131 file_internal_unlock_WRITER();
@@ -204,7 +150,7 @@ int closedir(DIR *dirp)
204 FILE_ERROR(EBADF, -2); 150 FILE_ERROR(EBADF, -2);
205 } 151 }
206 152
207 rc = close_stream_internal(&dir->stream); 153 rc = ns_close_stream(&dir->stream);
208 if (rc < 0) 154 if (rc < 0)
209 FILE_ERROR(ERRNO, rc * 10 - 3); 155 FILE_ERROR(ERRNO, rc * 10 - 3);
210 156
@@ -222,16 +168,11 @@ struct dirent * readdir(DIR *dirp)
222 168
223 struct dirent *res = NULL; 169 struct dirent *res = NULL;
224 170
225 int rc = readdir_volume(dir, &dir->entry); 171 int rc = ns_readdir_dirent(&dir->stream, &dir->scan, &dir->entry);
226 if (rc == 0)
227 {
228 rc = readdir_dirent(&dir->stream, &dir->scan, &dir->entry);
229 if (rc < 0)
230 FILE_ERROR(EIO, RC);
231 }
232
233 if (rc > 0) 172 if (rc > 0)
234 res = &dir->entry; 173 res = &dir->entry;
174 else if (rc < 0)
175 FILE_ERROR(EIO, RC);
235 176
236file_error: 177file_error:
237 RELEASE_DIRSTR(READER, dir); 178 RELEASE_DIRSTR(READER, dir);
@@ -258,13 +199,9 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
258 if (!dir) 199 if (!dir)
259 FILE_ERROR_RETURN(ERRNO, -1); 200 FILE_ERROR_RETURN(ERRNO, -1);
260 201
261 int rc = readdir_volume(dir, entry); 202 int rc = ns_readdir_dirent(&dir->stream, &dir->scan, entry);
262 if (rc == 0) 203 if (rc < 0)
263 { 204 FILE_ERROR(EIO, rc * 10 - 4);
264 rc = readdir_dirent(&dir->stream, &dir->scan, entry);
265 if (rc < 0)
266 FILE_ERROR(EIO, rc * 10 - 4);
267 }
268 205
269file_error: 206file_error:
270 RELEASE_DIRSTR(READER, dir); 207 RELEASE_DIRSTR(READER, dir);
@@ -288,12 +225,7 @@ void rewinddir(DIR *dirp)
288 if (!dir) 225 if (!dir)
289 FILE_ERROR_RETURN(ERRNO); 226 FILE_ERROR_RETURN(ERRNO);
290 227
291 rewinddir_dirent(&dir->scan); 228 ns_dirscan_rewind(&dir->scan);
292
293#ifdef HAVE_MULTIVOLUME
294 if (dir->volumecounter != INT_MAX)
295 dir->volumecounter = 0;
296#endif /* HAVE_MULTIVOLUME */
297 229
298 RELEASE_DIRSTR(READER, dir); 230 RELEASE_DIRSTR(READER, dir);
299} 231}