diff options
Diffstat (limited to '')
-rw-r--r-- | assuan/assuan-logging.c | 143 |
1 files changed, 136 insertions, 7 deletions
diff --git a/assuan/assuan-logging.c b/assuan/assuan-logging.c index 7c65d579..cfc3d846 100644 --- a/assuan/assuan-logging.c +++ b/assuan/assuan-logging.c @@ -15,29 +15,37 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <stdarg.h> #ifdef HAVE_W32_SYSTEM #include <windows.h> #endif /*HAVE_W32_SYSTEM*/ +#include <errno.h> +#include <ctype.h> #include "assuan-defs.h" static char prefix_buffer[80]; static FILE *_assuan_log; +static int full_logging; void _assuan_set_default_log_stream (FILE *fp) { if (!_assuan_log) - _assuan_log = fp; + { + _assuan_log = fp; + full_logging = !!getenv ("ASSUAN_FULL_LOGGING"); + } } void @@ -46,6 +54,22 @@ assuan_set_assuan_log_stream (FILE *fp) _assuan_log = fp; } + +/* Set the per context log stream. Also enable the default log stream + if it has not been set. */ +void +assuan_set_log_stream (assuan_context_t ctx, FILE *fp) +{ + if (ctx) + { + if (ctx->log_fp) + fflush (ctx->log_fp); + ctx->log_fp = fp; + _assuan_set_default_log_stream (fp); + } +} + + FILE * assuan_get_assuan_log_stream (void) { @@ -80,18 +104,123 @@ _assuan_log_printf (const char *format, ...) va_list arg_ptr; FILE *fp; const char *prf; - + int save_errno = errno; + fp = assuan_get_assuan_log_stream (); prf = assuan_get_assuan_log_prefix (); if (*prf) - { - fputs (prf, fp); - fputs (": ", fp); - } + fprintf (fp, "%s[%u]: ", prf, (unsigned int)getpid ()); va_start (arg_ptr, format); vfprintf (fp, format, arg_ptr ); va_end (arg_ptr); + errno = save_errno; +} + + +/* Dump a possibly binary string (used for debugging). Distinguish + ascii text from binary and print it accordingly. This function + takes FILE pointer arg becuase logging may be enabled on a per + context basis. */ +void +_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) +{ + const unsigned char *s; + int n; + + for (n=length,s=buffer; n; n--, s++) + if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80)) + break; + + s = buffer; + if (!n && *s != '[') + fwrite (buffer, length, 1, fp); + else + { +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + putc_unlocked ('[', fp); + if ( length > 16 && !full_logging) + { + for (n=0; n < 12; n++, s++) + fprintf (fp, " %02x", *s); + fprintf (fp, " ...(%d bytes skipped)", (int)length - 12); + } + else + { + for (n=0; n < length; n++, s++) + fprintf (fp, " %02x", *s); + } + putc_unlocked (' ', fp); + putc_unlocked (']', fp); +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif + } +} + +/* Log a user supplied string. Escapes non-printable before + printing. */ +void +_assuan_log_sanitized_string (const char *string) +{ + const unsigned char *s = (const unsigned char *) string; + FILE *fp = assuan_get_assuan_log_stream (); + + if (! *s) + return; + +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + + for (; *s; s++) + { + int c = 0; + + switch (*s) + { + case '\r': + c = 'r'; + break; + + case '\n': + c = 'n'; + break; + + case '\f': + c = 'f'; + break; + + case '\v': + c = 'v'; + break; + + case '\b': + c = 'b'; + break; + + default: + if ((isascii (*s) && isprint (*s)) || (*s >= 0x80)) + putc_unlocked (*s, fp); + else + { + putc_unlocked ('\\', fp); + fprintf (fp, "x%02x", *s); + } + } + + if (c) + { + putc_unlocked ('\\', fp); + putc_unlocked (c, fp); + } + } + +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif } |