summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-31 19:25:16 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-31 19:25:16 +0200
commit3559e5e0e840839ae85aa02c0748f89676c0a5e8 (patch)
tree004066f10f22b245d22ac73f71fd17ac5c8e3f06
parentc4a945dd254af75d334fdd881076c665184faa31 (diff)
gensquashfs: allow combining packdir and packfile
If packdir and packfile are both specified, use packdir as alternate root. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/fstree.h6
-rw-r--r--lib/fstree/fstree_from_file.c33
-rw-r--r--mkfs/mkfs.c13
-rw-r--r--mkfs/mkfs.h8
-rw-r--r--mkfs/options.c21
5 files changed, 42 insertions, 39 deletions
diff --git a/include/fstree.h b/include/fstree.h
index 13d4c78..33fa8b8 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -220,14 +220,16 @@ void fstree_xattr_deduplicate(fstree_t *fs);
/*
Parses the file format accepted by gensquashfs and produce a file system
- tree from it.
+ 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. The function actually chdirs into the root dir.
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);
+int fstree_from_file(fstree_t *fs, const char *filename, const char *rootdir);
/*
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 c2fac7a..5a87222 100644
--- a/lib/fstree/fstree_from_file.c
+++ b/lib/fstree/fstree_from_file.c
@@ -362,7 +362,7 @@ out_desc:
return -1;
}
-int fstree_from_file(fstree_t *fs, const char *filename)
+int fstree_from_file(fstree_t *fs, const char *filename, const char *rootdir)
{
FILE *fp = fopen(filename, "rb");
size_t n, line_num = 0;
@@ -375,23 +375,30 @@ int fstree_from_file(fstree_t *fs, const char *filename)
return -1;
}
- ptr = strrchr(filename, '/');
+ if (rootdir == NULL) {
+ ptr = strrchr(filename, '/');
- if (ptr != NULL) {
- line = strndup(filename, ptr - filename);
- if (line == NULL) {
- perror("composing root path");
- return -1;
- }
+ if (ptr != NULL) {
+ line = strndup(filename, ptr - filename);
+ if (line == NULL) {
+ perror("composing root path");
+ return -1;
+ }
+
+ if (chdir(line)) {
+ perror(line);
+ free(line);
+ return -1;
+ }
- if (chdir(line)) {
- perror(line);
free(line);
+ line = NULL;
+ }
+ } else {
+ if (chdir(rootdir)) {
+ perror(rootdir);
return -1;
}
-
- free(line);
- line = NULL;
}
for (;;) {
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 63b9c98..a6f19f1 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -70,17 +70,12 @@ int main(int argc, char **argv)
goto out_outfd;
}
- switch (info.opt.mode) {
- case PACK_FILE:
- if (fstree_from_file(&info.fs, info.opt.infile))
+ if (info.opt.infile != NULL) {
+ if (fstree_from_file(&info.fs, info.opt.infile, info.opt.packdir))
goto out_fstree;
- break;
- case PACK_DIR:
- if (fstree_from_dir(&info.fs, info.opt.infile))
+ } else {
+ if (fstree_from_dir(&info.fs, info.opt.packdir))
goto out_fstree;
- break;
- default:
- assert(0);
}
#ifdef WITH_SELINUX
diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h
index 67dc994..c73b74e 100644
--- a/mkfs/mkfs.h
+++ b/mkfs/mkfs.h
@@ -17,12 +17,6 @@
#include <fcntl.h>
#include <errno.h>
-typedef enum {
- PACK_NONE,
- PACK_FILE,
- PACK_DIR,
-} E_PACK_MODE;
-
typedef struct {
unsigned int def_uid;
unsigned int def_gid;
@@ -34,10 +28,10 @@ typedef struct {
int devblksz;
bool quiet;
const char *infile;
+ const char *packdir;
const char *outfile;
const char *selinux;
char *comp_extra;
- E_PACK_MODE mode;
} options_t;
typedef struct {
diff --git a/mkfs/options.c b/mkfs/options.c
index 56bc7d6..f64ec94 100644
--- a/mkfs/options.c
+++ b/mkfs/options.c
@@ -58,9 +58,17 @@ static const char *help_string =
"\n"
" --pack-file, -F <file> Use a `gen_init_cpio` style description file.\n"
" The file format is specified below.\n"
-" --pack-dir, -D <directory> Pack the contents of the given directory into\n"
-" a SquashFS image. The directory becomes the\n"
-" root of the file system.\n"
+" If --pack-dir is used, input file paths are\n"
+" relative to the pack directory, otherwise\n"
+" they are relative to the directory the pack\n"
+" file is in.\n"
+" --pack-dir, -D <directory> If --pack-file is used, this is the root path\n"
+" relative to which to read files. If no pack\n"
+" file is specified, pack the contents of the\n"
+" given directory into a SquashFS image. The\n"
+" directory becomes the root of the file\n"
+" system.\n"
+"\n"
" --compressor, -c <name> Select the compressor to use.\n"
" A list of available compressors is below.\n"
" Defaults to 'xz'.\n"
@@ -246,7 +254,6 @@ void process_command_line(options_t *opt, int argc, char **argv)
opt->devblksz = SQFS_DEVBLK_SIZE;
opt->infile = NULL;
opt->outfile = NULL;
- opt->mode = PACK_NONE;
for (;;) {
i = getopt_long(argc, argv, short_opts, long_opts, NULL);
@@ -294,12 +301,10 @@ void process_command_line(options_t *opt, int argc, char **argv)
opt->comp_extra = optarg;
break;
case 'F':
- opt->mode = PACK_FILE;
opt->infile = optarg;
break;
case 'D':
- opt->mode = PACK_DIR;
- opt->infile = optarg;
+ opt->packdir = optarg;
break;
#ifdef WITH_SELINUX
case 's':
@@ -331,7 +336,7 @@ void process_command_line(options_t *opt, int argc, char **argv)
exit(EXIT_SUCCESS);
}
- if (opt->mode == PACK_NONE) {
+ if (opt->infile == NULL && opt->packdir == NULL) {
fputs("No input file or directory specified.\n", stderr);
goto fail_arg;
}