From 6a174c024aa878e72386f811f28d880449fc264d Mon Sep 17 00:00:00 2001 From: Alexander Krutwig Date: Mon, 25 Jul 2016 15:34:43 +0200 Subject: Add Untar_FromGzChunk_Print() + Test --- 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 a50de9426d..4f5c01dd2b 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 006f06d065..4d00d369b2 100644 --- a/cpukit/libmisc/untar/untar.h +++ b/cpukit/libmisc/untar/untar.h @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -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 0000000000..1ab7ec9da5 --- /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 + * + * + * 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 + +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 a136749c8a..82f2d80a5b 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 6bcb4f26cd..d7257bc69f 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 285c767280..4bfa29c636 100644 --- a/testsuites/libtests/tar01/init.c +++ b/testsuites/libtests/tar01/init.c @@ -24,6 +24,7 @@ #include #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 1a8151c5f2..060f98a813 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 078cedffca..68fa951881 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 *** -- cgit v1.2.3