aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-12-16 23:18:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-12-16 23:18:59 +0100
commit8a936cfab718aee9f304f1b41e6b16cf6b5999f9 (patch)
tree5ae3e37a204a8d13e7e70b84a48ec415e464e98a
parent425ad9c93b2736a0ebfbba6267bc1ad56c49d156 (diff)
downloadbusybox-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.c5
-rw-r--r--archival/tar.c13
-rw-r--r--include/unarchive.h3
-rwxr-xr-xtestsuite/tar.tests13
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
776static const char tar_longopts[] ALIGN1 = 778static 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
34testing "tar --overwrite" "\
35rm -rf input_* test.tar 2>/dev/null
36ln input input_hard
37tar cf test.tar input_hard
38echo WRONG >input
39# --overwrite opens 'input_hard' without unlinking,
40# thus 'input_hard' still linked to 'input' and we write 'Ok' into it
41tar xf test.tar --overwrite 2>&1 && cat input
42" "\
43Ok
44" \
45"Ok\n" ""
46
34cd .. && rm -rf tempdir || exit 1 47cd .. && rm -rf tempdir || exit 1
35 48
36exit $FAILCOUNT 49exit $FAILCOUNT