зеркало из https://github.com/mozilla/pjs.git
Adding changes for external modular content type handler plugins.
This commit is contained in:
Родитель
e2d9eba7df
Коммит
c753c74eb9
|
@ -90,16 +90,17 @@ OBJS= \
|
|||
.\$(OBJDIR)\mimetric.obj \
|
||||
.\$(OBJDIR)\mimeunty.obj \
|
||||
.\$(OBJDIR)\mimemoz.obj \
|
||||
.\$(OBJDIR)\mimecth.obj \
|
||||
# VCARD REMOVAL EFFORT
|
||||
.\$(OBJDIR)\mimevcrd.obj \
|
||||
.\$(OBJDIR)\oldvcc.obj \
|
||||
.\$(OBJDIR)\oldvobj.obj \
|
||||
#
|
||||
# THIS WILL NEED WORK AFTER WE GET A LIBMSG MORE XP-COM-afied
|
||||
# .\$(OBJDIR)\mimedrft.obj \
|
||||
# XP-COM BRIDGES
|
||||
.\$(OBJDIR)\comi18n.obj \
|
||||
.\$(OBJDIR)\commsg.obj \
|
||||
# SHOULD HAVE XP-COM INTERFACES FOR THIS STUFF AND SHOULD NOT BE
|
||||
# A PART OF LIBMIME
|
||||
.\$(OBJDIR)\oldvcc.obj \
|
||||
.\$(OBJDIR)\oldvobj.obj \
|
||||
# EXTERNAL (OLD) DEPENDENCIES - SHOULD EVENTUALLY BE REMOVED
|
||||
# WHEN NEW WORLD FUNCTIONS ARE FOUND
|
||||
.\$(OBJDIR)\oldnet.obj \
|
||||
|
@ -118,11 +119,11 @@ OBJS= \
|
|||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DLLNAME=mime.dll
|
||||
LIBNAME=mime.lib
|
||||
PDBFILE=mime.pdb
|
||||
MAPFILE=mime.map
|
||||
DEFFILE=mime.def
|
||||
DLLNAME=$(MODULE).dll
|
||||
LIBNAME=$(MODULE).lib
|
||||
PDBFILE=$(MODULE).pdb
|
||||
MAPFILE=$(MODULE).map
|
||||
DEFFILE=$(MODULE).def
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
|
@ -165,6 +166,7 @@ LINCS=$(LINCS) -I. \
|
|||
-I$(PUBLIC)\netlib \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\raptor \
|
||||
-I..\..\base\public \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
|
|
|
@ -17,3 +17,10 @@ LIBRARY mime.dll
|
|||
|
||||
EXPORTS
|
||||
MIME_MessageConverter
|
||||
MIME_MimeObject_write
|
||||
MIME_GetmimeObjectClass
|
||||
MIME_GetmimeContainerClass
|
||||
MIME_GetmimeLeafClass
|
||||
MIME_GetmimeInlineTextClass
|
||||
MIME_GetmimeMultipartClass
|
||||
MIME_GetmimeMultipartSignedClass
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MIMECTH_H_
|
||||
#define _MIMECTH_H_
|
||||
|
||||
#include "mimei.h"
|
||||
#include "modmime.h"
|
||||
#include "mimeobj.h" /* MimeObject (abstract) */
|
||||
#include "mimecont.h" /* |--- MimeContainer (abstract) */
|
||||
#include "mimemult.h" /* | |--- MimeMultipart (abstract) */
|
||||
#include "mimemsig.h" /* | | |--- MimeMultipartSigned (abstract)*/
|
||||
#include "mimetext.h" /* | |--- MimeInlineText (abstract) */
|
||||
|
||||
/*
|
||||
This header exposes functions that are necessary to access the
|
||||
object heirarchy for the mime chart. The class hierarchy is:
|
||||
|
||||
MimeObject (abstract)
|
||||
|
|
||||
|--- MimeContainer (abstract)
|
||||
| |
|
||||
| |--- MimeMultipart (abstract)
|
||||
| | |
|
||||
| | |--- MimeMultipartMixed
|
||||
| | |
|
||||
| | |--- MimeMultipartDigest
|
||||
| | |
|
||||
| | |--- MimeMultipartParallel
|
||||
| | |
|
||||
| | |--- MimeMultipartAlternative
|
||||
| | |
|
||||
| | |--- MimeMultipartRelated
|
||||
| | |
|
||||
| | |--- MimeMultipartAppleDouble
|
||||
| | |
|
||||
| | |--- MimeSunAttachment
|
||||
| | |
|
||||
| | |--- MimeMultipartSigned (abstract)
|
||||
| | |
|
||||
| | |--- MimeMultipartSigned
|
||||
| |
|
||||
| |--- MimeXlateed (abstract)
|
||||
| | |
|
||||
| | |--- MimeXlateed
|
||||
| |
|
||||
| |--- MimeMessage
|
||||
| |
|
||||
| |--- MimeUntypedText
|
||||
|
|
||||
|--- MimeLeaf (abstract)
|
||||
| |
|
||||
| |--- MimeInlineText (abstract)
|
||||
| | |
|
||||
| | |--- MimeInlineTextPlain
|
||||
| | |
|
||||
| | |--- MimeInlineTextHTML
|
||||
| | |
|
||||
| | |--- MimeInlineTextRichtext
|
||||
| | | |
|
||||
| | | |--- MimeInlineTextEnriched
|
||||
| | |
|
||||
| | |--- MimeInlineTextVCard
|
||||
| | |
|
||||
| | |--- MimeInlineTextCalendar
|
||||
| |
|
||||
| |--- MimeInlineImage
|
||||
| |
|
||||
| |--- MimeExternalObject
|
||||
|
|
||||
|--- MimeExternalBody
|
||||
*/
|
||||
|
||||
#define MIME_PLUGIN_PREFIX "mimect-"
|
||||
#define MIME_PLUGIN_DIR "mimeplugins"
|
||||
|
||||
extern int MIME_MimeObject_write(MimeObject *, char *data,
|
||||
PRInt32 length,
|
||||
PRBool user_visible_p);
|
||||
extern MimeInlineTextClass *MIME_GetmimeInlineTextClass(void);
|
||||
extern MimeLeafClass *MIME_GetmimeLeafClass(void);
|
||||
extern MimeObjectClass *MIME_GetmimeObjectClass(void);
|
||||
extern MimeContainerClass *MIME_GetmimeContainerClass(void);
|
||||
extern MimeMultipartClass *MIME_GetmimeMultipartClass(void);
|
||||
extern MimeMultipartSignedClass *MIME_GetmimeMultipartSignedClass(void);
|
||||
|
||||
#endif /* _MIMECTH_H_ */
|
||||
|
||||
|
||||
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsMsgMessageFlags.h"
|
||||
#include "mimerosetta.h"
|
||||
#include "mimei.h"
|
||||
#include "xpgetstr.h"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "mimerosetta.h"
|
||||
|
||||
#ifdef MOZ_SECURITY
|
||||
|
@ -49,28 +48,235 @@
|
|||
#include "mimethtm.h" /* | | |--- MimeInlineTextHTML */
|
||||
#include "mimetric.h" /* | | |--- MimeInlineTextRichtext */
|
||||
#include "mimetenr.h" /* | | | |--- MimeInlineTextEnriched */
|
||||
#ifndef MOZILLA_30
|
||||
#include "mimevcrd.h" /* | | |--------- MimeInlineTextVCard */
|
||||
#ifdef RICHIE_CAL
|
||||
#include "mimecal.h" /* | | |--------- MimeInlineTextCalendar */
|
||||
/* SUPPORTED VIA PLUGIN | | |--------- MimeInlineTextCalendar */
|
||||
|
||||
#define RICHIE_VCARD 1
|
||||
#ifdef RICHIE_VCARD
|
||||
#include "mimevcrd.h" /* | | |--------- MimeInlineTextVCard */
|
||||
#endif
|
||||
|
||||
#include "prefapi.h"
|
||||
#endif /* !MOZILLA_30 */
|
||||
#include "mimeiimg.h" /* | |--- MimeInlineImage */
|
||||
#include "mimeeobj.h" /* | |--- MimeExternalObject */
|
||||
#include "mimeebod.h" /* |--- MimeExternalBody */
|
||||
|
||||
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "mimecth.h"
|
||||
|
||||
/* ==========================================================================
|
||||
Allocation and destruction
|
||||
==========================================================================
|
||||
*/
|
||||
|
||||
static int mime_classinit(MimeObjectClass *class);
|
||||
|
||||
/*
|
||||
* These are the necessary defines/variables for doing
|
||||
* content type handlers in external plugins.
|
||||
*/
|
||||
typedef struct {
|
||||
char *content_type;
|
||||
char *file_name;
|
||||
#ifdef XP_PC
|
||||
HINSTANCE ct_handler;
|
||||
#endif
|
||||
} cthandler_struct;
|
||||
|
||||
cthandler_struct *cthandler_list = NULL;
|
||||
PRInt32 plugin_count = -1;
|
||||
|
||||
/*
|
||||
* This will find the directory for content type handler plugins.
|
||||
*/
|
||||
PRBool
|
||||
find_plugin_directory(char *path, PRInt32 size)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
char *ptr;
|
||||
|
||||
if (!GetModuleFileName(NULL, path, size))
|
||||
return FALSE;
|
||||
ptr = PL_strrchr(path, '\\');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
PL_strcat(path, "\\");
|
||||
PL_strcat(path, MIME_PLUGIN_DIR);
|
||||
#else
|
||||
printf("Don't know how to locate plugins directory on Unix/Mac yet...\n");
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This will locate the number of content type handler plugins.
|
||||
*/
|
||||
PRInt32
|
||||
get_plugin_count(void)
|
||||
{
|
||||
PRDirEntry *dirEntry;
|
||||
PRInt32 count = 0;
|
||||
PRDir *dir;
|
||||
char path[1024];
|
||||
|
||||
if (!find_plugin_directory(path, sizeof(path)))
|
||||
return 0;
|
||||
|
||||
dir = PR_OpenDir(path);
|
||||
if (!dir)
|
||||
return count;
|
||||
|
||||
do
|
||||
{
|
||||
dirEntry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);
|
||||
if (!dirEntry)
|
||||
break;
|
||||
|
||||
if (PL_strncasecmp(MIME_PLUGIN_PREFIX, dirEntry->name, PL_strlen(MIME_PLUGIN_PREFIX)) == 0)
|
||||
++count;
|
||||
} while (dirEntry != NULL);
|
||||
|
||||
PR_CloseDir(dir);
|
||||
return count;
|
||||
}
|
||||
|
||||
char *
|
||||
get_content_type(cthandler_struct *ct)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
char * (FAR PASCAL *lpfnMIME_GetContentType) (void);
|
||||
|
||||
(FARPROC)lpfnMIME_GetContentType = GetProcAddress(ct->ct_handler, "MIME_GetContentType");
|
||||
if (!lpfnMIME_GetContentType)
|
||||
return NULL;
|
||||
|
||||
return ( (*lpfnMIME_GetContentType) () );
|
||||
#else /* Unix and Mac */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
MimeObjectClass *
|
||||
create_content_type_handler_class(cthandler_struct *ct)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
MimeObjectClass * (FAR PASCAL *lpfnMIME_CreateContentTypeHandlerClass) (const char *);
|
||||
|
||||
(FARPROC)lpfnMIME_CreateContentTypeHandlerClass = GetProcAddress(ct->ct_handler, "MIME_CreateContentTypeHandlerClass");
|
||||
if (lpfnMIME_CreateContentTypeHandlerClass)
|
||||
return (lpfnMIME_CreateContentTypeHandlerClass)(ct->content_type);
|
||||
else
|
||||
return NULL;
|
||||
#else /* Unix and Mac */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to initialize a table of external modules and
|
||||
* the content type that it will process. What we will do is check
|
||||
* the directory "mimeplugins" under the location where this DLL is
|
||||
* running. Any DLL in that directory will have the naming convention:
|
||||
*
|
||||
* mimect-mycontenttype.dll - where mycontenttype is the content type being
|
||||
* processed.
|
||||
*
|
||||
* This DLL will have specifically defined entry points to be used by
|
||||
* libmime for processing the data stream.
|
||||
*/
|
||||
PRInt32
|
||||
do_plugin_discovery(void)
|
||||
{
|
||||
PRDirEntry *dirEntry;
|
||||
PRInt32 count = 0;
|
||||
PRDir *dir;
|
||||
char path[1024];
|
||||
char full_name[1024];
|
||||
|
||||
if (!find_plugin_directory(path, sizeof(path)))
|
||||
return 0;
|
||||
|
||||
count = get_plugin_count();
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
cthandler_list = PR_MALLOC(count * sizeof(cthandler_struct));
|
||||
if (!cthandler_list)
|
||||
return 0;
|
||||
|
||||
dir = PR_OpenDir(path);
|
||||
if (!dir)
|
||||
return 0;
|
||||
|
||||
count = 0;
|
||||
do
|
||||
{
|
||||
dirEntry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);
|
||||
if (!dirEntry)
|
||||
break;
|
||||
|
||||
if (PL_strncasecmp(MIME_PLUGIN_PREFIX, dirEntry->name, PL_strlen(MIME_PLUGIN_PREFIX)) == 0)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
PL_strcpy(full_name, path);
|
||||
PL_strcat(full_name, "\\");
|
||||
PL_strcat(full_name, dirEntry->name);
|
||||
cthandler_list[count].ct_handler = LoadLibrary(full_name);
|
||||
if (!cthandler_list[count].ct_handler)
|
||||
continue;
|
||||
|
||||
cthandler_list[count].file_name = PL_strdup(full_name);
|
||||
if (!cthandler_list[count].file_name)
|
||||
{
|
||||
FreeLibrary(cthandler_list[count].ct_handler);
|
||||
continue;
|
||||
}
|
||||
|
||||
cthandler_list[count].content_type = PL_strdup(get_content_type(&(cthandler_list[count])));
|
||||
if (!cthandler_list[count].content_type)
|
||||
{
|
||||
FreeLibrary(cthandler_list[count].ct_handler);
|
||||
PR_FREEIF(cthandler_list[count].file_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
++count;
|
||||
#endif
|
||||
}
|
||||
} while (dirEntry != NULL);
|
||||
|
||||
PR_CloseDir(dir);
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will find all content type handler for a specifc content
|
||||
* type (if it exists)
|
||||
*/
|
||||
MimeObjectClass *
|
||||
mime_locate_external_content_handler(const char *content_type)
|
||||
{
|
||||
PRInt32 i;
|
||||
|
||||
if (plugin_count < 0)
|
||||
plugin_count = do_plugin_discovery();
|
||||
|
||||
for (i=0; i<plugin_count; i++)
|
||||
{
|
||||
if (PL_strcasecmp(content_type, cthandler_list[i].content_type) == 0)
|
||||
return( create_content_type_handler_class((&cthandler_list[i])) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is necessary to expose the MimeObject method outside of this DLL */
|
||||
int
|
||||
MIME_MimeObject_write(MimeObject *obj, char *output, PRInt32 length, PRBool user_visible_p)
|
||||
{
|
||||
return MimeObject_write(obj, output, length, user_visible_p);
|
||||
}
|
||||
|
||||
MimeObject *
|
||||
mime_new (MimeObjectClass *class, MimeHeaders *hdrs,
|
||||
const char *override_content_type)
|
||||
|
@ -143,136 +349,141 @@ mime_find_class (const char *content_type, MimeHeaders *hdrs,
|
|||
MimeDisplayOptions *opts, PRBool exact_match_p)
|
||||
{
|
||||
MimeObjectClass *class = 0;
|
||||
MimeObjectClass *tempClass = 0;
|
||||
|
||||
if (!content_type || !*content_type ||
|
||||
!PL_strcasecmp(content_type, "text")) /* with no / in the type */
|
||||
class = (MimeObjectClass *)&mimeUntypedTextClass;
|
||||
|
||||
/* Subtypes of text...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "text/", 5))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+5, "html"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextHTMLClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "enriched"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextEnrichedClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "richtext"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextRichtextClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "plain"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
#ifndef MOZILLA_30
|
||||
else if (!PL_strcasecmp(content_type+5, "x-vcard"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextVCardClass;
|
||||
#ifdef RICHIE_CAL
|
||||
else if (!PL_strcasecmp(content_type+5, "calendar"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextCalendarClass;
|
||||
/*
|
||||
* 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)) != NULL)
|
||||
{
|
||||
class = (MimeObjectClass *)tempClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!content_type || !*content_type ||
|
||||
!PL_strcasecmp(content_type, "text")) /* with no / in the type */
|
||||
class = (MimeObjectClass *)&mimeUntypedTextClass;
|
||||
|
||||
/* Subtypes of text...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "text/", 5))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+5, "html"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextHTMLClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "enriched"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextEnrichedClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "richtext"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextRichtextClass;
|
||||
else if (!PL_strcasecmp(content_type+5, "plain"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
|
||||
#ifdef RICHIE_VCARD
|
||||
else if (!PL_strcasecmp(content_type+5, "x-vcard"))
|
||||
class = (MimeObjectClass *)&mimeInlineTextVCardClass;
|
||||
#endif
|
||||
#endif /* !MOZILLA_30 */
|
||||
else if (!exact_match_p)
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
}
|
||||
|
||||
/* Subtypes of multipart...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "multipart/", 10))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+10, "alternative"))
|
||||
class = (MimeObjectClass *)&mimeMultipartAlternativeClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "related"))
|
||||
class = (MimeObjectClass *)&mimeMultipartRelatedClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "digest"))
|
||||
class = (MimeObjectClass *)&mimeMultipartDigestClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "appledouble") ||
|
||||
!PL_strcasecmp(content_type+10, "header-set"))
|
||||
class = (MimeObjectClass *)&mimeMultipartAppleDoubleClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "parallel"))
|
||||
class = (MimeObjectClass *)&mimeMultipartParallelClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "mixed"))
|
||||
class = (MimeObjectClass *)&mimeMultipartMixedClass;
|
||||
|
||||
else if (!PL_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,
|
||||
|
||||
else if (!exact_match_p)
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
}
|
||||
|
||||
/* Subtypes of multipart...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "multipart/", 10))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+10, "alternative"))
|
||||
class = (MimeObjectClass *)&mimeMultipartAlternativeClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "related"))
|
||||
class = (MimeObjectClass *)&mimeMultipartRelatedClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "digest"))
|
||||
class = (MimeObjectClass *)&mimeMultipartDigestClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "appledouble") ||
|
||||
!PL_strcasecmp(content_type+10, "header-set"))
|
||||
class = (MimeObjectClass *)&mimeMultipartAppleDoubleClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "parallel"))
|
||||
class = (MimeObjectClass *)&mimeMultipartParallelClass;
|
||||
else if (!PL_strcasecmp(content_type+10, "mixed"))
|
||||
class = (MimeObjectClass *)&mimeMultipartMixedClass;
|
||||
|
||||
else if (!PL_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);
|
||||
|
||||
: 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);
|
||||
|
||||
#ifdef MOZ_SECURITY
|
||||
HG01444
|
||||
HG01444
|
||||
#endif
|
||||
|
||||
PR_FREEIF(proto);
|
||||
PR_FREEIF(micalg);
|
||||
PR_FREEIF(ct);
|
||||
}
|
||||
|
||||
if (!class && !exact_match_p)
|
||||
/* Treat all unknown multipart subtypes as "multipart/mixed" */
|
||||
class = (MimeObjectClass *)&mimeMultipartMixedClass;
|
||||
}
|
||||
|
||||
/* Subtypes of message...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "message/", 8))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+8, "rfc822") ||
|
||||
!PL_strcasecmp(content_type+8, "news"))
|
||||
class = (MimeObjectClass *)&mimeMessageClass;
|
||||
else if (!PL_strcasecmp(content_type+8, "external-body"))
|
||||
class = (MimeObjectClass *)&mimeExternalBodyClass;
|
||||
else if (!PL_strcasecmp(content_type+8, "partial"))
|
||||
/* I guess these are most useful as externals, for now... */
|
||||
class = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
else if (!exact_match_p)
|
||||
/* Treat all unknown message subtypes as "text/plain" */
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
}
|
||||
|
||||
/* The magic image types which we are able to display internally...
|
||||
*/
|
||||
else if (!PL_strcasecmp(content_type, IMAGE_GIF) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_JPG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_PJPG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_PNG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM2) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM3))
|
||||
class = (MimeObjectClass *)&mimeInlineImageClass;
|
||||
|
||||
|
||||
PR_FREEIF(proto);
|
||||
PR_FREEIF(micalg);
|
||||
PR_FREEIF(ct);
|
||||
}
|
||||
|
||||
if (!class && !exact_match_p)
|
||||
/* Treat all unknown multipart subtypes as "multipart/mixed" */
|
||||
class = (MimeObjectClass *)&mimeMultipartMixedClass;
|
||||
}
|
||||
|
||||
/* Subtypes of message...
|
||||
*/
|
||||
else if (!PL_strncasecmp(content_type, "message/", 8))
|
||||
{
|
||||
if (!PL_strcasecmp(content_type+8, "rfc822") ||
|
||||
!PL_strcasecmp(content_type+8, "news"))
|
||||
class = (MimeObjectClass *)&mimeMessageClass;
|
||||
else if (!PL_strcasecmp(content_type+8, "external-body"))
|
||||
class = (MimeObjectClass *)&mimeExternalBodyClass;
|
||||
else if (!PL_strcasecmp(content_type+8, "partial"))
|
||||
/* I guess these are most useful as externals, for now... */
|
||||
class = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
else if (!exact_match_p)
|
||||
/* Treat all unknown message subtypes as "text/plain" */
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
}
|
||||
|
||||
/* The magic image types which we are able to display internally...
|
||||
*/
|
||||
else if (!PL_strcasecmp(content_type, IMAGE_GIF) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_JPG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_PJPG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_PNG) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM2) ||
|
||||
!PL_strcasecmp(content_type, IMAGE_XBM3))
|
||||
class = (MimeObjectClass *)&mimeInlineImageClass;
|
||||
|
||||
#ifdef MOZ_SECURITY
|
||||
HG01555
|
||||
HG01555
|
||||
#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 (!PL_strcasecmp(content_type, APPLICATION_PGP) ||
|
||||
!PL_strcasecmp(content_type, APPLICATION_PGP2))
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
|
||||
else if (!PL_strcasecmp(content_type, SUN_ATTACHMENT))
|
||||
class = (MimeObjectClass *)&mimeSunAttachmentClass;
|
||||
|
||||
/*
|
||||
* RICHIECT
|
||||
* This is where we will actually extend the mime handling for libmime
|
||||
* with a call to a MIME External Content Type Handler.
|
||||
else if (content_type lives in our list somewhere!)
|
||||
class = (MimeObjectClass *)&mimeExternalContentTypeHandler;
|
||||
*/
|
||||
|
||||
/* Everything else gets represented as a clickable link.
|
||||
*/
|
||||
else if (!exact_match_p)
|
||||
class = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
|
||||
/* 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 (!PL_strcasecmp(content_type, APPLICATION_PGP) ||
|
||||
!PL_strcasecmp(content_type, APPLICATION_PGP2))
|
||||
class = (MimeObjectClass *)&mimeInlineTextPlainClass;
|
||||
|
||||
else if (!PL_strcasecmp(content_type, SUN_ATTACHMENT))
|
||||
class = (MimeObjectClass *)&mimeSunAttachmentClass;
|
||||
|
||||
/* Everything else gets represented as a clickable link.
|
||||
*/
|
||||
else if (!exact_match_p)
|
||||
class = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
}
|
||||
|
||||
if (!exact_match_p)
|
||||
PR_ASSERT(class);
|
||||
|
@ -367,9 +578,7 @@ mime_create (const char *content_type, MimeHeaders *hdrs,
|
|||
|
||||
if (!got_lookup_pref)
|
||||
{
|
||||
#ifndef MOZILLA_30
|
||||
PREF_GetBoolPref("mailnews.autolookup_unknown_mime_types",&reverse_lookup);
|
||||
#endif
|
||||
got_lookup_pref = PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -434,11 +643,16 @@ mime_create (const char *content_type, MimeHeaders *hdrs,
|
|||
{
|
||||
/* change content-Disposition for vcards to be inline so */
|
||||
/* we can see a nice html display */
|
||||
#ifndef MOZILLA_30
|
||||
if (mime_subclass_p(class,(MimeObjectClass *)&mimeInlineTextVCardClass))
|
||||
StrAllocCopy(content_disposition, "inline");
|
||||
else
|
||||
#endif /* !MOZILLA_30 */
|
||||
#ifdef RICHIE_VCARD
|
||||
if (mime_subclass_p(class,(MimeObjectClass *)&mimeInlineTextVCardClass))
|
||||
StrAllocCopy(content_disposition, "inline");
|
||||
else
|
||||
#else
|
||||
if (!PL_strcasecmp(content_type+5, "x-vcard"))
|
||||
StrAllocCopy(content_disposition, "inline");
|
||||
else
|
||||
#endif
|
||||
|
||||
content_disposition = (hdrs
|
||||
? MimeHeaders_get(hdrs, HEADER_CONTENT_DISPOSITION,
|
||||
PR_TRUE, PR_FALSE)
|
||||
|
|
|
@ -79,10 +79,10 @@
|
|||
| | |--- MimeInlineTextRichtext
|
||||
| | | |
|
||||
| | | |--- MimeInlineTextEnriched
|
||||
| | |
|
||||
| | |--- MimeInlineTextVCard
|
||||
| | |
|
||||
| | |--- MimeInlineTextCalendar
|
||||
| | |
|
||||
| | |--- MimeInlineTextVCard
|
||||
| | |
|
||||
| | |--- MimeInlineTextCalendar
|
||||
| |
|
||||
| |--- MimeInlineImage
|
||||
| |
|
||||
|
@ -377,12 +377,6 @@ extern PRBool MimeObjectChildIsMessageBody(MimeObject *obj,
|
|||
|
||||
#endif /* MOZILLA_30 */
|
||||
|
||||
/* Sends some mail, without user interaction. */
|
||||
extern int
|
||||
MimeSendMessage(MimeDisplayOptions* options, char* to, char* subject,
|
||||
char* otherheaders, char* body);
|
||||
|
||||
|
||||
/* #### These ought to be in libxp or nspr, not libmsg...*/
|
||||
#if 0
|
||||
extern int msg_GrowBuffer (PRInt32 desired_size, PRInt32 element_size,
|
||||
|
|
|
@ -36,20 +36,18 @@
|
|||
#include "mimetric.h" /* for MIME_RichtextConverter */
|
||||
#include "mimethtm.h"
|
||||
#include "mimemsig.h"
|
||||
#ifndef MOZILLA_30
|
||||
#include "mimemrel.h"
|
||||
#include "mimemalt.h"
|
||||
# include "xpgetstr.h"
|
||||
#include "xpgetstr.h"
|
||||
|
||||
#ifdef RICHIE_VCARD
|
||||
# include "mimevcrd.h" /* for MIME_VCardConverter */
|
||||
#ifdef RICHIE_CAL
|
||||
# include "mimecal.h" /* for MIME_JulianConverter */
|
||||
#endif
|
||||
#endif RICHIE_VCARD
|
||||
|
||||
# include "edt.h"
|
||||
extern int XP_FORWARDED_MESSAGE_ATTACHMENT;
|
||||
#endif /* !MOZILLA_30 */
|
||||
extern int XP_FORWARDED_MESSAGE_ATTACHMENT;
|
||||
|
||||
#include "mimerosetta.h"
|
||||
|
||||
#ifdef MOZ_SECURITY
|
||||
#include HG01944
|
||||
#include HG04488
|
||||
|
@ -63,23 +61,8 @@
|
|||
#include "prprf.h"
|
||||
#include "intl_csi.h"
|
||||
|
||||
#ifdef RICHIE
|
||||
#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_MAC)
|
||||
#if !defined(MOZ_LITE)
|
||||
#define JULIAN_EXISTS 1 /* Julian isn't working on mac yet */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* RICHIE */
|
||||
|
||||
|
||||
#ifdef JULIAN_EXISTS
|
||||
#include "julianform.h"
|
||||
#include "prefapi.h"
|
||||
#include "fe_proto.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MIME_DATA_SLOT
|
||||
# define LOCK_LAST_CACHED_MESSAGE
|
||||
#define LOCK_LAST_CACHED_MESSAGE
|
||||
#endif
|
||||
|
||||
#include "mimei.h" /* for moved MimeDisplayData struct */
|
||||
|
@ -2285,6 +2268,7 @@ MIME_DisplayAttachmentPane(MWContext* context)
|
|||
}
|
||||
|
||||
|
||||
#ifdef RICHIE_VCARD
|
||||
/* This struct is the state we used in MIME_VCardConverter() */
|
||||
struct mime_vcard_data {
|
||||
URL_Struct *url; /* original url */
|
||||
|
@ -2376,12 +2360,15 @@ mime_vcard_abort (void *stream, int status )
|
|||
PR_Free (vcd);
|
||||
}
|
||||
|
||||
#endif /* RICHIE_VCARD */
|
||||
|
||||
extern int MIME_HasAttachments(MWContext *context)
|
||||
{
|
||||
return (context->mime_data && context->mime_data->last_parsed_object->showAttachmentIcon);
|
||||
}
|
||||
|
||||
|
||||
#ifdef RICHIE_VCARD
|
||||
|
||||
extern NET_StreamClass *
|
||||
MIME_VCardConverter2 ( int format_out,
|
||||
|
@ -2493,263 +2480,6 @@ MIME_VCardConverter2 ( int format_out,
|
|||
return stream;
|
||||
}
|
||||
|
||||
#endif /* RICHIE_VCARD */
|
||||
|
||||
#endif /* !MOZILLA_30 */
|
||||
|
||||
|
||||
|
||||
int
|
||||
MimeSendMessage(MimeDisplayOptions* options, char* to, char* subject,
|
||||
char* otherheaders, char* body)
|
||||
{
|
||||
struct mime_stream_data* msd =
|
||||
(struct mime_stream_data*) options->stream_closure;
|
||||
|
||||
return 0;
|
||||
#ifdef RICHIE
|
||||
return NET_SendMessageUnattended(msd->context, to, subject,
|
||||
otherheaders, body);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mime_TranslateCalendar(char* caldata, char** html)
|
||||
{
|
||||
#ifdef JULIAN_EXISTS
|
||||
static PRBool initialized = PR_FALSE;
|
||||
static PRBool bFoundNLSDataDirectory = PR_FALSE;
|
||||
void* closure;
|
||||
if (!initialized) {
|
||||
Julian_Form_Callback_Struct jcbs;
|
||||
|
||||
jcbs.my_context = (MWContext *)XP_FindSomeContext;
|
||||
jcbs.callbackurl = NET_CallbackURLCreate;
|
||||
jcbs.callbackurlfree = NET_CallbackURLFree;
|
||||
jcbs.ParseURL = NET_ParseURL;
|
||||
jcbs.MakeNewWindow = FE_MakeNewWindow;
|
||||
jcbs.CreateURLStruct = NET_CreateURLStruct;
|
||||
jcbs.BeginParseMDL = PA_BeginParseMDL;
|
||||
jcbs.ProcessTag = LO_ProcessTag;
|
||||
jcbs.SACopy = NET_SACopy;
|
||||
jcbs.RaiseWindow = FE_RaiseWindow;
|
||||
jcbs.FindSomeContext = XP_FindSomeContext;
|
||||
jcbs.FindNamedContextInList = XP_FindNamedContextInList;
|
||||
jcbs.CopyCharPref = PREF_CopyCharPref;
|
||||
jcbs.BoolPref = PREF_GetBoolPref;
|
||||
jcbs.IntPref = PREF_GetIntPref;
|
||||
jcbs.UnEscape = NET_UnEscape;
|
||||
jcbs.PlusToSpace = NET_PlusToSpace;
|
||||
jcbs.SetCharPref = PREF_SetCharPref;
|
||||
|
||||
/* John Sun added 4-22-98 */
|
||||
jcbs.SendMessageUnattended = NET_SendMessageUnattended;
|
||||
jcbs.DestroyWindow = FE_DestroyWindow;
|
||||
|
||||
jcbs.GetJulianPath = FEU_GetJulianPath;
|
||||
jcbs.GetString = XP_GetString;
|
||||
|
||||
bFoundNLSDataDirectory = jf_Initialize(&jcbs);
|
||||
initialized = PR_TRUE;
|
||||
}
|
||||
closure = jf_New(caldata, (PRBool) bFoundNLSDataDirectory);
|
||||
*html = jf_getForm(closure);
|
||||
jf_Destroy(closure);
|
||||
return 0;
|
||||
#else
|
||||
*html = PL_strdup("<b>Can't handle calendar data on this platform yet</b>");
|
||||
return 0;
|
||||
#endif /* JULIAN_EXISTS */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* MIME_JulianConverter Stream handler stuff
|
||||
*
|
||||
*/
|
||||
|
||||
struct mime_calendar_data {
|
||||
URL_Struct *url; /* original url */
|
||||
int format_out; /* intended output format; should be TEXT-CALENDAR */
|
||||
MWContext *context;
|
||||
NET_StreamClass *stream; /* not used for now */
|
||||
MimeDisplayOptions *options; /* data for communicating with libmime.a */
|
||||
MimeObject *obj; /* The root */
|
||||
};
|
||||
|
||||
|
||||
static int mime_calendar_write (void *stream, const char *buf, PRInt32 size )
|
||||
{
|
||||
struct mime_calendar_data *cald = (struct mime_calendar_data *) stream;
|
||||
PR_ASSERT ( cald );
|
||||
|
||||
if ( !cald || !cald->obj ) return -1;
|
||||
|
||||
return cald->obj->class->parse_line ((char *) buf, size, cald->obj);
|
||||
}
|
||||
|
||||
static unsigned int mime_calendar_write_ready (void *stream)
|
||||
{
|
||||
struct mime_calendar_data *cald = (struct mime_calendar_data *) stream;
|
||||
PR_ASSERT (cald);
|
||||
|
||||
if (!cald) return MAX_WRITE_READY;
|
||||
if (cald->stream)
|
||||
return cald->stream->is_write_ready ( cald->stream );
|
||||
else
|
||||
return MAX_WRITE_READY;
|
||||
}
|
||||
|
||||
static void mime_calendar_complete (void *stream)
|
||||
{
|
||||
struct mime_calendar_data *cald = (struct mime_calendar_data *) stream;
|
||||
|
||||
PR_ASSERT (cald);
|
||||
|
||||
if (!cald) return;
|
||||
|
||||
if (cald->obj) {
|
||||
int status;
|
||||
|
||||
status = cald->obj->class->parse_eof ( cald->obj, PR_FALSE );
|
||||
cald->obj->class->parse_end( cald->obj, status < 0 ? PR_TRUE : PR_FALSE );
|
||||
|
||||
mime_free (cald->obj);
|
||||
cald->obj = 0;
|
||||
|
||||
if (cald->stream) {
|
||||
cald->stream->complete (cald->stream);
|
||||
PR_Free( cald->stream );
|
||||
cald->stream = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mime_calendar_abort (void *stream, int status )
|
||||
{
|
||||
struct mime_calendar_data *cald = (struct mime_calendar_data *) stream;
|
||||
|
||||
PR_ASSERT (cald);
|
||||
if (!cald) return;
|
||||
|
||||
if (cald->obj) {
|
||||
int status;
|
||||
|
||||
if ( !cald->obj->closed_p )
|
||||
status = cald->obj->class->parse_eof ( cald->obj, PR_TRUE );
|
||||
if ( !cald->obj->parsed_p )
|
||||
cald->obj->class->parse_end( cald->obj, PR_TRUE );
|
||||
|
||||
mime_free (cald->obj);
|
||||
cald->obj = 0;
|
||||
|
||||
if (cald->stream) {
|
||||
cald->stream->abort (cald->stream, status);
|
||||
PR_Free( cald->stream );
|
||||
cald->stream = 0;
|
||||
}
|
||||
}
|
||||
PR_Free (cald);
|
||||
}
|
||||
|
||||
extern NET_StreamClass * MIME_JulianConverter (int format_out, void *closure, URL_Struct *url, MWContext *context )
|
||||
{
|
||||
int status = 0;
|
||||
NET_StreamClass * stream = NULL;
|
||||
NET_StreamClass * next_stream = NULL;
|
||||
struct mime_calendar_data *cald = NULL;
|
||||
MimeObject *obj;
|
||||
|
||||
PR_ASSERT (url && context);
|
||||
if ( !url || !context ) return NULL;
|
||||
|
||||
next_stream = mime_make_output_stream (TEXT_HTML, 0, 0, 0, 0,
|
||||
format_out, url, context, NULL);
|
||||
|
||||
if (!next_stream) return 0;
|
||||
|
||||
cald = PR_NEWZAP (struct mime_calendar_data);
|
||||
if (!cald) {
|
||||
PR_Free (next_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cald->url = url;
|
||||
cald->context = context;
|
||||
cald->format_out = format_out;
|
||||
cald->stream = next_stream;
|
||||
|
||||
cald->options = PR_NEWZAP ( MimeDisplayOptions );
|
||||
|
||||
if ( !cald->options ) {
|
||||
PR_Free (next_stream);
|
||||
PR_Free ( cald );
|
||||
return 0;
|
||||
}
|
||||
|
||||
cald->options->write_html_p = PR_TRUE;
|
||||
cald->options->output_fn = mime_output_fn;
|
||||
if (format_out == FO_NGLAYOUT ||
|
||||
format_out == FO_CACHE_AND_NGLAYOUT)
|
||||
cald->options->output_vcard_buttons_p = PR_FALSE;
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
cald->options->decompose_file_p = PR_FALSE; /* new field in MimeDisplayOptions */
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
cald->options->url = url->address;
|
||||
cald->options->stream_closure = cald;
|
||||
cald->options->html_closure = cald;
|
||||
|
||||
#ifdef RICHIE_CAL
|
||||
obj = mime_new ( (MimeObjectClass *) &mimeInlineTextCalendarClass,
|
||||
(MimeHeaders *) NULL,
|
||||
TEXT_CALENDAR );
|
||||
#endif
|
||||
|
||||
if ( !obj ) {
|
||||
PR_FREEIF( cald->options->part_to_load );
|
||||
PR_Free ( next_stream );
|
||||
PR_Free ( cald->options );
|
||||
PR_Free ( cald );
|
||||
return 0;
|
||||
}
|
||||
|
||||
obj->options = cald->options;
|
||||
cald->obj = obj;
|
||||
|
||||
stream = PR_NEWZAP ( NET_StreamClass );
|
||||
if ( !stream ) {
|
||||
PR_FREEIF ( cald->options->part_to_load );
|
||||
PR_Free ( next_stream );
|
||||
PR_Free ( cald->options );
|
||||
PR_Free ( cald );
|
||||
PR_Free ( obj );
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream->name = "MIME To Calendar Converter Stream";
|
||||
stream->complete = mime_calendar_complete;
|
||||
stream->abort = mime_calendar_abort;
|
||||
stream->put_block = mime_calendar_write;
|
||||
stream->is_write_ready = mime_calendar_write_ready;
|
||||
stream->data_object = cald;
|
||||
stream->window_id = context;
|
||||
|
||||
status = obj->class->initialize ( obj );
|
||||
if ( status >= 0 )
|
||||
status = obj->class->parse_begin ( obj );
|
||||
if ( status < 0 ) {
|
||||
PR_Free ( stream );
|
||||
PR_FREEIF( cald->options->part_to_load );
|
||||
PR_Free ( next_stream );
|
||||
PR_Free ( cald->options );
|
||||
PR_Free ( cald );
|
||||
PR_Free ( obj );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,608 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "mimemult.h"
|
||||
#include "modmime.h"
|
||||
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#define MIME_SUPERCLASS mimeContainerClass
|
||||
MimeDefClass(MimeMultipart, MimeMultipartClass,
|
||||
mimeMultipartClass, &MIME_SUPERCLASS);
|
||||
|
||||
static int MimeMultipart_initialize (MimeObject *);
|
||||
static void MimeMultipart_finalize (MimeObject *);
|
||||
static int MimeMultipart_parse_line (char *line, PRInt32 length, MimeObject *);
|
||||
static int MimeMultipart_parse_eof (MimeObject *object, PRBool abort_p);
|
||||
|
||||
static MimeMultipartBoundaryType MimeMultipart_check_boundary(MimeObject *,
|
||||
const char *,
|
||||
PRInt32);
|
||||
static int MimeMultipart_create_child(MimeObject *);
|
||||
static PRBool MimeMultipart_output_child_p(MimeObject *, MimeObject *);
|
||||
static int MimeMultipart_parse_child_line (MimeObject *, char *, PRInt32,
|
||||
PRBool);
|
||||
static int MimeMultipart_close_child(MimeObject *);
|
||||
|
||||
extern MimeObjectClass mimeMultipartAlternativeClass;
|
||||
extern MimeObjectClass mimeMultipartRelatedClass;
|
||||
extern MimeObjectClass mimeMultipartSignedClass;
|
||||
extern MimeObjectClass mimeInlineTextVCardClass;
|
||||
|
||||
#if defined(DEBUG) && defined(XP_UNIX)
|
||||
static int MimeMultipart_debug_print (MimeObject *, FILE *, PRInt32);
|
||||
#endif
|
||||
|
||||
static int
|
||||
MimeMultipartClassInitialize(MimeMultipartClass *class)
|
||||
{
|
||||
MimeObjectClass *oclass = (MimeObjectClass *) class;
|
||||
MimeMultipartClass *mclass = (MimeMultipartClass *) class;
|
||||
|
||||
PR_ASSERT(!oclass->class_initialized);
|
||||
oclass->initialize = MimeMultipart_initialize;
|
||||
oclass->finalize = MimeMultipart_finalize;
|
||||
oclass->parse_line = MimeMultipart_parse_line;
|
||||
oclass->parse_eof = MimeMultipart_parse_eof;
|
||||
|
||||
mclass->check_boundary = MimeMultipart_check_boundary;
|
||||
mclass->create_child = MimeMultipart_create_child;
|
||||
mclass->output_child_p = MimeMultipart_output_child_p;
|
||||
mclass->parse_child_line = MimeMultipart_parse_child_line;
|
||||
mclass->close_child = MimeMultipart_close_child;
|
||||
|
||||
#if defined(DEBUG) && defined(XP_UNIX)
|
||||
oclass->debug_print = MimeMultipart_debug_print;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_initialize (MimeObject *object)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) object;
|
||||
char *ct;
|
||||
|
||||
/* This is an abstract class; it shouldn't be directly instanciated. */
|
||||
PR_ASSERT(object->class != (MimeObjectClass *) &mimeMultipartClass);
|
||||
|
||||
ct = MimeHeaders_get (object->headers, HEADER_CONTENT_TYPE, PR_FALSE, PR_FALSE);
|
||||
mult->boundary = (ct
|
||||
? MimeHeaders_get_parameter (ct, HEADER_PARM_BOUNDARY, NULL, NULL)
|
||||
: 0);
|
||||
PR_FREEIF(ct);
|
||||
mult->state = MimeMultipartPreamble;
|
||||
return ((MimeObjectClass*)&MIME_SUPERCLASS)->initialize(object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MimeMultipart_finalize (MimeObject *object)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) object;
|
||||
|
||||
object->class->parse_eof(object, PR_FALSE);
|
||||
|
||||
PR_FREEIF(mult->boundary);
|
||||
if (mult->hdrs)
|
||||
MimeHeaders_free(mult->hdrs);
|
||||
mult->hdrs = 0;
|
||||
((MimeObjectClass*)&MIME_SUPERCLASS)->finalize(object);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_parse_line (char *line, PRInt32 length, MimeObject *obj)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) obj;
|
||||
int status = 0;
|
||||
MimeMultipartBoundaryType boundary;
|
||||
|
||||
PR_ASSERT(line && *line);
|
||||
if (!line || !*line) return -1;
|
||||
|
||||
PR_ASSERT(!obj->closed_p);
|
||||
if (obj->closed_p) return -1;
|
||||
|
||||
/* If we're supposed to write this object, but aren't supposed to convert
|
||||
it to HTML, simply pass it through unaltered. */
|
||||
if (obj->output_p &&
|
||||
obj->options &&
|
||||
!obj->options->write_html_p &&
|
||||
obj->options->output_fn)
|
||||
return MimeObject_write(obj, line, length, PR_TRUE);
|
||||
|
||||
|
||||
if (mult->state == MimeMultipartEpilogue) /* already done */
|
||||
boundary = MimeMultipartBoundaryTypeNone;
|
||||
else
|
||||
boundary = ((MimeMultipartClass *)obj->class)->check_boundary(obj, line,
|
||||
length);
|
||||
|
||||
if (boundary == MimeMultipartBoundaryTypeTerminator ||
|
||||
boundary == MimeMultipartBoundaryTypeSeparator)
|
||||
{
|
||||
/* Match! Close the currently-open part, move on to the next
|
||||
state, and discard this line.
|
||||
*/
|
||||
if (mult->state != MimeMultipartPreamble)
|
||||
status = ((MimeMultipartClass *)obj->class)->close_child(obj);
|
||||
if (status < 0) return status;
|
||||
|
||||
if (boundary == MimeMultipartBoundaryTypeTerminator)
|
||||
mult->state = MimeMultipartEpilogue;
|
||||
else
|
||||
{
|
||||
mult->state = MimeMultipartHeaders;
|
||||
|
||||
/* Reset the header parser for this upcoming part. */
|
||||
PR_ASSERT(!mult->hdrs);
|
||||
if (mult->hdrs)
|
||||
MimeHeaders_free(mult->hdrs);
|
||||
mult->hdrs = MimeHeaders_new();
|
||||
if (!mult->hdrs)
|
||||
return MK_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Now return, to ignore the boundary line itself. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, this isn't a boundary string. So do whatever it is we
|
||||
should do with this line (parse it as a header, feed it to the
|
||||
child part, ignore it, etc.) */
|
||||
|
||||
switch (mult->state)
|
||||
{
|
||||
case MimeMultipartPreamble:
|
||||
case MimeMultipartEpilogue:
|
||||
/* Ignore this line. */
|
||||
break;
|
||||
|
||||
case MimeMultipartHeaders:
|
||||
/* Parse this line as a header for the sub-part. */
|
||||
{
|
||||
status = MimeHeaders_parse_line(line, length, mult->hdrs);
|
||||
if (status < 0) return status;
|
||||
|
||||
/* If this line is blank, we're now done parsing headers, and should
|
||||
now examine the content-type to create this "body" part.
|
||||
*/
|
||||
if (*line == CR || *line == LF)
|
||||
{
|
||||
status = ((MimeMultipartClass *) obj->class)->create_child(obj);
|
||||
if (status < 0) return status;
|
||||
PR_ASSERT(mult->state != MimeMultipartHeaders);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MimeMultipartPartFirstLine:
|
||||
/* Hand this line off to the sub-part. */
|
||||
status = (((MimeMultipartClass *) obj->class)->parse_child_line(obj,
|
||||
line,
|
||||
length,
|
||||
PR_TRUE));
|
||||
if (status < 0) return status;
|
||||
mult->state = MimeMultipartPartLine;
|
||||
break;
|
||||
|
||||
case MimeMultipartPartLine:
|
||||
/* Hand this line off to the sub-part. */
|
||||
status = (((MimeMultipartClass *) obj->class)->parse_child_line(obj,
|
||||
line,
|
||||
length,
|
||||
PR_FALSE));
|
||||
if (status < 0) return status;
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static MimeMultipartBoundaryType
|
||||
MimeMultipart_check_boundary(MimeObject *obj, const char *line, PRInt32 length)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) obj;
|
||||
PRInt32 blen;
|
||||
PRBool term_p;
|
||||
|
||||
if (!mult->boundary ||
|
||||
line[0] != '-' ||
|
||||
line[1] != '-')
|
||||
return MimeMultipartBoundaryTypeNone;
|
||||
|
||||
/* This is a candidate line to be a boundary. Check it out... */
|
||||
blen = PL_strlen(mult->boundary);
|
||||
term_p = PR_FALSE;
|
||||
|
||||
/* strip trailing whitespace (including the newline.) */
|
||||
while(length > 2 && XP_IS_SPACE(line[length-1]))
|
||||
length--;
|
||||
|
||||
/* Could this be a terminating boundary? */
|
||||
if (length == blen + 4 &&
|
||||
line[length-1] == '-' &&
|
||||
line[length-2] == '-')
|
||||
{
|
||||
term_p = PR_TRUE;
|
||||
length -= 2;
|
||||
}
|
||||
|
||||
if (blen == length-2 && !PL_strncmp(line+2, mult->boundary, length-2))
|
||||
return (term_p
|
||||
? MimeMultipartBoundaryTypeTerminator
|
||||
: MimeMultipartBoundaryTypeSeparator);
|
||||
else
|
||||
return MimeMultipartBoundaryTypeNone;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_create_child(MimeObject *obj)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) obj;
|
||||
#ifdef JS_ATTACHMENT_MUMBO_JUMBO
|
||||
MimeContainer *cont = (MimeContainer *) obj;
|
||||
#endif
|
||||
int status;
|
||||
char *ct = (mult->hdrs
|
||||
? MimeHeaders_get (mult->hdrs, HEADER_CONTENT_TYPE,
|
||||
PR_TRUE, PR_FALSE)
|
||||
: 0);
|
||||
const char *dct = (((MimeMultipartClass *) obj->class)->default_part_type);
|
||||
MimeObject *body = NULL;
|
||||
MimeObject *parent = NULL;
|
||||
PRBool showIcon = PR_TRUE;
|
||||
|
||||
mult->state = MimeMultipartPartFirstLine;
|
||||
/* Don't pass in NULL as the content-type (this means that the
|
||||
auto-uudecode-hack won't ever be done for subparts of a
|
||||
multipart, but only for untyped children of message/rfc822.
|
||||
*/
|
||||
body = mime_create(((ct && *ct) ? ct : (dct ? dct: TEXT_PLAIN)),
|
||||
mult->hdrs, obj->options);
|
||||
PR_FREEIF(ct);
|
||||
if (!body) return MK_OUT_OF_MEMORY;
|
||||
status = ((MimeContainerClass *) obj->class)->add_child(obj, body);
|
||||
if (status < 0)
|
||||
{
|
||||
mime_free(body);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
if ( obj->options &&
|
||||
obj->options->decompose_file_p &&
|
||||
obj->options->is_multipart_msg &&
|
||||
obj->options->decompose_file_init_fn )
|
||||
{
|
||||
if ( !mime_typep(obj,(MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(obj,(MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(obj,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(body, (MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(body, (MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(body,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(body, (MimeObjectClass*)&mimeInlineTextVCardClass))
|
||||
{
|
||||
status = obj->options->decompose_file_init_fn ( obj->options->stream_closure, mult->hdrs );
|
||||
if (status < 0) return status;
|
||||
}
|
||||
}
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
|
||||
/* Now that we've added this new object to our list of children,
|
||||
start its parser going (if we want to display it.)
|
||||
*/
|
||||
body->output_p = (((MimeMultipartClass *) obj->class)
|
||||
->output_child_p(obj, body));
|
||||
if (body->output_p)
|
||||
{
|
||||
#ifdef JS_ATTACHMENT_MUMBO_JUMBO
|
||||
int attachment_count = 0;
|
||||
PRBool isMsgBody = PR_FALSE, isAlternativeOrRelated = PR_FALSE;
|
||||
#endif
|
||||
status = body->class->parse_begin(body);
|
||||
if (status < 0) return status;
|
||||
#ifdef JS_ATTACHMENT_MUMBO_JUMBO
|
||||
isMsgBody = MimeObjectChildIsMessageBody
|
||||
(obj, &isAlternativeOrRelated);
|
||||
if (isAlternativeOrRelated)
|
||||
attachment_count = 0;
|
||||
else if (isMsgBody)
|
||||
attachment_count = cont->nchildren - 1;
|
||||
else
|
||||
attachment_count = cont->nchildren;
|
||||
|
||||
if (attachment_count &&
|
||||
obj->options && !obj->options->nice_html_only_p) {
|
||||
/* This is not the first child, so it's an attachment. Cause the
|
||||
"attachments in this message" icon(s) to become visible.
|
||||
Excluding the following types to avoid inline graphics and dull items :
|
||||
Headers: Content-Disposition: inline
|
||||
Content-Type: text/x-vcard
|
||||
Content-Type: text/html
|
||||
Content-Type: text/plain
|
||||
Content-Type: message/rfc822 */
|
||||
char *tmp = NULL;
|
||||
|
||||
/* if (strncasestr(body->headers->all_headers, "DISPOSITION: INLINE", 300))
|
||||
showIcon = PR_FALSE; */
|
||||
if (PL_strstr(body->content_type, "text/x-vcard"))
|
||||
showIcon = PR_FALSE;
|
||||
else if (PL_strstr(body->content_type, "text/html"))
|
||||
showIcon = PR_FALSE;
|
||||
else if (PL_strstr(body->content_type, "message/rfc822"))
|
||||
showIcon = PR_FALSE;
|
||||
else if (PL_strstr(body->content_type, "multipart/signed"))
|
||||
showIcon = PR_FALSE;
|
||||
else if (PL_strstr(body->content_type, "application/x-pkcs7-signature"))
|
||||
showIcon = PR_FALSE;
|
||||
else if (PL_strstr(body->content_type, "multipart/mixed"))
|
||||
showIcon = PR_FALSE;
|
||||
|
||||
if (showIcon)
|
||||
{
|
||||
(obj)->showAttachmentIcon = PR_TRUE;
|
||||
parent = obj->parent;
|
||||
while (parent) {
|
||||
(parent)->showAttachmentIcon = PR_TRUE;
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
if (obj->options->attachment_icon_layer_id)
|
||||
{
|
||||
/* RICHIECSS
|
||||
tmp = PR_smprintf("\n\
|
||||
<SCRIPT>\n\
|
||||
window.document.layers[\"noattach-%ld\"].visibility = \"hide\";\n\
|
||||
window.document.layers[\"attach-%ld\"].visibility = \"show\";\n\
|
||||
</SCRIPT>\n",
|
||||
*/
|
||||
tmp = PR_smprintf("\n\
|
||||
<SCRIPT>\n\
|
||||
document.getElementById(\"noattach%ld\").style.display = \"none\";\n\
|
||||
document.getElementById(\"attach%ld\").style.display = \"\";\n\
|
||||
</SCRIPT>\n",
|
||||
(long) obj->options->attachment_icon_layer_id,
|
||||
(long) obj->options->attachment_icon_layer_id);
|
||||
if (tmp) {
|
||||
status = MimeObject_write(obj, tmp, PL_strlen(tmp), PR_TRUE);
|
||||
PR_Free(tmp);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* JS_ATTACHMENT_MUMBO_JUMBO */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PRBool
|
||||
MimeMultipart_output_child_p(MimeObject *obj, MimeObject *child)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_close_child(MimeObject *object)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) object;
|
||||
MimeContainer *cont = (MimeContainer *) object;
|
||||
|
||||
if (!mult->hdrs)
|
||||
return 0;
|
||||
|
||||
MimeHeaders_free(mult->hdrs);
|
||||
mult->hdrs = 0;
|
||||
|
||||
PR_ASSERT(cont->nchildren > 0);
|
||||
if (cont->nchildren > 0)
|
||||
{
|
||||
MimeObject *kid = cont->children[cont->nchildren-1];
|
||||
if (kid)
|
||||
{
|
||||
int status;
|
||||
status = kid->class->parse_eof(kid, PR_FALSE);
|
||||
if (status < 0) return status;
|
||||
status = kid->class->parse_end(kid, PR_FALSE);
|
||||
if (status < 0) return status;
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
if ( object->options &&
|
||||
object->options->decompose_file_p &&
|
||||
object->options->is_multipart_msg &&
|
||||
object->options->decompose_file_close_fn )
|
||||
{
|
||||
if ( !mime_typep(object,(MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(object,(MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(object,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(kid, (MimeObjectClass*)&mimeInlineTextVCardClass))
|
||||
{
|
||||
status = object->options->decompose_file_close_fn ( object->options->stream_closure );
|
||||
if (status < 0) return status;
|
||||
}
|
||||
}
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_parse_child_line (MimeObject *obj, char *line, PRInt32 length,
|
||||
PRBool first_line_p)
|
||||
{
|
||||
MimeContainer *cont = (MimeContainer *) obj;
|
||||
int status;
|
||||
MimeObject *kid;
|
||||
|
||||
PR_ASSERT(cont->nchildren > 0);
|
||||
if (cont->nchildren <= 0)
|
||||
return -1;
|
||||
|
||||
kid = cont->children[cont->nchildren-1];
|
||||
PR_ASSERT(kid);
|
||||
if (!kid) return -1;
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
if ( obj->options &&
|
||||
obj->options->decompose_file_p &&
|
||||
obj->options->is_multipart_msg &&
|
||||
obj->options->decompose_file_output_fn )
|
||||
{
|
||||
if (!mime_typep(obj,(MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(obj,(MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(obj,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartAlternativeClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartRelatedClass) &&
|
||||
!mime_typep(kid,(MimeObjectClass*)&mimeMultipartSignedClass) &&
|
||||
!mime_typep(kid, (MimeObjectClass*)&mimeInlineTextVCardClass))
|
||||
return obj->options->decompose_file_output_fn (line, length, obj->options->stream_closure);
|
||||
}
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
/* The newline issues here are tricky, since both the newlines before
|
||||
and after the boundary string are to be considered part of the
|
||||
boundary: this is so that a part can be specified such that it
|
||||
does not end in a trailing newline.
|
||||
|
||||
To implement this, we send a newline *before* each line instead
|
||||
of after, except for the first line, which is not preceeded by a
|
||||
newline.
|
||||
*/
|
||||
|
||||
/* Remove the trailing newline... */
|
||||
if (length > 0 && line[length-1] == LF) length--;
|
||||
if (length > 0 && line[length-1] == CR) length--;
|
||||
|
||||
if (!first_line_p)
|
||||
{
|
||||
/* Push out a preceeding newline... */
|
||||
char nl[] = LINEBREAK;
|
||||
status = kid->class->parse_buffer (nl, LINEBREAK_LEN, kid);
|
||||
if (status < 0) return status;
|
||||
}
|
||||
|
||||
/* Now push out the line sans trailing newline. */
|
||||
return kid->class->parse_buffer (line, length, kid);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
MimeMultipart_parse_eof (MimeObject *obj, PRBool abort_p)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) obj;
|
||||
MimeContainer *cont = (MimeContainer *) obj;
|
||||
|
||||
if (obj->closed_p) return 0;
|
||||
|
||||
/* Push out one last newline if part of the last line is still in the
|
||||
ibuffer. If this happens, this object does not end in a trailing newline
|
||||
(and the parse_line method will be called with a string with no trailing
|
||||
newline, which isn't the usual case.)
|
||||
*/
|
||||
if (!abort_p && obj->ibuffer_fp > 0)
|
||||
{
|
||||
int status = obj->class->parse_buffer (obj->ibuffer, obj->ibuffer_fp,
|
||||
obj);
|
||||
obj->ibuffer_fp = 0;
|
||||
if (status < 0)
|
||||
{
|
||||
obj->closed_p = PR_TRUE;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now call parse_eof for our active child, if there is one.
|
||||
*/
|
||||
if (cont->nchildren > 0 &&
|
||||
(mult->state == MimeMultipartPartLine ||
|
||||
mult->state == MimeMultipartPartFirstLine))
|
||||
{
|
||||
MimeObject *kid = cont->children[cont->nchildren-1];
|
||||
PR_ASSERT(kid);
|
||||
if (kid)
|
||||
{
|
||||
int status = kid->class->parse_eof(kid, abort_p);
|
||||
if (status < 0) return status;
|
||||
}
|
||||
}
|
||||
|
||||
return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG) && defined(XP_UNIX)
|
||||
static int
|
||||
MimeMultipart_debug_print (MimeObject *obj, FILE *stream, PRInt32 depth)
|
||||
{
|
||||
MimeMultipart *mult = (MimeMultipart *) obj;
|
||||
MimeContainer *cont = (MimeContainer *) obj;
|
||||
char *addr = mime_part_address(obj);
|
||||
int i;
|
||||
for (i=0; i < depth; i++)
|
||||
fprintf(stream, " ");
|
||||
fprintf(stream, "<%s %s (%d kid%s) boundary=%s 0x%08X>\n",
|
||||
obj->class->class_name,
|
||||
addr ? addr : "???",
|
||||
cont->nchildren, (cont->nchildren == 1 ? "" : "s"),
|
||||
(mult->boundary ? mult->boundary : "(none)"),
|
||||
(PRUint32) mult);
|
||||
PR_FREEIF(addr);
|
||||
|
||||
/*
|
||||
if (cont->nchildren > 0)
|
||||
fprintf(stream, "\n");
|
||||
*/
|
||||
|
||||
for (i = 0; i < cont->nchildren; i++)
|
||||
{
|
||||
MimeObject *kid = cont->children[i];
|
||||
int status = kid->class->debug_print (kid, stream, depth+1);
|
||||
if (status < 0) return status;
|
||||
}
|
||||
|
||||
/*
|
||||
if (cont->nchildren > 0)
|
||||
fprintf(stream, "\n");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче