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 #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 DebugLogSuppress(const int lSType)
00055 {
00056 (void)lSType;
00057 }
00058
00059 void DebugLogSetLogType(const int dbgtype)
00060 {
00061 (void)dbgtype;
00062 }
00063
00064 void DebugLogSetLevel(const int level)
00065 {
00066 (void)level;
00067 }
00068
00069 INTERNAL int DebugLogSetCategory(const int dbginfo)
00070 {
00071 (void)dbginfo;
00072
00073 return 0;
00074 }
00075
00076 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00077 const int len)
00078 {
00079 (void)category;
00080 (void)buffer;
00081 (void)len;
00082 }
00083
00084 #else
00085
00090 #define DEBUG_BUF_SIZE 2048
00091
00092 static char LogSuppress = DEBUGLOG_LOG_ENTRIES;
00093 static char LogMsgType = DEBUGLOG_NO_DEBUG;
00094 static char LogCategory = DEBUG_CATEGORY_NOTHING;
00095
00097 static char LogLevel = PCSC_LOG_ERROR;
00098
00099 static signed char LogDoColor = 0;
00101 static void log_line(const int priority, const char *DebugBuffer);
00102
00103 void log_msg(const int priority, const char *fmt, ...)
00104 {
00105 char DebugBuffer[DEBUG_BUF_SIZE];
00106 va_list argptr;
00107
00108 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00109 || (priority < LogLevel)
00110 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00111 return;
00112
00113 va_start(argptr, fmt);
00114 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00115 va_end(argptr);
00116
00117 log_line(priority, DebugBuffer);
00118 }
00119
00120 static void log_line(const int priority, const char *DebugBuffer)
00121 {
00122 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00123 syslog(LOG_INFO, "%s", DebugBuffer);
00124 else
00125 {
00126 if (LogDoColor)
00127 {
00128 const char *color_pfx = "", *color_sfx = "\33[0m";
00129 const char *time_pfx = "\33[36m", *time_sfx = color_sfx;
00130 static struct timeval last_time = { 0, 0 };
00131 struct timeval new_time = { 0, 0 };
00132 struct timeval tmp;
00133 int delta;
00134
00135 switch (priority)
00136 {
00137 case PCSC_LOG_CRITICAL:
00138 color_pfx = "\33[01;31m";
00139 break;
00140
00141 case PCSC_LOG_ERROR:
00142 color_pfx = "\33[35m";
00143 break;
00144
00145 case PCSC_LOG_INFO:
00146 color_pfx = "\33[34m";
00147 break;
00148
00149 case PCSC_LOG_DEBUG:
00150 color_pfx = "";
00151 color_sfx = "";
00152 break;
00153 }
00154
00155 gettimeofday(&new_time, NULL);
00156 if (0 == last_time.tv_sec)
00157 last_time = new_time;
00158
00159 tmp.tv_sec = new_time.tv_sec - last_time.tv_sec;
00160 tmp.tv_usec = new_time.tv_usec - last_time.tv_usec;
00161 if (tmp.tv_usec < 0)
00162 {
00163 tmp.tv_sec--;
00164 tmp.tv_usec += 1000000;
00165 }
00166 if (tmp.tv_sec < 100)
00167 delta = tmp.tv_sec * 1000000 + tmp.tv_usec;
00168 else
00169 delta = 99999999;
00170
00171 fprintf(stderr, "%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx,
00172 color_pfx, DebugBuffer, color_sfx);
00173 last_time = new_time;
00174 }
00175 else
00176 fprintf(stderr, "%s\n", DebugBuffer);
00177 }
00178 }
00179
00180 static void log_xxd_always(const int priority, const char *msg,
00181 const unsigned char *buffer, const int len)
00182 {
00183 char DebugBuffer[DEBUG_BUF_SIZE];
00184 int i;
00185 char *c;
00186 char *debug_buf_end;
00187
00188 debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
00189
00190 strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
00191 c = DebugBuffer + strlen(DebugBuffer);
00192
00193 for (i = 0; (i < len) && (c < debug_buf_end); ++i)
00194 {
00195 sprintf(c, "%02X ", buffer[i]);
00196 c += 3;
00197 }
00198
00199
00200 if ((c >= debug_buf_end) && (i < len))
00201 c[-3] = c[-2] = c[-1] = '.';
00202
00203 log_line(priority, DebugBuffer);
00204 }
00205
00206 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
00207 const int len)
00208 {
00209 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00210 || (priority < LogLevel)
00211 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00212 return;
00213
00214 log_xxd_always(priority, msg, buffer, len);
00215 }
00216
00217 void DebugLogSuppress(const int lSType)
00218 {
00219 LogSuppress = lSType;
00220 }
00221
00222 void DebugLogSetLogType(const int dbgtype)
00223 {
00224 switch (dbgtype)
00225 {
00226 case DEBUGLOG_NO_DEBUG:
00227 case DEBUGLOG_SYSLOG_DEBUG:
00228 case DEBUGLOG_STDERR_DEBUG:
00229 LogMsgType = dbgtype;
00230 break;
00231 default:
00232 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00233 dbgtype);
00234 LogMsgType = DEBUGLOG_STDERR_DEBUG;
00235 }
00236
00237
00238 if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00239 {
00240 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00241 char *term;
00242
00243 term = getenv("TERM");
00244 if (term)
00245 {
00246 unsigned int i;
00247
00248
00249 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00250 {
00251
00252 if (0 == strcmp(terms[i], term))
00253 {
00254 LogDoColor = 1;
00255 break;
00256 }
00257 }
00258 }
00259 }
00260 }
00261
00262 void DebugLogSetLevel(const int level)
00263 {
00264 LogLevel = level;
00265 switch (level)
00266 {
00267 case PCSC_LOG_CRITICAL:
00268 case PCSC_LOG_ERROR:
00269
00270 break;
00271
00272 case PCSC_LOG_INFO:
00273 Log1(PCSC_LOG_INFO, "debug level=notice");
00274 break;
00275
00276 case PCSC_LOG_DEBUG:
00277 Log1(PCSC_LOG_DEBUG, "debug level=debug");
00278 break;
00279
00280 default:
00281 LogLevel = PCSC_LOG_INFO;
00282 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00283 level);
00284 }
00285 }
00286
00287 INTERNAL int DebugLogSetCategory(const int dbginfo)
00288 {
00289 #define DEBUG_INFO_LENGTH 80
00290 char text[DEBUG_INFO_LENGTH];
00291
00292
00293
00294
00295 if (dbginfo < 0)
00296 LogCategory &= dbginfo;
00297 else
00298 LogCategory |= dbginfo;
00299
00300
00301 text[0] = '\0';
00302
00303 if (LogCategory & DEBUG_CATEGORY_APDU)
00304 strlcat(text, " APDU", sizeof(text));
00305
00306 Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00307
00308 return LogCategory;
00309 }
00310
00311 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00312 const int len)
00313 {
00314 if ((category & DEBUG_CATEGORY_APDU)
00315 && (LogCategory & DEBUG_CATEGORY_APDU))
00316 log_xxd_always(PCSC_LOG_INFO, "APDU: ", buffer, len);
00317
00318 if ((category & DEBUG_CATEGORY_SW)
00319 && (LogCategory & DEBUG_CATEGORY_APDU))
00320 log_xxd_always(PCSC_LOG_INFO, "SW: ", buffer, len);
00321 }
00322
00323
00324
00325
00326
00327 #ifdef PCSCD
00328 void debug_msg(const char *fmt, ...);
00329 void debug_msg(const char *fmt, ...)
00330 {
00331 char DebugBuffer[DEBUG_BUF_SIZE];
00332 va_list argptr;
00333
00334 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00335 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00336 return;
00337
00338 va_start(argptr, fmt);
00339 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00340 va_end(argptr);
00341
00342 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00343 syslog(LOG_INFO, "%s", DebugBuffer);
00344 else
00345 fprintf(stderr, "%s\n", DebugBuffer);
00346 }
00347
00348 void debug_xxd(const char *msg, const unsigned char *buffer, const int len);
00349 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00350 {
00351 log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00352 }
00353 #endif
00354
00355 #endif
00356