fix crash reading news msg in newsgroup when two accounts point to the same server, patch by frank.schoenheit@gmx.de, whitespace cleanup by me, r=bienvenu, sr=mscott, a=asa 210547

This commit is contained in:
bienvenu%nventure.com 2003-09-10 14:55:19 +00:00
Родитель cf45db3956
Коммит c01ba1217f
2 изменённых файлов: 359 добавлений и 272 удалений

Просмотреть файл

@ -181,7 +181,8 @@ nsMsgFolder::~nsMsgFolder(void)
nsCRT::free(mBaseMessageURI);
gInstanceCount--;
if (gInstanceCount <= 0) {
if (gInstanceCount <= 0)
{
NS_IF_RELEASE(kBiffStateAtom);
NS_IF_RELEASE(kNewMessagesAtom);
NS_IF_RELEASE(kNumNewBiffMessagesAtom);
@ -309,48 +310,57 @@ nsMsgFolder::Write(nsIObjectOutputStream *aStream)
// nsICollection methods:
NS_IMETHODIMP
nsMsgFolder::Count(PRUint32 *result) {
nsMsgFolder::Count(PRUint32 *result)
{
return mSubFolders->Count(result);
}
NS_IMETHODIMP
nsMsgFolder::GetElementAt(PRUint32 i, nsISupports* *result) {
nsMsgFolder::GetElementAt(PRUint32 i, nsISupports* *result)
{
return mSubFolders->GetElementAt(i, result);
}
NS_IMETHODIMP
nsMsgFolder::QueryElementAt(PRUint32 i, const nsIID & iid, void * *result) {
nsMsgFolder::QueryElementAt(PRUint32 i, const nsIID & iid, void * *result)
{
return mSubFolders->QueryElementAt(i, iid, result);
}
NS_IMETHODIMP
nsMsgFolder::SetElementAt(PRUint32 i, nsISupports* value) {
nsMsgFolder::SetElementAt(PRUint32 i, nsISupports* value)
{
return mSubFolders->SetElementAt(i, value);
}
NS_IMETHODIMP
nsMsgFolder::AppendElement(nsISupports *aElement) {
nsMsgFolder::AppendElement(nsISupports *aElement)
{
return mSubFolders->AppendElement(aElement);
}
NS_IMETHODIMP
nsMsgFolder::RemoveElement(nsISupports *aElement) {
nsMsgFolder::RemoveElement(nsISupports *aElement)
{
return mSubFolders->RemoveElement(aElement);
}
NS_IMETHODIMP
nsMsgFolder::Enumerate(nsIEnumerator* *result) {
nsMsgFolder::Enumerate(nsIEnumerator* *result)
{
// nsMsgFolders only have subfolders, no message elements
return mSubFolders->Enumerate(result);
}
NS_IMETHODIMP
nsMsgFolder::Clear(void) {
nsMsgFolder::Clear(void)
{
return mSubFolders->Clear();
}
NS_IMETHODIMP
nsMsgFolder::GetURI(char* *name) {
nsMsgFolder::GetURI(char* *name)
{
return nsRDFResource::GetValue(name);
}
@ -427,11 +437,13 @@ NS_IMETHODIMP nsMsgFolder::SetParent(nsIFolder *aParent)
{
mParent = do_GetWeakReference(aParent);
if (aParent) {
if (aParent)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> parentMsgFolder = do_QueryInterface(aParent, &rv);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
// servers do not have parents, so we must not be a server
mIsServer = PR_FALSE;
@ -513,7 +525,8 @@ NS_IMETHODIMP nsMsgFolder::GetServer(nsIMsgIncomingServer ** aServer)
// short circut the server if we have it.
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(mServer, &rv);
if (NS_FAILED(rv) || !server) {
if (NS_FAILED(rv) || !server)
{
// try again after parsing the URI
rv = parseURI(PR_TRUE);
server = do_QueryReferent(mServer);
@ -544,11 +557,12 @@ nsMsgFolder::parseURI(PRBool needServer)
#ifdef MSG_FASTER_URI_PARSING
nsMsgAutoBool parsingUrlState;
if (mParsingURLInUse) {
if (mParsingURLInUse)
{
url = do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
}
else {
else
{
url = mParsingURL;
mParsingURLInUse = PR_TRUE;
parsingUrlState.autoReset(&mParsingURLInUse);
@ -567,10 +581,12 @@ nsMsgFolder::parseURI(PRBool needServer)
//
// empty path tells us it's a server.
if (!mIsServerIsValid) {
if (!mIsServerIsValid)
{
nsCAutoString path;
rv = url->GetPath(path);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
if (!strcmp(path.get(), "/"))
mIsServer = PR_TRUE;
else
@ -580,12 +596,14 @@ nsMsgFolder::parseURI(PRBool needServer)
}
// grab the name off the leaf of the server
if (mName.IsEmpty()) {
if (mName.IsEmpty())
{
// mName:
// the name is the trailing directory in the path
nsCAutoString fileName;
url->GetFileName(fileName);
if (!fileName.IsEmpty()) {
if (!fileName.IsEmpty())
{
// XXX conversion to unicode here? is fileName in UTF8?
// yes, let's say it is in utf8
NS_UnescapeURL((char *)fileName.get());
@ -598,8 +616,8 @@ nsMsgFolder::parseURI(PRBool needServer)
// But avoid this extra work by first asking the parent, if any
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(mServer, &rv);
if (NS_FAILED(rv) || !server) {
if (NS_FAILED(rv) || !server)
{
// first try asking the parent instead of the URI
nsCOMPtr<nsIMsgFolder> parentMsgFolder;
rv = GetParentMsgFolder(getter_AddRefs(parentMsgFolder));
@ -608,7 +626,8 @@ nsMsgFolder::parseURI(PRBool needServer)
rv = parentMsgFolder->GetServer(getter_AddRefs(server));
// no parent. do the extra work of asking
if (!server && needServer) {
if (!server && needServer)
{
// Get username and hostname so we can get the server
nsCAutoString userPass;
rv = url->GetUserPass(userPass);
@ -640,12 +659,14 @@ nsMsgFolder::parseURI(PRBool needServer)
} /* !mServer */
// now try to find the local path for this folder
if (server) {
if (server)
{
nsCAutoString newPath;
nsCAutoString urlPath;
url->GetFilePath(urlPath);
if (!urlPath.IsEmpty()) {
if (!urlPath.IsEmpty())
{
NS_UnescapeURL((char *) urlPath.get());
// transform the filepath from the URI, such as
@ -663,10 +684,12 @@ nsMsgFolder::parseURI(PRBool needServer)
rv = server->GetLocalPath(getter_AddRefs(serverPath));
if (NS_FAILED(rv)) return rv;
if (serverPath) {
if (serverPath)
{
rv = serverPath->AppendRelativeUnixPath(newPath.get());
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to append to the serverPath");
if (NS_FAILED(rv)) {
if (NS_FAILED(rv))
{
mPath = nsnull;
return rv;
}
@ -686,7 +709,8 @@ nsMsgFolder::GetIsServer(PRBool *aResult)
NS_ENSURE_ARG_POINTER(aResult);
// make sure we've parsed the URI
if (!mIsServerIsValid) {
if (!mIsServerIsValid)
{
nsresult rv = parseURI();
if (NS_FAILED(rv) || !mIsServerIsValid)
return NS_ERROR_FAILURE;
@ -783,7 +807,8 @@ nsMsgFolder::GetCanRename(PRBool *aResult)
// by default, you can't rename servers, only folders
// if otherwise, override it.
if (isServer) {
if (isServer)
{
*aResult = PR_FALSE;
}
//
@ -805,10 +830,12 @@ nsMsgFolder::GetCanRename(PRBool *aResult)
mFlags & MSG_FOLDER_FLAG_INBOX ||
mFlags & MSG_FOLDER_FLAG_SENTMAIL ||
mFlags & MSG_FOLDER_FLAG_TEMPLATES ||
mFlags & MSG_FOLDER_FLAG_JUNK) {
mFlags & MSG_FOLDER_FLAG_JUNK)
{
*aResult = PR_FALSE;
}
else {
else
{
*aResult = PR_TRUE;
}
return NS_OK;
@ -865,13 +892,15 @@ NS_IMETHODIMP nsMsgFolder::GetName(PRUnichar **name)
NS_ENSURE_ARG_POINTER(name);
nsresult rv;
if (!mHaveParsedURI && mName.IsEmpty()) {
if (!mHaveParsedURI && mName.IsEmpty())
{
rv = parseURI();
if (NS_FAILED(rv)) return rv;
}
// if it's a server, just forward the call
if (mIsServer) {
if (mIsServer)
{
nsCOMPtr<nsIMsgIncomingServer> server;
rv = GetServer(getter_AddRefs(server));
if (NS_SUCCEEDED(rv) && server)
@ -932,7 +961,10 @@ NS_IMETHODIMP nsMsgFolder::GetChildNamed(const PRUnichar *name, nsISupports ** a
}
}
}
return NS_OK;
// don't return NS_OK if we didn't find the folder
// see http://bugzilla.mozilla.org/show_bug.cgi?id=210089#c15
// and http://bugzilla.mozilla.org/show_bug.cgi?id=210089#c17
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsMsgFolder::GetChildWithURI(const char *uri, PRBool deep, PRBool caseInsensitive, nsIMsgFolder ** child)
@ -1188,10 +1220,8 @@ NS_IMETHODIMP nsMsgFolder::ContainsChildNamed(const PRUnichar *name, PRBool* con
*containsChild = PR_FALSE;
nsCOMPtr<nsISupports> child;
if (NS_SUCCEEDED(GetChildNamed(name, getter_AddRefs(child))))
{
*containsChild = child != nsnull;
}
GetChildNamed(name, getter_AddRefs(child));
*containsChild = child != nsnull;
return NS_OK;
}
@ -1287,8 +1317,8 @@ NS_IMETHODIMP nsMsgFolder::GetNumUnread(PRBool deep, PRInt32 *numUnread)
total = 0;
PRUint32 count;
rv = mSubFolders->Count(&count);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
for (PRUint32 i = 0; i < count; i++)
{
nsCOMPtr<nsIMsgFolder> folder(do_QueryElementAt(mSubFolders, i, &rv));
@ -1319,7 +1349,8 @@ NS_IMETHODIMP nsMsgFolder::GetTotalMessages(PRBool deep, PRInt32 *totalMessages)
total = 0;
PRUint32 count;
rv = mSubFolders->Count(&count);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
for (PRUint32 i = 0; i < count; i++)
{
@ -1529,12 +1560,14 @@ NS_IMETHODIMP nsMsgFolder::OnFlagChange(PRUint32 flag)
if (db)
db->Commit(nsMsgDBCommitType::kLargeCommit);
if (flag & MSG_FOLDER_FLAG_OFFLINE) {
if (flag & MSG_FOLDER_FLAG_OFFLINE)
{
PRBool newValue = mFlags & MSG_FOLDER_FLAG_OFFLINE;
rv = NotifyBoolPropertyChanged(kSynchronizeAtom, !newValue, newValue);
NS_ENSURE_SUCCESS(rv,rv);
}
else if (flag & MSG_FOLDER_FLAG_ELIDED) {
else if (flag & MSG_FOLDER_FLAG_ELIDED)
{
PRBool newValue = mFlags & MSG_FOLDER_FLAG_ELIDED;
rv = NotifyBoolPropertyChanged(kOpenAtom, newValue, !newValue);
NS_ENSURE_SUCCESS(rv,rv);
@ -1557,8 +1590,10 @@ NS_IMETHODIMP nsMsgFolder::SetFlags(PRUint32 aFlags)
NS_IMETHODIMP nsMsgFolder::GetFoldersWithFlag(PRUint32 flags, PRUint32 resultsize, PRUint32 *numFolders, nsIMsgFolder **result)
{
PRUint32 num = 0;
if ((flags & mFlags) == flags) {
if (result && (num < resultsize)) {
if ((flags & mFlags) == flags)
{
if (result && (num < resultsize))
{
result[num] = this;
NS_IF_ADDREF(result[num]);
}
@ -1574,7 +1609,8 @@ NS_IMETHODIMP nsMsgFolder::GetFoldersWithFlag(PRUint32 flags, PRUint32 resultsiz
NS_ENSURE_SUCCESS(rv,rv);
rv = mSubFolders->Count(&cnt);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
for (PRUint32 i=0; i < cnt; i++)
{
nsCOMPtr<nsIMsgFolder> folder(do_QueryElementAt(mSubFolders, i, &rv));
@ -1622,7 +1658,8 @@ NS_IMETHODIMP nsMsgFolder::GetExpansionArray(nsISupportsArray *expansionArray)
{
PRUint32 cnt2;
rv = expansionArray->Count(&cnt2);
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
expansionArray->InsertElementAt(folder, cnt2);
PRUint32 flags;
folder->GetFlags(&flags);
@ -1950,7 +1987,8 @@ NS_IMETHODIMP nsMsgFolder::GetNewMessagesNotificationDescription(PRUnichar * *aD
// append the server name
nsXPIDLString serverName;
rv = server->GetPrettyName(getter_Copies(serverName));
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
// put this test here because we don't want to just put "folder name on"
// in case the above failed
if (!(mFlags & MSG_FOLDER_FLAG_INBOX))

Просмотреть файл

@ -103,7 +103,7 @@ nsNntpService::nsNntpService()
nsNntpService::~nsNntpService()
{
// do nothing
// do nothing
}
NS_IMPL_THREADSAFE_ADDREF(nsNntpService)
@ -129,13 +129,14 @@ nsNntpService::SaveMessageToDisk(const char *aMessageURI,
nsIUrlListener *aUrlListener,
nsIURI **aURL,
PRBool canonicalLineEnding,
nsIMsgWindow *aMsgWindow)
nsIMsgWindow *aMsgWindow)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(aMessageURI);
// double check it is a news-message:/ uri
if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen)) {
if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen))
{
rv = NS_ERROR_UNEXPECTED;
NS_ENSURE_SUCCESS(rv,rv);
}
@ -392,8 +393,8 @@ nsNntpService::FetchMessage(nsIMsgFolder *folder, nsMsgKey key, nsIMsgWindow *aM
if (aURL)
{
*aURL = url;
NS_IF_ADDREF(*aURL);
*aURL = url;
NS_IF_ADDREF(*aURL);
}
return rv;
@ -464,7 +465,7 @@ NS_IMETHODIMP nsNntpService::OpenAttachment(const char *aContentType,
}
else
return RunNewsUrl(url, aMsgWindow, aDisplayConsumer);
}
}
return NS_OK;
}
@ -475,7 +476,8 @@ NS_IMETHODIMP nsNntpService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL
NS_ENSURE_ARG_POINTER(aMessageURI);
// double check that it is a news-message:/ uri
if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen)) {
if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen))
{
rv = NS_ERROR_UNEXPECTED;
NS_ENSURE_SUCCESS(rv,rv);
}
@ -511,7 +513,8 @@ nsNntpService::DecomposeNewsURI(const char *uri, nsIMsgFolder **folder, nsMsgKey
{
nsresult rv;
// if we fix DecomposeNewsMessage to handle news message scheme, we could use it exclusively
if (nsCRT::strncmp(uri, kNewsMessageRootURI, kNewsMessageRootURILen) == 0) {
if (nsCRT::strncmp(uri, kNewsMessageRootURI, kNewsMessageRootURILen) == 0)
{
rv = DecomposeNewsMessageURI(uri, folder, aMsgKey);
NS_ENSURE_SUCCESS(rv,rv);
}
@ -621,11 +624,21 @@ nsNntpService::GetFolderFromUri(const char *aUri, nsIMsgFolder **aFolder)
rv = uri->GetPath(path);
NS_ENSURE_SUCCESS(rv,rv);
nsCAutoString userPass;
rv = uri->GetUserPass(userPass);
NS_ENSURE_SUCCESS(rv,rv);
char *unescapedUserPass = ToNewCString(userPass);
if (!unescapedUserPass)
return NS_ERROR_OUT_OF_MEMORY;
nsUnescape(unescapedUserPass);
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIMsgIncomingServer> server;
rv = accountManager->FindServer("", hostName.get(), "nntp", getter_AddRefs(server));
rv = accountManager->FindServer(unescapedUserPass, hostName.get(), "nntp", getter_AddRefs(server));
PR_Free(unescapedUserPass);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIFolder> rootFolder;
@ -634,9 +647,8 @@ nsNntpService::GetFolderFromUri(const char *aUri, nsIMsgFolder **aFolder)
// check if path is "/"
// if so, use the root folder
if (path.Length() == 1) {
if (path.Length() == 1)
return rootFolder->QueryInterface(NS_GET_IID(nsIMsgFolder), (void **) aFolder);
}
// the URI is news://host/(escaped group)
// but the *name* of the newsgroup (we are calling ::GetChildNamed())
@ -667,14 +679,14 @@ nsNntpService::CopyMessage(const char * aSrcMessageURI, nsIStreamListener * aMai
NS_ENSURE_SUCCESS(rv,rv);
rv = DisplayMessage(aSrcMessageURI, streamSupport, aMsgWindow, aUrlListener, nsnull, aURL);
return rv;
return rv;
}
NS_IMETHODIMP
nsNntpService::CopyMessages(nsMsgKeyArray *keys, nsIMsgFolder *srcFolder, nsIStreamListener * aMailboxCopyHandler, PRBool moveMessage,
nsIUrlListener * aUrlListener, nsIMsgWindow *aMsgWindow, nsIURI **aURL)
{
return NS_ERROR_NOT_IMPLEMENTED;
return NS_ERROR_NOT_IMPLEMENTED;
}
typedef struct _findNewsServerEntry {
@ -686,31 +698,33 @@ typedef struct _findNewsServerEntry {
PRBool
nsNntpService::findNewsServerWithGroup(nsISupports *aElement, void *data)
{
nsresult rv;
nsCOMPtr<nsINntpIncomingServer> newsserver = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv) || ! newsserver) return PR_TRUE;
findNewsServerEntry *entry = (findNewsServerEntry*) data;
PRBool containsGroup = PR_FALSE;
rv = newsserver->ContainsNewsgroup((const char *)(entry->newsgroup), &containsGroup);
if (NS_FAILED(rv)) return PR_TRUE;
if (containsGroup) {
entry->server = newsserver;
return PR_FALSE; // stop on first find
}
else {
return PR_TRUE;
}
nsresult rv;
nsCOMPtr<nsINntpIncomingServer> newsserver = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv) || ! newsserver) return PR_TRUE;
findNewsServerEntry *entry = (findNewsServerEntry*) data;
PRBool containsGroup = PR_FALSE;
rv = newsserver->ContainsNewsgroup((const char *)(entry->newsgroup), &containsGroup);
if (NS_FAILED(rv)) return PR_TRUE;
if (containsGroup)
{
entry->server = newsserver;
return PR_FALSE; // stop on first find
}
else
{
return PR_TRUE;
}
}
nsresult
nsNntpService::FindServerWithNewsgroup(nsCString &host, nsCString &groupName)
{
nsresult rv;
nsresult rv;
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
@ -727,7 +741,8 @@ nsNntpService::FindServerWithNewsgroup(nsCString &host, nsCString &groupName)
// this only looks at the list of subscribed newsgroups.
// fix to use the hostinfo.dat information
servers->EnumerateForwards(findNewsServerWithGroup, (void *)&serverInfo);
if (serverInfo.server) {
if (serverInfo.server)
{
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(serverInfo.server);
nsXPIDLCString thisHostname;
rv = server->GetRealHostName(getter_Copies(thisHostname));
@ -794,43 +809,53 @@ nsNntpService::SetUpNntpUrlForPosting(nsINntpUrl *nntpUrl, const char *newsgroup
nsCAutoString currentHost;
// does str start with "news:/"?
if (str.Find(kNewsRootURI) == 0) {
if (str.Find(kNewsRootURI) == 0)
{
// we have news://group or news://host/group
// set theRest to what's after news://
str.Right(theRest, str.Length() - kNewsRootURILen /* for news:/ */ - 1 /* for the slash */);
}
else if (str.Find(":/") != -1) {
else if (str.Find(":/") != -1)
{
// we have x:/y where x != news. this is bad, return failure
CRTFREEIF(list);
return NS_ERROR_FAILURE;
}
else {
else
{
theRest = str;
}
// theRest is "group" or "host/group"
PRInt32 slashpos = theRest.FindChar('/');
if (slashpos > 0 ) {
if (slashpos > 0 )
{
// theRest is "host/group"
theRest.Left(currentHost, slashpos);
theRest.Right(currentGroup, theRest.Length() - slashpos);
}
else {
else
{
// str is "group"
rv = FindHostFromGroup(currentHost, str);
currentGroup = str;
if (NS_FAILED(rv)) {
if (NS_FAILED(rv))
{
CRTFREEIF(list);
return rv;
}
return rv;
}
}
numGroups++;
if (!currentHost.IsEmpty()) {
if (host.IsEmpty()) {
if (!currentHost.IsEmpty())
{
if (host.IsEmpty())
{
host = currentHost;
}
else {
if (!host.Equals(currentHost)) {
else
{
if (!host.Equals(currentHost))
{
// yikes, we are trying to cross post
CRTFREEIF(list);
return NS_ERROR_NNTP_NO_CROSS_POSTING;
@ -846,24 +871,24 @@ nsNntpService::SetUpNntpUrlForPosting(nsINntpUrl *nntpUrl, const char *newsgroup
CRTFREEIF(list);
// if we don't have a news host, find the first news server and use it
if (host.IsEmpty()) {
if (host.IsEmpty())
{
nsCOMPtr<nsIMsgIncomingServer> server;
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
rv = accountManager->FindServer("","","nntp", getter_AddRefs(server));
if (NS_SUCCEEDED(rv) && server) {
nsXPIDLCString newsHostName;
rv = server->GetRealHostName(getter_Copies(newsHostName));
if (NS_SUCCEEDED(rv)) {
host = newsHostName;
}
if (NS_SUCCEEDED(rv) && server)
{
nsXPIDLCString newsHostName;
rv = server->GetRealHostName(getter_Copies(newsHostName));
if (NS_SUCCEEDED(rv))
host = newsHostName;
}
}
// if we *still* don't have a hostname, use "news"
if (host.IsEmpty()) {
if (host.IsEmpty())
host = "news";
}
*newsUrlSpec = PR_smprintf("%s/%s",kNewsRootURI,host.get());
if (!*newsUrlSpec) return NS_ERROR_FAILURE;
@ -901,32 +926,38 @@ nsNntpService::GenerateNewsHeaderValsForPosting(const char *newsgroupsList, char
nsCAutoString newsgroups;
token = nsCRT::strtok(rest, ",", &rest);
while (token && *token) {
while (token && *token)
{
str = token;
str.StripWhitespace();
if (!str.IsEmpty()) {
if (!str.IsEmpty())
{
nsCAutoString currentHost;
nsCAutoString theRest;
// does str start with "news:/"?
if (str.Find(kNewsRootURI) == 0) {
if (str.Find(kNewsRootURI) == 0)
{
// we have news://group or news://host/group
// set theRest to what's after news://
str.Right(theRest, str.Length() - kNewsRootURILen /* for news:/ */ - 1 /* for the slash */);
}
else if (str.Find(":/") != -1) {
else if (str.Find(":/") != -1)
{
// we have x:/y where x != news. this is bad, return failure
CRTFREEIF(list);
return NS_ERROR_FAILURE;
}
else {
else
{
theRest = str;
}
// theRest is "group" or "host/group"
PRInt32 slashpos = theRest.FindChar('/');
if (slashpos > 0 ) {
if (slashpos > 0 )
{
nsCAutoString currentGroup;
// theRest is "host/group"
@ -936,38 +967,43 @@ nsNntpService::GenerateNewsHeaderValsForPosting(const char *newsgroupsList, char
theRest.Right(currentGroup, theRest.Length() - currentHost.Length() - 1);
NS_ASSERTION(!currentGroup.IsEmpty(), "currentGroup is empty");
if (currentGroup.IsEmpty()) {
if (currentGroup.IsEmpty())
{
CRTFREEIF(list);
return NS_ERROR_FAILURE;
}
// build up the newsgroups
if (!newsgroups.IsEmpty()) {
if (!newsgroups.IsEmpty())
newsgroups += ",";
}
newsgroups += currentGroup;
}
else {
else
{
// str is "group"
rv = FindHostFromGroup(currentHost, str);
if (NS_FAILED(rv)) {
CRTFREEIF(list);
return rv;
if (NS_FAILED(rv))
{
CRTFREEIF(list);
return rv;
}
// build up the newsgroups
if (!newsgroups.IsEmpty()) {
if (!newsgroups.IsEmpty())
newsgroups += ",";
}
newsgroups += str;
}
if (!currentHost.IsEmpty()) {
if (host.IsEmpty()) {
if (!currentHost.IsEmpty())
{
if (host.IsEmpty())
{
host = currentHost;
}
else {
if (!host.Equals(currentHost)) {
else
{
if (!host.Equals(currentHost))
{
CRTFREEIF(list);
return NS_ERROR_NNTP_NO_CROSS_POSTING;
}
@ -1058,7 +1094,8 @@ nsNntpService::ConstructNntpUrl(const char *urlString, nsIUrlListener *aUrlListe
mailnewsurl->SetSpec(nsDependentCString(urlString));
nntpUrl->SetNewsAction(action);
if (originalMessageUri) {
if (originalMessageUri)
{
// we'll use this later in nsNNTPProtocol::ParseURL()
rv = msgUrl->SetOriginalSpec(originalMessageUri);
NS_ENSURE_SUCCESS(rv,rv);
@ -1075,51 +1112,51 @@ nsNntpService::ConstructNntpUrl(const char *urlString, nsIUrlListener *aUrlListe
nsresult
nsNntpService::CreateNewsAccount(const char *aHostname, PRBool aIsSecure, PRInt32 aPort, nsIMsgIncomingServer **aServer)
{
NS_ENSURE_ARG_POINTER(aHostname);
NS_ENSURE_ARG_POINTER(aServer);
nsresult rv;
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIMsgAccount> account;
rv = accountManager->CreateAccount(getter_AddRefs(account));
if (NS_FAILED(rv)) return rv;
// for news, username is always null
rv = accountManager->CreateIncomingServer(nsnull /* username */, aHostname, "nntp", aServer);
if (NS_FAILED(rv)) return rv;
rv = (*aServer)->SetIsSecure(aIsSecure);
if (NS_FAILED(rv)) return rv;
rv = (*aServer)->SetPort(aPort);
if (NS_FAILED(rv)) return rv;
nsCOMPtr <nsIMsgIdentity> identity;
rv = accountManager->CreateIdentity(getter_AddRefs(identity));
if (NS_FAILED(rv)) return rv;
if (!identity) return NS_ERROR_FAILURE;
// by default, news accounts should be composing in plain text
rv = identity->SetComposeHtml(PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
// the identity isn't filled in, so it is not valid.
rv = (*aServer)->SetValid(PR_FALSE);
if (NS_FAILED(rv)) return rv;
// hook them together
rv = account->SetIncomingServer(*aServer);
if (NS_FAILED(rv)) return rv;
rv = account->AddIdentity(identity);
if (NS_FAILED(rv)) return rv;
// Now save the new acct info to pref file.
rv = accountManager->SaveAccountInfo();
if (NS_FAILED(rv)) return rv;
return NS_OK;
NS_ENSURE_ARG_POINTER(aHostname);
NS_ENSURE_ARG_POINTER(aServer);
nsresult rv;
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIMsgAccount> account;
rv = accountManager->CreateAccount(getter_AddRefs(account));
if (NS_FAILED(rv)) return rv;
// for news, username is always null
rv = accountManager->CreateIncomingServer(nsnull /* username */, aHostname, "nntp", aServer);
if (NS_FAILED(rv)) return rv;
rv = (*aServer)->SetIsSecure(aIsSecure);
if (NS_FAILED(rv)) return rv;
rv = (*aServer)->SetPort(aPort);
if (NS_FAILED(rv)) return rv;
nsCOMPtr <nsIMsgIdentity> identity;
rv = accountManager->CreateIdentity(getter_AddRefs(identity));
if (NS_FAILED(rv)) return rv;
if (!identity) return NS_ERROR_FAILURE;
// by default, news accounts should be composing in plain text
rv = identity->SetComposeHtml(PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
// the identity isn't filled in, so it is not valid.
rv = (*aServer)->SetValid(PR_FALSE);
if (NS_FAILED(rv)) return rv;
// hook them together
rv = account->SetIncomingServer(*aServer);
if (NS_FAILED(rv)) return rv;
rv = account->AddIdentity(identity);
if (NS_FAILED(rv)) return rv;
// Now save the new acct info to pref file.
rv = accountManager->SaveAccountInfo();
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
nsresult
@ -1156,13 +1193,14 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
rv = accounts->Count(&accountCount);
if (NS_FAILED(rv)) return rv;
if (accountCount == 0) {
if (accountCount == 0)
{
nsCOMPtr <nsIMessengerMigrator> messengerMigrator = do_GetService(kMessengerMigratorCID, &rv);
if (NS_FAILED(rv)) return rv;
if (!messengerMigrator) return NS_ERROR_FAILURE;
if (!messengerMigrator) return NS_ERROR_FAILURE;
// migration can fail;
messengerMigrator->UpgradePrefs();
// migration can fail;
messengerMigrator->UpgradePrefs();
}
// news:group becomes news://group, so we have three types of urls:
@ -1181,7 +1219,8 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
getter_AddRefs(server));
// if we didn't find the server, and path was "/", this is a news://group url
if (!server && !strcmp("/",path.get())) {
if (!server && !strcmp("/",path.get()))
{
// the uri was news://group and we want to turn that into news://host/group
// step 1, set the path to be the hostName;
rv = aUri->SetPath(hostName);
@ -1189,7 +1228,8 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
// until we support default news servers, use the first nntp server we find
rv = accountManager->FindServer("","","nntp", getter_AddRefs(server));
if (NS_FAILED(rv) || !server) {
if (NS_FAILED(rv) || !server)
{
// step 2, set the uri's hostName and the local variable hostName
// to be "news"
rv = aUri->SetHost(NS_LITERAL_CSTRING("news"));
@ -1198,7 +1238,8 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
rv = aUri->GetAsciiHost(hostName);
NS_ENSURE_SUCCESS(rv,rv);
}
else {
else
{
// step 2, set the uri's hostName and the local variable hostName
// to be the host name of the server we found
nsXPIDLCString hostBuf;
@ -1211,15 +1252,16 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
}
}
if (NS_FAILED(rv) || !server) {
PRBool isSecure = PR_FALSE;
if (PL_strcasecmp("snews",scheme.get()) == 0) {
isSecure = PR_TRUE;
if ((port == 0) || (port == -1)) {
port = SECURE_NEWS_PORT;
}
}
rv = CreateNewsAccount(hostName.get(), isSecure, port, getter_AddRefs(server));
if (NS_FAILED(rv) || !server)
{
PRBool isSecure = PR_FALSE;
if (PL_strcasecmp("snews",scheme.get()) == 0)
{
isSecure = PR_TRUE;
if ((port == 0) || (port == -1))
port = SECURE_NEWS_PORT;
}
rv = CreateNewsAccount(hostName.get(), isSecure, port, getter_AddRefs(server));
}
if (NS_FAILED(rv)) return rv;
@ -1249,10 +1291,12 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
// XXX todo, or do we want to check if it is a news-message:// uri or
// a news:// uri (but action is not a fetch related action?)
if (!PL_strncmp(spec.get(), kNewsMessageRootURI, kNewsMessageRootURILen) ||
(action == nsINntpUrl::ActionFetchPart || action == nsINntpUrl::ActionFetchArticle)) {
(action == nsINntpUrl::ActionFetchPart || action == nsINntpUrl::ActionFetchArticle))
{
#else
// if this is a news-message:/ uri, decompose it and set hasMsgOffline on the uri
if (!PL_strncmp(spec.get(), kNewsMessageRootURI, kNewsMessageRootURILen)) {
if (!PL_strncmp(spec.get(), kNewsMessageRootURI, kNewsMessageRootURILen))
{
#endif
nsCOMPtr <nsIMsgFolder> folder;
nsMsgKey key = nsMsgKey_None;
@ -1280,9 +1324,8 @@ PRBool nsNntpService::WeAreOffline()
nsCOMPtr<nsIIOService> netService(do_GetService(kIOServiceCID, &rv));
if (NS_SUCCEEDED(rv) && netService)
{
netService->GetOffline(&offline);
}
return offline;
}
@ -1317,29 +1360,30 @@ NS_IMETHODIMP nsNntpService::GetNewNews(nsINntpIncomingServer *nntpServer, const
server = do_QueryInterface(nntpServer);
/* double check that it is a "news:/" url */
if (nsCRT::strncmp(uri, kNewsRootURI, kNewsRootURILen) == 0) {
if (nsCRT::strncmp(uri, kNewsRootURI, kNewsRootURILen) == 0)
{
nsCOMPtr<nsIURI> aUrl;
rv = ConstructNntpUrl(uri, aUrlListener, aMsgWindow, nsnull, nsINntpUrl::ActionGetNewNews, getter_AddRefs(aUrl));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsINntpUrl> nntpUrl = do_QueryInterface(aUrl);
if (nntpUrl) {
if (nntpUrl)
{
rv = nntpUrl->SetGetOldMessages(aGetOld);
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIMsgMailNewsUrl> mailNewsUrl = do_QueryInterface(aUrl);
if (mailNewsUrl) {
if (mailNewsUrl)
mailNewsUrl->SetUpdatingFolder(PR_TRUE);
}
rv = RunNewsUrl(aUrl, aMsgWindow, nsnull);
if (_retval) {
if (_retval)
NS_IF_ADDREF(*_retval = aUrl);
}
}
else {
else
{
NS_ASSERTION(0,"not a news:/ url");
rv = NS_ERROR_FAILURE;
}
@ -1364,7 +1408,8 @@ nsNntpService::CancelMessage(const char *cancelURL, const char *messageURI, nsIS
rv = RunNewsUrl(url, aMsgWindow, aConsumer);
NS_ENSURE_SUCCESS(rv,rv);
if (aURL) {
if (aURL)
{
*aURL = url;
NS_IF_ADDREF(*aURL);
}
@ -1374,8 +1419,8 @@ nsNntpService::CancelMessage(const char *cancelURL, const char *messageURI, nsIS
NS_IMETHODIMP nsNntpService::GetScheme(nsACString &aScheme)
{
aScheme = "news";
return NS_OK;
aScheme = "news";
return NS_OK;
}
NS_IMETHODIMP nsNntpService::GetDefaultDoBiff(PRBool *aDoBiff)
@ -1390,7 +1435,7 @@ NS_IMETHODIMP nsNntpService::GetDefaultPort(PRInt32 *aDefaultPort)
{
NS_ENSURE_ARG_POINTER(aDefaultPort);
*aDefaultPort = NEWS_PORT;
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsNntpService::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
@ -1477,11 +1522,13 @@ nsNntpService::GetDefaultLocalPath(nsIFileSpec ** aResult)
nsCOMPtr<nsILocalFile> prefLocal;
rv = prefBranch->GetComplexValue(PREF_MAIL_ROOT_NNTP, NS_GET_IID(nsILocalFile),
getter_AddRefs(prefLocal));
if (NS_SUCCEEDED(rv)) {
if (NS_SUCCEEDED(rv))
{
localFile = prefLocal;
havePref = PR_TRUE;
}
if (!localFile) {
if (!localFile)
{
rv = NS_GetSpecialDirectory(NS_APP_NEWS_50_DIR, getter_AddRefs(localFile));
if (NS_FAILED(rv)) return rv;
havePref = PR_FALSE;
@ -1490,7 +1537,8 @@ nsNntpService::GetDefaultLocalPath(nsIFileSpec ** aResult)
PRBool exists;
rv = localFile->Exists(&exists);
if (NS_FAILED(rv)) return rv;
if (!exists) {
if (!exists)
{
rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0775);
if (NS_FAILED(rv)) return rv;
}
@ -1519,41 +1567,41 @@ nsNntpService::GetServerIID(nsIID* *aServerIID)
NS_IMETHODIMP
nsNntpService::GetRequiresUsername(PRBool *aRequiresUsername)
{
NS_ENSURE_ARG_POINTER(aRequiresUsername);
*aRequiresUsername = PR_FALSE;
return NS_OK;
NS_ENSURE_ARG_POINTER(aRequiresUsername);
*aRequiresUsername = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpService::GetPreflightPrettyNameWithEmailAddress(PRBool *aPreflightPrettyNameWithEmailAddress)
{
NS_ENSURE_ARG_POINTER(aPreflightPrettyNameWithEmailAddress);
*aPreflightPrettyNameWithEmailAddress = PR_FALSE;
return NS_OK;
NS_ENSURE_ARG_POINTER(aPreflightPrettyNameWithEmailAddress);
*aPreflightPrettyNameWithEmailAddress = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpService::GetCanLoginAtStartUp(PRBool *aCanLoginAtStartUp)
{
NS_ENSURE_ARG_POINTER(aCanLoginAtStartUp);
*aCanLoginAtStartUp = PR_FALSE;
return NS_OK;
NS_ENSURE_ARG_POINTER(aCanLoginAtStartUp);
*aCanLoginAtStartUp = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpService::GetCanDelete(PRBool *aCanDelete)
{
NS_ENSURE_ARG_POINTER(aCanDelete);
*aCanDelete = PR_TRUE;
return NS_OK;
NS_ENSURE_ARG_POINTER(aCanDelete);
*aCanDelete = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpService::GetCanDuplicate(PRBool *aCanDuplicate)
{
NS_ENSURE_ARG_POINTER(aCanDuplicate);
*aCanDuplicate = PR_TRUE;
return NS_OK;
NS_ENSURE_ARG_POINTER(aCanDuplicate);
*aCanDuplicate = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
@ -1665,18 +1713,18 @@ NS_IMETHODIMP nsNntpService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgW
NS_IMETHODIMP
nsNntpService::UpdateCounts(nsINntpIncomingServer *aNntpServer, nsIMsgWindow *aMsgWindow)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aNntpServer);
nsCOMPtr<nsIURI> url;
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv)) return rv;
if (!server) return NS_ERROR_FAILURE;
nsXPIDLCString serverUri;
rv = server->GetServerURI(getter_Copies(serverUri));
if (NS_FAILED(rv)) return rv;
nsresult rv;
NS_ENSURE_ARG_POINTER(aNntpServer);
nsCOMPtr<nsIURI> url;
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv)) return rv;
if (!server) return NS_ERROR_FAILURE;
nsXPIDLCString serverUri;
rv = server->GetServerURI(getter_Copies(serverUri));
if (NS_FAILED(rv)) return rv;
rv = ConstructNntpUrl((const char *)serverUri, nsnull, aMsgWindow, nsnull, nsINntpUrl::ActionUpdateCounts, getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
@ -1684,36 +1732,36 @@ nsNntpService::UpdateCounts(nsINntpIncomingServer *aNntpServer, nsIMsgWindow *aM
rv = RunNewsUrl(url, aMsgWindow, nsnull);
// being offline is not an error.
if (NS_SUCCEEDED(rv) || (rv == NS_MSG_ERROR_OFFLINE)) {
if (NS_SUCCEEDED(rv) || (rv == NS_MSG_ERROR_OFFLINE))
return NS_OK;
}
return rv;
}
NS_IMETHODIMP
nsNntpService::GetListOfGroupsOnServer(nsINntpIncomingServer *aNntpServer, nsIMsgWindow *aMsgWindow)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aNntpServer);
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv)) return rv;
if (!server) return NS_ERROR_FAILURE;
nsXPIDLCString serverUri;
rv = server->GetServerURI(getter_Copies(serverUri));
nsCAutoString uriStr;
uriStr += (const char *)serverUri;
uriStr += "/*";
nsresult rv;
NS_ENSURE_ARG_POINTER(aNntpServer);
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv)) return rv;
if (!server) return NS_ERROR_FAILURE;
nsXPIDLCString serverUri;
rv = server->GetServerURI(getter_Copies(serverUri));
nsCAutoString uriStr;
uriStr += (const char *)serverUri;
uriStr += "/*";
nsCOMPtr <nsIUrlListener> listener = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv))
nsCOMPtr <nsIUrlListener> listener = do_QueryInterface(aNntpServer, &rv);
if (NS_FAILED(rv))
return rv;
if (!listener)
if (!listener)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> url;
rv = ConstructNntpUrl(uriStr.get(), listener, aMsgWindow, nsnull, nsINntpUrl::ActionListGroups, getter_AddRefs(url));
if (NS_FAILED(rv))
@ -1723,8 +1771,8 @@ nsNntpService::GetListOfGroupsOnServer(nsINntpIncomingServer *aNntpServer, nsIMs
rv = RunNewsUrl(url, aMsgWindow, nsnull);
if (NS_FAILED(rv))
return rv;
return NS_OK;
return NS_OK;
}
CMDLINEHANDLER3_IMPL(nsNntpService,"-news","general.startup.news","Start with news.",NS_NEWSSTARTUPHANDLER_CONTRACTID,"News Cmd Line Handler", PR_FALSE,"", PR_TRUE)
@ -1732,26 +1780,26 @@ CMDLINEHANDLER3_IMPL(nsNntpService,"-news","general.startup.news","Start with ne
NS_IMETHODIMP nsNntpService::GetChromeUrlForTask(char **aChromeUrlForTask)
{
#ifndef MOZ_THUNDERBIRD
if (!aChromeUrlForTask) return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv))
{
PRInt32 layout;
rv = prefBranch->GetIntPref("mail.pane_config", &layout);
if(NS_SUCCEEDED(rv))
{
if(layout == 0)
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul");
else
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/mail3PaneWindowVertLayout.xul");
return NS_OK;
}
}
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul");
return NS_OK;
if (!aChromeUrlForTask) return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv))
{
PRInt32 layout;
rv = prefBranch->GetIntPref("mail.pane_config", &layout);
if(NS_SUCCEEDED(rv))
{
if(layout == 0)
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul");
else
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/mail3PaneWindowVertLayout.xul");
return NS_OK;
}
}
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/messenger.xul");
return NS_OK;
#else
NS_ENSURE_ARG_POINTER(aChromeUrlForTask);
*aChromeUrlForTask = PL_strdup("chrome://messenger/content/");
@ -1795,7 +1843,8 @@ nsNntpService::HandleContent(const char * aContentType, const char * aCommand, n
NS_ENSURE_SUCCESS(rv, rv);
}
}
} else {
} else
{
// The content-type was not x-application-newsgroup.
return NS_ERROR_WONT_HANDLE_CONTENT;
}