summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/untar
diff options
context:
space:
mode:
authorAlexander Krutwig <alexander.krutwig@embedded-brains.de>2016-07-25 15:34:43 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-07-26 10:00:04 +0200
commit6a174c024aa878e72386f811f28d880449fc264d (patch)
tree908ac8a0d007430611dd14a84754d94e6885fcce /cpukit/libmisc/untar
parentAdd Untar_FromChunk_Print() + Test (diff)
downloadrtems-6a174c024aa878e72386f811f28d880449fc264d.tar.bz2
Add Untar_FromGzChunk_Print() + Test
Diffstat (limited to 'cpukit/libmisc/untar')
-rw-r--r--cpukit/libmisc/untar/untar.h33
-rw-r--r--cpukit/libmisc/untar/untar_tgz.c89
2 files changed, 122 insertions, 0 deletions
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 <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 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
+ * <info@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;
+}
+
+