diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-11 18:08:02 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-06-11 18:08:02 +0200 | 
| commit | 8fa122a59f61878bafa43ea45d9ea988f3a70998 (patch) | |
| tree | 68cecde13ae0cef26fa1289c236d7251c7d092a0 /unpack | |
| parent | cfbbe12db970b266186775350267f163967d2ede (diff) | |
cleanup: rdsquashfs: move command line option processing to options.c
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/Makemodule.am | 2 | ||||
| -rw-r--r-- | unpack/options.c | 171 | ||||
| -rw-r--r-- | unpack/rdsquashfs.c | 197 | ||||
| -rw-r--r-- | unpack/rdsquashfs.h | 19 | 
4 files changed, 209 insertions, 180 deletions
diff --git a/unpack/Makemodule.am b/unpack/Makemodule.am index c70026d..225263b 100644 --- a/unpack/Makemodule.am +++ b/unpack/Makemodule.am @@ -1,5 +1,5 @@  rdsquashfs_SOURCES = unpack/rdsquashfs.c unpack/rdsquashfs.h -rdsquashfs_SOURCES += unpack/list_files.c +rdsquashfs_SOURCES += unpack/list_files.c unpack/options.c  rdsquashfs_SOURCES += unpack/restore_fstree.c unpack/describe.c  rdsquashfs_LDADD = libsquashfs.a libfstree.a libcompress.a libutil.a diff --git a/unpack/options.c b/unpack/options.c new file mode 100644 index 0000000..ccfe7c8 --- /dev/null +++ b/unpack/options.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include "rdsquashfs.h" + +static struct option long_opts[] = { +	{ "list", required_argument, NULL, 'l' }, +	{ "cat", required_argument, NULL, 'c' }, +	{ "unpack-root", required_argument, NULL, 'p' }, +	{ "unpack-path", required_argument, NULL, 'u' }, +	{ "no-dev", no_argument, NULL, 'D' }, +	{ "no-sock", no_argument, NULL, 'S' }, +	{ "no-fifo", no_argument, NULL, 'F' }, +	{ "no-slink", no_argument, NULL, 'L' }, +	{ "no-empty-dir", no_argument, NULL, 'E' }, +	{ "describe", no_argument, NULL, 'd' }, +	{ "chmod", no_argument, NULL, 'C' }, +	{ "chown", no_argument, NULL, 'O' }, +	{ "quiet", no_argument, NULL, 'q' }, +	{ "help", no_argument, NULL, 'h' }, +	{ "version", no_argument, NULL, 'V' }, +}; + +static const char *short_opts = "l:c:u:p:DSFLCOEdqhV"; + +static const char *help_string = +"Usage: %s [OPTIONS] <squashfs-file>\n" +"\n" +"View or extract the contents of a squashfs image.\n" +"\n" +"Possible options:\n" +"\n" +"  --list, -l <path>         Produce a directory listing for a given path in\n" +"                            the squashfs image.\n" +"  --cat, -c <path>          If the specified path is a regular file in the,\n" +"                            image, dump its contents to stdout.\n" +"  --unpack-path, -u <path>  Unpack this sub directory from the image. To\n" +"                            unpack everything, simply specify /.\n" +"  --describe, -d            Produce a file listing from the image.\n" +"\n" +"  --unpack-root, -p <path>  If used with --unpack-path, this is where the\n" +"                            data unpacked to. If used with --describe, this\n" +"                            is used as a prefix for the input path of\n" +"                            regular files.\n" +"\n" +"  --no-dev, -D              Do not unpack device special files.\n" +"  --no-sock, -S             Do not unpack socket files.\n" +"  --no-fifo, -F             Do not unpack named pipes.\n" +"  --no-slink, -L            Do not unpack symbolic links.\n" +"  --no-empty-dir, -E        Do not unpack directories that would end up\n" +"                            empty after applying the above rules.\n" +"  --chmod, -C               Change permission flags of unpacked files to\n" +"                            those store in the squashfs image.\n" +"  --chown, -O               Change ownership of unpacked files to the\n" +"                            UID/GID set in the squashfs image.\n" +"  --quiet, -q               Do not print out progress while unpacking.\n" +"\n" +"  --help, -h                Print help text and exit.\n" +"  --version, -V             Print version information and exit.\n" +"\n"; + +extern const char *__progname; + +static char *get_path(char *old, const char *arg) +{ +	char *path; + +	free(old); + +	path = strdup(arg); +	if (path == NULL) { +		perror("processing arguments"); +		exit(EXIT_FAILURE); +	} + +	if (canonicalize_name(path)) { +		fprintf(stderr, "Invalid path: %s\n", arg); +		free(path); +		exit(EXIT_FAILURE); +	} + +	return path; +} + +void process_command_line(options_t *opt, int argc, char **argv) +{ +	int i; + +	opt->op = OP_NONE; +	opt->rdtree_flags = 0; +	opt->flags = 0; +	opt->cmdpath = NULL; +	opt->unpack_root = NULL; +	opt->image_name = NULL; + +	for (;;) { +		i = getopt_long(argc, argv, short_opts, long_opts, NULL); +		if (i == -1) +			break; + +		switch (i) { +		case 'D': +			opt->rdtree_flags |= RDTREE_NO_DEVICES; +			break; +		case 'S': +			opt->rdtree_flags |= RDTREE_NO_SOCKETS; +			break; +		case 'F': +			opt->rdtree_flags |= RDTREE_NO_FIFO; +			break; +		case 'L': +			opt->rdtree_flags |= RDTREE_NO_SLINKS; +			break; +		case 'E': +			opt->rdtree_flags |= RDTREE_NO_EMPTY; +			break; +		case 'C': +			opt->flags |= UNPACK_CHMOD; +			break; +		case 'O': +			opt->flags |= UNPACK_CHOWN; +			break; +		case 'c': +			opt->op = OP_CAT; +			opt->cmdpath = get_path(opt->cmdpath, optarg); +			break; +		case 'd': +			opt->op = OP_DESCRIBE; +			break; +		case 'l': +			opt->op = OP_LS; +			opt->cmdpath = get_path(opt->cmdpath, optarg); +			break; +		case 'p': +			opt->unpack_root = optarg; +			break; +		case 'u': +			opt->op = OP_UNPACK; +			opt->cmdpath = get_path(opt->cmdpath, optarg); +			break; +		case 'q': +			opt->flags |= UNPACK_QUIET; +			break; +		case 'h': +			printf(help_string, __progname); +			free(opt->cmdpath); +			exit(EXIT_SUCCESS); +		case 'V': +			print_version(); +			free(opt->cmdpath); +			exit(EXIT_SUCCESS); +		default: +			goto fail_arg; +		} +	} + +	if (opt->op == OP_NONE) { +		fputs("No opteration specified\n", stderr); +		goto fail_arg; +	} + +	if (optind >= argc) { +		fputs("Missing image argument\n", stderr); +		goto fail_arg; +	} + +	opt->image_name = argv[optind++]; +	return; +fail_arg: +	fprintf(stderr, "Try `%s --help' for more information.\n", __progname); +	free(opt->cmdpath); +	exit(EXIT_FAILURE); +} diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index a24d6c3..27a0cf5 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -1,72 +1,6 @@  /* SPDX-License-Identifier: GPL-3.0-or-later */  #include "rdsquashfs.h" -enum { -	OP_NONE = 0, -	OP_LS, -	OP_CAT, -	OP_UNPACK, -	OP_DESCRIBE, -}; - -static struct option long_opts[] = { -	{ "list", required_argument, NULL, 'l' }, -	{ "cat", required_argument, NULL, 'c' }, -	{ "unpack-root", required_argument, NULL, 'p' }, -	{ "unpack-path", required_argument, NULL, 'u' }, -	{ "no-dev", no_argument, NULL, 'D' }, -	{ "no-sock", no_argument, NULL, 'S' }, -	{ "no-fifo", no_argument, NULL, 'F' }, -	{ "no-slink", no_argument, NULL, 'L' }, -	{ "no-empty-dir", no_argument, NULL, 'E' }, -	{ "describe", no_argument, NULL, 'd' }, -	{ "chmod", no_argument, NULL, 'C' }, -	{ "chown", no_argument, NULL, 'O' }, -	{ "quiet", no_argument, NULL, 'q' }, -	{ "help", no_argument, NULL, 'h' }, -	{ "version", no_argument, NULL, 'V' }, -}; - -static const char *short_opts = "l:c:u:p:DSFLCOEdqhV"; - -static const char *help_string = -"Usage: %s [OPTIONS] <squashfs-file>\n" -"\n" -"View or extract the contents of a squashfs image.\n" -"\n" -"Possible options:\n" -"\n" -"  --list, -l <path>         Produce a directory listing for a given path in\n" -"                            the squashfs image.\n" -"  --cat, -c <path>          If the specified path is a regular file in the,\n" -"                            image, dump its contents to stdout.\n" -"  --unpack-path, -u <path>  Unpack this sub directory from the image. To\n" -"                            unpack everything, simply specify /.\n" -"  --describe, -d            Produce a file listing from the image.\n" -"\n" -"  --unpack-root, -p <path>  If used with --unpack-path, this is where the\n" -"                            data unpacked to. If used with --describe, this\n" -"                            is used as a prefix for the input path of\n" -"                            regular files.\n" -"\n" -"  --no-dev, -D              Do not unpack device special files.\n" -"  --no-sock, -S             Do not unpack socket files.\n" -"  --no-fifo, -F             Do not unpack named pipes.\n" -"  --no-slink, -L            Do not unpack symbolic links.\n" -"  --no-empty-dir, -E        Do not unpack directories that would end up\n" -"                            empty after applying the above rules.\n" -"  --chmod, -C               Change permission flags of unpacked files to\n" -"                            those store in the squashfs image.\n" -"  --chown, -O               Change ownership of unpacked files to the\n" -"                            UID/GID set in the squashfs image.\n" -"  --quiet, -q               Do not print out progress while unpacking.\n" -"\n" -"  --help, -h                Print help text and exit.\n" -"  --version, -V             Print version information and exit.\n" -"\n"; - -extern const char *__progname; -  static tree_node_t *find_node(tree_node_t *n, const char *path)  {  	const char *end; @@ -100,114 +34,22 @@ static tree_node_t *find_node(tree_node_t *n, const char *path)  	return n;  } -static char *get_path(char *old, const char *arg) -{ -	char *path; - -	free(old); - -	path = strdup(arg); -	if (path == NULL) { -		perror("processing arguments"); -		exit(EXIT_FAILURE); -	} - -	if (canonicalize_name(path)) { -		fprintf(stderr, "Invalid path: %s\n", arg); -		free(path); -		exit(EXIT_FAILURE); -	} - -	return path; -} -  int main(int argc, char **argv)  { -	int i, status = EXIT_FAILURE, op = OP_NONE; -	const char *unpack_root = NULL; -	int rdtree_flags = 0, flags = 0; +	int status = EXIT_FAILURE;  	data_reader_t *data = NULL; -	char *cmdpath = NULL;  	sqfs_super_t super;  	compressor_t *cmp;  	tree_node_t *n; +	options_t opt;  	fstree_t fs;  	int sqfsfd; -	for (;;) { -		i = getopt_long(argc, argv, short_opts, long_opts, NULL); -		if (i == -1) -			break; - -		switch (i) { -		case 'D': -			rdtree_flags |= RDTREE_NO_DEVICES; -			break; -		case 'S': -			rdtree_flags |= RDTREE_NO_SOCKETS; -			break; -		case 'F': -			rdtree_flags |= RDTREE_NO_FIFO; -			break; -		case 'L': -			rdtree_flags |= RDTREE_NO_SLINKS; -			break; -		case 'C': -			flags |= UNPACK_CHMOD; -			break; -		case 'O': -			flags |= UNPACK_CHOWN; -			break; -		case 'E': -			rdtree_flags |= RDTREE_NO_EMPTY; -			break; -		case 'c': -			op = OP_CAT; -			cmdpath = get_path(cmdpath, optarg); -			break; -		case 'd': -			op = OP_DESCRIBE; -			break; -		case 'l': -			op = OP_LS; -			cmdpath = get_path(cmdpath, optarg); -			break; -		case 'p': -			unpack_root = optarg; -			break; -		case 'u': -			op = OP_UNPACK; -			cmdpath = get_path(cmdpath, optarg); -			break; -		case 'q': -			flags |= UNPACK_QUIET; -			break; -		case 'h': -			printf(help_string, __progname); -			status = EXIT_SUCCESS; -			goto out_cmd; -		case 'V': -			print_version(); -			status = EXIT_SUCCESS; -			goto out_cmd; -		default: -			goto fail_arg; -		} -	} - -	if (op == OP_NONE) { -		fputs("No opteration specified\n", stderr); -		goto fail_arg; -	} - -	if (optind >= argc) { -		fputs("Missing image argument\n", stderr); -		goto fail_arg; -	} +	process_command_line(&opt, argc, argv); -	sqfsfd = open(argv[optind], O_RDONLY); +	sqfsfd = open(opt.image_name, O_RDONLY);  	if (sqfsfd < 0) { -		perror(argv[optind]); +		perror(opt.image_name);  		goto out_cmd;  	} @@ -240,28 +82,29 @@ int main(int argc, char **argv)  			goto out_cmp;  	} -	if (deserialize_fstree(&fs, &super, cmp, sqfsfd, rdtree_flags)) +	if (deserialize_fstree(&fs, &super, cmp, sqfsfd, opt.rdtree_flags))  		goto out_cmp; -	switch (op) { +	switch (opt.op) {  	case OP_LS: -		n = find_node(fs.root, cmdpath); +		n = find_node(fs.root, opt.cmdpath);  		if (n == NULL) { -			perror(cmdpath); +			perror(opt.cmdpath);  			goto out_fs;  		}  		list_files(n);  		break;  	case OP_CAT: -		n = find_node(fs.root, cmdpath); +		n = find_node(fs.root, opt.cmdpath);  		if (n == NULL) { -			perror(cmdpath); +			perror(opt.cmdpath);  			goto out_fs;  		}  		if (!S_ISREG(n->mode)) { -			fprintf(stderr, "/%s: not a regular file\n", cmdpath); +			fprintf(stderr, "/%s: not a regular file\n", +				opt.cmdpath);  			goto out_fs;  		} @@ -273,9 +116,9 @@ int main(int argc, char **argv)  			goto out_fs;  		break;  	case OP_UNPACK: -		n = find_node(fs.root, cmdpath); +		n = find_node(fs.root, opt.cmdpath);  		if (n == NULL) { -			perror(cmdpath); +			perror(opt.cmdpath);  			goto out_fs;  		} @@ -283,11 +126,11 @@ int main(int argc, char **argv)  		if (data == NULL)  			goto out_fs; -		if (restore_fstree(unpack_root, n, data, flags)) +		if (restore_fstree(opt.unpack_root, n, data, opt.flags))  			goto out_fs;  		break;  	case OP_DESCRIBE: -		describe_tree(fs.root, unpack_root); +		describe_tree(fs.root, opt.unpack_root);  		break;  	} @@ -301,10 +144,6 @@ out_cmp:  out_fd:  	close(sqfsfd);  out_cmd: -	free(cmdpath); +	free(opt.cmdpath);  	return status; -fail_arg: -	fprintf(stderr, "Try `%s --help' for more information.\n", __progname); -	free(cmdpath); -	return EXIT_FAILURE;  } diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index 959960a..9d1ab4f 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -26,6 +26,23 @@ enum UNPACK_FLAGS {  	UNPACK_QUIET = 0x04,  }; +enum { +	OP_NONE = 0, +	OP_LS, +	OP_CAT, +	OP_UNPACK, +	OP_DESCRIBE, +}; + +typedef struct { +	int op; +	int rdtree_flags; +	int flags; +	char *cmdpath; +	const char *unpack_root; +	const char *image_name; +} options_t; +  void list_files(tree_node_t *node);  int restore_fstree(const char *rootdir, tree_node_t *root, @@ -33,4 +50,6 @@ int restore_fstree(const char *rootdir, tree_node_t *root,  void describe_tree(tree_node_t *root, const char *unpack_root); +void process_command_line(options_t *opt, int argc, char **argv); +  #endif /* RDSQUASHFS_H */  | 
