aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/gensquashfs/src/fstree_from_dir.c9
-rw-r--r--bin/gensquashfs/src/glob.c81
-rw-r--r--bin/gensquashfs/test/fstree_glob1.c48
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 {