diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/rawlog.patch | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/contrib/rawlog.patch b/contrib/rawlog.patch new file mode 100644 index 00000000..a341d4e1 --- /dev/null +++ b/contrib/rawlog.patch @@ -0,0 +1,114 @@ +This patch logs raw socket data, to assist debugging when discriminating +between server and fetchmail bugs. + +Apply it to fetchmail 6.3.20 and set the environment variable +FETCHMAIL_RAW_LOGFILE to a log file writable by fetchmail. If it's not +there, it gets created with mode 0600 (which requires directory write +permission). + +The file gets appended to, so you can log into named pipes, character +(stream) devices and to the console if you're so inclined. + +Note 1: any logging failures cause fetchmail to abort() forcefully. + +Note 2: non-printable characters are hex-escaped, so it is safe to use +FETCHMAIL_RAW_LOGFILE=/dev/stderr or similar. + +-- Matthias Andree, August 2011 + +diff --git a/sink.c b/sink.c +index 5d92556..ff6208d 100644 +--- a/sink.c ++++ b/sink.c +@@ -649,6 +649,10 @@ int stuffline(struct query *ctl, char *buf) + while ((last += strlen(last)) && (last[-1] != '\n')) + last++; + ++ if (outlevel >= O_DEBUG && (size_t)(last - buf) != strlen(buf)) ++ report(stdout, GT_("DEBUG: stuffline shipping line with NULs, length=%lu, strlen=%lu\n"), last - buf, strlen(buf)); ++ ++ + /* fix message lines that have only \n termination (for qmail) */ + if (ctl->forcecr) + { +diff --git a/socket.c b/socket.c +index e338207..dcaf19d 100644 +--- a/socket.c ++++ b/socket.c +@@ -381,6 +381,49 @@ static SSL *_ssl_context[FD_SETSIZE]; + static SSL *SSLGetContext( int ); + #endif /* SSL_ENABLE */ + ++#include <fcntl.h> ++ ++static const char *rawlogfile; ++static FILE *rlogstream; ++ ++static int SockLog(void) { ++ static int haveinit; ++ static int wantlog; ++ static int logfd = -1; ++ ++ if (!haveinit) { ++ haveinit = 1; ++ if ((rawlogfile = getenv("FETCHMAIL_RAW_LOGFILE"))) { ++ if ((logfd = open(rawlogfile, O_WRONLY|O_APPEND|O_CREAT, 0600)) == -1) { ++ report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but opening \"%s\" for appending write failed: %s\n"), rawlogfile, strerror(errno)); ++ abort(); ++ } ++ if (!(rlogstream = fdopen(logfd, "a"))) { ++ report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but fdopen(%d) failed: %s\n"), logfd, strerror(errno)); ++ abort(); ++ } ++ setvbuf(rlogstream, NULL, _IOLBF, 0); ++ wantlog = 1; ++ } ++ } ++ return wantlog; ++} ++ ++static void LogPrintf(const char *fmt, ...) { ++ va_list va; ++ const char *locsav; ++ va_start(va, fmt); ++ if (!SockLog()) return; ++ locsav = setlocale(LC_ALL, NULL); ++ (void)setlocale(LC_ALL, "C"); ++ if (EOF == vfprintf(rlogstream, fmt, va) || EOF == fflush(rlogstream)) { ++ report(stderr, GT_("FETCHMAIL_RAW_LOGFILE is set, but logging failed: %s\n"), strerror(errno)); ++ abort(); ++ } ++ (void)setlocale(LC_ALL, locsav); ++ va_end(va); ++} ++ + int SockWrite(int sock, const char *buf, int len) + { + int n, wrlen = 0; +@@ -388,6 +431,12 @@ int SockWrite(int sock, const char *buf, int len) + SSL *ssl; + #endif + ++ if (SockLog()) { ++ char *tmps = sdump(buf, len); ++ LogPrintf("[>%d-%s count=%04d] %s\n", sock, SSLGetContext(sock) ? "crypt" : "plain", len, tmps); ++ free(tmps); ++ } ++ + while (len) + { + #ifdef SSL_ENABLE +@@ -504,6 +553,13 @@ int SockRead(int sock, char *buf, int len) + (!newline && len); + *bp = '\0'; + ++ if (SockLog()) ++ { ++ char *tmps = sdump(buf, bp - buf); ++ LogPrintf("[<%d-%s count=%04d] %s\n", sock, SSLGetContext(sock) ? "crypt" : "plain", bp - buf, tmps); ++ free(tmps); ++ } ++ + return bp - buf; + } + |