for (last = head; last; last = last->next) { switch (last->type) { case TYPEMULTIPART: fseek (fp, last->offset, 0); last->parts = mutt_parse_multipart (fp, mutt_get_parameter ("boundary", last->parameter), last->offset + last->length, mutt_strcasecmp ("digest", last->subtype) == 0); break;  case TYPEMESSAGE: if (last->subtype) { fseek (fp, last->offset, SEEK_SET); if (mutt_strcasecmp (last->subtype, "rfc822") == 0 || mutt_strcasecmp (last->subtype, "news") == 0) last->parts = mutt_parse_messageRFC822 (fp, last); else if (mutt_strcasecmp (last->subtype, "external-body") == 0) last->parts = mutt_read_mime_header (fp, 0); } break; } }
for(last = head; last; last = last->next) mutt_parse_part(fp, last);
BODY *mutt_parse_multipart (FILE *fp, const char *boundary, long end_off, int digest){  int blen, len, crlf = 0;  char buffer[LONG_STRING];  BODY *head = 0, *last = 0, *new = 0;  int i;  int final = 0; /* did we see the ending boundary? */  if (!boundary)  {    mutt_error _("multipart message has no boundary parameter!");    return (NULL);  }  blen = mutt_strlen (boundary);  while (ftell (fp) < end_off && fgets (buffer, LONG_STRING, fp) != NULL)  {    len = mutt_strlen (buffer);    /* take note of the line ending.  I'm assuming that either all endings     * will use <CR><LF> or none will.     */    if (len > 1 && buffer[len - 2] == '\r')      crlf = 1;    if (buffer[0] == '-' && buffer[1] == '-' &&	mutt_strncmp (buffer + 2, boundary, blen) == 0)    {      if (last)      {	last->length = ftell (fp) - last->offset - len - 1 - crlf;	if (last->parts && last->parts->length == 0)	  last->parts->length = ftell (fp) - last->parts->offset - len - 1 - crlf;	/* if the body is empty, we can end up with a -1 length */	if (last->length < 0)	  last->length = 0;      }      /* Remove any trailing whitespace, up to the length of the boundary */      for (i = len - 1; ISSPACE (buffer[i]) && i >= blen + 2; i--)        buffer[i] = 0;      /* Check for the end boundary */      if (mutt_strcmp (buffer + blen + 2, "--") == 0)      {	final = 1;	break; /* done parsing */      }      else if (buffer[2 + blen] == 0)      {	new = mutt_read_mime_header (fp, digest);		/*	 * Consistency checking - catch	 * bad attachment end boundaries	 */		if(new->offset > end_off)	{	  mutt_free_body(&new);	  break;	}	if (head)	{	  last->next = new;	  last = new;	}	else	  last = head = new;      }    }  }  /* in case of missing end boundary, set the length to something reasonable */  if (last && last->length == 0 && !final)    last->length = end_off - last->offset;  /* parse recursive MIME parts */  for (last = head; last; last = last->next)  {    switch (last->type)    {      case TYPEMULTIPART:	fseek (fp, last->offset, 0);	last->parts = mutt_parse_multipart (fp, mutt_get_parameter ("boundary", last->parameter), last->offset + last->length, mutt_strcasecmp ("digest", last->subtype) == 0);	break;      case TYPEMESSAGE:	if (last->subtype)	{	  fseek (fp, last->offset, SEEK_SET);	  if (mutt_strcasecmp (last->subtype, "rfc822") == 0 ||	      mutt_strcasecmp (last->subtype, "news") == 0)	    last->parts = mutt_parse_messageRFC822 (fp, last);	  else if (mutt_strcasecmp (last->subtype, "external-body") == 0)	    last->parts = mutt_read_mime_header (fp, 0);	}	break;    }  }  return (head);}