summaryrefslogtreecommitdiff
path: root/src/core_dump_handler/dlt_cdh_streamer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core_dump_handler/dlt_cdh_streamer.c')
-rw-r--r--src/core_dump_handler/dlt_cdh_streamer.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/core_dump_handler/dlt_cdh_streamer.c b/src/core_dump_handler/dlt_cdh_streamer.c
new file mode 100644
index 0000000..00b6d04
--- /dev/null
+++ b/src/core_dump_handler/dlt_cdh_streamer.c
@@ -0,0 +1,235 @@
+/*
+ * @licence app begin@
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2011-2015, BMW AG
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License (MPL), v. 2.0.
+ * If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+/*!
+ * \author Magneti Marelli http://www.magnetimarelli.com
+ * \author Lutz Helwing <lutz_helwing@mentor.com>
+ *
+ * \copyright Copyright © 2011-2015 BMW AG. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_cdh_streamer.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include "dlt_cdh_streamer.h"
+
+#define Z_CHUNK_SZ 1024*128
+#define Z_MODE_STR "wb1"
+
+cdh_status_t stream_init(file_streamer_t* p_fs, const char* p_src_fname, const char* p_dst_fname)
+{
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_init'");
+ return CDH_NOK;
+ }
+
+ memset(p_fs, 0, sizeof(file_streamer_t));
+
+ /* Allow to not save the coredump */
+ if (p_dst_fname == NULL)
+ {
+ p_fs->gz_dst_file = 0;
+ }
+ else
+ {
+ // Create output file
+ p_fs->gz_dst_file = gzopen(p_dst_fname, Z_MODE_STR);
+ if (p_fs->gz_dst_file == Z_NULL)
+ {
+ //return CDH_NOK;
+ syslog(LOG_ERR, "Cannot open output filename <%s>. %s", p_dst_fname, strerror(errno));
+ p_fs->gz_dst_file = 0;
+
+ }
+ }
+
+ if (p_fs->gz_dst_file == Z_NULL)
+ syslog(LOG_WARNING, "The coredump will be processed, but not written");
+
+ // Open input file
+ if (p_src_fname == NULL)
+ {
+ p_fs->stream = stdin;
+ }
+ else
+ {
+ if ((p_fs->stream = fopen(p_src_fname, "rb")) == NULL)
+ {
+ syslog(LOG_ERR, "Cannot open filename <%s>. %s", p_src_fname, strerror(errno));
+ return CDH_NOK;
+ }
+ }
+
+ // Allocate read buffer
+ if ((p_fs->read_buf = (unsigned char*) malloc(Z_CHUNK_SZ)) == NULL)
+ {
+ syslog(LOG_ERR, "Cannot allocate %d bytes for read buffer. %s", Z_CHUNK_SZ, strerror(errno));
+ return CDH_NOK;
+ }
+
+ return CDH_OK;
+}
+
+cdh_status_t stream_close(file_streamer_t* p_fs)
+{
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_close'");
+ return CDH_NOK;
+ }
+
+ if (p_fs->gz_dst_file != NULL)
+ {
+ gzflush(p_fs->gz_dst_file, Z_FINISH);
+ gzclose(p_fs->gz_dst_file);
+ p_fs->gz_dst_file = NULL;
+ }
+
+ if (p_fs->stream != NULL)
+ {
+ fclose(p_fs->stream);
+ p_fs->stream = NULL;
+ }
+
+ if (p_fs->read_buf != NULL)
+ {
+ free(p_fs->read_buf);
+ p_fs->read_buf = NULL;
+ }
+
+ return CDH_OK;
+}
+
+cdh_status_t stream_read(file_streamer_t* p_fs, void* p_buf, unsigned int p_size)
+{
+ unsigned int byte_read = 0;
+
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_read'");
+ return CDH_NOK;
+ }
+
+ if (p_buf == NULL)
+ {
+ syslog(LOG_ERR, "Internal buffer pointer error in 'stream_read'");
+ return CDH_NOK;
+ }
+
+ if ((byte_read = fread(p_buf, 1, p_size, p_fs->stream)) != p_size)
+ {
+ syslog(LOG_WARNING, "Cannot read %d bytes from src. %s", p_size, strerror(errno));
+ return CDH_NOK;
+ }
+
+ p_fs->offset += byte_read;
+
+ if (p_fs->gz_dst_file != NULL)
+ gzwrite(p_fs->gz_dst_file, p_buf, byte_read);
+
+ return CDH_OK;
+}
+
+int stream_finish(file_streamer_t* p_fs)
+{
+ if (p_fs == NULL || p_fs->stream == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_move_ahead'");
+ return CDH_NOK;
+ }
+
+ while (!feof(p_fs->stream))
+ {
+ size_t read_bytes = fread(p_fs->read_buf, 1, Z_CHUNK_SZ, p_fs->stream);
+
+ if (p_fs->gz_dst_file != NULL)
+ gzwrite(p_fs->gz_dst_file, p_fs->read_buf, read_bytes);
+
+ p_fs->offset += read_bytes;
+ if (ferror(p_fs->stream))
+ {
+ syslog(LOG_WARNING, "Error reading from the src stream: %s", strerror(errno));
+ return CDH_NOK;
+ }
+ }
+
+ return CDH_OK;
+}
+
+int stream_move_to_offest(file_streamer_t* p_fs, unsigned int p_offset)
+{
+ int bytes_to_read = 0;
+
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_move_to_offest'");
+ return CDH_NOK;
+ }
+
+ bytes_to_read = p_offset - p_fs->offset;
+
+ return stream_move_ahead(p_fs, bytes_to_read);
+}
+
+int stream_move_ahead(file_streamer_t* p_fs, unsigned int p_nbbytes)
+{
+ int bytes_to_read = p_nbbytes;
+
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_move_ahead'");
+ return CDH_NOK;
+ }
+
+ while (bytes_to_read > 0)
+ {
+ size_t chunk_size = bytes_to_read > Z_CHUNK_SZ ? Z_CHUNK_SZ : bytes_to_read;
+ size_t read_bytes = fread(p_fs->read_buf, 1, chunk_size, p_fs->stream);
+
+ if (read_bytes != chunk_size)
+ {
+ syslog(LOG_WARNING, "Cannot move ahead by %d bytes from src. Read %lu bytes", p_nbbytes, read_bytes);
+ return CDH_NOK;
+ }
+
+ if (p_fs->gz_dst_file != 0)
+ gzwrite(p_fs->gz_dst_file, p_fs->read_buf, chunk_size);
+
+ bytes_to_read -= chunk_size;
+ }
+
+ p_fs->offset += p_nbbytes;
+
+ return CDH_OK;
+}
+
+unsigned int stream_get_offset(file_streamer_t* p_fs)
+{
+ if (p_fs == NULL)
+ {
+ syslog(LOG_ERR, "Internal pointer error in 'stream_get_offset'");
+ return CDH_NOK;
+ }
+
+ return p_fs->offset;
+}