46#define COLOR_RESET "\033[0m"
47#define COLOR_RED "\033[31m"
48#define COLOR_GREEN "\033[32m"
49#define COLOR_YELLOW "\033[33m"
50#define COLOR_BLUE "\033[34m"
51#define COLOR_MAGENTA "\033[35m"
52#define COLOR_CYAN "\033[36m"
53#define COLOR_WHITE "\033[37m"
103 openlog(identity, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL7);
138 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
139 if (hOut != INVALID_HANDLE_VALUE) {
141 if (GetConsoleMode(hOut, &dwMode)) {
142 dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
143 if (SetConsoleMode(hOut, dwMode)) {
151 if (isatty(fileno(stdout))) {
180 int fd = open(file, O_CREAT | O_APPEND | O_WRONLY, 0600);
189 n_log(
LOG_ERR,
"fdopen returned an invalid file descriptor pointer for %s:%d",
_str(file), fd);
242 va_copy(argcopy, pargs);
243 retval = vsnprintf(NULL, 0, format, argcopy);
257int vasprintf(
char** strp,
const char* fmt, va_list ap) {
262 Malloc(str,
char, (
size_t)len + 1 +
sizeof(
void*));
265 int r = vsnprintf(str, (
size_t)(len + 1), fmt, ap);
267 return free(str), -1;
298void _n_log(
int level,
const char* file,
const char* func,
int line,
const char* format, ...) {
313 char* syslogbuffer = NULL;
314 char* eventbuffer = NULL;
315 char* syslogsafebuffer = NULL;
318 const char* name =
"NULL";
323 const char* color =
"";
324 const char* color_reset =
"";
360 va_start(args, format);
361 if (
vasprintf(&syslogbuffer, format, args) == -1) {
366 syslogsafebuffer = syslogbuffer ? syslogbuffer :
"<log: vasprintf failed>";
373 for (
char* p = syslogsafebuffer; *p; p++) {
374 if (*p ==
'"' || *p ==
'&' || *p ==
'|' || *p ==
'<' || *p ==
'>' || *p ==
'^') *p =
'_';
377 int snprintf_ret = snprintf(NULL, 0,
"start /B EventCreate /t %s /id 666 /l APPLICATION /so %s /d \"%s\" > NUL 2>&1",
prioritynames[level].w_name, name, syslogsafebuffer);
378 if (snprintf_ret > 0) {
379 needed = (
unsigned long long)snprintf_ret;
380 Malloc(eventbuffer,
char, needed + 4);
382 snprintf(eventbuffer, needed + 4,
"start /B EventCreate /t %s /id 666 /l APPLICATION /so %s /d \"%s\" > NUL 2>&1",
prioritynames[level].w_name, name, syslogsafebuffer);
387 syslog(level,
"%s->%s:%d %s",
_str(file),
_str(func),
line, syslogsafebuffer);
393 fprintf(out,
"%s%s:%jd:%s->%s:%d ", color,
prioritynames[level].c_name, (intmax_t)time(NULL),
_str(file),
_str(func),
line);
395 va_start(args, format);
396 vfprintf(out, format, args);
399 fprintf(out,
"%s\n", color_reset);
424 n_log(
LOG_ERR,
"Log struct already allocated without file");
428 if (!pathname || !opt) {
439 pthread_mutex_init(&(*log)->LOG_MUTEX, NULL);
442 if (strcmp(opt,
"a") == 0 || strcmp(opt,
"a+") == 0) {
443 flags = O_CREAT | O_APPEND | O_WRONLY;
444 }
else if (strcmp(opt,
"w") == 0 || strcmp(opt,
"w+") == 0) {
445 flags = O_CREAT | O_TRUNC | O_WRONLY;
448 pthread_mutex_destroy(&(*log)->LOG_MUTEX);
454 int fd = open(pathname, flags, 0600);
456 n_log(
LOG_ERR,
"Failed to open '%s' with 0600 permissions",
_str(pathname));
457 pthread_mutex_destroy(&(*log)->LOG_MUTEX);
463 (*log)->file = fdopen(fd, opt);
467 pthread_mutex_destroy(&(*log)->LOG_MUTEX);
492 vsnprintf(str,
sizeof(str), pat, arg);
497 fprintf(log->
file,
"%s", str);
void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color)
draw a line
#define FreeNoLog(__ptr)
Free Handler without log.
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define _str(__PTR)
define true
#define Free(__ptr)
Free Handler to get errors.
pthread_mutex_t LOG_MUTEX
mutex for thread-safe writting
#define LOG_ALERT
action must be taken immediately
#define LOG_SYSJRNL
to sysjrnl
FILE * get_log_file(void)
return the current log_file
int write_safe_log(TS_LOG *log, char *pat,...)
write to a thread-safe logging file
int open_safe_logging(TS_LOG **log, char *pathname, char *opt)
Open a thread-safe logging file.
#define LOG_EMERG
system is unusable
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_FILE
internal, logging to file
void close_sysjrnl(void)
Close syslog connection or clean internals for event log.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
char * open_sysjrnl(const char *identity)
Open connection to syslog or create internals for event log.
int set_log_file_fd(FILE *fd)
Set the logging to an already open stream instead of stderr.
#define N_PRINTF_FORMAT(fmt, args)
declare a function printf-like; nothing on a compiler without attributes
#define LOG_STDERR
internal, default LOG_TYPE
#define LOG_CRIT
critical conditions
int close_safe_logging(TS_LOG *log)
close a thread-safe logging file
int set_log_file(char *file)
Set the logging to a file instead of stderr.
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_NOTICE
normal but significant condition
#define LOG_WARNING
warning conditions
#define LOG_NULL
no log output
#define LOG_INFO
informational
void _n_log(int level, const char *file, const char *func, int line, const char *format,...)
Logging function.
int get_log_level(void)
Get the global log level value.
ThreadSafe LOGging structure.
Common headers and low-level functions & define.
static LOG_LEVELS prioritynames[]
array of log levels
static char * proc_name
static proc name, for windows event log
static int LOG_LEVEL
static global maximum wanted log level value
static int LOG_TYPE
static global logging type ( STDERR, FILE, SYSJRNL )
int vasprintf(char **strp, const char *fmt, va_list ap)
snprintf from a va_list, helper for asprintf
int asprintf(char *strp[], const char *fmt,...)
snprintf from a va_list
static int terminal_support_colors
static FILE * log_file
static FILE handling if logging to file is enabled
char * c_name
string of log type
static int log_file_owned
TRUE when log_file was opened by set_log_file() and must be closed by the library.
int _vscprintf_so(const char *format, va_list pargs)
compute the size of a string made with format 'fmt' and arguments in the va_list 'ap',...
internal struct to handle log types