pcsc-lite 1.6.4
|
00001 /* 00002 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 00003 * 00004 * Copyright (C) 1999-2002 00005 * David Corcoran <corcoran@linuxnet.com> 00006 * Copyright (C) 2002-2010 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: debuglog.c 5047 2010-06-29 14:39:24Z 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 #include <sys/time.h> 00029 #include <time.h> 00030 00031 #include "pcsclite.h" 00032 #include "misc.h" 00033 #include "debuglog.h" 00034 #include "sys_generic.h" 00035 #include "strlcpycat.h" 00036 00037 #ifdef NO_LOG 00038 00039 void log_msg(const int priority, const char *fmt, ...) 00040 { 00041 (void)priority; 00042 (void)fmt; 00043 } 00044 00045 void log_xxd(const int priority, const char *msg, const unsigned char *buffer, 00046 const int len) 00047 { 00048 (void)priority; 00049 (void)msg; 00050 (void)buffer; 00051 (void)len; 00052 } 00053 00054 void DebugLogSuppress(const int lSType) 00055 { 00056 (void)lSType; 00057 } 00058 00059 void DebugLogSetLogType(const int dbgtype) 00060 { 00061 (void)dbgtype; 00062 } 00063 00064 void DebugLogSetLevel(const int level) 00065 { 00066 (void)level; 00067 } 00068 00069 INTERNAL int DebugLogSetCategory(const int dbginfo) 00070 { 00071 (void)dbginfo; 00072 00073 return 0; 00074 } 00075 00076 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer, 00077 const int len) 00078 { 00079 (void)category; 00080 (void)buffer; 00081 (void)len; 00082 } 00083 00084 #else 00085 00090 #define DEBUG_BUF_SIZE 2048 00091 00092 static char LogSuppress = DEBUGLOG_LOG_ENTRIES; 00093 static char LogMsgType = DEBUGLOG_NO_DEBUG; 00094 static char LogCategory = DEBUG_CATEGORY_NOTHING; 00095 00097 static char LogLevel = PCSC_LOG_ERROR; 00098 00099 static signed char LogDoColor = 0; 00101 static void log_line(const int priority, const char *DebugBuffer); 00102 00103 void log_msg(const int priority, const char *fmt, ...) 00104 { 00105 char DebugBuffer[DEBUG_BUF_SIZE]; 00106 va_list argptr; 00107 00108 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES) 00109 || (priority < LogLevel) /* log priority lower than threshold? */ 00110 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00111 return; 00112 00113 va_start(argptr, fmt); 00114 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr); 00115 va_end(argptr); 00116 00117 log_line(priority, DebugBuffer); 00118 } /* log_msg */ 00119 00120 static void log_line(const int priority, const char *DebugBuffer) 00121 { 00122 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00123 syslog(LOG_INFO, "%s", DebugBuffer); 00124 else 00125 { 00126 if (LogDoColor) 00127 { 00128 const char *color_pfx = "", *color_sfx = "\33[0m"; 00129 const char *time_pfx = "\33[36m", *time_sfx = color_sfx; 00130 static struct timeval last_time = { 0, 0 }; 00131 struct timeval new_time = { 0, 0 }; 00132 struct timeval tmp; 00133 int delta; 00134 00135 switch (priority) 00136 { 00137 case PCSC_LOG_CRITICAL: 00138 color_pfx = "\33[01;31m"; /* bright + Red */ 00139 break; 00140 00141 case PCSC_LOG_ERROR: 00142 color_pfx = "\33[35m"; /* Magenta */ 00143 break; 00144 00145 case PCSC_LOG_INFO: 00146 color_pfx = "\33[34m"; /* Blue */ 00147 break; 00148 00149 case PCSC_LOG_DEBUG: 00150 color_pfx = ""; /* normal (black) */ 00151 color_sfx = ""; 00152 break; 00153 } 00154 00155 gettimeofday(&new_time, NULL); 00156 if (0 == last_time.tv_sec) 00157 last_time = new_time; 00158 00159 tmp.tv_sec = new_time.tv_sec - last_time.tv_sec; 00160 tmp.tv_usec = new_time.tv_usec - last_time.tv_usec; 00161 if (tmp.tv_usec < 0) 00162 { 00163 tmp.tv_sec--; 00164 tmp.tv_usec += 1000000; 00165 } 00166 if (tmp.tv_sec < 100) 00167 delta = tmp.tv_sec * 1000000 + tmp.tv_usec; 00168 else 00169 delta = 99999999; 00170 00171 fprintf(stderr, "%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx, 00172 color_pfx, DebugBuffer, color_sfx); 00173 last_time = new_time; 00174 } 00175 else 00176 fprintf(stderr, "%s\n", DebugBuffer); 00177 } 00178 } /* log_msg */ 00179 00180 static void log_xxd_always(const int priority, const char *msg, 00181 const unsigned char *buffer, const int len) 00182 { 00183 char DebugBuffer[DEBUG_BUF_SIZE]; 00184 int i; 00185 char *c; 00186 char *debug_buf_end; 00187 00188 debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5; 00189 00190 strlcpy(DebugBuffer, msg, sizeof(DebugBuffer)); 00191 c = DebugBuffer + strlen(DebugBuffer); 00192 00193 for (i = 0; (i < len) && (c < debug_buf_end); ++i) 00194 { 00195 sprintf(c, "%02X ", buffer[i]); 00196 c += 3; 00197 } 00198 00199 /* the buffer is too small so end it with "..." */ 00200 if ((c >= debug_buf_end) && (i < len)) 00201 c[-3] = c[-2] = c[-1] = '.'; 00202 00203 log_line(priority, DebugBuffer); 00204 } /* log_xxd_always */ 00205 00206 void log_xxd(const int priority, const char *msg, const unsigned char *buffer, 00207 const int len) 00208 { 00209 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES) 00210 || (priority < LogLevel) /* log priority lower than threshold? */ 00211 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00212 return; 00213 00214 log_xxd_always(priority, msg, buffer, len); 00215 } /* log_xxd */ 00216 00217 void DebugLogSuppress(const int lSType) 00218 { 00219 LogSuppress = lSType; 00220 } 00221 00222 void DebugLogSetLogType(const int dbgtype) 00223 { 00224 switch (dbgtype) 00225 { 00226 case DEBUGLOG_NO_DEBUG: 00227 case DEBUGLOG_SYSLOG_DEBUG: 00228 case DEBUGLOG_STDERR_DEBUG: 00229 LogMsgType = dbgtype; 00230 break; 00231 default: 00232 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr", 00233 dbgtype); 00234 LogMsgType = DEBUGLOG_STDERR_DEBUG; 00235 } 00236 00237 /* log to stderr and stderr is a tty? */ 00238 if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr))) 00239 { 00240 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" }; 00241 char *term; 00242 00243 term = getenv("TERM"); 00244 if (term) 00245 { 00246 unsigned int i; 00247 00248 /* for each known color terminal */ 00249 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++) 00250 { 00251 /* we found a supported term? */ 00252 if (0 == strcmp(terms[i], term)) 00253 { 00254 LogDoColor = 1; 00255 break; 00256 } 00257 } 00258 } 00259 } 00260 } 00261 00262 void DebugLogSetLevel(const int level) 00263 { 00264 LogLevel = level; 00265 switch (level) 00266 { 00267 case PCSC_LOG_CRITICAL: 00268 case PCSC_LOG_ERROR: 00269 /* do not log anything */ 00270 break; 00271 00272 case PCSC_LOG_INFO: 00273 Log1(PCSC_LOG_INFO, "debug level=notice"); 00274 break; 00275 00276 case PCSC_LOG_DEBUG: 00277 Log1(PCSC_LOG_DEBUG, "debug level=debug"); 00278 break; 00279 00280 default: 00281 LogLevel = PCSC_LOG_INFO; 00282 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice", 00283 level); 00284 } 00285 } 00286 00287 INTERNAL int DebugLogSetCategory(const int dbginfo) 00288 { 00289 #define DEBUG_INFO_LENGTH 80 00290 char text[DEBUG_INFO_LENGTH]; 00291 00292 /* use a negative number to UNset 00293 * typically use ~DEBUG_CATEGORY_APDU 00294 */ 00295 if (dbginfo < 0) 00296 LogCategory &= dbginfo; 00297 else 00298 LogCategory |= dbginfo; 00299 00300 /* set to empty string */ 00301 text[0] = '\0'; 00302 00303 if (LogCategory & DEBUG_CATEGORY_APDU) 00304 strlcat(text, " APDU", sizeof(text)); 00305 00306 Log2(PCSC_LOG_INFO, "Debug options:%s", text); 00307 00308 return LogCategory; 00309 } 00310 00311 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer, 00312 const int len) 00313 { 00314 if ((category & DEBUG_CATEGORY_APDU) 00315 && (LogCategory & DEBUG_CATEGORY_APDU)) 00316 log_xxd_always(PCSC_LOG_INFO, "APDU: ", buffer, len); 00317 00318 if ((category & DEBUG_CATEGORY_SW) 00319 && (LogCategory & DEBUG_CATEGORY_APDU)) 00320 log_xxd_always(PCSC_LOG_INFO, "SW: ", buffer, len); 00321 } 00322 00323 /* 00324 * old function supported for backward object code compatibility 00325 * defined only for pcscd 00326 */ 00327 #ifdef PCSCD 00328 void debug_msg(const char *fmt, ...); 00329 void debug_msg(const char *fmt, ...) 00330 { 00331 char DebugBuffer[DEBUG_BUF_SIZE]; 00332 va_list argptr; 00333 00334 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES) 00335 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00336 return; 00337 00338 va_start(argptr, fmt); 00339 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr); 00340 va_end(argptr); 00341 00342 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00343 syslog(LOG_INFO, "%s", DebugBuffer); 00344 else 00345 fprintf(stderr, "%s\n", DebugBuffer); 00346 } /* debug_msg */ 00347 00348 void debug_xxd(const char *msg, const unsigned char *buffer, const int len); 00349 void debug_xxd(const char *msg, const unsigned char *buffer, const int len) 00350 { 00351 log_xxd(PCSC_LOG_ERROR, msg, buffer, len); 00352 } /* debug_xxd */ 00353 #endif 00354 00355 #endif /* NO_LOG */ 00356