summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2009-09-28 22:47:42 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2009-09-28 22:47:42 +0200
commitf4980c7d59fa1e01ca4a5b5f65c9514ca18d3a88 (patch)
treeabbf368c53ce9e69c5188c731912325ceb86a13f /common
parent9a024f7f1addcb6bfccc49e74250009d7dfa31ae (diff)
parent5aed7f6775777b2a6166d6eddffaa976eb4fac8b (diff)
downloadeurephia-f4980c7d59fa1e01ca4a5b5f65c9514ca18d3a88.tar.gz
eurephia-f4980c7d59fa1e01ca4a5b5f65c9514ca18d3a88.tar.xz
eurephia-f4980c7d59fa1e01ca4a5b5f65c9514ca18d3a88.zip
Merge branch 'syslog'
Diffstat (limited to 'common')
-rw-r--r--common/eurephia_context.h7
-rw-r--r--common/eurephia_log.c302
-rw-r--r--common/eurephia_log.h27
-rw-r--r--common/eurephia_log_struct.h93
-rw-r--r--common/eurephia_nullsafe.c16
5 files changed, 391 insertions, 54 deletions
diff --git a/common/eurephia_context.h b/common/eurephia_context.h
index 877632c..e825c28 100644
--- a/common/eurephia_context.h
+++ b/common/eurephia_context.h
@@ -32,8 +32,8 @@
#define EUREPHIASTRUCT_H_
#include <stdio.h>
-#include "eurephiadb_struct.h"
-
+#include <eurephiadb_struct.h>
+#include <eurephia_log_struct.h>
/**
* eurephia context types
*/
@@ -58,8 +58,7 @@ typedef struct {
void *fwcfg; /**< Dummy pointer, if the firewall API is not enabled */
#endif
char *server_salt; /**< The in-memory password salt, used for the password cache */
- FILE *log; /**< FILE pointer to the log file */
- int loglevel; /**< Defines the log verbosity, higher number increases log verbosity */
+ eurephiaLOG *log; /**< Log context, used by eurephia_log() */
int fatal_error; /**< If this flag is set, the execution should stop immediately */
int context_type; /**< Defines the context type */
} eurephiaCTX;
diff --git a/common/eurephia_log.c b/common/eurephia_log.c
index 0955aa0..dde99d8 100644
--- a/common/eurephia_log.c
+++ b/common/eurephia_log.c
@@ -31,73 +31,303 @@
#include <stdio.h>
#include <stdarg.h>
+#include <syslog.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
+#include <assert.h>
#include <eurephia_context.h>
-#include "eurephia_log.h"
+#include <eurephia_log.h>
+#include <eurephia_nullsafe.h>
/**
- * Mapping table for mapping log types (defined in eurephia_log.h)
- * to string values
+ * Maps eurephia log types (priorities) to string values
+ *
+ * @param prio eurephia logtype, such as LOG_INFO, LOG_DEBUG, LOG_FATAL, etc
+ *
+ * @return String containing the log type/prio
*/
-const char *erp_logtypes[] = {
- "\0",
- "-- INFO -- \0", /**< LOG_INFO */
- "-- DEBUG -- \0", /**< LOG_DEBUG */
- "** WARNING ** \0", /**< LOG_WARNING */
- "** ERROR ** \0", /**< LOG_ERROR */
- "** CRITICAL ** \0", /**< LOG_CRITICAL */
- "** - FATAL - ** \0", /**< LOG_FATAL */
- "** * PANIC * ** \0" /**< LOG_PANIC */
+static inline const char *logprio_str(int prio) {
+ switch( prio ) {
+ case LOG_INFO:
+ return "-- INFO -- \0";
+ case LOG_DEBUG:
+ return "-- DEBUG -- \0";
+ case LOG_WARNING:
+ return "** WARNING ** \0";
+ case LOG_ERROR:
+ return "** ERROR ** \0";
+ case LOG_CRITICAL:
+ return "** CRITICAL ** \0";
+ case LOG_FATAL:
+ return "** - FATAL - ** \0";
+ case LOG_PANIC:
+ return "** * PANIC * ** \0";
+ default:
+ return "[[ UNKNOWN ]]\0";
+ }
+}
+
+
+/**
+ * Mapping table for eurephia log types to syslog log types
+ */
+static const int syslog_priority[] = {
+ -1,
+ LOG_INFO, /**< LOG_INFO */
+ LOG_DEBUG, /**< LOG_DEBUG */
+ LOG_WARNING, /**< LOG_WARNING */
+ LOG_ERR, /**< LOG_ERROR */
+ LOG_CRIT, /**< LOG_CRITICAL */
+ LOG_ALERT, /**< LOG_FATAL */
+ LOG_EMERG /**< LOG_PANIC */
};
+
+/**
+ * Converts eurephiaLOGTYPE value to a string
+ *
+ * @param lt eurephiaLOGTYPE, must be either logFILE or logSYSLOG
+ *
+ * @return Returns a static string with log type
+ */
+static inline const char *logtype_str(eurephiaLOGTYPE lt) {
+ switch( lt ) {
+ case logFILE:
+ return "file\0";
+ case logSYSLOG:
+ return "syslog\0";
+ }
+ return NULL;
+}
+
+
+/**
+ * Converts a string of log destination/facilities to syslog values
+ *
+ * @param dest String containing the log destination
+ *
+ * @return Returns a syslog compatible value, such as LOG_AUTHPRIV, LOG_LOCAL{0-7}, LOG_USER, etc.
+ * Unknown types will be set to syslog default, LOG_USER.
+ *
+ * @remark The following list will list up facilities which will be ignored and LOG_USER will be used
+ * instead: LOG_CRON, LOG_FTP, LOG_KERN, LOG_LPR, LOG_MAIL, LOG_NEWS, LOG_SYSLOG, LOG_UUCP.
+ *
+ */
+static const int syslog_logdest(const char *dest) {
+ if( dest == NULL ) {
+ return LOG_USER;
+ }
+
+ if( strcasecmp(dest, "auth") == 0 ) {
+ return LOG_AUTHPRIV; // LOG_AUTH is deprecated, and LOG_AUTHPRIV should be used instead
+ } else if( strcasecmp(dest, "authpriv") == 0 ) {
+ return LOG_AUTHPRIV;
+ } else if( strcasecmp(dest, "daemon") == 0 ) {
+ return LOG_DAEMON;
+ } else if( strcasecmp(dest, "local0") == 0 ) {
+ return LOG_LOCAL0;
+ } else if( strcasecmp(dest, "local1") == 0 ) {
+ return LOG_LOCAL1;
+ } else if( strcasecmp(dest, "local2") == 0 ) {
+ return LOG_LOCAL2;
+ } else if( strcasecmp(dest, "local3") == 0 ) {
+ return LOG_LOCAL3;
+ } else if( strcasecmp(dest, "local4") == 0 ) {
+ return LOG_LOCAL4;
+ } else if( strcasecmp(dest, "local5") == 0 ) {
+ return LOG_LOCAL5;
+ } else if( strcasecmp(dest, "local6") == 0 ) {
+ return LOG_LOCAL6;
+ } else if( strcasecmp(dest, "local7") == 0 ) {
+ return LOG_LOCAL7;
+ } else {
+ return LOG_USER;
+ }
+}
+
+
/**
* POSIX Mutex to avoid simultaneously logging activity from
* several threads at the same time
*/
pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Simple function for logging entries to a file with timestamp
+ *
+ * @param log FILE pointer to a log file
+ * @param logdst Log destiation/priority
+ * @param loglvl Log level of the message
+ * @param file String containing file name of the place this function was called. Usually the __FILE__ macro.
+ * @param line Line number of the source file this function was called. Usually the __LINE__ macro.
+ * @param fmt stdarg, format string
+ * @param ap stdarg va_list, prepared by va_start()
+ */
+static void file_log(FILE *log, int logdst, int loglvl, const char *file, const int line,
+ const char *fmt, va_list ap)
+{
+ char tstmp_str[200];
+ time_t tstmp;
+ struct tm *loctstmp;
+
+ if( log == NULL ) {
+ return;
+ }
+
+ // Get time stamp
+ memset(&tstmp_str, 0, 200);
+ tstmp = time(NULL);
+ loctstmp = localtime(&tstmp);
+ if( loctstmp != NULL ) {
+ if( strftime(tstmp_str, 198, "%Y-%m-%d %H:%M:%S %Z", loctstmp) == 0 ) {
+ snprintf(tstmp_str, 198, "(error getting time stamp string)");
+ }
+ } else {
+ snprintf(tstmp_str, 198, "(error getting timestamp)");
+ }
+
+ // Do the logging
+ pthread_mutex_lock(&log_mutex); // Block other threads from writing when we write
+ fprintf(log, "[%s] %s [%i] {%s:%i} ", tstmp_str, logprio_str(logdst), loglvl, file, line);
+ vfprintf(log, fmt, ap);
+ fprintf(log, "\n");
+ fflush(log);
+ pthread_mutex_unlock(&log_mutex); // Unblock other threads
+}
+
/**
- * Simple log function which writes log data to the log file available in the eurephiaCTX
+ * Internal function. This function should normally be called via the eurephia_log() function.
*
* @param ctx eurephiaCTX
* @param logdst Log destination, can be LOG_INFO, LOG_DEBUG, LOG_WARNING, LOG_ERROR,
* LOG_CRITICAL, LOG_FATAL or LOG_PANIC
* @param loglvl Log level of the message. If the eurephiaCTX has a lower log level setup
* than what this parameter is set to, the message will not be logged.
+ * @param file String containing file name of the place this function was called. Usually the __FILE__ macro.
+ * @param line Line number of the source file this function was called. Usually the __LINE__ macro.
* @param fmt Contents of the log message (stdarg)
*/
-void eurephia_log(eurephiaCTX *ctx, int logdst, int loglvl, const char *fmt, ... ) {
+void _eurephia_log_func(eurephiaCTX *ctx, int logdst, int loglvl, const char *file, const int line,
+ const char *fmt, ... )
+{
// Only log if we have an open log file and which has high enough log level
- if( (ctx != NULL) && (ctx->log != NULL) && (ctx->loglevel >= loglvl) ) {
+ if( (ctx != NULL) && (ctx->log != NULL) && (ctx->log->opened == 1)
+ && (ctx->log->loglevel >= loglvl) ) {
va_list ap;
- char tstmp_str[200];
- time_t tstmp;
- struct tm *loctstmp;
-
- // Get time stamp
- memset(&tstmp_str, 0, 200);
- tstmp = time(NULL);
- loctstmp = localtime(&tstmp);
- if( loctstmp != NULL ) {
- if( strftime(tstmp_str, 198, "%Y-%m-%d %H:%M:%S %Z", loctstmp) == 0 ) {
- snprintf(tstmp_str, 198, "(error getting time stamp string)");
- }
- } else {
- snprintf(tstmp_str, 198, "(error getting timestamp)");
- }
va_start(ap, fmt);
- pthread_mutex_lock(&log_mutex); // Block other threads from writing when we write
- fprintf(ctx->log, "[%s] %s [%i] ", tstmp_str, erp_logtypes[logdst], loglvl);
- vfprintf(ctx->log, fmt, ap);
- fprintf(ctx->log, "\n");
- fflush(ctx->log);
- pthread_mutex_unlock(&log_mutex); // Unblock other threads
+ switch( ctx->log->logtype ) {
+ case logFILE:
+ file_log(ctx->log->logfile, logdst, loglvl, file, line, fmt, ap);
+ break;
+ case logSYSLOG:
+ vsyslog(syslog_priority[logdst], fmt, ap);
+ break;
+ }
va_end(ap);
}
}
+
+/**
+ * Closes an eurephia log context
+ *
+ * @param ctx eurephiaCTX containing the log context to be closed
+ *
+ */
+void eurephia_log_close(eurephiaCTX *ctx) {
+ if( (ctx == NULL) || (ctx->log == NULL) ) {
+ return;
+ }
+
+ eurephia_log(ctx, LOG_INFO, 2, "Closing %s logging (%s).",
+ logtype_str(ctx->log->logtype), ctx->log->destination);
+ if( ctx->log->opened == 1 ) {
+ switch( ctx->log->logtype ) {
+ case logFILE:
+ if( ctx->log->logfile != NULL ) {
+ fflush(ctx->log->logfile);
+ fclose(ctx->log->logfile);
+ }
+ ctx->log->logfile = NULL;
+ break;
+
+ case logSYSLOG:
+ closelog();
+ break;
+ }
+ ctx->log->opened = 0;
+ }
+ free_nullsafe(ctx, ctx->log->destination);
+ free_nullsafe(ctx, ctx->log);
+}
+
+/**
+ * Initialises and preapres the log device
+ *
+ * @param ctx eurephiaCTX where the log context will be associated
+ * @param ident Log ident. Used when logging to syslog primarily, to identify log entries in syslog logs
+ * @param dest Log destination. For can be a file name, "syslog:", "stdout:", "stderr:" or "none:".
+ * If it is "syslog:" it must continue with a string describing log facility such as
+ * "syslog:authpriv", "syslog:local0", "syslog:local1", "syslog:user", etc. If the
+ * facility is unknown, it will default to "user"
+ * @param loglevel Sets the verbosity level for the log file. The higher number, the more information
+ * will be logged.
+ *
+ * @return Returns 1 on success, otherwise 0;
+ */
+int eurephia_log_init(eurephiaCTX *ctx, const char *ident, const char *dest, int loglevel) {
+
+ assert( (ctx != NULL) && (dest != NULL) );
+
+ // Create log context
+ ctx->log = (eurephiaLOG *) malloc_nullsafe(ctx, sizeof(eurephiaLOG)+2);
+ if( ctx->log == NULL ) {
+ return 0;
+ }
+
+ if( strncmp(dest, "syslog:", 7) == 0 ) {
+ ctx->log->logtype = logSYSLOG;
+ ctx->log->destination = strdup(dest+7);
+ } else {
+ ctx->log->logtype = logFILE;
+ ctx->log->destination = strdup(dest);
+ }
+ if( ctx->log->destination == NULL) {
+ free_nullsafe(ctx, ctx->log);
+ return 0;
+ }
+ ctx->log->loglevel = loglevel;
+
+ switch( ctx->log->logtype ) {
+ case logFILE: // Open log file
+ if( strcmp(dest, "stdout:") == 0 ) {
+ ctx->log->logfile = stdout;
+ } else if( strcmp(dest, "stderr:") == 0 ) {
+ ctx->log->logfile = stderr;
+ } else if( strcmp(dest, "none:") == 0 ) {
+ ctx->log->logfile = NULL;
+ ctx->log->loglevel = 0;
+ ctx->log->opened = 0;
+ return 1;
+ } else if( (ctx->log->logfile = fopen(dest, "aw")) == NULL ) {
+ fprintf(stderr, "ERROR: Could not open log file: %s\n", ctx->log->destination);
+ free_nullsafe(ctx, ctx->log->destination);
+ free_nullsafe(ctx, ctx->log);
+ return 0;
+ }
+ break;
+
+ case logSYSLOG: // Open syslog
+ openlog(ident, LOG_PID, syslog_logdest(ctx->log->destination));
+ break;
+ }
+ ctx->log->opened = 1;
+ eurephia_log(ctx, LOG_INFO, 1, "Logging to %s (%s) started",
+ logtype_str(ctx->log->logtype), ctx->log->destination);
+ return 1;
+}
diff --git a/common/eurephia_log.h b/common/eurephia_log.h
index 97e58d2..d059735 100644
--- a/common/eurephia_log.h
+++ b/common/eurephia_log.h
@@ -31,16 +31,9 @@
#ifndef EUREPHIA_LOG_H_
#define EUREPHIA_LOG_H_
+#include <eurephia_log_struct.h>
#include <eurephia_context.h>
-#define LOG_INFO 1 /**< Informational messages. Log level should be < 5 */
-#define LOG_DEBUG 2 /**< Messages intended when debugging. Only for log level > 10 */
-#define LOG_WARNING 3 /**< Input data or processing revealed unexpected data. Log level never > 2*/
-#define LOG_ERROR 4 /**< API errors but not sever, program can continue to run */
-#define LOG_CRITICAL 5 /**< Operation failed and might have been aborted. Log level always 0 */
-#define LOG_FATAL 6 /**< Operation failed and cannot continue. Log level always < 2 */
-#define LOG_PANIC 7 /**< Action failed an program could not continue to run. Log level always 0 */
-
#ifdef ENABLE_DEBUG
#warning ###### DEBUG LOGGING IS ENABLED - THIS COULD BE A SECURITY ISSUE ######
/**
@@ -48,7 +41,7 @@
* binary if debug logging is not enabled at compile time. This will always use the LOG_DEBUG target
* when calling eurephia_log().
*/
-#define DEBUG(ctx, log_level, log_string...) eurephia_log(ctx, LOG_DEBUG, log_level, ## log_string);
+#define DEBUG(ctx, log_level, log_string...) _eurephia_log_func(ctx, LOG_DEBUG, log_level, __FILE__, __LINE__, ## log_string);
#else
#define DEBUG(ctx, lvl, rest...) {};
#endif
@@ -60,6 +53,20 @@
#warning ## ##
#warning ##########################################################################################
#endif
-void eurephia_log(eurephiaCTX *ctx, int logdst, int loglvl, const char *fmt, ... );
+int eurephia_log_init(eurephiaCTX *ctx, const char *ident, const char *dest, int loglvl);
+void eurephia_log_close(eurephiaCTX *ctx);
+
+/**
+ * Simple log function which writes log data to the log file available in the eurephiaCTX
+ * Frontend wrapper for the _eurephia_log_func() function.
+ *
+ * @param ctx eurephiaCTX
+ * @param dst Log destination/priority (LOG_INFO, LOG_PANIC, LOG_ERROR, etc)
+ * @param lvl Verbosity level of the message
+ * @param log_string The message to be logged
+ */
+#define eurephia_log(ctx, dst, lvl, log_string...) _eurephia_log_func(ctx, dst, lvl, __FILE__, __LINE__, ## log_string)
+void _eurephia_log_func(eurephiaCTX *ctx, int logdst, int loglvl, const char *file, int line,
+ const char *fmt, ... );
#endif /* !EUREPHIA_LOG_H_ */
diff --git a/common/eurephia_log_struct.h b/common/eurephia_log_struct.h
new file mode 100644
index 0000000..babd5d2
--- /dev/null
+++ b/common/eurephia_log_struct.h
@@ -0,0 +1,93 @@
+/* eurephia_log.h -- eurephia log struct definition
+ *
+ * GPLv2 only - Copyright (C) 2009
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * 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
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file eurephia_log_struct.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2009-09-23
+ *
+ * @brief Defines the eurphia log structure
+ *
+ */
+
+#ifndef EUREPHIA_LOG_STRUCT_H
+#define EUREPHIA_LOG_STRUCT_H
+
+#include <syslog.h>
+
+/*
+ * A lot of these definitions are here to make sure LOG_* definitions will not
+ * collide with syslog definitions.
+ *
+ */
+
+#ifndef LOG_INFO
+#define LOG_INFO 101 /**< Informational messages. Log level should be < 5 */
+#endif
+
+#ifndef LOG_DEBUG
+#define LOG_DEBUG 102 /**< Messages intended when debugging. Only for log level > 10 */
+#endif
+
+#ifndef LOG_WARNING
+#define LOG_WARNING 103 /**< Input data or processing revealed unexpected data. Log level never > 2*/
+#endif
+
+#ifndef LOG_ERR
+#define LOG_ERR 104 /**< Alias for LOG_ERROR, in case it is not defined */
+#endif
+#define LOG_ERROR LOG_ERR /**< API errors but not sever, program can continue to run */
+
+#ifndef LOG_CRIT
+#define LOG_CRIT 105 /**< Alias for LOG_CRITICAL */
+#endif
+#define LOG_CRITICAL LOG_CRIT /**< Operation failed and might have been aborted. Log level always 0 */
+
+#ifndef LOG_ALERT
+#define LOG_ALERT 106 /**< Alias for LOG_FATAL */
+#endif
+#define LOG_FATAL LOG_ALERT /**< Operation failed and cannot continue. Log level always < 2 */
+
+#ifndef LOG_EMERG
+#define LOG_EMERG 107 /**< Alias for LOG_PANIC */
+#endif
+#define LOG_PANIC LOG_EMERG /**< Action failed an program could not continue to run. Log level always 0 */
+
+
+/**
+ * Defines the different valid log types / logging backends
+ */
+typedef enum { logFILE, /**< Log to file */
+ logSYSLOG /**< Log via syslog */
+} eurephiaLOGTYPE;
+
+/**
+ * eurephia log context. Defines how the logging will be done when using eurephia_log()
+ */
+typedef struct {
+ eurephiaLOGTYPE logtype; /**< Defines which log backend to use */
+ unsigned int opened; /**< Boolean flag, if the logging is openend and enabled */
+ char *destination; /**< String containing log destination info (filename, syslog facility) */
+ FILE *logfile; /**< File pointer to the log file if logtype == logFILE */
+ int loglevel; /**< Defines the log verbosity, higher number increases log verbosity */
+} eurephiaLOG;
+
+#endif
diff --git a/common/eurephia_nullsafe.c b/common/eurephia_nullsafe.c
index 2536d4b..5f507c3 100644
--- a/common/eurephia_nullsafe.c
+++ b/common/eurephia_nullsafe.c
@@ -71,10 +71,15 @@ __malloc__ void *_malloc_nullsafe(eurephiaCTX *ctx, size_t sz, const char *file,
"Could not allocate memory region for %ld bytes (File %s, line %i)",
sz, file, line);
}
- } else {
- DEBUG(ctx, 40, "Allocated %ld bytes of memory on address %p (File %s, line %i)",
- sz, buf, file, line);
}
+#ifdef DEBUG
+ else {
+ // Don't use DEBUG macro, to catch the right file and line number for the log
+ _eurephia_log_func(ctx, LOG_DEBUG, 40, file, line,
+ "Allocated %ld bytes of memory on address %p",
+ sz, buf);
+ }
+#endif
return buf;
}
@@ -93,6 +98,9 @@ void inline _free_nullsafe(eurephiaCTX *ctx, void *ptr, const char *file, int li
if( ptr == NULL ) {
return;
}
- DEBUG(ctx, 40, "Freeing memory on address %p (File %s, line %i)", ptr, file, line);
+#ifdef DEBUG
+ // Don't use DEBUG macro, to catch the right file and line number for the log
+ _eurephia_log_func(ctx, LOG_DEBUG, 40, file, line, "Freeing memory on address %p", ptr);
+#endif
free(ptr);
}