add StrBufRFC2047encodeMessage which does quoted printeable encoding for a message.
authorWilfried Goesgens <dothebart@citadel.org>
Sun, 27 Oct 2013 13:22:52 +0000 (14:22 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 27 Oct 2013 13:22:52 +0000 (14:22 +0100)
libcitadel/lib/libcitadel.h
libcitadel/lib/stringbuf.c
libcitadel/tests/stringbuf_conversion.c

index dbe302f..4e85002 100644 (file)
@@ -339,6 +339,7 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, const StrBuf *DecodeMe, const StrBuf*
 
 int StrBufDecodeBase64(StrBuf *Buf);
 int StrBufDecodeHex(StrBuf *Buf);
 
 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, 
 int StrBufRFC2047encode(StrBuf **target, const StrBuf *source);
 StrBuf *StrBufSanitizeEmailRecipientVector(const StrBuf *Recp, 
                                           StrBuf *UserName, 
index eb751c8..86f83d8 100644 (file)
@@ -2882,6 +2882,97 @@ int StrBufRFC2047encode(StrBuf **target, const StrBuf *source)
        return (*target)->BufUsed;;
 }
 
        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, 
 
 
 static void AddRecipient(StrBuf *Target, 
index 15634cc..00cbbe4 100644 (file)
@@ -321,6 +321,33 @@ static void TestEncodeEmailSTDIN(void)
        FreeStrBuf(&Source);
 }
 
        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)
 {
 
 static void TestHTML2ASCII_line(void)
 {
@@ -390,6 +417,9 @@ static void AddStrBufSimlpeTests(void)
                             case 'U':
                                     pTest = CU_add_test(pGroup, "TestUrlescEncodeStdin", TestUrlescEncodeStdin);
                                     break;
                             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);
                             default:
                                     printf("%c not supported!\n", OutputEscapeAs);
                                     CU_ASSERT(1);