46 #include <sys/types.h>
58 void log_msg(
const int priority,
const char *fmt, ...)
64 void log_xxd(
const int priority,
const char *msg,
const unsigned char *buffer,
73 void DebugLogSetLogType(
const int dbgtype)
78 void DebugLogSetLevel(
const int level)
83 INTERNAL
void DebugLogSetCategory(
const int dbginfo)
88 INTERNAL
void DebugLogCategory(
const int category,
const unsigned char *buffer,
101 #define DEBUG_BUF_SIZE 2048
103 static char LogMsgType = DEBUGLOG_NO_DEBUG;
104 static char LogCategory = DEBUG_CATEGORY_NOTHING;
111 static pthread_mutex_t LastTimeMutex = PTHREAD_MUTEX_INITIALIZER;
113 static void log_line(
const int priority,
const char *DebugBuffer,
119 void log_msg_rv(
const int priority,
unsigned int rv,
const char *fmt, ...)
125 || (DEBUGLOG_NO_DEBUG == LogMsgType))
128 va_start(argptr, fmt);
129 vsnprintf(DebugBuffer,
sizeof DebugBuffer, fmt, argptr);
132 log_line(priority, DebugBuffer, rv);
135 void log_msg(
const int priority,
const char *fmt, ...)
141 || (DEBUGLOG_NO_DEBUG == LogMsgType))
144 va_start(argptr, fmt);
145 vsnprintf(DebugBuffer,
sizeof DebugBuffer, fmt, argptr);
148 log_line(priority, DebugBuffer, -1);
154 const char * rv2text(
unsigned int rv)
156 const char *rv_text = NULL;
157 static __thread
char strError[30];
161 rv_text = "rv=" #x; \
164 if (rv != (
unsigned int)-1)
193 (void)snprintf(strError,
sizeof(strError)-1,
194 "Unknown error: 0x%08X", rv);
202 static void log_line(
const int priority,
const char *DebugBuffer,
205 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
206 syslog(LOG_INFO,
"%s", DebugBuffer);
209 static struct timeval last_time = { 0, 0 };
210 struct timeval new_time = { 0, 0 };
214 const char *rv_text = NULL;
216 (void)pthread_mutex_lock(&LastTimeMutex);
217 gettimeofday(&new_time, NULL);
218 if (0 == last_time.tv_sec)
219 last_time = new_time;
221 tmp.tv_sec = new_time.tv_sec - last_time.tv_sec;
222 tmp.tv_usec = new_time.tv_usec - last_time.tv_usec;
226 tmp.tv_usec += 1000000;
228 if (tmp.tv_sec < 100)
229 delta = tmp.tv_sec * 1000000 + tmp.tv_usec;
233 last_time = new_time;
234 (void)pthread_mutex_unlock(&LastTimeMutex);
236 thread_id = pthread_self();
238 rv_text = rv2text(rv);
242 const char *color_pfx =
"", *color_sfx =
"\33[0m";
243 const char *time_pfx =
"\33[36m", *time_sfx = color_sfx;
247 case PCSC_LOG_CRITICAL:
248 color_pfx =
"\33[01;31m";
252 color_pfx =
"\33[35m";
256 color_pfx =
"\33[34m";
266 #define THREAD_FORMAT "%p"
268 #define THREAD_FORMAT "%lu"
272 const char * rv_pfx =
"", * rv_sfx =
"";
279 printf(
"%s%.8d%s [" THREAD_FORMAT
"] %s%s%s, %s%s%s\n",
280 time_pfx, delta, time_sfx, thread_id,
281 color_pfx, DebugBuffer, color_sfx,
282 rv_pfx, rv_text, rv_sfx);
285 printf(
"%s%.8d%s [" THREAD_FORMAT
"] %s%s%s\n",
286 time_pfx, delta, time_sfx, thread_id,
287 color_pfx, DebugBuffer, color_sfx);
292 printf(
"%.8d %s, %s\n", delta, DebugBuffer, rv_text);
294 printf(
"%.8d %s\n", delta, DebugBuffer);
300 static void log_xxd_always(
const int priority,
const char *msg,
301 const unsigned char *buffer,
const int len)
303 char DebugBuffer[len*3 + strlen(msg) +1];
308 strcpy(DebugBuffer, msg);
309 c = DebugBuffer + strlen(DebugBuffer);
311 for (i = 0; (i < len); ++i)
314 snprintf(c, 4,
"%02X ", buffer[i]);
318 log_line(priority, DebugBuffer, -1);
321 void log_xxd(
const int priority,
const char *msg,
const unsigned char *buffer,
325 || (DEBUGLOG_NO_DEBUG == LogMsgType))
332 log_xxd_always(priority, msg, buffer, len);
335 void DebugLogSetLogType(
const int dbgtype)
339 case DEBUGLOG_NO_DEBUG:
340 case DEBUGLOG_SYSLOG_DEBUG:
341 case DEBUGLOG_STDOUT_DEBUG:
342 case DEBUGLOG_STDOUT_COLOR_DEBUG:
343 LogMsgType = dbgtype;
346 Log2(PCSC_LOG_CRITICAL,
"unknown log type (%d), using stdout",
348 LogMsgType = DEBUGLOG_STDOUT_DEBUG;
352 if ((DEBUGLOG_STDOUT_DEBUG == LogMsgType && isatty(fileno(stdout)))
353 || (DEBUGLOG_STDOUT_COLOR_DEBUG == LogMsgType))
360 const char *terms[] = {
"linux",
"xterm",
"xterm-color",
"Eterm",
"rxvt",
"rxvt-unicode",
"xterm-256color" };
364 for (i = 0; i < COUNT_OF(terms); i++)
367 if (0 == strcmp(terms[i], term))
377 void DebugLogSetLevel(
const int level)
382 case PCSC_LOG_CRITICAL:
388 Log1(PCSC_LOG_INFO,
"debug level=info");
392 Log1(PCSC_LOG_DEBUG,
"debug level=debug");
397 Log2(PCSC_LOG_CRITICAL,
"unknown level (%d), using level=info",
402 INTERNAL
void DebugLogSetCategory(
const int dbginfo)
408 LogCategory &= dbginfo;
410 LogCategory |= dbginfo;
412 if (LogCategory & DEBUG_CATEGORY_APDU)
413 Log1(PCSC_LOG_INFO,
"Debug options: APDU");
416 INTERNAL
void DebugLogCategory(
const int category,
const unsigned char *buffer,
419 if ((category & DEBUG_CATEGORY_APDU)
420 && (LogCategory & DEBUG_CATEGORY_APDU))
421 log_xxd_always(PCSC_LOG_INFO,
"APDU: ", buffer, len);
423 if ((category & DEBUG_CATEGORY_SW)
424 && (LogCategory & DEBUG_CATEGORY_APDU))
425 log_xxd_always(PCSC_LOG_INFO,
"SW: ", buffer, len);
433 void debug_msg(
const char *fmt, ...);
434 void debug_msg(
const char *fmt, ...)
439 if (DEBUGLOG_NO_DEBUG == LogMsgType)
442 va_start(argptr, fmt);
443 vsnprintf(DebugBuffer,
sizeof DebugBuffer, fmt, argptr);
446 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
447 syslog(LOG_INFO,
"%s", DebugBuffer);
452 void debug_xxd(
const char *msg,
const unsigned char *buffer,
const int len);
453 void debug_xxd(
const char *msg,
const unsigned char *buffer,
const int len)
455 log_xxd(PCSC_LOG_ERROR, msg, buffer, len);