diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-11 21:47:23 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-11 21:47:23 +0000 |
commit | fa1649e9ac6ec8d84f10a14f4f1e28b86645206f (patch) | |
tree | 9d2a6a659f53d7af59e3d92addef739ae9bc36e8 | |
parent | dee8587d9208e4ea5ba8f8bb73b555007529372e (diff) | |
download | busybox-w32-fa1649e9ac6ec8d84f10a14f4f1e28b86645206f.tar.gz busybox-w32-fa1649e9ac6ec8d84f10a14f4f1e28b86645206f.tar.bz2 busybox-w32-fa1649e9ac6ec8d84f10a14f4f1e28b86645206f.zip |
cpio: backport the fix for
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466771
-rw-r--r-- | archival/cpio.c | 110 | ||||
-rw-r--r-- | archival/libunarchive/get_header_cpio.c | 5 | ||||
-rwxr-xr-x | testsuite/cpio.tests | 66 |
3 files changed, 138 insertions, 43 deletions
diff --git a/archival/cpio.c b/archival/cpio.c index 2919ff8de..bf442d789 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -14,18 +14,6 @@ | |||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | #include "unarchive.h" | 15 | #include "unarchive.h" |
16 | 16 | ||
17 | enum { | ||
18 | CPIO_OPT_EXTRACT = (1 << 0), | ||
19 | CPIO_OPT_TEST = (1 << 1), | ||
20 | CPIO_OPT_UNCONDITIONAL = (1 << 2), | ||
21 | CPIO_OPT_VERBOSE = (1 << 3), | ||
22 | CPIO_OPT_FILE = (1 << 4), | ||
23 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), | ||
24 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), | ||
25 | CPIO_OPT_CREATE = (1 << 7), | ||
26 | CPIO_OPT_FORMAT = (1 << 8), | ||
27 | }; | ||
28 | |||
29 | #if ENABLE_FEATURE_CPIO_O | 17 | #if ENABLE_FEATURE_CPIO_O |
30 | static off_t cpio_pad4(off_t size) | 18 | static off_t cpio_pad4(off_t size) |
31 | { | 19 | { |
@@ -190,21 +178,108 @@ static int cpio_o(void) | |||
190 | } | 178 | } |
191 | #endif | 179 | #endif |
192 | 180 | ||
181 | /* GNU cpio (GNU cpio) 2.9 help (abridged): | ||
182 | |||
183 | Main operation mode: | ||
184 | -i, --extract Extract files from an archive | ||
185 | -o, --create Create the archive | ||
186 | -p, --pass-through Copy-pass mode (was ist das?!) | ||
187 | -t, --list List the archive | ||
188 | |||
189 | Operation modifiers valid in any mode: | ||
190 | --block-size=SIZE I/O block size = SIZE * 512 bytes | ||
191 | -B I/O block size = 5120 bytes | ||
192 | -c Use the old portable (ASCII) archive format | ||
193 | -C, --io-size=NUMBER I/O block size to the given NUMBER bytes | ||
194 | -f, --nonmatching Only copy files that do not match given pattern | ||
195 | -F, --file=FILE Use FILE instead of standard input or output | ||
196 | -H, --format=FORMAT Use given archive FORMAT | ||
197 | -M, --message=STRING Print STRING when the end of a volume of the | ||
198 | backup media is reached | ||
199 | -n, --numeric-uid-gid If -v, show numeric UID and GID | ||
200 | --quiet Do not print the number of blocks copied | ||
201 | --rsh-command=COMMAND Use remote COMMAND instead of rsh | ||
202 | -v, --verbose Verbosely list the files processed | ||
203 | -V, --dot Print a "." for each file processed | ||
204 | -W, --warning=FLAG Control warning display: 'none','truncate','all'; | ||
205 | multiple options accumulate | ||
206 | |||
207 | Operation modifiers valid only in --extract mode: | ||
208 | -b, --swap Swap both halfwords of words and bytes of | ||
209 | halfwords in the data (equivalent to -sS) | ||
210 | -r, --rename Interactively rename files | ||
211 | -s, --swap-bytes Swap the bytes of each halfword in the files | ||
212 | -S, --swap-halfwords Swap the halfwords of each word (4 bytes) | ||
213 | --to-stdout Extract files to standard output | ||
214 | -E, --pattern-file=FILE Read additional patterns specifying filenames to | ||
215 | extract or list from FILE | ||
216 | --only-verify-crc Verify CRC's, don't actually extract the files | ||
217 | |||
218 | Operation modifiers valid only in --create mode: | ||
219 | -A, --append Append to an existing archive | ||
220 | -O FILE File to use instead of standard output | ||
221 | |||
222 | Operation modifiers valid only in --pass-through mode: | ||
223 | -l, --link Link files instead of copying them, when possible | ||
224 | |||
225 | Operation modifiers valid in --extract and --create modes: | ||
226 | --absolute-filenames Do not strip file system prefix components from | ||
227 | the file names | ||
228 | --no-absolute-filenames Create all files relative to the current dir | ||
229 | |||
230 | Operation modifiers valid in --create and --pass-through modes: | ||
231 | -0, --null A list of filenames is terminated by a NUL | ||
232 | -a, --reset-access-time Reset the access times of files after reading them | ||
233 | -I FILE File to use instead of standard input | ||
234 | -L, --dereference Dereference symbolic links (copy the files | ||
235 | that they point to instead of copying the links) | ||
236 | -R, --owner=[USER][:.][GROUP] Set owner of created files | ||
237 | |||
238 | Operation modifiers valid in --extract and --pass-through modes: | ||
239 | -d, --make-directories Create leading directories where needed | ||
240 | -m, --preserve-modification-time | ||
241 | Retain previous file modification times when | ||
242 | creating files | ||
243 | --no-preserve-owner Do not change the ownership of the files | ||
244 | --sparse Write files with blocks of zeros as sparse files | ||
245 | -u, --unconditional Replace all files unconditionally | ||
246 | */ | ||
247 | |||
193 | int cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 248 | int cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
194 | int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv) | 249 | int cpio_main(int argc UNUSED_PARAM, char **argv) |
195 | { | 250 | { |
196 | archive_handle_t *archive_handle; | 251 | archive_handle_t *archive_handle; |
197 | char *cpio_filename; | 252 | char *cpio_filename; |
253 | USE_FEATURE_CPIO_O(const char *cpio_fmt = "";) | ||
254 | unsigned opt; | ||
255 | enum { | ||
256 | CPIO_OPT_EXTRACT = (1 << 0), | ||
257 | CPIO_OPT_TEST = (1 << 1), | ||
258 | CPIO_OPT_UNCONDITIONAL = (1 << 2), | ||
259 | CPIO_OPT_VERBOSE = (1 << 3), | ||
260 | CPIO_OPT_FILE = (1 << 4), | ||
261 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), | ||
262 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), | ||
263 | CPIO_OPT_CREATE = (1 << 7), | ||
264 | CPIO_OPT_FORMAT = (1 << 8), | ||
265 | }; | ||
266 | |||
267 | #if ENABLE_GETOPT_LONG && ENABLE_DESKTOP | ||
268 | applet_long_options = | ||
269 | "extract\0" No_argument "i" | ||
270 | "list\0" No_argument "t" | ||
198 | #if ENABLE_FEATURE_CPIO_O | 271 | #if ENABLE_FEATURE_CPIO_O |
199 | const char *cpio_fmt = ""; | 272 | "create\0" No_argument "o" |
273 | "format\0" Required_argument "H" | ||
274 | #endif | ||
275 | ; | ||
200 | #endif | 276 | #endif |
201 | unsigned opt; | ||
202 | 277 | ||
203 | /* Initialize */ | 278 | /* Initialize */ |
204 | archive_handle = init_handle(); | 279 | archive_handle = init_handle(); |
205 | archive_handle->src_fd = STDIN_FILENO; | 280 | archive_handle->src_fd = STDIN_FILENO; |
206 | archive_handle->seek = seek_by_read; | 281 | archive_handle->seek = seek_by_read; |
207 | archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE; | 282 | archive_handle->flags = ARCHIVE_EXTRACT_NEWER; |
208 | 283 | ||
209 | #if ENABLE_FEATURE_CPIO_O | 284 | #if ENABLE_FEATURE_CPIO_O |
210 | opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); | 285 | opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); |
@@ -258,6 +333,9 @@ int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
258 | if (opt & CPIO_OPT_CREATE_LEADING_DIR) { | 333 | if (opt & CPIO_OPT_CREATE_LEADING_DIR) { |
259 | archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; | 334 | archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; |
260 | } | 335 | } |
336 | if (opt & CPIO_OPT_PRESERVE_MTIME) { | ||
337 | archive_handle->flags |= ARCHIVE_PRESERVE_DATE; | ||
338 | } | ||
261 | 339 | ||
262 | while (*argv) { | 340 | while (*argv) { |
263 | archive_handle->filter = filter_accept_list; | 341 | archive_handle->filter = filter_accept_list; |
diff --git a/archival/libunarchive/get_header_cpio.c b/archival/libunarchive/get_header_cpio.c index b97b53b20..0b9d385c1 100644 --- a/archival/libunarchive/get_header_cpio.c +++ b/archival/libunarchive/get_header_cpio.c | |||
@@ -7,8 +7,8 @@ | |||
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "unarchive.h" | 8 | #include "unarchive.h" |
9 | 9 | ||
10 | typedef struct hardlinks_s { | 10 | typedef struct hardlinks_t { |
11 | struct hardlinks_s *next; | 11 | struct hardlinks_t *next; |
12 | int inode; /* TODO: must match maj/min too! */ | 12 | int inode; /* TODO: must match maj/min too! */ |
13 | int mode ; | 13 | int mode ; |
14 | int mtime; /* These three are useful only in corner case */ | 14 | int mtime; /* These three are useful only in corner case */ |
@@ -144,6 +144,7 @@ char get_header_cpio(archive_handle_t *archive_handle) | |||
144 | free(make_me); | 144 | free(make_me); |
145 | goto next_link; | 145 | goto next_link; |
146 | } | 146 | } |
147 | cur = cur->next; | ||
147 | } | 148 | } |
148 | /* Oops... no file with such inode was created... do it now | 149 | /* Oops... no file with such inode was created... do it now |
149 | * (happens when hardlinked files are empty (zero length)) */ | 150 | * (happens when hardlinked files are empty (zero length)) */ |
diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests index 55594b3a6..6514e3f4c 100755 --- a/testsuite/cpio.tests +++ b/testsuite/cpio.tests | |||
@@ -4,13 +4,7 @@ | |||
4 | 4 | ||
5 | . testing.sh | 5 | . testing.sh |
6 | 6 | ||
7 | # check if hexdump supports the '-R' option | 7 | # ls -ln shows date. Need to remove that, it's variable. |
8 | hexdump -R </dev/null >/dev/null 2>&1 || { | ||
9 | echo "'hexdump -R' is not available" >&2 | ||
10 | exit 1 | ||
11 | } | ||
12 | |||
13 | # ls -ln is showing date. Need to remove that, it's variable | ||
14 | # sed: coalesce spaces | 8 | # sed: coalesce spaces |
15 | # cut: remove date | 9 | # cut: remove date |
16 | FILTER_LS="sed 's/ */ /g' | cut -d' ' -f 1-5,9-" | 10 | 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-" | |||
18 | 12 | ||
19 | # newc cpio archive of directory cpio.testdir with empty x and y hardlinks | 13 | # newc cpio archive of directory cpio.testdir with empty x and y hardlinks |
20 | hexdump="\ | 14 | hexdump="\ |
21 | 00000000 42 5a 68 39 31 41 59 26 53 59 64 1e 91 8c 00 00 | 15 | \x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x64\x1e\x91\x8c\x00\x00\ |
22 | 00000010 48 7f 80 4c 48 08 00 28 01 ff e0 3f 24 14 00 0e | 16 | \x48\x7f\x80\x4c\x48\x08\x00\x28\x01\xff\xe0\x3f\x24\x14\x00\x0e\ |
23 | 00000020 20 dc 60 20 00 92 11 ea a0 1a 00 00 00 03 20 8a | 17 | \x20\xdc\x60\x20\x00\x92\x11\xea\xa0\x1a\x00\x00\x00\x03\x20\x8a\ |
24 | 00000030 93 d4 9a 68 1a 0d 1e 91 a1 a0 06 98 e3 5c 2f d9 | 18 | \x93\xd4\x9a\x68\x1a\x0d\x1e\x91\xa1\xa0\x06\x98\xe3\x5c\x2f\xd9\ |
25 | 00000040 26 a1 25 24 20 ed 47 c7 21 40 2b 6e f2 e6 fe 98 | 19 | \x26\xa1\x25\x24\x20\xed\x47\xc7\x21\x40\x2b\x6e\xf2\xe6\xfe\x98\ |
26 | 00000050 13 68 a8 bd 82 b2 4f 26 02 24 16 5b 22 16 72 74 | 20 | \x13\x68\xa8\xbd\x82\xb2\x4f\x26\x02\x24\x16\x5b\x22\x16\x72\x74\ |
27 | 00000060 15 cd c1 a6 9e a6 5e 6c 16 37 35 01 99 c4 81 21 | 21 | \x15\xcd\xc1\xa6\x9e\xa6\x5e\x6c\x16\x37\x35\x01\x99\xc4\x81\x21\ |
28 | 00000070 29 28 4b 69 51 a9 3c 1a 9b 0a e1 e4 b4 af 85 73 | 22 | \x29\x28\x4b\x69\x51\xa9\x3c\x1a\x9b\x0a\xe1\xe4\xb4\xaf\x85\x73\ |
29 | 00000080 ba 23 10 59 e8 b3 e1 a1 63 05 8c 4f c5 dc 91 4e | 23 | \xba\x23\x10\x59\xe8\xb3\xe1\xa1\x63\x05\x8c\x4f\xc5\xdc\x91\x4e\ |
30 | 00000090 14 24 19 07 a4 63 00 | 24 | \x14\x24\x19\x07\xa4\x63\x00" |
31 | " | ||
32 | 25 | ||
33 | user=$(id -u) | 26 | user=$(id -u) |
34 | group=$(id -g) | 27 | group=$(id -g) |
35 | 28 | ||
36 | rm -rf cpio.testdir | 29 | rm -rf cpio.testdir cpio.testdir2 2>/dev/null |
37 | 30 | ||
38 | # testing "test name" "options" "expected result" "file input" "stdin" | 31 | # testing "test name" "command" "expected result" "file input" "stdin" |
39 | 32 | ||
40 | testing "cpio extracts zero-sized hardlinks" \ | 33 | testing "cpio extracts zero-sized hardlinks" \ |
41 | "echo '$hexdump' | hexdump -R | bzcat | cpio -i; echo \$?; | 34 | "echo -ne '$hexdump' | bzcat | cpio -i; echo \$?; |
42 | ls -ln cpio.testdir | $FILTER_LS" \ | 35 | ls -ln cpio.testdir | $FILTER_LS" \ |
43 | "\ | 36 | "\ |
44 | 1 blocks | 37 | 1 blocks |
45 | 0 | 38 | 0 |
@@ -51,7 +44,7 @@ testing "cpio extracts zero-sized hardlinks" \ | |||
51 | # Currently fails. Numerous: "1 blocks" versus "1 block", | 44 | # Currently fails. Numerous: "1 blocks" versus "1 block", |
52 | # "1 block" must go to stderr, does not list cpio.testdir/x and cpio.testdir/y | 45 | # "1 block" must go to stderr, does not list cpio.testdir/x and cpio.testdir/y |
53 | testing "cpio lists hardlinks" \ | 46 | testing "cpio lists hardlinks" \ |
54 | "echo '$hexdump' | hexdump -R | bzcat | cpio -t 2>&1; echo \$?" \ | 47 | "echo -ne '$hexdump' | bzcat | cpio -t 2>&1; echo \$?" \ |
55 | "\ | 48 | "\ |
56 | 1 block | 49 | 1 block |
57 | cpio.testdir | 50 | cpio.testdir |
@@ -61,7 +54,30 @@ cpio.testdir/y | |||
61 | " \ | 54 | " \ |
62 | "" "" | 55 | "" "" |
63 | 56 | ||
64 | # clean up | 57 | # More complex case |
65 | rm -rf cpio.testdir | 58 | rm -rf cpio.testdir cpio.testdir2 2>/dev/null |
59 | mkdir cpio.testdir | ||
60 | touch cpio.testdir/solo | ||
61 | touch cpio.testdir/empty | ||
62 | echo x >cpio.testdir/nonempty | ||
63 | ln cpio.testdir/empty cpio.testdir/empty1 | ||
64 | ln cpio.testdir/nonempty cpio.testdir/nonempty1 | ||
65 | mkdir cpio.testdir2 | ||
66 | |||
67 | testing "cpio extracts zero-sized hardlinks 2" \ | ||
68 | "find cpio.testdir | cpio -H newc --create | (cd cpio.testdir2 && cpio -i); echo \$?; | ||
69 | ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \ | ||
70 | "\ | ||
71 | 0 | ||
72 | -rw-r--r-- 2 $user $group 0 empty | ||
73 | -rw-r--r-- 2 $user $group 0 empty1 | ||
74 | -rw-r--r-- 2 $user $group 2 nonempty | ||
75 | -rw-r--r-- 2 $user $group 2 nonempty1 | ||
76 | -rw-r--r-- 1 $user $group 0 solo | ||
77 | " \ | ||
78 | "" "" | ||
79 | |||
80 | # Clean up | ||
81 | rm -rf cpio.testdir cpio.testdir2 2>/dev/null | ||
66 | 82 | ||
67 | exit $FAILCOUNT | 83 | exit $FAILCOUNT |