mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
fs/cromfs: More directory traversal fixes. tools/gencromfs.c: Add ability use a callback with directory traversal. Not currently used but left in place in case it is needed in the future.
This commit is contained in:
+27
-8
@@ -313,6 +313,7 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
FAR void *arg)
|
FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR struct cromfs_comparenode_s *cpnode;
|
FAR struct cromfs_comparenode_s *cpnode;
|
||||||
|
FAR const struct cromfs_node_s *child;
|
||||||
FAR char *name;
|
FAR char *name;
|
||||||
int namlen;
|
int namlen;
|
||||||
|
|
||||||
@@ -324,6 +325,8 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
name = (FAR char *)cromfs_offset2addr(fs, node->cn_name);
|
name = (FAR char *)cromfs_offset2addr(fs, node->cn_name);
|
||||||
namlen = strlen(name);
|
namlen = strlen(name);
|
||||||
|
|
||||||
|
finfo("Compare %s to %s[0-%u]\n", name, cpnode->segment, cpnode->seglen);
|
||||||
|
|
||||||
/* If the lengths of the name does not match the length of the next path
|
/* If the lengths of the name does not match the length of the next path
|
||||||
* segment, then this is not the node we are looking for.
|
* segment, then this is not the node we are looking for.
|
||||||
*/
|
*/
|
||||||
@@ -350,8 +353,20 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
* and return 1 to stop the traversal.
|
* and return 1 to stop the traversal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 1 /* REVISIT: This seems to work, but I don't fully follow the logic. */
|
||||||
|
if (S_ISDIR(node->cn_mode))
|
||||||
|
{
|
||||||
|
*cpnode->node = (FAR const struct cromfs_node_s *)
|
||||||
|
cromfs_offset2addr(fs, node->u.cn_child);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*cpnode->node = node;
|
||||||
|
}
|
||||||
|
#else
|
||||||
*cpnode->node = (FAR const struct cromfs_node_s *)
|
*cpnode->node = (FAR const struct cromfs_node_s *)
|
||||||
cromfs_offset2addr(fs, node->u.cn_child);
|
cromfs_offset2addr(fs, node->u.cn_child);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +395,8 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
* this recurses and could potentially eat up a lot of stack.
|
* this recurses and could potentially eat up a lot of stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
child = (FAR const struct cromfs_node_s *)
|
||||||
|
cromfs_offset2addr(fs, node->u.cn_child);
|
||||||
segment = cpnode->segment + cpnode->seglen;
|
segment = cpnode->segment + cpnode->seglen;
|
||||||
|
|
||||||
/* Skip over any '/' delimiter */
|
/* Skip over any '/' delimiter */
|
||||||
@@ -395,7 +412,7 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||||||
|
|
||||||
/* Then recurse */
|
/* Then recurse */
|
||||||
|
|
||||||
return cromfs_foreach_node(fs, node, cromfs_comparenode, cpnode);
|
return cromfs_foreach_node(fs, child, cromfs_comparenode, cpnode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -415,6 +432,8 @@ static int cromfs_findnode(FAR const struct cromfs_volume_s *fs,
|
|||||||
FAR const struct cromfs_node_s *root;
|
FAR const struct cromfs_node_s *root;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
finfo("relpath: %s\n", relpath);
|
||||||
|
|
||||||
/* Get the root node */
|
/* Get the root node */
|
||||||
|
|
||||||
root = (FAR const struct cromfs_node_s *)
|
root = (FAR const struct cromfs_node_s *)
|
||||||
@@ -470,7 +489,7 @@ static int cromfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||||||
FAR struct cromfs_file_s *ff;
|
FAR struct cromfs_file_s *ff;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("Open '%s'\n", relpath);
|
finfo("Open: %s\n", relpath);
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
|
||||||
@@ -894,7 +913,7 @@ static int cromfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
|||||||
FAR const struct cromfs_node_s *node;
|
FAR const struct cromfs_node_s *node;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
finfo("relpath: %s\n", relpath);
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
|
||||||
@@ -977,7 +996,7 @@ static int cromfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||||||
/* Save the filename and file type */
|
/* Save the filename and file type */
|
||||||
|
|
||||||
name = (FAR char *)cromfs_offset2addr(fs, node->cn_name);
|
name = (FAR char *)cromfs_offset2addr(fs, node->cn_name);
|
||||||
finfo("Entry %lu: \"%s\"\n", (unsigned long)offset, name);
|
finfo("Entry %lu: %s\n", (unsigned long)offset, name);
|
||||||
strncpy(dir->fd_dir.d_name, name, NAME_MAX + 1);
|
strncpy(dir->fd_dir.d_name, name, NAME_MAX + 1);
|
||||||
|
|
||||||
switch (node->cn_mode & s_IFTGT)
|
switch (node->cn_mode & s_IFTGT)
|
||||||
@@ -1020,7 +1039,7 @@ static int cromfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||||||
|
|
||||||
static int cromfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
static int cromfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||||
{
|
{
|
||||||
finfo("Entry\n");
|
finfo("mountpt: %p dir: %p\n", mountpt, dir);
|
||||||
|
|
||||||
dir->u.cromfs.cr_curroffset = dir->u.cromfs.cr_firstoffset;
|
dir->u.cromfs.cr_curroffset = dir->u.cromfs.cr_firstoffset;
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1062,8 +1081,8 @@ static int cromfs_bind(FAR struct inode *blkdriver, const void *data,
|
|||||||
static int cromfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
|
static int cromfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
finfo("handle: %p blkdriver: %p flags: %02x\n",
|
finfo("handle: %p blkdriver: %p flags: %02x\n",
|
||||||
handle, blkdriver, flags);
|
handle, blkdriver, flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,7 +1132,7 @@ static int cromfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
|||||||
FAR const struct cromfs_node_s *node;
|
FAR const struct cromfs_node_s *node;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
finfo("mountptr: %p relpath: %s buf: %p\n", mountpt, relpath, buf);
|
finfo("mountpt: %p relpath: %s buf: %p\n", mountpt, relpath, buf);
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
|
|
||||||
|
|||||||
+25
-9
@@ -211,6 +211,11 @@ union lzf_result_u
|
|||||||
|
|
||||||
static uint8_t *g_lzf_hashtab[LZF_HSIZE];
|
static uint8_t *g_lzf_hashtab[LZF_HSIZE];
|
||||||
|
|
||||||
|
/* Type of the callback from traverse_directory() */
|
||||||
|
|
||||||
|
typedef int (*traversal_callback_t)(const char *dirpath, const char *name,
|
||||||
|
void *arg, bool lastentry);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -260,9 +265,10 @@ static void gen_directory(const char *path, const char *name, mode_t mode,
|
|||||||
bool lastentry);
|
bool lastentry);
|
||||||
static void gen_file(const char *path, const char *name, mode_t mode,
|
static void gen_file(const char *path, const char *name, mode_t mode,
|
||||||
bool lastentry);
|
bool lastentry);
|
||||||
static void process_direntry(const char *dirpath, const char *name,
|
static int process_direntry(const char *dirpath, const char *name,
|
||||||
bool lastentry);
|
void *arg, bool lastentry);
|
||||||
static void traverse_directory(const char *dirpath);
|
static int traverse_directory(const char *dirpath,
|
||||||
|
traversal_callback_t callback, void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -923,7 +929,7 @@ static void gen_directory(const char *path, const char *name, mode_t mode,
|
|||||||
|
|
||||||
/* Then recurse to generate all of the nodes for the subtree */
|
/* Then recurse to generate all of the nodes for the subtree */
|
||||||
|
|
||||||
traverse_directory(path);
|
(void)traverse_directory(path, process_direntry, NULL);
|
||||||
|
|
||||||
/* When traverse_directory() returns, all of the nodes in the sub-tree under
|
/* When traverse_directory() returns, all of the nodes in the sub-tree under
|
||||||
* 'name' will have been written to the new tmpfile. g_offset is correct,
|
* 'name' will have been written to the new tmpfile. g_offset is correct,
|
||||||
@@ -1079,8 +1085,8 @@ static void gen_file(const char *path, const char *name, mode_t mode,
|
|||||||
append_tmpfile(g_tmpstream, outstream);
|
append_tmpfile(g_tmpstream, outstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_direntry(const char *dirpath, const char *name,
|
static int process_direntry(const char *dirpath, const char *name,
|
||||||
bool lastentry)
|
void *arg, bool lastentry)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
char *path;
|
char *path;
|
||||||
@@ -1121,13 +1127,16 @@ static void process_direntry(const char *dirpath, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void traverse_directory(const char *dirpath)
|
static int traverse_directory(const char *dirpath,
|
||||||
|
traversal_callback_t callback, void *arg)
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *direntry;
|
struct dirent *direntry;
|
||||||
char name[NAME_MAX + 1];
|
char name[NAME_MAX + 1];
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/* Open the directory */
|
/* Open the directory */
|
||||||
|
|
||||||
@@ -1163,9 +1172,16 @@ static void traverse_directory(const char *dirpath)
|
|||||||
{
|
{
|
||||||
/* Process the directory entry */
|
/* Process the directory entry */
|
||||||
|
|
||||||
process_direntry(dirpath, name, direntry == NULL);
|
ret = callback(dirpath, name, arg, direntry == NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closedir(dirp);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1221,7 +1237,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
* directory entry encountered.
|
* directory entry encountered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
traverse_directory(g_dirname);
|
(void)traverse_directory(g_dirname, process_direntry, NULL);
|
||||||
|
|
||||||
/* Now append the volume header to output file */
|
/* Now append the volume header to output file */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user