From 52827e3ebcd80f634f990030ee697254a0ae517d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 26 Jun 2010 18:21:36 +0200 Subject: [PATCH] *: tar-related cleanups: move struct to unarchive.h; move help to tar.c Signed-off-by: Denys Vlasenko --- archival/libunarchive/get_header_tar.c | 40 ++------- archival/tar.c | 107 ++++++++++++++++--------- include/unarchive.h | 33 ++++++++ include/usage.src.h | 48 ----------- procps/smemcap.c | 43 +++------- 5 files changed, 118 insertions(+), 153 deletions(-) diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index fcddcb834..01c10433e 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c @@ -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...), diff --git a/archival/tar.c b/archival/tar.c index 344c9dea4..f49fb129e 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -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 ,) diff --git a/include/unarchive.h b/include/unarchive.h index f3aa05d09..b4cf16082 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -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 { diff --git a/include/usage.src.h b/include/usage.src.h index f30edbc54..f84bb93c7 100644 --- a/include/usage.src.h +++ b/include/usage.src.h @@ -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" \ diff --git a/procps/smemcap.c b/procps/smemcap.c index cdcc891a1..06cf93c85 100644 --- a/procps/smemcap.c +++ b/procps/smemcap.c @@ -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);