248 lines
5.8 KiB
C
248 lines
5.8 KiB
C
/*-
|
|
* Copyright (c) 2017-2019 Carsten Sonne Larsen <cs@innolan.net>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "log.h"
|
|
#include "mem.h"
|
|
#include <stdarg.h>
|
|
|
|
#define MAXLOGLINESIZE 255
|
|
|
|
enum LogSeverity
|
|
{
|
|
ErrorMessage = 5,
|
|
WarningMessage = 10,
|
|
InfoMessage = 20,
|
|
TraceMessage = 30
|
|
};
|
|
|
|
struct LogEntry
|
|
{
|
|
enum LogSeverity level;
|
|
char *line;
|
|
struct LogEntry *next;
|
|
};
|
|
|
|
static bool logDisabled = false;
|
|
static bool bufferLog = false;
|
|
static BPTR logFile = NULL;
|
|
static struct LogEntry *firstEntry = NULL;
|
|
static struct LogEntry *lastEntry = NULL;
|
|
|
|
void OpenLogFile(void)
|
|
{
|
|
BPTR lock;
|
|
bool deleteFirst = false;
|
|
|
|
if (Globals->Settings->LogFile == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lock = Lock((STRPTR)Globals->Settings->LogFile, ACCESS_READ);
|
|
if (lock)
|
|
{
|
|
deleteFirst = true;
|
|
UnLock(lock);
|
|
}
|
|
|
|
if (deleteFirst)
|
|
{
|
|
bool success;
|
|
LogWarning("Deleting existing log file %s", Globals->Settings->LogFile);
|
|
success = DeleteFile((STRPTR)Globals->Settings->LogFile);
|
|
if (!success)
|
|
{
|
|
char message[MAXDOSERRORLEN];
|
|
long error = IoErr();
|
|
Fault(error, (STRPTR) "Cannot delete existing log file %s", (STRPTR)message, MAXDOSERRORLEN);
|
|
LogWarning(message);
|
|
logFile = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
LogInfo("Opening log file %s", Globals->Settings->LogFile);
|
|
logFile = Open((STRPTR)Globals->Settings->LogFile, MODE_READWRITE);
|
|
if (!logFile)
|
|
{
|
|
char message[MAXDOSERRORLEN];
|
|
long error = IoErr();
|
|
Fault(error, (STRPTR) "Cannot open log file %s", (STRPTR)message, MAXDOSERRORLEN);
|
|
LogWarning(message);
|
|
logFile = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void CloseLogFile(void)
|
|
{
|
|
if (logFile == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LogTrace("Closing log file %s", Globals->Settings->LogFile);
|
|
Close(logFile);
|
|
logFile = NULL;
|
|
logDisabled = true;
|
|
}
|
|
|
|
bool TraceLogging(void)
|
|
{
|
|
return Globals->Settings->Verbose * 10 >= (int)TraceMessage
|
|
? true
|
|
: false;
|
|
}
|
|
|
|
static void VLogLine(enum LogSeverity level, const char *format, va_list ap)
|
|
{
|
|
struct LogEntry *entry;
|
|
char line[MAXLOGLINESIZE + 1];
|
|
|
|
if (logDisabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bufferLog || Globals->Settings->Verbose * 10 >= (int)level)
|
|
{
|
|
int len;
|
|
VSNPrintf(line, MAXLOGLINESIZE - 1, format, ap);
|
|
len = TrimRight(line);
|
|
if (len != 0)
|
|
{
|
|
line[len++] = '\n';
|
|
line[len] = '\0';
|
|
}
|
|
}
|
|
|
|
if (bufferLog)
|
|
{
|
|
entry = (struct LogEntry *)AllocMemSafe(sizeof(struct LogEntry));
|
|
entry->level = level;
|
|
entry->line = StrDupSafe(line);
|
|
entry->next = NULL;
|
|
|
|
if (firstEntry == NULL)
|
|
{
|
|
firstEntry = entry;
|
|
lastEntry = entry;
|
|
}
|
|
else
|
|
{
|
|
lastEntry->next = entry;
|
|
lastEntry = entry;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (Globals->Settings->Verbose * 10 >= (int)level)
|
|
{
|
|
if (logFile != NULL)
|
|
{
|
|
FPuts(logFile, (STRPTR)line);
|
|
Flush(logFile);
|
|
}
|
|
else
|
|
{
|
|
Printf((STRPTR)line);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LogTrace(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, format);
|
|
VLogLine(TraceMessage, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
void LogInfo(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, format);
|
|
VLogLine(InfoMessage, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
void LogWarning(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, format);
|
|
VLogLine(WarningMessage, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
void LogError(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, format);
|
|
VLogLine(ErrorMessage, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
void SetLogBuffer(void)
|
|
{
|
|
bufferLog = true;
|
|
}
|
|
|
|
void FlushLogBuffer(void)
|
|
{
|
|
struct LogEntry *current;
|
|
|
|
if (!bufferLog)
|
|
return;
|
|
|
|
current = firstEntry;
|
|
while (current != NULL)
|
|
{
|
|
struct LogEntry *last;
|
|
if (Globals->Settings->Verbose * 10 >= (int)current->level)
|
|
{
|
|
if (logFile != NULL)
|
|
{
|
|
FPuts(logFile, (STRPTR)current->line);
|
|
}
|
|
else
|
|
{
|
|
Printf((STRPTR)current->line);
|
|
}
|
|
}
|
|
|
|
last = current;
|
|
current = current->next;
|
|
|
|
FreeMemSafe(last->line, __FUNCTION__);
|
|
FreeMemSafe(last, __FUNCTION__);
|
|
}
|
|
|
|
bufferLog = false;
|
|
firstEntry = NULL;
|
|
lastEntry = NULL;
|
|
}
|