aboutsummaryrefslogtreecommitdiff
path: root/bin/gensquashfs/src
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-05-28 16:33:21 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-05-30 12:22:56 +0200
commit5197d47639146111bfb365fd543c83c539c8a9c5 (patch)
treed4e47d1c06c1ffd882bba3461f65e34fe9c649ac /bin/gensquashfs/src
parent6351872732fce77186f401050eee92c7c3aa3461 (diff)
gensquashfs: split glob related code from fstree_from_file.c
The glob function and everything associated is moved to a separate file, the entry point exposed any the special case handling is removed from the other callbacks in fstree_from_file.c Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin/gensquashfs/src')
-rw-r--r--bin/gensquashfs/src/fstree_from_file.c312
-rw-r--r--bin/gensquashfs/src/glob.c233
-rw-r--r--bin/gensquashfs/src/mkfs.h5
3 files changed, 273 insertions, 277 deletions
diff --git a/bin/gensquashfs/src/fstree_from_file.c b/bin/gensquashfs/src/fstree_from_file.c
index 318c129..d4d77a7 100644
--- a/bin/gensquashfs/src/fstree_from_file.c
+++ b/bin/gensquashfs/src/fstree_from_file.c
@@ -4,45 +4,11 @@
*
* Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
*/
-#include "config.h"
-
-#include "util/util.h"
-#include "io/file.h"
-#include "compat.h"
#include "mkfs.h"
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-static const struct {
- const char *name;
- unsigned int clear_flag;
- unsigned int set_flag;
-} glob_scan_flags[] = {
- { "-type b", DIR_SCAN_NO_BLK, 0 },
- { "-type c", DIR_SCAN_NO_CHR, 0 },
- { "-type d", DIR_SCAN_NO_DIR, 0 },
- { "-type p", DIR_SCAN_NO_FIFO, 0 },
- { "-type f", DIR_SCAN_NO_FILE, 0 },
- { "-type l", DIR_SCAN_NO_SLINK, 0 },
- { "-type s", DIR_SCAN_NO_SOCK, 0 },
- { "-xdev", 0, DIR_SCAN_ONE_FILESYSTEM },
- { "-mount", 0, DIR_SCAN_ONE_FILESYSTEM },
- { "-keeptime", 0, DIR_SCAN_KEEP_TIME },
- { "-nonrecursive", 0, DIR_SCAN_NO_RECURSION },
-};
-
static int add_generic(fstree_t *fs, const char *filename, size_t line_num,
- const char *path, struct stat *sb,
- const char *basepath, unsigned int glob_flags,
- const char *extra)
+ const char *path, struct stat *sb, const char *extra)
{
- (void)basepath;
- (void)glob_flags;
-
if (fstree_add_generic(fs, path, sb, extra) == NULL) {
fprintf(stderr, "%s: " PRI_SZ ": %s: %s\n",
filename, line_num, path, strerror(errno));
@@ -53,8 +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 *basepath,
- unsigned int glob_flags, const char *extra)
+ const char *path, struct stat *sb, const char *extra)
{
unsigned int maj, min;
char c;
@@ -77,28 +42,22 @@ static int add_device(fstree_t *fs, const char *filename, size_t line_num,
}
sb->st_rdev = makedev(maj, min);
- return add_generic(fs, filename, line_num, path, sb, basepath,
- glob_flags, NULL);
+ return add_generic(fs, filename, line_num, path, sb, NULL);
}
static int add_file(fstree_t *fs, const char *filename, size_t line_num,
- const char *path, struct stat *basic, const char *basepath,
- unsigned int glob_flags, const char *extra)
+ const char *path, struct stat *basic, const char *extra)
{
if (extra == NULL || *extra == '\0')
extra = path;
- return add_generic(fs, filename, line_num, path, basic,
- basepath, glob_flags, extra);
+ 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 *basepath, unsigned int glob_flags,
const char *extra)
{
- (void)basepath;
- (void)glob_flags;
(void)basic;
if (fstree_add_hard_link(fs, path, extra) == NULL) {
@@ -109,233 +68,21 @@ static int add_hard_link(fstree_t *fs, const char *filename, size_t line_num,
return 0;
}
-static size_t name_string_length(const char *str)
-{
- size_t len = 0;
- int start;
-
- if (*str == '"' || *str == '\'') {
- start = *str;
- ++len;
-
- while (str[len] != '\0' && str[len] != start)
- ++len;
-
- if (str[len] == start)
- ++len;
- } else {
- while (str[len] != '\0' && !isspace(str[len]))
- ++len;
- }
-
- return len;
-}
-
-static void quote_remove(char *str)
-{
- char *dst = str;
- int start = *(str++);
-
- if (start != '\'' && start != '"')
- return;
-
- while (*str != start && *str != '\0')
- *(dst++) = *(str++);
-
- *(dst++) = '\0';
-}
-
-static int glob_files(fstree_t *fs, const char *filename, size_t line_num,
- const char *path, struct stat *basic,
- const char *basepath, unsigned int glob_flags,
- const char *extra)
-{
- char *name_pattern = NULL, *prefix = NULL;
- unsigned int scan_flags = 0, all_flags;
- dir_iterator_t *dir = NULL;
- bool first_clear_flag;
- size_t i, count, len;
- dir_tree_cfg_t cfg;
- tree_node_t *root;
- int ret;
-
- /* fetch the actual target node */
- root = fstree_get_node_by_path(fs, fs->root, path, true, false);
- if (root == NULL) {
- fprintf(stderr, "%s: " PRI_SZ ": %s: %s\n",
- filename, line_num, path, strerror(errno));
- return -1;
- }
-
- if (!S_ISDIR(root->mode)) {
- fprintf(stderr, "%s: " PRI_SZ ": %s is not a directoy!\n",
- filename, line_num, path);
- 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;
-
- all_flags = DIR_SCAN_NO_BLK | DIR_SCAN_NO_CHR | DIR_SCAN_NO_DIR |
- DIR_SCAN_NO_FIFO | DIR_SCAN_NO_FILE | DIR_SCAN_NO_SLINK |
- DIR_SCAN_NO_SOCK;
-
- while (extra != NULL && *extra != '\0') {
- count = sizeof(glob_scan_flags) / sizeof(glob_scan_flags[0]);
-
- for (i = 0; i < count; ++i) {
- len = strlen(glob_scan_flags[i].name);
- if (strncmp(extra, glob_scan_flags[i].name, len) != 0)
- continue;
-
- if (isspace(extra[len])) {
- extra += len;
- while (isspace(*extra))
- ++extra;
- break;
- }
- }
-
- if (i < count) {
- if (glob_scan_flags[i].clear_flag != 0 &&
- first_clear_flag) {
- scan_flags |= all_flags;
- first_clear_flag = false;
- }
-
- scan_flags &= ~(glob_scan_flags[i].clear_flag);
- scan_flags |= glob_scan_flags[i].set_flag;
- continue;
- }
-
- if (strncmp(extra, "-name", 5) == 0 && isspace(extra[5])) {
- for (extra += 5; isspace(*extra); ++extra)
- ;
-
- len = name_string_length(extra);
-
- free(name_pattern);
- name_pattern = strndup(extra, len);
- extra += len;
-
- while (isspace(*extra))
- ++extra;
-
- quote_remove(name_pattern);
- continue;
- }
-
- if (strncmp(extra, "-path", 5) == 0 && isspace(extra[5])) {
- for (extra += 5; isspace(*extra); ++extra)
- ;
-
- len = name_string_length(extra);
-
- free(name_pattern);
- name_pattern = strndup(extra, len);
- extra += len;
-
- while (isspace(*extra))
- ++extra;
-
- quote_remove(name_pattern);
- glob_flags |= DIR_SCAN_MATCH_FULL_PATH;
- continue;
- }
-
- if (extra[0] == '-') {
- if (extra[1] == '-' && isspace(extra[2])) {
- extra += 2;
- while (isspace(*extra))
- ++extra;
- break;
- }
-
- fprintf(stderr, "%s: " PRI_SZ ": unknown option.\n",
- filename, line_num);
- free(name_pattern);
- free(prefix);
- return -1;
- } else {
- break;
- }
- }
-
- if (extra != NULL && *extra == '\0')
- extra = NULL;
-
- /* 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.prefix = prefix;
- cfg.name_pattern = name_pattern;
-
- if (basepath == NULL) {
- dir = dir_tree_iterator_create(extra == NULL ? "." : extra,
- &cfg);
- } else {
- size_t plen = strlen(basepath);
- size_t slen = strlen(extra);
- char *temp = calloc(1, plen + 1 + slen + 1);
-
- if (temp == NULL) {
- fprintf(stderr, "%s: " PRI_SZ ": allocation failure.\n",
- filename, line_num);
- } else {
- memcpy(temp, basepath, plen);
- temp[plen] = '/';
- memcpy(temp + plen + 1, extra, slen);
- temp[plen + 1 + slen] = '\0';
-
- dir = dir_tree_iterator_create(temp, &cfg);
- }
-
- free(temp);
- }
-
- if (dir != NULL) {
- ret = fstree_from_dir(fs, dir);
- sqfs_drop(dir);
- } else {
- ret = -1;
- }
-
- free(name_pattern);
- free(prefix);
- return ret;
-}
-
static const struct callback_t {
const char *keyword;
unsigned int mode;
bool need_extra;
- bool is_glob;
bool allow_root;
int (*callback)(fstree_t *fs, const char *filename, size_t line_num,
- const char *path, struct stat *sb,
- const char *basepath, unsigned int glob_flags,
- const char *extra);
+ const char *path, struct stat *sb, const char *extra);
} file_list_hooks[] = {
- { "dir", S_IFDIR, false, false, true, add_generic },
- { "slink", S_IFLNK, true, false, false, add_generic },
- { "link", 0, true, false, false, add_hard_link },
- { "nod", 0, true, false, false, add_device },
- { "pipe", S_IFIFO, false, false, false, add_generic },
- { "sock", S_IFSOCK, false, false, false, add_generic },
- { "file", S_IFREG, false, false, false, add_file },
- { "glob", 0, false, true, true, glob_files },
+ { "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 },
};
#define NUM_HOOKS (sizeof(file_list_hooks) / sizeof(file_list_hooks[0]))
@@ -414,6 +161,7 @@ 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;
+ bool is_glob = false;
struct stat sb;
char *path;
@@ -429,8 +177,14 @@ static int handle_line(fstree_t *fs, const char *filename,
}
}
- if (cb == NULL)
- goto fail_kw;
+ if (cb == NULL) {
+ if (strncmp("glob", line, 4) == 0 && isspace(line[4])) {
+ line = skip_space(line + 4);
+ is_glob = true;
+ } else {
+ goto fail_kw;
+ }
+ }
if ((line = read_str(line, &path)) == NULL)
goto fail_ent;
@@ -438,10 +192,10 @@ static int handle_line(fstree_t *fs, const char *filename,
if (canonicalize_name(path))
goto fail_ent;
- if (*path == '\0' && !cb->allow_root)
+ if (*path == '\0' && !(is_glob || cb->allow_root))
goto fail_root;
- if (cb->is_glob && *line == '*') {
+ if (is_glob && *line == '*') {
++line;
mode = 0;
glob_flags |= DIR_SCAN_KEEP_MODE;
@@ -453,7 +207,7 @@ static int handle_line(fstree_t *fs, const char *filename,
if ((line = skip_space(line)) == NULL)
goto fail_ent;
- if (cb->is_glob && *line == '*') {
+ if (is_glob && *line == '*') {
++line;
uid = 0;
glob_flags |= DIR_SCAN_KEEP_UID;
@@ -465,7 +219,7 @@ static int handle_line(fstree_t *fs, const char *filename,
if ((line = skip_space(line)) == NULL)
goto fail_ent;
- if (cb->is_glob && *line == '*') {
+ if (is_glob && *line == '*') {
++line;
gid = 0;
glob_flags |= DIR_SCAN_KEEP_GID;
@@ -477,21 +231,25 @@ static int handle_line(fstree_t *fs, const char *filename,
if ((line = skip_space(line)) != NULL && *line != '\0')
extra = line;
- if (cb->need_extra && extra == NULL)
+ if (!is_glob && cb->need_extra && extra == NULL)
goto fail_no_extra;
/* forward to callback */
memset(&sb, 0, sizeof(sb));
sb.st_mtime = fs->defaults.mtime;
- sb.st_mode = mode | cb->mode;
+ sb.st_mode = mode | (is_glob ? 0 : cb->mode);
sb.st_uid = uid;
sb.st_gid = gid;
- return cb->callback(fs, filename, line_num, path,
- &sb, basepath, glob_flags, extra);
+ if (is_glob) {
+ return glob_files(fs, filename, line_num, path, &sb,
+ basepath, glob_flags, extra);
+ }
+
+ return cb->callback(fs, filename, line_num, path, &sb, extra);
fail_root:
fprintf(stderr, "%s: " PRI_SZ ": cannot use / as argument for %s.\n",
- filename, line_num, cb->keyword);
+ filename, line_num, is_glob ? "glob" : cb->keyword);
return -1;
fail_no_extra:
fprintf(stderr, "%s: " PRI_SZ ": missing argument for %s.\n",
diff --git a/bin/gensquashfs/src/glob.c b/bin/gensquashfs/src/glob.c
new file mode 100644
index 0000000..c95d06d
--- /dev/null
+++ b/bin/gensquashfs/src/glob.c
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * glob.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "mkfs.h"
+
+static const struct {
+ const char *name;
+ unsigned int clear_flag;
+ unsigned int set_flag;
+} glob_scan_flags[] = {
+ { "-type b", DIR_SCAN_NO_BLK, 0 },
+ { "-type c", DIR_SCAN_NO_CHR, 0 },
+ { "-type d", DIR_SCAN_NO_DIR, 0 },
+ { "-type p", DIR_SCAN_NO_FIFO, 0 },
+ { "-type f", DIR_SCAN_NO_FILE, 0 },
+ { "-type l", DIR_SCAN_NO_SLINK, 0 },
+ { "-type s", DIR_SCAN_NO_SOCK, 0 },
+ { "-xdev", 0, DIR_SCAN_ONE_FILESYSTEM },
+ { "-mount", 0, DIR_SCAN_ONE_FILESYSTEM },
+ { "-keeptime", 0, DIR_SCAN_KEEP_TIME },
+ { "-nonrecursive", 0, DIR_SCAN_NO_RECURSION },
+};
+
+static size_t name_string_length(const char *str)
+{
+ size_t len = 0;
+ int start;
+
+ if (*str == '"' || *str == '\'') {
+ start = *str;
+ ++len;
+
+ while (str[len] != '\0' && str[len] != start)
+ ++len;
+
+ if (str[len] == start)
+ ++len;
+ } else {
+ while (str[len] != '\0' && !isspace(str[len]))
+ ++len;
+ }
+
+ return len;
+}
+
+static void quote_remove(char *str)
+{
+ char *dst = str;
+ int start = *(str++);
+
+ if (start != '\'' && start != '"')
+ return;
+
+ while (*str != start && *str != '\0')
+ *(dst++) = *(str++);
+
+ *(dst++) = '\0';
+}
+
+int glob_files(fstree_t *fs, const char *filename, size_t line_num,
+ const char *path, struct stat *basic,
+ const char *basepath, unsigned int glob_flags,
+ const char *extra)
+{
+ char *name_pattern = NULL, *prefix = NULL;
+ unsigned int scan_flags = 0, all_flags;
+ dir_iterator_t *dir = NULL;
+ bool first_clear_flag;
+ size_t i, count, len;
+ dir_tree_cfg_t cfg;
+ tree_node_t *root;
+ int ret;
+
+ /* fetch the actual target node */
+ root = fstree_get_node_by_path(fs, fs->root, path, true, false);
+ if (root == NULL) {
+ fprintf(stderr, "%s: " PRI_SZ ": %s: %s\n",
+ filename, line_num, path, strerror(errno));
+ return -1;
+ }
+
+ if (!S_ISDIR(root->mode)) {
+ fprintf(stderr, "%s: " PRI_SZ ": %s is not a directoy!\n",
+ filename, line_num, path);
+ 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;
+
+ all_flags = DIR_SCAN_NO_BLK | DIR_SCAN_NO_CHR | DIR_SCAN_NO_DIR |
+ DIR_SCAN_NO_FIFO | DIR_SCAN_NO_FILE | DIR_SCAN_NO_SLINK |
+ DIR_SCAN_NO_SOCK;
+
+ while (extra != NULL && *extra != '\0') {
+ count = sizeof(glob_scan_flags) / sizeof(glob_scan_flags[0]);
+
+ for (i = 0; i < count; ++i) {
+ len = strlen(glob_scan_flags[i].name);
+ if (strncmp(extra, glob_scan_flags[i].name, len) != 0)
+ continue;
+
+ if (isspace(extra[len])) {
+ extra += len;
+ while (isspace(*extra))
+ ++extra;
+ break;
+ }
+ }
+
+ if (i < count) {
+ if (glob_scan_flags[i].clear_flag != 0 &&
+ first_clear_flag) {
+ scan_flags |= all_flags;
+ first_clear_flag = false;
+ }
+
+ scan_flags &= ~(glob_scan_flags[i].clear_flag);
+ scan_flags |= glob_scan_flags[i].set_flag;
+ continue;
+ }
+
+ if (strncmp(extra, "-name", 5) == 0 && isspace(extra[5])) {
+ for (extra += 5; isspace(*extra); ++extra)
+ ;
+
+ len = name_string_length(extra);
+
+ free(name_pattern);
+ name_pattern = strndup(extra, len);
+ extra += len;
+
+ while (isspace(*extra))
+ ++extra;
+
+ quote_remove(name_pattern);
+ continue;
+ }
+
+ if (strncmp(extra, "-path", 5) == 0 && isspace(extra[5])) {
+ for (extra += 5; isspace(*extra); ++extra)
+ ;
+
+ len = name_string_length(extra);
+
+ free(name_pattern);
+ name_pattern = strndup(extra, len);
+ extra += len;
+
+ while (isspace(*extra))
+ ++extra;
+
+ quote_remove(name_pattern);
+ glob_flags |= DIR_SCAN_MATCH_FULL_PATH;
+ continue;
+ }
+
+ if (extra[0] == '-') {
+ if (extra[1] == '-' && isspace(extra[2])) {
+ extra += 2;
+ while (isspace(*extra))
+ ++extra;
+ break;
+ }
+
+ fprintf(stderr, "%s: " PRI_SZ ": unknown option.\n",
+ filename, line_num);
+ free(name_pattern);
+ free(prefix);
+ return -1;
+ } else {
+ break;
+ }
+ }
+
+ if (extra != NULL && *extra == '\0')
+ extra = NULL;
+
+ /* 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.prefix = prefix;
+ cfg.name_pattern = name_pattern;
+
+ if (basepath == NULL) {
+ dir = dir_tree_iterator_create(extra == NULL ? "." : extra,
+ &cfg);
+ } else {
+ size_t plen = strlen(basepath);
+ size_t slen = strlen(extra);
+ char *temp = calloc(1, plen + 1 + slen + 1);
+
+ if (temp == NULL) {
+ fprintf(stderr, "%s: " PRI_SZ ": allocation failure.\n",
+ filename, line_num);
+ } else {
+ memcpy(temp, basepath, plen);
+ temp[plen] = '/';
+ memcpy(temp + plen + 1, extra, slen);
+ temp[plen + 1 + slen] = '\0';
+
+ dir = dir_tree_iterator_create(temp, &cfg);
+ }
+
+ free(temp);
+ }
+
+ if (dir != NULL) {
+ ret = fstree_from_dir(fs, dir);
+ sqfs_drop(dir);
+ } else {
+ ret = -1;
+ }
+
+ free(name_pattern);
+ free(prefix);
+ return ret;
+}
diff --git a/bin/gensquashfs/src/mkfs.h b/bin/gensquashfs/src/mkfs.h
index 9205b7b..6c95588 100644
--- a/bin/gensquashfs/src/mkfs.h
+++ b/bin/gensquashfs/src/mkfs.h
@@ -124,4 +124,9 @@ 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 char *basepath, unsigned int glob_flags,
+ const char *extra);
+
#endif /* MKFS_H */