1 This patch logs raw socket data, to assist debugging when discriminating
2 between server and fetchmail bugs.
4 Apply it to socket.c (works as of 6.3.20) and set the environment
5 variable FETCHMAIL_RAW_LOGFILE to a log file writable by fetchmail. If
6 it's not there, it gets created with mode 0600 (which requires directory
9 The file gets appended to, so you can log into named pipes, character
10 (stream) devices and to the console if you're so inclined.
12 Note 1: any logging failures cause fetchmail to abort() forcefully.
14 Note 2: raw control characters persist in the log and are not filtered
15 out. In doubt use a pager that filters control characters, or use tools
16 such as a binary-capable text edtior, vim's xxd, or hexdump, or od, to
17 view the raw log message.
19 -- Matthias Andree, June 2011
21 diff --git a/socket.c b/socket.c
22 index c8117a5..89847fe 100644
25 @@ -362,6 +362,49 @@ static SSL *_ssl_context[FD_SETSIZE];
26 static SSL *SSLGetContext( int );
27 #endif /* SSL_ENABLE */
31 +static const char *rawlogfile;
32 +static FILE *rlogstream;
34 +static int SockLog(void) {
35 + static int haveinit;
37 + static int logfd = -1;
41 + if ((rawlogfile = getenv("FETCHMAIL_RAW_LOGFILE"))) {
42 + if ((logfd = open(rawlogfile, O_WRONLY|O_APPEND|O_CREAT, 0600)) == -1) {
43 + report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but opening \"%s\" for appending write failed: %s\n"), rawlogfile, strerror(errno));
46 + if (!(rlogstream = fdopen(logfd, "a"))) {
47 + report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but fdopen(%d) failed: %s\n"), logfd, strerror(errno));
50 + setvbuf(rlogstream, NULL, _IOLBF, 0);
57 +static void LogPrintf(const char *fmt, ...) {
61 + if (!SockLog()) return;
62 + locsav = setlocale(LC_ALL, NULL);
63 + (void)setlocale(LC_ALL, "C");
64 + if (EOF == vfprintf(rlogstream, fmt, va) || EOF == fflush(rlogstream)) {
65 + report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but logging failed: %s\n"), strerror(errno));
68 + (void)setlocale(LC_ALL, locsav);
72 int SockWrite(int sock, const char *buf, int len)
75 @@ -369,6 +412,8 @@ int SockWrite(int sock, const char *buf, int len)
79 + LogPrintf("[>%d-%s count=%04d] %.*s%s", sock, SSLGetContext(sock) ? "crypt" : "plain", len, len, buf, (len < 1 || buf[len - 1] != '\n') ? "\n" : "");
84 @@ -471,6 +516,8 @@ int SockRead(int sock, char *buf, int len)
88 + LogPrintf("[<%d-%s count=%04d] %.*s%s", sock, SSLGetContext(sock) ? "crypt" : "plain", bp - buf, bp - buf, buf, newline ? "" : "\n");