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