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 += strlen(c);
00132 }
00133
00134 #ifndef WIN32
00135 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00136 syslog(LOG_INFO, "%s", DebugBuffer);
00137 else
00138 #endif
00139 fprintf(stderr, "%s\n", DebugBuffer);
00140 }
00141
00142 #ifdef PCSCD
00143 void DebugLogSuppress(const int lSType)
00144 {
00145 LogSuppress = lSType;
00146 }
00147 #endif
00148
00149 void DebugLogSetLogType(const int dbgtype)
00150 {
00151 switch (dbgtype)
00152 {
00153 case DEBUGLOG_NO_DEBUG:
00154 case DEBUGLOG_SYSLOG_DEBUG:
00155 case DEBUGLOG_STDERR_DEBUG:
00156 LogMsgType = dbgtype;
00157 break;
00158 default:
00159 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00160 dbgtype);
00161 LogMsgType = DEBUGLOG_STDERR_DEBUG;
00162 }
00163
00164
00165 #ifndef WIN32
00166
00167 if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00168 {
00169 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00170 char *term;
00171
00172 term = getenv("TERM");
00173 if (term)
00174 {
00175 int i;
00176
00177
00178 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00179 {
00180
00181 if (0 == strcmp(terms[i], term))
00182 {
00183 LogDoColor = 1;
00184 break;
00185 }
00186 }
00187 }
00188 }
00189 #endif
00190 }
00191
00192 void DebugLogSetLevel(const int level)
00193 {
00194 LogLevel = level;
00195 switch (level)
00196 {
00197 case PCSC_LOG_CRITICAL:
00198 case PCSC_LOG_ERROR:
00199
00200 break;
00201
00202 case PCSC_LOG_INFO:
00203 Log1(PCSC_LOG_INFO, "debug level=notice");
00204 break;
00205
00206 case PCSC_LOG_DEBUG:
00207 Log1(PCSC_LOG_DEBUG, "debug level=debug");
00208 break;
00209
00210 default:
00211 LogLevel = PCSC_LOG_INFO;
00212 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00213 level);
00214 }
00215 }
00216
00217 INTERNAL int DebugLogSetCategory(const int dbginfo)
00218 {
00219 #define DEBUG_INFO_LENGTH 80
00220 char text[DEBUG_INFO_LENGTH];
00221
00222
00223
00224
00225 if (dbginfo < 0)
00226 LogCategory &= dbginfo;
00227 else
00228 LogCategory |= dbginfo;
00229
00230
00231 text[0] = '\0';
00232
00233 if (LogCategory & DEBUG_CATEGORY_APDU)
00234 strlcat(text, " APDU", sizeof(text));
00235
00236 Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00237
00238 return LogCategory;
00239 }
00240
00241 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00242 const int len)
00243 {
00244 if ((category & DEBUG_CATEGORY_APDU)
00245 && (LogCategory & DEBUG_CATEGORY_APDU))
00246 log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00247
00248 if ((category & DEBUG_CATEGORY_SW)
00249 && (LogCategory & DEBUG_CATEGORY_APDU))
00250 log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00251 }
00252
00253
00254
00255
00256
00257 #ifdef PCSCD
00258 void debug_msg(const char *fmt, ...)
00259 {
00260 char DebugBuffer[DEBUG_BUF_SIZE];
00261 va_list argptr;
00262
00263 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00264 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00265 return;
00266
00267 va_start(argptr, fmt);
00268 #ifndef WIN32
00269 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00270 #else
00271 #if HAVE_VSNPRINTF
00272 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00273 #else
00274 vsprintf(DebugBuffer, fmt, argptr);
00275 #endif
00276 #endif
00277 va_end(argptr);
00278
00279 #ifndef WIN32
00280 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00281 syslog(LOG_INFO, "%s", DebugBuffer);
00282 else
00283 #endif
00284 fprintf(stderr, "%s\n", DebugBuffer);
00285 }
00286
00287 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00288 {
00289 log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00290 }
00291 #endif
00292