From c58fef3409228abe2c52bb855bc13dd50fe6aa63 Mon Sep 17 00:00:00 2001
From: Dave McCaldon <dave@mccaldon.com>
Date: Wed, 20 Jan 2010 12:02:13 -0500
Subject: [PATCH] Pass user context through libssh2_trace_sethandler() to callback

The libssh2_trace_sethandler() call allows the user to handle the output of libssh2 rather than having it written to stderr.  This patch updates libssh2_trace_sethandler() to allow a user-defined void* context value to be passed back to the output handler.
---
 docs/libssh2_trace_sethandler.3 |    4 ++++
 include/libssh2.h               |    5 ++++-
 src/libssh2_priv.h              |    1 +
 src/misc.c                      |    8 +++++---
 src/transport.c                 |    4 ++--
 5 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/docs/libssh2_trace_sethandler.3 b/docs/libssh2_trace_sethandler.3
index a039a79..25fd2c8 100644
--- a/docs/libssh2_trace_sethandler.3
+++ b/docs/libssh2_trace_sethandler.3
@@ -8,10 +8,12 @@ libssh2_trace_sethandler - set a trace output handler
 #include <libssh2.h>
 
 typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION *session,
+                                           void* context,
                                            const char *data,
                                            size_t length);
 
 int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
+                             void* context,
                              libssh2_trace_handler_func callback);
 .SH DESCRIPTION
 libssh2_trace_sethandler installs a trace output handler for your application.
@@ -22,5 +24,7 @@ libssh2 will call back as it generates trace output.  This can be used to
 capture the trace output and put it into a log file or diagnostic window.
 This function has no effect unless libssh2 was built to support this option,
 and a typical "release build" might not.
+
+\fBcontext\fP can be used to pass arbitrary user defined data back into the callback when invoked.
 .SH AVAILABILITY
 Added in libssh2 version 1.2.3
diff --git a/include/libssh2.h b/include/libssh2.h
index 39817d3..890749e 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -987,9 +987,12 @@ LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
 #define LIBSSH2_TRACE_PUBLICKEY (1<<8)
 #define LIBSSH2_TRACE_SOCKET (1<<9)
 
-typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, const char *,
+typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*,
+                                           void*,
+                                           const char *,
                                            size_t);
 LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
+                                         void* context,
                                          libssh2_trace_handler_func callback);
 
 #ifdef __cplusplus
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 8f26efb..f1b34dd 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -736,6 +736,7 @@ struct _LIBSSH2_SESSION
 #ifdef LIBSSH2DEBUG
     int showmask;               /* what debug/trace messages to display */
     libssh2_trace_handler_func tracehandler; /* callback to display trace messages */
+    void* tracehandler_context; /* context for the trace handler */
 #endif
 
     /* State variables used in libssh2_banner_send() */
diff --git a/src/misc.c b/src/misc.c
index 3b55806..ea6859e 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -313,9 +313,10 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
 }
 
 LIBSSH2_API int
-libssh2_trace_sethandler(LIBSSH2_SESSION *session, libssh2_trace_handler_func callback)
+libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
 {
     session->tracehandler = callback;
+    session->tracehandler_context = handler_context;
     return 0;
 }
 
@@ -362,7 +363,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
     va_end(vargs);
 
     if (session->tracehandler) {
-        (session->tracehandler)(session, buffer, len + 1);
+        (session->tracehandler)(session, session->tracehandler_context, buffer, len + 1);
     } else {
         write(2, buffer, len + 1);
     }
@@ -378,9 +379,10 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
 }
 
 LIBSSH2_API int
-libssh2_trace_sethandler(LIBSSH2_SESSION *session, libssh2_trace_handler_func callback)
+libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
 {
     (void) session;
+    (void) handler_context;
     (void) callback;
     return 0;
 }
diff --git a/src/transport.c b/src/transport.c
index 0be694d..1894485 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -71,7 +71,7 @@ debugdump(LIBSSH2_SESSION * session,
     used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
                     desc, (int) size);
     if (session->tracehandler)
-        (session->tracehandler)(session, buffer, used);
+        (session->tracehandler)(session, session->tracehandler_context, buffer, used);
     else
         write(2 /* stderr */, buffer, used);
 
@@ -104,7 +104,7 @@ debugdump(LIBSSH2_SESSION * session,
         buffer[used] = 0;
 
         if (session->tracehandler)
-            (session->tracehandler)(session, buffer, used);
+            (session->tracehandler)(session, session->tracehandler_context, buffer, used);
         else
             write(2, buffer, used);
     }
-- 
1.6.4.4

