ccid/src/debug.c

241 lines
5.1 KiB
C

/*
debug.c: log (or not) messages
Copyright (C) 2003-2011 Ludovic Rousseau
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include "misc.h"
#include "debug.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#endif
#include "strlcpycat.h"
#undef LOG_TO_STDERR
#ifdef LOG_TO_STDERR
#define LOG_STREAM stderr
#else
#define LOG_STREAM stdout
#endif
#ifdef USE_OS_LOG
void log_msg(const int priority, const char *fmt, ...)
{
char debug_buffer[3 * 80]; /* up to 3 lines of 80 characters */
va_list argptr;
int os_log_type;
switch(priority)
{
case PCSC_LOG_CRITICAL:
os_log_type = OS_LOG_TYPE_FAULT;
break;
case PCSC_LOG_ERROR:
os_log_type = OS_LOG_TYPE_ERROR;
break;
case PCSC_LOG_INFO:
os_log_type = OS_LOG_TYPE_INFO;
break;
default:
os_log_type = OS_LOG_TYPE_DEBUG;
}
va_start(argptr, fmt);
(void)vsnprintf(debug_buffer, sizeof debug_buffer, fmt, argptr);
va_end(argptr);
os_log_with_type(OS_LOG_DEFAULT, os_log_type, "%s", debug_buffer);
} /* log_msg */
void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
const int len)
{
int i;
char *c, debug_buffer[len*3 + strlen(msg) +1];
size_t l;
(void)priority;
l = strlcpy(debug_buffer, msg, sizeof debug_buffer);
c = debug_buffer + l;
for (i = 0; i < len; ++i)
{
/* 2 hex characters, 1 space, 1 NUL : total 4 characters */
(void)snprintf(c, 4, "%02X ", buffer[i]);
c += 3;
}
os_log(OS_LOG_DEFAULT, "%s", debug_buffer);
} /* log_xxd */
#else
void log_msg(const int priority, const char *fmt, ...)
{
char debug_buffer[3 * 80]; /* up to 3 lines of 80 characters */
va_list argptr;
static struct timeval last_time = { 0, 0 };
struct timeval new_time = { 0, 0 };
struct timeval tmp;
int delta;
#ifdef USE_SYSLOG
int syslog_level;
switch(priority)
{
case PCSC_LOG_CRITICAL:
syslog_level = LOG_CRIT;
break;
case PCSC_LOG_ERROR:
syslog_level = LOG_ERR;
break;
case PCSC_LOG_INFO:
syslog_level = LOG_INFO;
break;
default:
syslog_level = LOG_DEBUG;
}
#else
const char *color_pfx = "", *color_sfx = "";
const char *time_pfx = "", *time_sfx = "";
static int initialized = 0;
static int LogDoColor = 0;
if (!initialized)
{
char *term;
initialized = 1;
term = getenv("TERM");
if (term)
{
const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode", "xterm-256color" };
unsigned int i;
/* for each known color terminal */
for (i = 0; i < COUNT_OF(terms); i++)
{
/* we found a supported term? */
if (0 == strcmp(terms[i], term))
{
LogDoColor = 1;
break;
}
}
}
}
if (LogDoColor)
{
color_sfx = "\33[0m";
time_sfx = color_sfx;
time_pfx = "\33[36m"; /* Cyan */
switch (priority)
{
case PCSC_LOG_CRITICAL:
color_pfx = "\33[01;31m"; /* bright + Red */
break;
case PCSC_LOG_ERROR:
color_pfx = "\33[35m"; /* Magenta */
break;
case PCSC_LOG_INFO:
color_pfx = "\33[34m"; /* Blue */
break;
case PCSC_LOG_DEBUG:
color_pfx = ""; /* normal (black) */
color_sfx = "";
break;
}
}
#endif
gettimeofday(&new_time, NULL);
if (0 == last_time.tv_sec)
last_time = new_time;
tmp.tv_sec = new_time.tv_sec - last_time.tv_sec;
tmp.tv_usec = new_time.tv_usec - last_time.tv_usec;
if (tmp.tv_usec < 0)
{
tmp.tv_sec--;
tmp.tv_usec += 1000000;
}
if (tmp.tv_sec < 100)
delta = tmp.tv_sec * 1000000 + tmp.tv_usec;
else
delta = 99999999;
last_time = new_time;
va_start(argptr, fmt);
(void)vsnprintf(debug_buffer, sizeof debug_buffer, fmt, argptr);
va_end(argptr);
#ifdef USE_SYSLOG
syslog(syslog_level, "%.8d %s", delta, debug_buffer);
#else
(void)fprintf(LOG_STREAM, "%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx,
color_pfx, debug_buffer, color_sfx);
fflush(LOG_STREAM);
#endif
} /* log_msg */
void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
const int len)
{
int i;
char *c, debug_buffer[len*3 + strlen(msg) +1];
size_t l;
(void)priority;
l = strlcpy(debug_buffer, msg, sizeof debug_buffer);
c = debug_buffer + l;
for (i = 0; i < len; ++i)
{
/* 2 hex characters, 1 space, 1 NUL : total 4 characters */
(void)snprintf(c, 4, "%02X ", buffer[i]);
c += 3;
}
#ifdef USE_SYSLOG
syslog(LOG_DEBUG, "%s", debug_buffer);
#else
(void)fprintf(LOG_STREAM, "%s\n", debug_buffer);
fflush(LOG_STREAM);
#endif
} /* log_xxd */
#endif