aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/util-debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/util-debug.c')
-rw-r--r--framework/src/suricata/src/util-debug.c1653
1 files changed, 0 insertions, 1653 deletions
diff --git a/framework/src/suricata/src/util-debug.c b/framework/src/suricata/src/util-debug.c
deleted file mode 100644
index d9af08c4..00000000
--- a/framework/src/suricata/src/util-debug.c
+++ /dev/null
@@ -1,1653 +0,0 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \file
- *
- * \author Anoop Saldanha <anoopsaldanha@gmail.com>
- *
- * Debug utility functions
- */
-
-#include "suricata-common.h"
-#include "threads.h"
-#include "util-debug.h"
-#include "util-error.h"
-#include "util-enum.h"
-#include "util-debug-filters.h"
-
-#include "decode.h"
-#include "detect.h"
-#include "packet-queue.h"
-#include "threadvars.h"
-
-#include "tm-queuehandlers.h"
-#include "tm-queues.h"
-#include "tm-threads.h"
-
-#include "util-unittest.h"
-#include "util-syslog.h"
-
-#include "conf.h"
-
-/* holds the string-enum mapping for the enums held in the table SCLogLevel */
-SCEnumCharMap sc_log_level_map[ ] = {
- { "Not set", SC_LOG_NOTSET},
- { "None", SC_LOG_NONE },
- { "Emergency", SC_LOG_EMERGENCY },
- { "Alert", SC_LOG_ALERT },
- { "Critical", SC_LOG_CRITICAL },
- { "Error", SC_LOG_ERROR },
- { "Warning", SC_LOG_WARNING },
- { "Notice", SC_LOG_NOTICE },
- { "Info", SC_LOG_INFO },
- { "Debug", SC_LOG_DEBUG },
- { NULL, -1 }
-};
-
-/* holds the string-enum mapping for the enums held in the table SCLogOPIface */
-SCEnumCharMap sc_log_op_iface_map[ ] = {
- { "Console", SC_LOG_OP_IFACE_CONSOLE },
- { "File", SC_LOG_OP_IFACE_FILE },
- { "Syslog", SC_LOG_OP_IFACE_SYSLOG },
- { NULL, -1 }
-};
-
-#if defined (OS_WIN32)
-/**
- * \brief Used for synchronous output on WIN32
- */
-static SCMutex sc_log_stream_lock = NULL;
-#endif /* OS_WIN32 */
-
-/**
- * \brief Holds the config state for the logging module
- */
-static SCLogConfig *sc_log_config = NULL;
-
-/**
- * \brief Returns the full path given a file and configured log dir
- */
-static char *SCLogGetLogFilename(char *);
-
-/**
- * \brief Holds the global log level. Is the same as sc_log_config->log_level
- */
-SCLogLevel sc_log_global_log_level;
-
-/**
- * \brief Used to indicate whether the logging module has been init or not
- */
-int sc_log_module_initialized = 0;
-
-/**
- * \brief Used to indicate whether the logging module has been cleaned or not
- */
-int sc_log_module_cleaned = 0;
-
-/**
- * \brief Maps the SC logging level to the syslog logging level
- *
- * \param The SC logging level that has to be mapped to the syslog_log_level
- *
- * \retval syslog_log_level The mapped syslog_api_log_level, for the logging
- * module api's internal log_level
- */
-static inline int SCLogMapLogLevelToSyslogLevel(int log_level)
-{
- int syslog_log_level = 0;
-
- switch (log_level) {
- case SC_LOG_EMERGENCY:
- syslog_log_level = LOG_EMERG;
- break;
- case SC_LOG_ALERT:
- syslog_log_level = LOG_ALERT;
- break;
- case SC_LOG_CRITICAL:
- syslog_log_level = LOG_CRIT;
- break;
- case SC_LOG_ERROR:
- syslog_log_level = LOG_ERR;
- break;
- case SC_LOG_WARNING:
- syslog_log_level = LOG_WARNING;
- break;
- case SC_LOG_NOTICE:
- syslog_log_level = LOG_NOTICE;
- break;
- case SC_LOG_INFO:
- syslog_log_level = LOG_INFO;
- break;
- case SC_LOG_DEBUG:
- syslog_log_level = LOG_DEBUG;
- break;
- default:
- syslog_log_level = LOG_EMERG;
- break;
- }
-
- return syslog_log_level;
-}
-
-/**
- * \brief Output function that logs a character string out to a file descriptor
- *
- * \param fd Pointer to the file descriptor
- * \param msg Pointer to the character string that should be logged
- */
-static inline void SCLogPrintToStream(FILE *fd, char *msg)
-{
-#if defined (OS_WIN32)
- SCMutexLock(&sc_log_stream_lock);
-#endif /* OS_WIN32 */
-
- if (fprintf(fd, "%s\n", msg) < 0)
- printf("Error writing to stream using fprintf\n");
-
- fflush(fd);
-
-#if defined (OS_WIN32)
- SCMutexUnlock(&sc_log_stream_lock);
-#endif /* OS_WIN32 */
-
- return;
-}
-
-/**
- * \brief Output function that logs a character string throught the syslog iface
- *
- * \param syslog_log_level Holds the syslog_log_level that the message should be
- * logged as
- * \param msg Pointer to the char string, that should be logged
- *
- * \todo syslog is thread-safe according to POSIX manual and glibc code, but we
- * we will have to look into non POSIX compliant boxes like freeBSD
- */
-static inline void SCLogPrintToSyslog(int syslog_log_level, const char *msg)
-{
- //static struct syslog_data data = SYSLOG_DATA_INIT;
- //syslog_r(syslog_log_level, NULL, "%s", msg);
-
- syslog(syslog_log_level, "%s", msg);
-
- return;
-}
-
-#ifdef HAVE_LIBJANSSON
-/**
- */
-int SCLogMessageJSON(struct timeval *tval, char *buffer, size_t buffer_size,
- SCLogLevel log_level, const char *file,
- unsigned line, const char *function, SCError error_code,
- const char *message)
-{
- json_t *js = json_object();
- if (unlikely(js == NULL))
- goto error;
- json_t *ejs = json_object();
- if (unlikely(ejs == NULL))
- goto error;
-
- char timebuf[64];
- CreateIsoTimeString(tval, timebuf, sizeof(timebuf));
- json_object_set_new(js, "timestamp", json_string(timebuf));
-
- json_object_set_new(js, "event_type", json_string("engine"));
-
- if (error_code > 0) {
- json_object_set_new(ejs, "error_code", json_integer(error_code));
- json_object_set_new(ejs, "error", json_string(SCErrorToString(error_code)));
- }
-
- if (message)
- json_object_set_new(ejs, "message", json_string(message));
-
- if (log_level >= SC_LOG_DEBUG) {
- if (function)
- json_object_set_new(ejs, "function", json_string(function));
-
- if (file)
- json_object_set_new(ejs, "file", json_string(file));
-
- if (line > 0)
- json_object_set_new(ejs, "line", json_integer(line));
- }
-
- json_object_set_new(js, "engine", ejs);
-
- char *js_s = json_dumps(js,
- JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII|
-#ifdef JSON_ESCAPE_SLASH
- JSON_ESCAPE_SLASH
-#else
- 0
-#endif
- );
- snprintf(buffer, buffer_size, "%s", js_s);
- free(js_s);
-
- json_object_del(js, "engine");
- json_object_clear(js);
- json_decref(js);
-
- return 0;
-error:
- return -1;
-}
-#endif /* HAVE_LIBJANSSON */
-
-/**
- * \brief Adds the global log_format to the outgoing buffer
- *
- * \param log_level log_level of the message that has to be logged
- * \param msg Buffer containing the outgoing message
- * \param file File_name from where the message originated
- * \param function Function_name from where the message originated
- * \param line Line_no from where the messaged originated
- *
- * \retval SC_OK on success; else an error code
- */
-static SCError SCLogMessageGetBuffer(
- struct timeval *tval, int color, SCLogOPType type,
- char *buffer, size_t buffer_size,
- const char *log_format,
-
- const SCLogLevel log_level, const char *file,
- const unsigned int line, const char *function,
- const SCError error_code, const char *message)
-{
-#ifdef HAVE_LIBJANSSON
- if (type == SC_LOG_OP_TYPE_JSON)
- return SCLogMessageJSON(tval, buffer, buffer_size, log_level, file, line, function, error_code, message);
-#endif
-
- char *temp = buffer;
- const char *s = NULL;
- struct tm *tms = NULL;
-
- char *redb = "";
- char *red = "";
- char *yellowb = "";
- char *yellow = "";
- char *green = "";
- char *blue = "";
- char *reset = "";
- if (color) {
- redb = "\x1b[1;31m";
- red = "\x1b[31m";
- yellowb = "\x1b[1;33m";
- yellow = "\x1b[33m";
- green = "\x1b[32m";
- blue = "\x1b[34m";
- reset = "\x1b[0m";
- }
-
- /* no of characters_written(cw) by snprintf */
- int cw = 0;
-
- if (sc_log_module_initialized != 1) {
-#ifdef DEBUG
- printf("Logging module not initialized. Call SCLogInitLogModule(), "
- "before using the logging API\n");
-#endif
- return SC_ERR_LOG_MODULE_NOT_INIT;
- }
-
- char *temp_fmt = strdup(log_format);
- if (unlikely(temp_fmt == NULL)) {
- return SC_ERR_MEM_ALLOC;
- }
- char *temp_fmt_h = temp_fmt;
- char *substr = temp_fmt;
-
- while ( (temp_fmt = index(temp_fmt, SC_LOG_FMT_PREFIX)) ) {
- if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_OK;
- }
- switch(temp_fmt[1]) {
- case SC_LOG_FMT_TIME:
- temp_fmt[0] = '\0';
-
- struct tm local_tm;
- tms = SCLocalTime(tval->tv_sec, &local_tm);
-
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%d/%d/%04d -- %02d:%02d:%02d%s",
- substr, green, tms->tm_mday, tms->tm_mon + 1,
- tms->tm_year + 1900, tms->tm_hour, tms->tm_min,
- tms->tm_sec, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- case SC_LOG_FMT_PID:
- temp_fmt[0] = '\0';
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%u%s", substr, yellow, getpid(), reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- case SC_LOG_FMT_TID:
- temp_fmt[0] = '\0';
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%lu%s", substr, yellow, SCGetThreadIdLong(), reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
- case SC_LOG_FMT_TM:
- temp_fmt[0] = '\0';
-/* disabled to prevent dead lock:
- * log or alloc (which calls log on error) can call TmThreadsGetCallingThread
- * which will lock tv_root_lock. This can happen while we already hold this
- * lock. */
-#if 0
- ThreadVars *tv = TmThreadsGetCallingThread();
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - *msg),
- "%s%s", substr, ((tv != NULL)? tv->name: "UNKNOWN TM"));
-#endif
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s", substr, "N/A");
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
- case SC_LOG_FMT_LOG_LEVEL:
- temp_fmt[0] = '\0';
- s = SCMapEnumValueToName(log_level, sc_log_level_map);
- if (s != NULL) {
- if (log_level <= SC_LOG_ERROR)
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, redb, s, reset);
- else if (log_level == SC_LOG_WARNING)
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, red, s, reset);
- else if (log_level == SC_LOG_NOTICE)
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, yellowb, s, reset);
- else
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, yellow, s, reset);
- } else {
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s", substr, "INVALID");
- }
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- case SC_LOG_FMT_FILE_NAME:
- temp_fmt[0] = '\0';
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, blue, file, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- case SC_LOG_FMT_LINE:
- temp_fmt[0] = '\0';
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%u%s", substr, green, line, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- case SC_LOG_FMT_FUNCTION:
- temp_fmt[0] = '\0';
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "%s%s%s%s", substr, green, function, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- temp_fmt++;
- substr = temp_fmt;
- substr++;
- break;
-
- }
- temp_fmt++;
- }
- if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_OK;
- }
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s", substr);
- if (cw < 0)
- goto error;
- temp += cw;
- if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_OK;
- }
-
- if (error_code != SC_OK) {
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
- "[%sERRCODE%s: %s%s%s(%s%d%s)] - ", yellow, reset, red, SCErrorToString(error_code), reset, yellow, error_code, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_OK;
- }
- }
-
- char *xyellow = error_code > SC_OK ? yellow : "";
- cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s", xyellow, message, reset);
- if (cw < 0)
- goto error;
- temp += cw;
- if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_OK;
- }
-
- SCFree(temp_fmt_h);
-
- if (sc_log_config->op_filter_regex != NULL) {
-#define MAX_SUBSTRINGS 30
- int ov[MAX_SUBSTRINGS];
-
- if (pcre_exec(sc_log_config->op_filter_regex,
- sc_log_config->op_filter_regex_study,
- buffer, strlen(buffer), 0, 0, ov, MAX_SUBSTRINGS) < 0)
- {
- return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
- }
-#undef MAX_SUBSTRINGS
- }
-
- return SC_OK;
-
- error:
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_ERR_SPRINTF;
-}
-
-/**
- * \brief Adds the global log_format to the outgoing buffer
- *
- * \param log_level log_level of the message that has to be logged
- * \param msg Buffer containing the outgoing message
- * \param file File_name from where the message originated
- * \param function Function_name from where the message originated
- * \param line Line_no from where the messaged originated
- *
- * \retval SC_OK on success; else an error code
- */
-SCError SCLogMessage(const SCLogLevel log_level, const char *file,
- const unsigned int line, const char *function,
- const SCError error_code, const char *message)
-{
- char buffer[SC_LOG_MAX_LOG_MSG_LEN] = "";
- SCLogOPIfaceCtx *op_iface_ctx = NULL;
-
- if (sc_log_module_initialized != 1) {
- printf("Logging module not initialized. Call SCLogInitLogModule() "
- "first before using the debug API\n");
- return SC_OK;
- }
-
- /* get ts here so we log the same ts to each output */
- struct timeval tval;
- gettimeofday(&tval, NULL);
-
- op_iface_ctx = sc_log_config->op_ifaces;
- while (op_iface_ctx != NULL) {
- if (log_level != SC_LOG_NOTSET && log_level > op_iface_ctx->log_level) {
- op_iface_ctx = op_iface_ctx->next;
- continue;
- }
-
- switch (op_iface_ctx->iface) {
- case SC_LOG_OP_IFACE_CONSOLE:
- if (SCLogMessageGetBuffer(&tval, op_iface_ctx->use_color, op_iface_ctx->type,
- buffer, sizeof(buffer),
- op_iface_ctx->log_format ?
- op_iface_ctx->log_format : sc_log_config->log_format,
- log_level, file, line, function,
- error_code, message) == 0)
- {
- SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer);
- }
- break;
- case SC_LOG_OP_IFACE_FILE:
- if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
- op_iface_ctx->log_format ?
- op_iface_ctx->log_format : sc_log_config->log_format,
- log_level, file, line, function,
- error_code, message) == 0)
- {
- SCLogPrintToStream(op_iface_ctx->file_d, buffer);
- }
- break;
- case SC_LOG_OP_IFACE_SYSLOG:
- if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
- op_iface_ctx->log_format ?
- op_iface_ctx->log_format : sc_log_config->log_format,
- log_level, file, line, function,
- error_code, message) == 0)
- {
- SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer);
- }
- break;
- default:
- break;
- }
- op_iface_ctx = op_iface_ctx->next;
- }
- return SC_OK;
-}
-
-/**
- * \brief Returns whether debug messages are enabled to be logged or not
- *
- * \retval 1 if debug messages are enabled to be logged
- * \retval 0 if debug messages are not enabled to be logged
- */
-int SCLogDebugEnabled(void)
-{
-#ifdef DEBUG
- if (sc_log_global_log_level == SC_LOG_DEBUG)
- return 1;
- else
- return 0;
-#else
- return 0;
-#endif
-}
-
-/**
- * \brief Allocates an output buffer for an output interface. Used when we
- * want the op_interface log_format to override the global_log_format.
- * Currently not used.
- *
- * \retval buffer Pointer to the newly created output_buffer
- */
-SCLogOPBuffer *SCLogAllocLogOPBuffer(void)
-{
- SCLogOPBuffer *buffer = NULL;
- SCLogOPIfaceCtx *op_iface_ctx = NULL;
- int i = 0;
-
- if ( (buffer = SCMalloc(sc_log_config->op_ifaces_cnt *
- sizeof(SCLogOPBuffer))) == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting...");
- exit(EXIT_FAILURE);
- }
-
- op_iface_ctx = sc_log_config->op_ifaces;
- for (i = 0;
- i < sc_log_config->op_ifaces_cnt;
- i++, op_iface_ctx = op_iface_ctx->next) {
- buffer[i].log_format = op_iface_ctx->log_format;
- buffer[i].temp = buffer[i].msg;
- }
-
- return buffer;
-}
-
-/*----------------------The logging module initialization code--------------- */
-
-/**
- * \brief Returns a new output_interface_context
- *
- * \retval iface_ctx Pointer to a newly allocated output_interface_context
- * \initonly
- */
-static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx()
-{
- SCLogOPIfaceCtx *iface_ctx = NULL;
-
- if ( (iface_ctx = SCMalloc(sizeof(SCLogOPIfaceCtx))) == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting...");
- exit(EXIT_FAILURE);
- }
- memset(iface_ctx, 0, sizeof(SCLogOPIfaceCtx));
-
- return iface_ctx;
-}
-
-/**
- * \brief Initializes the file output interface
- *
- * \param file Path to the file used for logging purposes
- * \param log_format Pointer to the log_format for this op interface, that
- * overrides the global_log_format
- * \param log_level Override of the global_log_level by this interface
- *
- * \retval iface_ctx Pointer to the file output interface context created
- * \initonly
- */
-static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file,
- const char *log_format,
- int log_level,
- SCLogOPType type)
-{
- SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
-
- if (iface_ctx == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitFileOPIface. Exiting...");
- exit(EXIT_FAILURE);
- }
-
- if (file == NULL || log_format == NULL) {
- goto error;
- }
-
- iface_ctx->iface = SC_LOG_OP_IFACE_FILE;
- iface_ctx->type = type;
-
- if ( (iface_ctx->file_d = fopen(file, "w+")) == NULL) {
- printf("Error opening file %s\n", file);
- goto error;
- }
-
- if ((iface_ctx->file = SCStrdup(file)) == NULL) {
- goto error;
- }
-
- if ((iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
- goto error;
- }
-
- iface_ctx->log_level = log_level;
-
- return iface_ctx;
-
-error:
- if (iface_ctx->file != NULL) {
- SCFree((char *)iface_ctx->file);
- iface_ctx->file = NULL;
- }
- if (iface_ctx->log_format != NULL) {
- SCFree((char *)iface_ctx->log_format);
- iface_ctx->log_format = NULL;
- }
- if (iface_ctx->file_d != NULL) {
- fclose(iface_ctx->file_d);
- iface_ctx->file_d = NULL;
- }
- return NULL;
-}
-
-/**
- * \brief Initializes the console output interface and deals with possible
- * env var overrides.
- *
- * \param log_format Pointer to the log_format for this op interface, that
- * overrides the global_log_format
- * \param log_level Override of the global_log_level by this interface
- *
- * \retval iface_ctx Pointer to the console output interface context created
- * \initonly
- */
-static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format,
- SCLogLevel log_level, SCLogOPType type)
-{
- SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
-
- if (iface_ctx == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitConsoleOPIface. Exiting...");
- exit(EXIT_FAILURE);
- }
-
- iface_ctx->iface = SC_LOG_OP_IFACE_CONSOLE;
- iface_ctx->type = type;
-
- /* console log format is overridden by envvars */
- const char *tmp_log_format = log_format;
- const char *s = getenv(SC_LOG_ENV_LOG_FORMAT);
- if (s != NULL) {
-#if 0
- printf("Overriding setting for \"console.format\" because of env "
- "var SC_LOG_FORMAT=\"%s\".\n", s);
-#endif
- tmp_log_format = s;
- }
-
- if (tmp_log_format != NULL &&
- (iface_ctx->log_format = SCStrdup(tmp_log_format)) == NULL) {
- printf("Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
-
- /* console log level is overridden by envvars */
- SCLogLevel tmp_log_level = log_level;
- s = getenv(SC_LOG_ENV_LOG_LEVEL);
- if (s != NULL) {
- SCLogLevel l = SCMapEnumNameToValue(s, sc_log_level_map);
- if (l > SC_LOG_NOTSET && l < SC_LOG_LEVEL_MAX) {
-#if 0
- printf("Overriding setting for \"console.level\" because of env "
- "var SC_LOG_LEVEL=\"%s\".\n", s);
-#endif
- tmp_log_level = l;
- }
- }
- iface_ctx->log_level = tmp_log_level;
-
- if (isatty(fileno(stdout)) && isatty(fileno(stderr))) {
- iface_ctx->use_color = TRUE;
- }
-
- return iface_ctx;
-}
-
-/**
- * \brief Initializes the syslog output interface
- *
- * \param facility The facility code for syslog
- * \param log_format Pointer to the log_format for this op interface, that
- * overrides the global_log_format
- * \param log_level Override of the global_log_level by this interface
- *
- * \retval iface_ctx Pointer to the syslog output interface context created
- */
-static inline SCLogOPIfaceCtx *SCLogInitSyslogOPIface(int facility,
- const char *log_format,
- SCLogLevel log_level,
- SCLogOPType type)
-{
- SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
-
- if ( iface_ctx == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitSyslogOPIface. Exiting...");
- exit(EXIT_FAILURE);
- }
-
- iface_ctx->iface = SC_LOG_OP_IFACE_SYSLOG;
- iface_ctx->type = type;
-
- if (facility == -1)
- facility = SC_LOG_DEF_SYSLOG_FACILITY;
- iface_ctx->facility = facility;
-
- if (log_format != NULL &&
- (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
- printf("Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
-
- iface_ctx->log_level = log_level;
-
- openlog(NULL, LOG_NDELAY, iface_ctx->facility);
-
- return iface_ctx;
-}
-
-/**
- * \brief Frees the output_interface context supplied as an argument
- *
- * \param iface_ctx Pointer to the op_interface_context to be freed
- */
-static inline void SCLogFreeLogOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx)
-{
- SCLogOPIfaceCtx *temp = NULL;
-
- while (iface_ctx != NULL) {
- temp = iface_ctx;
-
- if (iface_ctx->file_d != NULL)
- fclose(iface_ctx->file_d);
-
- if (iface_ctx->file != NULL)
- SCFree((void *)iface_ctx->file);
-
- if (iface_ctx->log_format != NULL)
- SCFree((void *)iface_ctx->log_format);
-
- if (iface_ctx->iface == SC_LOG_OP_IFACE_SYSLOG) {
- closelog();
- }
-
- iface_ctx = iface_ctx->next;
-
- SCFree(temp);
- }
-
- return;
-}
-
-/**
- * \brief Internal function used to set the logging module global_log_level
- * during the initialization phase
- *
- * \param sc_lid The initialization data supplied.
- * \param sc_lc The logging module context which has to be updated.
- */
-static inline void SCLogSetLogLevel(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
-{
- SCLogLevel log_level = SC_LOG_NOTSET;
- const char *s = NULL;
-
- /* envvar overrides config */
- s = getenv(SC_LOG_ENV_LOG_LEVEL);
- if (s != NULL) {
- log_level = SCMapEnumNameToValue(s, sc_log_level_map);
- } else if (sc_lid != NULL) {
- log_level = sc_lid->global_log_level;
- }
-
- /* deal with the global_log_level to be used */
- if (log_level > SC_LOG_NOTSET && log_level < SC_LOG_LEVEL_MAX)
- sc_lc->log_level = log_level;
- else {
- sc_lc->log_level = SC_LOG_DEF_LOG_LEVEL;
-#ifndef UNITTESTS
- if (sc_lid != NULL) {
- printf("Warning: Invalid/No global_log_level assigned by user. Falling "
- "back on the default_log_level \"%s\"\n",
- SCMapEnumValueToName(sc_lc->log_level, sc_log_level_map));
- }
-#endif
- }
-
- /* we also set it to a global var, as it is easier to access it */
- sc_log_global_log_level = sc_lc->log_level;
-
- return;
-}
-
-/**
- * \brief Internal function used to set the logging module global_log_format
- * during the initialization phase
- *
- * \param sc_lid The initialization data supplied.
- * \param sc_lc The logging module context which has to be updated.
- */
-static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
-{
- char *format = NULL;
-
- /* envvar overrides config */
- format = getenv(SC_LOG_ENV_LOG_FORMAT);
- if (format == NULL) {
- if (sc_lid != NULL) {
- format = sc_lid->global_log_format;
- }
- }
-
- /* deal with the global log format to be used */
- if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) {
- format = SC_LOG_DEF_LOG_FORMAT;
-#ifndef UNITTESTS
- if (sc_lid != NULL) {
- printf("Warning: Invalid/No global_log_format supplied by user or format "
- "length exceeded limit of \"%d\" characters. Falling back on "
- "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN,
- format);
- }
-#endif
- }
-
- if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) {
- printf("Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
-
- return;
-}
-
-/**
- * \brief Internal function used to set the logging module global_op_ifaces
- * during the initialization phase
- *
- * \param sc_lid The initialization data supplied.
- * \param sc_lc The logging module context which has to be updated.
- */
-static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
-{
- SCLogOPIfaceCtx *op_ifaces_ctx = NULL;
- int op_iface = 0;
- const char *s = NULL;
-
- if (sc_lid != NULL && sc_lid->op_ifaces != NULL) {
- sc_lc->op_ifaces = sc_lid->op_ifaces;
- sc_lid->op_ifaces = NULL;
- sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt;
- } else {
- s = getenv(SC_LOG_ENV_LOG_OP_IFACE);
- if (s != NULL) {
- op_iface = SCMapEnumNameToValue(s, sc_log_op_iface_map);
-
- if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) {
- op_iface = SC_LOG_DEF_LOG_OP_IFACE;
-#ifndef UNITTESTS
- printf("Warning: Invalid output interface supplied by user. "
- "Falling back on default_output_interface \"%s\"\n",
- SCMapEnumValueToName(op_iface, sc_log_op_iface_map));
-#endif
- }
- }
- else {
- op_iface = SC_LOG_DEF_LOG_OP_IFACE;
-#ifndef UNITTESTS
- if (sc_lid != NULL) {
- printf("Warning: Output_interface not supplied by user. Falling "
- "back on default_output_interface \"%s\"\n",
- SCMapEnumValueToName(op_iface, sc_log_op_iface_map));
- }
-#endif
- }
-
- switch (op_iface) {
- case SC_LOG_OP_IFACE_CONSOLE:
- op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0);
- break;
- case SC_LOG_OP_IFACE_FILE:
- s = getenv(SC_LOG_ENV_LOG_FILE);
- if (s == NULL) {
- char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
- if (str != NULL) {
- op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0);
- SCFree(str);
- }
- } else {
- op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0);
- }
- break;
- case SC_LOG_OP_IFACE_SYSLOG:
- s = getenv(SC_LOG_ENV_LOG_FACILITY);
- if (s == NULL)
- s = SC_LOG_DEF_SYSLOG_FACILITY_STR;
-
- op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0);
- break;
- }
- sc_lc->op_ifaces = op_ifaces_ctx;
- sc_lc->op_ifaces_cnt++;
- }
- return;
-}
-
-/**
- * \brief Internal function used to set the logging module op_filter
- * during the initialization phase
- *
- * \param sc_lid The initialization data supplied.
- * \param sc_lc The logging module context which has to be updated.
- */
-static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
-{
- const char *filter = NULL;
-
- int opts = 0;
- const char *ep;
- int eo = 0;
-
- /* envvar overrides */
- filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
- if (filter == NULL) {
- if (sc_lid != NULL) {
- filter = sc_lid->op_filter;
- }
- }
-
- if (filter != NULL && strcmp(filter, "") != 0) {
- sc_lc->op_filter = SCStrdup(filter);
- if (sc_lc->op_filter == NULL) {
- printf("pcre filter alloc failed\n");
- return;
- }
- sc_lc->op_filter_regex = pcre_compile(filter, opts, &ep, &eo, NULL);
- if (sc_lc->op_filter_regex == NULL) {
- SCFree(sc_lc->op_filter);
- printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter,
- eo, ep);
- return;
- }
-
- sc_lc->op_filter_regex_study = pcre_study(sc_lc->op_filter_regex, 0,
- &ep);
- if (ep != NULL) {
- printf("pcre study failed: %s\n", ep);
- return;
- }
- }
-
- return;
-}
-
-/**
- * \brief Returns a pointer to a new SCLogInitData. This is a public interface
- * intended to be used after the logging paramters are read from the
- * conf file
- *
- * \retval sc_lid Pointer to the newly created SCLogInitData
- * \initonly
- */
-SCLogInitData *SCLogAllocLogInitData(void)
-{
- SCLogInitData *sc_lid = NULL;
-
- /* not using SCMalloc here because if it fails we can't log */
- if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL)
- return NULL;
-
- memset(sc_lid, 0, sizeof(SCLogInitData));
-
- return sc_lid;
-}
-
-/**
- * \brief Frees a SCLogInitData
- *
- * \param sc_lid Pointer to the SCLogInitData to be freed
- */
-void SCLogFreeLogInitData(SCLogInitData *sc_lid)
-{
- if (sc_lid != NULL) {
- if (sc_lid->startup_message != NULL)
- SCFree(sc_lid->startup_message);
- if (sc_lid->global_log_format != NULL)
- SCFree(sc_lid->global_log_format);
- if (sc_lid->op_filter != NULL)
- SCFree(sc_lid->op_filter);
-
- SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces);
- }
-
- return;
-}
-
-/**
- * \brief Frees the logging module context
- */
-static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
-{
- if (sc_lc != NULL) {
- if (sc_lc->startup_message != NULL)
- SCFree(sc_lc->startup_message);
- if (sc_lc->log_format != NULL)
- SCFree(sc_lc->log_format);
- if (sc_lc->op_filter != NULL)
- SCFree(sc_lc->op_filter);
-
- SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
- SCFree(sc_lc);
- }
-
- return;
-}
-
-/**
- * \brief Appends an output_interface to the output_interface list sent in head
- *
- * \param iface_ctx Pointer to the output_interface that has to be added to head
- * \param head Pointer to the output_interface list
- */
-void SCLogAppendOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx, SCLogInitData *sc_lid)
-{
- SCLogOPIfaceCtx *temp = NULL, *prev = NULL;
- SCLogOPIfaceCtx **head = &sc_lid->op_ifaces;
-
- if (iface_ctx == NULL) {
-#ifdef DEBUG
- printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n");
-#endif
- return;
- }
-
- temp = *head;
- while (temp != NULL) {
- prev = temp;
- temp = temp->next;
- }
-
- if (prev == NULL)
- *head = iface_ctx;
- else
- prev->next = iface_ctx;
-
- sc_lid->op_ifaces_cnt++;
-
- return;
-}
-
-
-/**
- * \brief Creates a new output interface based on the arguments sent. The kind
- * of output interface to be created is decided by the iface_name arg.
- * If iface_name is "file", the arg argument will hold the filename to be
- * used for logging purposes. If iface_name is "syslog", the arg
- * argument holds the facility code. If iface_name is "console", arg is
- * NULL.
- *
- * \param iface_name Interface name. Can be "console", "file" or "syslog"
- * \param log_format Override for the global_log_format
- * \param log_level Override for the global_log_level
- * \param log_level Parameter required by a particular interface. Explained in
- * the function description
- *
- * \retval iface_ctx Pointer to the newly created output interface
- */
-SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
- const char *log_format,
- int log_level, const char *arg)
-{
- int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map);
-
- if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) {
-#ifndef UNITTESTS
- printf("Warning: Supplied log_level_override for op_interface \"%s\" "
- "is invalid. Defaulting to not specifying an override\n",
- iface_name);
-#endif
- log_level = SC_LOG_NOTSET;
- }
-
- switch (iface) {
- case SC_LOG_OP_IFACE_CONSOLE:
- return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
- case SC_LOG_OP_IFACE_FILE:
- return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
- case SC_LOG_OP_IFACE_SYSLOG:
- return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
- log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
- default:
-#ifdef DEBUG
- printf("Output Interface \"%s\" not supported by the logging module",
- iface_name);
-#endif
- return NULL;
- }
-}
-
-/**
- * \brief Initializes the logging module.
- *
- * \param sc_lid The initialization data for the logging module. If sc_lid is
- * NULL, we would stick to the default configuration for the
- * logging subsystem.
- * \initonly
- */
-void SCLogInitLogModule(SCLogInitData *sc_lid)
-{
- /* De-initialize the logging context, if it has already init by the
- * environment variables at the start of the engine */
- SCLogDeInitLogModule();
-
-#if defined (OS_WIN32)
- if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) {
- SCLogError(SC_ERR_MUTEX, "Failed to initialize log mutex.");
- exit(EXIT_FAILURE);
- }
-#endif /* OS_WIN32 */
-
- /* sc_log_config is a global variable */
- if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) {
- SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitLogModule. Exiting...");
- exit(EXIT_FAILURE);
- }
- memset(sc_log_config, 0, sizeof(SCLogConfig));
-
- SCLogSetLogLevel(sc_lid, sc_log_config);
- SCLogSetLogFormat(sc_lid, sc_log_config);
- SCLogSetOPIface(sc_lid, sc_log_config);
- SCLogSetOPFilter(sc_lid, sc_log_config);
-
- sc_log_module_initialized = 1;
- sc_log_module_cleaned = 0;
-
- //SCOutputPrint(sc_did->startup_message);
-
- return;
-}
-
-void SCLogLoadConfig(int daemon, int verbose)
-{
- ConfNode *outputs;
- SCLogInitData *sc_lid;
- int have_logging = 0;
-
- outputs = ConfGetNode("logging.outputs");
- if (outputs == NULL) {
- SCLogDebug("No logging.output configuration section found.");
- return;
- }
-
- sc_lid = SCLogAllocLogInitData();
- if (sc_lid == NULL) {
- SCLogDebug("Could not allocate memory for log init data");
- return;
- }
-
- /* Get default log level and format. */
- char *default_log_level_s = NULL;
- if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) {
- sc_lid->global_log_level =
- SCMapEnumNameToValue(default_log_level_s, sc_log_level_map);
- if (sc_lid->global_log_level == -1) {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s",
- default_log_level_s);
- exit(EXIT_FAILURE);
- }
- }
- else {
- SCLogWarning(SC_ERR_MISSING_CONFIG_PARAM,
- "No default log level set, will use notice.");
- sc_lid->global_log_level = SC_LOG_NOTICE;
- }
-
- if (verbose) {
- sc_lid->global_log_level += verbose;
- if (sc_lid->global_log_level > SC_LOG_LEVEL_MAX)
- sc_lid->global_log_level = SC_LOG_LEVEL_MAX;
- }
-
- if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1)
- sc_lid->global_log_format = SC_LOG_DEF_LOG_FORMAT;
-
- ConfGet("logging.default-output-filter", &sc_lid->op_filter);
-
- ConfNode *seq_node, *output;
- TAILQ_FOREACH(seq_node, &outputs->head, next) {
- SCLogLevel level = sc_lid->global_log_level;
- SCLogOPIfaceCtx *op_iface_ctx = NULL;
- const char *format;
- const char *level_s;
-
- output = ConfNodeLookupChild(seq_node, seq_node->val);
- if (output == NULL)
- continue;
-
- /* By default an output is enabled. */
- const char *enabled = ConfNodeLookupChildValue(output, "enabled");
- if (enabled != NULL && ConfValIsFalse(enabled))
- continue;
-
- SCLogOPType type = SC_LOG_OP_TYPE_REGULAR;
- const char *type_s = ConfNodeLookupChildValue(output, "type");
- if (type_s != NULL) {
- if (strcmp(type_s, "regular") == 0)
- type = SC_LOG_OP_TYPE_REGULAR;
- else if (strcmp(type_s, "json") == 0) {
-#ifdef HAVE_LIBJANSSON
- type = SC_LOG_OP_TYPE_JSON;
-#else
- SCLogError(SC_ERR_INVALID_ARGUMENT, "libjansson support not "
- "compiled in, can't use 'json' logging");
- exit(EXIT_FAILURE);
-#endif /* HAVE_LIBJANSSON */
- }
- }
-
- /* if available use the log format setting for this output,
- * otherwise fall back to the global setting. */
- format = ConfNodeLookupChildValue(output, "format");
- if (format == NULL)
- format = sc_lid->global_log_format;
-
- level_s = ConfNodeLookupChildValue(output, "level");
- if (level_s != NULL) {
- level = SCMapEnumNameToValue(level_s, sc_log_level_map);
- if (level == -1) {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s",
- level_s);
- exit(EXIT_FAILURE);
- }
- }
-
- if (strcmp(output->name, "console") == 0) {
- op_iface_ctx = SCLogInitConsoleOPIface(format, level, type);
- }
- else if (strcmp(output->name, "file") == 0) {
- const char *filename = ConfNodeLookupChildValue(output, "filename");
- if (filename == NULL) {
- SCLogError(SC_ERR_MISSING_CONFIG_PARAM,
- "Logging to file requires a filename");
- exit(EXIT_FAILURE);
- }
- have_logging = 1;
- op_iface_ctx = SCLogInitFileOPIface(filename, format, level, type);
- }
- else if (strcmp(output->name, "syslog") == 0) {
- int facility = SC_LOG_DEF_SYSLOG_FACILITY;
- const char *facility_s = ConfNodeLookupChildValue(output,
- "facility");
- if (facility_s != NULL) {
- facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
- if (facility == -1) {
- SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog "
- "facility: \"%s\", now using \"%s\" as syslog "
- "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR);
- facility = SC_LOG_DEF_SYSLOG_FACILITY;
- }
- }
- printf("Initialization syslog logging with format \"%s\".\n",
- format);
- have_logging = 1;
- op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type);
- }
- else {
- SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, "
- "ignoring", output->name);
- }
- if (op_iface_ctx != NULL) {
- SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid);
- }
- }
-
- if (daemon && (have_logging == 0)) {
- SCLogError(SC_ERR_MISSING_CONFIG_PARAM,
- "NO logging compatible with daemon mode selected,"
- " suricata won't be able to log. Please update "
- " 'logging.outputs' in the YAML.");
- }
-
- SCLogInitLogModule(sc_lid);
-
- SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level);
- SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format);
- SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter);
-
- if (sc_lid != NULL)
- SCFree(sc_lid);
-}
-
-/**
- * \brief Returns a full file path given a filename uses log dir specified in
- * conf or DEFAULT_LOG_DIR
- *
- * \param filearg The relative filename for which we want a full path include
- * log directory
- *
- * \retval log_filename The fullpath of the logfile to open
- */
-static char *SCLogGetLogFilename(char *filearg)
-{
- char *log_dir;
- char *log_filename;
-
- log_dir = ConfigGetLogDirectory();
-
- log_filename = SCMalloc(PATH_MAX);
- if (unlikely(log_filename == NULL))
- return NULL;
- snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg);
-
- return log_filename;
-}
-
-/**
- * \brief De-Initializes the logging module
- */
-void SCLogDeInitLogModule(void)
-{
- SCLogFreeLogConfig(sc_log_config);
-
- /* reset the global logging_module variables */
- sc_log_global_log_level = 0;
- sc_log_module_initialized = 0;
- sc_log_module_cleaned = 1;
- sc_log_config = NULL;
-
- /* de-init the FD filters */
- SCLogReleaseFDFilters();
- /* de-init the FG filters */
- SCLogReleaseFGFilters();
-
-#if defined (OS_WIN32)
- if (sc_log_stream_lock != NULL) {
- SCMutexDestroy(&sc_log_stream_lock);
- sc_log_stream_lock = NULL;
- }
-#endif /* OS_WIN32 */
-
- return;
-}
-
-//------------------------------------Unit_Tests--------------------------------
-
-/* The logging engine should be tested to the maximum extent possible, since
- * logging code would be used throughout the codebase, and hence we can't afford
- * to have a single bug here(not that you can afford to have a bug
- * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug
- * from the logging module.
- */
-
-#ifdef UNITTESTS
-
-int SCLogTestInit01()
-{
- int result = 1;
-
- /* unset any environment variables set for the logging module */
- unsetenv(SC_LOG_ENV_LOG_LEVEL);
- unsetenv(SC_LOG_ENV_LOG_OP_IFACE);
- unsetenv(SC_LOG_ENV_LOG_FORMAT);
-
- SCLogInitLogModule(NULL);
-
- if (sc_log_config == NULL)
- return 0;
-
- result &= (SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level);
- result &= (sc_log_config->op_ifaces != NULL &&
- SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface);
- result &= (sc_log_config->log_format != NULL &&
- strcmp(SC_LOG_DEF_LOG_FORMAT, sc_log_config->log_format) == 0);
-
- SCLogDeInitLogModule();
-
- setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1);
- setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1);
- setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1);
-
- SCLogInitLogModule(NULL);
-
- result &= (SC_LOG_DEBUG == sc_log_config->log_level);
- result &= (sc_log_config->op_ifaces != NULL &&
- SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
- result &= (sc_log_config->log_format != NULL &&
- !strcmp("%n- %l", sc_log_config->log_format));
-
- unsetenv(SC_LOG_ENV_LOG_LEVEL);
- unsetenv(SC_LOG_ENV_LOG_OP_IFACE);
- unsetenv(SC_LOG_ENV_LOG_FORMAT);
-
- SCLogDeInitLogModule();
-
- return result;
-}
-
-int SCLogTestInit02()
-{
- SCLogInitData *sc_lid = NULL;
- SCLogOPIfaceCtx *sc_iface_ctx = NULL;
- int result = 1;
- char *logfile = SCLogGetLogFilename("boo.txt");
- sc_lid = SCLogAllocLogInitData();
- if (sc_lid == NULL)
- return 0;
- sc_lid->startup_message = "Test02";
- sc_lid->global_log_level = SC_LOG_DEBUG;
- sc_lid->op_filter = "boo";
- sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT,
- logfile);
- SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
- sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR,
- NULL);
- SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
-
- SCLogInitLogModule(sc_lid);
-
- if (sc_log_config == NULL)
- return 0;
-
- result &= (SC_LOG_DEBUG == sc_log_config->log_level);
- result &= (sc_log_config->op_ifaces != NULL &&
- SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->next != NULL &&
- SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface);
- result &= (sc_log_config->log_format != NULL &&
- strcmp(SC_LOG_DEF_LOG_FORMAT, sc_log_config->log_format) == 0);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->log_format != NULL &&
- strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->next != NULL &&
- sc_log_config->op_ifaces->next->log_format == NULL);
-
- SCLogDeInitLogModule();
-
- sc_lid = SCLogAllocLogInitData();
- if (sc_lid == NULL)
- return 0;
- sc_lid->startup_message = "Test02";
- sc_lid->global_log_level = SC_LOG_DEBUG;
- sc_lid->op_filter = "boo";
- sc_lid->global_log_format = "kaboo";
-
- SCLogInitLogModule(sc_lid);
-
- if (sc_log_config == NULL)
- return 0;
-
- result &= (SC_LOG_DEBUG == sc_log_config->log_level);
- result &= (sc_log_config->op_ifaces != NULL &&
- SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->next == NULL);
- result &= (sc_log_config->log_format != NULL &&
- strcmp("kaboo", sc_log_config->log_format) == 0);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->log_format == NULL);
- result &= (sc_log_config->op_ifaces != NULL &&
- sc_log_config->op_ifaces->next == NULL);
-
- SCLogDeInitLogModule();
-
- return result;
-}
-
-int SCLogTestInit03()
-{
- int result = 1;
-
- SCLogInitLogModule(NULL);
-
- SCLogAddFGFilterBL(NULL, "bamboo", -1);
- SCLogAddFGFilterBL(NULL, "soo", -1);
- SCLogAddFGFilterBL(NULL, "dummy", -1);
-
- result &= (SCLogPrintFGFilters() == 3);
-
- SCLogAddFGFilterBL(NULL, "dummy1", -1);
- SCLogAddFGFilterBL(NULL, "dummy2", -1);
-
- result &= (SCLogPrintFGFilters() == 5);
-
- SCLogDeInitLogModule();
-
- return result;
-}
-
-int SCLogTestInit04()
-{
- int result = 1;
-
- SCLogInitLogModule(NULL);
-
- SCLogAddFDFilter("bamboo");
- SCLogAddFDFilter("soo");
- SCLogAddFDFilter("foo");
- SCLogAddFDFilter("roo");
-
- result &= (SCLogPrintFDFilters() == 4);
-
- SCLogAddFDFilter("loo");
- SCLogAddFDFilter("soo");
-
- result &= (SCLogPrintFDFilters() == 5);
-
- SCLogRemoveFDFilter("bamboo");
- SCLogRemoveFDFilter("soo");
- SCLogRemoveFDFilter("foo");
- SCLogRemoveFDFilter("noo");
-
- result &= (SCLogPrintFDFilters() == 2);
-
- SCLogDeInitLogModule();
-
- return result;
-}
-
-int SCLogTestInit05()
-{
- int result = 1;
-
- SCLogInfo("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
-
- return result;
-}
-
-
-#endif /* UNITTESTS */
-
-void SCLogRegisterTests()
-{
-
-#ifdef UNITTESTS
-
- UtRegisterTest("SCLogTestInit01", SCLogTestInit01, 1);
- UtRegisterTest("SCLogTestInit02", SCLogTestInit02, 1);
- UtRegisterTest("SCLogTestInit03", SCLogTestInit03, 1);
- UtRegisterTest("SCLogTestInit04", SCLogTestInit04, 1);
- UtRegisterTest("SCLogTestInit05", SCLogTestInit05, 1);
-
-#endif /* UNITTESTS */
-
- return;
-}