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 1827 2006-01-24 14:49:52Z 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 += strlen(c);
00132     }
00133 
00134 #ifndef WIN32
00135     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00136         syslog(LOG_INFO, "%s", DebugBuffer);
00137     else
00138 #endif
00139         fprintf(stderr, "%s\n", DebugBuffer);
00140 } /* log_xxd */
00141 
00142 #ifdef PCSCD
00143 void DebugLogSuppress(const int lSType)
00144 {
00145     LogSuppress = lSType;
00146 }
00147 #endif
00148 
00149 void DebugLogSetLogType(const int dbgtype)
00150 {
00151     switch (dbgtype)
00152     {
00153         case DEBUGLOG_NO_DEBUG:
00154         case DEBUGLOG_SYSLOG_DEBUG:
00155         case DEBUGLOG_STDERR_DEBUG:
00156             LogMsgType = dbgtype;
00157             break;
00158         default:
00159             Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00160                 dbgtype);
00161             LogMsgType = DEBUGLOG_STDERR_DEBUG;
00162     }
00163 
00164     /* no color under Windows */
00165 #ifndef WIN32
00166     /* log to stderr and stderr is a tty? */
00167     if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00168     {
00169         const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00170         char *term;
00171 
00172         term = getenv("TERM");
00173         if (term)
00174         {
00175             int i;
00176 
00177             /* for each known color terminal */
00178             for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00179             {
00180                 /* we found a supported term? */
00181                 if (0 == strcmp(terms[i], term))
00182                 {
00183                     LogDoColor = 1;
00184                     break;
00185                 }
00186             }
00187         }
00188     }
00189 #endif
00190 }
00191 
00192 void DebugLogSetLevel(const int level)
00193 {
00194     LogLevel = level;
00195     switch (level)
00196     {
00197         case PCSC_LOG_CRITICAL:
00198         case PCSC_LOG_ERROR:
00199             /* do not log anything */
00200             break;
00201 
00202         case PCSC_LOG_INFO:
00203             Log1(PCSC_LOG_INFO, "debug level=notice");
00204             break;
00205 
00206         case PCSC_LOG_DEBUG:
00207             Log1(PCSC_LOG_DEBUG, "debug level=debug");
00208             break;
00209 
00210         default:
00211             LogLevel = PCSC_LOG_INFO;
00212             Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00213                 level);
00214     }
00215 }
00216 
00217 INTERNAL int DebugLogSetCategory(const int dbginfo)
00218 {
00219 #define DEBUG_INFO_LENGTH 80
00220     char text[DEBUG_INFO_LENGTH];
00221 
00222     /* use a negative number to UNset
00223      * typically use ~DEBUG_CATEGORY_APDU
00224      */
00225     if (dbginfo < 0)
00226         LogCategory &= dbginfo;
00227     else
00228         LogCategory |= dbginfo;
00229 
00230     /* set to empty string */
00231     text[0] = '\0';
00232 
00233     if (LogCategory & DEBUG_CATEGORY_APDU)
00234         strlcat(text, " APDU", sizeof(text));
00235 
00236     Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00237 
00238     return LogCategory;
00239 }
00240 
00241 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00242     const int len)
00243 {
00244     if ((category & DEBUG_CATEGORY_APDU)
00245         && (LogCategory & DEBUG_CATEGORY_APDU))
00246         log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00247 
00248     if ((category & DEBUG_CATEGORY_SW)
00249         && (LogCategory & DEBUG_CATEGORY_APDU))
00250         log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00251 }
00252 
00270 char* pcsc_stringify_error(long pcscError)
00271 {
00272     static char strError[75];
00273 
00274     switch (pcscError)
00275     {
00276     case SCARD_S_SUCCESS:
00277         strlcpy(strError, "Command successful.", sizeof(strError));
00278         break;
00279     case SCARD_E_CANCELLED:
00280         strlcpy(strError, "Command cancelled.", sizeof(strError));
00281         break;
00282     case SCARD_E_CANT_DISPOSE:
00283         strlcpy(strError, "Cannot dispose handle.", sizeof(strError));
00284         break;
00285     case SCARD_E_INSUFFICIENT_BUFFER:
00286         strlcpy(strError, "Insufficient buffer.", sizeof(strError));
00287         break;
00288     case SCARD_E_INVALID_ATR:
00289         strlcpy(strError, "Invalid ATR.", sizeof(strError));
00290         break;
00291     case SCARD_E_INVALID_HANDLE:
00292         strlcpy(strError, "Invalid handle.", sizeof(strError));
00293         break;
00294     case SCARD_E_INVALID_PARAMETER:
00295         strlcpy(strError, "Invalid parameter given.", sizeof(strError));
00296         break;
00297     case SCARD_E_INVALID_TARGET:
00298         strlcpy(strError, "Invalid target given.", sizeof(strError));
00299         break;
00300     case SCARD_E_INVALID_VALUE:
00301         strlcpy(strError, "Invalid value given.", sizeof(strError));
00302         break;
00303     case SCARD_E_NO_MEMORY:
00304         strlcpy(strError, "Not enough memory.", sizeof(strError));
00305         break;
00306     case SCARD_F_COMM_ERROR:
00307         strlcpy(strError, "RPC transport error.", sizeof(strError));
00308         break;
00309     case SCARD_F_INTERNAL_ERROR:
00310         strlcpy(strError, "Internal error.", sizeof(strError));
00311         break;
00312     case SCARD_F_UNKNOWN_ERROR:
00313         strlcpy(strError, "Unknown error.", sizeof(strError));
00314         break;
00315     case SCARD_F_WAITED_TOO_LONG:
00316         strlcpy(strError, "Waited too long.", sizeof(strError));
00317         break;
00318     case SCARD_E_UNKNOWN_READER:
00319         strlcpy(strError, "Unknown reader specified.", sizeof(strError));
00320         break;
00321     case SCARD_E_TIMEOUT:
00322         strlcpy(strError, "Command timeout.", sizeof(strError));
00323         break;
00324     case SCARD_E_SHARING_VIOLATION:
00325         strlcpy(strError, "Sharing violation.", sizeof(strError));
00326         break;
00327     case SCARD_E_NO_SMARTCARD:
00328         strlcpy(strError, "No smart card inserted.", sizeof(strError));
00329         break;
00330     case SCARD_E_UNKNOWN_CARD:
00331         strlcpy(strError, "Unknown card.", sizeof(strError));
00332         break;
00333     case SCARD_E_PROTO_MISMATCH:
00334         strlcpy(strError, "Card protocol mismatch.", sizeof(strError));
00335         break;
00336     case SCARD_E_NOT_READY:
00337         strlcpy(strError, "Subsystem not ready.", sizeof(strError));
00338         break;
00339     case SCARD_E_SYSTEM_CANCELLED:
00340         strlcpy(strError, "System cancelled.", sizeof(strError));
00341         break;
00342     case SCARD_E_NOT_TRANSACTED:
00343         strlcpy(strError, "Transaction failed.", sizeof(strError));
00344         break;
00345     case SCARD_E_READER_UNAVAILABLE:
00346         strlcpy(strError, "Reader is unavailable.", sizeof(strError));
00347         break;
00348     case SCARD_W_UNSUPPORTED_CARD:
00349         strlcpy(strError, "Card is not supported.", sizeof(strError));
00350         break;
00351     case SCARD_W_UNRESPONSIVE_CARD:
00352         strlcpy(strError, "Card is unresponsive.", sizeof(strError));
00353         break;
00354     case SCARD_W_UNPOWERED_CARD:
00355         strlcpy(strError, "Card is unpowered.", sizeof(strError));
00356         break;
00357     case SCARD_W_RESET_CARD:
00358         strlcpy(strError, "Card was reset.", sizeof(strError));
00359         break;
00360     case SCARD_W_REMOVED_CARD:
00361         strlcpy(strError, "Card was removed.", sizeof(strError));
00362         break;
00363     case SCARD_W_INSERTED_CARD:
00364         strlcpy(strError, "Card was inserted.", sizeof(strError));
00365         break;
00366     case SCARD_E_UNSUPPORTED_FEATURE:
00367         strlcpy(strError, "Feature not supported.", sizeof(strError));
00368         break;
00369     case SCARD_E_PCI_TOO_SMALL:
00370         strlcpy(strError, "PCI struct too small.", sizeof(strError));
00371         break;
00372     case SCARD_E_READER_UNSUPPORTED:
00373         strlcpy(strError, "Reader is unsupported.", sizeof(strError));
00374         break;
00375     case SCARD_E_DUPLICATE_READER:
00376         strlcpy(strError, "Reader already exists.", sizeof(strError));
00377         break;
00378     case SCARD_E_CARD_UNSUPPORTED:
00379         strlcpy(strError, "Card is unsupported.", sizeof(strError));
00380         break;
00381     case SCARD_E_NO_SERVICE:
00382         strlcpy(strError, "Service not available.", sizeof(strError));
00383         break;
00384     case SCARD_E_SERVICE_STOPPED:
00385         strlcpy(strError, "Service was stopped.", sizeof(strError));
00386         break;
00387     default:
00388         snprintf(strError, sizeof(strError)-1, "Unkown error: 0x%08lX",
00389             pcscError);
00390     };
00391 
00392     /* add a null byte */
00393     strError[sizeof(strError)] = '\0';
00394 
00395     return strError;
00396 }
00397 
00398 /*
00399  * old function supported for backward object code compatibility
00400  * defined only for pcscd
00401  */
00402 #ifdef PCSCD
00403 void debug_msg(const char *fmt, ...)
00404 {
00405     char DebugBuffer[DEBUG_BUF_SIZE];
00406     va_list argptr;
00407 
00408     if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00409         || (DEBUGLOG_NO_DEBUG == LogMsgType))
00410         return;
00411 
00412     va_start(argptr, fmt);
00413 #ifndef WIN32
00414     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00415 #else
00416 #if HAVE_VSNPRINTF
00417     vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00418 #else
00419     vsprintf(DebugBuffer, fmt, argptr);
00420 #endif
00421 #endif
00422     va_end(argptr);
00423 
00424 #ifndef WIN32
00425     if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00426         syslog(LOG_INFO, "%s", DebugBuffer);
00427     else
00428 #endif
00429         fprintf(stderr, "%s\n", DebugBuffer);
00430 } /* debug_msg */
00431 
00432 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00433 {
00434     log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00435 } /* debug_xxd */
00436 #endif
00437 

Generated on Fri Mar 24 04:30:05 2006 for pcsc-lite by  doxygen 1.4.6