diff options
-rw-r--r-- | include/fstree.h | 9 | ||||
-rw-r--r-- | lib/fstree/fstree_from_dir.c | 48 |
2 files changed, 48 insertions, 9 deletions
diff --git a/include/fstree.h b/include/fstree.h index 193cecb..e5fc966 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -254,4 +254,13 @@ int fstree_resolve_hard_link(fstree_t *fs, tree_node_t *node); int fstree_from_dir(fstree_t *fs, tree_node_t *root, const char *path, unsigned int flags); +/* + Same as fstree_from_dir, but scans a sub-directory inside the specified path. + + Returns 0 on success, prints to stderr on failure. + */ +int fstree_from_subdir(fstree_t *fs, tree_node_t *root, + const char *path, const char *subdir, + unsigned int flags); + #endif /* FSTREE_H */ diff --git a/lib/fstree/fstree_from_dir.c b/lib/fstree/fstree_from_dir.c index fe12b24..d3e188d 100644 --- a/lib/fstree/fstree_from_dir.c +++ b/lib/fstree/fstree_from_dir.c @@ -13,13 +13,20 @@ #include <errno.h> #ifdef _WIN32 -int fstree_from_dir(fstree_t *fs, tree_node_t *root, - const char *path, unsigned int flags) +int fstree_from_subdir(fstree_t *fs, tree_node_t *root, + const char *path, const char *subdir, + unsigned int flags) { - (void)fs; (void)root; (void)path; (void)flags; + (void)fs; (void)root; (void)path; (void)subdir; (void)flags; fputs("Packing a directory is not supported on Windows.\n", stderr); return -1; } + +int fstree_from_dir(fstree_t *fs, tree_node_t *root, + const char *path, unsigned int flags) +{ + return fstree_from_subdir(fs, root, path, NULL, flags); +} #else static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root, dev_t devstart, unsigned int flags) @@ -150,16 +157,17 @@ fail: return -1; } -int fstree_from_dir(fstree_t *fs, tree_node_t *root, - const char *path, unsigned int flags) +int fstree_from_subdir(fstree_t *fs, tree_node_t *root, + const char *path, const char *subdir, + unsigned int flags) { struct stat sb; - int fd; + int fd, subfd; if (!S_ISDIR(root->mode)) { fprintf(stderr, - "scanning %s into %s: target is not a directory\n", - path, root->name); + "scanning %s/%s into %s: target is not a directory\n", + path, subdir == NULL ? "" : subdir, root->name); return -1; } @@ -169,12 +177,34 @@ int fstree_from_dir(fstree_t *fs, tree_node_t *root, return -1; } + if (subdir != NULL) { + subfd = openat(fd, subdir, O_DIRECTORY | O_RDONLY | O_CLOEXEC); + + if (subfd < 0) { + fprintf(stderr, "%s/%s: %s\n", path, subdir, + strerror(errno)); + close(fd); + return -1; + } + + close(fd); + fd = subfd; + } + if (fstat(fd, &sb)) { - perror(path); + fprintf(stderr, "%s/%s: %s\n", path, + subdir == NULL ? "" : subdir, + strerror(errno)); close(fd); return -1; } return populate_dir(fd, fs, root, sb.st_dev, flags); } + +int fstree_from_dir(fstree_t *fs, tree_node_t *root, + const char *path, unsigned int flags) +{ + return fstree_from_subdir(fs, root, path, NULL, flags); +} #endif |