mirror of https://github.com/mirror/busybox.git
parent
dee8587d92
commit
fa1649e9ac
112
archival/cpio.c
112
archival/cpio.c
|
@ -14,18 +14,6 @@
|
|||
#include "libbb.h"
|
||||
#include "unarchive.h"
|
||||
|
||||
enum {
|
||||
CPIO_OPT_EXTRACT = (1 << 0),
|
||||
CPIO_OPT_TEST = (1 << 1),
|
||||
CPIO_OPT_UNCONDITIONAL = (1 << 2),
|
||||
CPIO_OPT_VERBOSE = (1 << 3),
|
||||
CPIO_OPT_FILE = (1 << 4),
|
||||
CPIO_OPT_CREATE_LEADING_DIR = (1 << 5),
|
||||
CPIO_OPT_PRESERVE_MTIME = (1 << 6),
|
||||
CPIO_OPT_CREATE = (1 << 7),
|
||||
CPIO_OPT_FORMAT = (1 << 8),
|
||||
};
|
||||
|
||||
#if ENABLE_FEATURE_CPIO_O
|
||||
static off_t cpio_pad4(off_t size)
|
||||
{
|
||||
|
@ -190,21 +178,108 @@ static int cpio_o(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* GNU cpio (GNU cpio) 2.9 help (abridged):
|
||||
|
||||
Main operation mode:
|
||||
-i, --extract Extract files from an archive
|
||||
-o, --create Create the archive
|
||||
-p, --pass-through Copy-pass mode (was ist das?!)
|
||||
-t, --list List the archive
|
||||
|
||||
Operation modifiers valid in any mode:
|
||||
--block-size=SIZE I/O block size = SIZE * 512 bytes
|
||||
-B I/O block size = 5120 bytes
|
||||
-c Use the old portable (ASCII) archive format
|
||||
-C, --io-size=NUMBER I/O block size to the given NUMBER bytes
|
||||
-f, --nonmatching Only copy files that do not match given pattern
|
||||
-F, --file=FILE Use FILE instead of standard input or output
|
||||
-H, --format=FORMAT Use given archive FORMAT
|
||||
-M, --message=STRING Print STRING when the end of a volume of the
|
||||
backup media is reached
|
||||
-n, --numeric-uid-gid If -v, show numeric UID and GID
|
||||
--quiet Do not print the number of blocks copied
|
||||
--rsh-command=COMMAND Use remote COMMAND instead of rsh
|
||||
-v, --verbose Verbosely list the files processed
|
||||
-V, --dot Print a "." for each file processed
|
||||
-W, --warning=FLAG Control warning display: 'none','truncate','all';
|
||||
multiple options accumulate
|
||||
|
||||
Operation modifiers valid only in --extract mode:
|
||||
-b, --swap Swap both halfwords of words and bytes of
|
||||
halfwords in the data (equivalent to -sS)
|
||||
-r, --rename Interactively rename files
|
||||
-s, --swap-bytes Swap the bytes of each halfword in the files
|
||||
-S, --swap-halfwords Swap the halfwords of each word (4 bytes)
|
||||
--to-stdout Extract files to standard output
|
||||
-E, --pattern-file=FILE Read additional patterns specifying filenames to
|
||||
extract or list from FILE
|
||||
--only-verify-crc Verify CRC's, don't actually extract the files
|
||||
|
||||
Operation modifiers valid only in --create mode:
|
||||
-A, --append Append to an existing archive
|
||||
-O FILE File to use instead of standard output
|
||||
|
||||
Operation modifiers valid only in --pass-through mode:
|
||||
-l, --link Link files instead of copying them, when possible
|
||||
|
||||
Operation modifiers valid in --extract and --create modes:
|
||||
--absolute-filenames Do not strip file system prefix components from
|
||||
the file names
|
||||
--no-absolute-filenames Create all files relative to the current dir
|
||||
|
||||
Operation modifiers valid in --create and --pass-through modes:
|
||||
-0, --null A list of filenames is terminated by a NUL
|
||||
-a, --reset-access-time Reset the access times of files after reading them
|
||||
-I FILE File to use instead of standard input
|
||||
-L, --dereference Dereference symbolic links (copy the files
|
||||
that they point to instead of copying the links)
|
||||
-R, --owner=[USER][:.][GROUP] Set owner of created files
|
||||
|
||||
Operation modifiers valid in --extract and --pass-through modes:
|
||||
-d, --make-directories Create leading directories where needed
|
||||
-m, --preserve-modification-time
|
||||
Retain previous file modification times when
|
||||
creating files
|
||||
--no-preserve-owner Do not change the ownership of the files
|
||||
--sparse Write files with blocks of zeros as sparse files
|
||||
-u, --unconditional Replace all files unconditionally
|
||||
*/
|
||||
|
||||
int cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
||||
int cpio_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
archive_handle_t *archive_handle;
|
||||
char *cpio_filename;
|
||||
#if ENABLE_FEATURE_CPIO_O
|
||||
const char *cpio_fmt = "";
|
||||
#endif
|
||||
USE_FEATURE_CPIO_O(const char *cpio_fmt = "";)
|
||||
unsigned opt;
|
||||
enum {
|
||||
CPIO_OPT_EXTRACT = (1 << 0),
|
||||
CPIO_OPT_TEST = (1 << 1),
|
||||
CPIO_OPT_UNCONDITIONAL = (1 << 2),
|
||||
CPIO_OPT_VERBOSE = (1 << 3),
|
||||
CPIO_OPT_FILE = (1 << 4),
|
||||
CPIO_OPT_CREATE_LEADING_DIR = (1 << 5),
|
||||
CPIO_OPT_PRESERVE_MTIME = (1 << 6),
|
||||
CPIO_OPT_CREATE = (1 << 7),
|
||||
CPIO_OPT_FORMAT = (1 << 8),
|
||||
};
|
||||
|
||||
#if ENABLE_GETOPT_LONG && ENABLE_DESKTOP
|
||||
applet_long_options =
|
||||
"extract\0" No_argument "i"
|
||||
"list\0" No_argument "t"
|
||||
#if ENABLE_FEATURE_CPIO_O
|
||||
"create\0" No_argument "o"
|
||||
"format\0" Required_argument "H"
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Initialize */
|
||||
archive_handle = init_handle();
|
||||
archive_handle->src_fd = STDIN_FILENO;
|
||||
archive_handle->seek = seek_by_read;
|
||||
archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE;
|
||||
archive_handle->flags = ARCHIVE_EXTRACT_NEWER;
|
||||
|
||||
#if ENABLE_FEATURE_CPIO_O
|
||||
opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt);
|
||||
|
@ -258,6 +333,9 @@ int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||
if (opt & CPIO_OPT_CREATE_LEADING_DIR) {
|
||||
archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS;
|
||||
}
|
||||
if (opt & CPIO_OPT_PRESERVE_MTIME) {
|
||||
archive_handle->flags |= ARCHIVE_PRESERVE_DATE;
|
||||
}
|
||||
|
||||
while (*argv) {
|
||||
archive_handle->filter = filter_accept_list;
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include "libbb.h"
|
||||
#include "unarchive.h"
|
||||
|
||||
typedef struct hardlinks_s {
|
||||
struct hardlinks_s *next;
|
||||
typedef struct hardlinks_t {
|
||||
struct hardlinks_t *next;
|
||||
int inode; /* TODO: must match maj/min too! */
|
||||
int mode ;
|
||||
int mtime; /* These three are useful only in corner case */
|
||||
|
@ -144,6 +144,7 @@ char get_header_cpio(archive_handle_t *archive_handle)
|
|||
free(make_me);
|
||||
goto next_link;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
/* Oops... no file with such inode was created... do it now
|
||||
* (happens when hardlinked files are empty (zero length)) */
|
||||
|
|
|
@ -4,13 +4,7 @@
|
|||
|
||||
. testing.sh
|
||||
|
||||
# check if hexdump supports the '-R' option
|
||||
hexdump -R </dev/null >/dev/null 2>&1 || {
|
||||
echo "'hexdump -R' is not available" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ls -ln is showing date. Need to remove that, it's variable
|
||||
# ls -ln shows date. Need to remove that, it's variable.
|
||||
# sed: coalesce spaces
|
||||
# cut: remove date
|
||||
FILTER_LS="sed 's/ */ /g' | cut -d' ' -f 1-5,9-"
|
||||
|
@ -18,28 +12,27 @@ FILTER_LS="sed 's/ */ /g' | cut -d' ' -f 1-5,9-"
|
|||
|
||||
# newc cpio archive of directory cpio.testdir with empty x and y hardlinks
|
||||
hexdump="\
|
||||
00000000 42 5a 68 39 31 41 59 26 53 59 64 1e 91 8c 00 00
|
||||
00000010 48 7f 80 4c 48 08 00 28 01 ff e0 3f 24 14 00 0e
|
||||
00000020 20 dc 60 20 00 92 11 ea a0 1a 00 00 00 03 20 8a
|
||||
00000030 93 d4 9a 68 1a 0d 1e 91 a1 a0 06 98 e3 5c 2f d9
|
||||
00000040 26 a1 25 24 20 ed 47 c7 21 40 2b 6e f2 e6 fe 98
|
||||
00000050 13 68 a8 bd 82 b2 4f 26 02 24 16 5b 22 16 72 74
|
||||
00000060 15 cd c1 a6 9e a6 5e 6c 16 37 35 01 99 c4 81 21
|
||||
00000070 29 28 4b 69 51 a9 3c 1a 9b 0a e1 e4 b4 af 85 73
|
||||
00000080 ba 23 10 59 e8 b3 e1 a1 63 05 8c 4f c5 dc 91 4e
|
||||
00000090 14 24 19 07 a4 63 00
|
||||
"
|
||||
\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x64\x1e\x91\x8c\x00\x00\
|
||||
\x48\x7f\x80\x4c\x48\x08\x00\x28\x01\xff\xe0\x3f\x24\x14\x00\x0e\
|
||||
\x20\xdc\x60\x20\x00\x92\x11\xea\xa0\x1a\x00\x00\x00\x03\x20\x8a\
|
||||
\x93\xd4\x9a\x68\x1a\x0d\x1e\x91\xa1\xa0\x06\x98\xe3\x5c\x2f\xd9\
|
||||
\x26\xa1\x25\x24\x20\xed\x47\xc7\x21\x40\x2b\x6e\xf2\xe6\xfe\x98\
|
||||
\x13\x68\xa8\xbd\x82\xb2\x4f\x26\x02\x24\x16\x5b\x22\x16\x72\x74\
|
||||
\x15\xcd\xc1\xa6\x9e\xa6\x5e\x6c\x16\x37\x35\x01\x99\xc4\x81\x21\
|
||||
\x29\x28\x4b\x69\x51\xa9\x3c\x1a\x9b\x0a\xe1\xe4\xb4\xaf\x85\x73\
|
||||
\xba\x23\x10\x59\xe8\xb3\xe1\xa1\x63\x05\x8c\x4f\xc5\xdc\x91\x4e\
|
||||
\x14\x24\x19\x07\xa4\x63\x00"
|
||||
|
||||
user=$(id -u)
|
||||
group=$(id -g)
|
||||
|
||||
rm -rf cpio.testdir
|
||||
rm -rf cpio.testdir cpio.testdir2 2>/dev/null
|
||||
|
||||
# testing "test name" "options" "expected result" "file input" "stdin"
|
||||
# testing "test name" "command" "expected result" "file input" "stdin"
|
||||
|
||||
testing "cpio extracts zero-sized hardlinks" \
|
||||
"echo '$hexdump' | hexdump -R | bzcat | cpio -i; echo \$?;
|
||||
ls -ln cpio.testdir | $FILTER_LS" \
|
||||
"echo -ne '$hexdump' | bzcat | cpio -i; echo \$?;
|
||||
ls -ln cpio.testdir | $FILTER_LS" \
|
||||
"\
|
||||
1 blocks
|
||||
0
|
||||
|
@ -51,7 +44,7 @@ testing "cpio extracts zero-sized hardlinks" \
|
|||
# Currently fails. Numerous: "1 blocks" versus "1 block",
|
||||
# "1 block" must go to stderr, does not list cpio.testdir/x and cpio.testdir/y
|
||||
testing "cpio lists hardlinks" \
|
||||
"echo '$hexdump' | hexdump -R | bzcat | cpio -t 2>&1; echo \$?" \
|
||||
"echo -ne '$hexdump' | bzcat | cpio -t 2>&1; echo \$?" \
|
||||
"\
|
||||
1 block
|
||||
cpio.testdir
|
||||
|
@ -61,7 +54,30 @@ cpio.testdir/y
|
|||
" \
|
||||
"" ""
|
||||
|
||||
# clean up
|
||||
rm -rf cpio.testdir
|
||||
# More complex case
|
||||
rm -rf cpio.testdir cpio.testdir2 2>/dev/null
|
||||
mkdir cpio.testdir
|
||||
touch cpio.testdir/solo
|
||||
touch cpio.testdir/empty
|
||||
echo x >cpio.testdir/nonempty
|
||||
ln cpio.testdir/empty cpio.testdir/empty1
|
||||
ln cpio.testdir/nonempty cpio.testdir/nonempty1
|
||||
mkdir cpio.testdir2
|
||||
|
||||
testing "cpio extracts zero-sized hardlinks 2" \
|
||||
"find cpio.testdir | cpio -H newc --create | (cd cpio.testdir2 && cpio -i); echo \$?;
|
||||
ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \
|
||||
"\
|
||||
0
|
||||
-rw-r--r-- 2 $user $group 0 empty
|
||||
-rw-r--r-- 2 $user $group 0 empty1
|
||||
-rw-r--r-- 2 $user $group 2 nonempty
|
||||
-rw-r--r-- 2 $user $group 2 nonempty1
|
||||
-rw-r--r-- 1 $user $group 0 solo
|
||||
" \
|
||||
"" ""
|
||||
|
||||
# Clean up
|
||||
rm -rf cpio.testdir cpio.testdir2 2>/dev/null
|
||||
|
||||
exit $FAILCOUNT
|
||||
|
|
Loading…
Reference in New Issue