[PATCH] Add Untar_FromGzChunk_Print() + Test
Chris Johns
chrisj at rtems.org
Mon Jul 25 21:59:38 UTC 2016
OK to push.
On 25/07/2016 11:46 PM, Alexander Krutwig wrote:
> ---
> cpukit/libmisc/Makefile.am | 2 +-
> cpukit/libmisc/untar/untar.h | 33 +++++++++++++
> cpukit/libmisc/untar/untar_tgz.c | 89 +++++++++++++++++++++++++++++++++++
> testsuites/libtests/configure.ac | 3 +-
> testsuites/libtests/tar01/Makefile.am | 32 +++++++++++--
> testsuites/libtests/tar01/init.c | 45 ++++++++++++++++++
> testsuites/libtests/tar01/tar01.doc | 1 +
> testsuites/libtests/tar01/tar01.scn | 11 +++++
> 8 files changed, 210 insertions(+), 6 deletions(-)
> create mode 100644 cpukit/libmisc/untar/untar_tgz.c
>
> diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
> index a50de94..4f5c01d 100644
> --- a/cpukit/libmisc/Makefile.am
> +++ b/cpukit/libmisc/Makefile.am
> @@ -155,7 +155,7 @@ EXTRA_DIST += stackchk/README
>
> ## libuntar
> noinst_LIBRARIES += libuntar.a
> -libuntar_a_SOURCES = untar/untar.c untar/untar.h
> +libuntar_a_SOURCES = untar/untar.c untar/untar_tgz.c untar/untar.h
>
> EXTRA_DIST += untar/README
>
> diff --git a/cpukit/libmisc/untar/untar.h b/cpukit/libmisc/untar/untar.h
> index 006f06d..4d00d36 100644
> --- a/cpukit/libmisc/untar/untar.h
> +++ b/cpukit/libmisc/untar/untar.h
> @@ -20,6 +20,7 @@
> #include <stdbool.h>
> #include <stddef.h>
> #include <tar.h>
> +#include <zlib.h>
>
> #include <rtems/print.h>
>
> @@ -38,6 +39,8 @@ extern "C" {
> #define UNTAR_INVALID_CHECKSUM 2
> #define UNTAR_INVALID_HEADER 3
>
> +#define UNTAR_GZ_INFLATE_FAILED 4
> +#define UNTAR_GZ_INFLATE_END_FAILED 5
>
> int Untar_FromMemory(void *tar_buf, size_t size);
> int Untar_FromMemory_Print(void *tar_buf, size_t size, const rtems_printer* printer);
> @@ -137,6 +140,36 @@ int Untar_FromChunk_Print(
> const rtems_printer* printer
> );
>
> +/**
> + * @brief Initializes the Untar_ChunkGzContext.
> + *
> + * @param Untar_ChunkGzContext *context [in] Pointer to a context structure.
> + * @param void *inflateBuffer [in] Pointer to a context structure.
> + * @param size_t inflateBufferSize [in] Size of inflateBuffer.
> + */
> +int Untar_GzChunkContext_Init(
> + Untar_GzChunkContext *ctx,
> + void *inflateBuffer,
> + size_t inflateBufferSize
> +);
> +
> +/*
> + * @brief Untars a GZ compressed POSIX TAR file.
> + *
> + * This is a subroutine used to rip links, directories, and
> + * files out of a tar.gz/tgz file.
> + *
> + * @param Untar_ChunkContext *context [in] Pointer to a context structure.
> + * @param ssize buflen [in] Size of valid bytes in input buffer.
> + * @param z_stream *strm [in] Pointer to the current zlib context.
> + */
> +int Untar_FromGzChunk_Print(
> + Untar_GzChunkContext *ctx,
> + void *chunk,
> + size_t chunk_size,
> + const rtems_printer* printer
> +);
> +
> /**************************************************************************
> * This converts octal ASCII number representations into an
> * unsigned long. Only support 32-bit numbers for now.
> diff --git a/cpukit/libmisc/untar/untar_tgz.c b/cpukit/libmisc/untar/untar_tgz.c
> new file mode 100644
> index 0000000..1ab7ec9
> --- /dev/null
> +++ b/cpukit/libmisc/untar/untar_tgz.c
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
> + *
> + * embedded brains GmbH
> + * Dornierstr. 4
> + * 82178 Puchheim
> + * Germany
> + * <info at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/untar.h>
> +
> +int Untar_GzChunkContext_Init(
> + Untar_GzChunkContext *ctx,
> + void *inflateBuffer,
> + size_t inflateBufferSize
> +)
> +{
> + int ret;
> + int status = UNTAR_SUCCESSFUL;
> +
> + Untar_ChunkContext_Init(&ctx->base);
> + ctx->inflateBuffer = inflateBuffer;
> + ctx->inflateBufferSize = inflateBufferSize;
> + memset(&ctx->strm, 0, sizeof(ctx->strm));
> + ret = inflateInit2(&ctx->strm, 32 + MAX_WBITS);
> + if (ret != Z_OK){
> + status = UNTAR_FAIL;
> + }
> + return status;
> +}
> +
> +int Untar_FromGzChunk_Print(
> + Untar_GzChunkContext *ctx,
> + void *chunk,
> + size_t chunk_size,
> + const rtems_printer *printer
> +)
> +{
> + int untar_succesful;
> + int status;
> +
> + ctx->strm.next_in = (Bytef *)chunk;
> + ctx->strm.avail_in = (size_t)chunk_size;
> +
> + /* Inflate until output buffer is not full */
> + do {
> + ctx->strm.next_out = (Bytef *) ctx->inflateBuffer;
> + ctx->strm.avail_out = ctx->inflateBufferSize;
> +
> + status = inflate(&ctx->strm, Z_NO_FLUSH);
> + if (status == Z_OK || status == Z_STREAM_END) {
> + size_t inflated_size =
> + ctx->inflateBufferSize - ctx->strm.avail_out;
> + untar_succesful = Untar_FromChunk_Print(&ctx->base,
> + ctx->inflateBuffer, inflated_size, NULL);
> + if (untar_succesful != UNTAR_SUCCESSFUL){
> + return untar_succesful;
> + }
> + }
> + } while (ctx->strm.avail_out == 0 && ctx->strm.avail_in > 0
> + && status == Z_OK);
> +
> + if (status != Z_OK) {
> + if (untar_succesful != UNTAR_SUCCESSFUL){
> + rtems_printf(printer, "Untar not successful\n");
> + }
> +
> + if (status != Z_STREAM_END) {
> + rtems_printf(printer, "Zlib inflate failed\n");
> + }
> +
> + status = inflateEnd(&ctx->strm);
> + if (status != Z_OK) {
> + rtems_printf(printer, "Zlib inflate end failed\n");
> + }
> + }
> + return untar_succesful;
> +}
> +
> +
> diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
> index a136749..82f2d80 100644
> --- a/testsuites/libtests/configure.ac
> +++ b/testsuites/libtests/configure.ac
> @@ -31,6 +31,7 @@ RTEMS_CHECK_CPUOPTS([RTEMS_POSIX_API])
>
> AC_PROG_LN_S
> AC_PATH_PROG([PAX],[pax],no)
> +AC_PATH_PROG([GZIP],[gzip],no)
>
> AS_IF([test "x$PAX" = "xno"],[
> AC_MSG_ERROR([pax is missing.])
> @@ -38,7 +39,7 @@ AS_IF([test "x$PAX" = "xno"],[
>
> AC_CHECK_HEADERS([complex.h])
>
> -AM_CONDITIONAL(TARTESTS,test "$as_ln_s" = "ln -s" && test -n "$PAX")
> +AM_CONDITIONAL(TARTESTS,test "$as_ln_s" = "ln -s" && test -n "$PAX" && test -n "$GZIP")
>
> AM_CONDITIONAL(HAS_CXX,test "$rtems_cv_HAS_CPLUSPLUS" = "yes")
> AM_CONDITIONAL([HAS_COMPLEX],[test "$ac_cv_header_complex_h" = yes])
> diff --git a/testsuites/libtests/tar01/Makefile.am b/testsuites/libtests/tar01/Makefile.am
> index 6bcb4f2..d7257bc 100644
> --- a/testsuites/libtests/tar01/Makefile.am
> +++ b/testsuites/libtests/tar01/Makefile.am
> @@ -1,9 +1,20 @@
> if TARTESTS
> rtems_tests_PROGRAMS = tar01
> -tar01_SOURCES = init.c ../../psxtests/psxfile01/test_cat.c \
> - initial_filesystem_tar.c initial_filesystem_tar.h
> +tar01_SOURCES =
> +tar01_SOURCES += init.c
> +tar01_SOURCES += ../../psxtests/psxfile01/test_cat.c
> +tar01_SOURCES += initial_filesystem_tar.c
> +tar01_SOURCES += initial_filesystem_tar.h
> +tar01_SOURCES += initial_filesystem_tar_gz.c
> +tar01_SOURCES += initial_filesystem_tar_gz.h
> +
> +tar01_LDADD = -lrtemscpu -lz
>
> -BUILT_SOURCES = initial_filesystem_tar.c initial_filesystem_tar.h
> +BUILT_SOURCES =
> +BUILT_SOURCES += initial_filesystem_tar.c
> +BUILT_SOURCES += initial_filesystem_tar.h
> +BUILT_SOURCES += initial_filesystem_tar_gz.c
> +BUILT_SOURCES += initial_filesystem_tar_gz.h
>
> dist_rtems_tests_DATA = tar01.scn
> dist_rtems_tests_DATA += tar01.doc
> @@ -18,7 +29,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/include
> AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> AM_CPPFLAGS += -I$(top_srcdir)/../psxtests/include
>
> -LINK_OBJS = $(tar01_OBJECTS)
> +LINK_OBJS = $(tar01_OBJECTS) $(tar01_LDADD)
> LINK_LIBS = $(tar01_LDLIBS)
>
> tar01$(EXEEXT): $(tar01_OBJECTS) $(tar01_DEPENDENCIES)
> @@ -33,6 +44,14 @@ initial_filesystem_tar.h: initial_filesystem.tar
> $(BIN2C) -H initial_filesystem.tar initial_filesystem_tar
> CLEANFILES += initial_filesystem_tar.h
>
> +initial_filesystem_tar_gz.c: initial_filesystem.tar.gz
> + $(BIN2C) -C initial_filesystem.tar.gz initial_filesystem_tar_gz
> +CLEANFILES += initial_filesystem_tar_gz.h
> +
> +initial_filesystem_tar_gz.h: initial_filesystem.tar.gz
> + $(BIN2C) -H initial_filesystem.tar.gz initial_filesystem_tar_gz
> +CLEANFILES += initial_filesystem_tar_gz.h
> +
> initial_filesystem.tar:
> rm -rf initial_fs
> $(MKDIR_P) initial_fs/home
> @@ -42,6 +61,11 @@ initial_filesystem.tar:
> $(LN_S) home/test_file symlink; \
> $(PAX) -w -f ../initial_filesystem.tar home symlink)
> CLEANFILES += initial_filesystem.tar
> +
> +initial_filesystem.tar.gz: initial_filesystem.tar
> + $(GZIP) < initial_filesystem.tar > initial_filesystem.tar.gz
> +CLEANFILES += initial_filesystem.tar.gz
> +
> endif TARTESTS
>
> clean-local:
> diff --git a/testsuites/libtests/tar01/init.c b/testsuites/libtests/tar01/init.c
> index 285c767..4bfa29c 100644
> --- a/testsuites/libtests/tar01/init.c
> +++ b/testsuites/libtests/tar01/init.c
> @@ -24,6 +24,7 @@
> #include <unistd.h>
>
> #include "initial_filesystem_tar.h"
> +#include "initial_filesystem_tar_gz.h"
>
> const char rtems_test_name[] = "TAR 1";
>
> @@ -32,9 +33,12 @@ rtems_task Init(rtems_task_argument argument);
> void test_untar_from_memory(void);
> void test_untar_from_file(void);
> void test_untar_chunks_from_memory(void);
> +void test_untar_unzip_tgz(void);
>
> #define TARFILE_START initial_filesystem_tar
> #define TARFILE_SIZE initial_filesystem_tar_size
> +#define TARFILE_GZ_START initial_filesystem_tar_gz
> +#define TARFILE_GZ_SIZE initial_filesystem_tar_gz_size
>
> void test_cat(
> char *file,
> @@ -145,6 +149,45 @@ void test_untar_chunks_from_memory(void)
>
> }
>
> +void test_untar_unzip_tgz(void)
> +{
> + int status;
> + rtems_printer printer;
> + int rv;
> + Untar_GzChunkContext ctx;
> + size_t i = 0;
> + char *buffer = (char *)TARFILE_GZ_START;
> + size_t buflen = TARFILE_GZ_SIZE;
> + char inflate_buffer;
> +
> + rtems_print_printer_printf(&printer);
> +
> + /* make a directory to untar it into */
> + rv = mkdir( "/dest3", 0777 );
> + rtems_test_assert( rv == 0 );
> +
> + rv = chdir( "/dest3" );
> + rtems_test_assert( rv == 0 );
> +
> + printf( "Untaring chunks from tgz - " );
> +
> + status = Untar_GzChunkContext_Init(&ctx, &inflate_buffer, 1);
> + rtems_test_assert(status == UNTAR_SUCCESSFUL);
> + for(i = 0; i < buflen; i++) {
> + status = Untar_FromGzChunk_Print(&ctx, &buffer[i], 1, &printer);
> + rtems_test_assert(status == UNTAR_SUCCESSFUL);
> + }
> + printf( "successful\n" );
> +
> + /******************/
> + printf( "========= /dest3/home/test_file =========\n" );
> + test_cat( "/dest3/home/test_file", 0, 0 );
> +
> + /******************/
> + printf( "========= /dest3/symlink =========\n" );
> + test_cat( "/dest3/symlink", 0, 0 );
> +}
> +
> rtems_task Init(
> rtems_task_argument ignored
> )
> @@ -156,6 +199,8 @@ rtems_task Init(
> test_untar_from_file();
> puts( "" );
> test_untar_chunks_from_memory();
> + puts( "" );
> + test_untar_unzip_tgz();
>
> TEST_END();
> exit( 0 );
> diff --git a/testsuites/libtests/tar01/tar01.doc b/testsuites/libtests/tar01/tar01.doc
> index 1a8151c..060f98a 100644
> --- a/testsuites/libtests/tar01/tar01.doc
> +++ b/testsuites/libtests/tar01/tar01.doc
> @@ -15,6 +15,7 @@ directives:
> + Untar_FromMemory
> + Untar_FromFile
> + Untar_ChunksFromMemory
> + + Untar_UnzipTgz
>
> concepts:
>
> diff --git a/testsuites/libtests/tar01/tar01.scn b/testsuites/libtests/tar01/tar01.scn
> index 078cedf..68fa951 100644
> --- a/testsuites/libtests/tar01/tar01.scn
> +++ b/testsuites/libtests/tar01/tar01.scn
> @@ -31,4 +31,15 @@ initial tar image.
> (0)This is a test of loading an RTEMS filesystem from an
> initial tar image.
>
> +
> +Untaring chunks from tgz- untar: dir: home
> +untar: file: home/test_file (73)
> +successful
> +========= /dest3/home/test_file =========
> +(0)This is a test of loading an RTEMS filesystem from an
> +initial tar image.
> +
> +========= /dest3/symlink =========
> +(0)This is a test of loading an RTEMS filesystem from an
> +initial tar image.
> *** END OF TAR01 TEST ***
>
More information about the devel
mailing list