const struct socket_function_table *fn;
/* the above variable absolutely *must* be the first in this structure */
- HANDLE send_H, recv_H;
- struct handle *send_h, *recv_h;
+ HANDLE send_H, recv_H, stderr_H;
+ struct handle *send_h, *recv_h, *stderr_h;
/*
* Freezing one of these sockets is a slightly fiddly business,
/* We buffer data here if we receive it from winhandl while frozen. */
bufchain inputdata;
+ /* Data received from stderr_H, if we have one. */
+ bufchain stderrdata;
+
char *error;
Plug plug;
-
- void *privptr;
};
static int handle_gotdata(struct handle *h, void *data, int len)
}
}
+static int handle_stderr(struct handle *h, void *data, int len)
+{
+ Handle_Socket ps = (Handle_Socket) handle_get_privdata(h);
+
+ if (len > 0)
+ log_proxy_stderr(ps->plug, &ps->stderrdata, data, len);
+
+ return 0;
+}
+
static void handle_sentdata(struct handle *h, int new_backlog)
{
Handle_Socket ps = (Handle_Socket) handle_get_privdata(h);
if (ps->recv_H != ps->send_H)
CloseHandle(ps->recv_H);
bufchain_clear(&ps->inputdata);
+ bufchain_clear(&ps->stderrdata);
sfree(ps);
}
/* do nothing */
}
-static void sk_handle_set_private_ptr(Socket s, void *ptr)
-{
- Handle_Socket ps = (Handle_Socket) s;
- ps->privptr = ptr;
-}
-
-static void *sk_handle_get_private_ptr(Socket s)
-{
- Handle_Socket ps = (Handle_Socket) s;
- return ps->privptr;
-}
-
static void handle_socket_unfreeze(void *psv)
{
Handle_Socket ps = (Handle_Socket) psv;
return ps->error;
}
-Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, Plug plug,
- int overlapped)
+static char *sk_handle_peer_info(Socket s)
+{
+ Handle_Socket ps = (Handle_Socket) s;
+ ULONG pid;
+ static HMODULE kernel32_module;
+ DECL_WINDOWS_FUNCTION(static, BOOL, GetNamedPipeClientProcessId,
+ (HANDLE, PULONG));
+
+ if (!kernel32_module) {
+ kernel32_module = load_system32_dll("kernel32.dll");
+ GET_WINDOWS_FUNCTION(kernel32_module, GetNamedPipeClientProcessId);
+ }
+
+ /*
+ * Of course, not all handles managed by this module will be
+ * server ends of named pipes, but if they are, then it's useful
+ * to log what we can find out about the client end.
+ */
+ if (p_GetNamedPipeClientProcessId &&
+ p_GetNamedPipeClientProcessId(ps->send_H, &pid))
+ return dupprintf("process id %lu", (unsigned long)pid);
+
+ return NULL;
+}
+
+Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
+ Plug plug, int overlapped)
{
static const struct socket_function_table socket_fn_table = {
sk_handle_plug,
sk_handle_write_oob,
sk_handle_write_eof,
sk_handle_flush,
- sk_handle_set_private_ptr,
- sk_handle_get_private_ptr,
sk_handle_set_frozen,
- sk_handle_socket_error
+ sk_handle_socket_error,
+ sk_handle_peer_info,
};
Handle_Socket ret;
ret->error = NULL;
ret->frozen = UNFROZEN;
bufchain_init(&ret->inputdata);
+ bufchain_init(&ret->stderrdata);
ret->recv_H = recv_H;
ret->recv_h = handle_input_new(ret->recv_H, handle_gotdata, ret, flags);
ret->send_H = send_H;
ret->send_h = handle_output_new(ret->send_H, handle_sentdata, ret, flags);
+ ret->stderr_H = stderr_H;
+ if (ret->stderr_H)
+ ret->stderr_h = handle_input_new(ret->stderr_H, handle_stderr,
+ ret, flags);
return (Socket) ret;
}