pcsc-lite
1.8.3
|
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 6229 2012-02-21 08:49:21Z 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 /* len is an error value? */ 00206 if (len < 0) 00207 return; 00208 00209 log_xxd_always(priority, msg, buffer, len); 00210 } /* log_xxd */ 00211 00212 void DebugLogSetLogType(const int dbgtype) 00213 { 00214 switch (dbgtype) 00215 { 00216 case DEBUGLOG_NO_DEBUG: 00217 case DEBUGLOG_SYSLOG_DEBUG: 00218 case DEBUGLOG_STDOUT_DEBUG: 00219 case DEBUGLOG_STDOUT_COLOR_DEBUG: 00220 LogMsgType = dbgtype; 00221 break; 00222 default: 00223 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stdout", 00224 dbgtype); 00225 LogMsgType = DEBUGLOG_STDOUT_DEBUG; 00226 } 00227 00228 /* log to stdout and stdout is a tty? */ 00229 if ((DEBUGLOG_STDOUT_DEBUG == LogMsgType && isatty(fileno(stdout))) 00230 || (DEBUGLOG_STDOUT_COLOR_DEBUG == LogMsgType)) 00231 { 00232 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode", "xterm-256color" }; 00233 char *term; 00234 00235 term = getenv("TERM"); 00236 if (term) 00237 { 00238 unsigned int i; 00239 00240 /* for each known color terminal */ 00241 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++) 00242 { 00243 /* we found a supported term? */ 00244 if (0 == strcmp(terms[i], term)) 00245 { 00246 LogDoColor = 1; 00247 break; 00248 } 00249 } 00250 } 00251 } 00252 } 00253 00254 void DebugLogSetLevel(const int level) 00255 { 00256 LogLevel = level; 00257 switch (level) 00258 { 00259 case PCSC_LOG_CRITICAL: 00260 case PCSC_LOG_ERROR: 00261 /* do not log anything */ 00262 break; 00263 00264 case PCSC_LOG_INFO: 00265 Log1(PCSC_LOG_INFO, "debug level=notice"); 00266 break; 00267 00268 case PCSC_LOG_DEBUG: 00269 Log1(PCSC_LOG_DEBUG, "debug level=debug"); 00270 break; 00271 00272 default: 00273 LogLevel = PCSC_LOG_INFO; 00274 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice", 00275 level); 00276 } 00277 } 00278 00279 INTERNAL int DebugLogSetCategory(const int dbginfo) 00280 { 00281 #define DEBUG_INFO_LENGTH 80 00282 char text[DEBUG_INFO_LENGTH]; 00283 00284 /* use a negative number to UNset 00285 * typically use ~DEBUG_CATEGORY_APDU 00286 */ 00287 if (dbginfo < 0) 00288 LogCategory &= dbginfo; 00289 else 00290 LogCategory |= dbginfo; 00291 00292 /* set to empty string */ 00293 text[0] = '\0'; 00294 00295 if (LogCategory & DEBUG_CATEGORY_APDU) 00296 strlcat(text, " APDU", sizeof(text)); 00297 00298 Log2(PCSC_LOG_INFO, "Debug options:%s", text); 00299 00300 return LogCategory; 00301 } 00302 00303 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer, 00304 const int len) 00305 { 00306 if ((category & DEBUG_CATEGORY_APDU) 00307 && (LogCategory & DEBUG_CATEGORY_APDU)) 00308 log_xxd_always(PCSC_LOG_INFO, "APDU: ", buffer, len); 00309 00310 if ((category & DEBUG_CATEGORY_SW) 00311 && (LogCategory & DEBUG_CATEGORY_APDU)) 00312 log_xxd_always(PCSC_LOG_INFO, "SW: ", buffer, len); 00313 } 00314 00315 /* 00316 * old function supported for backward object code compatibility 00317 * defined only for pcscd 00318 */ 00319 #ifdef PCSCD 00320 void debug_msg(const char *fmt, ...); 00321 void debug_msg(const char *fmt, ...) 00322 { 00323 char DebugBuffer[DEBUG_BUF_SIZE]; 00324 va_list argptr; 00325 00326 if (DEBUGLOG_NO_DEBUG == LogMsgType) 00327 return; 00328 00329 va_start(argptr, fmt); 00330 vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr); 00331 va_end(argptr); 00332 00333 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00334 syslog(LOG_INFO, "%s", DebugBuffer); 00335 else 00336 puts(DebugBuffer); 00337 } /* debug_msg */ 00338 00339 void debug_xxd(const char *msg, const unsigned char *buffer, const int len); 00340 void debug_xxd(const char *msg, const unsigned char *buffer, const int len) 00341 { 00342 log_xxd(PCSC_LOG_ERROR, msg, buffer, len); 00343 } /* debug_xxd */ 00344 #endif 00345 00346 #endif /* NO_LOG */ 00347