00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00046 static char LogLevel = PCSC_LOG_INFO;
00047
00048 static signed char LogDoColor = 0;
00049
00050 static void log_line(const int priority, const char *DebugBuffer);
00051
00052 void log_msg(const int priority, const char *fmt, ...)
00053 {
00054 char DebugBuffer[DEBUG_BUF_SIZE];
00055 va_list argptr;
00056
00057 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00058 || (priority < LogLevel)
00059 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00060 return;
00061
00062 va_start(argptr, fmt);
00063 #ifndef WIN32
00064 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00065 #else
00066 #if HAVE_VSNPRINTF
00067 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00068 #else
00069 vsprintf(DebugBuffer, fmt, argptr);
00070 #endif
00071 #endif
00072 va_end(argptr);
00073
00074 log_line(priority, DebugBuffer);
00075 }
00076
00077 static void log_line(const int priority, const char *DebugBuffer)
00078 {
00079 #ifndef WIN32
00080 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00081 syslog(LOG_INFO, "%s", DebugBuffer);
00082 else
00083 {
00084 if (LogDoColor)
00085 {
00086 const char *color_pfx = "", *color_sfx = "\33[0m";
00087
00088 switch (priority)
00089 {
00090 case PCSC_LOG_CRITICAL:
00091 color_pfx = "\33[01;31m";
00092 break;
00093
00094 case PCSC_LOG_ERROR:
00095 color_pfx = "\33[35m";
00096 break;
00097
00098 case PCSC_LOG_INFO:
00099 color_pfx = "\33[34m";
00100 break;
00101
00102 case PCSC_LOG_DEBUG:
00103 color_pfx = "";
00104 color_sfx = "";
00105 break;
00106 }
00107 fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
00108 }
00109 else
00110 fprintf(stderr, "%s\n", DebugBuffer);
00111 }
00112 #else
00113 fprintf(stderr, "%s\n", DebugBuffer);
00114 #endif
00115 }
00116
00117 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
00118 const int len)
00119 {
00120 char DebugBuffer[DEBUG_BUF_SIZE];
00121 int i;
00122 char *c;
00123 char *debug_buf_end;
00124
00125 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00126 || (priority < LogLevel)
00127 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00128 return;
00129
00130 debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
00131
00132 strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
00133 c = DebugBuffer + strlen(DebugBuffer);
00134
00135 for (i = 0; (i < len) && (c < debug_buf_end); ++i)
00136 {
00137 sprintf(c, "%02X ", buffer[i]);
00138 c += 3;
00139 }
00140
00141
00142 if ((c >= debug_buf_end) && (i < len))
00143 c[-3] = c[-2] = c[-1] = '.';
00144
00145 log_line(priority, DebugBuffer);
00146 }
00147
00148 #ifdef PCSCD
00149 void DebugLogSuppress(const int lSType)
00150 {
00151 LogSuppress = lSType;
00152 }
00153 #endif
00154
00155 void DebugLogSetLogType(const int dbgtype)
00156 {
00157 switch (dbgtype)
00158 {
00159 case DEBUGLOG_NO_DEBUG:
00160 case DEBUGLOG_SYSLOG_DEBUG:
00161 case DEBUGLOG_STDERR_DEBUG:
00162 LogMsgType = dbgtype;
00163 break;
00164 default:
00165 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00166 dbgtype);
00167 LogMsgType = DEBUGLOG_STDERR_DEBUG;
00168 }
00169
00170
00171 #ifndef WIN32
00172
00173 if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00174 {
00175 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00176 char *term;
00177
00178 term = getenv("TERM");
00179 if (term)
00180 {
00181 unsigned int i;
00182
00183
00184 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00185 {
00186
00187 if (0 == strcmp(terms[i], term))
00188 {
00189 LogDoColor = 1;
00190 break;
00191 }
00192 }
00193 }
00194 }
00195 #endif
00196 }
00197
00198 void DebugLogSetLevel(const int level)
00199 {
00200 LogLevel = level;
00201 switch (level)
00202 {
00203 case PCSC_LOG_CRITICAL:
00204 case PCSC_LOG_ERROR:
00205
00206 break;
00207
00208 case PCSC_LOG_INFO:
00209 Log1(PCSC_LOG_INFO, "debug level=notice");
00210 break;
00211
00212 case PCSC_LOG_DEBUG:
00213 Log1(PCSC_LOG_DEBUG, "debug level=debug");
00214 break;
00215
00216 default:
00217 LogLevel = PCSC_LOG_INFO;
00218 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00219 level);
00220 }
00221 }
00222
00223 INTERNAL int DebugLogSetCategory(const int dbginfo)
00224 {
00225 #define DEBUG_INFO_LENGTH 80
00226 char text[DEBUG_INFO_LENGTH];
00227
00228
00229
00230
00231 if (dbginfo < 0)
00232 LogCategory &= dbginfo;
00233 else
00234 LogCategory |= dbginfo;
00235
00236
00237 text[0] = '\0';
00238
00239 if (LogCategory & DEBUG_CATEGORY_APDU)
00240 strlcat(text, " APDU", sizeof(text));
00241
00242 Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00243
00244 return LogCategory;
00245 }
00246
00247 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00248 const int len)
00249 {
00250 if ((category & DEBUG_CATEGORY_APDU)
00251 && (LogCategory & DEBUG_CATEGORY_APDU))
00252 log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00253
00254 if ((category & DEBUG_CATEGORY_SW)
00255 && (LogCategory & DEBUG_CATEGORY_APDU))
00256 log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00257 }
00258
00259
00260
00261
00262
00263 #ifdef PCSCD
00264 void debug_msg(const char *fmt, ...);
00265 void debug_msg(const char *fmt, ...)
00266 {
00267 char DebugBuffer[DEBUG_BUF_SIZE];
00268 va_list argptr;
00269
00270 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00271 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00272 return;
00273
00274 va_start(argptr, fmt);
00275 #ifndef WIN32
00276 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00277 #else
00278 #if HAVE_VSNPRINTF
00279 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00280 #else
00281 vsprintf(DebugBuffer, fmt, argptr);
00282 #endif
00283 #endif
00284 va_end(argptr);
00285
00286 #ifndef WIN32
00287 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00288 syslog(LOG_INFO, "%s", DebugBuffer);
00289 else
00290 #endif
00291 fprintf(stderr, "%s\n", DebugBuffer);
00292 }
00293
00294 void debug_xxd(const char *msg, const unsigned char *buffer, const int len);
00295 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00296 {
00297 log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00298 }
00299 #endif
00300