tools/gencromfs.c and fs/cromfs: More corrections to directory traversal logic. Still some bugs.
This commit is contained in:
parent
22484386ee
commit
aeeee54921
2 changed files with 36 additions and 25 deletions
|
@ -104,6 +104,7 @@ static FAR void *cromfs_offset2addr(FAR const struct cromfs_volume_s *fs,
|
|||
static uint32_t cromfs_addr2offset(FAR const struct cromfs_volume_s *fs,
|
||||
FAR const void *addr);
|
||||
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
||||
FAR const struct cromfs_node_s *node,
|
||||
cromfs_foreach_t callback, FAR void *arg);
|
||||
static uint16_t cromfs_seglen(FAR const char *relpath);
|
||||
static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
||||
|
@ -256,12 +257,15 @@ static uint32_t cromfs_addr2offset(FAR const struct cromfs_volume_s *fs,
|
|||
****************************************************************************/
|
||||
|
||||
static int cromfs_foreach_node(FAR const struct cromfs_volume_s *fs,
|
||||
cromfs_foreach_t callback, FAR void *arg)
|
||||
FAR const struct cromfs_node_s *node,
|
||||
cromfs_foreach_t callback, FAR void *arg)
|
||||
{
|
||||
FAR const struct cromfs_node_s *node;
|
||||
int ret = OK;
|
||||
|
||||
node = (FAR const struct cromfs_node_s *)cromfs_offset2addr(fs, fs->cv_root);
|
||||
/* Traverse all entries in this directory (i.e., following the 'peer'
|
||||
* links).
|
||||
*/
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
ret = callback(fs, node, arg);
|
||||
|
@ -347,11 +351,11 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||
*/
|
||||
|
||||
*cpnode->node = (FAR const struct cromfs_node_s *)
|
||||
cromfs_offset2addr(fs, node->u.cn_child);
|
||||
cromfs_offset2addr(fs, node->u.cn_child);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A specal cas is if the path ends in "/". In this case I suppose
|
||||
/* A special case is if the path ends in "/". In this case I suppose
|
||||
* we need to interpret the as matching as long as it is a directory?
|
||||
*/
|
||||
|
||||
|
@ -391,7 +395,7 @@ static int cromfs_comparenode(FAR const struct cromfs_volume_s *fs,
|
|||
|
||||
/* Then recurse */
|
||||
|
||||
return cromfs_foreach_node(fs, cromfs_comparenode, cpnode);
|
||||
return cromfs_foreach_node(fs, node, cromfs_comparenode, cpnode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -408,14 +412,19 @@ static int cromfs_findnode(FAR const struct cromfs_volume_s *fs,
|
|||
FAR const char *relpath)
|
||||
{
|
||||
struct cromfs_comparenode_s cpnode;
|
||||
FAR const struct cromfs_node_s *root;
|
||||
int ret;
|
||||
|
||||
/* Get the root node */
|
||||
|
||||
root = (FAR const struct cromfs_node_s *)
|
||||
cromfs_offset2addr(fs, fs->cv_root);
|
||||
|
||||
/* NULL or empty string refers to the root node */
|
||||
|
||||
if (relpath == NULL || relpath[0] == '\0')
|
||||
{
|
||||
*node = (FAR const struct cromfs_node_s *)
|
||||
cromfs_offset2addr(fs, fs->cv_root);
|
||||
*node = root;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -433,7 +442,7 @@ static int cromfs_findnode(FAR const struct cromfs_volume_s *fs,
|
|||
cpnode.segment = relpath;
|
||||
cpnode.seglen = (uint16_t)cromfs_seglen(relpath);
|
||||
|
||||
ret = cromfs_foreach_node(fs, cromfs_comparenode, &cpnode);
|
||||
ret = cromfs_foreach_node(fs, root, cromfs_comparenode, &cpnode);
|
||||
if (ret > 0)
|
||||
{
|
||||
return OK;
|
||||
|
|
|
@ -260,7 +260,7 @@ static void gen_directory(const char *path, const char *name, mode_t mode,
|
|||
bool lastentry);
|
||||
static void gen_file(const char *path, const char *name, mode_t mode,
|
||||
bool lastentry);
|
||||
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
||||
static void process_direntry(const char *dirpath, const char *name,
|
||||
bool lastentry);
|
||||
static void traverse_directory(const char *dirpath);
|
||||
|
||||
|
@ -1079,14 +1079,14 @@ static void gen_file(const char *path, const char *name, mode_t mode,
|
|||
append_tmpfile(g_tmpstream, outstream);
|
||||
}
|
||||
|
||||
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
||||
static void process_direntry(const char *dirpath, const char *name,
|
||||
bool lastentry)
|
||||
{
|
||||
struct stat buf;
|
||||
char *path;
|
||||
int ret;
|
||||
|
||||
asprintf(&path, "%s/%s", dirpath, direntry->d_name);
|
||||
asprintf(&path, "%s/%s", dirpath, name);
|
||||
|
||||
ret = stat(path, &buf);
|
||||
if (ret < 0)
|
||||
|
@ -1109,11 +1109,11 @@ static void process_direntry(const char *dirpath, struct dirent *direntry,
|
|||
|
||||
else if (S_ISDIR(buf.st_mode))
|
||||
{
|
||||
gen_directory(path, direntry->d_name, buf.st_mode, lastentry);
|
||||
gen_directory(path, name, buf.st_mode, lastentry);
|
||||
}
|
||||
else if (S_ISREG(buf.st_mode))
|
||||
{
|
||||
gen_file(path, direntry->d_name, buf.st_mode, lastentry);
|
||||
gen_file(path, name, buf.st_mode, lastentry);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1127,7 +1127,7 @@ static void traverse_directory(const char *dirpath)
|
|||
{
|
||||
DIR *dirp;
|
||||
struct dirent *direntry;
|
||||
struct dirent *nextentry;
|
||||
char name[NAME_MAX + 1];
|
||||
|
||||
/* Open the directory */
|
||||
|
||||
|
@ -1144,25 +1144,27 @@ static void traverse_directory(const char *dirpath)
|
|||
direntry = readdir(dirp);
|
||||
while (direntry != NULL)
|
||||
{
|
||||
/* Get the next entry so that we can anticipate the end of the
|
||||
* directory.
|
||||
/* Preserve the name from the directory entry. The return value
|
||||
* from readdir() only persists until the next time that readdir()
|
||||
* is called (alternatively, use readdir_r).
|
||||
*/
|
||||
|
||||
nextentry = readdir(dirp);
|
||||
strncpy(name, direntry->d_name, NAME_MAX + 1);
|
||||
|
||||
/* Get the next entry in advance so that we can anticipate the end of
|
||||
* the directory.
|
||||
*/
|
||||
|
||||
direntry = readdir(dirp);
|
||||
|
||||
/* Skip the '.' and '..' hard links */
|
||||
|
||||
if (strcmp(direntry->d_name, ".") != 0 &&
|
||||
strcmp(direntry->d_name, "..") != 0)
|
||||
if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
|
||||
{
|
||||
/* Process the directory entry */
|
||||
|
||||
process_direntry(dirpath, direntry, nextentry == NULL);
|
||||
process_direntry(dirpath, name, direntry == NULL);
|
||||
}
|
||||
|
||||
/* Skip to the next entry */
|
||||
|
||||
direntry = nextentry;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue