diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-16 23:18:59 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-16 23:18:59 +0100 |
commit | 8a936cfab718aee9f304f1b41e6b16cf6b5999f9 (patch) | |
tree | 5ae3e37a204a8d13e7e70b84a48ec415e464e98a | |
parent | 425ad9c93b2736a0ebfbba6267bc1ad56c49d156 (diff) | |
download | busybox-w32-8a936cfab718aee9f304f1b41e6b16cf6b5999f9.tar.gz busybox-w32-8a936cfab718aee9f304f1b41e6b16cf6b5999f9.tar.bz2 busybox-w32-8a936cfab718aee9f304f1b41e6b16cf6b5999f9.zip |
tar: add support for --overwrite. +70 bytes.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libunarchive/data_extract_all.c | 5 | ||||
-rw-r--r-- | archival/tar.c | 13 | ||||
-rw-r--r-- | include/unarchive.h | 3 | ||||
-rwxr-xr-x | testsuite/tar.tests | 13 |
4 files changed, 30 insertions, 4 deletions
diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index ae242df64..874d37d94 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c | |||
@@ -72,8 +72,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
72 | switch (file_header->mode & S_IFMT) { | 72 | switch (file_header->mode & S_IFMT) { |
73 | case S_IFREG: { | 73 | case S_IFREG: { |
74 | /* Regular file */ | 74 | /* Regular file */ |
75 | int flags = O_WRONLY | O_CREAT | O_EXCL; | ||
76 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | ||
77 | flags = O_WRONLY | O_CREAT | O_TRUNC; | ||
75 | dst_fd = xopen3(file_header->name, | 78 | dst_fd = xopen3(file_header->name, |
76 | O_WRONLY | O_CREAT | O_EXCL, | 79 | flags, |
77 | file_header->mode | 80 | file_header->mode |
78 | ); | 81 | ); |
79 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); | 82 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); |
diff --git a/archival/tar.c b/archival/tar.c index 7ec101d31..5994d8913 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -751,6 +751,7 @@ enum { | |||
751 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 751 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
752 | OPTBIT_NUMERIC_OWNER, | 752 | OPTBIT_NUMERIC_OWNER, |
753 | OPTBIT_NOPRESERVE_PERM, | 753 | OPTBIT_NOPRESERVE_PERM, |
754 | OPTBIT_OVERWRITE, | ||
754 | #endif | 755 | #endif |
755 | OPT_TEST = 1 << 0, // t | 756 | OPT_TEST = 1 << 0, // t |
756 | OPT_EXTRACT = 1 << 1, // x | 757 | OPT_EXTRACT = 1 << 1, // x |
@@ -771,6 +772,7 @@ enum { | |||
771 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z | 772 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
772 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 773 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
773 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 774 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
775 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | ||
774 | }; | 776 | }; |
775 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 777 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
776 | static const char tar_longopts[] ALIGN1 = | 778 | static const char tar_longopts[] ALIGN1 = |
@@ -807,9 +809,11 @@ static const char tar_longopts[] ALIGN1 = | |||
807 | "compress\0" No_argument "Z" | 809 | "compress\0" No_argument "Z" |
808 | # endif | 810 | # endif |
809 | /* use numeric uid/gid from tar header, not textual */ | 811 | /* use numeric uid/gid from tar header, not textual */ |
810 | "numeric-owner\0" No_argument "\xfd" | 812 | "numeric-owner\0" No_argument "\xfc" |
811 | /* do not restore mode */ | 813 | /* do not restore mode */ |
812 | "no-same-permissions\0" No_argument "\xfe" | 814 | "no-same-permissions\0" No_argument "\xfd" |
815 | /* on unpack, open with O_TRUNC and !O_EXCL */ | ||
816 | "overwrite\0" No_argument "\xfe" | ||
813 | /* --exclude takes next bit position in option mask, */ | 817 | /* --exclude takes next bit position in option mask, */ |
814 | /* therefore we have to put it _after_ --no-same-permissions */ | 818 | /* therefore we have to put it _after_ --no-same-permissions */ |
815 | # if ENABLE_FEATURE_TAR_FROM | 819 | # if ENABLE_FEATURE_TAR_FROM |
@@ -924,6 +928,11 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
924 | if (opt & OPT_NOPRESERVE_PERM) | 928 | if (opt & OPT_NOPRESERVE_PERM) |
925 | tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM; | 929 | tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM; |
926 | 930 | ||
931 | if (opt & OPT_OVERWRITE) { | ||
932 | tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; | ||
933 | tar_handle->ah_flags |= ARCHIVE_O_TRUNC; | ||
934 | } | ||
935 | |||
927 | if (opt & OPT_GZIP) | 936 | if (opt & OPT_GZIP) |
928 | get_header_ptr = get_header_tar_gz; | 937 | get_header_ptr = get_header_tar_gz; |
929 | 938 | ||
diff --git a/include/unarchive.h b/include/unarchive.h index 35ce52181..68e83f01c 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -58,7 +58,7 @@ typedef struct archive_handle_t { | |||
58 | char *ah_buffer; | 58 | char *ah_buffer; |
59 | 59 | ||
60 | /* Flags and misc. stuff */ | 60 | /* Flags and misc. stuff */ |
61 | unsigned char ah_flags; | 61 | unsigned ah_flags; |
62 | 62 | ||
63 | /* "Private" storage for archivers */ | 63 | /* "Private" storage for archivers */ |
64 | // unsigned char ah_priv_inited; | 64 | // unsigned char ah_priv_inited; |
@@ -74,6 +74,7 @@ typedef struct archive_handle_t { | |||
74 | #define ARCHIVE_DONT_RESTORE_OWNER (1 << 5) | 74 | #define ARCHIVE_DONT_RESTORE_OWNER (1 << 5) |
75 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) | 75 | #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) |
76 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) | 76 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) |
77 | #define ARCHIVE_O_TRUNC (1 << 8) | ||
77 | 78 | ||
78 | 79 | ||
79 | /* Info struct unpackers can fill out to inform users of thing like | 80 | /* Info struct unpackers can fill out to inform users of thing like |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 35f96b77e..6c136a615 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -31,6 +31,19 @@ Ok | |||
31 | " \ | 31 | " \ |
32 | "" "" | 32 | "" "" |
33 | 33 | ||
34 | testing "tar --overwrite" "\ | ||
35 | rm -rf input_* test.tar 2>/dev/null | ||
36 | ln input input_hard | ||
37 | tar cf test.tar input_hard | ||
38 | echo WRONG >input | ||
39 | # --overwrite opens 'input_hard' without unlinking, | ||
40 | # thus 'input_hard' still linked to 'input' and we write 'Ok' into it | ||
41 | tar xf test.tar --overwrite 2>&1 && cat input | ||
42 | " "\ | ||
43 | Ok | ||
44 | " \ | ||
45 | "Ok\n" "" | ||
46 | |||
34 | cd .. && rm -rf tempdir || exit 1 | 47 | cd .. && rm -rf tempdir || exit 1 |
35 | 48 | ||
36 | exit $FAILCOUNT | 49 | exit $FAILCOUNT |