debuglog.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999-2002
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  * Copyright (C) 1999-2005
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: debuglog.c 2555 2007-05-30 09:44:22Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #ifdef HAVE_SYSLOG_H
00019 #include <syslog.h>
00020 #endif
00021 #include <unistd.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <stdarg.h>
00026 #include <assert.h>
00027 #include <sys/types.h>
00028 
00029 #include "pcsclite.h"
00030 #include "misc.h"
00031 #include "debuglog.h"
00032 #include "sys_generic.h"
00033 #include "strlcpycat.h"
00034 
00039 #define DEBUG_BUF_SIZE 2048
00040 
00041 static char LogSuppress = DEBUGLOG_LOG_ENTRIES;
00042 static char LogMsgType = DEBUGLOG_NO_DEBUG;
00043 static char LogCategory = DEBUG_CATEGORY_NOTHING;
00044 
00045 /* default level is a bit verbose to be backward compatible */
00046 static char LogLevel = PCSC_LOG_INFO;
00047 
00048 static signed char LogDoColor = 0;  /* no color by default */
00049 
00050 static void log_line(const int priority, const char *DebugBuffer);
00051 
00052 void log_msg(const int priority, const char *fmt, ...)
00053 {
00054     char DebugBuffer[DEBUG_BUF_SIZE];
00055     va_list argptr;
00056 
00057     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00058         || (priority < LogLevel) /* log priority lower than threshold? */
00059         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00060         return;
00061 
00062     va_start(argptr, fmt);
00063 #ifndef WIN32
00064     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00065 #else
00066 #if HAVE_VSNPRINTF
00067     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00068 #else
00069     vsprintf(DebugBuffer, fmt, argptr);
00070 #endif
00071 #endif
00072     va_end(argptr);
00073 
00074     log_line(priority, DebugBuffer);
00075 } /* log_msg */
00076 
00077 static void log_line(const int priority, const char *DebugBuffer)
00078 {
00079 #ifndef WIN32
00080     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00081         syslog(LOG_INFO, "%s", DebugBuffer);
00082     else
00083     {
00084         if (LogDoColor)
00085         {
00086             const char *color_pfx = "", *color_sfx = "\33[0m";
00087 
00088             switch (priority)
00089             {
00090                 case PCSC_LOG_CRITICAL:
00091                     color_pfx = "\33[01;31m"; /* bright + Red */
00092                     break;
00093 
00094                 case PCSC_LOG_ERROR:
00095                     color_pfx = "\33[35m"; /* Magenta */
00096                     break;
00097 
00098                 case PCSC_LOG_INFO:
00099                     color_pfx = "\33[34m"; /* Blue */
00100                     break;
00101 
00102                 case PCSC_LOG_DEBUG:
00103                     color_pfx = ""; /* normal (black) */
00104                     color_sfx = "";
00105                     break;
00106             }
00107             fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
00108         }
00109         else
00110             fprintf(stderr, "%s\n", DebugBuffer);
00111     }
00112 #else
00113     fprintf(stderr, "%s\n", DebugBuffer);
00114 #endif
00115 } /* log_msg */
00116 
00117 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
00118     const int len)
00119 {
00120     char DebugBuffer[DEBUG_BUF_SIZE];
00121     int i;
00122     char *c;
00123     char *debug_buf_end;
00124 
00125     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00126         || (priority < LogLevel) /* log priority lower than threshold? */
00127         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00128         return;
00129 
00130     debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
00131 
00132     strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
00133     c = DebugBuffer + strlen(DebugBuffer);
00134 
00135     for (i = 0; (i < len) && (c < debug_buf_end); ++i)
00136     {
00137         sprintf(c, "%02X ", buffer[i]);
00138         c += 3;
00139     }
00140 
00141     /* the buffer is too small so end it with "..." */
00142     if ((c >= debug_buf_end) && (i < len))
00143         c[-3] = c[-2] = c[-1] = '.';
00144 
00145     log_line(priority, DebugBuffer);
00146 } /* log_xxd */
00147 
00148 #ifdef PCSCD
00149 void DebugLogSuppress(const int lSType)
00150 {
00151     LogSuppress = lSType;
00152 }
00153 #endif
00154 
00155 void DebugLogSetLogType(const int dbgtype)
00156 {
00157     switch (dbgtype)
00158     {
00159         case DEBUGLOG_NO_DEBUG:
00160         case DEBUGLOG_SYSLOG_DEBUG:
00161         case DEBUGLOG_STDERR_DEBUG:
00162             LogMsgType = dbgtype;
00163             break;
00164         default:
00165             Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00166                 dbgtype);
00167             LogMsgType = DEBUGLOG_STDERR_DEBUG;
00168     }
00169 
00170     /* no color under Windows */
00171 #ifndef WIN32
00172     /* log to stderr and stderr is a tty? */
00173     if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00174     {
00175         const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00176         char *term;
00177 
00178         term = getenv("TERM");
00179         if (term)
00180         {
00181             unsigned int i;
00182 
00183             /* for each known color terminal */
00184             for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00185             {
00186                 /* we found a supported term? */
00187                 if (0 == strcmp(terms[i], term))
00188                 {
00189                     LogDoColor = 1;
00190                     break;
00191                 }
00192             }
00193         }
00194     }
00195 #endif
00196 }
00197 
00198 void DebugLogSetLevel(const int level)
00199 {
00200     LogLevel = level;
00201     switch (level)
00202     {
00203         case PCSC_LOG_CRITICAL:
00204         case PCSC_LOG_ERROR:
00205             /* do not log anything */
00206             break;
00207 
00208         case PCSC_LOG_INFO:
00209             Log1(PCSC_LOG_INFO, "debug level=notice");
00210             break;
00211 
00212         case PCSC_LOG_DEBUG:
00213             Log1(PCSC_LOG_DEBUG, "debug level=debug");
00214             break;
00215 
00216         default:
00217             LogLevel = PCSC_LOG_INFO;
00218             Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00219                 level);
00220     }
00221 }
00222 
00223 INTERNAL int DebugLogSetCategory(const int dbginfo)
00224 {
00225 #define DEBUG_INFO_LENGTH 80
00226     char text[DEBUG_INFO_LENGTH];
00227 
00228     /* use a negative number to UNset
00229      * typically use ~DEBUG_CATEGORY_APDU
00230      */
00231     if (dbginfo < 0)
00232         LogCategory &= dbginfo;
00233     else
00234         LogCategory |= dbginfo;
00235 
00236     /* set to empty string */
00237     text[0] = '\0';
00238 
00239     if (LogCategory & DEBUG_CATEGORY_APDU)
00240         strlcat(text, " APDU", sizeof(text));
00241 
00242     Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00243 
00244     return LogCategory;
00245 }
00246 
00247 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00248     const int len)
00249 {
00250     if ((category & DEBUG_CATEGORY_APDU)
00251         && (LogCategory & DEBUG_CATEGORY_APDU))
00252         log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00253 
00254     if ((category & DEBUG_CATEGORY_SW)
00255         && (LogCategory & DEBUG_CATEGORY_APDU))
00256         log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00257 }
00258 
00259 /*
00260  * old function supported for backward object code compatibility
00261  * defined only for pcscd
00262  */
00263 #ifdef PCSCD
00264 void debug_msg(const char *fmt, ...);
00265 void debug_msg(const char *fmt, ...)
00266 {
00267     char DebugBuffer[DEBUG_BUF_SIZE];
00268     va_list argptr;
00269 
00270     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00271         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00272         return;
00273 
00274     va_start(argptr, fmt);
00275 #ifndef WIN32
00276     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00277 #else
00278 #if HAVE_VSNPRINTF
00279     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00280 #else
00281     vsprintf(DebugBuffer, fmt, argptr);
00282 #endif
00283 #endif
00284     va_end(argptr);
00285 
00286 #ifndef WIN32
00287     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00288         syslog(LOG_INFO, "%s", DebugBuffer);
00289     else
00290 #endif
00291         fprintf(stderr, "%s\n", DebugBuffer);
00292 } /* debug_msg */
00293 
00294 void debug_xxd(const char *msg, const unsigned char *buffer, const int len);
00295 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00296 {
00297     log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00298 } /* debug_xxd */
00299 #endif
00300 

Generated on Sun Jun 1 18:42:42 2008 for pcsc-lite by  doxygen 1.4.7