# Add minimal multipart support to slrn
# text type parts are displayed correctly
# binary and other unsupported parts are hidden
#
# Don't expect it to read html postings or 
# to save binary attachments, it just helps to
# ease the pain when reading pgp/mime signed
# postings or postings created by pine.
#
# You can disable the minimal multipart support by
# adding "set minimal_multipart 0" in your slrnrc.
#
# Thanks to Christian Ebert. He helped a lot to
# debug this patch, thus you could call it 
# now quite stable.
#
# send bugs and other feedback to wiegner(at)gmx.de
#
# Thomas Wiegner
#
# Changelog
#
#  2007-07-10  - Fixed bug with nested multiparts
#              - Fixed bug with base64 encoded parts
#  2007-07-14  - Fixed crash due to uninitialized pointers
#  2007-07-24  - Code cleanup, no crash due to corrupted multipart postings
#  2007-08-02  - disable/enable via slrnrc
#  2007-08-18  - Fixed possible crash when decoding qp parts
#  2007-09-06  - Fixed line->prev of pseudeo article 
#
--- src/version.c      2007-07-07 13:14:58.000000000 +0200
+++ src/version.c      2007-07-07 13:13:27.000000000 +0200
@@ -83,2 +83,3 @@
 static char *included_patches[] =
 {
+ "minimal_multipart",

--- src/art.h	2006-08-16 09:24:01.000000000 +0200
+++ src/art.h	2007-07-01 11:40:44.000000000 +0200
@@ -184,6 +184,7 @@
     int was_modified;
     int was_parsed;
     int needs_metamail;
+    char *boundary;
 }
 Slrn_Mime_Type;
 
--- src/mime.h	2007-06-30 10:24:46.000000000 +0200
+++ src/mime.h	2007-08-02 17:15:51.000000000 +0200
@@ -33,5 +33,6 @@
 extern char *Slrn_MetaMail_Cmd;
 extern char *Slrn_Fallback_Input_Charset;
 extern int Slrn_Usascii_Override;
+extern int Slrn_Minimal_Multipart;
 
 #endif /* _SLRN_MIME_H */
--- src/startup.c	2007-06-24 11:26:42.000000000 +0200
+++ src/startup.c	2007-08-02 17:15:08.000000000 +0200
@@ -615,6 +615,7 @@
      {"use_header_numbers", &Slrn_Use_Header_Numbers},
      {"use_localtime", &Slrn_Use_Localtime},
      {"usascii_override", &Slrn_Usascii_Override},
+     {"minimal_multipart", &Slrn_Minimal_Multipart},
 #if SLRN_HAS_SPOILERS
      {"spoiler_char", &Slrn_Spoiler_Char},
      {"spoiler_display_mode", &Slrn_Spoiler_Display_Mode},
--- src/mime.c	2007-07-24 18:21:55.000000000 +0200
+++ src/mime.c	2007-09-05 19:40:08.000000000 +0200
@@ -54,6 +54,7 @@
 char *Slrn_MetaMail_Cmd;
 char *Slrn_Fallback_Input_Charset = NULL;
 int Slrn_Usascii_Override = 0;
+int Slrn_Minimal_Multipart =1;
 
 #ifndef SLRNPULL_CODE
 #define CONTENT_TYPE_TEXT		0x01
@@ -127,19 +128,68 @@
      }
    else if (0 == slrn_case_strncmp ((unsigned char *)b,
 				    (unsigned char *) "message/",
-				    5))
+				    8))
      {
 	a->mime.content_type = CONTENT_TYPE_MESSAGE;
 	a->mime.content_subtype = CONTENT_SUBTYPE_UNKNOWN;
 	b += 8;
      }
    else if (0 == slrn_case_strncmp ((unsigned char *)b,
+				    (unsigned char *) "application/",
+				    12))
+     {
+	b += 12;
+	if (0 != slrn_case_strncmp ((unsigned char *)b,
+				    (unsigned char *) "pgp-signature",
+				    13))
+	  {
+	     a->mime.content_type = CONTENT_TYPE_UNSUPPORTED;
+	     a->mime.content_subtype = CONTENT_SUBTYPE_UNSUPPORTED;
+	     return -1;
+	  }
+	a->mime.content_type = CONTENT_TYPE_TEXT;
+	a->mime.content_subtype = CONTENT_SUBTYPE_PLAIN;
+     }
+   else if (0 == slrn_case_strncmp ((unsigned char *)b,
 				    (unsigned char *) "multipart/",
 				    5))
      {
 	a->mime.content_type = CONTENT_TYPE_MULTIPART;
 	a->mime.content_subtype = CONTENT_SUBTYPE_UNKNOWN;
 	b += 10;
+	while (NULL != (b = slrn_strchr (b, ';')))
+	  {
+	     char *boundary;
+	     unsigned int len;
+	     
+	     b = slrn_skip_whitespace (b + 1);
+	     
+	     if (0 != slrn_case_strncmp ((unsigned char *)b,
+					 (unsigned char *)"boundary",
+					 8))
+	       continue;
+	     
+	     b = slrn_skip_whitespace (b + 8);
+
+	     if (*b != '=') continue;
+	     b++;
+	     if (*b == '"') b++;
+	     boundary = b;
+	     while (*b && (*b != ';')
+		    && (*b != ' ') && (*b != '\t') && (*b != '\n')
+		    && (*b != '"'))
+	       b++;
+	     len = b - boundary;
+
+             /* add a "--" at the start of boundary */
+	     a->mime.boundary = slrn_safe_malloc(len+5);
+             a->mime.boundary[0]='-';
+             a->mime.boundary[1]='-';
+             slrn_strncpy(a->mime.boundary+2, boundary, len+1);
+             a->mime.boundary[len+2]='-';
+             a->mime.boundary[len+3]='-';
+	     return 0;
+	  }
      }
    else
      {
@@ -714,6 +764,7 @@
    m->was_parsed = 0;
    m->needs_metamail = 0;
    m->charset = NULL;
+   m->boundary = NULL;
    m->content_type = 0;
    m->content_subtype = 0;
 }
