Split lines before column 80
[infodrom/newmail] / rfc2047.c
index c85756e..82e9dee 100644 (file)
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include "charset.h"
@@ -118,29 +119,42 @@ char *convert_header(char *buf)
   int encoding;
   char *inp, *outp, *encstart, *wordp, *encp, *endp;
   char *decode;
+  char *output;
   size_t size;
+  size_t outlen;
 
   endp = buf+strlen(buf);
-  inp = outp = buf;
+  inp = buf;
+
+  outlen = strlen(buf)+1;
+  if ((output = (char *)malloc(outlen)) == NULL) {
+    perror ("malloc");
+    return buf;
+  }
+
+  memset(output, 0, outlen);
+  outp = output;
 
   while ((encstart = strstr (inp, "=?"))) {
-    if (inp == outp)
-      outp = encstart;
-    else {
-      memmove (outp, inp, encstart-inp-1);
-      outp += encstart-inp-1;
+    if (encstart != inp) {
+      // -1 nur falls vorher kein encoded-word
+      memcpy (outp, inp, encstart-inp);
+      outp += encstart-inp;
     }
     charset = encstart+2;
 
     if ((encp = strchr (charset, '?')) == NULL) {
-      memmove (outp, inp, strlen(inp)+1);
+      memcpy (outp, inp, strlen(inp)+1);
       break;
     }
 
     *encp = '\0';
 
     if ((encp + 3 >= endp) || !strchr ("BbQq", *encp) || (*(encp+2) != '?')) {
-      memmove (outp, inp, strlen(inp)+1);
+      *encp = '?';
+      memcpy (outp, inp, strlen(inp)+1);
+      outp += strlen(inp)+1;
+      inp += strlen(inp)+1;
       break;
     }
 
@@ -149,16 +163,21 @@ char *convert_header(char *buf)
     inp = encp + 3;
 
     if ((wordp = strstr (inp, "?=")) == NULL) {
-      memmove (outp, encstart, strlen(encstart)+1);
-      strcat (outp, "?");
-      encstart += strlen(encstart)+1;
-      memmove (outp, encstart, strlen(encstart)+1);
+      memcpy (outp, inp, strlen(inp)+1);
+      outp += strlen(inp)+1;
+      inp += strlen(inp)+1;
       break;
     }
 
     *wordp = '\0';
     wordp += 2;
 
+    /* Look for next =?, spaces will be eaten between two encoded-words */
+    if (*wordp && *wordp == ' ' &&
+       *(wordp+1) && *(wordp+1) == '=' &&
+       *(wordp+2) && *(wordp+2) == '?')
+      wordp++;
+
     switch (encoding) {
     case 'B':
       decode = decode_base64 (inp);
@@ -171,17 +190,19 @@ char *convert_header(char *buf)
       break;
     }
 
-    size = wordp - outp -1;
+    size = outlen - strlen(output);
     decode = convert_word (charset, decode, outp, size);
 
-    memmove (outp, decode, strlen(decode));
     outp += strlen(decode);
 
     inp = wordp;
   }
 
-  if (inp != outp)
-    memmove (outp, inp, strlen(inp)+1);
+  if (strlen(inp))
+    memcpy (outp, inp, strlen(inp)+1);
+
+  memcpy (buf, output, strlen(output)+1);
+  free (output);
 
   return buf;
 }