48 |
|
|
49 |
#if ENABLE_FEATURE_TAR_CREATE |
#if ENABLE_FEATURE_TAR_CREATE |
50 |
|
|
|
/* Tar file constants */ |
|
|
|
|
|
#define TAR_BLOCK_SIZE 512 |
|
|
|
|
|
/* POSIX tar Header Block, from POSIX 1003.1-1990 */ |
|
|
#define NAME_SIZE 100 |
|
|
#define NAME_SIZE_STR "100" |
|
|
typedef struct TarHeader { /* byte offset */ |
|
|
char name[NAME_SIZE]; /* 0-99 */ |
|
|
char mode[8]; /* 100-107 */ |
|
|
char uid[8]; /* 108-115 */ |
|
|
char gid[8]; /* 116-123 */ |
|
|
char size[12]; /* 124-135 */ |
|
|
char mtime[12]; /* 136-147 */ |
|
|
char chksum[8]; /* 148-155 */ |
|
|
char typeflag; /* 156-156 */ |
|
|
char linkname[NAME_SIZE]; /* 157-256 */ |
|
|
/* POSIX: "ustar" NUL "00" */ |
|
|
/* GNU tar: "ustar " NUL */ |
|
|
/* Normally it's defined as magic[6] followed by |
|
|
* version[2], but we put them together to save code. |
|
|
*/ |
|
|
char magic[8]; /* 257-264 */ |
|
|
char uname[32]; /* 265-296 */ |
|
|
char gname[32]; /* 297-328 */ |
|
|
char devmajor[8]; /* 329-336 */ |
|
|
char devminor[8]; /* 337-344 */ |
|
|
char prefix[155]; /* 345-499 */ |
|
|
char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */ |
|
|
} TarHeader; |
|
|
|
|
51 |
/* |
/* |
52 |
** writeTarFile(), writeFileToTarball(), and writeTarHeader() are |
** writeTarFile(), writeFileToTarball(), and writeTarHeader() are |
53 |
** the only functions that deal with the HardLinkInfo structure. |
** the only functions that deal with the HardLinkInfo structure. |
162 |
} |
} |
163 |
#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) |
#define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) |
164 |
|
|
165 |
static void chksum_and_xwrite(int fd, struct TarHeader* hp) |
static void chksum_and_xwrite(int fd, struct tar_header_t* hp) |
166 |
{ |
{ |
167 |
/* POSIX says that checksum is done on unsigned bytes |
/* POSIX says that checksum is done on unsigned bytes |
168 |
* (Sun and HP-UX gets it wrong... more details in |
* (Sun and HP-UX gets it wrong... more details in |
204 |
"00000000000", |
"00000000000", |
205 |
"00000000000", |
"00000000000", |
206 |
}; |
}; |
207 |
struct TarHeader header; |
struct tar_header_t header; |
208 |
int size; |
int size; |
209 |
|
|
210 |
dir = !!dir; /* normalize: 0/1 */ |
dir = !!dir; /* normalize: 0/1 */ |
231 |
#endif |
#endif |
232 |
|
|
233 |
/* Write out a tar header for the specified file/directory/whatever */ |
/* Write out a tar header for the specified file/directory/whatever */ |
|
void BUG_tar_header_size(void); |
|
234 |
static int writeTarHeader(struct TarBallInfo *tbInfo, |
static int writeTarHeader(struct TarBallInfo *tbInfo, |
235 |
const char *header_name, const char *fileName, struct stat *statbuf) |
const char *header_name, const char *fileName, struct stat *statbuf) |
236 |
{ |
{ |
237 |
struct TarHeader header; |
struct tar_header_t header; |
|
|
|
|
if (sizeof(header) != 512) |
|
|
BUG_tar_header_size(); |
|
238 |
|
|
239 |
memset(&header, 0, sizeof(struct TarHeader)); |
memset(&header, 0, sizeof(header)); |
240 |
|
|
241 |
strncpy(header.name, header_name, sizeof(header.name)); |
strncpy(header.name, header_name, sizeof(header.name)); |
242 |
|
|
514 |
(void) &zip_exec; |
(void) &zip_exec; |
515 |
# endif |
# endif |
516 |
|
|
517 |
gzipPid = vfork(); |
gzipPid = xvfork(); |
|
if (gzipPid < 0) |
|
|
bb_perror_msg_and_die("vfork"); |
|
518 |
|
|
519 |
if (gzipPid == 0) { |
if (gzipPid == 0) { |
520 |
/* child */ |
/* child */ |
701 |
} |
} |
702 |
#endif |
#endif |
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 |
|
|
766 |
enum { |
enum { |
767 |
OPTBIT_KEEP_OLD = 8, |
OPTBIT_KEEP_OLD = 8, |
768 |
IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) |
IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) |
775 |
IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit |
IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit |
776 |
IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
777 |
#if ENABLE_FEATURE_TAR_LONG_OPTIONS |
#if ENABLE_FEATURE_TAR_LONG_OPTIONS |
778 |
|
IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) |
779 |
OPTBIT_NUMERIC_OWNER, |
OPTBIT_NUMERIC_OWNER, |
780 |
OPTBIT_NOPRESERVE_PERM, |
OPTBIT_NOPRESERVE_PERM, |
781 |
OPTBIT_OVERWRITE, |
OPTBIT_OVERWRITE, |
798 |
OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
799 |
OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
800 |
OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
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 |
802 |
OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
803 |
OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
804 |
OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite |
OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite |
840 |
# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
841 |
"touch\0" No_argument "m" |
"touch\0" No_argument "m" |
842 |
# endif |
# endif |
843 |
|
# if ENABLE_FEATURE_TAR_TO_COMMAND |
844 |
|
"to-command\0" Required_argument "\xfb" |
845 |
|
# endif |
846 |
/* use numeric uid/gid from tar header, not textual */ |
/* use numeric uid/gid from tar header, not textual */ |
847 |
"numeric-owner\0" No_argument "\xfc" |
"numeric-owner\0" No_argument "\xfc" |
848 |
/* do not restore mode */ |
/* do not restore mode */ |
934 |
, &tar_filename // -f filename |
, &tar_filename // -f filename |
935 |
IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T |
IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T |
936 |
IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X |
IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X |
937 |
|
IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command |
938 |
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
939 |
, &excludes // --exclude |
, &excludes // --exclude |
940 |
#endif |
#endif |
953 |
if (opt & OPT_2STDOUT) |
if (opt & OPT_2STDOUT) |
954 |
tar_handle->action_data = data_extract_to_stdout; |
tar_handle->action_data = data_extract_to_stdout; |
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 |
|
|
962 |
if (opt & OPT_KEEP_OLD) |
if (opt & OPT_KEEP_OLD) |
963 |
tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; |
tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; |
964 |
|
|