aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fstree.h12
-rw-r--r--lib/fstree/fstree_from_file.c34
-rw-r--r--mkfs/mkfs.c75
3 files changed, 60 insertions, 61 deletions
diff --git a/include/fstree.h b/include/fstree.h
index 74d1c7f..784364e 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
+#include <stdio.h>
#include "str_table.h"
@@ -215,19 +216,18 @@ void fstree_xattr_deduplicate(fstree_t *fs);
/*
Parses the file format accepted by gensquashfs and produce a file system
- tree from it. File input paths are interpreted as relative to the given
- root dir. If rootdir is NULL, use the path where the input file is as root
- dir.
+ tree from it. File input paths are interpreted as relative to the current
+ working directory.
- This function tries to temporarily change the working directory, so if it
- fails, the current working directory is undefined.
+ Data is read from the given file pointer. The filename is only used for
+ producing error messages.
On failure, an error report with filename and line number is written
to stderr.
Returns 0 on success.
*/
-int fstree_from_file(fstree_t *fs, const char *filename, const char *rootdir);
+int fstree_from_file(fstree_t *fs, const char *filename, FILE *fp);
/*
Recursively scan a directory and generate a file system tree from it.
diff --git a/lib/fstree/fstree_from_file.c b/lib/fstree/fstree_from_file.c
index ded404a..0031c09 100644
--- a/lib/fstree/fstree_from_file.c
+++ b/lib/fstree/fstree_from_file.c
@@ -8,7 +8,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
-#include <stdio.h>
#include <ctype.h>
#include <errno.h>
@@ -258,36 +257,12 @@ out_desc:
return -1;
}
-int fstree_from_file(fstree_t *fs, const char *filename, const char *rootdir)
+int fstree_from_file(fstree_t *fs, const char *filename, FILE *fp)
{
- FILE *fp = fopen(filename, "rb");
- bool need_restore = false;
size_t n, line_num = 0;
- const char *ptr;
ssize_t ret;
char *line;
- if (fp == NULL) {
- perror(filename);
- return -1;
- }
-
- if (rootdir == NULL) {
- ptr = strrchr(filename, '/');
-
- if (ptr != NULL) {
- if (pushdn(filename, ptr - filename)) {
- free(line);
- return -1;
- }
- need_restore = true;
- }
- } else {
- if (pushd(rootdir))
- return -1;
- need_restore = true;
- }
-
for (;;) {
line = NULL;
n = 0;
@@ -318,15 +293,8 @@ int fstree_from_file(fstree_t *fs, const char *filename, const char *rootdir)
free(line);
}
-
- fclose(fp);
-
- if (need_restore && popd() != 0)
- return -1;
-
return 0;
fail_line:
free(line);
- fclose(fp);
return -1;
}
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 12b4de9..371c578 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -39,25 +39,32 @@ static int pack_files_dfs(data_writer_t *data, tree_node_t *n, bool quiet)
return 0;
}
-static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt)
+static int set_working_dir(options_t *opt)
{
- bool need_restore = false;
const char *ptr;
- if (opt->packdir != NULL) {
- if (pushd(opt->packdir))
- return -1;
- need_restore = true;
- } else {
- ptr = strrchr(opt->infile, '/');
+ if (opt->packdir != NULL)
+ return pushd(opt->packdir);
- if (ptr != NULL) {
- if (pushdn(opt->infile, ptr - opt->infile))
- return -1;
+ ptr = strrchr(opt->infile, '/');
+ if (ptr != NULL)
+ return pushdn(opt->infile, ptr - opt->infile);
- need_restore = true;
- }
- }
+ return 0;
+}
+
+static int restore_working_dir(options_t *opt)
+{
+ if (opt->packdir != NULL || strrchr(opt->infile, '/') != NULL)
+ return popd();
+
+ return 0;
+}
+
+static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt)
+{
+ if (set_working_dir(opt))
+ return -1;
if (pack_files_dfs(data, fs->root, opt->quiet))
return -1;
@@ -65,7 +72,36 @@ static int pack_files(data_writer_t *data, fstree_t *fs, options_t *opt)
if (data_writer_flush_fragments(data))
return -1;
- return need_restore ? popd() : 0;
+ return restore_working_dir(opt);
+}
+
+static int read_fstree(fstree_t *fs, options_t *opt)
+{
+ FILE *fp;
+ int ret;
+
+ if (opt->infile == NULL)
+ return fstree_from_dir(fs, opt->packdir);
+
+ fp = fopen(opt->infile, "rb");
+ if (fp == NULL) {
+ perror(opt->infile);
+ return -1;
+ }
+
+ if (set_working_dir(opt)) {
+ fclose(fp);
+ return -1;
+ }
+
+ ret = fstree_from_file(fs, opt->infile, fp);
+
+ fclose(fp);
+
+ if (restore_working_dir(opt))
+ return -1;
+
+ return ret;
}
int main(int argc, char **argv)
@@ -101,13 +137,8 @@ int main(int argc, char **argv)
goto out_outfd;
}
- if (opt.infile != NULL) {
- if (fstree_from_file(&fs, opt.infile, opt.packdir))
- goto out_fstree;
- } else {
- if (fstree_from_dir(&fs, opt.packdir))
- goto out_fstree;
- }
+ if (read_fstree(&fs, &opt))
+ goto out_fstree;
tree_node_sort_recursive(fs.root);