summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/console/dlt-convert.c11
-rw-r--r--src/daemon/CMakeLists.txt1
-rw-r--r--src/daemon/dlt-daemon.c52
-rw-r--r--src/daemon/dlt-daemon.h11
-rw-r--r--src/daemon/dlt.conf9
-rw-r--r--src/gateway/dlt_gateway.c3
-rw-r--r--src/lib/CMakeLists.txt1
-rw-r--r--src/shared/dlt_common.c156
-rw-r--r--src/shared/dlt_multiple_files.c499
-rw-r--r--src/shared/dlt_offline_trace.c397
10 files changed, 724 insertions, 416 deletions
diff --git a/src/console/dlt-convert.c b/src/console/dlt-convert.c
index b97a11f..8c72b60 100644
--- a/src/console/dlt-convert.c
+++ b/src/console/dlt-convert.c
@@ -126,17 +126,6 @@ void usage()
printf(" -t Handling input compressed files (tar.gz)\n");
}
-char *get_filename_ext(const char *filename)
-{
- if (filename == NULL)
- fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__);
-
- char *dot = strrchr(filename, '.');
- if(!dot || dot == filename)
- return "";
- return dot + 1;
-}
-
void empty_dir(const char *dir)
{
struct dirent **files = { 0 };
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index f7aaa26..9916bb4 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -32,6 +32,7 @@ set(dlt_daemon_SRCS
${PROJECT_SOURCE_DIR}/src/lib/dlt_client.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_common.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_config_file_parser.c
+ ${PROJECT_SOURCE_DIR}/src/shared/dlt_multiple_files.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_offline_trace.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_protocol.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_user_shared.c
diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c
index c8a8506..ee0f772 100644
--- a/src/daemon/dlt-daemon.c
+++ b/src/daemon/dlt-daemon.c
@@ -46,6 +46,8 @@
#endif
#include <sys/stat.h>
#include <sys/time.h>
+#include <libgen.h>
+
#if defined(linux) && defined(__NR_statx)
# include <linux/stat.h>
#endif
@@ -338,7 +340,7 @@ int option_file_parser(DltDaemonLocal *daemon_local)
daemon_local->flags.offlineTraceDirectory[0] = 0;
daemon_local->flags.offlineTraceFileSize = 1000000;
daemon_local->flags.offlineTraceMaxSize = 4000000;
- daemon_local->flags.offlineTraceFilenameTimestampBased = 1;
+ daemon_local->flags.offlineTraceFilenameTimestampBased = true;
daemon_local->flags.loggingMode = DLT_LOG_TO_CONSOLE;
daemon_local->flags.loggingLevel = LOG_INFO;
@@ -356,6 +358,9 @@ int option_file_parser(DltDaemonLocal *daemon_local)
dlt_vlog(LOG_WARNING, "%s: snprintf truncation/error(%ld) %s\n",
__func__, n, daemon_local->flags.loggingFilename);
}
+ daemon_local->flags.enableLoggingFileLimit = false;
+ daemon_local->flags.loggingFileSize = 250000;
+ daemon_local->flags.loggingFileMaxSize = 1000000;
daemon_local->timeoutOnSend = 4;
daemon_local->RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE;
@@ -514,7 +519,7 @@ int option_file_parser(DltDaemonLocal *daemon_local)
}
else if (strcmp(token, "LoggingMode") == 0)
{
- daemon_local->flags.loggingMode = atoi(value);
+ daemon_local->flags.loggingMode = (DltLoggingMode)atoi(value);
/*printf("Option: %s=%s\n",token,value); */
}
else if (strcmp(token, "LoggingLevel") == 0)
@@ -530,6 +535,18 @@ int option_file_parser(DltDaemonLocal *daemon_local)
daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename) - 1] = 0;
/*printf("Option: %s=%s\n",token,value); */
}
+ else if (strcmp(token, "EnableLoggingFileLimit") == 0)
+ {
+ daemon_local->flags.enableLoggingFileLimit = (bool)atoi(value);
+ }
+ else if (strcmp(token, "LoggingFileSize") == 0)
+ {
+ daemon_local->flags.loggingFileSize = atoi(value);
+ }
+ else if (strcmp(token, "LoggingFileMaxSize") == 0)
+ {
+ daemon_local->flags.loggingFileMaxSize = atoi(value);
+ }
else if (strcmp(token, "TimeOutOnSend") == 0)
{
daemon_local->timeoutOnSend = atoi(value);
@@ -578,7 +595,7 @@ int option_file_parser(DltDaemonLocal *daemon_local)
}
else if (strcmp(token, "OfflineTraceFileNameTimestampBased") == 0)
{
- daemon_local->flags.offlineTraceFilenameTimestampBased = atoi(value);
+ daemon_local->flags.offlineTraceFilenameTimestampBased = (bool)atoi(value);
/*printf("Option: %s=%s\n",token,value); */
}
else if (strcmp(token, "SendECUSoftwareVersion") == 0)
@@ -941,7 +958,10 @@ int main(int argc, char *argv[])
dlt_log_set_filename(daemon_local.flags.loggingFilename);
dlt_log_set_level(daemon_local.flags.loggingLevel);
DltReturnValue log_init_result =
- dlt_log_init(daemon_local.flags.loggingMode);
+ dlt_log_init_multiple_logfiles_support(daemon_local.flags.loggingMode,
+ daemon_local.flags.enableLoggingFileLimit,
+ daemon_local.flags.loggingFileSize,
+ daemon_local.flags.loggingFileMaxSize);
if (log_init_result != DLT_RETURN_OK) {
fprintf(stderr, "Failed to init internal logging\n");
@@ -1126,6 +1146,8 @@ int main(int argc, char *argv[])
dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
+ dlt_log_free();
+
return 0;
} /* main() */
@@ -1171,7 +1193,12 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in
/* Re-Initialize internal logging facility after fork */
dlt_log_set_filename(daemon_local->flags.loggingFilename);
dlt_log_set_level(daemon_local->flags.loggingLevel);
- dlt_log_init(daemon_local->flags.loggingMode);
+ // 'free' dlt logging and corresponding file handle before re-initializing
+ dlt_log_free();
+ dlt_log_init_multiple_logfiles_support(daemon_local->flags.loggingMode,
+ daemon_local->flags.enableLoggingFileLimit,
+ daemon_local->flags.loggingFileSize,
+ daemon_local->flags.loggingFileMaxSize);
/* initialise structure to use DLT file */
ret = dlt_file_init(&(daemon_local->file), daemon_local->flags.vflag);
@@ -1218,11 +1245,14 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in
/* init offline trace */
if (((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) &&
daemon_local->flags.offlineTraceDirectory[0]) {
- if (dlt_offline_trace_init(&(daemon_local->offlineTrace),
- daemon_local->flags.offlineTraceDirectory,
- daemon_local->flags.offlineTraceFileSize,
- daemon_local->flags.offlineTraceMaxSize,
- daemon_local->flags.offlineTraceFilenameTimestampBased) == -1) {
+ if (multiple_files_buffer_init(&(daemon_local->offlineTrace),
+ daemon_local->flags.offlineTraceDirectory,
+ daemon_local->flags.offlineTraceFileSize,
+ daemon_local->flags.offlineTraceMaxSize,
+ daemon_local->flags.offlineTraceFilenameTimestampBased,
+ false,
+ DLT_OFFLINETRACE_FILENAME_BASE,
+ DLT_OFFLINETRACE_FILENAME_EXT) == -1) {
dlt_log(LOG_ERR, "Could not initialize offline trace\n");
return -1;
}
@@ -1786,7 +1816,7 @@ void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, i
/* free shared memory */
if (daemon_local->flags.offlineTraceDirectory[0])
- dlt_offline_trace_free(&(daemon_local->offlineTrace));
+ multiple_files_buffer_free(&(daemon_local->offlineTrace));
/* Ignore result */
dlt_file_free(&(daemon_local->file), daemon_local->flags.vflag);
diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h
index 071562f..cc879cb 100644
--- a/src/daemon/dlt-daemon.h
+++ b/src/daemon/dlt-daemon.h
@@ -69,6 +69,7 @@
#include <limits.h> /* for NAME_MAX */
#include <sys/time.h>
+#include <stdarg.h>
#include "dlt_daemon_common.h"
#include "dlt_user_shared.h"
@@ -103,10 +104,13 @@ typedef struct
char offlineTraceDirectory[DLT_DAEMON_FLAG_MAX]; /**< (String: Directory) Store DLT messages to local directory (Default: /etc/dlt.conf) */
int offlineTraceFileSize; /**< (int) Maximum size in bytes of one trace file (Default: 1000000) */
int offlineTraceMaxSize; /**< (int) Maximum size of all trace files (Default: 4000000) */
- int offlineTraceFilenameTimestampBased; /**< (int) timestamp based or index based (Default: 1 Timestamp based) */
- int loggingMode; /**< (int) The logging console for internal logging of dlt-daemon (Default: 0) */
+ bool offlineTraceFilenameTimestampBased; /**< (Boolean) timestamp based or index based (Default: true=Timestamp based) */
+ DltLoggingMode loggingMode; /**< (int) The logging console for internal logging of dlt-daemon (Default: 0) */
int loggingLevel; /**< (int) The logging level for internal logging of dlt-daemon (Default: 6) */
char loggingFilename[DLT_DAEMON_FLAG_MAX]; /**< (String: Filename) The logging filename if internal logging mode is log to file (Default: /tmp/log) */
+ bool enableLoggingFileLimit; /**< (Boolean) Indicate whether size of logging file(s) is limited (Default: false) */
+ int loggingFileSize; /**< (int) Maximum size in bytes of one logging file (Default: 250000) */
+ int loggingFileMaxSize; /**< (int) Maximum size in bytes of all logging files (Default: 1000000) */
int sendECUSoftwareVersion; /**< (Boolean) Send ECU software version perdiodically */
char pathToECUSoftwareVersion[DLT_DAEMON_FLAG_MAX]; /**< (String: Filename) The file from which to read the ECU version from. */
int sendTimezone; /**< (Boolean) Send Timezone perdiodically */
@@ -154,7 +158,8 @@ typedef struct
DltShm dlt_shm; /**< Shared memory handling */
unsigned char *recv_buf_shm; /**< buffer for receive message from shm */
#endif
- DltOfflineTrace offlineTrace; /**< Offline trace handling */
+ MultipleFilesRingBuffer offlineTrace; /**< Offline trace handling */
+ MultipleFilesRingBuffer dltLogging; /**< Dlt logging handling */
int timeoutOnSend;
unsigned long RingbufferMinSize;
unsigned long RingbufferMaxSize;
diff --git a/src/daemon/dlt.conf b/src/daemon/dlt.conf
index 777aa82..11a5057 100644
--- a/src/daemon/dlt.conf
+++ b/src/daemon/dlt.conf
@@ -50,6 +50,15 @@ LoggingLevel = 6
# if WITH_DLT_FILE_LOGGING_SYSLOG_FALLBACK is set as compile flag
LoggingFilename = /tmp/dlt.log
+# Indicate whether size of logging file(s) is limited (Default: 0)
+EnableLoggingFileLimit = 0
+
+# Maximum size in bytes of one logging file (Default: 250000)
+# LoggingFileSize = 250000
+
+# Maximum size in bytes of all logging files (Default: 1000000)
+# LoggingFileMaxSize = 1000000
+
# Timeout on send to client (sec)
TimeOutOnSend = 4
diff --git a/src/gateway/dlt_gateway.c b/src/gateway/dlt_gateway.c
index 2b4f070..3d832ce 100644
--- a/src/gateway/dlt_gateway.c
+++ b/src/gateway/dlt_gateway.c
@@ -669,6 +669,9 @@ int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose)
/* read configuration file */
file = dlt_config_file_init(config_file);
+ if(file == NULL) {
+ return DLT_RETURN_ERROR;
+ }
/* get number of entries and allocate memory to store information */
ret = dlt_config_file_get_num_sections(file, &num_sections);
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 3293376..e6d6334 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -19,6 +19,7 @@ set(dlt_LIB_SRCS
dlt_filetransfer.c
dlt_env_ll.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_common.c
+ ${PROJECT_SOURCE_DIR}/src/shared/dlt_multiple_files.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_protocol.c
${PROJECT_SOURCE_DIR}/src/shared/dlt_user_shared.c
)
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c
index 97766f7..cbbe99a 100644
--- a/src/shared/dlt_common.c
+++ b/src/shared/dlt_common.c
@@ -31,6 +31,7 @@
#include <time.h> /* for localtime_r(), strftime() */
#include <limits.h> /* for NAME_MAX */
#include <inttypes.h> /* for PRI formatting macro */
+#include <libgen.h> /* dirname */
#include <stdarg.h>
#include <err.h>
@@ -41,6 +42,7 @@
#include "dlt_user_shared.h"
#include "dlt_common.h"
#include "dlt_common_cfg.h"
+#include "dlt_multiple_files.h"
#include "dlt_version.h"
@@ -84,6 +86,17 @@ static bool print_with_attributes = false;
int logging_mode = DLT_LOG_TO_STDERR;
FILE *logging_handle = NULL;
+//use ohandle as an indicator that multiple files logging is active
+MultipleFilesRingBuffer multiple_files_ring_buffer = {
+ .directory={0},
+ .filename={0},
+ .fileSize=0,
+ .maxSize=0,
+ .filenameTimestampBased=false,
+ .filenameBase={0},
+ .filenameExt={0},
+ .ohandle=-1};
+
char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" };
char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" };
char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" };
@@ -1816,34 +1829,114 @@ void dlt_print_with_attributes(bool state)
DltReturnValue dlt_log_init(int mode)
{
+ return dlt_log_init_multiple_logfiles_support((DltLoggingMode)mode, false, 0, 0);
+}
+
+DltReturnValue dlt_log_init_multiple_logfiles_support(const DltLoggingMode mode, const bool enable_multiple_logfiles,
+ const int logging_file_size, const int logging_files_max_size)
+{
if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) {
- dlt_user_printf("Wrong parameter for mode: %d\n", mode);
+ dlt_vlog(LOG_WARNING, "Wrong parameter for mode: %d\n", mode);
return DLT_RETURN_WRONG_PARAMETER;
}
logging_mode = mode;
- if (logging_mode == DLT_LOG_TO_FILE) {
- /* internal logging to file */
- logging_handle = fopen(logging_filename, "a");
+ if (logging_mode != DLT_LOG_TO_FILE) {
+ return DLT_RETURN_OK;
+ }
- if (logging_handle == NULL) {
- dlt_user_printf("Internal log file %s cannot be opened!\n", logging_filename);
- return DLT_RETURN_ERROR;
+ if (enable_multiple_logfiles) {
+ dlt_user_printf("configure dlt logging using file limits\n");
+ int result = dlt_log_init_multiple_logfiles(logging_file_size, logging_files_max_size);
+ if (result == DLT_RETURN_OK) {
+ return DLT_RETURN_OK;
}
+ dlt_user_printf("dlt logging for limits fails with error code=%d, use logging without limits as fallback\n", result);
+ return dlt_log_init_single_logfile();
+ } else {
+ dlt_user_printf("configure dlt logging without file limits\n");
+ return dlt_log_init_single_logfile();
}
+}
+DltReturnValue dlt_log_init_single_logfile()
+{
+ /* internal logging to file */
+ errno = 0;
+ logging_handle = fopen(logging_filename, "a");
+
+ if (logging_handle == NULL) {
+ dlt_user_printf("Internal log file %s cannot be opened, error: %s\n", logging_filename, strerror(errno));
+ return DLT_RETURN_ERROR;
+ }
return DLT_RETURN_OK;
}
+DltReturnValue dlt_log_init_multiple_logfiles(const int logging_file_size, const int logging_files_max_size)
+{
+ char path_logging_filename[PATH_MAX + 1];
+ strncpy(path_logging_filename, logging_filename, PATH_MAX);
+ path_logging_filename[PATH_MAX] = 0;
+
+ const char *directory = dirname(path_logging_filename);
+ if (directory[0]) {
+ char basename_logging_filename[NAME_MAX + 1];
+ strncpy(basename_logging_filename, logging_filename, NAME_MAX);
+ basename_logging_filename[NAME_MAX] = 0;
+
+ const char *file_name = basename(basename_logging_filename);
+ char filename_base[NAME_MAX];
+ if (!dlt_extract_base_name_without_ext(file_name, filename_base, sizeof(filename_base))) return DLT_RETURN_ERROR;
+
+ const char *filename_ext = get_filename_ext(file_name);
+ if (!filename_ext) return DLT_RETURN_ERROR;
+
+ DltReturnValue result = multiple_files_buffer_init(
+ &multiple_files_ring_buffer,
+ directory,
+ logging_file_size,
+ logging_files_max_size,
+ false,
+ true,
+ filename_base,
+ filename_ext);
+
+ return result;
+ }
+
+ return DLT_RETURN_ERROR;
+}
+
void dlt_log_free(void)
{
- if (logging_mode == DLT_LOG_TO_FILE && logging_handle)
+ if (logging_mode == DLT_LOG_TO_FILE) {
+ if (dlt_is_log_in_multiple_files_active()) {
+ dlt_log_free_multiple_logfiles();
+ } else {
+ dlt_log_free_single_logfile();
+ }
+ }
+}
+
+void dlt_log_free_single_logfile()
+{
+ if (logging_handle)
fclose(logging_handle);
}
+void dlt_log_free_multiple_logfiles()
+{
+ if (DLT_RETURN_ERROR == multiple_files_buffer_free(&multiple_files_ring_buffer)) return;
+
+ // reset indicator of multiple files usage
+ multiple_files_ring_buffer.ohandle = -1;
+}
+
int dlt_user_printf(const char *format, ...)
{
+ if (format == NULL) return -1;
+
va_list args;
va_start(args, format);
@@ -1922,9 +2015,13 @@ DltReturnValue dlt_log(int prio, char *s)
#endif
break;
case DLT_LOG_TO_FILE:
-
/* log to file */
- if (logging_handle) {
+
+ if (dlt_is_log_in_multiple_files_active()) {
+ dlt_log_multiple_files_write(sFormatString, (unsigned int)sTimeSpec.tv_sec,
+ (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s);
+ }
+ else if (logging_handle) {
fprintf(logging_handle, sFormatString, (unsigned int)sTimeSpec.tv_sec,
(unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s);
fflush(logging_handle);
@@ -4308,3 +4405,42 @@ int dlt_execute_command(char *filename, char *command, ...)
free(args);
return ret;
}
+
+char *get_filename_ext(const char *filename)
+{
+ if (filename == NULL) {
+ fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__);
+ return NULL;
+ }
+
+ char *dot = strrchr(filename, '.');
+ return (!dot || dot == filename) ? NULL : dot;
+}
+
+bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) {
+ if (abs_file_name == NULL || base_name == NULL) return false;
+
+ const char* last_separator = strrchr(abs_file_name, '.');
+ if (!last_separator) return false;
+ long length = last_separator - abs_file_name;
+ length = length > base_name_len ? base_name_len : length;
+
+ strncpy(base_name, abs_file_name, length);
+ base_name[length] = '\0';
+ return true;
+}
+
+void dlt_log_multiple_files_write(const char* format, ...)
+{
+ char output_string[2048] = { 0 };
+ va_list args;
+ va_start (args, format);
+ vsnprintf(output_string, 2047, format, args);
+ va_end (args);
+ multiple_files_buffer_write(&multiple_files_ring_buffer, (unsigned char*)output_string, strlen(output_string));
+}
+
+bool dlt_is_log_in_multiple_files_active()
+{
+ return multiple_files_ring_buffer.ohandle > -1;
+}
diff --git a/src/shared/dlt_multiple_files.c b/src/shared/dlt_multiple_files.c
new file mode 100644
index 0000000..754fd1e
--- /dev/null
+++ b/src/shared/dlt_multiple_files.c
@@ -0,0 +1,499 @@
+/*
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2022, Daimler TSS GmbH
+ *
+ * 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 https://www.covesa.global/.
+ */
+
+/*!
+ * \author
+ * Oleg Tropmann <oleg.tropmann@daimler.com>
+ * Daniel Weber <daniel.w.weber@daimler.com>
+ *
+ * \copyright Copyright © 2022 Daimler TSS GmbH. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_daemon_log.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include <dlt_multiple_files.h>
+#include "dlt_common.h"
+
+unsigned int multiple_files_buffer_storage_dir_info(const char *path, const char *file_name,
+ char *newest, char *oldest)
+{
+ int i = 0;
+ unsigned int num_log_files = 0;
+ struct dirent **files = { 0 };
+ char *tmp_old = NULL;
+ char *tmp_new = NULL;
+
+ if ((path == NULL) || (file_name == NULL) || (newest == NULL) || (oldest == NULL)) {
+ fprintf(stderr, "multiple_files_buffer_storage_dir_info: Invalid parameter(s)");
+ return 0;
+ }
+
+ const int file_cnt = scandir(path, &files, NULL, alphasort);
+ if (file_cnt <= 0) return 0;
+
+ for (i = 0; i < file_cnt; i++) {
+ int len = 0;
+ len = strlen(file_name);
+
+ if ((strncmp(files[i]->d_name, file_name, len) == 0) &&
+ (files[i]->d_name[len] == MULTIPLE_FILES_FILENAME_INDEX_DELIM[0])) {
+ num_log_files++;
+
+ if ((tmp_old == NULL) || (strlen(tmp_old) >= strlen(files[i]->d_name))) {
+ if (tmp_old == NULL) {
+ tmp_old = files[i]->d_name;
+ } else if (strlen(tmp_old) > strlen(files[i]->d_name)) {
+ /* when file name is smaller, it is older */
+ tmp_old = files[i]->d_name;
+ } else if (strcmp(tmp_old, files[i]->d_name) > 0) {
+ /* filename length is equal, do a string compare */
+ tmp_old = files[i]->d_name;
+ }
+ }
+
+ if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) {
+ if (tmp_new == NULL) {
+ tmp_new = files[i]->d_name;
+ } else if (strlen(tmp_new) < strlen(files[i]->d_name)) {
+ /* when file name is longer, it is younger */
+ tmp_new = files[i]->d_name;
+ } else if (strcmp(tmp_new, files[i]->d_name) < 0) {
+ tmp_new = files[i]->d_name;
+ }
+ }
+ }
+ }
+
+ if (num_log_files > 0) {
+ if ((tmp_old != NULL) && (strlen(tmp_old) < NAME_MAX)) {
+ strncpy(oldest, tmp_old, NAME_MAX);
+ oldest[NAME_MAX] = '\0';
+ } else if ((tmp_old != NULL) && (strlen(tmp_old) >= NAME_MAX)) {
+ printf("length mismatch of file %s\n", tmp_old);
+ }
+
+ if ((tmp_new != NULL) && (strlen(tmp_new) < NAME_MAX)) {
+ strncpy(newest, tmp_new, NAME_MAX);
+ oldest[NAME_MAX] = '\0';
+ } else if ((tmp_new != NULL) && (strlen(tmp_new) >= NAME_MAX)) {
+ printf("length mismatch of file %s\n", tmp_new);
+ }
+ }
+
+ /* free scandir result */
+ for (i = 0; i < file_cnt; i++) free(files[i]);
+
+ free(files);
+
+ return num_log_files;
+}
+
+void multiple_files_buffer_file_name(MultipleFilesRingBuffer *files_buffer, const size_t length, const unsigned int idx)
+{
+ char file_index[11]; /* UINT_MAX = 4294967295 -> 10 digits */
+ snprintf(file_index, sizeof(file_index), "%010u", idx);
+
+ /* create log file name */
+ char* file_name = files_buffer->filename;
+ memset(file_name, 0, length * sizeof(char));
+
+ const size_t size = length - strlen(file_name) - 1;
+ strncat(file_name, files_buffer->filenameBase, size);
+ strncat(file_name, MULTIPLE_FILES_FILENAME_INDEX_DELIM, size);
+ strncat(file_name, file_index, size);
+ strncat(file_name, files_buffer->filenameExt, size);
+}
+
+unsigned int multiple_files_buffer_get_idx_of_log_file(char *file)
+{
+ if ((file == NULL) || (file[0] == '\0')) return 0;
+
+ const char d[2] = MULTIPLE_FILES_FILENAME_INDEX_DELIM;
+ char *token;
+
+ token = strtok(file, d);
+ /* we are interested in 2. token because of log file name */
+ token = strtok(NULL, d);
+
+ return token != NULL ? strtol(token, NULL, 10) : 0;
+}
+
+DltReturnValue multiple_files_buffer_create_new_file(MultipleFilesRingBuffer *files_buffer)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ time_t t;
+ struct tm tmp;
+ char file_path[PATH_MAX + 1];
+ unsigned int idx = 0;
+ int ret = 0;
+
+ /* set filename */
+ if (files_buffer->filenameTimestampBased) {
+ /* timestamp format: "yyyymmdd_hhmmss" */
+ char timestamp[16];
+ t = time(NULL);
+ tzset();
+ localtime_r(&t, &tmp);
+
+ strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &tmp);
+
+ ret = snprintf(files_buffer->filename, sizeof(files_buffer->filename), "%s%s%s%s",
+ files_buffer->filenameBase,
+ MULTIPLE_FILES_FILENAME_TIMESTAMP_DELIM, timestamp,
+ files_buffer->filenameExt);
+
+ if ((ret < 0) || ((size_t)ret >= (int)sizeof(files_buffer->filename))) {
+ fprintf(stderr, "filename cannot be concatenated\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ ret = snprintf(file_path, sizeof(file_path), "%s/%s",
+ files_buffer->directory, files_buffer->filename);
+
+ if ((ret < 0) || ((size_t)ret >= (int)sizeof(file_path))) {
+ fprintf(stderr, "file path cannot be concatenated\n");
+ return DLT_RETURN_ERROR;
+ }
+ }
+ else {
+ char newest[NAME_MAX + 1] = { 0 };
+ char oldest[NAME_MAX + 1] = { 0 };
+ /* targeting newest file, ignoring number of files in dir returned */
+ if (0 == multiple_files_buffer_storage_dir_info(files_buffer->directory,
+ files_buffer->filenameBase,
+ newest,
+ oldest)) {
+ printf("No multiple files found\n");
+ }
+
+ idx = multiple_files_buffer_get_idx_of_log_file(newest) + 1;
+
+ multiple_files_buffer_file_name(files_buffer, sizeof(files_buffer->filename), idx);
+ ret = snprintf(file_path, sizeof(file_path), "%s/%s",
+ files_buffer->directory, files_buffer->filename);
+
+ if ((ret < 0) || (ret >= NAME_MAX)) {
+ fprintf(stderr, "filename cannot be concatenated\n");
+ return DLT_RETURN_ERROR;
+ }
+ }
+
+ /* open DLT output file */
+ errno = 0;
+ files_buffer->ohandle = open(file_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH); /* mode: wb */
+
+ if (files_buffer->ohandle == -1) {
+ /* file cannot be opened */
+ fprintf(stderr, "file %s cannot be created, error: %s\n", file_path, strerror(errno));
+ return DLT_RETURN_ERROR;
+ }
+
+ return DLT_RETURN_OK;
+}
+
+ssize_t multiple_files_buffer_get_total_size(const MultipleFilesRingBuffer *files_buffer)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return -1;
+ }
+
+ struct dirent *dp;
+ char filename[PATH_MAX + 1];
+ ssize_t size = 0;
+ struct stat status;
+
+ /* go through all dlt files in directory */
+ DIR *dir = opendir(files_buffer->directory);
+ if (!dir) {
+ fprintf(stderr, "directory %s cannot be opened, error=%s\n", files_buffer->directory, strerror(errno));
+ return -1;
+ }
+
+ while ((dp = readdir(dir)) != NULL) {
+ // consider files matching with a specific base name and a particular extension
+ if (strstr(dp->d_name, files_buffer->filenameBase) && strstr(dp->d_name, files_buffer->filenameExt)) {
+ int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
+
+ /* if the total length of the string is greater than the buffer, silently forget it. */
+ /* snprintf: a return value of size or more means that the output was truncated */
+ /* if an output error is encountered, a negative value is returned. */
+ if (((unsigned int)res < sizeof(filename)) && (res > 0)) {
+ errno = 0;
+ if (0 == stat(filename, &status))
+ size += status.st_size;
+ else
+ fprintf(stderr, "file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
+ }
+ }
+ }
+
+ closedir(dir);
+
+ /* return size */
+ return size;
+}
+
+int multiple_files_buffer_delete_oldest_file(MultipleFilesRingBuffer *files_buffer)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return -1; /* ERROR */
+ }
+
+ struct dirent *dp;
+ char filename[PATH_MAX + 1];
+ char filename_oldest[PATH_MAX + 1];
+ unsigned long size_oldest = 0;
+ struct stat status;
+ time_t time_oldest = 0;
+ int index_oldest = INT_MAX;
+
+ filename[0] = 0;
+ filename_oldest[0] = 0;
+
+ /* go through all dlt files in directory */
+ DIR *dir = opendir(files_buffer->directory);
+
+ if(!dir)
+ return -1;
+
+ while ((dp = readdir(dir)) != NULL) {
+ if (strstr(dp->d_name, files_buffer->filenameBase) && strstr(dp->d_name, files_buffer->filenameExt)) {
+ int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
+
+ /* if the total length of the string is greater than the buffer, silently forget it. */
+ /* snprintf: a return value of size or more means that the output was truncated */
+ /* if an output error is encountered, a negative value is returned. */
+ if (((unsigned int) res >= sizeof(filename)) || (res <= 0)) {
+ printf("Filename for delete oldest too long. Skip file.\n");
+ continue;
+ }
+
+ if (files_buffer->filenameTimestampBased) {
+ errno = 0;
+ if (0 == stat(filename, &status)) {
+ if ((time_oldest == 0) || (status.st_mtime < time_oldest)) {
+ time_oldest = status.st_mtime;
+ size_oldest = status.st_size;
+ strncpy(filename_oldest, filename, PATH_MAX);
+ filename_oldest[PATH_MAX] = 0;
+ }
+ } else {
+ printf("Old file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
+ }
+ } else {
+ //index based
+ const int index = multiple_files_buffer_get_idx_of_log_file(filename);
+ if (index < index_oldest) {
+ index_oldest = index;
+ snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
+ strncpy(filename_oldest, filename, PATH_MAX);
+ filename_oldest[PATH_MAX] = 0;
+ }
+ }
+ }
+ }
+
+ closedir(dir);
+
+ /* delete file */
+ if (filename_oldest[0]) {
+ if (remove(filename_oldest)) {
+ fprintf(stderr, "Remove file %s failed! error=%s\n", filename_oldest, strerror(errno));
+ return -1; /* ERROR */
+ }
+ } else {
+ fprintf(stderr, "No file to be removed!\n");
+ return -1; /* ERROR */
+ }
+
+ /* return size of deleted file*/
+ return size_oldest;
+}
+
+DltReturnValue multiple_files_buffer_check_size(MultipleFilesRingBuffer *files_buffer)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ struct stat status;
+
+ /* check for existence of buffer files directory */
+ errno = 0;
+ if (stat(files_buffer->directory, &status) == -1) {
+ fprintf(stderr, "Buffer files directory: %s doesn't exist, error=%s\n", files_buffer->directory, strerror(errno));
+ return DLT_RETURN_ERROR;
+ }
+ /* check for accessibility of buffer files directory */
+ else if (access(files_buffer->directory, W_OK) != 0) {
+ fprintf(stderr, "Buffer files directory: %s doesn't have the write access \n", files_buffer->directory);
+ return DLT_RETURN_ERROR;
+ }
+
+ ssize_t total_size = 0;
+ /* check size of complete buffer file */
+ while ((total_size = multiple_files_buffer_get_total_size(files_buffer)) > (files_buffer->maxSize - files_buffer->fileSize)) {
+ /* remove the oldest files as long as new file will not fit in completely into complete multiple files buffer */
+ if (multiple_files_buffer_delete_oldest_file(files_buffer) < 0) return DLT_RETURN_ERROR;
+ }
+
+ return total_size == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
+}
+
+DltReturnValue multiple_files_buffer_open_file_for_append(MultipleFilesRingBuffer *files_buffer) {
+ if (files_buffer == NULL || files_buffer->filenameTimestampBased) return DLT_RETURN_ERROR;
+
+ char newest[NAME_MAX + 1] = {0};
+ char oldest[NAME_MAX + 1] = {0};
+ /* targeting the newest file, ignoring number of files in dir returned */
+
+ if (0 == multiple_files_buffer_storage_dir_info(files_buffer->directory,
+ files_buffer->filenameBase, newest, oldest) ) {
+ // no file for appending found. Create a new one
+ printf("No multiple files for appending found. Create a new one\n");
+ return multiple_files_buffer_create_new_file(files_buffer);
+ }
+
+ char file_path[PATH_MAX + 1];
+ int ret = snprintf(file_path, sizeof(file_path), "%s/%s",
+ files_buffer->directory, newest);
+
+ if ((ret < 0) || (ret >= NAME_MAX)) {
+ fprintf(stderr, "filename cannot be concatenated\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ /* open DLT output file */
+ errno = 0;
+ files_buffer->ohandle = open(file_path, O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH); /* mode: wb */
+
+ return files_buffer->ohandle == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
+}
+
+DltReturnValue multiple_files_buffer_init(MultipleFilesRingBuffer *files_buffer,
+ const char *directory,
+ const int file_size,
+ const int max_size,
+ const bool filename_timestamp_based,
+ const bool append,
+ const char *filename_base,
+ const char *filename_ext)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ /* init parameters */
+ strncpy(files_buffer->directory, directory, NAME_MAX);
+ files_buffer->directory[NAME_MAX] = 0;
+ files_buffer->fileSize = file_size;
+ files_buffer->maxSize = max_size;
+ files_buffer->filenameTimestampBased = filename_timestamp_based;
+ strncpy(files_buffer->filenameBase, filename_base, NAME_MAX);
+ files_buffer->filenameBase[NAME_MAX] = 0;
+ strncpy(files_buffer->filenameExt, filename_ext, NAME_MAX);
+ files_buffer->filenameExt[NAME_MAX] = 0;
+
+ if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer)) return DLT_RETURN_ERROR;
+
+ return (!files_buffer->filenameTimestampBased && append)
+ ? multiple_files_buffer_open_file_for_append(files_buffer)
+ : multiple_files_buffer_create_new_file(files_buffer);
+}
+
+void multiple_files_buffer_rotate_file(MultipleFilesRingBuffer *files_buffer, const int size)
+{
+ /* check file size here */
+ if ((lseek(files_buffer->ohandle, 0, SEEK_CUR) + size) < files_buffer->fileSize) return;
+
+ /* close old file */
+ close(files_buffer->ohandle);
+ files_buffer->ohandle = -1;
+
+ /* check complete files size, remove old logs if needed */
+ if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer)) return;
+
+ /* create new file */
+ multiple_files_buffer_create_new_file(files_buffer);
+}
+
+DltReturnValue multiple_files_buffer_write_chunk(const MultipleFilesRingBuffer *files_buffer,
+ const unsigned char *data,
+ const int size)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ if (data && (files_buffer->ohandle >= 0)) {
+ if (write(files_buffer->ohandle, data, size) != size) {
+ fprintf(stderr, "file write failed!\n");
+ return DLT_RETURN_ERROR;
+ }
+ }
+ return DLT_RETURN_OK;
+}
+
+DltReturnValue multiple_files_buffer_write(MultipleFilesRingBuffer *files_buffer,
+ const unsigned char *data,
+ const int size)
+{
+ if (files_buffer->ohandle < 0) return DLT_RETURN_ERROR;
+
+ multiple_files_buffer_rotate_file(files_buffer, size);
+
+ /* write data into log file */
+ return multiple_files_buffer_write_chunk(files_buffer, data, size);
+}
+
+DltReturnValue multiple_files_buffer_free(const MultipleFilesRingBuffer *files_buffer)
+{
+ if (files_buffer == NULL) {
+ fprintf(stderr, "multiple files buffer not set\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ if (files_buffer->ohandle < 0) return DLT_RETURN_ERROR;
+
+ /* close last used log file */
+ close(files_buffer->ohandle);
+
+ return DLT_RETURN_OK;
+}
diff --git a/src/shared/dlt_offline_trace.c b/src/shared/dlt_offline_trace.c
index 2b1e0df..b8b9a85 100644
--- a/src/shared/dlt_offline_trace.c
+++ b/src/shared/dlt_offline_trace.c
@@ -61,393 +61,28 @@
#include <unistd.h>
#include <dirent.h>
#include <syslog.h>
+#include <errno.h>
#include <dlt_offline_trace.h>
-#include "dlt_common.h"
-
-unsigned int dlt_offline_trace_storage_dir_info(char *path, char *file_name, char *newest, char *oldest)
-{
- int i = 0;
- unsigned int num = 0;
- int cnt = 0;
- struct dirent **files = { 0 };
- char *tmp_old = NULL;
- char *tmp_new = NULL;
-
- if ((path == NULL) || (file_name == NULL) || (newest == NULL) || (oldest == NULL)) {
- printf("dlt_offline_trace_storage_dir_info: Invalid parameter(s)");
- return 0;
- }
-
- cnt = scandir(path, &files, NULL, alphasort);
-
- if (cnt < 0)
- return 0;
-
- for (i = 0; i < cnt; i++) {
- int len = 0;
- len = strlen(file_name);
-
- if ((strncmp(files[i]->d_name, file_name, len) == 0) &&
- (files[i]->d_name[len] == DLT_OFFLINETRACE_FILENAME_INDEX_DELI[0])) {
- num++;
-
- if ((tmp_old == NULL) || (strlen(tmp_old) >= strlen(files[i]->d_name))) {
- if (tmp_old == NULL)
- tmp_old = files[i]->d_name;
- /* when file name is smaller, it is older */
- else if (strlen(tmp_old) > strlen(files[i]->d_name))
- tmp_old = files[i]->d_name;
- else /* filename is equal, do a string compare */
- if (strcmp(tmp_old, files[i]->d_name) > 0)
- tmp_old = files[i]->d_name;
- }
-
- if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) {
- if (tmp_new == NULL)
- tmp_new = files[i]->d_name;
- /* when file name is longer, it is younger */
- else if (strlen(tmp_new) < strlen(files[i]->d_name))
- tmp_new = files[i]->d_name;
- else if (strcmp(tmp_new, files[i]->d_name) < 0)
- tmp_new = files[i]->d_name;
- }
- }
- }
-
- if (num > 0) {
- if ((tmp_old != NULL) && (strlen(tmp_old) < NAME_MAX)) {
- strncpy(oldest, tmp_old, NAME_MAX);
- oldest[NAME_MAX] = '\0';
- }
-
- if ((tmp_new != NULL) && (strlen(tmp_old) < NAME_MAX)) {
- strncpy(newest, tmp_new, NAME_MAX);
- oldest[NAME_MAX] = '\0';
- }
- }
-
- /* free scandir result */
- for (i = 0; i < cnt; i++)
- free(files[i]);
-
- free(files);
-
- return num;
-}
-
-void dlt_offline_trace_file_name(char *log_file_name, size_t length,
- char *name, unsigned int idx)
-{
- char file_index[11]; /* UINT_MAX = 4294967295 -> 10 digits */
- snprintf(file_index, sizeof(file_index), "%010u", idx);
-
- /* create log file name */
- memset(log_file_name, 0, length * sizeof(char));
- strncat(log_file_name, name, length - strlen(log_file_name) - 1);
- strncat(log_file_name, DLT_OFFLINETRACE_FILENAME_INDEX_DELI,
- length - strlen(log_file_name) - 1);
- strncat(log_file_name, file_index, length - strlen(log_file_name) - 1);
- strncat(log_file_name, DLT_OFFLINETRACE_FILENAME_EXT,
- length - strlen(log_file_name) - 1);
-}
-
-unsigned int dlt_offline_trace_get_idx_of_log_file(char *file)
-{
- const char d[2] = DLT_OFFLINETRACE_FILENAME_INDEX_DELI;
- char *token;
- unsigned int idx = 0;
-
- if (file[0] == '\0')
- return 0;
-
- token = strtok(file, d);
- /* we are interested in 2. token because of log file name */
- token = strtok(NULL, d);
-
- if (token != NULL)
- idx = strtol(token, NULL, 10);
- else
- idx = 0;
-
- return idx;
-}
-
-
-DltReturnValue dlt_offline_trace_create_new_file(DltOfflineTrace *trace)
-{
- time_t t;
- struct tm tmp;
- char file_path[PATH_MAX + 1];
- unsigned int idx = 0;
- int ret = 0;
-
- /* set filename */
- if (trace->filenameTimestampBased) {
- /* timestamp format: "yyyymmdd_hhmmss" */
- char timestamp[16];
- t = time(NULL);
- tzset();
- localtime_r(&t, &tmp);
-
- strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &tmp);
-
- ret = snprintf(trace->filename, sizeof(trace->filename), "%s%s%s%s",
- DLT_OFFLINETRACE_FILENAME_BASE,
- DLT_OFFLINETRACE_FILENAME_TIMESTAMP_DELI, timestamp,
- DLT_OFFLINETRACE_FILENAME_EXT);
-
- if ((ret < 0) || ((size_t)ret >= (int)sizeof(trace->filename))) {
- printf("dlt_offlinetrace filename cannot be concatenated\n");
- return DLT_RETURN_ERROR;
- }
-
- ret = snprintf(file_path, sizeof(file_path), "%s/%s",
- trace->directory, trace->filename);
-
- if ((ret < 0) || ((size_t)ret >= (int)sizeof(file_path))) {
- printf("dlt_offlinetrace file path cannot be concatenated\n");
- return DLT_RETURN_ERROR;
- }
- }
- else {
- char newest[NAME_MAX + 1] = { 0 };
- char oldest[NAME_MAX + 1] = { 0 };
- /* targeting newest file, ignoring number of files in dir returned */
- dlt_offline_trace_storage_dir_info(trace->directory,
- DLT_OFFLINETRACE_FILENAME_BASE, newest, oldest);
- idx = dlt_offline_trace_get_idx_of_log_file(newest) + 1;
-
- dlt_offline_trace_file_name(trace->filename, sizeof(trace->filename),
- DLT_OFFLINETRACE_FILENAME_BASE, idx);
- ret = snprintf(file_path, sizeof(file_path), "%s/%s",
- trace->directory, trace->filename);
-
- if ((ret < 0) || (ret >= NAME_MAX)) {
- printf("filename cannot be concatenated\n");
- return DLT_RETURN_ERROR;
- }
- }
-
- /* open DLT output file */
- trace->ohandle = open(file_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
- S_IRGRP | S_IROTH); /* mode: wb */
-
- if (trace->ohandle == -1) {
- /* trace file cannot be opened */
- printf("Offline trace file %s cannot be created\n", file_path);
- return DLT_RETURN_ERROR;
- } /* if */
-
- return DLT_RETURN_OK; /* OK */
-}
-
-ssize_t dlt_offline_trace_get_total_size(DltOfflineTrace *trace)
-{
- struct dirent *dp;
- char filename[PATH_MAX + 1];
- ssize_t size = 0;
- struct stat status;
-
- /* go through all dlt files in directory */
- DIR *dir = opendir(trace->directory);
-
- if (!dir)
- return -1;
-
- while ((dp = readdir(dir)) != NULL)
- if (strstr(dp->d_name, DLT_OFFLINETRACE_FILENAME_BASE)) {
- int res = snprintf(filename, sizeof(filename), "%s/%s", trace->directory, dp->d_name);
-
- /* if the total length of the string is greater than the buffer, silently forget it. */
- /* snprintf: a return value of size or more means that the output was truncated */
- /* if an output error is encountered, a negative value is returned. */
- if (((unsigned int)res < sizeof(filename)) && (res > 0)) {
- if (0 == stat(filename, &status))
- size += status.st_size;
- else
- printf("Offline trace file %s cannot be stat-ed", filename);
- }
-
- /*else */
- /*{ */
- /* dlt_log(3, "dlt_offline_trace_get_total_size: long filename ignored"); */
- /*} */
- }
-
- closedir(dir);
-
- /* return size */
- return size;
-}
-
-int dlt_offline_trace_delete_oldest_file(DltOfflineTrace *trace)
-{
- struct dirent *dp;
- char filename[PATH_MAX + 1];
- char filename_oldest[PATH_MAX + 1];
- unsigned long size_oldest = 0;
- struct stat status;
- time_t time_oldest = 0;
-
- filename[0] = 0;
- filename_oldest[0] = 0;
-
- /* go through all dlt files in directory */
- DIR *dir = opendir(trace->directory);
-
- if(!dir)
- return -1;
-
- while ((dp = readdir(dir)) != NULL)
- if (strstr(dp->d_name, DLT_OFFLINETRACE_FILENAME_BASE)) {
- int res = snprintf(filename, sizeof(filename), "%s/%s", trace->directory, dp->d_name);
-
- /* if the total length of the string is greater than the buffer, silently forget it. */
- /* snprintf: a return value of size or more means that the output was truncated */
- /* if an output error is encountered, a negative value is returned. */
- if (((unsigned int)res < sizeof(filename)) && (res > 0)) {
- if (0 == stat(filename, &status)) {
- if ((time_oldest == 0) || (status.st_mtime < time_oldest)) {
- time_oldest = status.st_mtime;
- size_oldest = status.st_size;
- strncpy(filename_oldest, filename, PATH_MAX);
- filename_oldest[PATH_MAX] = 0;
- }
- }
- else {
- printf("Old offline trace file %s cannot be stat-ed", filename);
- }
- }
- }
-
- closedir(dir);
-
- /* delete file */
- if (filename_oldest[0]) {
- if (remove(filename_oldest)) {
- printf("Remove file %s failed!\n", filename_oldest);
- return -1; /* ERROR */
- }
- }
- else {
- printf("No file to be removed!\n");
- return -1; /* ERROR */
- }
-
- /* return size of deleted file*/
- return size_oldest;
-}
-
-DltReturnValue dlt_offline_trace_check_size(DltOfflineTrace *trace)
-{
-
- struct stat status;
-
- /* check for existence of offline trace directory */
- if (stat(trace->directory, &status) == -1) {
- dlt_vlog(LOG_ERR, "Offline trace directory: %s doesn't exist \n", trace->directory);
- return DLT_RETURN_ERROR;
- }
-
- /* check for accesibilty of offline trace directory */
- else if (access(trace->directory, W_OK) != 0)
- {
- dlt_vlog(LOG_ERR, "Offline trace directory: %s doesn't have the write access \n", trace->directory);
- return DLT_RETURN_ERROR;
- }
-
- ssize_t s = 0;
-
- /* check size of complete offline trace */
- while ((s = dlt_offline_trace_get_total_size(trace)) > (trace->maxSize - trace->fileSize))
- /* remove oldest files as long as new file will not fit in completely into complete offline trace */
- if (dlt_offline_trace_delete_oldest_file(trace) < 0)
- return DLT_RETURN_ERROR;
-
- if (s == -1)
- return DLT_RETURN_ERROR;
-
- return DLT_RETURN_OK; /* OK */
-}
-
-DltReturnValue dlt_offline_trace_init(DltOfflineTrace *trace,
- const char *directory,
- int fileSize,
- int maxSize,
- int filenameTimestampBased)
-{
-
- /* init parameters */
- strncpy(trace->directory, directory, NAME_MAX);
- trace->directory[NAME_MAX] = 0;
- trace->fileSize = fileSize;
- trace->maxSize = maxSize;
- trace->filenameTimestampBased = filenameTimestampBased;
- /* check complete offlien trace size, remove old logs if needed */
- dlt_offline_trace_check_size(trace);
-
- return dlt_offline_trace_create_new_file(trace);
-}
-
-DltReturnValue dlt_offline_trace_write(DltOfflineTrace *trace,
- unsigned char *data1,
- int size1,
- unsigned char *data2,
- int size2,
- unsigned char *data3,
- int size3)
+#include <dlt_multiple_files.h>
+
+DltReturnValue dlt_offline_trace_write(MultipleFilesRingBuffer *trace,
+ const unsigned char *data1,
+ const int size1,
+ const unsigned char *data2,
+ const int size2,
+ const unsigned char *data3,
+ const int size3)
{
- if (trace->ohandle < 0)
- return DLT_RETURN_ERROR;
-
- /* check file size here */
- if ((lseek(trace->ohandle, 0, SEEK_CUR) + size1 + size2 + size3) >= trace->fileSize) {
- /* close old file */
- close(trace->ohandle);
- trace->ohandle = -1;
-
- /* check complete offline trace size, remove old logs if needed */
- dlt_offline_trace_check_size(trace);
+ if (trace->ohandle < 0) return DLT_RETURN_ERROR;
- /* create new file */
- dlt_offline_trace_create_new_file(trace);
- }
+ multiple_files_buffer_rotate_file(trace, size1 + size2 + size3);
/* write data into log file */
- if (data1 && (trace->ohandle >= 0)) {
- if (write(trace->ohandle, data1, size1) != size1) {
- printf("Offline trace write failed!\n");
- return DLT_RETURN_ERROR;
- }
- }
-
- if (data2 && (trace->ohandle >= 0)) {
- if (write(trace->ohandle, data2, size2) != size2) {
- printf("Offline trace write failed!\n");
- return DLT_RETURN_ERROR;
- }
- }
-
- if (data3 && (trace->ohandle >= 0)) {
- if (write(trace->ohandle, data3, size3) != size3) {
- printf("Offline trace write failed!\n");
- return DLT_RETURN_ERROR;
- }
- }
-
- return DLT_RETURN_OK; /* OK */
-}
-
-DltReturnValue dlt_offline_trace_free(DltOfflineTrace *trace)
-{
-
- if (trace->ohandle < 0)
- return DLT_RETURN_ERROR;
-
- /* close last used log file */
- close(trace->ohandle);
+ if (multiple_files_buffer_write_chunk(trace, data1, size1) != DLT_RETURN_OK) return DLT_RETURN_ERROR;
+ if (multiple_files_buffer_write_chunk(trace, data2, size2) != DLT_RETURN_OK) return DLT_RETURN_ERROR;
+ if (multiple_files_buffer_write_chunk(trace, data3, size3) != DLT_RETURN_OK) return DLT_RETURN_ERROR;
- return DLT_RETURN_OK; /* OK */
+ return DLT_RETURN_OK;
}