From dac9b3ef6f31553f5cae283aaaa7418b8e2bc1e2 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Tue, 4 Nov 2008 19:19:53 +0000 Subject: [PATCH] Experimental rfc822 output helper that folds lines --- citadel/msgbase.c | 6 +++--- citadel/sysdep.c | 42 +++++++++++++++++++++++++++++++++++++++--- citadel/sysdep_decls.h | 2 ++ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 1d691ebb8..e73121577 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1794,7 +1794,7 @@ int CtdlOutputPreLoadedMsg( else if (i == 'Y') { if ((flags & QP_EADDR) != 0) mptr = qp_encode_email_addrs(mptr); - cprintf("CC: %s%s", mptr, nl); + fold_cprintf("CC: %s%s", mptr, nl); } else if (i == 'P') { cprintf("Return-Path: %s%s", mptr, nl); @@ -1824,13 +1824,13 @@ int CtdlOutputPreLoadedMsg( { if (haschar(mptr, '@') == 0) { - cprintf("To: %s@%s%s", mptr, config.c_fqdn, nl); + fold_cprintf("To: %s@%s%s", mptr, config.c_fqdn, nl); } else { if ((flags & QP_EADDR) != 0) mptr = qp_encode_email_addrs(mptr); - cprintf("To: %s%s", mptr, nl); + fold_cprintf("To: %s%s", mptr, nl); } } else if (i == 'T') { diff --git a/citadel/sysdep.c b/citadel/sysdep.c index d79785a5a..975585c0f 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -707,9 +707,8 @@ int client_write(char *buf, int nbytes) /* - * cprintf() ... Send formatted printable data to the client. It is - * implemented in terms of client_write() but remains in - * sysdep.c in case we port to somewhere without va_args... + * cprintf() Send formatted printable data to the client. + * Implemented in terms of client_write() so it's technically not sysdep... */ void cprintf(const char *format, ...) { va_list arg_ptr; @@ -723,6 +722,43 @@ void cprintf(const char *format, ...) { } +/* + * fold_cprintf() Like cprintf() except it can do RFC2822-style header folding. + */ +void fold_cprintf(const char *format, ...) { + va_list arg_ptr; + char buf[4096]; + int len; + char *bbuf; + char *ptr; + + va_start(arg_ptr, format); + if (vsnprintf(buf, sizeof buf, format, arg_ptr) == -1) + buf[sizeof buf - 2] = '\n'; + va_end(arg_ptr); + + len = strlen(buf); + bbuf = buf; + + while (len > 998) { + ptr = strchr(&bbuf[900], ','); + if (ptr == NULL) { + ptr = bbuf+990; + } + if ((ptr - bbuf) > 990) { + ptr = bbuf+990; + } + ++ptr; + client_write(bbuf, ptr-bbuf); + client_write("\r\n\t", 3); + len -= (ptr-bbuf); + bbuf = ptr++; + } + + client_write(bbuf, len); +} + + /* * Read data from the client socket. * Return values are: diff --git a/citadel/sysdep_decls.h b/citadel/sysdep_decls.h index 8a16f7305..cf2b9c3ab 100644 --- a/citadel/sysdep_decls.h +++ b/citadel/sysdep_decls.h @@ -42,8 +42,10 @@ #ifdef __GNUC__ void cprintf (const char *format, ...) __attribute__((__format__(__printf__,1,2))); +void fold_cprintf (const char *format, ...) __attribute__((__format__(__printf__,1,2))); #else void cprintf (const char *format, ...); +void fold_cprintf (const char *format, ...); #endif void CtdlLogPrintf(enum LogLevel loglevel, const char *format, ...); -- 2.39.2