diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /mailnews/mime/cthandlers | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'mailnews/mime/cthandlers')
-rw-r--r-- | mailnews/mime/cthandlers/glue/mimexpcom.cpp | 132 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/glue/mimexpcom.h | 93 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/glue/moz.build | 18 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp | 60 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h | 47 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/moz.build | 12 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/pgpmime/moz.build | 20 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp | 634 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h | 69 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/vcard/mimevcrd.cpp | 378 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/vcard/mimevcrd.h | 33 | ||||
-rw-r--r-- | mailnews/mime/cthandlers/vcard/moz.build | 14 |
12 files changed, 1510 insertions, 0 deletions
diff --git a/mailnews/mime/cthandlers/glue/mimexpcom.cpp b/mailnews/mime/cthandlers/glue/mimexpcom.cpp new file mode 100644 index 000000000..094f61e37 --- /dev/null +++ b/mailnews/mime/cthandlers/glue/mimexpcom.cpp @@ -0,0 +1,132 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsIComponentManager.h" +#include "nsIMimeObjectClassAccess.h" +#include "nsMsgMimeCID.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +static NS_DEFINE_CID(kMimeObjectClassAccessCID, NS_MIME_OBJECT_CLASS_ACCESS_CID); + +/* + * These calls are necessary to expose the object class hierarchy + * to externally developed content type handlers. + */ +extern "C" void * +COM_GetmimeInlineTextClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeInlineTextClass(&ptr); + + return ptr; +} + +extern "C" void * +COM_GetmimeLeafClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeLeafClass(&ptr); + + return ptr; +} + +extern "C" void * +COM_GetmimeObjectClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeObjectClass(&ptr); + + return ptr; +} + +extern "C" void * +COM_GetmimeContainerClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeContainerClass(&ptr); + + return ptr; +} + +extern "C" void * +COM_GetmimeMultipartClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeMultipartClass(&ptr); + + return ptr; +} + +extern "C" void * +COM_GetmimeMultipartSignedClass(void) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->GetmimeMultipartSignedClass(&ptr); + + return ptr; +} + +extern "C" int +COM_MimeObject_write(void *mimeObject, char *data, int32_t length, + bool user_visible_p) +{ + int32_t rc = -1; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + { + if (NS_SUCCEEDED(objAccess->MimeObjectWrite(mimeObject, data, length, user_visible_p))) + rc = length; + else + rc = -1; + } + + return rc; +} + +extern "C" void * +COM_MimeCreate(char * content_type, void * hdrs, void * opts) +{ + void *ptr = NULL; + + nsresult res; + nsCOMPtr<nsIMimeObjectClassAccess> objAccess = + do_CreateInstance(kMimeObjectClassAccessCID, &res); + if (NS_SUCCEEDED(res) && objAccess) + objAccess->MimeCreate(content_type, hdrs, opts, &ptr); + + return ptr; +} diff --git a/mailnews/mime/cthandlers/glue/mimexpcom.h b/mailnews/mime/cthandlers/glue/mimexpcom.h new file mode 100644 index 000000000..9468b22b4 --- /dev/null +++ b/mailnews/mime/cthandlers/glue/mimexpcom.h @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This is the definitions for the Content Type Handler plugins to + * access internals of libmime via XP-COM calls + */ +#ifndef _MIMEXPCOM_H_ +#define _MIMEXPCOM_H_ + +/* + This header exposes functions that are necessary to access the + object hierarchy 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 + | | + | |--- MimeInlineImage + | | + | |--- MimeExternalObject + | + |--- MimeExternalBody + */ + +/* + * These functions are exposed by libmime to be used by content type + * handler plugins for processing stream data. + */ +/* + * This is the write call for outputting processed stream data. + */ +extern "C" int COM_MimeObject_write(void *mimeObject, const char *data, + int32_t length, + bool user_visible_p); +/* + * The following group of calls expose the pointers for the object + * system within libmime. + */ +extern "C" void *COM_GetmimeInlineTextClass(void); +extern "C" void *COM_GetmimeLeafClass(void); +extern "C" void *COM_GetmimeObjectClass(void); +extern "C" void *COM_GetmimeContainerClass(void); +extern "C" void *COM_GetmimeMultipartClass(void); +extern "C" void *COM_GetmimeMultipartSignedClass(void); + +extern "C" void *COM_MimeCreate(char * content_type, void * hdrs, void * opts); + +#endif /* _MIMEXPCOM_H_ */ diff --git a/mailnews/mime/cthandlers/glue/moz.build b/mailnews/mime/cthandlers/glue/moz.build new file mode 100644 index 000000000..f51518ca9 --- /dev/null +++ b/mailnews/mime/cthandlers/glue/moz.build @@ -0,0 +1,18 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + 'nsMimeContentTypeHandler.h', +] + +SOURCES += [ + 'mimexpcom.cpp', + 'nsMimeContentTypeHandler.cpp', +] + +FINAL_LIBRARY = 'mail' + +Library('mimecthglue_s') + diff --git a/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp b/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp new file mode 100644 index 000000000..369f8c4bf --- /dev/null +++ b/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <stdio.h> +#include "nscore.h" +#include "plstr.h" +//#include "mimecth.h" +#include "nsMimeContentTypeHandler.h" + +/* + * The following macros actually implement addref, release and + * query interface for our component. + */ +NS_IMPL_ISUPPORTS(nsMimeContentTypeHandler, nsIMimeContentTypeHandler) + +/* + * nsIMimeEmitter definitions.... + */ +nsMimeContentTypeHandler::nsMimeContentTypeHandler(const char *aMimeType, + MCTHCreateCTHClass callback) +{ + NS_ASSERTION(aMimeType, "nsMimeContentTypeHandler should be initialized with non-null mime type"); + NS_ASSERTION(callback, "nsMimeContentTypeHandler should be initialized with non-null callback"); + mimeType = PL_strdup(aMimeType); + realCreateContentTypeHandlerClass = callback; +} + +nsMimeContentTypeHandler::~nsMimeContentTypeHandler(void) +{ + if (mimeType) { + NS_Free(mimeType); + mimeType = 0; + } + realCreateContentTypeHandlerClass = 0; +} + +// Get the content type if necessary +nsresult +nsMimeContentTypeHandler::GetContentType(char **contentType) +{ + *contentType = PL_strdup(mimeType); + return NS_OK; +} + +// Set the output stream for processed data. +nsresult +nsMimeContentTypeHandler::CreateContentTypeHandlerClass(const char *content_type, + contentTypeHandlerInitStruct *initStruct, + MimeObjectClass **objClass) +{ + *objClass = realCreateContentTypeHandlerClass(content_type, initStruct); + if (!*objClass) + return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */ + else + return NS_OK; +} + + + diff --git a/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h b/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h new file mode 100644 index 000000000..8cc142268 --- /dev/null +++ b/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This interface is implemented by content type handlers that will be + * called upon by libmime to process various attachments types. The primary + * purpose of these handlers will be to represent the attached data in a + * viewable HTML format that is useful for the user + * + * Note: These will all register by their content type prefixed by the + * following: mimecth:text/vcard + * + * libmime will then use the XPCOM Component Manager to + * locate the appropriate Content Type handler + */ +#ifndef nsMimeContentTypeHandler_h_ +#define nsMimeContentTypeHandler_h_ + +#include "mozilla/Attributes.h" +#include "nsIMimeContentTypeHandler.h" + +typedef MimeObjectClass * +(* MCTHCreateCTHClass)(const char *content_type, + contentTypeHandlerInitStruct *initStruct); + +class nsMimeContentTypeHandler : public nsIMimeContentTypeHandler { +public: + nsMimeContentTypeHandler (const char *aMimeType, + MCTHCreateCTHClass callback); + + /* this macro defines QueryInterface, AddRef and Release for this class */ + NS_DECL_ISUPPORTS + + NS_IMETHOD GetContentType(char **contentType) override; + + NS_IMETHOD CreateContentTypeHandlerClass(const char *content_type, + contentTypeHandlerInitStruct *initStruct, + MimeObjectClass **objClass) override; + private: + virtual ~nsMimeContentTypeHandler(); + char *mimeType; + MCTHCreateCTHClass realCreateContentTypeHandlerClass; +}; + +#endif /* nsMimeContentTypeHandler_h_ */ diff --git a/mailnews/mime/cthandlers/moz.build b/mailnews/mime/cthandlers/moz.build new file mode 100644 index 000000000..31807499d --- /dev/null +++ b/mailnews/mime/cthandlers/moz.build @@ -0,0 +1,12 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# pgpmime depends on glue. +DIRS += [ + 'glue', + 'vcard', + 'pgpmime', +] + diff --git a/mailnews/mime/cthandlers/pgpmime/moz.build b/mailnews/mime/cthandlers/pgpmime/moz.build new file mode 100644 index 000000000..878bd5bfa --- /dev/null +++ b/mailnews/mime/cthandlers/pgpmime/moz.build @@ -0,0 +1,20 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + 'nsPgpMimeProxy.h', +] + +SOURCES += [ + 'nsPgpMimeProxy.cpp', +] + +FINAL_LIBRARY = 'mail' + +Library('pgpmime_s') + +LOCAL_INCLUDES += [ + '../glue', +] diff --git a/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp new file mode 100644 index 000000000..de4ec3174 --- /dev/null +++ b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp @@ -0,0 +1,634 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsPgpMimeProxy.h" +#include "nspr.h" +#include "plstr.h" +#include "nsCOMPtr.h" +#include "nsStringGlue.h" +#include "mozilla/Services.h" +#include "nsIRequest.h" +#include "nsIStringBundle.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" +#include "nsIURI.h" +#include "mimexpcom.h" +#include "nsMsgUtils.h" + +#include "nsMsgMimeCID.h" + +#include "mimecth.h" +#include "mimemoz2.h" +#include "nspr.h" +#include "plstr.h" +#include "nsIPgpMimeProxy.h" +#include "nsComponentManagerUtils.h" + +#define MIME_SUPERCLASS mimeEncryptedClass +MimeDefClass(MimeEncryptedPgp, MimeEncryptedPgpClass, + mimeEncryptedPgpClass, &MIME_SUPERCLASS); + +#define kCharMax 1024 + +extern "C" MimeObjectClass * +MIME_PgpMimeCreateContentTypeHandlerClass( + const char *content_type, + contentTypeHandlerInitStruct *initStruct) +{ + MimeObjectClass *objClass = (MimeObjectClass *) &mimeEncryptedPgpClass; + + initStruct->force_inline_display = false; + + return objClass; +} + +static void *MimePgpe_init(MimeObject *, + int (*output_fn) (const char *, int32_t, void *), + void *); +static int MimePgpe_write (const char *, int32_t, void *); +static int MimePgpe_eof (void *, bool); +static char* MimePgpe_generate (void *); +static void MimePgpe_free (void *); + +/* Returns a string describing the location of the part (like "2.5.3"). + This is not a full URL, just a part-number. + */ +static nsCString determineMimePart(MimeObject* obj); + + +#define PGPMIME_PROPERTIES_URL "chrome://messenger/locale/pgpmime.properties" +#define PGPMIME_STR_NOT_SUPPORTED_ID u"pgpMimeNeedsAddon" +#define PGPMIME_URL_PREF "mail.pgpmime.addon_url" + +static void PgpMimeGetNeedsAddonString(nsCString &aResult) +{ + aResult.AssignLiteral("???"); + + nsCOMPtr<nsIStringBundleService> stringBundleService = + mozilla::services::GetStringBundleService(); + + nsCOMPtr<nsIStringBundle> stringBundle; + nsresult rv = stringBundleService->CreateBundle(PGPMIME_PROPERTIES_URL, + getter_AddRefs(stringBundle)); + if (NS_FAILED(rv)) + return; + + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return; + + nsCString url; + if (NS_FAILED(prefs->GetCharPref("mail.pgpmime.addon_url", + getter_Copies(url)))) + return; + + NS_ConvertUTF8toUTF16 url16(url); + const char16_t *formatStrings[] = { url16.get() }; + + nsString result; + rv = stringBundle->FormatStringFromName(PGPMIME_STR_NOT_SUPPORTED_ID, + formatStrings, 1, getter_Copies(result)); + if (NS_FAILED(rv)) + return; + aResult = NS_ConvertUTF16toUTF8(result); +} + +static int +MimeEncryptedPgpClassInitialize(MimeEncryptedPgpClass *clazz) +{ + mozilla::DebugOnly<MimeObjectClass *> oclass = (MimeObjectClass *) clazz; + NS_ASSERTION(!oclass->class_initialized, "oclass is not initialized"); + + MimeEncryptedClass *eclass = (MimeEncryptedClass *) clazz; + + eclass->crypto_init = MimePgpe_init; + eclass->crypto_write = MimePgpe_write; + eclass->crypto_eof = MimePgpe_eof; + eclass->crypto_generate_html = MimePgpe_generate; + eclass->crypto_free = MimePgpe_free; + + return 0; +} + +class MimePgpeData : public nsISupports +{ +public: + NS_DECL_ISUPPORTS + + int (*output_fn) (const char *buf, int32_t buf_size, void *output_closure); + void *output_closure; + MimeObject *self; + + nsCOMPtr<nsIPgpMimeProxy> mimeDecrypt; + + MimePgpeData() + : output_fn(nullptr), + output_closure(nullptr) + { + } + +private: + virtual ~MimePgpeData() + { + } +}; + +NS_IMPL_ISUPPORTS0(MimePgpeData) + +static void* +MimePgpe_init(MimeObject *obj, + int (*output_fn) (const char *buf, int32_t buf_size, + void *output_closure), + void *output_closure) +{ + if (!(obj && obj->options && output_fn)) + return nullptr; + + MimePgpeData* data = new MimePgpeData(); + NS_ENSURE_TRUE(data, nullptr); + + data->self = obj; + data->output_fn = output_fn; + data->output_closure = output_closure; + data->mimeDecrypt = nullptr; + + nsresult rv; + data->mimeDecrypt = do_CreateInstance(NS_PGPMIMEPROXY_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return data; + + char *ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, false, false); + + rv = (ct ? data->mimeDecrypt->SetContentType(nsDependentCString(ct)) + : data->mimeDecrypt->SetContentType(EmptyCString())); + + PR_Free(ct); + + if (NS_FAILED(rv)) + return nullptr; + + nsCString mimePart = determineMimePart(obj); + + rv = data->mimeDecrypt->SetMimePart(mimePart); + if (NS_FAILED(rv)) + return nullptr; + + mime_stream_data *msd = (mime_stream_data *) (data->self->options->stream_closure); + nsIChannel *channel = msd->channel; + + nsCOMPtr<nsIURI> uri; + if (channel) + channel->GetURI(getter_AddRefs(uri)); + + if (NS_FAILED(data->mimeDecrypt->SetMimeCallback(output_fn, output_closure, uri))) + return nullptr; + + return data; +} + +static int +MimePgpe_write(const char *buf, int32_t buf_size, void *output_closure) +{ + MimePgpeData* data = (MimePgpeData *) output_closure; + + if (!data || !data->output_fn) + return -1; + + if (!data->mimeDecrypt) + return 0; + + return (NS_SUCCEEDED(data->mimeDecrypt->Write(buf, buf_size)) ? 0 : -1); +} + +static int +MimePgpe_eof(void* output_closure, bool abort_p) +{ + MimePgpeData* data = (MimePgpeData *) output_closure; + + if (!data || !data->output_fn) + return -1; + + if (NS_FAILED(data->mimeDecrypt->Finish())) + return -1; + + data->mimeDecrypt = nullptr; + return 0; +} + +static char* +MimePgpe_generate(void *output_closure) +{ + const char htmlMsg[] = "<html><body><b>GEN MSG<b></body></html>"; + char* msg = (char *) PR_MALLOC(strlen(htmlMsg) + 1); + if (msg) + PL_strcpy(msg, htmlMsg); + + return msg; +} + +static void +MimePgpe_free(void *output_closure) +{ +} + +/* Returns a string describing the location of the part (like "2.5.3"). + This is not a full URL, just a part-number. + */ +static nsCString +determineMimePart(MimeObject* obj) +{ + char mimePartNum[20]; + MimeObject *kid; + MimeContainer *cont; + int32_t i; + + nsCString mimePart; + + while (obj->parent) { + cont = (MimeContainer *) obj->parent; + for (i = 0; i < cont->nchildren; i++) { + kid = cont->children[i]; + if (kid == obj) { + sprintf(mimePartNum, ".%d", i + 1); + mimePart.Insert(mimePartNum, 0); + } + } + obj = obj->parent; + } + + // remove leading "." + if (mimePart.Length() > 0) + mimePart.Cut(0, 1); + + return mimePart; +} + + +//////////////////////////////////////////////////////////////////////////// +NS_IMPL_ISUPPORTS(nsPgpMimeProxy, + nsIPgpMimeProxy, + nsIRequestObserver, + nsIStreamListener, + nsIRequest, + nsIInputStream) + +// nsPgpMimeProxy implementation +nsPgpMimeProxy::nsPgpMimeProxy() + : mInitialized(false), + mDecryptor(nullptr), + mLoadGroup(nullptr), + mLoadFlags(LOAD_NORMAL), + mCancelStatus(NS_OK) +{ +} + +nsPgpMimeProxy::~nsPgpMimeProxy() +{ + Finalize(); +} + +nsresult +nsPgpMimeProxy::Finalize() +{ + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::SetMimeCallback(MimeDecodeCallbackFun outputFun, + void* outputClosure, + nsIURI* myUri) +{ + if (!outputFun || !outputClosure) + return NS_ERROR_NULL_POINTER; + + mOutputFun = outputFun; + mOutputClosure = outputClosure; + mInitialized = true; + + mStreamOffset = 0; + mByteBuf.Truncate(); + + if (mDecryptor) + return mDecryptor->OnStartRequest((nsIRequest*) this, myUri); + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Init() +{ + mByteBuf.Truncate(); + + nsresult rv; + nsCOMPtr<nsIPrefBranch> pbi(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + + mDecryptor = do_CreateInstance(PGPMIME_JS_DECRYPTOR_CONTRACTID, &rv); + if (NS_FAILED(rv)) + mDecryptor = nullptr; + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Write(const char *buf, uint32_t buf_size) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + mByteBuf.Assign(buf, buf_size); + mStreamOffset = 0; + + if (mDecryptor) + return mDecryptor->OnDataAvailable((nsIRequest*) this, nullptr, (nsIInputStream*) this, + 0, buf_size); + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Finish() { + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + if (mDecryptor) { + return mDecryptor->OnStopRequest((nsIRequest*) this, nullptr, NS_OK); + } + else { + nsCString temp; + temp.Append("Content-Type: text/html\r\nCharset: UTF-8\r\n\r\n<html><body>"); + temp.Append("<BR><text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#FF0000\" vlink=\"#800080\" alink=\"#0000FF\">"); + temp.Append("<center><table BORDER=1 ><tr><td><CENTER>"); + + nsCString tString; + PgpMimeGetNeedsAddonString(tString); + temp.Append(tString); + temp.Append("</CENTER></td></tr></table></center><BR></body></html>\r\n"); + + PR_SetError(0,0); + int status = mOutputFun(temp.get(), temp.Length(), mOutputClosure); + if (status < 0) { + PR_SetError(status, 0); + mOutputFun = nullptr; + return NS_ERROR_FAILURE; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::GetDecryptor(nsIStreamListener **aDecryptor) +{ + NS_IF_ADDREF(*aDecryptor = mDecryptor); + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::SetDecryptor(nsIStreamListener *aDecryptor) +{ + mDecryptor = aDecryptor; + + return NS_OK; +} + + +NS_IMETHODIMP +nsPgpMimeProxy::GetContentType(nsACString &aContentType) +{ + aContentType = mContentType; + return NS_OK; +} + + +NS_IMETHODIMP +nsPgpMimeProxy::SetContentType(const nsACString &aContentType) +{ + mContentType = aContentType; + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::GetMimePart(nsACString &aMimePart) +{ + aMimePart = mMimePart; + return NS_OK; +} + + +NS_IMETHODIMP +nsPgpMimeProxy::SetMimePart(const nsACString &aMimePart) +{ + mMimePart = aMimePart; + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIRequest methods +/////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPgpMimeProxy::GetName(nsACString &result) +{ + result = "pgpmimeproxy"; + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::IsPending(bool *result) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + *result = NS_SUCCEEDED(mCancelStatus); + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::GetStatus(nsresult *status) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + *status = mCancelStatus; + return NS_OK; +} + +// NOTE: We assume that OnStopRequest should not be called if +// request is canceled. This may be wrong! +NS_IMETHODIMP +nsPgpMimeProxy::Cancel(nsresult status) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + // Need a non-zero status code to cancel + if (NS_SUCCEEDED(status)) + return NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(mCancelStatus)) + mCancelStatus = status; + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Suspend(void) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Resume(void) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsPgpMimeProxy::GetLoadGroup(nsILoadGroup * *aLoadGroup) +{ + NS_IF_ADDREF(*aLoadGroup = mLoadGroup); + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::SetLoadGroup(nsILoadGroup* aLoadGroup) +{ + mLoadGroup = aLoadGroup; + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::GetLoadFlags(nsLoadFlags *aLoadFlags) +{ + *aLoadFlags = mLoadFlags; + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::SetLoadFlags(nsLoadFlags aLoadFlags) +{ + mLoadFlags = aLoadFlags; + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIInputStream methods +/////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPgpMimeProxy::Available(uint64_t* _retval) +{ + NS_ENSURE_ARG(_retval); + + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + *_retval = (mByteBuf.Length() > mStreamOffset) ? + mByteBuf.Length() - mStreamOffset : 0; + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Read(char* buf, uint32_t count, + uint32_t *readCount) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + if (!buf || !readCount) + return NS_ERROR_NULL_POINTER; + + int32_t avail = (mByteBuf.Length() > mStreamOffset) ? + mByteBuf.Length() - mStreamOffset : 0; + + uint32_t readyCount = ((uint32_t) avail > count) ? count : avail; + + if (readyCount) { + memcpy(buf, mByteBuf.get()+mStreamOffset, readyCount); + *readCount = readyCount; + } + + mStreamOffset += *readCount; + + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::ReadSegments(nsWriteSegmentFun writer, + void * aClosure, uint32_t count, + uint32_t *readCount) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsPgpMimeProxy::IsNonBlocking(bool *aNonBlocking) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + *aNonBlocking = true; + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::Close() +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + mStreamOffset = 0; + mByteBuf.Truncate(); + + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIStreamListener methods +/////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPgpMimeProxy::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsPgpMimeProxy::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, + nsresult aStatus) +{ + return NS_OK; +} + +/////////////////////////////////////////////////////////////////////////////// +// nsIStreamListener method +/////////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsPgpMimeProxy::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, + nsIInputStream *aInputStream, + uint64_t aSourceOffset, + uint32_t aLength) +{ + NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED); + + NS_ENSURE_ARG(aInputStream); + + char buf[kCharMax]; + uint32_t readCount, readMax; + + while (aLength > 0) { + readMax = (aLength < kCharMax) ? aLength : kCharMax; + + nsresult rv; + rv = aInputStream->Read((char *) buf, readMax, &readCount); + NS_ENSURE_SUCCESS(rv, rv); + + int status = mOutputFun(buf, readCount, mOutputClosure); + if (status < 0) { + PR_SetError(status, 0); + mOutputFun = nullptr; + return NS_ERROR_FAILURE; + } + + aLength -= readCount; + } + + return NS_OK; +} diff --git a/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h new file mode 100644 index 000000000..41e7f59cc --- /dev/null +++ b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h @@ -0,0 +1,69 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _nsPgpmimeDecrypt_h_ +#define _nsPgpmimeDecrypt_h_ + +#include "mimecth.h" +#include "nsIPgpMimeProxy.h" +#include "nsCOMPtr.h" +#include "nsIStreamListener.h" +#include "nsIInputStream.h" +#include "nsILoadGroup.h" + +#define PGPMIME_JS_DECRYPTOR_CONTRACTID "@mozilla.org/mime/pgp-mime-js-decrypt;1" + +typedef struct MimeEncryptedPgpClass MimeEncryptedPgpClass; +typedef struct MimeEncryptedPgp MimeEncryptedPgp; + +struct MimeEncryptedPgpClass { + MimeEncryptedClass encrypted; +}; + +struct MimeEncryptedPgp { + MimeEncrypted encrypted; +}; + +class nsPgpMimeProxy : public nsIPgpMimeProxy, + public nsIRequest, + public nsIInputStream +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPGPMIMEPROXY + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIREQUEST + NS_DECL_NSIINPUTSTREAM + + nsPgpMimeProxy(); + + // Define a Create method to be used with a factory: + static NS_METHOD + Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); + +protected: + virtual ~nsPgpMimeProxy(); + bool mInitialized; + nsCOMPtr<nsIStreamListener> mDecryptor; + + MimeDecodeCallbackFun mOutputFun; + void* mOutputClosure; + + nsCOMPtr<nsILoadGroup> mLoadGroup; + nsLoadFlags mLoadFlags; + nsresult mCancelStatus; + + uint32_t mStreamOffset; + nsCString mByteBuf; + nsCString mContentType; + nsCString mMimePart; + + nsresult Finalize(); +}; + +#define MimeEncryptedPgpClassInitializer(ITYPE,CSUPER) \ + { MimeEncryptedClassInitializer(ITYPE,CSUPER) } + +#endif diff --git a/mailnews/mime/cthandlers/vcard/mimevcrd.cpp b/mailnews/mime/cthandlers/vcard/mimevcrd.cpp new file mode 100644 index 000000000..140afb5aa --- /dev/null +++ b/mailnews/mime/cthandlers/vcard/mimevcrd.cpp @@ -0,0 +1,378 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mimevcrd.h" + +#include "mimecth.h" +#include "mimexpcom.h" +#include "nsIMsgVCardService.h" +#include "nsINetUtil.h" +#include "nsMsgUtils.h" +#include "prmem.h" +#include "prprf.h" +#include "nsServiceManagerUtils.h" + +static int MimeInlineTextVCard_parse_line (const char *, int32_t, MimeObject *); +static int MimeInlineTextVCard_parse_eof (MimeObject *, bool); +static int MimeInlineTextVCard_parse_begin (MimeObject *obj); + +static int s_unique = 0; + +static int BeginVCard (MimeObject *obj); +static int EndVCard (MimeObject *obj); +static int WriteOutVCard (MimeObject *obj, VObject* v); + +static int GenerateVCardData(MimeObject * aMimeObj, VObject* aVcard); +static int OutputVcardAttribute(MimeObject *aMimeObj, VObject *aVcard, const char* id, nsACString& vCardOutput); +static int OutputBasicVcard(MimeObject *aMimeObj, VObject *aVcard, nsACString& vCardOutput); + +typedef struct + { + const char *attributeName; + int resourceId; + } AttributeName; + +#define kNumAttributes 12 + +#define MSGVCARDSERVICE_CONTRACT_ID "@mozilla.org/addressbook/msgvcardservice;1" + +/* This is the object definition. Note: we will set the superclass + to NULL and manually set this on the class creation */ +MimeDefClass(MimeInlineTextVCard, MimeInlineTextVCardClass, + mimeInlineTextVCardClass, NULL); + +extern "C" MimeObjectClass * +MIME_VCardCreateContentTypeHandlerClass(const char *content_type, + contentTypeHandlerInitStruct *initStruct) +{ + MimeObjectClass *clazz = (MimeObjectClass *)&mimeInlineTextVCardClass; + /* + * Must set the superclass by hand. + */ + if (!COM_GetmimeInlineTextClass()) + return NULL; + + clazz->superclass = (MimeObjectClass *)COM_GetmimeInlineTextClass(); + initStruct->force_inline_display = true; + return clazz; +} + +/* + * Implementation of VCard clazz + */ +static int +MimeInlineTextVCardClassInitialize(MimeInlineTextVCardClass *clazz) +{ + MimeObjectClass *oclass = (MimeObjectClass *) clazz; + NS_ASSERTION(!oclass->class_initialized, "1.1 <rhp@netscape.com> 19 Mar 1999 12:11"); + oclass->parse_begin = MimeInlineTextVCard_parse_begin; + oclass->parse_line = MimeInlineTextVCard_parse_line; + oclass->parse_eof = MimeInlineTextVCard_parse_eof; + return 0; +} + +static int +MimeInlineTextVCard_parse_begin (MimeObject *obj) +{ + int status = ((MimeObjectClass*)COM_GetmimeLeafClass())->parse_begin(obj); + MimeInlineTextVCardClass *clazz; + if (status < 0) return status; + + if (!obj->output_p) return 0; + if (!obj->options || !obj->options->write_html_p) return 0; + + /* This is a fine place to write out any HTML before the real meat begins. + In this sample code, we tell it to start a table. */ + + clazz = ((MimeInlineTextVCardClass *) obj->clazz); + /* initialize vcard string to empty; */ + NS_MsgSACopy(&(clazz->vCardString), ""); + + obj->options->state->separator_suppressed_p = true; + return 0; +} + +char *strcpySafe (char *dest, const char *src, size_t destLength) +{ + char *result = strncpy (dest, src, --destLength); + dest[destLength] = '\0'; + return result; +} + +static int +MimeInlineTextVCard_parse_line (const char *line, int32_t length, MimeObject *obj) +{ + // This routine gets fed each line of data, one at a time. + char* linestring; + MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *) obj->clazz); + + if (!obj->output_p) return 0; + if (!obj->options || !obj->options->output_fn) return 0; + if (!obj->options->write_html_p) + { + return COM_MimeObject_write(obj, line, length, true); + } + + linestring = (char *) PR_MALLOC (length + 1); + memset(linestring, 0, (length + 1)); + + if (linestring) + { + strcpySafe((char *)linestring, line, length + 1); + NS_MsgSACat (&clazz->vCardString, linestring); + PR_Free (linestring); + } + + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +static int +MimeInlineTextVCard_parse_eof (MimeObject *obj, bool abort_p) +{ + nsCOMPtr<nsIMsgVCardService> vCardService = + do_GetService(MSGVCARDSERVICE_CONTRACT_ID); + if (!vCardService) + return -1; + + int status = 0; + MimeInlineTextVCardClass *clazz = ((MimeInlineTextVCardClass *) obj->clazz); + + VObject *t, *v; + + if (obj->closed_p) return 0; + + /* Run parent method first, to flush out any buffered data. */ + // status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p); + status = ((MimeObjectClass*)COM_GetmimeInlineTextClass())->parse_eof(obj, abort_p); + if (status < 0) return status; + + // Don't quote vCards... + if ( (obj->options) && + ((obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting) || + (obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting)) + ) + return 0; + + if (!clazz->vCardString) return 0; + + v = vCardService->Parse_MIME(clazz->vCardString, strlen(clazz->vCardString)); + NS_ASSERTION(v, "parse of vCard failed"); + + if (clazz->vCardString) { + PR_Free ((char*) clazz->vCardString); + clazz->vCardString = NULL; + } + + if (obj->output_p && obj->options && obj->options->write_html_p && + obj->options->headers != MimeHeadersCitation) { + /* This is a fine place to write any closing HTML. In fact, you may + want all the writing to be here, and all of the above would just + collect data into datastructures, though that isn't very + "streaming". */ + t = v; + while (v && status >= 0) { + /* write out html */ + status = WriteOutVCard (obj, v); + /* parse next vcard incase they're embedded */ + v = vCardService->NextVObjectInList(v); + } + + (void)vCardService->CleanVObject(t); + } + + if (status < 0) + return status; + + return 0; +} + +static int EndVCard (MimeObject *obj) +{ + int status = 0; + + /* Scribble HTML-ending stuff into the stream */ + char htmlFooters[32]; + PR_snprintf (htmlFooters, sizeof(htmlFooters), "</BODY>%s</HTML>%s", MSG_LINEBREAK, MSG_LINEBREAK); + status = COM_MimeObject_write(obj, htmlFooters, strlen(htmlFooters), false); + + if (status < 0) return status; + + return 0; +} + +static int BeginVCard (MimeObject *obj) +{ + int status = 0; + + /* Scribble HTML-starting stuff into the stream */ + char htmlHeaders[32]; + + s_unique++; + PR_snprintf (htmlHeaders, sizeof(htmlHeaders), "<HTML>%s<BODY>%s", MSG_LINEBREAK, MSG_LINEBREAK); + status = COM_MimeObject_write(obj, htmlHeaders, strlen(htmlHeaders), true); + + if (status < 0) return status; + + return 0; +} + + +static int WriteOutVCard (MimeObject * aMimeObj, VObject* aVcard) +{ + BeginVCard (aMimeObj); + + GenerateVCardData(aMimeObj, aVcard); + + return EndVCard (aMimeObj); +} + + +static int GenerateVCardData(MimeObject * aMimeObj, VObject* aVcard) +{ + // style is driven from CSS not here. Just layout the minimal vCard data + nsCString vCardOutput; + + vCardOutput = "<table class=\"moz-vcard-table\"> <tr> "; // outer table plus the first (and only row) we use for this table + + // we need to get an escaped vCard url to bind to our add to address book button + nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(MSGVCARDSERVICE_CONTRACT_ID); + if (!vCardService) + return -1; + + nsAutoCString vCard; + nsAutoCString vEscCard; + int len = 0; + + vCard.Adopt(vCardService->WriteMemoryVObjects(0, &len, aVcard, false)); + MsgEscapeString(vCard, nsINetUtil::ESCAPE_XALPHAS, vEscCard); + + // first cell in the outer table row is a clickable image which brings up the rich address book UI for the vcard + vCardOutput += "<td valign=\"top\"> <a class=\"moz-vcard-badge\" href=\"addbook:add?action=add?vcard="; + vCardOutput += vEscCard; // the href is the vCard + vCardOutput += "\"></a></td>"; + + // the 2nd cell in the outer table row is a nested table containing the actual vCard properties + vCardOutput += "<td> <table id=\"moz-vcard-properties-table\"> <tr> "; + + OutputBasicVcard(aMimeObj, aVcard, vCardOutput); + + // close the properties table + vCardOutput += "</table> </td> "; + + // 2nd cell in the outer table is our vCard image + + vCardOutput += "</tr> </table>"; + + // now write out the vCard + return COM_MimeObject_write(aMimeObj, (char *) vCardOutput.get(), vCardOutput.Length(), true); +} + + +static int OutputBasicVcard(MimeObject *aMimeObj, VObject *aVcard, nsACString& vCardOutput) +{ + VObject *prop = NULL; + nsAutoCString urlstring; + nsAutoCString namestring; + nsAutoCString emailstring; + + nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(MSGVCARDSERVICE_CONTRACT_ID); + if (!vCardService) + return -1; + + /* get the name and email */ + prop = vCardService->IsAPropertyOf(aVcard, VCFullNameProp); + if (prop) + { + if (VALUE_TYPE(prop)) + { + if (VALUE_TYPE(prop) != VCVT_RAW) + namestring.Adopt(vCardService->FakeCString(prop)); + else + namestring.Adopt(vCardService->VObjectAnyValue(prop)); + + if (!namestring.IsEmpty()) + { + vCardOutput += "<td class=\"moz-vcard-title-property\"> "; + + prop = vCardService->IsAPropertyOf(aVcard, VCURLProp); + if (prop) + { + urlstring.Adopt(vCardService->FakeCString(prop)); + if (urlstring.IsEmpty()) + vCardOutput += namestring; + else + { + char buf[512]; + PR_snprintf(buf, 512, "<a href=""%s"" private>%s</a>", urlstring.get(), namestring.get()); + vCardOutput.Append(buf); + } + } + else + vCardOutput += namestring; + + /* get the email address */ + prop = vCardService->IsAPropertyOf(aVcard, VCEmailAddressProp); + if (prop) + { + emailstring.Adopt(vCardService->FakeCString(prop)); + if (!emailstring.IsEmpty()) + { + char buf[512]; + PR_snprintf(buf, 512, " <<a href=""mailto:%s"" private>%s</a>>", emailstring.get(), emailstring.get()); + vCardOutput.Append(buf); + } + } // if email address property + + vCardOutput += "</td> </tr> "; // end the cell for the name/email address + } // if we have a name property + } + } // if full name property + + // now each basic property goes on its own line + + // title + (void) OutputVcardAttribute (aMimeObj, aVcard, VCTitleProp, vCardOutput); + + // org name and company name + prop = vCardService->IsAPropertyOf(aVcard, VCOrgProp); + if (prop) + { + OutputVcardAttribute (aMimeObj, prop, VCOrgUnitProp, vCardOutput); + OutputVcardAttribute (aMimeObj, prop, VCOrgNameProp, vCardOutput); + } + + return 0; +} + +static int OutputVcardAttribute(MimeObject *aMimeObj, VObject *aVcard, const char* id, nsACString& vCardOutput) +{ + VObject *prop = NULL; + nsAutoCString string; + + nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(MSGVCARDSERVICE_CONTRACT_ID); + if (!vCardService) + return -1; + + prop = vCardService->IsAPropertyOf(aVcard, id); + if (prop) + if (VALUE_TYPE(prop)) + { + if (VALUE_TYPE(prop) != VCVT_RAW) + string.Adopt(vCardService->FakeCString(prop)); + else + string.Adopt(vCardService->VObjectAnyValue(prop)); + + if (!string.IsEmpty()) + { + vCardOutput += "<tr> <td class=\"moz-vcard-property\">"; + vCardOutput += string; + vCardOutput += "</td> </tr> "; + } + } + + return 0; +} diff --git a/mailnews/mime/cthandlers/vcard/mimevcrd.h b/mailnews/mime/cthandlers/vcard/mimevcrd.h new file mode 100644 index 000000000..6e731f555 --- /dev/null +++ b/mailnews/mime/cthandlers/vcard/mimevcrd.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MIMEVCRD_H_ +#define _MIMEVCRD_H_ + +#include "mimetext.h" +#include "nsCOMPtr.h" + +/* The MimeInlineTextHTML class implements the text/x-vcard and (maybe? + someday?) the application/directory MIME content types. + */ + +typedef struct MimeInlineTextVCardClass MimeInlineTextVCardClass; +typedef struct MimeInlineTextVCard MimeInlineTextVCard; + +struct MimeInlineTextVCardClass { + MimeInlineTextClass text; + char *vCardString; +}; + +extern MimeInlineTextVCardClass mimeInlineTextVCardClass; + +struct MimeInlineTextVCard { + MimeInlineText text; +}; + +#define MimeInlineTextVCardClassInitializer(ITYPE,CSUPER) \ + { MimeInlineTextClassInitializer(ITYPE,CSUPER) } + +#endif /* _MIMEVCRD_H_ */ diff --git a/mailnews/mime/cthandlers/vcard/moz.build b/mailnews/mime/cthandlers/vcard/moz.build new file mode 100644 index 000000000..55de22391 --- /dev/null +++ b/mailnews/mime/cthandlers/vcard/moz.build @@ -0,0 +1,14 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +SOURCES += [ + 'mimevcrd.cpp', +] + +FINAL_LIBRARY = 'mail' + +LOCAL_INCLUDES += [ + '../glue', +] |