From 4390eddccfb3918291e7b8e4d708411f9b828c04 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 29 Apr 2023 03:12:06 +0200 Subject: gensquashfs: use prefix functionality for glob_files target node Piece together the prefix path and pass it to the iterator. That way, we get the full target paths back from the iterator and can use those directly in the callback for filtering. We also no longer need the root node for fstree_from_dir (always tree root) and the callback can no longer return an error state. Signed-off-by: David Oberhollenzer --- bin/gensquashfs/src/fstree_from_dir.c | 9 +++-- bin/gensquashfs/src/fstree_from_file.c | 70 ++++++++-------------------------- bin/gensquashfs/src/mkfs.c | 2 +- bin/gensquashfs/src/mkfs.h | 5 +-- include/fstree.h | 4 -- lib/fstree/src/add_by_path.c | 11 +----- 6 files changed, 26 insertions(+), 75 deletions(-) diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c index b2d27f1..c960430 100644 --- a/bin/gensquashfs/src/fstree_from_dir.c +++ b/bin/gensquashfs/src/fstree_from_dir.c @@ -21,7 +21,7 @@ static sqfs_u32 clamp_timestamp(sqfs_s64 ts) return ts; } -int fstree_from_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir, +int fstree_from_dir(fstree_t *fs, dir_iterator_t *dir, scan_node_callback cb, void *user) { for (;;) { @@ -38,12 +38,13 @@ int fstree_from_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir, return -1; } - n = fstree_get_node_by_path(fs, root, ent->name, false, true); + n = fstree_get_node_by_path(fs, fs->root, ent->name, + false, true); if (n == NULL) ret = 1; if (ret == 0 && cb != NULL) - ret = cb(user, root, ent); + ret = cb(user, ent); if (ret < 0) { free(ent); @@ -72,7 +73,7 @@ int fstree_from_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir, sb.st_mode = ent->mode; sb.st_mtime = clamp_timestamp(ent->mtime); - n = fstree_add_generic_at(fs, root, ent->name, &sb, extra); + n = fstree_add_generic(fs, ent->name, &sb, extra); free(extra); free(ent); diff --git a/bin/gensquashfs/src/fstree_from_file.c b/bin/gensquashfs/src/fstree_from_file.c index 8f1b50b..4cdfe66 100644 --- a/bin/gensquashfs/src/fstree_from_file.c +++ b/bin/gensquashfs/src/fstree_from_file.c @@ -18,11 +18,7 @@ #include struct glob_context { - const char *filename; - size_t line_num; - unsigned int glob_flags; - char *name_pattern; }; @@ -122,54 +118,15 @@ static int add_hard_link(fstree_t *fs, const char *filename, size_t line_num, return 0; } -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) +static int glob_node_callback(void *user, dir_entry_t *ent) { struct glob_context *ctx = user; int ret; if (ctx->name_pattern != NULL) { if (ctx->glob_flags & GLOB_FLAG_PATH) { - char *path = full_path(root, ent); - if (path == NULL) - goto fail_alloc; - ret = fnmatch(ctx->name_pattern, path, FNM_PATHNAME); - free(path); + ret = fnmatch(ctx->name_pattern, + ent->name, FNM_PATHNAME); } else { const char *name = strrchr(ent->name, '/'); name = (name == NULL) ? ent->name : (name + 1); @@ -182,10 +139,6 @@ static int glob_node_callback(void *user, tree_node_t *root, dir_entry_t *ent) } 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) @@ -236,11 +189,10 @@ static int glob_files(fstree_t *fs, const char *filename, size_t line_num, size_t i, count, len; dir_tree_cfg_t cfg; tree_node_t *root; + char *prefix; int ret; memset(&ctx, 0, sizeof(ctx)); - ctx.filename = filename; - ctx.line_num = line_num; ctx.glob_flags = glob_flags; /* fetch the actual target node */ @@ -257,6 +209,14 @@ static int glob_files(fstree_t *fs, const char *filename, size_t line_num, return -1; } + prefix = fstree_get_path(root); + if (canonicalize_name(prefix) != 0) { + fprintf(stderr, "%s: " PRI_SZ ": error cannonicalizing `%s`!\n", + filename, line_num, prefix); + free(prefix); + return -1; + } + /* process options */ first_clear_flag = true; @@ -338,6 +298,7 @@ static int glob_files(fstree_t *fs, const char *filename, size_t line_num, fprintf(stderr, "%s: " PRI_SZ ": unknown option.\n", filename, line_num); free(ctx.name_pattern); + free(prefix); return -1; } else { break; @@ -354,6 +315,7 @@ static int glob_files(fstree_t *fs, const char *filename, size_t line_num, cfg.def_uid = basic->st_uid; cfg.def_gid = basic->st_gid; cfg.def_mode = basic->st_mode; + cfg.prefix = prefix; if (basepath == NULL) { dir = dir_tree_iterator_create(extra == NULL ? "." : extra, @@ -379,14 +341,14 @@ static int glob_files(fstree_t *fs, const char *filename, size_t line_num, } if (dir != NULL) { - ret = fstree_from_dir(fs, root, dir, - glob_node_callback, &ctx); + ret = fstree_from_dir(fs, dir, glob_node_callback, &ctx); sqfs_drop(dir); } else { ret = -1; } free(ctx.name_pattern); + free(prefix); return ret; } diff --git a/bin/gensquashfs/src/mkfs.c b/bin/gensquashfs/src/mkfs.c index 051b6ac..8ad394b 100644 --- a/bin/gensquashfs/src/mkfs.c +++ b/bin/gensquashfs/src/mkfs.c @@ -179,7 +179,7 @@ int main(int argc, char **argv) if (dir == NULL) goto out; - ret = fstree_from_dir(&sqfs.fs, sqfs.fs.root, dir, NULL, NULL); + ret = fstree_from_dir(&sqfs.fs, dir, NULL, NULL); sqfs_drop(dir); if (ret != 0) goto out; diff --git a/bin/gensquashfs/src/mkfs.h b/bin/gensquashfs/src/mkfs.h index 6923164..3157694 100644 --- a/bin/gensquashfs/src/mkfs.h +++ b/bin/gensquashfs/src/mkfs.h @@ -49,8 +49,7 @@ 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, tree_node_t *root, - dir_entry_t *ent); +typedef int (*scan_node_callback)(void *user, dir_entry_t *ent); typedef struct { sqfs_writer_cfg_t cfg; @@ -130,7 +129,7 @@ int fstree_from_file_stream(fstree_t *fs, istream_t *file, Returns 0 on success, prints to stderr on failure. */ -int fstree_from_dir(fstree_t *fs, tree_node_t *root, dir_iterator_t *dir, +int fstree_from_dir(fstree_t *fs, dir_iterator_t *dir, scan_node_callback cb, void *user); int fstree_sort_files(fstree_t *fs, istream_t *sortfile); diff --git a/include/fstree.h b/include/fstree.h index ccd1bcc..96ddf8f 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -160,10 +160,6 @@ tree_node_t *fstree_mknode(tree_node_t *parent, const char *name, tree_node_t *fstree_add_generic(fstree_t *fs, const char *path, const struct stat *sb, const char *extra); -tree_node_t *fstree_add_generic_at(fstree_t *fs, tree_node_t *root, - const char *path, const struct stat *sb, - const char *extra); - /* This function performs all the necessary post processing steps on the file system tree, i.e. recursively sorting all directory entries by name, diff --git a/lib/fstree/src/add_by_path.c b/lib/fstree/src/add_by_path.c index f204836..344b586 100644 --- a/lib/fstree/src/add_by_path.c +++ b/lib/fstree/src/add_by_path.c @@ -14,24 +14,17 @@ tree_node_t *fstree_add_generic(fstree_t *fs, const char *path, const struct stat *sb, const char *extra) -{ - return fstree_add_generic_at(fs, fs->root, path, sb, extra); -} - -tree_node_t *fstree_add_generic_at(fstree_t *fs, tree_node_t *root, - const char *path, const struct stat *sb, - const char *extra) { tree_node_t *child, *parent; const char *name; if (*path == '\0') { - child = root; + child = fs->root; assert(child != NULL); goto out; } - parent = fstree_get_node_by_path(fs, root, path, true, true); + parent = fstree_get_node_by_path(fs, fs->root, path, true, true); if (parent == NULL) return NULL; -- cgit v1.2.3