if (pref) pref->GetBoolPref("mailnews.display.disable_format_flowed_support", &disable_format_flowed);
if (prefBranch) prefBranch->GetBoolPref("mailnews.display.disable_format_flowed_support", &disable_format_flowed);
static int mime_classinit(MimeObjectClass *clazz);/*  * These are the necessary defines/variables for doing * content type handlers in external plugins. */typedef struct {  char        content_type[128];  PRBool      force_inline_display;} cthandler_struct;nsVoidArray         *ctHandlerList = NULL;PRBool              foundIt = PR_FALSE; PRBool              force_display = PR_FALSE;PRBool PR_CALLBACKEnumFunction(void* aElement, void *aData){  cthandler_struct    *ptr = (cthandler_struct *) aElement;  char                *ctPtr = (char *)aData;  if ( (!aElement) || (!aData) )    return PR_TRUE;  if (nsCRT::strcasecmp(ctPtr, ptr->content_type) == 0)  {    foundIt = PR_TRUE;    force_display = ptr->force_inline_display;    return PR_FALSE;  }  return PR_TRUE;}/* * This will return TRUE if the content_type is found in the * list, FALSE if it is not found.  */PRBoolfind_content_type_attribs(const char *content_type,                           PRBool     *force_inline_display){  *force_inline_display = PR_FALSE;  if (!ctHandlerList)    return PR_FALSE;  foundIt = PR_FALSE;  force_display = PR_FALSE;  ctHandlerList->EnumerateForwards(EnumFunction, (void *)content_type);  if (foundIt)    *force_inline_display = force_display;  return (foundIt);}voidadd_content_type_attribs(const char *content_type,                          contentTypeHandlerInitStruct  *ctHandlerInfo){  cthandler_struct    *ptr = NULL;  PRBool              force_inline_display;  if (find_content_type_attribs(content_type, &force_inline_display))    return;  if ( (!content_type) || (!ctHandlerInfo) )    return;  if (!ctHandlerList)    ctHandlerList = new nsVoidArray();  if (!ctHandlerList)    return;  ptr = (cthandler_struct *) PR_MALLOC(sizeof(cthandler_struct));  if (!ptr)    return;  PL_strncpy(ptr->content_type, content_type, sizeof(ptr->content_type));  ptr->force_inline_display = ctHandlerInfo->force_inline_display;  ctHandlerList->AppendElement(ptr);}/*  * This routine will find all content type handler for a specifc content * type (if it exists) */PRBoolforce_inline_display(const char *content_type){  PRBool     force_inline_disp;  find_content_type_attribs(content_type, &force_inline_disp);  return (force_inline_disp);}/*  * This routine will find all content type handler for a specifc content * type (if it exists) and is defined to the nsRegistry */MimeObjectClass *mime_locate_external_content_handler(const char *content_type,                                        contentTypeHandlerInitStruct  *ctHandlerInfo){  MimeObjectClass               *newObj = NULL;  char                          lookupID[256];  nsCOMPtr<nsIMimeContentTypeHandler>     ctHandler;  nsresult rv;  PR_snprintf(lookupID, sizeof(lookupID), "@mozilla.org/mimecth;1?type=%s", content_type);    ctHandler = do_CreateInstance(lookupID, &rv);  if (NS_FAILED(rv) || !ctHandler)    return nsnull;    rv = ctHandler->CreateContentTypeHandlerClass(content_type, ctHandlerInfo, &newObj);  if (NS_FAILED(rv))    return nsnull;  add_content_type_attribs(content_type, ctHandlerInfo);  return newObj;}/* This is necessary to expose the MimeObject method outside of this DLL */intMIME_MimeObject_write(MimeObject *obj, const char *output, PRInt32 length, PRBool user_visible_p){  return MimeObject_write(obj, output, length, user_visible_p);}MimeObject *mime_new (MimeObjectClass *clazz, MimeHeaders *hdrs,		  const char *override_content_type){  int size = clazz->instance_size;  MimeObject *object;  int status;  /* Some assertions to verify that this isn't random junk memory... */  NS_ASSERTION(clazz->class_name && strlen(clazz->class_name) > 0, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  NS_ASSERTION(size > 0 && size < 1000, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (!clazz->class_initialized)	{	  status = mime_classinit(clazz);	  if (status < 0) return 0;	}  NS_ASSERTION(clazz->initialize && clazz->finalize, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (hdrs)	{    hdrs = MimeHeaders_copy (hdrs);	  if (!hdrs) return 0;	}  object = (MimeObject *) PR_MALLOC(size);  if (!object) return 0;  memset(object, 0, size);  object->clazz = clazz;  object->headers = hdrs;  object->dontShowAsAttachment = PR_FALSE;  if (override_content_type && *override_content_type)	object->content_type = nsCRT::strdup(override_content_type);  status = clazz->initialize(object);  if (status < 0)	{	  clazz->finalize(object);	  PR_Free(object);	  return 0;	}  return object;}voidmime_free (MimeObject *object){# ifdef DEBUG__  int i, size = object->clazz->instance_size;  PRUint32 *array = (PRUint32*) object;# endif /* DEBUG */  object->clazz->finalize(object);# ifdef DEBUG__  for (i = 0; i < (size / sizeof(*array)); i++)	array[i] = (PRUint32) 0xDEADBEEF;# endif /* DEBUG */  PR_Free(object);}PRBool mime_is_allowed_class(const MimeObjectClass *clazz,                             PRInt32 types_of_classes_to_disallow){  if (types_of_classes_to_disallow == 0)    return PR_TRUE;  PRBool avoid_html = (types_of_classes_to_disallow >= 1);  PRBool avoid_images = (types_of_classes_to_disallow >= 2);  PRBool avoid_strange_content = (types_of_classes_to_disallow >= 3);  PRBool allow_only_vanilla_classes = (types_of_classes_to_disallow == 100);  if (allow_only_vanilla_classes)    /* A "safe" class is one that is unlikely to have security bugs or to       allow security exploits or one that is essential for the usefulness       of the application, even for paranoid users.       What's included here is more personal judgement than following       strict rules, though, unfortunately.       The function returns true only for known good classes, i.e. is a       "whitelist" in this case.       This idea comes from Georgi Guninski.    */    return      (        clazz == (MimeObjectClass *)&mimeInlineTextPlainClass ||        clazz == (MimeObjectClass *)&mimeInlineTextPlainFlowedClass ||        clazz == (MimeObjectClass *)&mimeInlineTextHTMLSanitizedClass ||        clazz == (MimeObjectClass *)&mimeInlineTextHTMLAsPlaintextClass ||           /* The latter 2 classes bear some risk, because they use the Gecko              HTML parser, but the user has the option to make an explicit              choice in this case, via html_as. */        clazz == (MimeObjectClass *)&mimeMultipartMixedClass ||        clazz == (MimeObjectClass *)&mimeMultipartAlternativeClass ||        clazz == (MimeObjectClass *)&mimeMultipartDigestClass ||        clazz == (MimeObjectClass *)&mimeMultipartAppleDoubleClass ||        clazz == (MimeObjectClass *)&mimeMessageClass ||        clazz == (MimeObjectClass *)&mimeExternalObjectClass ||                               /*    mimeUntypedTextClass? -- does uuencode */#ifdef ENABLE_SMIME        clazz == (MimeObjectClass *)&mimeMultipartSignedCMSClass ||        clazz == (MimeObjectClass *)&mimeEncryptedCMSClass ||#endif        clazz == 0      );  /* Contrairy to above, the below code is a "blacklist", i.e. it     *excludes* some "bad" classes. */  return     !(        (avoid_html         && (              clazz == (MimeObjectClass *)&mimeInlineTextHTMLClass                         /* Should not happen - we protect against that in                            mime_find_class(). Still for safety... */            )) ||        (avoid_images         && (              clazz == (MimeObjectClass *)&mimeInlineImageClass            )) ||        (avoid_strange_content         && (              clazz == (MimeObjectClass *)&mimeInlineTextEnrichedClass ||              clazz == (MimeObjectClass *)&mimeInlineTextRichtextClass ||              clazz == (MimeObjectClass *)&mimeSunAttachmentClass ||              clazz == (MimeObjectClass *)&mimeExternalBodyClass            ))      );}#ifdef MOZ_THUNDERBIRDvoid getMsgHdrForCurrentURL(MimeDisplayOptions *opts, nsIMsgDBHdr ** aMsgHdr){  *aMsgHdr = nsnull;  if (!opts)    return;     mime_stream_data *msd = (mime_stream_data *) (opts->stream_closure);  if (!msd)    return;  nsIChannel *channel = msd->channel;  // note the lack of ref counting...  if (channel)  {    nsCOMPtr<nsIURI> uri;    nsCOMPtr<nsIMsgMessageUrl> msgURI;    channel->GetURI(getter_AddRefs(uri));    if (uri)    {      msgURI = do_QueryInterface(uri);      if (msgURI)      {        nsXPIDLCString rdfURI;        msgURI->GetUri(getter_Copies(rdfURI));        if (rdfURI.get())        {          nsCOMPtr<nsIMsgDBHdr> msgHdr;          GetMsgDBHdrFromURI(rdfURI, getter_AddRefs(msgHdr));          NS_IF_ADDREF(*aMsgHdr = msgHdr);        }      }    }  }  return;}#endifMimeObjectClass *mime_find_class (const char *content_type, MimeHeaders *hdrs,				 MimeDisplayOptions *opts, PRBool exact_match_p){  MimeObjectClass *clazz = 0;  MimeObjectClass *tempClass = 0;  contentTypeHandlerInitStruct  ctHandlerInfo;  // Read some prefs  nsIPref *pref = GetPrefServiceManager(opts);   PRInt32 html_as = 0;  // def. see below  PRInt32 types_of_classes_to_disallow = 0;  /* Let only a few libmime classes       process incoming data. This protects from bugs (e.g. buffer overflows)       and from security loopholes (e.g. allowing unchecked HTML in some       obscure classes, although the user has html_as > 0).       This option is mainly for the UI of html_as.       0 = allow all available classes       1 = Use hardcoded blacklist to avoid rendering (incoming) HTML       2 = ... and images       3 = ... and some other uncommon content types       100 = Use hardcoded whitelist to avoid even more bugs(buffer overflows).           This mode will limit the features available (e.g. uncommon           attachment types and inline images) and is for paranoid users.       */  if (opts && opts->format_out != nsMimeOutput::nsMimeMessageFilterSniffer &&               opts->format_out != nsMimeOutput::nsMimeMessageDecrypt)    if (pref)    {      pref->GetIntPref("mailnews.display.html_as", &html_as);      pref->GetIntPref("mailnews.display.disallow_mime_handlers",                       &types_of_classes_to_disallow);      if (types_of_classes_to_disallow > 0 && html_as == 0)           // We have non-sensical prefs. Do some fixup.        html_as = 1;    }#ifdef MOZ_THUNDERBIRD  // first, check to see if the message has been marked as JUNK. If it has,   // then force the message to be rendered as simple.  PRBool sanitizeJunkMail = PR_FALSE;  // it is faster to read the pref first then figure out the msg hdr for the current url only if we have to  // XXX instead of reading this pref every time, part of mime should be an observer listening to this pref change  // and updating internal state accordingly. But none of the other prefs in this file seem to be doing that...=(  if (pref)    pref->GetBoolPref("mailnews.display.sanitizeJunkMail", &sanitizeJunkMail);  if (sanitizeJunkMail)  {    nsCOMPtr<nsIMsgDBHdr> msgHdr;    getMsgHdrForCurrentURL(opts, getter_AddRefs(msgHdr));    if (msgHdr)    {      nsXPIDLCString junkScoreStr;      (void) msgHdr->GetStringProperty("junkscore", getter_Copies(junkScoreStr));      if (html_as == 0 && junkScoreStr.get() && atoi(junkScoreStr.get()) > 50)        html_as = 3; // 3 == Simple HTML    } // if msgHdr  } // if we are supposed to sanitize junk mail#endif  /*  * What we do first is check for an external content handler plugin.   * This will actually extend the mime handling by calling a routine   * which will allow us to load an external content type handler  * for specific content types. If one is not found, we will drop back  * to the default handler.  */  if ((tempClass = mime_locate_external_content_handler(content_type, &ctHandlerInfo)) != NULL)  {    if (types_of_classes_to_disallow > 0        && (!nsCRT::strncasecmp(content_type, "text/x-vcard", 12) ||            !nsCRT::strncasecmp(content_type, "text/calendar", 13))       )      /* Use a little hack to prevent some dangerous plugins, which ship         with Mozilla, to run.         For the truely user-installed plugins, we rely on the judgement         of the user. */    {      if (!exact_match_p)        clazz = (MimeObjectClass *)&mimeExternalObjectClass; // As attachment    }    else      clazz = (MimeObjectClass *)tempClass;  }  else  {    if (!content_type || !*content_type ||        !nsCRT::strcasecmp(content_type, "text"))  /* with no / in the type */      clazz = (MimeObjectClass *)&mimeUntypedTextClass;        /* Subtypes of text...    */    else if (!nsCRT::strncasecmp(content_type,			"text/", 5))    {      if      (!nsCRT::strcasecmp(content_type+5,		"html"))      {        if (opts            && opts->format_out == nsMimeOutput::nsMimeMessageSaveAs)          // SaveAs in new modes doesn't work yet.        {          clazz = (MimeObjectClass *)&mimeInlineTextHTMLClass;          types_of_classes_to_disallow = 0;        }        else if (html_as == 0) // Render sender's HTML          clazz = (MimeObjectClass *)&mimeInlineTextHTMLClass;        else if (html_as == 1) // convert HTML to plaintext          // Do a HTML->TXT->HTML conversion, see mimethpl.h.          clazz = (MimeObjectClass *)&mimeInlineTextHTMLAsPlaintextClass;        else if (html_as == 2) // display HTML source          /* This is for the freaks. Treat HTML as plaintext,             which will cause the HTML source to be displayed.             Not very user-friendly, but some seem to want this. */          clazz = (MimeObjectClass *)&mimeInlineTextPlainClass;        else if (html_as == 3) // Sanitize          // Strip all but allowed HTML          clazz = (MimeObjectClass *)&mimeInlineTextHTMLSanitizedClass;        else // Goofy pref          /* User has an unknown pref value. Maybe he used a newer Mozilla             with a new alternative to avoid HTML. Defaulting to option 1,             which is less dangerous than defaulting to the raw HTML. */          clazz = (MimeObjectClass *)&mimeInlineTextHTMLAsPlaintextClass;      }      else if (!nsCRT::strcasecmp(content_type+5,		"enriched"))        clazz = (MimeObjectClass *)&mimeInlineTextEnrichedClass;      else if (!nsCRT::strcasecmp(content_type+5,		"richtext"))        clazz = (MimeObjectClass *)&mimeInlineTextRichtextClass;      else if (!nsCRT::strcasecmp(content_type+5,		"rtf"))        clazz = (MimeObjectClass *)&mimeExternalObjectClass;      else if (!nsCRT::strcasecmp(content_type+5,		"plain"))      {        // Preliminary use the normal plain text        clazz = (MimeObjectClass *)&mimeInlineTextPlainClass;                if (opts && opts->format_out != nsMimeOutput::nsMimeMessageFilterSniffer)        {          PRBool disable_format_flowed = PR_FALSE;          if (pref)            pref->GetBoolPref("mailnews.display.disable_format_flowed_support",                              &disable_format_flowed);          if(!disable_format_flowed)          {            // Check for format=flowed, damn, it is already stripped away from            // the contenttype!            // Look in headers instead even though it's expensive and clumsy            // First find Content-Type:            char *content_type_row =              (hdrs               ? MimeHeaders_get(hdrs, HEADER_CONTENT_TYPE,                                 PR_FALSE, PR_FALSE)               : 0);            // Then the format parameter if there is one.            // I would rather use a PARAM_FORMAT but I can't find the right            // place to put the define. The others seems to be in net.h            // but is that really really the right place? There is also            // a nsMimeTypes.h but that one isn't included. Bug?            char *content_type_format =              (content_type_row               ? MimeHeaders_get_parameter(content_type_row, "format", NULL,NULL)               : 0);            if (content_type_format && !nsCRT::strcasecmp(content_type_format,                                                          "flowed"))              clazz = (MimeObjectClass *)&mimeInlineTextPlainFlowedClass;            PR_FREEIF(content_type_format);            PR_FREEIF(content_type_row);          }        }      }      else if (!exact_match_p)        clazz = (MimeObjectClass *)&mimeInlineTextPlainClass;    }        /* Subtypes of multipart...    */    else if (!nsCRT::strncasecmp(content_type,			"multipart/", 10))    {      if      (!nsCRT::strcasecmp(content_type+10,	"alternative"))        clazz = (MimeObjectClass *)&mimeMultipartAlternativeClass;      else if (!nsCRT::strcasecmp(content_type+10,	"related"))        clazz = (MimeObjectClass *)&mimeMultipartRelatedClass;      else if (!nsCRT::strcasecmp(content_type+10,	"digest"))        clazz = (MimeObjectClass *)&mimeMultipartDigestClass;      else if (!nsCRT::strcasecmp(content_type+10,	"appledouble") ||               !nsCRT::strcasecmp(content_type+10,	"header-set"))        clazz = (MimeObjectClass *)&mimeMultipartAppleDoubleClass;      else if (!nsCRT::strcasecmp(content_type+10,	"parallel"))        clazz = (MimeObjectClass *)&mimeMultipartParallelClass;      else if (!nsCRT::strcasecmp(content_type+10,	"mixed"))        clazz = (MimeObjectClass *)&mimeMultipartMixedClass;#ifdef ENABLE_SMIME            else if (!nsCRT::strcasecmp(content_type+10,	"signed"))      {      /* Check that the "protocol" and "micalg" parameters are ones we        know about. */        char *ct = (hdrs          ? MimeHeaders_get(hdrs, HEADER_CONTENT_TYPE,                            PR_FALSE, PR_FALSE)                    : 0);        char *proto = (ct          ? MimeHeaders_get_parameter(ct, PARAM_PROTOCOL, NULL, NULL)          : 0);        char *micalg = (ct          ? MimeHeaders_get_parameter(ct, PARAM_MICALG, NULL, NULL)          : 0);          if (proto              && (                  (/* is a signature */                   !nsCRT::strcasecmp(proto, APPLICATION_XPKCS7_SIGNATURE)                   ||                   !nsCRT::strcasecmp(proto, APPLICATION_PKCS7_SIGNATURE))                  && micalg                  && (!nsCRT::strcasecmp(micalg, PARAM_MICALG_MD5) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_MD5_2) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_SHA1) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_SHA1_2) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_SHA1_3) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_SHA1_4) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_SHA1_5) ||                      !nsCRT::strcasecmp(micalg, PARAM_MICALG_MD2))))            clazz = (MimeObjectClass *)&mimeMultipartSignedCMSClass;          else            clazz = 0;                  PR_FREEIF(proto);        PR_FREEIF(micalg);        PR_FREEIF(ct);      } #endif            if (!clazz && !exact_match_p)        /* Treat all unknown multipart subtypes as "multipart/mixed" */        clazz = (MimeObjectClass *)&mimeMultipartMixedClass;      /* If we are sniffing a message, let's threat alternative parts as mixed */      if (opts && opts->format_out == nsMimeOutput::nsMimeMessageFilterSniffer)        if (clazz == (MimeObjectClass *)&mimeMultipartAlternativeClass)          clazz = (MimeObjectClass *)&mimeMultipartMixedClass;    }        /* Subtypes of message...    */    else if (!nsCRT::strncasecmp(content_type,			"message/", 8))    {      if      (!nsCRT::strcasecmp(content_type+8,		"rfc822") ||        !nsCRT::strcasecmp(content_type+8,		"news"))        clazz = (MimeObjectClass *)&mimeMessageClass;      else if (!nsCRT::strcasecmp(content_type+8,		"external-body"))        clazz = (MimeObjectClass *)&mimeExternalBodyClass;      else if (!nsCRT::strcasecmp(content_type+8,		"partial"))        /* I guess these are most useful as externals, for now... */        clazz = (MimeObjectClass *)&mimeExternalObjectClass;      else if (!exact_match_p)        /* Treat all unknown message subtypes as "text/plain" */        clazz = (MimeObjectClass *)&mimeInlineTextPlainClass;    }        /* The magic image types which we are able to display internally...    */    else if (!nsCRT::strncasecmp(content_type,		"image/", 6)) {        nsCOMPtr<imgILoader> loader(do_GetService("@mozilla.org/image/loader;1"));        PRBool isReg = PR_FALSE;        loader->SupportImageWithMimeType(content_type, &isReg);        if (isReg)          clazz = (MimeObjectClass *)&mimeInlineImageClass;        else          clazz = (MimeObjectClass *)&mimeExternalObjectClass;    }    #ifdef ENABLE_SMIME    else if (!nsCRT::strcasecmp(content_type, APPLICATION_XPKCS7_MIME)             || !nsCRT::strcasecmp(content_type, APPLICATION_PKCS7_MIME))	        clazz = (MimeObjectClass *)&mimeEncryptedCMSClass;#endif    /* A few types which occur in the real world and which we would otherwise    treat as non-text types (which would be bad) without this special-case...    */    else if (!nsCRT::strcasecmp(content_type,			APPLICATION_PGP) ||             !nsCRT::strcasecmp(content_type,			APPLICATION_PGP2))      clazz = (MimeObjectClass *)&mimeInlineTextPlainClass;    else if (!nsCRT::strcasecmp(content_type,			SUN_ATTACHMENT))      clazz = (MimeObjectClass *)&mimeSunAttachmentClass;        /* Everything else gets represented as a clickable link.    */    else if (!exact_match_p)      clazz = (MimeObjectClass *)&mimeExternalObjectClass;    if (!mime_is_allowed_class(clazz, types_of_classes_to_disallow))    {      /* Do that check here (not after the if block), because we want to allow         user-installed plugins. */      if(!exact_match_p)        clazz = (MimeObjectClass *)&mimeExternalObjectClass;      else        clazz = 0;    }  } #ifdef ENABLE_SMIME  // see bug #189988  if (opts && opts->format_out == nsMimeOutput::nsMimeMessageDecrypt &&        (clazz != (MimeObjectClass *)&mimeEncryptedCMSClass)) {    clazz = (MimeObjectClass *)&mimeExternalObjectClass;  }#endif  if (!exact_match_p)    NS_ASSERTION(clazz, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (!clazz) return 0;  NS_ASSERTION(clazz, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (clazz && !clazz->class_initialized)	{	  int status = mime_classinit(clazz);	  if (status < 0) return 0;	}  return clazz;}MimeObject *mime_create (const char *content_type, MimeHeaders *hdrs,			 MimeDisplayOptions *opts){  /* If there is no Content-Disposition header, or if the Content-Disposition	 is ``inline'', then we display the part inline (and let mime_find_class()	 decide how.)	 If there is any other Content-Disposition (either ``attachment'' or some	 disposition that we don't recognise) then we always display the part as	 an external link, by using MimeExternalObject to display it.	 But Content-Disposition is ignored for all containers except `message'.	 (including multipart/mixed, and multipart/digest.)  It's not clear if	 this is to spec, but from a usability standpoint, I think it's necessary.   */  MimeObjectClass *clazz = 0;  char *content_disposition = 0;  MimeObject *obj = 0;  char *override_content_type = 0;  /* There are some clients send out all attachments with a content-type	 of application/octet-stream.  So, if we have an octet-stream attachment,	 try to guess what type it really is based on the file extension.  I HATE	 that we have to do this...  */  if (hdrs && opts && opts->file_type_fn &&	  /* ### mwelch - don't override AppleSingle */	  (content_type ? nsCRT::strcasecmp(content_type, APPLICATION_APPLEFILE) : PR_TRUE) &&	  /* ## davidm Apple double shouldn't use this #$%& either. */	  (content_type ? nsCRT::strcasecmp(content_type, MULTIPART_APPLEDOUBLE) : PR_TRUE) &&	  (!content_type ||	   !nsCRT::strcasecmp(content_type, APPLICATION_OCTET_STREAM) ||	   !nsCRT::strcasecmp(content_type, UNKNOWN_CONTENT_TYPE)))	{	  char *name = MimeHeaders_get_name(hdrs, opts);	  if (name)		{		  override_content_type = opts->file_type_fn (name, opts->stream_closure);		  PR_FREEIF(name);      // Of, if we got here and it is not the unknown content type from the       // file name, lets do some better checking not to inline something bad      //                            if (override_content_type && (nsCRT::strcasecmp(override_content_type, UNKNOWN_CONTENT_TYPE)))      {        // Only inline this if it makes sense to do so!        if ( (!content_type) ||             (content_type && (!nsCRT::strcasecmp(content_type, UNKNOWN_CONTENT_TYPE))) )        {  	  		content_type = override_content_type;        }        else          PR_FREEIF(override_content_type);      }		}	}  clazz = mime_find_class(content_type, hdrs, opts, PR_FALSE);  NS_ASSERTION(clazz, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (!clazz) goto FAIL;  if (opts && opts->part_to_load)	/* Always ignore Content-Disposition when we're loading some specific	   sub-part (which may be within some container that we wouldn't otherwise	   descend into, if the container itself had a Content-Disposition of	   `attachment'. */	content_disposition = 0;  else if (mime_subclass_p(clazz,(MimeObjectClass *)&mimeContainerClass) &&		   !mime_subclass_p(clazz,(MimeObjectClass *)&mimeMessageClass))	/* Ignore Content-Disposition on all containers except `message'.	   That is, Content-Disposition is ignored for multipart/mixed objects,	   but is obeyed for message/rfc822 objects. */	content_disposition = 0;  else  {    /* Check to see if the plugin should override the content disposition       to make it appear inline. One example is a vcard which has a content       disposition of an "attachment;" */    if (force_inline_display(content_type))  		NS_MsgSACopy(&content_disposition, "inline");    else  		content_disposition = (hdrs							   ? MimeHeaders_get(hdrs, HEADER_CONTENT_DISPOSITION, PR_TRUE, PR_FALSE)							   : 0);  }  if (!content_disposition || !nsCRT::strcasecmp(content_disposition, "inline"))    ;	/* Use the class we've got. */  else  {     //     // rhp: Ok, this is a modification to try to deal with messages    //      that have content disposition set to "attachment" even though    //      we probably should show them inline.     //    if (  (clazz != (MimeObjectClass *)&mimeInlineTextHTMLClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextPlainClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextPlainFlowedClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextHTMLClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextHTMLSanitizedClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextHTMLAsPlaintextClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextRichtextClass) &&          (clazz != (MimeObjectClass *)&mimeInlineTextEnrichedClass) &&          (clazz != (MimeObjectClass *)&mimeMessageClass) &&          (clazz != (MimeObjectClass *)&mimeInlineImageClass) )      clazz = (MimeObjectClass *)&mimeExternalObjectClass;  }  /* If the option `Show Attachments Inline' is off, now would be the time to change our mind... */  if (opts && !opts->show_attachment_inline_p)  {    if (mime_subclass_p(clazz, (MimeObjectClass *)&mimeInlineTextClass))    {      /* It's a text type.  Write it only if it's the *first* part         that we're writing, and then only if it has no "filename"         specified (the assumption here being, if it has a filename,         it wasn't simply typed into the text field -- it was actually         an attached document.) */      if (opts->state && opts->state->first_part_written_p)        clazz = (MimeObjectClass *)&mimeExternalObjectClass;      else      {        /* If there's a name, then write this as an attachment. */        char *name = (hdrs ? MimeHeaders_get_name(hdrs, opts) : nsnull);        if (name)        {          clazz = (MimeObjectClass *)&mimeExternalObjectClass;          PR_Free(name);        }      }    }    else      if (mime_subclass_p(clazz,(MimeObjectClass *)&mimeContainerClass) &&           !mime_subclass_p(clazz,(MimeObjectClass *)&mimeMessageClass))        /* Multipart subtypes are ok, except for messages; descend into           multiparts, and defer judgement.            Encrypted blobs are just like other containers (make the crypto           layer invisible, and treat them as simple containers.  So there's           no easy way to save encrypted data directly to disk; it will tend           to always be wrapped inside a message/rfc822.  That's ok.) */          ;        else if (opts && opts->part_to_load &&                  mime_subclass_p(clazz,(MimeObjectClass *)&mimeMessageClass))          /* Descend into messages only if we're looking for a specific sub-part. */            ;          else          {            /* Anything else, and display it as a link (and cause subsequent               text parts to also be displayed as links.) */            clazz = (MimeObjectClass *)&mimeExternalObjectClass;          }  }  PR_FREEIF(content_disposition);  obj = mime_new (clazz, hdrs, content_type); FAIL:  /* If we decided to ignore the content-type in the headers of this object	 (see above) then make sure that our new content-type is stored in the	 object itself.  (Or free it, if we're in an out-of-memory situation.)   */  if (override_content_type)	{	  if (obj)		{		  PR_FREEIF(obj->content_type);		  obj->content_type = override_content_type;		}	  else		{		  PR_Free(override_content_type);		}	}  return obj;}static int mime_classinit_1(MimeObjectClass *clazz, MimeObjectClass *target);static intmime_classinit(MimeObjectClass *clazz){  int status;  if (clazz->class_initialized)	return 0;  NS_ASSERTION(clazz->class_initialize, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");  if (!clazz->class_initialize)	return -1;  /* First initialize the superclass.   */  if (clazz->superclass && !clazz->superclass->class_initialized)	{	  status = mime_classinit(clazz->superclass);	  if (status < 0) return status;	}  /* Now run each of the superclass-init procedures in turn,	 parentmost-first. */  status = mime_classinit_1(clazz, clazz);  if (status < 0) return status;  /* Now we're done. */  clazz->class_initialized = PR_TRUE;  return 0;}