Update TortoiseGitPlink to PuTTY Plink 0.78
[TortoiseGit.git] / src / TortoisePlink / utils / log_proxy_stderr.c
blob202a23fd78374f5f837f75e639937dd2134851c7
1 #include <assert.h>
2 #include <string.h>
4 #include "putty.h"
5 #include "network.h"
7 void psb_init(ProxyStderrBuf *psb)
9 psb->size = 0;
10 psb->prefix = "proxy";
13 void psb_set_prefix(ProxyStderrBuf *psb, const char *prefix)
15 psb->prefix = prefix;
18 void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
19 const void *vdata, size_t len)
21 const char *data = (const char *)vdata;
24 * This helper function allows us to collect the data written to a
25 * local proxy command's standard error in whatever size chunks we
26 * happen to get from its pipe, and whenever we have a complete
27 * line, we pass it to plug_log.
29 * (We also do this when the buffer in psb fills up, to avoid just
30 * allocating more and more memory forever, and also to keep Event
31 * Log lines reasonably bounded in size.)
33 * Prerequisites: a plug to log to, and a ProxyStderrBuf stored
34 * somewhere to collect any not-yet-output partial line.
37 while (len > 0) {
39 * Copy as much data into psb->buf as will fit.
41 assert(psb->size < lenof(psb->buf));
42 size_t to_consume = lenof(psb->buf) - psb->size;
43 if (to_consume > len)
44 to_consume = len;
45 memcpy(psb->buf + psb->size, data, to_consume);
46 data += to_consume;
47 len -= to_consume;
48 psb->size += to_consume;
51 * Output any full lines in psb->buf.
53 size_t pos = 0;
54 while (pos < psb->size) {
55 char *nlpos = memchr(psb->buf + pos, '\n', psb->size - pos);
56 if (!nlpos)
57 break;
60 * Found a newline in the buffer, so we can output a line.
62 size_t endpos = nlpos - psb->buf;
63 while (endpos > pos && (psb->buf[endpos-1] == '\n' ||
64 psb->buf[endpos-1] == '\r'))
65 endpos--;
66 char *msg = dupprintf(
67 "%s: %.*s", psb->prefix, (int)(endpos - pos), psb->buf + pos);
68 plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
69 sfree(msg);
71 pos = nlpos - psb->buf + 1;
72 assert(pos <= psb->size);
76 * If the buffer is completely full and we didn't output
77 * anything, then output the whole thing, flagging it as a
78 * truncated line.
80 if (pos == 0 && psb->size == lenof(psb->buf)) {
81 char *msg = dupprintf(
82 "%s (partial line): %.*s", psb->prefix, (int)psb->size,
83 psb->buf);
84 plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
85 sfree(msg);
87 pos = psb->size = 0;
91 * Now move any remaining data up to the front of the buffer.
93 size_t newsize = psb->size - pos;
94 if (newsize)
95 memmove(psb->buf, psb->buf + pos, newsize);
96 psb->size = newsize;
99 * And loop round again if there's more data to be read from
100 * our input.