pcsc-lite
1.7.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-2011 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: debuglog.c 5713 2011-05-05 09:25:14Z 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 00085 #define DEBUG_BUF_SIZE 2048 00086 00087 static char LogMsgType = DEBUGLOG_NO_DEBUG; 00088 static char LogCategory = DEBUG_CATEGORY_NOTHING; 00089 00091 static char LogLevel = PCSC_LOG_ERROR; 00092 00093 static signed char LogDoColor = 0; 00095 static void log_line(const int priority, const char *DebugBuffer); 00096 00097 void log_msg(const int priority, const char *fmt, ...) 00098 { 00099 char DebugBuffer[DEBUG_BUF_SIZE]; 00100 va_list argptr; 00101 00102 if ((priority < LogLevel) /* log priority lower than threshold? */ 00103 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 00104 return; 00105 00106 va_start(argptr, fmt); 00107 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr); 00108 va_end(argptr); 00109 00110 log_line(priority, DebugBuffer); 00111 } /* log_msg */ 00112 00113 static void log_line(const int priority, const char *DebugBuffer) 00114 { 00115 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) 00116 syslog(LOG_INFO, "%s", DebugBuffer); 00117 else 00118 { 00119 static struct timeval last_time = { 0, 0 }; 00120 struct timeval new_time = { 0, 0 }; 00121 struct timeval tmp; 00122 int delta; 00123 00124 gettimeofday(&new_time, NULL); 00125 if (0 == last_time.tv_sec) 00126 last_time = new_time; 00127 00128 tmp.tv_sec = new_time.tv_sec - last_time.tv_sec; 00129 tmp.tv_usec = new_time.tv_usec - last_time.tv_usec; 00130 if (tmp.tv_usec < 0) 00131 { 00132 tmp.tv_sec--; 00133 tmp.tv_usec += 1000000; 00134 } 00135 if (tmp.tv_sec < 100) 00136 delta = tmp.tv_sec * 1000000 + tmp.tv_usec; 00137 else 00138 delta = 99999999; 00139 00140 if (LogDoColor) 00141 { 00142 const char *color_pfx = "", *color_sfx = "\33[0m"; 00143 const char *time_pfx = "\33[36m", *time_sfx = color_sfx; 00144 00145 switch (priority) 00146 { 00147 case PCSC_LOG_CRITICAL: 00148 color_pfx = "\33[01;31m"; /* bright + Red */ 00149 break; 00150 00151 case PCSC_LOG_ERROR: 00152 color_pfx = "\33[35m"; /* Magenta */ 00153 break; 00154 00155 case PCSC_LOG_INFO: 00156 color_pfx = "\33[34m"; /* Blue */ 00157 break; 00158 00159 case PCSC_LOG_DEBUG: 00160 color_pfx = ""; /* normal (black) */ 00161 color_sfx = ""; 00162 break; 00163 } 00164 00165 printf("%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx, 00166 color_pfx, DebugBuffer, color_sfx); 00167 last_time = new_time; 00168 } 00169 else 00170 { 00171 printf("%.8d %s\n", delta, DebugBuffer); 00172 } 00173 } 00174 } /* log_msg */ 00175 00176 static void log_xxd_always(const int priority, const char *msg, 00177 const unsigned char *buffer, const int len) 00178 { 00179 char DebugBuffer[DEBUG_BUF_SIZE]; 00180 int i; 00181 char *c; 00182 char *debug_buf_end; 00183 00184 debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5; 00185 00186 strlcpy(DebugBuffer, msg, sizeof(DebugBuffer)); 00187 c = DebugBuffer + strlen(DebugBuffer); 00188 00189 for (i = 0; (i < len) && (c < debug_buf_end); ++i) 00190 { 00191 sprintf(c, "%02X ", buffer[i]); 00192 c += 3; 00193 } 00194 00195 /* the buffer is too small so end it with "..." */ 00196 if ((c >= debug_buf_end) && (i < len)) 00197 c[-3] = c[-2] = c[-1] = '.'; 00198 00199 log_line(priority, DebugBuffer); 00200 } /* log_xxd_always */ 00201 00202 void log_xxd(const int priority, const char *msg, const unsigned char *buffer, 00203 const int len) 00204 { 00205 if ((priority < LogLevel) /* log priority lower than threshold? */ 00206 || (DEBUGLOG_NO_DEBUG == LogMsgType)) 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" }; 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, DEBUG_BUF_SIZE, 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