From: Wilfried Goesgens Date: Sun, 27 Oct 2013 13:22:52 +0000 (+0100) Subject: add StrBufRFC2047encodeMessage which does quoted printeable encoding for a message. X-Git-Tag: v9.01~207 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=33b3af37b60fba208a3654d20f5e4915cd315b23 add StrBufRFC2047encodeMessage which does quoted printeable encoding for a message. --- diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index dbe302f7b..4e8500293 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -339,6 +339,7 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf* int StrBufDecodeBase64(StrBuf *Buf); int StrBufDecodeHex(StrBuf *Buf); +StrBuf *StrBufRFC2047encodeMessage(const StrBuf *EncodeMe); int StrBufRFC2047encode(StrBuf **target, const StrBuf *source); StrBuf *StrBufSanitizeEmailRecipientVector(const StrBuf *Recp, StrBuf *UserName, diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index eb751c8d7..86f83d805 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -2882,6 +2882,97 @@ int StrBufRFC2047encode(StrBuf **target, const StrBuf *source) return (*target)->BufUsed;; } +/** + * @ingroup StrBuf_DeEnCoder + * @brief Quoted-Printable encode a message; make it < 80 columns width. + * @param source Source string to be encoded. + * @returns buffer with encoded message. + */ +StrBuf *StrBufRFC2047encodeMessage(const StrBuf *EncodeMe) +{ + StrBuf *OutBuf; + char *Optr, *OEptr; + const char *ptr, *eptr; + unsigned char ch; + int LinePos; + + OutBuf = NewStrBufPlain(NULL, StrLength(EncodeMe) * 4); + Optr = OutBuf->buf; + OEptr = OutBuf->buf + OutBuf->BufSize; + ptr = EncodeMe->buf; + eptr = EncodeMe->buf + EncodeMe->BufUsed; + LinePos = 0; + + while (ptr < eptr) + { + if (Optr + 4 >= OEptr) + { + long Offset; + Offset = Optr - OutBuf->buf; + IncreaseBuf(OutBuf, 1, 0); + Optr = OutBuf->buf + Offset; + OEptr = OutBuf->buf + OutBuf->BufSize; + } + if ((*ptr == '\r') || (*ptr == '\n')) + { + /* ignore carriage returns */ + ptr ++; + } + else if (*ptr == 10) { + /* hard line break */ + if ((LinePos > 0) && (isspace(*(Optr-1)))) + { + memcpy(Optr, HKEY("=0A")); + Optr += 3; + } + ptr ++; + LinePos = 0; + } + else if (( (*ptr >= 32) && (*ptr <= 60) ) || + ( (*ptr >= 62) && (*ptr <= 126) )) + { + *Optr = *ptr; + Optr ++; + ptr ++; + LinePos ++; + } + else { + ch = *ptr; + *Optr = '='; + Optr ++; + *Optr = HexList[ch][0]; + Optr ++; + *Optr = HexList[ch][1]; + Optr ++; + LinePos += 3; + ptr ++; + } + + if (LinePos > 72) { + /* soft line break */ + if (isspace(*(Optr - 1))) { + ch = *(Optr - 1); + Optr --; + *Optr = '='; + Optr ++; + *Optr = HexList[ch][0]; + Optr ++; + *Optr = HexList[ch][1]; + Optr ++; + LinePos += 3; + } + *Optr = '='; + Optr ++; + *Optr = '\n'; + Optr ++; + LinePos = 0; + } + } + *Optr = '\0'; + OutBuf->BufUsed = Optr - OutBuf->buf; + + return OutBuf; +} static void AddRecipient(StrBuf *Target, diff --git a/libcitadel/tests/stringbuf_conversion.c b/libcitadel/tests/stringbuf_conversion.c index 15634cc16..00cbbe426 100644 --- a/libcitadel/tests/stringbuf_conversion.c +++ b/libcitadel/tests/stringbuf_conversion.c @@ -321,6 +321,33 @@ static void TestEncodeEmailSTDIN(void) FreeStrBuf(&Source); } +static void StrBufRFC2047encodeMessageStdin(void) +{ + int fdin = 0;// STDIN + const char *Err; + StrBuf *Target; + StrBuf *Source; + StrBuf *Src; + + Source = NewStrBuf(); + Src = NewStrBuf(); + + printf("["); + while (fdin == 0) { + + StrBufTCP_read_line(Source, &fdin, 0, &Err); + StrBufAppendBuf(Src, Source, 0); + StrBufAppendBufPlain(Src, HKEY("\n"), 0); + + } + + Target = StrBufRFC2047encodeMessage(Src); + + printf("Target: \n%s\n", ChrPtr(Target)); + FreeStrBuf(&Source); + FreeStrBuf(&Src); + FreeStrBuf(&Target); +} static void TestHTML2ASCII_line(void) { @@ -390,6 +417,9 @@ static void AddStrBufSimlpeTests(void) case 'U': pTest = CU_add_test(pGroup, "TestUrlescEncodeStdin", TestUrlescEncodeStdin); break; + case 'R': + pTest = CU_add_test(pGroup, "StrBufRFC2047encodeMessageStdin", StrBufRFC2047encodeMessageStdin); + break; default: printf("%c not supported!\n", OutputEscapeAs); CU_ASSERT(1);