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 2302 2007-01-06 17:57:58Z 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 void log_msg(const int priority, const char *fmt, ...)
00051 {
00052     char DebugBuffer[DEBUG_BUF_SIZE];
00053     va_list argptr;
00054 
00055     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00056         || (priority < LogLevel) /* log priority lower than threshold? */
00057         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00058         return;
00059 
00060     va_start(argptr, fmt);
00061 #ifndef WIN32
00062     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00063 #else
00064 #if HAVE_VSNPRINTF
00065     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00066 #else
00067     vsprintf(DebugBuffer, fmt, argptr);
00068 #endif
00069 #endif
00070     va_end(argptr);
00071 
00072 #ifndef WIN32
00073     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00074         syslog(LOG_INFO, "%s", DebugBuffer);
00075     else
00076     {
00077         if (LogDoColor)
00078         {
00079             const char *color_pfx = "", *color_sfx = "\33[0m";
00080 
00081             switch (priority)
00082             {
00083                 case PCSC_LOG_CRITICAL:
00084                     color_pfx = "\33[01;31m"; /* bright + Red */
00085                     break;
00086 
00087                 case PCSC_LOG_ERROR:
00088                     color_pfx = "\33[35m"; /* Magenta */
00089                     break;
00090 
00091                 case PCSC_LOG_INFO:
00092                     color_pfx = "\33[34m"; /* Blue */
00093                     break;
00094 
00095                 case PCSC_LOG_DEBUG:
00096                     color_pfx = ""; /* normal (black) */
00097                     color_sfx = "";
00098                     break;
00099             }
00100             fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
00101         }
00102         else
00103             fprintf(stderr, "%s\n", DebugBuffer);
00104     }
00105 #else
00106     fprintf(stderr, "%s\n", DebugBuffer);
00107 #endif
00108 } /* log_msg */
00109 
00110 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
00111     const int len)
00112 {
00113     char DebugBuffer[DEBUG_BUF_SIZE];
00114     int i;
00115     char *c;
00116     char *debug_buf_end;
00117 
00118     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00119         || (priority < LogLevel) /* log priority lower than threshold? */
00120         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00121         return;
00122 
00123     debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
00124 
00125     strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
00126     c = DebugBuffer + strlen(DebugBuffer);
00127 
00128     for (i = 0; (i < len) && (c < debug_buf_end); ++i)
00129     {
00130         sprintf(c, "%02X ", buffer[i]);
00131         c += 3;
00132     }
00133 
00134     /* the buffer is too small so end it with "..." */
00135     if ((c >= debug_buf_end) && (i < len))
00136         c[-3] = c[-2] = c[-1] = '.';
00137 
00138 #ifndef WIN32
00139     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00140         syslog(LOG_INFO, "%s", DebugBuffer);
00141     else
00142 #endif
00143         fprintf(stderr, "%s\n", DebugBuffer);
00144 } /* log_xxd */
00145 
00146 #ifdef PCSCD
00147 void DebugLogSuppress(const int lSType)
00148 {
00149     LogSuppress = lSType;
00150 }
00151 #endif
00152 
00153 void DebugLogSetLogType(const int dbgtype)
00154 {
00155     switch (dbgtype)
00156     {
00157         case DEBUGLOG_NO_DEBUG:
00158         case DEBUGLOG_SYSLOG_DEBUG:
00159         case DEBUGLOG_STDERR_DEBUG:
00160             LogMsgType = dbgtype;
00161             break;
00162         default:
00163             Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00164                 dbgtype);
00165             LogMsgType = DEBUGLOG_STDERR_DEBUG;
00166     }
00167 
00168     /* no color under Windows */
00169 #ifndef WIN32
00170     /* log to stderr and stderr is a tty? */
00171     if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00172     {
00173         const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00174         char *term;
00175 
00176         term = getenv("TERM");
00177         if (term)
00178         {
00179             unsigned int i;
00180 
00181             /* for each known color terminal */
00182             for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00183             {
00184                 /* we found a supported term? */
00185                 if (0 == strcmp(terms[i], term))
00186                 {
00187                     LogDoColor = 1;
00188                     break;
00189                 }
00190             }
00191         }
00192     }
00193 #endif
00194 }
00195 
00196 void DebugLogSetLevel(const int level)
00197 {
00198     LogLevel = level;
00199     switch (level)
00200     {
00201         case PCSC_LOG_CRITICAL:
00202         case PCSC_LOG_ERROR:
00203             /* do not log anything */
00204             break;
00205 
00206         case PCSC_LOG_INFO:
00207             Log1(PCSC_LOG_INFO, "debug level=notice");
00208             break;
00209 
00210         case PCSC_LOG_DEBUG:
00211             Log1(PCSC_LOG_DEBUG, "debug level=debug");
00212             break;
00213 
00214         default:
00215             LogLevel = PCSC_LOG_INFO;
00216             Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00217                 level);
00218     }
00219 }
00220 
00221 INTERNAL int DebugLogSetCategory(const int dbginfo)
00222 {
00223 #define DEBUG_INFO_LENGTH 80
00224     char text[DEBUG_INFO_LENGTH];
00225 
00226     /* use a negative number to UNset
00227      * typically use ~DEBUG_CATEGORY_APDU
00228      */
00229     if (dbginfo < 0)
00230         LogCategory &= dbginfo;
00231     else
00232         LogCategory |= dbginfo;
00233 
00234     /* set to empty string */
00235     text[0] = '\0';
00236 
00237     if (LogCategory & DEBUG_CATEGORY_APDU)
00238         strlcat(text, " APDU", sizeof(text));
00239 
00240     Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00241 
00242     return LogCategory;
00243 }
00244 
00245 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00246     const int len)
00247 {
00248     if ((category & DEBUG_CATEGORY_APDU)
00249         && (LogCategory & DEBUG_CATEGORY_APDU))
00250         log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00251 
00252     if ((category & DEBUG_CATEGORY_SW)
00253         && (LogCategory & DEBUG_CATEGORY_APDU))
00254         log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00255 }
00256 
00257 /*
00258  * old function supported for backward object code compatibility
00259  * defined only for pcscd
00260  */
00261 #ifdef PCSCD
00262 void debug_msg(const char *fmt, ...)
00263 {
00264     char DebugBuffer[DEBUG_BUF_SIZE];
00265     va_list argptr;
00266 
00267     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00268         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00269         return;
00270 
00271     va_start(argptr, fmt);
00272 #ifndef WIN32
00273     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00274 #else
00275 #if HAVE_VSNPRINTF
00276     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00277 #else
00278     vsprintf(DebugBuffer, fmt, argptr);
00279 #endif
00280 #endif
00281     va_end(argptr);
00282 
00283 #ifndef WIN32
00284     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00285         syslog(LOG_INFO, "%s", DebugBuffer);
00286     else
00287 #endif
00288         fprintf(stderr, "%s\n", DebugBuffer);
00289 } /* debug_msg */
00290 
00291 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00292 {
00293     log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00294 } /* debug_xxd */
00295 #endif
00296 

Generated on Mon Mar 5 22:33:02 2007 for pcsc-lite by  doxygen 1.4.7