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