*: tar-related cleanups: move struct to unarchive.h; move help to tar.c
No binary (build failed)
—
(log yok)
| @@ -118,34 +118,10 @@ static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, uns | |
| } | |
| #endif | |
| - | void BUG_tar_header_size(void); |
| char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |
| { | |
| file_header_t *file_header = archive_handle->file_header; | |
| - | struct { |
| - | /* ustar header, Posix 1003.1 */ |
| - | char name[100]; /* 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[100]; /* 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 simplify 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 */ |
| - | } tar; |
| + | struct tar_header_t tar; |
| char *cp; | |
| int i, sum_u, sum; | |
| #if ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY | |
| @@ -162,9 +138,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |
| # define p_linkname 0 | |
| #endif | |
| - | if (sizeof(tar) != 512) |
| - | BUG_tar_header_size(); |
| - | |
| #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX | |
| again: | |
| #endif | |
| @@ -230,18 +203,21 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |
| * we can switch to get_header_tar_gz/bz2/lzma(). | |
| * Needs seekable fd. I wish recv(MSG_PEEK) works | |
| * on any fd... */ | |
| - | #if ENABLE_FEATURE_SEAMLESS_GZ |
| + | # if ENABLE_FEATURE_SEAMLESS_GZ |
| if (tar.name[0] == 0x1f && tar.name[1] == (char)0x8b) { /* gzip */ | |
| get_header_ptr = get_header_tar_gz; | |
| } else | |
| - | #endif |
| - | #if ENABLE_FEATURE_SEAMLESS_BZ2 |
| + | # endif |
| + | # if ENABLE_FEATURE_SEAMLESS_BZ2 |
| if (tar.name[0] == 'B' && tar.name[1] == 'Z' | |
| && tar.name[2] == 'h' && isdigit(tar.name[3]) | |
| ) { /* bzip2 */ | |
| get_header_ptr = get_header_tar_bz2; | |
| } else | |
| - | #endif |
| + | # endif |
| + | # if ENABLE_FEATURE_SEAMLESS_XZ |
| + | //TODO |
| + | # endif |
| goto err; | |
| /* Two different causes for lseek() != 0: | |
| * unseekable fd (would like to support that too, but...), | |
| @@ -48,37 +48,6 @@ | |
| #if ENABLE_FEATURE_TAR_CREATE | |
| - | /* 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; |
| - | |
| /* | |
| ** writeTarFile(), writeFileToTarball(), and writeTarHeader() are | |
| ** the only functions that deal with the HardLinkInfo structure. | |
| @@ -193,7 +162,7 @@ static void putOctal(char *cp, int len, off_t value) | |
| } | |
| #define PUT_OCTAL(a, b) putOctal((a), sizeof(a), (b)) | |
| - | static void chksum_and_xwrite(int fd, struct TarHeader* hp) |
| + | static void chksum_and_xwrite(int fd, struct tar_header_t* hp) |
| { | |
| /* POSIX says that checksum is done on unsigned bytes | |
| * (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) | |
| "00000000000", | |
| "00000000000", | |
| }; | |
| - | struct TarHeader header; |
| + | struct tar_header_t header; |
| int size; | |
| dir = !!dir; /* normalize: 0/1 */ | |
| @@ -262,17 +231,13 @@ static void writeLongname(int fd, int type, const char *name, int dir) | |
| #endif | |
| /* Write out a tar header for the specified file/directory/whatever */ | |
| - | void BUG_tar_header_size(void); |
| static int writeTarHeader(struct TarBallInfo *tbInfo, | |
| const char *header_name, const char *fileName, struct stat *statbuf) | |
| { | |
| - | struct TarHeader header; |
| - | |
| - | if (sizeof(header) != 512) |
| - | BUG_tar_header_size(); |
| - | |
| - | memset(&header, 0, sizeof(struct TarHeader)); |
| + | struct tar_header_t header; |
| + | memset(&header, 0, sizeof(header)); |
| + | |
| strncpy(header.name, header_name, sizeof(header.name)); | |
| /* POSIX says to mask mode with 07777. */ | |
| @@ -738,6 +703,68 @@ static void handle_SIGCHLD(int status) | |
| } | |
| #endif | |
| + | //usage:#define tar_trivial_usage |
| + | //usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" IF_FEATURE_SEAMLESS_GZ("z") |
| + | //usage: IF_FEATURE_SEAMLESS_BZ2("j") IF_FEATURE_SEAMLESS_LZMA("a") |
| + | //usage: IF_FEATURE_SEAMLESS_Z("Z") IF_FEATURE_TAR_NOPRESERVE_TIME("m") "vO] " |
| + | //usage: IF_FEATURE_TAR_FROM("[-X FILE] ") |
| + | //usage: "[-f TARFILE] [-C DIR] [FILE]..." |
| + | //usage:#define tar_full_usage "\n\n" |
| + | //usage: IF_FEATURE_TAR_CREATE("Create, extract, ") |
| + | //usage: IF_NOT_FEATURE_TAR_CREATE("Extract ") |
| + | //usage: "or list files from a tar file\n" |
| + | //usage: "\nOperation:" |
| + | //usage: IF_FEATURE_TAR_CREATE( |
| + | //usage: "\n c Create" |
| + | //usage: ) |
| + | //usage: "\n x Extract" |
| + | //usage: "\n t List" |
| + | //usage: "\nOptions:" |
| + | //usage: "\n f Name of TARFILE ('-' for stdin/out)" |
| + | //usage: "\n C Change to DIR before operation" |
| + | //usage: "\n v Verbose" |
| + | //usage: IF_FEATURE_SEAMLESS_GZ( |
| + | //usage: "\n z (De)compress using gzip" |
| + | //usage: ) |
| + | //usage: IF_FEATURE_SEAMLESS_BZ2( |
| + | //usage: "\n j (De)compress using bzip2" |
| + | //usage: ) |
| + | //usage: IF_FEATURE_SEAMLESS_LZMA( |
| + | //usage: "\n a (De)compress using lzma" |
| + | //usage: ) |
| + | //usage: IF_FEATURE_SEAMLESS_Z( |
| + | //usage: "\n Z (De)compress using compress" |
| + | //usage: ) |
| + | //usage: "\n O Extract to stdout" |
| + | //usage: IF_FEATURE_TAR_CREATE( |
| + | //usage: "\n h Follow symlinks" |
| + | //usage: ) |
| + | //usage: IF_FEATURE_TAR_NOPRESERVE_TIME( |
| + | //usage: "\n m Don't restore mtime" |
| + | //usage: ) |
| + | //usage: IF_FEATURE_TAR_FROM( |
| + | //usage: IF_FEATURE_TAR_LONG_OPTIONS( |
| + | //usage: "\n exclude File to exclude" |
| + | //usage: ) |
| + | //usage: "\n X File with names to exclude" |
| + | //usage: "\n T File with names to include" |
| + | //usage: ) |
| + | //usage: |
| + | //usage:#define tar_example_usage |
| + | //usage: "$ zcat /tmp/tarball.tar.gz | tar -xf -\n" |
| + | //usage: "$ tar -cf /tmp/tarball.tar /usr/local\n" |
| + | |
| + | // Supported but aren't in --help: |
| + | // o no-same-owner |
| + | // p same-permissions |
| + | // k keep-old |
| + | // numeric-owner |
| + | // no-same-permissions |
| + | // overwrite |
| + | //IF_FEATURE_TAR_TO_COMMAND( |
| + | // to-command |
| + | //) |
| + | |
| enum { | |
| OPTBIT_KEEP_OLD = 8, | |
| IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) | |
| @@ -113,6 +113,39 @@ typedef struct archive_handle_t { | |
| #define ARCHIVE_O_TRUNC (1 << 8) | |
| + | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ |
| + | #define TAR_BLOCK_SIZE 512 |
| + | #define NAME_SIZE 100 |
| + | #define NAME_SIZE_STR "100" |
| + | typedef struct tar_header_t { /* 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) */ |
| + | } tar_header_t; |
| + | struct BUG_tar_header { |
| + | char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; |
| + | }; |
| + | |
| + | |
| + | |
| /* Info struct unpackers can fill out to inform users of thing like | |
| * timestamps of unpacked files */ | |
| typedef struct unpack_info_t { | |
| @@ -4273,54 +4273,6 @@ INSERT | |
| #define tac_full_usage "\n\n" \ | |
| "Concatenate FILEs and print them in reverse" | |
| - | #define tar_trivial_usage \ |
| - | "-[" IF_FEATURE_TAR_CREATE("c") "xt" IF_FEATURE_SEAMLESS_GZ("z") \ |
| - | IF_FEATURE_SEAMLESS_BZ2("j") IF_FEATURE_SEAMLESS_LZMA("a") \ |
| - | IF_FEATURE_SEAMLESS_Z("Z") IF_FEATURE_TAR_NOPRESERVE_TIME("m") "vO] " \ |
| - | IF_FEATURE_TAR_FROM("[-X FILE] ") \ |
| - | "[-f TARFILE] [-C DIR] [FILE]..." |
| - | #define tar_full_usage "\n\n" \ |
| - | IF_FEATURE_TAR_CREATE("Create, extract, ") \ |
| - | IF_NOT_FEATURE_TAR_CREATE("Extract ") \ |
| - | "or list files from a tar file\n" \ |
| - | "\nOptions:" \ |
| - | IF_FEATURE_TAR_CREATE( \ |
| - | "\n c Create" \ |
| - | ) \ |
| - | "\n x Extract" \ |
| - | "\n t List" \ |
| - | "\nArchive format selection:" \ |
| - | IF_FEATURE_SEAMLESS_GZ( \ |
| - | "\n z Filter the archive through gzip" \ |
| - | ) \ |
| - | IF_FEATURE_SEAMLESS_BZ2( \ |
| - | "\n j Filter the archive through bzip2" \ |
| - | ) \ |
| - | IF_FEATURE_SEAMLESS_LZMA( \ |
| - | "\n a Filter the archive through lzma" \ |
| - | ) \ |
| - | IF_FEATURE_SEAMLESS_Z( \ |
| - | "\n Z Filter the archive through compress" \ |
| - | ) \ |
| - | IF_FEATURE_TAR_NOPRESERVE_TIME( \ |
| - | "\n m Do not restore mtime" \ |
| - | ) \ |
| - | "\nFile selection:" \ |
| - | "\n f Name of TARFILE or \"-\" for stdin" \ |
| - | "\n O Extract to stdout" \ |
| - | IF_FEATURE_TAR_FROM( \ |
| - | IF_FEATURE_TAR_LONG_OPTIONS( \ |
| - | "\n exclude File to exclude" \ |
| - | ) \ |
| - | "\n X File with names to exclude" \ |
| - | ) \ |
| - | "\n C Change to DIR before operation" \ |
| - | "\n v Verbose" \ |
| - | |
| - | #define tar_example_usage \ |
| - | "$ zcat /tmp/tarball.tar.gz | tar -xf -\n" \ |
| - | "$ tar -cf /tmp/tarball.tar /usr/local\n" |
| - | |
| #define taskset_trivial_usage \ | |
| "[-p] [MASK] [PID | PROG ARGS]" | |
| #define taskset_full_usage "\n\n" \ | |
| @@ -20,42 +20,19 @@ | |
| //config: a memory usage statistic tool. | |
| #include "libbb.h" | |
| - | |
| - | struct tar_header { |
| - | char name[100]; /* 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[100]; /* 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_512) */ |
| - | }; |
| + | #include "unarchive.h" |
| struct fileblock { | |
| struct fileblock *next; | |
| - | char data[512]; |
| + | char data[TAR_BLOCK_SIZE]; |
| }; | |
| static void writeheader(const char *path, struct stat *sb, int type) | |
| { | |
| - | struct tar_header header; |
| + | struct tar_header_t header; |
| int i, sum; | |
| - | memset(&header, 0, 512); |
| + | memset(&header, 0, TAR_BLOCK_SIZE); |
| strcpy(header.name, path); | |
| sprintf(header.mode, "%o", sb->st_mode & 0777); | |
| /* careful to not overflow fields! */ | |
| @@ -73,11 +50,11 @@ static void writeheader(const char *path, struct stat *sb, int type) | |
| * digits, followed by a NUL like the other fields... */ | |
| header.chksum[7] = ' '; | |
| sum = ' ' * 7; | |
| - | for (i = 0; i < 512; i++) |
| + | for (i = 0; i < TAR_BLOCK_SIZE; i++) |
| sum += ((unsigned char*)&header)[i]; | |
| sprintf(header.chksum, "%06o", sum); | |
| - | xwrite(STDOUT_FILENO, &header, 512); |
| + | xwrite(STDOUT_FILENO, &header, TAR_BLOCK_SIZE); |
| } | |
| static void archivefile(const char *path) | |
| @@ -94,10 +71,10 @@ static void archivefile(const char *path) | |
| cur = xzalloc(sizeof(*cur)); | |
| *prev = cur; | |
| prev = &cur->next; | |
| - | r = full_read(fd, cur->data, 512); |
| + | r = full_read(fd, cur->data, TAR_BLOCK_SIZE); |
| if (r > 0) | |
| size += r; | |
| - | } while (r == 512); |
| + | } while (r == TAR_BLOCK_SIZE); |
| /* write archive header */ | |
| fstat(fd, &s); | |
| @@ -106,8 +83,8 @@ static void archivefile(const char *path) | |
| writeheader(path, &s, '0'); | |
| /* dump file contents */ | |
| - | for (cur = start; (int)size > 0; size -= 512) { |
| - | xwrite(STDOUT_FILENO, cur->data, 512); |
| + | for (cur = start; (int)size > 0; size -= TAR_BLOCK_SIZE) { |
| + | xwrite(STDOUT_FILENO, cur->data, TAR_BLOCK_SIZE); |
| start = cur; | |
| cur = cur->next; | |
| free(start); | |