From: Mike Kazantsev Date: Fri, 4 Apr 2014 09:59:15 +0000 (+0600) Subject: Add optional bsdcat tool. X-Git-Tag: v3.1.900a~308^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d3f56d24b30bb3805cebde8186301ef9aad0e35;p=thirdparty%2Flibarchive.git Add optional bsdcat tool. bsdcat works like zcat, bzcat, xzcat and similar tools, but auto-detects source data format, which can also vary between multiple input files. --- diff --git a/.gitignore b/.gitignore index ecc75ef5d..52c905445 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ bsdcpio bsdcpio_test bsdtar bsdtar_test +bsdcat build/autoconf/compile build/autoconf/config.guess build/autoconf/config.sub diff --git a/CMakeLists.txt b/CMakeLists.txt index 2069c23a4..b55567095 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision}) SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}") SET(BSDCPIO_VERSION_STRING "${VERSION}") SET(BSDTAR_VERSION_STRING "${VERSION}") +SET(BSDCAT_VERSION_STRING "${VERSION}") SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}") SET(LIBARCHIVE_VERSION_STRING "${VERSION}") @@ -168,6 +169,8 @@ OPTION(ENABLE_TAR "Enable tar building" ON) OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE) OPTION(ENABLE_CPIO "Enable cpio building" ON) OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE) +OPTION(ENABLE_CAT "Enable cat building" ON) +OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE) OPTION(ENABLE_XATTR "Enable extended attribute support" ON) OPTION(ENABLE_ACL "Enable ACL support" ON) OPTION(ENABLE_ICONV "Enable iconv support" ON) @@ -1565,5 +1568,6 @@ IF(ENABLE_TEST) ENDIF(ENABLE_TEST) add_subdirectory(libarchive) +add_subdirectory(cat) add_subdirectory(tar) add_subdirectory(cpio) diff --git a/Makefile.am b/Makefile.am index 63a1d098f..c7c8fb296 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,8 +8,8 @@ ACLOCAL_AMFLAGS = -I build/autoconf # lib_LTLIBRARIES= libarchive.la noinst_LTLIBRARIES= libarchive_fe.la -bin_PROGRAMS= $(bsdtar_programs) $(bsdcpio_programs) -man_MANS= $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS) +bin_PROGRAMS= $(bsdtar_programs) $(bsdcpio_programs) $(bsdcat_programs) +man_MANS= $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS) $(bsdcat_man_MANS) BUILT_SOURCES= libarchive/test/list.h tar/test/list.h cpio/test/list.h # @@ -48,6 +48,7 @@ EXTRA_DIST= \ $(bsdtar_test_EXTRA_DIST) \ $(bsdcpio_EXTRA_DIST) \ $(bsdcpio_test_EXTRA_DIST) + $(bsdcat_EXTRA_DIST) # a) Clean out some unneeded files and directories # b) Collect all documentation and format it for distribution. @@ -78,6 +79,7 @@ distclean-local: -[ -f tar/test/Makefile ] && cd tar/test && make clean -[ -f cpio/Makefile ] && cd cpio && make clean -[ -f cpio/test/Makefile ] && cd cpio/test && make clean + -[ -f cat/Makefile ] && cd cat && make clean # # Libarchive headers, source, etc. @@ -1051,3 +1053,46 @@ bsdcpio_test_EXTRA_DIST= \ cpio/test/test_option_t.stdout.uu \ cpio/test/test_option_tv.stdout.uu \ cpio/test/CMakeLists.txt + +# +# +# bsdcat source, docs, etc. +# +# + +bsdcat_SOURCES= \ + cat/bsdcat.c \ + cat/bsdcat.h + +if INC_WINDOWS_FILES +bsdcat_SOURCES+= +endif + +bsdcat_DEPENDENCIES = libarchive.la libarchive_fe.la + + +if STATIC_BSDCAT +bsdcat_ldstatic= -static +bsdcat_ccstatic= -DLIBARCHIVE_STATIC +else +bsdcat_ldstatic= +bsdcat_ccstatic= +endif + +bsdcat_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) +bsdcat_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcat_ccstatic) $(PLATFORMCPPFLAGS) +bsdcat_LDFLAGS= $(bsdcat_ldstatic) + +bsdcat_EXTRA_DIST= \ + cat/bsdcat.1 \ + cat/CMakeLists.txt + + +if BUILD_BSDCAT +# Manpages to install +bsdcat_man_MANS= cat/bsdcat.1 +bsdcat_programs= bsdcat +else +bsdcat_man_MANS= +bsdcat_programs= +endif diff --git a/README b/README index 1c974fde2..817db7b73 100644 --- a/README +++ b/README @@ -16,6 +16,8 @@ This distribution bundle includes the following components: replacement built on libarchive * cpio: the 'bsdcpio' program is a different interface to essentially the same functionality + * cat: the 'bsdcat' program is a simple replacement tool for + zcat, bzcat, xzcat, and such * examples: Some small example programs that you may find useful. * examples/minitar: a compact sample demonstrating use of libarchive. * contrib: Various items sent to me by third parties; @@ -39,6 +41,7 @@ The following files in the top-level directory are used by the Guide to Documentation installed by this system: * bsdtar.1 explains the use of the bsdtar program * bsdcpio.1 explains the use of the bsdcpio program + * bsdcat.1 explains the use of the bsdcat program * libarchive.3 gives an overview of the library as a whole * archive_read.3, archive_write.3, archive_write_disk.3, and archive_read_disk.3 provide detailed calling sequences for the read diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index a6933f694..179ffa7ca 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -289,6 +289,9 @@ typedef uint64_t uintmax_t; /* Version number of bsdtar */ #cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}" +/* Version number of bsdcat */ +#cmakedefine BSDCAT_VERSION_STRING "${BSDCAT_VERSION_STRING}" + /* Define to 1 if you have the `acl_create_entry' function. */ #cmakedefine HAVE_ACL_CREATE_ENTRY 1 diff --git a/cat/CMakeLists.txt b/cat/CMakeLists.txt new file mode 100644 index 000000000..3c46aaa2e --- /dev/null +++ b/cat/CMakeLists.txt @@ -0,0 +1,31 @@ +############################################ +# +# How to build bsdcat +# +############################################ +IF(ENABLE_CAT) + + SET(bsdcat_SOURCES + bsdcat.c + bsdcat.h + ) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) + + # bsdcat documentation + SET(bsdcat_MANS bsdcat.1) + + # How to build bsdcat + ADD_EXECUTABLE(bsdcat ${bsdcat_SOURCES}) + IF(ENABLE_CAT_SHARED) + TARGET_LINK_LIBRARIES(bsdcat archive ${ADDITIONAL_LIBS}) + ELSE(ENABLE_CAT_SHARED) + TARGET_LINK_LIBRARIES(bsdcat archive_static ${ADDITIONAL_LIBS}) + SET_TARGET_PROPERTIES(bsdcat PROPERTIES COMPILE_DEFINITIONS + LIBARCHIVE_STATIC) + ENDIF(ENABLE_CAT_SHARED) + GET_TARGET_PROPERTY(BSDCAT bsdcat LOCATION) + + # Installation rules + INSTALL(TARGETS bsdcat RUNTIME DESTINATION bin) + INSTALL_MAN(${bsdcat_MANS}) +ENDIF(ENABLE_CAT) diff --git a/cat/bsdcat.1 b/cat/bsdcat.1 new file mode 100644 index 000000000..4f82b1e57 --- /dev/null +++ b/cat/bsdcat.1 @@ -0,0 +1,62 @@ +.\" Copyright (c) 2011-2014, Mike Kazantsev +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 1, 2014 +.Dt BSDCAT 1 +.Os +.Sh NAME +.Nm bsdcat +.Nd expand files to standard output +.Sh SYNOPSIS +.Nm +.Op options +.Op files +.Pp +.Sh DESCRIPTION +.Nm +expands files to standard output. +.Sh OPTIONS +.Nm +typically takes a filename as an argument or reads standard input when used in a +pipe. In both cases decompressed data it written to standard output. +.Sh EXAMPLES +.Pp +To decompress a file: +.Pp +.Dl bsdcat example.txt.gz > example.txt +.Pp +To decompress standard input in a pipe: +.Pp +.Dl cat example.txt.gz | bsdcat > example.txt +.Pp +Both examples achieve the same results - a decompressed file by redirecting +output. +.Sh SEE ALSO +.Xr uncompress 1 , +.Xr zcat 1 , +.Xr bzcat 1 , +.Xr xzcat 1 , +.Xr libarchive-formats 5 , diff --git a/cat/bsdcat.c b/cat/bsdcat.c new file mode 100644 index 000000000..e9b344879 --- /dev/null +++ b/cat/bsdcat.c @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2011-2014, Mike Kazantsev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "bsdcat.h" +#include "err.h" + +#define BYTES_PER_BLOCK (20*512) + +struct archive *a; +struct archive_entry *ae; +char *bsdcat_current_path; +int c, err; + + +static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'v'}, + {NULL, 0, NULL, 0} +}; + +void +usage(void) +{ + const char *p; + p = lafe_getprogname(); + fprintf(stderr, "Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p); + exit(1); +} + +static void +version(void) +{ + printf("bsdcat %s - %s\n", + BSDCAT_VERSION_STRING, + archive_version_details()); + exit(0); +} + +void +bsdcat_next() +{ + a = archive_read_new(); + archive_read_support_filter_all(a); + archive_read_support_format_raw(a); +} + +void +bsdcat_read_to_stdout(char* filename) +{ + if ((archive_read_open_filename(a, filename, BYTES_PER_BLOCK) != ARCHIVE_OK) + || (archive_read_next_header(a, &ae) != ARCHIVE_OK) + || (archive_read_data_into_fd(a, 1) != ARCHIVE_OK) + || (archive_read_free(a) != ARCHIVE_OK)) + goto fail; + return; +fail: + lafe_errc(1, 0, "Error: %s - %s", + bsdcat_current_path, archive_error_string(a)); +} + +int +main(int argc, char **argv) +{ + lafe_setprogname(*argv, "bsdcat"); + + int option_index = 0; + while ((c = getopt_long(argc, argv, "h", + long_options, &option_index)) != -1) { + switch (c) { + case 'v': + version(); + break; + default: + usage(); + } + } + + bsdcat_next(); + if (optind >= argc) { + bsdcat_current_path = ""; + bsdcat_read_to_stdout(NULL); + } else + while (optind < argc) { + bsdcat_current_path = argv[optind++]; + bsdcat_read_to_stdout(bsdcat_current_path); + bsdcat_next(); + } + + exit(0); +} diff --git a/cat/bsdcat.h b/cat/bsdcat.h new file mode 100644 index 000000000..5daf3cf3a --- /dev/null +++ b/cat/bsdcat.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2014, Mike Kazantsev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(PLATFORM_CONFIG_H) +/* Use hand-built config.h in environments that need it. */ +#include PLATFORM_CONFIG_H +#else +/* Not having a config.h of some sort is a serious problem. */ +#include "config.h" +#endif + +#include +#include + +void usage(void); +void bsdcat_next(void); +void bsdcat_read_to_stdout(char* filename); diff --git a/configure.ac b/configure.ac index e92ea252d..8bf2f2334 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,7 @@ m4_define([LIBARCHIVE_VERSION_N],[3001002]) dnl bsdtar and bsdcpio versioning tracks libarchive m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S()) +m4_define([BSDCAT_VERSION_S],LIBARCHIVE_VERSION_S()) AC_PREREQ(2.65) @@ -53,12 +54,15 @@ AC_DEFINE([BSDCPIO_VERSION_STRING],"BSDCPIO_VERSION_S()", [Version number of bsdcpio]) AC_DEFINE([BSDTAR_VERSION_STRING],"BSDTAR_VERSION_S()", [Version number of bsdtar]) +AC_DEFINE([BSDCAT_VERSION_STRING],"BSDTAR_VERSION_S()", + [Version number of bsdcat]) # The shell variables here must be the same as the AC_SUBST() variables # below, but the shell variable names apparently cannot be the same as # the m4 macro names above. Why? Ask autoconf. BSDCPIO_VERSION_STRING=BSDCPIO_VERSION_S() BSDTAR_VERSION_STRING=BSDTAR_VERSION_S() +BSDCAT_VERSION_STRING=BSDCAT_VERSION_S() LIBARCHIVE_VERSION_STRING=LIBARCHIVE_VERSION_S() LIBARCHIVE_VERSION_NUMBER=LIBARCHIVE_VERSION_N() @@ -68,6 +72,7 @@ LIBARCHIVE_VERSION_NUMBER=LIBARCHIVE_VERSION_N() AC_SUBST(ARCHIVE_LIBTOOL_VERSION) AC_SUBST(BSDCPIO_VERSION_STRING) AC_SUBST(BSDTAR_VERSION_STRING) +AC_SUBST(BSDCAT_VERSION_STRING) AC_SUBST(LIBARCHIVE_VERSION_STRING) AC_SUBST(LIBARCHIVE_VERSION_NUMBER) @@ -147,6 +152,50 @@ esac AM_CONDITIONAL([BUILD_BSDTAR], [ test "$build_bsdtar" = yes ]) AM_CONDITIONAL([STATIC_BSDTAR], [ test "$static_bsdtar" = yes ]) +# +# Options for building bsdcat. +# +# Default is to build bsdcat, but allow people to override that. +# +AC_ARG_ENABLE([bsdcat], + [AS_HELP_STRING([--enable-bsdcat], [enable build of bsdcat (default)]) + AS_HELP_STRING([--enable-bsdcat=static], [force static build of bsdcat]) + AS_HELP_STRING([--enable-bsdcat=shared], [force dynamic build of bsdcat]) +AS_HELP_STRING([--disable-bsdcat], [disable build of bsdcat])], + [], [enable_bsdcat=yes]) + +case "$enable_bsdcat" in +yes) + if test "$enable_static" = "no"; then + static_bsdcat=no + else + static_bsdcat=yes + fi + build_bsdcat=yes + ;; +dynamic|shared) + if test "$enable_shared" = "no"; then + AC_MSG_FAILURE([Shared linking of bsdcat requires shared libarchive]) + fi + build_bsdcat=yes + static_bsdcat=no + ;; +static) + build_bsdcat=yes + static_bsdcat=yes + ;; +no) + build_bsdcat=no + static_bsdcat=no + ;; +*) + AC_MSG_FAILURE([Unsupported value for --enable-bsdcat]) + ;; +esac + +AM_CONDITIONAL([BUILD_BSDCAT], [ test "$build_bsdcat" = yes ]) +AM_CONDITIONAL([STATIC_BSDCAT], [ test "$static_bsdcat" = yes ]) + # # Options for building bsdcpio. # @@ -787,6 +836,6 @@ esac # Ensure test directories are present if building out-of-tree AC_CONFIG_COMMANDS([mkdirs], - [mkdir -p {libarchive,tar,cpio}/test]) + [mkdir -p {libarchive,tar,cat,cpio}/test]) AC_OUTPUT