summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fstree.h9
-rw-r--r--lib/fstree/fstree_from_dir.c48
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