aboutsummaryrefslogtreecommitdiff
path: root/archival/tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/tar.c')
-rw-r--r--archival/tar.c121
1 files changed, 79 insertions, 42 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 3a940128b..5ddff7fa5 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -48,37 +48,6 @@
48 48
49#if ENABLE_FEATURE_TAR_CREATE 49#if ENABLE_FEATURE_TAR_CREATE
50 50
51/* Tar file constants */
52
53#define TAR_BLOCK_SIZE 512
54
55/* POSIX tar Header Block, from POSIX 1003.1-1990 */
56#define NAME_SIZE 100
57#define NAME_SIZE_STR "100"
58typedef struct TarHeader { /* byte offset */
59 char name[NAME_SIZE]; /* 0-99 */
60 char mode[8]; /* 100-107 */
61 char uid[8]; /* 108-115 */
62 char gid[8]; /* 116-123 */
63 char size[12]; /* 124-135 */
64 char mtime[12]; /* 136-147 */
65 char chksum[8]; /* 148-155 */
66 char typeflag; /* 156-156 */
67 char linkname[NAME_SIZE]; /* 157-256 */
68 /* POSIX: "ustar" NUL "00" */
69 /* GNU tar: "ustar " NUL */
70 /* Normally it's defined as magic[6] followed by
71 * version[2], but we put them together to save code.
72 */
73 char magic[8]; /* 257-264 */
74 char uname[32]; /* 265-296 */
75 char gname[32]; /* 297-328 */
76 char devmajor[8]; /* 329-336 */
77 char devminor[8]; /* 337-344 */
78 char prefix[155]; /* 345-499 */
79 char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */
80} TarHeader;
81
82/* 51/*
83** writeTarFile(), writeFileToTarball(), and writeTarHeader() are 52** writeTarFile(), writeFileToTarball(), and writeTarHeader() are
84** the only functions that deal with the HardLinkInfo structure. 53** the only functions that deal with the HardLinkInfo structure.
@@ -193,7 +162,7 @@ static void putOctal(char *cp, int len, off_t value)
193} 162}
194#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) 163#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b))
195 164
196static void chksum_and_xwrite(int fd, struct TarHeader* hp) 165static void chksum_and_xwrite(int fd, struct tar_header_t* hp)
197{ 166{
198 /* POSIX says that checksum is done on unsigned bytes 167 /* POSIX says that checksum is done on unsigned bytes
199 * (Sun and HP-UX gets it wrong... more details in 168 * (Sun and HP-UX gets it wrong... more details in
@@ -235,7 +204,7 @@ static void writeLongname(int fd, int type, const char *name, int dir)
235 "00000000000", 204 "00000000000",
236 "00000000000", 205 "00000000000",
237 }; 206 };
238 struct TarHeader header; 207 struct tar_header_t header;
239 int size; 208 int size;
240 209
241 dir = !!dir; /* normalize: 0/1 */ 210 dir = !!dir; /* normalize: 0/1 */
@@ -262,16 +231,12 @@ static void writeLongname(int fd, int type, const char *name, int dir)
262#endif 231#endif
263 232
264/* Write out a tar header for the specified file/directory/whatever */ 233/* Write out a tar header for the specified file/directory/whatever */
265void BUG_tar_header_size(void);
266static int writeTarHeader(struct TarBallInfo *tbInfo, 234static int writeTarHeader(struct TarBallInfo *tbInfo,
267 const char *header_name, const char *fileName, struct stat *statbuf) 235 const char *header_name, const char *fileName, struct stat *statbuf)
268{ 236{
269 struct TarHeader header; 237 struct tar_header_t header;
270 238
271 if (sizeof(header) != 512) 239 memset(&header, 0, sizeof(header));
272 BUG_tar_header_size();
273
274 memset(&header, 0, sizeof(struct TarHeader));
275 240
276 strncpy(header.name, header_name, sizeof(header.name)); 241 strncpy(header.name, header_name, sizeof(header.name));
277 242
@@ -549,9 +514,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
549 (void) &zip_exec; 514 (void) &zip_exec;
550# endif 515# endif
551 516
552 gzipPid = vfork(); 517 gzipPid = xvfork();
553 if (gzipPid < 0)
554 bb_perror_msg_and_die("vfork");
555 518
556 if (gzipPid == 0) { 519 if (gzipPid == 0) {
557 /* child */ 520 /* child */
@@ -738,6 +701,68 @@ static void handle_SIGCHLD(int status)
738} 701}
739#endif 702#endif
740 703
704//usage:#define tar_trivial_usage
705//usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" IF_FEATURE_SEAMLESS_GZ("z")
706//usage: IF_FEATURE_SEAMLESS_BZ2("j") IF_FEATURE_SEAMLESS_LZMA("a")
707//usage: IF_FEATURE_SEAMLESS_Z("Z") IF_FEATURE_TAR_NOPRESERVE_TIME("m") "vO] "
708//usage: IF_FEATURE_TAR_FROM("[-X FILE] ")
709//usage: "[-f TARFILE] [-C DIR] [FILE]..."
710//usage:#define tar_full_usage "\n\n"
711//usage: IF_FEATURE_TAR_CREATE("Create, extract, ")
712//usage: IF_NOT_FEATURE_TAR_CREATE("Extract ")
713//usage: "or list files from a tar file\n"
714//usage: "\nOperation:"
715//usage: IF_FEATURE_TAR_CREATE(
716//usage: "\n c Create"
717//usage: )
718//usage: "\n x Extract"
719//usage: "\n t List"
720//usage: "\nOptions:"
721//usage: "\n f Name of TARFILE ('-' for stdin/out)"
722//usage: "\n C Change to DIR before operation"
723//usage: "\n v Verbose"
724//usage: IF_FEATURE_SEAMLESS_GZ(
725//usage: "\n z (De)compress using gzip"
726//usage: )
727//usage: IF_FEATURE_SEAMLESS_BZ2(
728//usage: "\n j (De)compress using bzip2"
729//usage: )
730//usage: IF_FEATURE_SEAMLESS_LZMA(
731//usage: "\n a (De)compress using lzma"
732//usage: )
733//usage: IF_FEATURE_SEAMLESS_Z(
734//usage: "\n Z (De)compress using compress"
735//usage: )
736//usage: "\n O Extract to stdout"
737//usage: IF_FEATURE_TAR_CREATE(
738//usage: "\n h Follow symlinks"
739//usage: )
740//usage: IF_FEATURE_TAR_NOPRESERVE_TIME(
741//usage: "\n m Don't restore mtime"
742//usage: )
743//usage: IF_FEATURE_TAR_FROM(
744//usage: IF_FEATURE_TAR_LONG_OPTIONS(
745//usage: "\n exclude File to exclude"
746//usage: )
747//usage: "\n X File with names to exclude"
748//usage: "\n T File with names to include"
749//usage: )
750//usage:
751//usage:#define tar_example_usage
752//usage: "$ zcat /tmp/tarball.tar.gz | tar -xf -\n"
753//usage: "$ tar -cf /tmp/tarball.tar /usr/local\n"
754
755// Supported but aren't in --help:
756// o no-same-owner
757// p same-permissions
758// k keep-old
759// numeric-owner
760// no-same-permissions
761// overwrite
762//IF_FEATURE_TAR_TO_COMMAND(
763// to-command
764//)
765
741enum { 766enum {
742 OPTBIT_KEEP_OLD = 8, 767 OPTBIT_KEEP_OLD = 8,
743 IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) 768 IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,)
@@ -750,6 +775,7 @@ enum {
750 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit 775 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit
751 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) 776 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
752#if ENABLE_FEATURE_TAR_LONG_OPTIONS 777#if ENABLE_FEATURE_TAR_LONG_OPTIONS
778 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,)
753 OPTBIT_NUMERIC_OWNER, 779 OPTBIT_NUMERIC_OWNER,
754 OPTBIT_NOPRESERVE_PERM, 780 OPTBIT_NOPRESERVE_PERM,
755 OPTBIT_OVERWRITE, 781 OPTBIT_OVERWRITE,
@@ -772,6 +798,7 @@ enum {
772 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z 798 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
773 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z 799 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
774 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m 800 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
801 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
775 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner 802 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
776 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions 803 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
777 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite 804 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite
@@ -813,6 +840,9 @@ static const char tar_longopts[] ALIGN1 =
813# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME 840# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME
814 "touch\0" No_argument "m" 841 "touch\0" No_argument "m"
815# endif 842# endif
843# if ENABLE_FEATURE_TAR_TO_COMMAND
844 "to-command\0" Required_argument "\xfb"
845# endif
816 /* use numeric uid/gid from tar header, not textual */ 846 /* use numeric uid/gid from tar header, not textual */
817 "numeric-owner\0" No_argument "\xfc" 847 "numeric-owner\0" No_argument "\xfc"
818 /* do not restore mode */ 848 /* do not restore mode */
@@ -904,6 +934,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
904 , &tar_filename // -f filename 934 , &tar_filename // -f filename
905 IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T 935 IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
906 IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X 936 IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
937 IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command
907#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 938#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
908 , &excludes // --exclude 939 , &excludes // --exclude
909#endif 940#endif
@@ -922,6 +953,12 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
922 if (opt & OPT_2STDOUT) 953 if (opt & OPT_2STDOUT)
923 tar_handle->action_data = data_extract_to_stdout; 954 tar_handle->action_data = data_extract_to_stdout;
924 955
956 if (opt & OPT_2COMMAND) {
957 putenv((char*)"TAR_FILETYPE=f");
958 signal(SIGPIPE, SIG_IGN);
959 tar_handle->action_data = data_extract_to_command;
960 }
961
925 if (opt & OPT_KEEP_OLD) 962 if (opt & OPT_KEEP_OLD)
926 tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; 963 tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD;
927 964