mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-10 18:00:15 +01:00
856 lines
28 KiB
C++
856 lines
28 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "msgCore.h" // precompiled header...
|
|
#include "nsXPIDLString.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "nsIPrefService.h"
|
|
#include "nsIPrefBranch.h"
|
|
#include "nsIIOService.h"
|
|
#include "nsIPipe.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsEscape.h"
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "nsSmtpService.h"
|
|
#include "nsIMsgMailSession.h"
|
|
#include "nsMsgBaseCID.h"
|
|
#include "nsMsgCompCID.h"
|
|
|
|
#include "nsSmtpUrl.h"
|
|
#include "nsSmtpProtocol.h"
|
|
#include "nsIFileSpec.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIMsgIdentity.h"
|
|
#include "nsMsgComposeStringBundle.h"
|
|
#include "nsIPrompt.h"
|
|
#include "nsIWindowWatcher.h"
|
|
#include "nsMsgSimulateError.h"
|
|
#include "nsIUTF8ConverterService.h"
|
|
#include "nsUConvCID.h"
|
|
|
|
#define SERVER_DELIMITER ","
|
|
#define APPEND_SERVERS_VERSION_PREF_NAME "append_preconfig_smtpservers.version"
|
|
#define MAIL_ROOT_PREF "mail."
|
|
#define PREF_MAIL_SMTPSERVERS "mail.smtpservers"
|
|
#define PREF_MAIL_SMTPSERVERS_APPEND_SERVERS "mail.smtpservers.appendsmtpservers"
|
|
#define PREF_MAIL_SMTP_DEFAULTSERVER "mail.smtp.defaultserver"
|
|
|
|
typedef struct _findServerByKeyEntry {
|
|
const char *key;
|
|
nsISmtpServer *server;
|
|
} findServerByKeyEntry;
|
|
|
|
typedef struct _findServerByHostnameEntry {
|
|
const char *hostname;
|
|
const char *username;
|
|
nsISmtpServer *server;
|
|
} findServerByHostnameEntry;
|
|
|
|
static NS_DEFINE_CID(kCSmtpUrlCID, NS_SMTPURL_CID);
|
|
static NS_DEFINE_CID(kCMailtoUrlCID, NS_MAILTOURL_CID);
|
|
|
|
// foward declarations...
|
|
nsresult
|
|
NS_MsgBuildSmtpUrl(nsIFileSpec * aFilePath,
|
|
const char* aSmtpHostName,
|
|
PRInt32 aSmtpPort,
|
|
const char* aSmtpUserName,
|
|
const char* aRecipients,
|
|
nsIMsgIdentity * aSenderIdentity,
|
|
nsIUrlListener * aUrlListener,
|
|
nsIMsgStatusFeedback *aStatusFeedback,
|
|
nsIInterfaceRequestor* aNotificationCallbacks,
|
|
nsIURI ** aUrl);
|
|
|
|
nsresult NS_MsgLoadSmtpUrl(nsIURI * aUrl, nsISupports * aConsumer, nsIRequest ** aRequest);
|
|
|
|
nsSmtpService::nsSmtpService() :
|
|
mSmtpServersLoaded(PR_FALSE)
|
|
{
|
|
NS_NewISupportsArray(getter_AddRefs(mSmtpServers));
|
|
}
|
|
|
|
nsSmtpService::~nsSmtpService()
|
|
{
|
|
// save the SMTP servers to disk
|
|
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS2(nsSmtpService, nsISmtpService, nsIProtocolHandler)
|
|
|
|
|
|
nsresult nsSmtpService::SendMailMessage(nsIFileSpec * aFilePath,
|
|
const char * aRecipients,
|
|
nsIMsgIdentity * aSenderIdentity,
|
|
const char * aPassword,
|
|
nsIUrlListener * aUrlListener,
|
|
nsIMsgStatusFeedback *aStatusFeedback,
|
|
nsIInterfaceRequestor* aNotificationCallbacks,
|
|
nsIURI ** aURL,
|
|
nsIRequest ** aRequest)
|
|
{
|
|
nsIURI * urlToRun = nsnull;
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsISmtpServer> smtpServer;
|
|
rv = GetSmtpServerByIdentity(aSenderIdentity, getter_AddRefs(smtpServer));
|
|
|
|
if (NS_SUCCEEDED(rv) && smtpServer)
|
|
{
|
|
if (aPassword && *aPassword)
|
|
smtpServer->SetPassword(aPassword);
|
|
|
|
nsXPIDLCString smtpHostName;
|
|
nsXPIDLCString smtpUserName;
|
|
PRInt32 smtpPort;
|
|
PRInt32 trySSL;
|
|
|
|
smtpServer->GetHostname(getter_Copies(smtpHostName));
|
|
smtpServer->GetUsername(getter_Copies(smtpUserName));
|
|
smtpServer->GetPort(&smtpPort);
|
|
smtpServer->GetTrySSL(&trySSL);
|
|
|
|
if (smtpPort == 0)
|
|
{
|
|
if (trySSL == PREF_SECURE_ALWAYS_SMTPS)
|
|
smtpPort = nsISmtpUrl::DEFAULT_SMTPS_PORT;
|
|
else
|
|
smtpPort = nsISmtpUrl::DEFAULT_SMTP_PORT;
|
|
}
|
|
|
|
if (smtpHostName && smtpHostName.get()[0] && !CHECK_SIMULATED_ERROR(SIMULATED_SEND_ERROR_10))
|
|
{
|
|
rv = NS_MsgBuildSmtpUrl(aFilePath, smtpHostName, smtpPort, smtpUserName,
|
|
aRecipients, aSenderIdentity, aUrlListener, aStatusFeedback,
|
|
aNotificationCallbacks, &urlToRun); // this ref counts urlToRun
|
|
if (NS_SUCCEEDED(rv) && urlToRun)
|
|
{
|
|
nsCOMPtr<nsISmtpUrl> smtpUrl = do_QueryInterface(urlToRun, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
smtpUrl->SetSmtpServer(smtpServer);
|
|
rv = NS_MsgLoadSmtpUrl(urlToRun, nsnull, aRequest);
|
|
}
|
|
|
|
if (aURL) // does the caller want a handle on the url?
|
|
*aURL = urlToRun; // transfer our ref count to the caller....
|
|
else
|
|
NS_IF_RELEASE(urlToRun);
|
|
}
|
|
else
|
|
rv = NS_ERROR_COULD_NOT_LOGIN_TO_SMTP_SERVER;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
// The following are two convience functions I'm using to help expedite building and running a mail to url...
|
|
|
|
// short cut function for creating a mailto url...
|
|
nsresult NS_MsgBuildSmtpUrl(nsIFileSpec * aFilePath,
|
|
const char* aSmtpHostName,
|
|
PRInt32 aSmtpPort,
|
|
const char* aSmtpUserName,
|
|
const char * aRecipients,
|
|
nsIMsgIdentity * aSenderIdentity,
|
|
nsIUrlListener * aUrlListener,
|
|
nsIMsgStatusFeedback *aStatusFeedback,
|
|
nsIInterfaceRequestor* aNotificationCallbacks,
|
|
nsIURI ** aUrl)
|
|
{
|
|
// mscott: this function is a convience hack until netlib actually dispatches smtp urls.
|
|
// in addition until we have a session to get a password, host and other stuff from, we need to use default values....
|
|
// ..for testing purposes....
|
|
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr <nsISmtpUrl> smtpUrl (do_CreateInstance(kCSmtpUrlCID, &rv));
|
|
|
|
if (NS_SUCCEEDED(rv) && smtpUrl)
|
|
{
|
|
nsCAutoString urlSpec("smtp://");
|
|
if (aSmtpUserName)
|
|
{
|
|
nsXPIDLCString escapedUsername;
|
|
*((char **)getter_Copies(escapedUsername)) = nsEscape(aSmtpUserName, url_XAlphas);
|
|
urlSpec += escapedUsername;
|
|
urlSpec += '@';
|
|
}
|
|
|
|
urlSpec += aSmtpHostName;
|
|
if (!PL_strchr(aSmtpHostName, ':'))
|
|
{
|
|
urlSpec += ':';
|
|
urlSpec.AppendInt(aSmtpPort);
|
|
}
|
|
|
|
if (urlSpec.get())
|
|
{
|
|
nsCOMPtr<nsIMsgMailNewsUrl> url = do_QueryInterface(smtpUrl);
|
|
url->SetSpec(urlSpec);
|
|
smtpUrl->SetRecipients(aRecipients);
|
|
smtpUrl->SetPostMessageFile(aFilePath);
|
|
smtpUrl->SetSenderIdentity(aSenderIdentity);
|
|
smtpUrl->SetNotificationCallbacks(aNotificationCallbacks);
|
|
|
|
nsCOMPtr<nsIPrompt> smtpPrompt(do_GetInterface(aNotificationCallbacks));
|
|
nsCOMPtr<nsIAuthPrompt> smtpAuthPrompt(do_GetInterface(aNotificationCallbacks));
|
|
if (!smtpPrompt || !smtpAuthPrompt)
|
|
{
|
|
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
|
if (wwatch) {
|
|
if (!smtpPrompt)
|
|
wwatch->GetNewPrompter(0, getter_AddRefs(smtpPrompt));
|
|
if (!smtpAuthPrompt)
|
|
wwatch->GetNewAuthPrompter(0, getter_AddRefs(smtpAuthPrompt));
|
|
}
|
|
}
|
|
smtpUrl->SetPrompt(smtpPrompt);
|
|
smtpUrl->SetAuthPrompt(smtpAuthPrompt);
|
|
url->RegisterListener(aUrlListener);
|
|
if (aStatusFeedback)
|
|
url->SetStatusFeedback(aStatusFeedback);
|
|
}
|
|
rv = smtpUrl->QueryInterface(NS_GET_IID(nsIURI), (void **) aUrl);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult NS_MsgLoadSmtpUrl(nsIURI * aUrl, nsISupports * aConsumer, nsIRequest ** aRequest)
|
|
{
|
|
// for now, assume the url is an smtp url and load it....
|
|
nsCOMPtr <nsISmtpUrl> smtpUrl;
|
|
nsSmtpProtocol *smtpProtocol = nsnull;
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aUrl)
|
|
return rv;
|
|
|
|
// turn the url into an smtp url...
|
|
smtpUrl = do_QueryInterface(aUrl);
|
|
if (smtpUrl)
|
|
{
|
|
// almost there...now create a smtp protocol instance to run the url in...
|
|
smtpProtocol = new nsSmtpProtocol(aUrl);
|
|
if (smtpProtocol == nsnull)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(smtpProtocol);
|
|
rv = smtpProtocol->LoadUrl(aUrl, aConsumer); // protocol will get destroyed when url is completed...
|
|
smtpProtocol->QueryInterface(NS_GET_IID(nsIRequest), (void **) aRequest);
|
|
NS_RELEASE(smtpProtocol);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsSmtpService::GetScheme(nsACString &aScheme)
|
|
{
|
|
aScheme = "mailto";
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsSmtpService::GetDefaultPort(PRInt32 *aDefaultPort)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
if (aDefaultPort)
|
|
*aDefaultPort = nsISmtpUrl::DEFAULT_SMTP_PORT;
|
|
else
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
|
|
{
|
|
// allow smtp to run on any port
|
|
*_retval = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsSmtpService::GetProtocolFlags(PRUint32 *result)
|
|
{
|
|
*result = URI_NORELATIVE | ALLOWS_PROXY;
|
|
return NS_OK;
|
|
}
|
|
|
|
// the smtp service is also the protocol handler for mailto urls....
|
|
|
|
NS_IMETHODIMP nsSmtpService::NewURI(const nsACString &aSpec,
|
|
const char *aOriginCharset,
|
|
nsIURI *aBaseURI,
|
|
nsIURI **_retval)
|
|
{
|
|
// get a new smtp url
|
|
|
|
nsresult rv;
|
|
nsCOMPtr <nsIURI> mailtoUrl = do_CreateInstance(kCMailtoUrlCID, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
nsCAutoString utf8Spec;
|
|
if (aOriginCharset)
|
|
{
|
|
nsCOMPtr<nsIUTF8ConverterService>
|
|
utf8Converter(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID, &rv));
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = utf8Converter->ConvertURISpecToUTF8(aSpec, aOriginCharset, utf8Spec);
|
|
}
|
|
|
|
// utf8Spec is filled up only when aOriginCharset is specified and
|
|
// the conversion is successful. Otherwise, fall back to aSpec.
|
|
if (aOriginCharset && NS_SUCCEEDED(rv))
|
|
mailtoUrl->SetSpec(utf8Spec);
|
|
else
|
|
mailtoUrl->SetSpec(aSpec);
|
|
rv = mailtoUrl->QueryInterface(NS_GET_IID(nsIURI), (void **) _retval);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsSmtpService::NewChannel(nsIURI *aURI, nsIChannel **_retval)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
// create an empty pipe for use with the input stream channel.
|
|
nsCOMPtr<nsIInputStream> pipeIn;
|
|
nsCOMPtr<nsIOutputStream> pipeOut;
|
|
nsresult rv = NS_NewPipe(getter_AddRefs(pipeIn),
|
|
getter_AddRefs(pipeOut));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pipeOut->Close();
|
|
|
|
return NS_NewInputStreamChannel(_retval, aURI, pipeIn,
|
|
NS_LITERAL_CSTRING("application/x-mailto"));
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::GetSmtpServers(nsISupportsArray ** aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
nsresult rv;
|
|
|
|
// now read in the servers from prefs if necessary
|
|
PRUint32 serverCount;
|
|
rv = mSmtpServers->Count(&serverCount);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (serverCount<=0) loadSmtpServers();
|
|
|
|
*aResult = mSmtpServers;
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsSmtpService::loadSmtpServers()
|
|
{
|
|
if (mSmtpServersLoaded) return NS_OK;
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
if (NS_FAILED(rv)) return rv;
|
|
nsCOMPtr<nsIPrefBranch> prefRootBranch;
|
|
prefService->GetBranch(nsnull, getter_AddRefs(prefRootBranch));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsXPIDLCString tempServerList;
|
|
nsXPIDLCString serverList;
|
|
rv = prefRootBranch->GetCharPref(PREF_MAIL_SMTPSERVERS, getter_Copies(tempServerList));
|
|
|
|
//Get the pref in a tempServerList and then parse it to see if it has dupes.
|
|
//if so remove the dupes and then create the serverList.
|
|
if (!tempServerList.IsEmpty()) {
|
|
|
|
// Tokenize the data and add each smtp server if it is not already there
|
|
// in the user's current smtp server list
|
|
nsCStringArray servers;
|
|
servers.ParseString(tempServerList.get(), SERVER_DELIMITER);
|
|
nsCAutoString tempSmtpServer;
|
|
for (PRInt32 i = 0; i < servers.Count(); i++)
|
|
{
|
|
if (servers.IndexOf(* (servers[i])) == i) {
|
|
tempSmtpServer.Assign(* (servers[i]));
|
|
tempSmtpServer.StripWhitespace();
|
|
if (!serverList.IsEmpty())
|
|
serverList += SERVER_DELIMITER;
|
|
serverList += tempSmtpServer;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
serverList = tempServerList;
|
|
}
|
|
|
|
// We need to check if we have any pre-configured smtp servers so that
|
|
// those servers can be appended to the list.
|
|
nsXPIDLCString appendServerList;
|
|
rv = prefRootBranch->GetCharPref(PREF_MAIL_SMTPSERVERS_APPEND_SERVERS, getter_Copies(appendServerList));
|
|
|
|
// Get the list of smtp servers (either from regular pref i.e, mail.smtpservers or
|
|
// from preconfigured pref mail.smtpservers.appendsmtpservers) and create a keyed
|
|
// server list.
|
|
if (!serverList.IsEmpty() || !appendServerList.IsEmpty()) {
|
|
/**
|
|
* Check to see if we need to add pre-configured smtp servers.
|
|
* Following prefs are important to note in understanding the procedure here.
|
|
*
|
|
* 1. pref("mailnews.append_preconfig_smtpservers.version", version number);
|
|
* This pref registers the current version in the user prefs file. A default value
|
|
* is stored in mailnews.js file. If a given vendor needs to add more preconfigured
|
|
* smtp servers, the default version number can be increased. Comparing version
|
|
* number from user's prefs file and the default one from mailnews.js, we
|
|
* can add new smtp servers and any other version level changes that need to be done.
|
|
*
|
|
* 2. pref("mail.smtpservers.appendsmtpservers", <comma separated servers list>);
|
|
* This pref contains the list of pre-configured smp servers that ISP/Vendor wants to
|
|
* to add to the existing servers list.
|
|
*/
|
|
nsCOMPtr<nsIPrefBranch> defaultsPrefBranch;
|
|
rv = prefService->GetDefaultBranch(MAIL_ROOT_PREF, getter_AddRefs(defaultsPrefBranch));
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
nsCOMPtr<nsIPrefBranch> prefBranch;
|
|
rv = prefService->GetBranch(MAIL_ROOT_PREF, getter_AddRefs(prefBranch));
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
PRInt32 appendSmtpServersCurrentVersion=0;
|
|
PRInt32 appendSmtpServersDefaultVersion=0;
|
|
rv = prefBranch->GetIntPref(APPEND_SERVERS_VERSION_PREF_NAME, &appendSmtpServersCurrentVersion);
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
rv = defaultsPrefBranch->GetIntPref(APPEND_SERVERS_VERSION_PREF_NAME, &appendSmtpServersDefaultVersion);
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
// Update the smtp server list if needed
|
|
if ((appendSmtpServersCurrentVersion <= appendSmtpServersDefaultVersion)) {
|
|
// If there are pre-configured servers, add them to the existing server list
|
|
if (!appendServerList.IsEmpty()) {
|
|
if (!serverList.IsEmpty()) {
|
|
nsCStringArray existingSmtpServersArray;
|
|
existingSmtpServersArray.ParseString(serverList.get(), SERVER_DELIMITER);
|
|
|
|
// Tokenize the data and add each smtp server if it is not already there
|
|
// in the user's current smtp server list
|
|
char *newSmtpServerStr;
|
|
char *preConfigSmtpServersStr = ToNewCString(appendServerList);
|
|
|
|
char *token = nsCRT::strtok(preConfigSmtpServersStr, SERVER_DELIMITER, &newSmtpServerStr);
|
|
|
|
nsCAutoString newSmtpServer;
|
|
while (token) {
|
|
if (token && *token) {
|
|
newSmtpServer.Assign(token);
|
|
newSmtpServer.StripWhitespace();
|
|
|
|
if (existingSmtpServersArray.IndexOf(newSmtpServer) == -1) {
|
|
serverList += ",";
|
|
serverList += newSmtpServer;
|
|
}
|
|
}
|
|
token = nsCRT::strtok(newSmtpServerStr, SERVER_DELIMITER, &newSmtpServerStr);
|
|
}
|
|
PR_Free(preConfigSmtpServersStr);
|
|
}
|
|
else {
|
|
serverList = appendServerList;
|
|
}
|
|
// Increase the version number so that updates will happen as and when needed
|
|
rv = prefBranch->SetIntPref(APPEND_SERVERS_VERSION_PREF_NAME, appendSmtpServersCurrentVersion + 1);
|
|
}
|
|
}
|
|
|
|
char *newStr;
|
|
char *pref = nsCRT::strtok(serverList.BeginWriting(), ", ", &newStr);
|
|
|
|
while (pref) {
|
|
// fix for bug #96207
|
|
// code above makes sure that no duplicate entries in mail.smtpservers find
|
|
// their way to the mSmtpServers list. But it doesn't check, if a server to be
|
|
// added already is in mSmtpServers. That can happen in mail has been sent before
|
|
// opening the settings (loading the list).
|
|
// use GetServerByKey to check if the key (pref) is already in
|
|
// in the list. If not it calls createKeyedServer directly.
|
|
nsCOMPtr<nsISmtpServer> server;
|
|
rv = GetServerByKey(pref, getter_AddRefs(server));
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "GetServerByKey failed");
|
|
pref = nsCRT::strtok(newStr, ", ", &newStr);
|
|
}
|
|
}
|
|
|
|
saveKeyList();
|
|
|
|
mSmtpServersLoaded = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|
|
// save the list of keys
|
|
nsresult
|
|
nsSmtpService::saveKeyList()
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return prefBranch->SetCharPref(PREF_MAIL_SMTPSERVERS, mServerKeyList.get());
|
|
}
|
|
|
|
nsresult
|
|
nsSmtpService::createKeyedServer(const char *key, nsISmtpServer** aResult)
|
|
{
|
|
if (!key) return NS_ERROR_NULL_POINTER;
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsISmtpServer> server = do_CreateInstance(NS_SMTPSERVER_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
server->SetKey(key);
|
|
mSmtpServers->AppendElement(server);
|
|
|
|
if (mServerKeyList.IsEmpty())
|
|
mServerKeyList = key;
|
|
else {
|
|
mServerKeyList.Append(',');
|
|
mServerKeyList += key;
|
|
}
|
|
|
|
if (aResult) {
|
|
*aResult = server;
|
|
NS_IF_ADDREF(*aResult);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::GetSessionDefaultServer(nsISmtpServer **aServer)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aServer);
|
|
|
|
if (!mSessionDefaultServer)
|
|
return GetDefaultServer(aServer);
|
|
|
|
*aServer = mSessionDefaultServer;
|
|
NS_ADDREF(*aServer);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::SetSessionDefaultServer(nsISmtpServer *aServer)
|
|
{
|
|
mSessionDefaultServer = aServer;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::GetDefaultServer(nsISmtpServer **aServer)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aServer);
|
|
|
|
nsresult rv;
|
|
|
|
loadSmtpServers();
|
|
|
|
*aServer = nsnull;
|
|
// always returns NS_OK, just leaving *aServer at nsnull
|
|
if (!mDefaultSmtpServer) {
|
|
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// try to get it from the prefs
|
|
nsXPIDLCString defaultServerKey;
|
|
rv = prefBranch->GetCharPref(PREF_MAIL_SMTP_DEFAULTSERVER, getter_Copies(defaultServerKey));
|
|
if (NS_SUCCEEDED(rv) &&
|
|
!defaultServerKey.IsEmpty()) {
|
|
|
|
nsCOMPtr<nsISmtpServer> server;
|
|
rv = GetServerByKey(defaultServerKey,
|
|
getter_AddRefs(mDefaultSmtpServer));
|
|
} else {
|
|
// no pref set, so just return the first one, and set the pref
|
|
|
|
PRUint32 count=0;
|
|
nsCOMPtr<nsISupportsArray> smtpServers;
|
|
rv = GetSmtpServers(getter_AddRefs(smtpServers));
|
|
rv = smtpServers->Count(&count);
|
|
|
|
// nothing in the array, we had better create a new server
|
|
// (which will add it to the array & prefs anyway)
|
|
if (count == 0)
|
|
return nsnull;//if there are no smtp servers then dont create one for the default.
|
|
else
|
|
rv = mSmtpServers->QueryElementAt(0, NS_GET_IID(nsISmtpServer),
|
|
(void **)getter_AddRefs(mDefaultSmtpServer));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
NS_ENSURE_TRUE(mDefaultSmtpServer, NS_ERROR_UNEXPECTED);
|
|
|
|
// now we have a default server, set the prefs correctly
|
|
nsXPIDLCString serverKey;
|
|
mDefaultSmtpServer->GetKey(getter_Copies(serverKey));
|
|
if (NS_SUCCEEDED(rv))
|
|
prefBranch->SetCharPref(PREF_MAIL_SMTP_DEFAULTSERVER, serverKey);
|
|
}
|
|
}
|
|
|
|
// at this point:
|
|
// * mDefaultSmtpServer has a valid server
|
|
// * the key has been set in the prefs
|
|
|
|
*aServer = mDefaultSmtpServer;
|
|
NS_IF_ADDREF(*aServer);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::SetDefaultServer(nsISmtpServer *aServer)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aServer);
|
|
|
|
mDefaultSmtpServer = aServer;
|
|
|
|
nsXPIDLCString serverKey;
|
|
nsresult rv = aServer->GetKey(getter_Copies(serverKey));
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
|
|
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
prefBranch->SetCharPref(PREF_MAIL_SMTP_DEFAULTSERVER, serverKey);
|
|
return NS_OK;
|
|
}
|
|
|
|
PRBool
|
|
nsSmtpService::findServerByKey (nsISupports *element, void *aData)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsISmtpServer> server = do_QueryInterface(element, &rv);
|
|
if (NS_FAILED(rv)) return PR_TRUE;
|
|
|
|
findServerByKeyEntry *entry = (findServerByKeyEntry*) aData;
|
|
|
|
nsXPIDLCString key;
|
|
rv = server->GetKey(getter_Copies(key));
|
|
if (NS_FAILED(rv)) return PR_TRUE;
|
|
|
|
if (nsCRT::strcmp(key, entry->key)==0) {
|
|
entry->server = server;
|
|
return PR_FALSE;
|
|
}
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::CreateSmtpServer(nsISmtpServer **aResult)
|
|
{
|
|
if (!aResult) return NS_ERROR_NULL_POINTER;
|
|
|
|
loadSmtpServers();
|
|
nsresult rv;
|
|
|
|
PRInt32 i=0;
|
|
PRBool unique = PR_FALSE;
|
|
|
|
findServerByKeyEntry entry;
|
|
nsCAutoString key;
|
|
|
|
do {
|
|
key = "smtp";
|
|
key.AppendInt(++i);
|
|
|
|
entry.key = key.get();
|
|
entry.server = nsnull;
|
|
|
|
mSmtpServers->EnumerateForwards(findServerByKey, (void *)&entry);
|
|
if (!entry.server) unique=PR_TRUE;
|
|
|
|
} while (!unique);
|
|
|
|
rv = createKeyedServer(key.get(), aResult);
|
|
saveKeyList();
|
|
return rv;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsSmtpService::GetServerByKey(const char* aKey, nsISmtpServer **aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
if (!aKey || !*aKey)
|
|
{
|
|
NS_ASSERTION(PR_FALSE, "bad key");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
findServerByKeyEntry entry;
|
|
entry.key = aKey;
|
|
entry.server = nsnull;
|
|
mSmtpServers->EnumerateForwards(findServerByKey, (void *)&entry);
|
|
|
|
if (entry.server) {
|
|
(*aResult) = entry.server;
|
|
NS_ADDREF(*aResult);
|
|
return NS_OK;
|
|
}
|
|
|
|
// not found in array, I guess we load it
|
|
return createKeyedServer(aKey, aResult);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::DeleteSmtpServer(nsISmtpServer *aServer)
|
|
{
|
|
if (!aServer) return NS_OK;
|
|
|
|
nsresult rv;
|
|
|
|
PRInt32 idx = 0;
|
|
rv = mSmtpServers->GetIndexOf(aServer, &idx);
|
|
if (NS_FAILED(rv) || idx==-1)
|
|
return NS_OK;
|
|
|
|
nsXPIDLCString serverKey;
|
|
aServer->GetKey(getter_Copies(serverKey));
|
|
|
|
rv = mSmtpServers->DeleteElementAt(idx);
|
|
|
|
if (mDefaultSmtpServer.get() == aServer)
|
|
mDefaultSmtpServer = nsnull;
|
|
if (mSessionDefaultServer.get() == aServer)
|
|
mSessionDefaultServer = nsnull;
|
|
|
|
nsCAutoString newServerList;
|
|
char *newStr;
|
|
char *rest = ToNewCString(mServerKeyList);
|
|
|
|
char *token = nsCRT::strtok(rest, ",", &newStr);
|
|
while (token) {
|
|
// only re-add the string if it's not the key
|
|
if (nsCRT::strcmp(token, serverKey) != 0) {
|
|
if (newServerList.IsEmpty())
|
|
newServerList = token;
|
|
else {
|
|
newServerList += ',';
|
|
newServerList += token;
|
|
}
|
|
}
|
|
|
|
token = nsCRT::strtok(newStr, ",", &newStr);
|
|
}
|
|
|
|
// make sure the server clears out it's values....
|
|
aServer->ClearAllValues();
|
|
|
|
mServerKeyList = newServerList;
|
|
saveKeyList();
|
|
return rv;
|
|
}
|
|
|
|
PRBool
|
|
nsSmtpService::findServerByHostname(nsISupports *element, void *aData)
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISmtpServer> server = do_QueryInterface(element, &rv);
|
|
if (NS_FAILED(rv)) return PR_TRUE;
|
|
|
|
findServerByHostnameEntry *entry = (findServerByHostnameEntry*)aData;
|
|
|
|
nsXPIDLCString hostname;
|
|
rv = server->GetHostname(getter_Copies(hostname));
|
|
if (NS_FAILED(rv)) return PR_TRUE;
|
|
|
|
nsXPIDLCString username;
|
|
rv = server->GetUsername(getter_Copies(username));
|
|
if (NS_FAILED(rv)) return PR_TRUE;
|
|
|
|
PRBool checkHostname = entry->hostname && PL_strcmp(entry->hostname, "");
|
|
PRBool checkUsername = entry->username && PL_strcmp(entry->username, "");
|
|
|
|
if ((!checkHostname || (PL_strcasecmp(entry->hostname, hostname)==0)) &&
|
|
(!checkUsername || (PL_strcmp(entry->username, username)==0))) {
|
|
entry->server = server;
|
|
return PR_FALSE; // stop when found
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::FindServer(const char *aUsername,
|
|
const char *aHostname, nsISmtpServer ** aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
findServerByHostnameEntry entry;
|
|
entry.server=nsnull;
|
|
entry.hostname = aHostname;
|
|
entry.username = aUsername;
|
|
|
|
mSmtpServers->EnumerateForwards(findServerByHostname, (void *)&entry);
|
|
|
|
// entry.server may be null, but that's ok.
|
|
// just return null if no server is found
|
|
*aResult = entry.server;
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSmtpService::GetSmtpServerByIdentity(nsIMsgIdentity *aSenderIdentity, nsISmtpServer **aSmtpServer)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aSmtpServer);
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
// First try the identity's preferred server
|
|
if (aSenderIdentity) {
|
|
nsXPIDLCString smtpServerKey;
|
|
rv = aSenderIdentity->GetSmtpServerKey(getter_Copies(smtpServerKey));
|
|
if (NS_SUCCEEDED(rv) && !(smtpServerKey.IsEmpty()))
|
|
rv = GetServerByKey(smtpServerKey, aSmtpServer);
|
|
}
|
|
|
|
// Fallback to the default
|
|
if (NS_FAILED(rv) || !(*aSmtpServer))
|
|
rv = GetDefaultServer(aSmtpServer);
|
|
return rv;
|
|
}
|