Initial commit
[platform/upstream/ccid.git] / src / debug.c
1 /*
2     debug.c: log (or not) messages
3     Copyright (C) 2003-2011   Ludovic Rousseau
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15         You should have received a copy of the GNU Lesser General Public License
16         along with this library; if not, write to the Free Software Foundation,
17         Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <config.h>
21 #include "misc.h"
22 #include "debug.h"
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <sys/time.h>
28 #include <stdlib.h>
29
30 #ifdef USE_SYSLOG
31 #include <syslog.h>
32 #endif
33
34 #include "strlcpycat.h"
35
36 #undef LOG_TO_STDERR
37
38 #ifdef LOG_TO_STDERR
39 #define LOG_STREAM stderr
40 #else
41 #define LOG_STREAM stdout
42 #endif
43
44 #ifdef USE_OS_LOG
45
46 void log_msg(const int priority, const char *fmt, ...)
47 {
48         char debug_buffer[3 * 80]; /* up to 3 lines of 80 characters */
49         va_list argptr;
50         int os_log_type;
51
52         switch(priority)
53         {
54                 case PCSC_LOG_CRITICAL:
55                         os_log_type = OS_LOG_TYPE_FAULT;
56                         break;
57                 case PCSC_LOG_ERROR:
58                         os_log_type = OS_LOG_TYPE_ERROR;
59                         break;
60                 case PCSC_LOG_INFO:
61                         os_log_type = OS_LOG_TYPE_INFO;
62                         break;
63                 default:
64                         os_log_type = OS_LOG_TYPE_DEBUG;
65         }
66
67         va_start(argptr, fmt);
68         (void)vsnprintf(debug_buffer, sizeof debug_buffer, fmt, argptr);
69         va_end(argptr);
70
71         os_log_with_type(OS_LOG_DEFAULT, os_log_type, "%s", debug_buffer);
72 } /* log_msg */
73
74 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
75         const int len)
76 {
77         int i;
78         char *c, debug_buffer[len*3 + strlen(msg) +1];
79         size_t l;
80
81         (void)priority;
82
83         l = strlcpy(debug_buffer, msg, sizeof debug_buffer);
84         c = debug_buffer + l;
85
86         for (i = 0; i < len; ++i)
87         {
88                 /* 2 hex characters, 1 space, 1 NUL : total 4 characters */
89                 (void)snprintf(c, 4, "%02X ", buffer[i]);
90                 c += 3;
91         }
92
93         os_log(OS_LOG_DEFAULT, "%s", debug_buffer);
94 } /* log_xxd */
95
96 #else
97
98 void log_msg(const int priority, const char *fmt, ...)
99 {
100         char debug_buffer[3 * 80]; /* up to 3 lines of 80 characters */
101         va_list argptr;
102         static struct timeval last_time = { 0, 0 };
103         struct timeval new_time = { 0, 0 };
104         struct timeval tmp;
105         int delta;
106 #ifdef USE_SYSLOG
107         int syslog_level;
108
109         switch(priority)
110         {
111                 case PCSC_LOG_CRITICAL:
112                         syslog_level = LOG_CRIT;
113                         break;
114                 case PCSC_LOG_ERROR:
115                         syslog_level = LOG_ERR;
116                         break;
117                 case PCSC_LOG_INFO:
118                         syslog_level = LOG_INFO;
119                         break;
120                 default:
121                         syslog_level = LOG_DEBUG;
122         }
123 #else
124         const char *color_pfx = "", *color_sfx = "";
125         const char *time_pfx = "", *time_sfx = "";
126         static int initialized = 0;
127         static int LogDoColor = 0;
128
129         if (!initialized)
130         {
131                 char *term;
132
133                 initialized = 1;
134                 term = getenv("TERM");
135                 if (term)
136                 {
137                         const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode", "xterm-256color" };
138                         unsigned int i;
139
140                         /* for each known color terminal */
141                         for (i = 0; i < COUNT_OF(terms); i++)
142                         {
143                                 /* we found a supported term? */
144                                 if (0 == strcmp(terms[i], term))
145                                 {
146                                         LogDoColor = 1;
147                                         break;
148                                 }
149                         }
150                 }
151         }
152
153         if (LogDoColor)
154         {
155                 color_sfx = "\33[0m";
156                 time_sfx = color_sfx;
157                 time_pfx = "\33[36m"; /* Cyan */
158
159                 switch (priority)
160                 {
161                         case PCSC_LOG_CRITICAL:
162                                 color_pfx = "\33[01;31m"; /* bright + Red */
163                                 break;
164
165                         case PCSC_LOG_ERROR:
166                                 color_pfx = "\33[35m"; /* Magenta */
167                                 break;
168
169                         case PCSC_LOG_INFO:
170                                 color_pfx = "\33[34m"; /* Blue */
171                                 break;
172
173                         case PCSC_LOG_DEBUG:
174                                 color_pfx = ""; /* normal (black) */
175                                 color_sfx = "";
176                                 break;
177                 }
178         }
179 #endif
180
181         gettimeofday(&new_time, NULL);
182         if (0 == last_time.tv_sec)
183                 last_time = new_time;
184
185         tmp.tv_sec = new_time.tv_sec - last_time.tv_sec;
186         tmp.tv_usec = new_time.tv_usec - last_time.tv_usec;
187         if (tmp.tv_usec < 0)
188         {
189                 tmp.tv_sec--;
190                 tmp.tv_usec += 1000000;
191         }
192         if (tmp.tv_sec < 100)
193                 delta = tmp.tv_sec * 1000000 + tmp.tv_usec;
194         else
195                 delta = 99999999;
196
197         last_time = new_time;
198
199         va_start(argptr, fmt);
200         (void)vsnprintf(debug_buffer, sizeof debug_buffer, fmt, argptr);
201         va_end(argptr);
202
203 #ifdef USE_SYSLOG
204         syslog(syslog_level, "%.8d %s", delta, debug_buffer);
205 #else
206         (void)fprintf(LOG_STREAM, "%s%.8d%s %s%s%s\n", time_pfx, delta, time_sfx,
207                 color_pfx, debug_buffer, color_sfx);
208         fflush(LOG_STREAM);
209 #endif
210 } /* log_msg */
211
212 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
213         const int len)
214 {
215         int i;
216         char *c, debug_buffer[len*3 + strlen(msg) +1];
217         size_t l;
218
219         (void)priority;
220
221         l = strlcpy(debug_buffer, msg, sizeof debug_buffer);
222         c = debug_buffer + l;
223
224         for (i = 0; i < len; ++i)
225         {
226                 /* 2 hex characters, 1 space, 1 NUL : total 4 characters */
227                 (void)snprintf(c, 4, "%02X ", buffer[i]);
228                 c += 3;
229         }
230
231 #ifdef USE_SYSLOG
232         syslog(LOG_DEBUG, "%s", debug_buffer);
233 #else
234         (void)fprintf(LOG_STREAM, "%s\n", debug_buffer);
235         fflush(LOG_STREAM);
236 #endif
237 } /* log_xxd */
238
239 #endif
240