diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/ChangeLog | 10 | ||||
-rw-r--r-- | src/assuan-defs.h | 6 | ||||
-rw-r--r-- | src/assuan-logging.c | 130 | ||||
-rw-r--r-- | src/assuan-util.c | 107 | ||||
-rw-r--r-- | src/assuan.h | 5 | ||||
-rw-r--r-- | tests/fdpassing.c | 55 |
7 files changed, 201 insertions, 115 deletions
@@ -13,6 +13,9 @@ Noteworthy changes in version 0.9.0 If the new macro _ASSUAN_ONLY_GPG_ERRORS is defned all old definitions are excluded from assuan.h. + * Logging of hex strings is now limited to 16 bytes. To enable + printing of the full data, a new environment variable + ASSUAN_FULL_LOGGING may be set to any value. Noteworthy changes in version 0.6.10 (2005-06-20) ------------------------------------------------- diff --git a/src/ChangeLog b/src/ChangeLog index 7740e0e..77649e6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2006-09-10 Werner Koch <wk@g10code.com> + + * assuan-util.c (_assuan_log_print_buffer) + (_assuan_log_sanitized_string,assuan_set_log_stream): Moved to .. + * assuan-logging.c: .. here. + (_assuan_log_print_buffer): Only print the leading bytes in hex + log mode unless the new env variable ASSUAN_FULL_LOGGING has been + set. + (_assuan_set_default_log_stream): Test this env variable. + 2006-09-06 Werner Koch <wk@g10code.com> * assuan.h (_ASSUAN_ONLY_GPG_ERRORS): New. diff --git a/src/assuan-defs.h b/src/assuan-defs.h index 11f4cfd..e6bacf5 100644 --- a/src/assuan-defs.h +++ b/src/assuan-defs.h @@ -237,9 +237,6 @@ void _assuan_free (void *p); #define set_error(c,e,t) \ assuan_set_error ((c), _assuan_error (ASSUAN_ ## e), (t)) -void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); -void _assuan_log_sanitized_string (const char *string); - #ifdef HAVE_W32_SYSTEM const char *_assuan_w32_strerror (int ec); #define w32_strerror(e) _assuan_w32_strerror ((e)) @@ -254,6 +251,9 @@ void _assuan_log_printf (const char *format, ...) __attribute__ ((format (printf,1,2))) #endif ; +void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); +void _assuan_log_sanitized_string (const char *string); + /*-- assuan-io.c --*/ ssize_t _assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size); diff --git a/src/assuan-logging.c b/src/assuan-logging.c index 665efa9..cfc3d84 100644 --- a/src/assuan-logging.c +++ b/src/assuan-logging.c @@ -23,23 +23,29 @@ #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 @@ -48,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) { @@ -96,6 +118,112 @@ _assuan_log_printf (const char *format, ...) } +/* 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 +} + + #ifdef HAVE_W32_SYSTEM const char * diff --git a/src/assuan-util.c b/src/assuan-util.c index d4f2b96..3e627fc 100644 --- a/src/assuan-util.c +++ b/src/assuan-util.c @@ -107,19 +107,6 @@ assuan_get_pointer (assuan_context_t ctx) 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); - } -} - - -void assuan_begin_confidential (assuan_context_t ctx) { if (ctx) @@ -167,97 +154,3 @@ assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag) } -/* Dump a possibly binary string (used for debugging). Distinguish - ascii text from binary and print it accordingly. */ -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); - 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 -} - diff --git a/src/assuan.h b/src/assuan.h index 44c458a..8553ab0 100644 --- a/src/assuan.h +++ b/src/assuan.h @@ -430,9 +430,8 @@ assuan_error_t assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length); /* The file descriptor must be pending before assuan_receivefd is - call. This means that assuan_sendfd should be called *before* the - trigger is sent (normally via assuan_send_data ("I sent you a - descriptor")). */ + called. This means that assuan_sendfd should be called *before* the + trigger is sent (normally via assuan_write_line ("INPUT FD")). */ assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd); assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd); diff --git a/tests/fdpassing.c b/tests/fdpassing.c index 9317ed2..c2f4bf6 100644 --- a/tests/fdpassing.c +++ b/tests/fdpassing.c @@ -42,7 +42,28 @@ static int cmd_echo (assuan_context_t ctx, char *line) { + int fd; + int c; + FILE *fp; + log_info ("got ECHO command (%s)\n", line); + + fd = assuan_get_input_fd (ctx); + if (fd == -1) + return ASSUAN_No_Input; + fp = fdopen (dup (fd), "r"); + if (!fp) + { + log_error ("fdopen failed on input fd: %s\n", strerror (errno)); + return ASSUAN_General_Error; + } + log_info ("printing input to stdout:\n"); + while ( (c=getc (fp)) != -1) + putc (c, stdout); + fflush (stdout); + log_info ("done printing input to stdout\n"); + + fclose (fp); return 0; } @@ -123,6 +144,8 @@ client (int fd) { int rc; assuan_context_t ctx; + FILE *fp; + int i; log_info ("client started on fd %d\n", fd); @@ -132,7 +155,37 @@ client (int fd) log_error ("assuan_domain_connect failed: %s\n", assuan_strerror (rc)); return -1; } - + + fp = fopen ("/etc/motd", "r"); + if (!fp) + { + log_error ("failed to open `%s': %s\n", "/etc/motd", strerror (errno)); + return -1; + } + + rc = assuan_sendfd (ctx, fileno (fp)); + if (rc) + { + log_error ("assuan_sendfd failed: %s\n", assuan_strerror (rc)); + return -1; + } + + rc = assuan_transact (ctx, "INPUT FD", NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + { + log_error ("sending INPUT FD failed: %s\n", assuan_strerror (rc)); + return -1; + } + + + rc = assuan_transact (ctx, "ECHO", NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + { + log_error ("sending ECHO failed: %s\n", assuan_strerror (rc)); + return -1; + } + + sleep (100); assuan_disconnect (ctx); return 0; |