Added pwmd_disconnect() to close the connection without freeing the
[libpwmd.git] / assuan / assuan-logging.c
blob2ebd6678f89be101806aabaa88d43ed7e0310612
1 /* assuan-logging.c - Default logging function.
2 * Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
4 * This file is part of Assuan.
6 * Assuan is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * Assuan is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #ifdef HAVE_W32_SYSTEM
28 #include <windows.h>
29 #endif /*HAVE_W32_SYSTEM*/
30 #include <errno.h>
31 #include <ctype.h>
33 #include "assuan-defs.h"
35 static char prefix_buffer[80];
36 static FILE *_assuan_log;
37 static int full_logging;
39 void
40 _assuan_set_default_log_stream (FILE *fp)
42 if (!_assuan_log)
44 _assuan_log = fp;
45 full_logging = !!getenv ("ASSUAN_FULL_LOGGING");
49 void
50 assuan_set_assuan_log_stream (FILE *fp)
52 _assuan_log = fp;
56 /* Set the per context log stream. Also enable the default log stream
57 if it has not been set. */
58 void
59 assuan_set_log_stream (assuan_context_t ctx, FILE *fp)
61 if (ctx)
63 if (ctx->log_fp)
64 fflush (ctx->log_fp);
65 ctx->log_fp = fp;
66 _assuan_set_default_log_stream (fp);
71 FILE *
72 assuan_get_assuan_log_stream (void)
74 return _assuan_log ? _assuan_log : stderr;
78 /* Set the prefix to be used for logging to TEXT or
79 resets it to the default if TEXT is NULL. */
80 void
81 assuan_set_assuan_log_prefix (const char *text)
83 if (text)
85 strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
86 prefix_buffer[sizeof (prefix_buffer)-1] = 0;
88 else
89 *prefix_buffer = 0;
92 const char *
93 assuan_get_assuan_log_prefix (void)
95 return prefix_buffer;
99 void
100 _assuan_log_printf (const char *format, ...)
102 va_list arg_ptr;
103 FILE *fp;
104 const char *prf;
105 int save_errno = errno;
107 fp = assuan_get_assuan_log_stream ();
108 prf = assuan_get_assuan_log_prefix ();
109 if (*prf)
110 fprintf (fp, "%s[%u]: ", prf, (unsigned int)getpid ());
112 va_start (arg_ptr, format);
113 vfprintf (fp, format, arg_ptr );
114 va_end (arg_ptr);
115 /* If the log stream is a file, the output would be buffered. This
116 is bad for debugging, thus we flush the stream if FORMAT ends
117 with a LF. */
118 if (format && *format && format[strlen(format)-1] == '\n')
119 fflush (fp);
120 errno = save_errno;
124 /* Dump a possibly binary string (used for debugging). Distinguish
125 ascii text from binary and print it accordingly. This function
126 takes FILE pointer arg because logging may be enabled on a per
127 context basis. */
128 void
129 _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
131 const unsigned char *s;
132 unsigned int n;
134 for (n = length, s = buffer; n; n--, s++)
135 if ((! isascii (*s) || iscntrl (*s) || ! isprint (*s)) && !(*s >= 0x80))
136 break;
138 s = buffer;
139 if (! n && *s != '[')
140 fwrite (buffer, length, 1, fp);
141 else
143 #ifdef HAVE_FLOCKFILE
144 flockfile (fp);
145 #endif
146 putc_unlocked ('[', fp);
147 if (length > 16 && ! full_logging)
149 for (n = 0; n < 12; n++, s++)
150 fprintf (fp, " %02x", *s);
151 fprintf (fp, " ...(%d bytes skipped)", (int) length - 12);
153 else
155 for (n = 0; n < length; n++, s++)
156 fprintf (fp, " %02x", *s);
158 putc_unlocked (' ', fp);
159 putc_unlocked (']', fp);
160 #ifdef HAVE_FUNLOCKFILE
161 funlockfile (fp);
162 #endif
166 /* Log a user supplied string. Escapes non-printable before
167 printing. */
168 void
169 _assuan_log_sanitized_string (const char *string)
171 const unsigned char *s = (const unsigned char *) string;
172 FILE *fp = assuan_get_assuan_log_stream ();
174 if (! *s)
175 return;
177 #ifdef HAVE_FLOCKFILE
178 flockfile (fp);
179 #endif
181 for (; *s; s++)
183 int c = 0;
185 switch (*s)
187 case '\r':
188 c = 'r';
189 break;
191 case '\n':
192 c = 'n';
193 break;
195 case '\f':
196 c = 'f';
197 break;
199 case '\v':
200 c = 'v';
201 break;
203 case '\b':
204 c = 'b';
205 break;
207 default:
208 if ((isascii (*s) && isprint (*s)) || (*s >= 0x80))
209 putc_unlocked (*s, fp);
210 else
212 putc_unlocked ('\\', fp);
213 fprintf (fp, "x%02x", *s);
217 if (c)
219 putc_unlocked ('\\', fp);
220 putc_unlocked (c, fp);
224 #ifdef HAVE_FUNLOCKFILE
225 funlockfile (fp);
226 #endif
231 #ifdef HAVE_W32_SYSTEM
232 const char *
233 _assuan_w32_strerror (int ec)
235 static char strerr[256];
237 if (ec == -1)
238 ec = (int)GetLastError ();
239 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
240 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
241 strerr, sizeof (strerr)-1, NULL);
242 return strerr;
245 static int (*my_strerror_r) (unsigned int err, char *buf, size_t buflen);
246 static const char * (*my_strsource) (unsigned int err);
248 static int
249 load_libgpg_error (void)
251 /* This code is not race free but suitable for our purpose. */
252 static volatile int initialized;
253 void *handle;
255 if (initialized)
256 return (my_strerror_r && my_strsource)? 0:-1;
257 handle = LoadLibrary ("libgpg-error-0.dll");
258 if (handle)
260 void *foo, *bar;
261 foo = GetProcAddress (handle, "gpg_strerror_r");
262 bar = GetProcAddress (handle, "gpg_strsource");
263 if (foo && bar)
265 my_strerror_r = foo;
266 my_strsource = bar;
268 else
269 CloseHandle (handle);
271 initialized = 1;
272 return 0;
276 _assuan_gpg_strerror_r (unsigned int err, char *buf, size_t buflen)
278 if (load_libgpg_error ())
279 return -1;
280 return my_strerror_r (err, buf, buflen);
284 const char *
285 _assuan_gpg_strsource (unsigned int err)
287 if (load_libgpg_error ())
288 return NULL;
289 return my_strsource (err);
291 #endif /*HAVE_W32_SYSTEM*/