cpio: allow cpio -i to take params - names of files to extract

Also, improve help text

function                                             old     new   delta
packed_usage                                       28028   28035      +7
cpio_main                                            542     532     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 7/-10)              Total: -3 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-12-26 02:22:51 +01:00
parent e4e911e712
commit 1f937d6468
2 changed files with 66 additions and 68 deletions

View File

@ -14,13 +14,43 @@
#include "libbb.h" #include "libbb.h"
#include "archive.h" #include "archive.h"
//usage:#define cpio_trivial_usage
//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]")
//usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
//usage: " [EXTR_FILE]..."
//usage:#define cpio_full_usage "\n\n"
//usage: "Extract or list files from a cpio archive"
//usage: IF_FEATURE_CPIO_O(", or"
//usage: "\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)")
//usage: " using file list on stdin"
//usage: )
//usage: "\n"
//usage: "\nMain operation mode:"
//usage: "\n -t List"
//usage: "\n -i Extract EXTR_FILEs (or all)"
//usage: IF_FEATURE_CPIO_O(
//usage: "\n -o Create (requires -H newc)"
//usage: )
//usage: IF_FEATURE_CPIO_P(
//usage: "\n -p DIR Copy files to DIR"
//usage: )
//usage: "\nOptions:"
//usage: "\n -d Make leading directories"
//usage: "\n -m Preserve mtime"
//usage: "\n -v Verbose"
//usage: "\n -u Overwrite"
//usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file"
//usage: IF_FEATURE_CPIO_O(
//usage: "\n -H newc Archive format"
//usage: )
/* GNU cpio 2.9 --help (abridged): /* GNU cpio 2.9 --help (abridged):
Modes: Modes:
-t, --list List the archive -t, --list List the archive
-i, --extract Extract files from an archive -i, --extract Extract files from an archive
-o, --create Create the archive -o, --create Create the archive
-p, --pass-through Copy-pass mode [was ist das?!] -p, --pass-through Copy-pass mode
Options valid in any mode: Options valid in any mode:
--block-size=SIZE I/O block size = SIZE * 512 bytes --block-size=SIZE I/O block size = SIZE * 512 bytes
@ -78,27 +108,28 @@
--sparse Write files with blocks of zeros as sparse files --sparse Write files with blocks of zeros as sparse files
-u, --unconditional Replace all files unconditionally -u, --unconditional Replace all files unconditionally
*/ */
enum { enum {
CPIO_OPT_EXTRACT = (1 << 0), OPT_EXTRACT = (1 << 0),
CPIO_OPT_TEST = (1 << 1), OPT_TEST = (1 << 1),
CPIO_OPT_NUL_TERMINATED = (1 << 2), OPT_NUL_TERMINATED = (1 << 2),
CPIO_OPT_UNCONDITIONAL = (1 << 3), OPT_UNCONDITIONAL = (1 << 3),
CPIO_OPT_VERBOSE = (1 << 4), OPT_VERBOSE = (1 << 4),
CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), OPT_CREATE_LEADING_DIR = (1 << 5),
CPIO_OPT_PRESERVE_MTIME = (1 << 6), OPT_PRESERVE_MTIME = (1 << 6),
CPIO_OPT_DEREF = (1 << 7), OPT_DEREF = (1 << 7),
CPIO_OPT_FILE = (1 << 8), OPT_FILE = (1 << 8),
OPTBIT_FILE = 8, OPTBIT_FILE = 8,
IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) IF_FEATURE_CPIO_O(OPTBIT_CREATE ,)
IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,)
IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,)
IF_LONG_OPTS( OPTBIT_QUIET ,) IF_LONG_OPTS( OPTBIT_QUIET ,)
IF_LONG_OPTS( OPTBIT_2STDOUT ,) IF_LONG_OPTS( OPTBIT_2STDOUT ,)
CPIO_OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0, OPT_CREATE = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE )) + 0,
CPIO_OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0, OPT_FORMAT = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT )) + 0,
CPIO_OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0, OPT_PASSTHROUGH = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0,
CPIO_OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0, OPT_QUIET = IF_LONG_OPTS( (1 << OPTBIT_QUIET )) + 0,
CPIO_OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0,
}; };
#define OPTION_STR "it0uvdmLF:" #define OPTION_STR "it0uvdmLF:"
@ -138,7 +169,7 @@ static NOINLINE int cpio_o(void)
char *line; char *line;
struct stat st; struct stat st;
line = (option_mask32 & CPIO_OPT_NUL_TERMINATED) line = (option_mask32 & OPT_NUL_TERMINATED)
? bb_get_chunk_from_file(stdin, NULL) ? bb_get_chunk_from_file(stdin, NULL)
: xmalloc_fgetline(stdin); : xmalloc_fgetline(stdin);
@ -153,7 +184,7 @@ static NOINLINE int cpio_o(void)
free(line); free(line);
continue; continue;
} }
if ((option_mask32 & CPIO_OPT_DEREF) if ((option_mask32 & OPT_DEREF)
? stat(name, &st) ? stat(name, &st)
: lstat(name, &st) : lstat(name, &st)
) { ) {
@ -308,28 +339,24 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
/* -L makes sense only with -o or -p */ /* -L makes sense only with -o or -p */
#if !ENABLE_FEATURE_CPIO_O #if !ENABLE_FEATURE_CPIO_O
/* no parameters */
opt_complementary = "=0";
opt = getopt32(argv, OPTION_STR, &cpio_filename); opt = getopt32(argv, OPTION_STR, &cpio_filename);
argv += optind; argv += optind;
if (opt & CPIO_OPT_FILE) { /* -F */ if (opt & OPT_FILE) { /* -F */
xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
} }
#else #else
/* _exactly_ one parameter for -p, thus <= 1 param if -p is allowed */
opt_complementary = ENABLE_FEATURE_CPIO_P ? "?1" : "=0";
opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt);
argv += optind; argv += optind;
if ((opt & (CPIO_OPT_FILE|CPIO_OPT_CREATE)) == CPIO_OPT_FILE) { /* -F without -o */ if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */
xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
} }
if (opt & CPIO_OPT_PASSTHROUGH) { if (opt & OPT_PASSTHROUGH) {
pid_t pid; pid_t pid;
struct fd_pair pp; struct fd_pair pp;
if (argv[0] == NULL) if (argv[0] == NULL)
bb_show_usage(); bb_show_usage();
if (opt & CPIO_OPT_CREATE_LEADING_DIR) if (opt & OPT_CREATE_LEADING_DIR)
mkdir(argv[0], 0777); mkdir(argv[0], 0777);
/* Crude existence check: /* Crude existence check:
* close(xopen(argv[0], O_RDONLY | O_DIRECTORY)); * close(xopen(argv[0], O_RDONLY | O_DIRECTORY));
@ -361,15 +388,15 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
xchdir(*argv++); xchdir(*argv++);
close(pp.wr); close(pp.wr);
xmove_fd(pp.rd, STDIN_FILENO); xmove_fd(pp.rd, STDIN_FILENO);
//opt &= ~CPIO_OPT_PASSTHROUGH; //opt &= ~OPT_PASSTHROUGH;
opt |= CPIO_OPT_EXTRACT; opt |= OPT_EXTRACT;
goto skip; goto skip;
} }
/* -o */ /* -o */
if (opt & CPIO_OPT_CREATE) { if (opt & OPT_CREATE) {
if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */ if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */
bb_show_usage(); bb_show_usage();
if (opt & CPIO_OPT_FILE) { if (opt & OPT_FILE) {
xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO); xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
} }
dump: dump:
@ -379,35 +406,35 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
#endif #endif
/* One of either extract or test options must be given */ /* One of either extract or test options must be given */
if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { if ((opt & (OPT_TEST | OPT_EXTRACT)) == 0) {
bb_show_usage(); bb_show_usage();
} }
if (opt & CPIO_OPT_TEST) { if (opt & OPT_TEST) {
/* if both extract and test options are given, ignore extract option */ /* if both extract and test options are given, ignore extract option */
opt &= ~CPIO_OPT_EXTRACT; opt &= ~OPT_EXTRACT;
archive_handle->action_header = header_list; archive_handle->action_header = header_list;
} }
if (opt & CPIO_OPT_EXTRACT) { if (opt & OPT_EXTRACT) {
archive_handle->action_data = data_extract_all; archive_handle->action_data = data_extract_all;
if (opt & CPIO_OPT_2STDOUT) if (opt & OPT_2STDOUT)
archive_handle->action_data = data_extract_to_stdout; archive_handle->action_data = data_extract_to_stdout;
} }
if (opt & CPIO_OPT_UNCONDITIONAL) { if (opt & OPT_UNCONDITIONAL) {
archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD; archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD;
archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER; archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER;
} }
if (opt & CPIO_OPT_VERBOSE) { if (opt & OPT_VERBOSE) {
if (archive_handle->action_header == header_list) { if (archive_handle->action_header == header_list) {
archive_handle->action_header = header_verbose_list; archive_handle->action_header = header_verbose_list;
} else { } else {
archive_handle->action_header = header_list; archive_handle->action_header = header_list;
} }
} }
if (opt & CPIO_OPT_CREATE_LEADING_DIR) { if (opt & OPT_CREATE_LEADING_DIR) {
archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS; archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS;
} }
if (opt & CPIO_OPT_PRESERVE_MTIME) { if (opt & OPT_PRESERVE_MTIME) {
archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE; archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE;
} }
@ -423,7 +450,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
continue; continue;
if (archive_handle->cpio__blocks != (off_t)-1 if (archive_handle->cpio__blocks != (off_t)-1
&& !(opt & CPIO_OPT_QUIET) && !(opt & OPT_QUIET)
) { ) {
fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks); fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks);
} }

View File

@ -592,35 +592,6 @@ INSERT
"\n -i Prompt before overwrite" \ "\n -i Prompt before overwrite" \
"\n -l,-s Create (sym)links" \ "\n -l,-s Create (sym)links" \
#define cpio_trivial_usage \
"[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") \
" [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
#define cpio_full_usage "\n\n" \
"Extract or list files from a cpio archive" \
IF_FEATURE_CPIO_O(", or" \
"\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)") \
" using file list on stdin" \
) \
"\n" \
"\nMain operation mode:" \
"\n -t List" \
"\n -i Extract" \
IF_FEATURE_CPIO_O( \
"\n -o Create (requires -H newc)" \
) \
IF_FEATURE_CPIO_P( \
"\n -p DIR Copy files to DIR" \
) \
"\nOptions:" \
"\n -d Make leading directories" \
"\n -m Preserve mtime" \
"\n -v Verbose" \
"\n -u Overwrite" \
"\n -F FILE Input (-t,-i,-p) or output (-o) file" \
IF_FEATURE_CPIO_O( \
"\n -H newc Archive format" \
) \
#define crond_trivial_usage \ #define crond_trivial_usage \
"-fbS -l N " IF_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR" "-fbS -l N " IF_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR"
#define crond_full_usage "\n\n" \ #define crond_full_usage "\n\n" \