[PATCH] Add Untar_FromGzChunk_Print() + Test
Alexander Krutwig
alexander.krutwig at embedded-brains.de
Mon Jul 25 13:46:43 UTC 2016
---
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 ***
--
1.8.4.5
More information about the devel
mailing list