@@ -726,6 +777,10 @@
     {
        slrn_free(m->charset);
     }
+  if (m->boundary != NULL)
+    {
+       slrn_free(m->boundary);
+    }
 }
 
 /*}}}*/
@@ -775,7 +830,119 @@
 	obj=tmp;
      }
 }
+/*}}}*/
+
+int slrn_convert_multipart_article(Slrn_Article_Type *a, char *to_charset)/*{{{*/
+{
+   struct Slrn_Article_Line_Type *line, *first_line,  *line_start_part, *line_end_part, *line_tmp;
+   int len;
+   int i=0;
+   int j=1;
+   int endfound=0;
+
+   Slrn_Mime_Type mime_bak;
+
+   first_line =a->lines;
+   line       =a->lines;
+   len = strlen(a->mime.boundary)-2;
+   /* search 1st boundary */ 
+   do
+   {
+      if((line->flags & HEADER_LINE) == 0)
+      {
+        line->flags |= HIDDEN_LINE;
+      }
+      line=line->next;
+   } while ((line->next != NULL) && slrn_case_strncmp(line->buf, a->mime.boundary, len) != 0);
 
+   while ((line->next != NULL) && (endfound == 0))
+     {
+       j++;
+       line_start_part = line;
+       do
+       {
+         line->flags |= HIDDEN_LINE;
+         line->flags |= HEADER_LINE;
+         line=line->next; 
+
+       } while ((line->next != NULL) && (*(line->buf) != 0));
+      
+       /* search boundary */
+       while ((line->next != NULL) && (slrn_case_strncmp(line->buf, a->mime.boundary, len) != 0))
+       {
+         line_end_part=line;
+         line=line->next;
+       }
+       if(slrn_case_strncmp(line->buf, a->mime.boundary, len+2) == 0)
+       {
+         /* we found the normal ending boundary */
+         endfound=1;
+       }
+       else if(line->next==NULL)
+       {
+         /* end of article, indicating a corrupted article */
+         endfound=2;
+       }
+
+       /* pseudo article with only multipart */
+       mime_bak = a->mime;
+       slrn_mime_init(&a->mime);
+       a->lines = line_start_part;
+
+       /* start of pseudo article has no prev, save old prev value in line_start_part */
+       line_start_part=line_start_part->prev;
+       a->lines->prev = NULL;
+
+       if(endfound != 2)
+       {
+         line_end_part->next = NULL;
+       }
+
+       _slrn_art_unfold_header_lines(a);
+       slrn_mime_process_article (a);
+
+       line->flags |= HIDDEN_LINE;
+       line_tmp = a->lines;
+       do 
+       {
+           if( line_tmp->flags & HEADER_LINE)
+             {
+               line_tmp->flags ^= HEADER_LINE;
+             }
+           else if(a->mime.content_type == CONTENT_TYPE_UNSUPPORTED)
+             {
+               /* hide not supported multiparts */
+               line_tmp->flags |= HIDDEN_LINE;
+             }
+           line_end_part=line_tmp;
+           line_tmp=line_tmp->next;
+       } while (line_tmp != NULL);
+
+       /* set back article */ 
+       line_start_part->next=a->lines;
+       a->lines->prev=line_start_part;
+
+       a->lines = first_line;
+       if(endfound != 2)
+       {
+         line_end_part->next = line;
+         line->prev          = line_end_part;
+       }
+       else
+       {
+         slrn_message (_("Multipart article is corrupted."));
+       }
+
+       if(a->mime.content_type == CONTENT_TYPE_UNSUPPORTED)
+         slrn_message (_("Unsupported multiparts were hidden."));
+
+       /* free space */
+       slrn_mime_free(&a->mime);
+
+       a->mime=mime_bak;
+     }
+   return 0;
+}
 /*}}}*/
 
 int slrn_mime_process_article (Slrn_Article_Type *a)/*{{{*/
@@ -796,6 +963,12 @@
 	a->mime.needs_metamail = 1;
 	return 0;
      }
+
+	
+   if ((a->mime.content_type == CONTENT_TYPE_MULTIPART) && (Slrn_Minimal_Multipart != 0) )
+     {
+	return slrn_convert_multipart_article(a, Slrn_Display_Charset);
+     }
    
    switch (parse_content_transfer_encoding_line (a))
      {
