diff options
-rw-r--r-- | bin/gensquashfs/src/fstree_from_dir.c | 9 | ||||
-rw-r--r-- | bin/gensquashfs/src/glob.c | 81 | ||||
-rw-r--r-- | bin/gensquashfs/test/fstree_glob1.c | 48 |
3 files changed, 128 insertions, 10 deletions
diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c index cbdc270..defc8bf 100644 --- a/bin/gensquashfs/src/fstree_from_dir.c +++ b/bin/gensquashfs/src/fstree_from_dir.c @@ -21,15 +21,6 @@ int fstree_from_dir(fstree_t *fs, sqfs_dir_iterator_t *dir) return -1; } - n = fstree_get_node_by_path(fs, fs->root, ent->name, - false, true); - if (n == NULL) { - if (S_ISDIR(ent->mode)) - dir->ignore_subdir(dir); - free(ent); - continue; - } - if (S_ISLNK(ent->mode)) { ret = dir->read_link(dir, &extra); if (ret) { diff --git a/bin/gensquashfs/src/glob.c b/bin/gensquashfs/src/glob.c index dbe93a2..7d37538 100644 --- a/bin/gensquashfs/src/glob.c +++ b/bin/gensquashfs/src/glob.c @@ -63,6 +63,82 @@ static bool set_scan_flag(const char *arg, dir_tree_cfg_t *cfg) return false; } +static int scan_directory(fstree_t *fs, sqfs_dir_iterator_t *dir, + size_t prefix_len, const char *file_prefix) +{ + for (;;) { + sqfs_dir_entry_t *ent = NULL; + tree_node_t *n = NULL; + char *extra = NULL; + + int ret = dir->next(dir, &ent); + if (ret > 0) + break; + if (ret < 0) { + sqfs_perror("readdir", NULL, ret); + return -1; + } + + n = fstree_get_node_by_path(fs, fs->root, ent->name, + false, true); + if (n == NULL) { + if (S_ISDIR(ent->mode)) + dir->ignore_subdir(dir); + free(ent); + continue; + } + + if (S_ISLNK(ent->mode)) { + ret = dir->read_link(dir, &extra); + if (ret) { + free(ent); + sqfs_perror("readlink", ent->name, ret); + return -1; + } + } else if (S_ISREG(ent->mode)) { + const char *src; + + /* skip the prefix, get the name actually + returned by the nested iterator */ + src = ent->name + prefix_len; + while (*src == '/') + ++src; + + /* reconstruct base path relative file path */ + if (file_prefix == NULL) { + extra = strdup(src); + } else { + size_t fxlen = strlen(file_prefix) + 1; + size_t srclen = strlen(src) + 1; + + extra = malloc(fxlen + srclen); + if (extra != NULL) { + memcpy(extra, file_prefix, fxlen); + memcpy(extra + fxlen, src, srclen); + extra[fxlen - 1] = '/'; + } + } + + if (extra == NULL) { + free(ent); + fputs("out-of-memory\n", stderr); + return -1; + } + } + + n = fstree_add_generic(fs, ent, extra); + free(extra); + free(ent); + + if (n == NULL) { + perror("creating tree node"); + return -1; + } + } + + return 0; +} + int glob_files(fstree_t *fs, const char *filename, size_t line_num, const sqfs_dir_entry_t *ent, const char *basepath, unsigned int glob_flags, @@ -70,6 +146,7 @@ int glob_files(fstree_t *fs, const char *filename, size_t line_num, { bool first_type_flag = true; sqfs_dir_iterator_t *dir = NULL; + const char *file_prefix = NULL; char *prefix = NULL; dir_tree_cfg_t cfg; tree_node_t *root; @@ -155,12 +232,14 @@ int glob_files(fstree_t *fs, const char *filename, size_t line_num, dir = dir_tree_iterator_create(temp, &cfg); free(temp); + + file_prefix = sep->args[0]; } if (dir == NULL) goto fail; - ret = fstree_from_dir(fs, dir); + ret = scan_directory(fs, dir, strlen(cfg.prefix), file_prefix); sqfs_drop(dir); free(prefix); diff --git a/bin/gensquashfs/test/fstree_glob1.c b/bin/gensquashfs/test/fstree_glob1.c index f7a61e0..315ab74 100644 --- a/bin/gensquashfs/test/fstree_glob1.c +++ b/bin/gensquashfs/test/fstree_glob1.c @@ -43,6 +43,10 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/file-size/gnu.tar"); + m = m->next; TEST_NULL(m); } else { @@ -62,12 +66,20 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/format-acceptance/gnu-g.tar"); + m = m->next; TEST_NOT_NULL(m); TEST_STR_EQUAL(m->name, "gnu.tar"); TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/format-acceptance/gnu.tar"); + m = m->next; TEST_NULL(m); } else { @@ -94,6 +106,10 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/large-mtime/gnu.tar"); + m = m->next; TEST_NULL(m); } else { @@ -113,6 +129,10 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/long-paths/gnu.tar"); + m = m->next; TEST_NULL(m); } else { @@ -132,6 +152,10 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/negative-mtime/gnu.tar"); + m = m->next; TEST_NULL(m); } else { @@ -151,30 +175,50 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/sparse-files/gnu-small.tar"); + m = m->next; TEST_NOT_NULL(m); TEST_STR_EQUAL(m->name, "gnu.tar"); TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/sparse-files/gnu.tar"); + m = m->next; TEST_NOT_NULL(m); TEST_STR_EQUAL(m->name, "pax-gnu0-0.tar"); TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/sparse-files/pax-gnu0-0.tar"); + m = m->next; TEST_NOT_NULL(m); TEST_STR_EQUAL(m->name, "pax-gnu0-1.tar"); TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/sparse-files/pax-gnu0-1.tar"); + m = m->next; TEST_NOT_NULL(m); TEST_STR_EQUAL(m->name, "pax-gnu1-0.tar"); TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/sparse-files/pax-gnu1-0.tar"); + m = m->next; TEST_NULL(m); } else { @@ -194,6 +238,10 @@ static void check_hierarchy(tree_node_t *root, bool subdir, bool recursive) TEST_ASSERT(S_ISREG(m->mode)); TEST_ASSERT(m->parent == n); + TEST_NOT_NULL(m->data.file.input_file); + TEST_STR_EQUAL(m->data.file.input_file, + "../../../lib/tar/test/data/user-group-largenum/gnu.tar"); + m = m->next; TEST_NULL(m); } else { |