pcsc-lite
1.8.2
|
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-2011 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: debuglog.c 6028 2011-10-11 14:18:43Z 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 DebugLogSetLogType(const int dbgtype) 00055 { 00056 (void)dbgtype; 00057 } 00058 00059 void DebugLogSetLevel(const int level) 00060 { 00061 (void)level; 00062 } 00063 00064 INTERNAL int DebugLogSetCategory(const int dbginfo) 00065 { 00066 (void)dbginfo; 00067 00068 return 0; 00069 } 00070 00071 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer, 00072 const int len) 00073 { 00074 (void)category; 00075 (void)buffer; 00076 (void)len; 00077 } 00078 00079 #else 00080 00084 #define DEBUG_BUF_SIZE 160 00085 00086 static char LogMsgType = DEBUGLOG_NO_DEBUG; 00087 static char LogCategory = DEBUG_CATEGORY_NOTHING; 00088 00090 static char LogLevel = PCSC_LOG_ERROR; 00091 00092 static signed char LogDoColor = 0; 00094 static void log_line(const int priority, const char *DebugBuffer); 00095 00096 void log_msg(const int priority, const char *fmt, ...) 00097 { 00098 char DebugBuffer[DEBUG_BUF_SIZE]; 00099 va_list argptr; 00100 00101 if ((priority < LogLevel) /* log priority lower than threshold? */ 00102 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00103 return; 00104 00105 va_start(argptr, fmt); 00106 vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr); 00107 va_end(argptr); 00108 00109 log_line(priority, DebugBuffer); 00110 } /* log_msg */ 00111 00112 static void log_line(const int priority, const char *DebugBuffer) 00113 { 00114 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00115 syslog(LOG_INFO, "%s", DebugBuffer); 00116 else 00117 { 00118 static struct timeval last_time = { 0, 0 }; 00119 struct timeval new_time = { 0, 0 }; 00120 struct timeval tmp; 00121 int delta; 00122 00123 gettimeofday(&new_time, NULL); 00124 if (0 == last_time.tv_sec) 00125 last_time = new_time; 00126 00127 tmp.tv_sec = new_time.tv_sec - last_time.tv_sec; 00128 tmp.tv_usec = new_time.tv_usec - last_time.tv_usec; 00129 if (tmp.tv_usec < 0) 00130 { 00131 tmp.tv_sec--; 00132 tmp.tv_usec += 1000000; 00133 } 00134 if (tmp.tv_sec < 100) 00135 delta = tmp.tv_sec * 1000000 + tmp.tv_usec; 00136 else 00137 delta = 99999999; 00138 00139 last_time = new_time; 00140 00141 if (LogDoColor) 00142 { 00143 const char *color_pfx = "", *color_sfx = "\33[0m"; 00144 const char *time_pfx = "\33[36m", *time_sfx = color_sfx; 00145 00146 switch (priority) 00147 { 00148 case PCSC_LOG_CRITICAL: 00149 color_pfx = "\33[01;31m"; /* bright + Red */ 00150 break; 00151 00152 case PCSC_LOG_ERROR: 00153 color_pfx = "\33[35m"; /* Magenta */ 00154 break; 00155 00156 case PCSC_LOG_INFO: 00157 color_pfx = "\33[34m"; /* Blue */ 00158 break; 00159 00160 case PCSC_LOG_DEBUG: 00161 color_pfx = ""; /* normal (black) */ 00162 color_sfx = ""; 00163 break; 00164 } 00165 00166 printf("%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx, 00167 color_pfx, DebugBuffer, color_sfx); 00168 } 00169 else 00170 { 00171 printf("%.8d %s\n", delta, DebugBuffer); 00172 } 00173 fflush(stdout); 00174 } 00175 } /* log_msg */ 00176 00177 static void log_xxd_always(const int priority, const char *msg, 00178 const unsigned char *buffer, const int len) 00179 { 00180 char DebugBuffer[len*3 + strlen(msg) +1]; 00181 int i; 00182 char *c; 00183 size_t l; 00184 00185 l = strlcpy(DebugBuffer, msg, sizeof(DebugBuffer)); 00186 c = DebugBuffer + l; 00187 00188 for (i = 0; (i < len); ++i) 00189 { 00190 /* 2 hex characters, 1 space, 1 NUL : total 4 characters */ 00191 snprintf(c, 4, "%02X ", buffer[i]); 00192 c += 3; 00193 } 00194 00195 log_line(priority, DebugBuffer); 00196 } /* log_xxd_always */ 00197 00198 void log_xxd(const int priority, const char *msg, const unsigned char *buffer, 00199 const int len) 00200 { 00201 if ((priority < LogLevel) /* log priority lower than threshold? */ 00202 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00203 return; 00204 00205 log_xxd_always(priority, msg, buffer, len); 00206 } /* log_xxd */ 00207 00208 void DebugLogSetLogType(const int dbgtype) 00209 { 00210 switch (dbgtype) 00211 { 00212 case DEBUGLOG_NO_DEBUG: 00213 case DEBUGLOG_SYSLOG_DEBUG: 00214 case DEBUGLOG_STDOUT_DEBUG: 00215 case DEBUGLOG_STDOUT_COLOR_DEBUG: 00216 LogMsgType = dbgtype; 00217 break; 00218 default: 00219 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stdout", 00220 dbgtype); 00221 LogMsgType = DEBUGLOG_STDOUT_DEBUG; 00222 } 00223 00224 /* log to stdout and stdout is a tty? */ 00225 if ((DEBUGLOG_STDOUT_DEBUG == LogMsgType && isatty(fileno(stdout))) 00226 || (DEBUGLOG_STDOUT_COLOR_DEBUG == LogMsgType)) 00227 { 00228 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode", "xterm-256color" }; 00229 char *term; 00230 00231 term = getenv("TERM"); 00232 if (term) 00233 { 00234 unsigned int i; 00235 00236 /* for each known color terminal */ 00237 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++) 00238 { 00239 /* we found a supported term? */ 00240 if (0 == strcmp(terms[i], term)) 00241 { 00242 LogDoColor = 1; 00243 break; 00244 } 00245 } 00246 } 00247 } 00248 } 00249 00250 void DebugLogSetLevel(const int level) 00251 { 00252 LogLevel = level; 00253 switch (level) 00254 { 00255 case PCSC_LOG_CRITICAL: 00256 case PCSC_LOG_ERROR: 00257 /* do not log anything */ 00258 break; 00259 00260 case PCSC_LOG_INFO: 00261 Log1(PCSC_LOG_INFO, "debug level=notice"); 00262 break; 00263 00264 case PCSC_LOG_DEBUG: 00265 Log1(PCSC_LOG_DEBUG, "debug level=debug"); 00266 break; 00267 00268 default: 00269 LogLevel = PCSC_LOG_INFO; 00270 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice", 00271 level); 00272 } 00273 } 00274 00275 INTERNAL int DebugLogSetCategory(const int dbginfo) 00276 { 00277 #define DEBUG_INFO_LENGTH 80 00278 char text[DEBUG_INFO_LENGTH]; 00279 00280 /* use a negative number to UNset 00281 * typically use ~DEBUG_CATEGORY_APDU 00282 */ 00283 if (dbginfo < 0) 00284 LogCategory &= dbginfo; 00285 else 00286 LogCategory |= dbginfo; 00287 00288 /* set to empty string */ 00289 text[0] = '\0'; 00290 00291 if (LogCategory & DEBUG_CATEGORY_APDU) 00292 strlcat(text, " APDU", sizeof(text)); 00293 00294 Log2(PCSC_LOG_INFO, "Debug options:%s", text); 00295 00296 return LogCategory; 00297 } 00298 00299 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer, 00300 const int len) 00301 { 00302 if ((category & DEBUG_CATEGORY_APDU) 00303 && (LogCategory & DEBUG_CATEGORY_APDU)) 00304 log_xxd_always(PCSC_LOG_INFO, "APDU: ", buffer, len); 00305 00306 if ((category & DEBUG_CATEGORY_SW) 00307 && (LogCategory & DEBUG_CATEGORY_APDU)) 00308 log_xxd_always(PCSC_LOG_INFO, "SW: ", buffer, len); 00309 } 00310 00311 /* 00312 * old function supported for backward object code compatibility 00313 * defined only for pcscd 00314 */ 00315 #ifdef PCSCD 00316 void debug_msg(const char *fmt, ...); 00317 void debug_msg(const char *fmt, ...) 00318 { 00319 char DebugBuffer[DEBUG_BUF_SIZE]; 00320 va_list argptr; 00321 00322 if (DEBUGLOG_NO_DEBUG == LogMsgType) 00323 return; 00324 00325 va_start(argptr, fmt); 00326 vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr); 00327 va_end(argptr); 00328 00329 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00330 syslog(LOG_INFO, "%s", DebugBuffer); 00331 else 00332 puts(DebugBuffer); 00333 } /* debug_msg */ 00334 00335 void debug_xxd(const char *msg, const unsigned char *buffer, const int len); 00336 void debug_xxd(const char *msg, const unsigned char *buffer, const int len) 00337 { 00338 log_xxd(PCSC_LOG_ERROR, msg, buffer, len); 00339 } /* debug_xxd */ 00340 #endif 00341 00342 #endif /* NO_LOG */ 00343