aboutsummaryrefslogtreecommitdiff
path: root/bin/gensquashfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-28 17:06:06 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-04-29 00:26:32 +0200
commit46b01473eee7301cb7b49533af16abe0ee15c286 (patch)
tree38b16209b29f6ac95e537ea411db1174242925b5 /bin/gensquashfs
parent935d4186952e4e4f544ddb20d8f7e4c2657ecb63 (diff)
gensquashfs: Move the scan_dir callback before creating the node
This way, we can remove the discard_node function and simplify the scan_dir code further. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin/gensquashfs')
-rw-r--r--bin/gensquashfs/src/fstree_from_dir.c43
-rw-r--r--bin/gensquashfs/src/fstree_from_file.c71
-rw-r--r--bin/gensquashfs/src/mkfs.h3
3 files changed, 66 insertions, 51 deletions
diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c
index 25a6bd7..22493c5 100644
--- a/bin/gensquashfs/src/fstree_from_dir.c
+++ b/bin/gensquashfs/src/fstree_from_dir.c
@@ -21,25 +21,6 @@ static sqfs_u32 clamp_timestamp(sqfs_s64 ts)
return ts;
}
-static void discard_node(tree_node_t *root, tree_node_t *n)
-{
- tree_node_t *it;
-
- if (n == root->data.children) {
- root->data.children = n->next;
- } else {
- it = root->data.children;
-
- while (it != NULL && it->next != n)
- it = it->next;
-
- if (it != NULL)
- it->next = n->next;
- }
-
- free(n);
-}
-
static int scan_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir,
scan_node_callback cb, void *user)
{
@@ -58,7 +39,18 @@ static int scan_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir,
}
n = fstree_get_node_by_path(fs, root, ent->name, false, true);
- if (n == NULL) {
+ if (n == NULL)
+ ret = 1;
+
+ if (ret == 0 && cb != NULL)
+ ret = cb(user, root, ent);
+
+ if (ret < 0) {
+ free(ent);
+ return -1;
+ }
+
+ if (ret > 0) {
if (S_ISDIR(ent->mode))
dir_tree_iterator_skip(dir);
free(ent);
@@ -88,17 +80,6 @@ static int scan_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir,
perror("creating tree node");
return -1;
}
-
- ret = (cb == NULL) ? 0 : cb(user, fs, n);
-
- if (ret < 0)
- return -1;
-
- if (ret > 0) {
- if (S_ISDIR(n->mode))
- dir_tree_iterator_skip(dir);
- discard_node(n->parent, n);
- }
}
return 0;
diff --git a/bin/gensquashfs/src/fstree_from_file.c b/bin/gensquashfs/src/fstree_from_file.c
index 34fcf83..e75c819 100644
--- a/bin/gensquashfs/src/fstree_from_file.c
+++ b/bin/gensquashfs/src/fstree_from_file.c
@@ -126,41 +126,70 @@ static int add_hard_link(fstree_t *fs, const char *filename, size_t line_num,
return 0;
}
-static int glob_node_callback(void *user, fstree_t *fs, tree_node_t *node)
+static char *full_path(tree_node_t *root, dir_entry_t *ent)
+{
+ char *path = NULL, *new = NULL;
+ size_t plen = 0, slen = 0;
+
+ if (root->parent == NULL)
+ return strdup(ent->name);
+
+ path = fstree_get_path(root);
+ if (path == NULL)
+ return NULL;
+
+ if (canonicalize_name(path) != 0)
+ goto fail;
+
+ plen = strlen(path);
+ slen = strlen(ent->name) + 1;
+
+ if (plen == 0) {
+ free(path);
+ return strdup(ent->name);
+ }
+
+ new = realloc(path, plen + 1 + slen + 1);
+ if (new == NULL)
+ goto fail;
+ path = new;
+
+ path[plen] = '/';
+ memcpy(path + plen + 1, ent->name, slen + 1);
+ return path;
+fail:
+ free(path);
+ return NULL;
+}
+
+static int glob_node_callback(void *user, tree_node_t *root, dir_entry_t *ent)
{
struct glob_context *ctx = user;
- char *path;
int ret;
- (void)fs;
if (!(ctx->glob_flags & GLOB_MODE_FROM_SRC)) {
- node->mode &= ~(07777);
- node->mode |= ctx->basic->st_mode & 07777;
+ ent->mode &= ~(07777);
+ ent->mode |= ctx->basic->st_mode & 07777;
}
if (!(ctx->glob_flags & GLOB_UID_FROM_SRC))
- node->uid = ctx->basic->st_uid;
+ ent->uid = ctx->basic->st_uid;
if (!(ctx->glob_flags & GLOB_GID_FROM_SRC))
- node->gid = ctx->basic->st_gid;
+ ent->gid = ctx->basic->st_gid;
if (ctx->name_pattern != NULL) {
if (ctx->glob_flags & GLOB_FLAG_PATH) {
- path = fstree_get_path(node);
- if (path == NULL) {
- fprintf(stderr, "%s: " PRI_SZ ": %s\n",
- ctx->filename, ctx->line_num,
- strerror(errno));
- return -1;
- }
-
- ret = canonicalize_name(path);
- assert(ret == 0);
-
+ char *path = full_path(root, ent);
+ if (path == NULL)
+ goto fail_alloc;
ret = fnmatch(ctx->name_pattern, path, FNM_PATHNAME);
free(path);
} else {
- ret = fnmatch(ctx->name_pattern, node->name, 0);
+ const char *name = strrchr(ent->name, '/');
+ name = (name == NULL) ? ent->name : (name + 1);
+
+ ret = fnmatch(ctx->name_pattern, name, 0);
}
if (ret != 0)
@@ -168,6 +197,10 @@ static int glob_node_callback(void *user, fstree_t *fs, tree_node_t *node)
}
return 0;
+fail_alloc:
+ fprintf(stderr, "%s: " PRI_SZ ": allocation failure\n",
+ ctx->filename, ctx->line_num);
+ return -1;
}
static size_t name_string_length(const char *str)
diff --git a/bin/gensquashfs/src/mkfs.h b/bin/gensquashfs/src/mkfs.h
index 5bcdd16..9064a75 100644
--- a/bin/gensquashfs/src/mkfs.h
+++ b/bin/gensquashfs/src/mkfs.h
@@ -49,7 +49,8 @@
If it returns a value > 0, the new node is discarded, if < 0, scanning is
aborted and returns a failure status.
*/
-typedef int (*scan_node_callback)(void *user, fstree_t *fs, tree_node_t *node);
+typedef int (*scan_node_callback)(void *user, tree_node_t *root,
+ dir_entry_t *ent);
typedef struct {
sqfs_writer_cfg_t cfg;