From 50b67940c793e72656787469ced6e0245bb580b4 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 29 May 2023 20:16:38 +0200 Subject: libfstree: accept dir_entry_t instead of path and struct stat Because the dir_entry_t also has a flag for had links, the regular node and hard-link node interface can be unified. This simplifies the users of libfstree (gensquashfs, tar2sqfs) since we can simply hose the entries from an iterator directly into the tree. Signed-off-by: David Oberhollenzer --- bin/gensquashfs/src/fstree_from_dir.c | 18 +------- bin/gensquashfs/src/fstree_from_file.c | 83 +++++++++++++++++----------------- bin/gensquashfs/src/glob.c | 16 +++---- bin/gensquashfs/src/mkfs.h | 2 +- 4 files changed, 51 insertions(+), 68 deletions(-) (limited to 'bin/gensquashfs') diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c index 6c37ee8..e2558bc 100644 --- a/bin/gensquashfs/src/fstree_from_dir.c +++ b/bin/gensquashfs/src/fstree_from_dir.c @@ -12,22 +12,12 @@ #include #include -static sqfs_u32 clamp_timestamp(sqfs_s64 ts) -{ - if (ts < 0) - return 0; - if (ts > 0x0FFFFFFFFLL) - return 0xFFFFFFFF; - return ts; -} - int fstree_from_dir(fstree_t *fs, dir_iterator_t *dir) { for (;;) { dir_entry_t *ent = NULL; tree_node_t *n = NULL; char *extra = NULL; - struct stat sb; int ret = dir->next(dir, &ent); if (ret > 0) @@ -55,13 +45,7 @@ int fstree_from_dir(fstree_t *fs, dir_iterator_t *dir) } } - memset(&sb, 0, sizeof(sb)); - sb.st_uid = ent->uid; - sb.st_gid = ent->gid; - sb.st_mode = ent->mode; - sb.st_mtime = clamp_timestamp(ent->mtime); - - n = fstree_add_generic(fs, ent->name, &sb, extra); + n = fstree_add_generic(fs, ent, extra); free(extra); free(ent); diff --git a/bin/gensquashfs/src/fstree_from_file.c b/bin/gensquashfs/src/fstree_from_file.c index d4d77a7..dc7181f 100644 --- a/bin/gensquashfs/src/fstree_from_file.c +++ b/bin/gensquashfs/src/fstree_from_file.c @@ -7,11 +7,11 @@ #include "mkfs.h" static int add_generic(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *sb, const char *extra) + dir_entry_t *ent, const char *extra) { - if (fstree_add_generic(fs, path, sb, extra) == NULL) { + if (fstree_add_generic(fs, ent, extra) == NULL) { fprintf(stderr, "%s: " PRI_SZ ": %s: %s\n", - filename, line_num, path, strerror(errno)); + filename, line_num, ent->name, strerror(errno)); return -1; } @@ -19,7 +19,7 @@ static int add_generic(fstree_t *fs, const char *filename, size_t line_num, } static int add_device(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *sb, const char *extra) + dir_entry_t *ent, const char *extra) { unsigned int maj, min; char c; @@ -32,57 +32,44 @@ static int add_device(fstree_t *fs, const char *filename, size_t line_num, } if (c == 'c' || c == 'C') { - sb->st_mode |= S_IFCHR; + ent->mode |= S_IFCHR; } else if (c == 'b' || c == 'B') { - sb->st_mode |= S_IFBLK; + ent->mode |= S_IFBLK; } else { fprintf(stderr, "%s: " PRI_SZ ": unknown device type '%c'\n", filename, line_num, c); return -1; } - sb->st_rdev = makedev(maj, min); - return add_generic(fs, filename, line_num, path, sb, NULL); + ent->rdev = makedev(maj, min); + return add_generic(fs, filename, line_num, ent, NULL); } static int add_file(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *basic, const char *extra) + dir_entry_t *ent, const char *extra) { if (extra == NULL || *extra == '\0') - extra = path; + extra = ent->name; - return add_generic(fs, filename, line_num, path, basic, extra); -} - -static int add_hard_link(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *basic, - const char *extra) -{ - (void)basic; - - if (fstree_add_hard_link(fs, path, extra) == NULL) { - fprintf(stderr, "%s: " PRI_SZ ": %s\n", - filename, line_num, strerror(errno)); - return -1; - } - return 0; + return add_generic(fs, filename, line_num, ent, extra); } static const struct callback_t { const char *keyword; unsigned int mode; + unsigned int flags; bool need_extra; bool allow_root; int (*callback)(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *sb, const char *extra); + dir_entry_t *ent, const char *extra); } file_list_hooks[] = { - { "dir", S_IFDIR, false, true, add_generic }, - { "slink", S_IFLNK, true, false, add_generic }, - { "link", 0, true, false, add_hard_link }, - { "nod", 0, true, false, add_device }, - { "pipe", S_IFIFO, false, false, add_generic }, - { "sock", S_IFSOCK, false, false, add_generic }, - { "file", S_IFREG, false, false, add_file }, + { "dir", S_IFDIR, 0, false, true, add_generic }, + { "slink", S_IFLNK, 0, true, false, add_generic }, + { "link", S_IFLNK, DIR_ENTRY_FLAG_HARD_LINK, true, false, add_generic }, + { "nod", 0, 0, true, false, add_device }, + { "pipe", S_IFIFO, 0, false, false, add_generic }, + { "sock", S_IFSOCK, 0, false, false, add_generic }, + { "file", S_IFREG, 0, false, false, add_file }, }; #define NUM_HOOKS (sizeof(file_list_hooks) / sizeof(file_list_hooks[0])) @@ -161,9 +148,10 @@ static int handle_line(fstree_t *fs, const char *filename, const struct callback_t *cb = NULL; unsigned int glob_flags = 0; sqfs_u32 uid, gid, mode; + dir_entry_t *ent = NULL; bool is_glob = false; - struct stat sb; char *path; + int ret; for (size_t i = 0; i < NUM_HOOKS; ++i) { size_t len = strlen(file_list_hooks[i].keyword); @@ -235,18 +223,29 @@ static int handle_line(fstree_t *fs, const char *filename, goto fail_no_extra; /* forward to callback */ - memset(&sb, 0, sizeof(sb)); - sb.st_mtime = fs->defaults.mtime; - sb.st_mode = mode | (is_glob ? 0 : cb->mode); - sb.st_uid = uid; - sb.st_gid = gid; + ent = alloc_flex(sizeof(*ent), 1, strlen(path) + 1); + if (ent == NULL) + goto fail_alloc; + + strcpy(ent->name, path); + ent->mtime = fs->defaults.mtime; + ent->mode = mode | (is_glob ? 0 : cb->mode); + ent->uid = uid; + ent->gid = gid; if (is_glob) { - return glob_files(fs, filename, line_num, path, &sb, - basepath, glob_flags, extra); + ret = glob_files(fs, filename, line_num, ent, + basepath, glob_flags, extra); + } else { + ret = cb->callback(fs, filename, line_num, ent, extra); } - return cb->callback(fs, filename, line_num, path, &sb, extra); + free(ent); + return ret; +fail_alloc: + fprintf(stderr, "%s: " PRI_SZ ": out of memory\n", + filename, line_num); + return -1; fail_root: fprintf(stderr, "%s: " PRI_SZ ": cannot use / as argument for %s.\n", filename, line_num, is_glob ? "glob" : cb->keyword); diff --git a/bin/gensquashfs/src/glob.c b/bin/gensquashfs/src/glob.c index 8540d81..853ba42 100644 --- a/bin/gensquashfs/src/glob.c +++ b/bin/gensquashfs/src/glob.c @@ -79,7 +79,7 @@ static bool match_option(const char **line, const char *candidate) } int glob_files(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *basic, + const dir_entry_t *ent, const char *basepath, unsigned int glob_flags, const char *extra) { @@ -92,7 +92,7 @@ int glob_files(fstree_t *fs, const char *filename, size_t line_num, int ret; /* fetch the actual target node */ - root = fstree_get_node_by_path(fs, fs->root, path, true, false); + root = fstree_get_node_by_path(fs, fs->root, ent->name, true, false); if (root == NULL) goto fail_path; @@ -165,10 +165,10 @@ int glob_files(fstree_t *fs, const char *filename, size_t line_num, /* do the scan */ memset(&cfg, 0, sizeof(cfg)); cfg.flags = scan_flags | glob_flags; - cfg.def_mtime = basic->st_mtime; - cfg.def_uid = basic->st_uid; - cfg.def_gid = basic->st_gid; - cfg.def_mode = basic->st_mode; + cfg.def_mtime = ent->mtime; + cfg.def_uid = ent->uid; + cfg.def_gid = ent->gid; + cfg.def_mode = ent->mode; cfg.prefix = prefix; cfg.name_pattern = name_pattern; @@ -207,11 +207,11 @@ fail_unknown: goto fail; fail_path: fprintf(stderr, "%s: " PRI_SZ ": %s: %s\n", - filename, line_num, path, strerror(errno)); + filename, line_num, ent->name, strerror(errno)); goto fail; fail_not_dir: fprintf(stderr, "%s: " PRI_SZ ": %s is not a directoy!\n", - filename, line_num, path); + filename, line_num, ent->name); goto fail; fail_prefix: fprintf(stderr, "%s: " PRI_SZ ": error cannonicalizing `%s`!\n", diff --git a/bin/gensquashfs/src/mkfs.h b/bin/gensquashfs/src/mkfs.h index 6c95588..9cb289d 100644 --- a/bin/gensquashfs/src/mkfs.h +++ b/bin/gensquashfs/src/mkfs.h @@ -125,7 +125,7 @@ int fstree_from_dir(fstree_t *fs, dir_iterator_t *dir); int fstree_sort_files(fstree_t *fs, istream_t *sortfile); int glob_files(fstree_t *fs, const char *filename, size_t line_num, - const char *path, struct stat *basic, + const dir_entry_t *ent, const char *basepath, unsigned int glob_flags, const char *extra); -- cgit v1.2.3