From 46b01473eee7301cb7b49533af16abe0ee15c286 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 28 Apr 2023 17:06:06 +0200 Subject: 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 --- bin/gensquashfs/src/fstree_from_dir.c | 43 ++++++-------------- bin/gensquashfs/src/fstree_from_file.c | 71 +++++++++++++++++++++++++--------- bin/gensquashfs/src/mkfs.h | 3 +- 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; -- cgit v1.2.3