LCOV - code coverage report
Current view: directory - extensions/pref/autoconfig/src - nsAutoConfig.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 248 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Mitesh Shah <mitesh@netscape.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifdef MOZ_LOGGING
      40                 : // sorry, this has to be before the pre-compiled header
      41                 : #define FORCE_PR_LOG /* Allow logging in the release build */
      42                 : #endif
      43                 : #include "nsAutoConfig.h"
      44                 : #include "nsIURI.h"
      45                 : #include "nsIHttpChannel.h"
      46                 : #include "nsIFileStreams.h"
      47                 : #include "nsThreadUtils.h"
      48                 : #include "nsAppDirectoryServiceDefs.h"
      49                 : #include "prmem.h"
      50                 : #include "nsIProfile.h"
      51                 : #include "nsIObserverService.h"
      52                 : #include "nsLiteralString.h"
      53                 : #include "nsIPromptService.h"
      54                 : #include "nsIServiceManager.h"
      55                 : #include "nsIStringBundle.h"
      56                 : #include "nsCRT.h"
      57                 : #include "nspr.h"
      58                 : 
      59                 : PRLogModuleInfo *MCD;
      60                 : 
      61                 : extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
      62                 :                                           const char *filename, 
      63                 :                                           bool bGlobalContext, 
      64                 :                                           bool bCallbacks, 
      65                 :                                           bool skipFirstLine);
      66                 : 
      67                 : // nsISupports Implementation
      68                 : 
      69               0 : NS_IMPL_THREADSAFE_ISUPPORTS6(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener, nsIObserver, nsIRequestObserver, nsISupportsWeakReference)
      70                 : 
      71               0 : nsAutoConfig::nsAutoConfig()
      72                 : {
      73               0 : }
      74                 : 
      75               0 : nsresult nsAutoConfig::Init()
      76                 : {
      77                 :     // member initializers and constructor code
      78                 : 
      79                 :     nsresult rv;
      80               0 :     mLoaded = false;
      81                 :     
      82                 :     // Registering the object as an observer to the profile-after-change topic
      83                 :     nsCOMPtr<nsIObserverService> observerService =
      84               0 :         do_GetService("@mozilla.org/observer-service;1", &rv);
      85               0 :     if (NS_FAILED(rv)) 
      86               0 :         return rv;
      87                 : 
      88               0 :     rv = observerService->AddObserver(this,"profile-after-change", true);
      89                 :     
      90               0 :     return rv;
      91                 : }
      92                 : 
      93               0 : nsAutoConfig::~nsAutoConfig()
      94                 : {
      95               0 : }
      96                 : 
      97                 : // attribute string configURL
      98               0 : NS_IMETHODIMP nsAutoConfig::GetConfigURL(char **aConfigURL)
      99                 : {
     100               0 :     if (!aConfigURL) 
     101               0 :         return NS_ERROR_NULL_POINTER;
     102                 : 
     103               0 :     if (mConfigURL.IsEmpty()) {
     104               0 :         *aConfigURL = nsnull;
     105               0 :         return NS_OK;
     106                 :     }
     107                 :     
     108               0 :     *aConfigURL = ToNewCString(mConfigURL);
     109               0 :     if (!*aConfigURL)
     110               0 :         return NS_ERROR_OUT_OF_MEMORY;
     111               0 :     return NS_OK;
     112                 : }
     113               0 : NS_IMETHODIMP nsAutoConfig::SetConfigURL(const char *aConfigURL)
     114                 : {
     115               0 :     if (!aConfigURL)
     116               0 :         return NS_ERROR_NULL_POINTER;
     117               0 :     mConfigURL.Assign(aConfigURL);
     118               0 :     return NS_OK;
     119                 : }
     120                 : 
     121                 : NS_IMETHODIMP
     122               0 : nsAutoConfig::OnStartRequest(nsIRequest *request, nsISupports *context)
     123                 : {
     124               0 :     return NS_OK;
     125                 : }
     126                 : 
     127                 : 
     128                 : NS_IMETHODIMP
     129               0 : nsAutoConfig::OnDataAvailable(nsIRequest *request, 
     130                 :                               nsISupports *context,
     131                 :                               nsIInputStream *aIStream, 
     132                 :                               PRUint32 aSourceOffset,
     133                 :                               PRUint32 aLength)
     134                 : {    
     135                 :     PRUint32 amt, size;
     136                 :     nsresult rv;
     137                 :     char buf[1024];
     138                 :     
     139               0 :     while (aLength) {
     140               0 :         size = NS_MIN<size_t>(aLength, sizeof(buf));
     141               0 :         rv = aIStream->Read(buf, size, &amt);
     142               0 :         if (NS_FAILED(rv))
     143               0 :             return rv;
     144               0 :         mBuf.Append(buf, amt);
     145               0 :         aLength -= amt;
     146                 :     }
     147               0 :     return NS_OK;
     148                 : }
     149                 : 
     150                 : 
     151                 : NS_IMETHODIMP
     152               0 : nsAutoConfig::OnStopRequest(nsIRequest *request, nsISupports *context,
     153                 :                             nsresult aStatus)
     154                 : {
     155                 :     nsresult rv;
     156                 : 
     157                 :     // If the request is failed, go read the failover.jsc file
     158               0 :     if (NS_FAILED(aStatus)) {
     159               0 :         PR_LOG(MCD, PR_LOG_DEBUG, ("mcd request failed with status %x\n", aStatus));
     160               0 :         return readOfflineFile();
     161                 :     }
     162                 : 
     163                 :     // Checking for the http response, if failure go read the failover file.
     164               0 :     nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
     165               0 :     if (pHTTPCon) {
     166                 :         PRUint32 httpStatus;
     167               0 :         pHTTPCon->GetResponseStatus(&httpStatus);
     168               0 :         if (httpStatus != 200) 
     169                 :         {
     170               0 :             PR_LOG(MCD, PR_LOG_DEBUG, ("mcd http request failed with status %x\n", httpStatus));
     171               0 :             return readOfflineFile();
     172                 :         }
     173                 :     }
     174                 :     
     175                 :     // Send the autoconfig.jsc to javascript engine.
     176                 :     
     177                 :     rv = EvaluateAdminConfigScript(mBuf.get(), mBuf.Length(),
     178               0 :                               nsnull, false,true, false);
     179               0 :     if (NS_SUCCEEDED(rv)) {
     180                 : 
     181                 :         // Write the autoconfig.jsc to failover.jsc (cached copy) 
     182               0 :         rv = writeFailoverFile(); 
     183                 : 
     184               0 :         if (NS_FAILED(rv)) 
     185               0 :             NS_WARNING("Error writing failover.jsc file");
     186                 : 
     187                 :         // Releasing the lock to allow the main thread to start execution
     188               0 :         mLoaded = true;  
     189                 : 
     190               0 :         return NS_OK;
     191                 :     }
     192                 :     // there is an error in parsing of the autoconfig file.
     193               0 :     NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
     194               0 :     return readOfflineFile();
     195                 : }
     196                 : 
     197                 : // Notify method as a TimerCallBack function 
     198               0 : NS_IMETHODIMP nsAutoConfig::Notify(nsITimer *timer) 
     199                 : {
     200               0 :     downloadAutoConfig();
     201               0 :     return NS_OK;
     202                 : }
     203                 : 
     204                 : /* Observe() is called twice: once at the instantiation time and other 
     205                 :    after the profile is set. It doesn't do anything but return NS_OK during the
     206                 :    creation time. Second time it calls  downloadAutoConfig().
     207                 : */
     208                 : 
     209               0 : NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject, 
     210                 :                                     const char *aTopic, 
     211                 :                                     const PRUnichar *someData)
     212                 : {
     213               0 :     nsresult rv = NS_OK;
     214               0 :     if (!nsCRT::strcmp(aTopic, "profile-after-change")) {
     215                 : 
     216                 :         // Getting the current profile name since we already have the 
     217                 :         // pointer to the object.
     218               0 :         nsCOMPtr<nsIProfile> profile = do_QueryInterface(aSubject);
     219               0 :         if (profile) {
     220               0 :             nsXPIDLString profileName;
     221               0 :             rv = profile->GetCurrentProfile(getter_Copies(profileName));
     222               0 :             if (NS_SUCCEEDED(rv)) {
     223                 :                 // setting the member variable to the current profile name
     224               0 :                 CopyUTF16toUTF8(profileName, mCurrProfile);
     225                 :             }
     226                 :             else {
     227               0 :                 NS_WARNING("nsAutoConfig::GetCurrentProfile() failed");
     228                 :             }
     229                 :         } 
     230                 : 
     231                 :         // We will be calling downloadAutoConfig even if there is no profile 
     232                 :         // name. Nothing will be passed as a parameter to the URL and the
     233                 :         // default case will be picked up by the script.
     234                 :         
     235               0 :         rv = downloadAutoConfig();
     236                 : 
     237                 :     }  
     238                 :    
     239               0 :     return rv;
     240                 : }
     241                 : 
     242               0 : nsresult nsAutoConfig::downloadAutoConfig()
     243                 : {
     244                 :     nsresult rv;
     245               0 :     nsCAutoString emailAddr;
     246               0 :     nsXPIDLCString urlName;
     247                 :     static bool firstTime = true;
     248                 :     
     249               0 :     if (mConfigURL.IsEmpty()) {
     250               0 :         PR_LOG(MCD, PR_LOG_DEBUG, ("global config url is empty - did you set autoadmin.global_config_url?\n"));
     251               0 :         NS_WARNING("AutoConfig called without global_config_url");
     252               0 :         return NS_OK;
     253                 :     }
     254                 :     
     255                 :     // If there is an email address appended as an argument to the ConfigURL
     256                 :     // in the previous read, we need to remove it when timer kicks in and 
     257                 :     // downloads the autoconfig file again. 
     258                 :     // If necessary, the email address will be added again as an argument.
     259               0 :     PRInt32 index = mConfigURL.RFindChar((PRUnichar)'?');
     260               0 :     if (index != -1)
     261               0 :         mConfigURL.Truncate(index);
     262                 : 
     263                 :     // Clean up the previous read, the new read is going to use the same buffer
     264               0 :     if (!mBuf.IsEmpty())
     265               0 :         mBuf.Truncate(0);
     266                 : 
     267                 :     // Get the preferences branch and save it to the member variable
     268               0 :     if (!mPrefBranch) {
     269                 :         nsCOMPtr<nsIPrefService> prefs =
     270               0 :             do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
     271               0 :         if (NS_FAILED(rv)) 
     272               0 :             return rv;
     273                 :     
     274               0 :         rv = prefs->GetBranch(nsnull,getter_AddRefs(mPrefBranch));
     275               0 :         if (NS_FAILED(rv))
     276               0 :             return rv;
     277                 :     }
     278                 :     
     279                 :     // Check to see if the network is online/offline 
     280               0 :     nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     281               0 :     if (NS_FAILED(rv)) 
     282               0 :         return rv;
     283                 :     
     284                 :     bool offline;
     285               0 :     rv = ios->GetOffline(&offline);
     286               0 :     if (NS_FAILED(rv)) 
     287               0 :         return rv;
     288                 :     
     289               0 :     if (offline) {
     290                 :         bool offlineFailover;
     291               0 :         rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover", 
     292               0 :                                       &offlineFailover);
     293                 :         // Read the failover.jsc if the network is offline and the pref says so
     294               0 :         if (NS_SUCCEEDED(rv) && offlineFailover)
     295               0 :             return readOfflineFile();
     296                 :     }
     297                 : 
     298                 :     /* Append user's identity at the end of the URL if the pref says so.
     299                 :        First we are checking for the user's email address but if it is not
     300                 :        available in the case where the client is used without messenger, user's
     301                 :        profile name will be used as an unique identifier
     302                 :     */
     303                 :     bool appendMail;
     304               0 :     rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail);
     305               0 :     if (NS_SUCCEEDED(rv) && appendMail) {
     306               0 :         rv = getEmailAddr(emailAddr);
     307               0 :         if (NS_SUCCEEDED(rv) && emailAddr.get()) {
     308                 :             /* Adding the unique identifier at the end of autoconfig URL. 
     309                 :                In this case the autoconfig URL is a script and 
     310                 :                emailAddr as passed as an argument 
     311                 :             */
     312               0 :             mConfigURL.Append("?");
     313               0 :             mConfigURL.Append(emailAddr); 
     314                 :         }
     315                 :     }
     316                 :     
     317                 :     // create a new url 
     318               0 :     nsCOMPtr<nsIURI> url;
     319               0 :     nsCOMPtr<nsIChannel> channel;
     320                 :     
     321               0 :     rv = NS_NewURI(getter_AddRefs(url), mConfigURL.get(), nsnull, nsnull);
     322               0 :     if (NS_FAILED(rv))
     323                 :     {
     324               0 :         PR_LOG(MCD, PR_LOG_DEBUG, ("failed to create URL - is autoadmin.global_config_url valid? - %s\n", mConfigURL.get()));
     325               0 :         return rv;
     326                 :     }
     327                 : 
     328               0 :     PR_LOG(MCD, PR_LOG_DEBUG, ("running MCD url %s\n", mConfigURL.get()));
     329                 :     // open a channel for the url
     330               0 :     rv = NS_NewChannel(getter_AddRefs(channel),url, nsnull, nsnull, nsnull, nsIRequest::INHIBIT_PERSISTENT_CACHING | nsIRequest::LOAD_BYPASS_CACHE);
     331               0 :     if (NS_FAILED(rv)) 
     332               0 :         return rv;
     333                 : 
     334               0 :     rv = channel->AsyncOpen(this, nsnull); 
     335               0 :     if (NS_FAILED(rv)) {
     336               0 :         readOfflineFile();
     337               0 :         return rv;
     338                 :     }
     339                 :     
     340                 :     // Set a repeating timer if the pref is set.
     341                 :     // This is to be done only once.
     342                 :     // Also We are having the event queue processing only for the startup
     343                 :     // It is not needed with the repeating timer.
     344               0 :     if (firstTime) {
     345               0 :         firstTime = false;
     346                 :     
     347                 :         // Getting the current thread. If we start an AsyncOpen, the thread
     348                 :         // needs to wait before the reading of autoconfig is done
     349                 : 
     350               0 :         nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
     351               0 :         NS_ENSURE_STATE(thread);
     352                 :     
     353                 :         /* process events until we're finished. AutoConfig.jsc reading needs
     354                 :            to be finished before the browser starts loading up
     355                 :            We are waiting for the mLoaded which will be set through 
     356                 :            onStopRequest or readOfflineFile methods
     357                 :            There is a possibility of deadlock so we need to make sure
     358                 :            that mLoaded will be set to true in any case (success/failure)
     359                 :         */
     360                 :         
     361               0 :         while (!mLoaded)
     362               0 :             NS_ENSURE_STATE(NS_ProcessNextEvent(thread));
     363                 :         
     364                 :         PRInt32 minutes;
     365               0 :         rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval", 
     366               0 :                                      &minutes);
     367               0 :         if (NS_SUCCEEDED(rv) && minutes > 0) {
     368                 :             // Create a new timer and pass this nsAutoConfig 
     369                 :             // object as a timer callback. 
     370               0 :             mTimer = do_CreateInstance("@mozilla.org/timer;1",&rv);
     371               0 :             if (NS_FAILED(rv)) 
     372               0 :                 return rv;
     373               0 :             rv = mTimer->InitWithCallback(this, minutes * 60 * 1000, 
     374               0 :                              nsITimer::TYPE_REPEATING_SLACK);
     375               0 :             if (NS_FAILED(rv)) 
     376               0 :                 return rv;
     377                 :         }
     378                 :     } //first_time
     379                 :     
     380               0 :     return NS_OK;
     381                 : } // nsPref::downloadAutoConfig()
     382                 : 
     383                 : 
     384                 : 
     385               0 : nsresult nsAutoConfig::readOfflineFile()
     386                 : {
     387                 :     nsresult rv;
     388                 :     
     389                 :     /* Releasing the lock to allow main thread to start 
     390                 :        execution. At this point we do not need to stall 
     391                 :        the thread since all network activities are done.
     392                 :     */
     393               0 :     mLoaded = true; 
     394                 : 
     395                 :     bool failCache;
     396               0 :     rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
     397               0 :     if (NS_SUCCEEDED(rv) && !failCache) {
     398                 :         // disable network connections and return.
     399                 :         
     400                 :         nsCOMPtr<nsIIOService> ios =
     401               0 :             do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     402               0 :         if (NS_FAILED(rv)) 
     403               0 :             return rv;
     404                 :         
     405                 :         bool offline;
     406               0 :         rv = ios->GetOffline(&offline);
     407               0 :         if (NS_FAILED(rv)) 
     408               0 :             return rv;
     409                 : 
     410               0 :         if (!offline) {
     411               0 :             rv = ios->SetOffline(true);
     412               0 :             if (NS_FAILED(rv)) 
     413               0 :                 return rv;
     414                 :         }
     415                 :         
     416                 :         // lock the "network.online" prference so user cannot toggle back to
     417                 :         // online mode.
     418               0 :         rv = mPrefBranch->SetBoolPref("network.online", false);
     419               0 :         if (NS_FAILED(rv)) 
     420               0 :             return rv;
     421                 : 
     422               0 :         mPrefBranch->LockPref("network.online");
     423               0 :         return NS_OK;
     424                 :     }
     425                 :     
     426                 :     /* faiover_to_cached is set to true so 
     427                 :        Open the file and read the content.
     428                 :        execute the javascript file
     429                 :     */
     430                 :     
     431               0 :     nsCOMPtr<nsIFile> failoverFile; 
     432                 :     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
     433               0 :                                 getter_AddRefs(failoverFile));
     434               0 :     if (NS_FAILED(rv)) 
     435               0 :         return rv;
     436                 :     
     437               0 :     failoverFile->AppendNative(NS_LITERAL_CSTRING("failover.jsc"));
     438               0 :     rv = evaluateLocalFile(failoverFile);
     439               0 :     if (NS_FAILED(rv)) 
     440               0 :         NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
     441               0 :     return NS_OK;
     442                 : }
     443                 : 
     444               0 : nsresult nsAutoConfig::evaluateLocalFile(nsIFile *file)
     445                 : {
     446                 :     nsresult rv;
     447               0 :     nsCOMPtr<nsIInputStream> inStr;
     448                 :     
     449               0 :     rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
     450               0 :     if (NS_FAILED(rv)) 
     451               0 :         return rv;
     452                 :         
     453                 :     PRInt64 fileSize;
     454               0 :     PRUint32 fs, amt=0;
     455               0 :     file->GetFileSize(&fileSize);
     456               0 :     LL_L2UI(fs, fileSize); // Converting 64 bit structure to unsigned int
     457               0 :     char *buf = (char *)PR_Malloc(fs * sizeof(char));
     458               0 :     if (!buf) 
     459               0 :         return NS_ERROR_OUT_OF_MEMORY;
     460                 :     
     461               0 :     rv = inStr->Read(buf, fs, &amt);
     462               0 :     if (NS_SUCCEEDED(rv)) {
     463                 :       EvaluateAdminConfigScript(buf, fs, nsnull, false, 
     464               0 :                                 true, false);
     465                 :     }
     466               0 :     inStr->Close();
     467               0 :     PR_Free(buf);
     468               0 :     return rv;
     469                 : }
     470                 : 
     471               0 : nsresult nsAutoConfig::writeFailoverFile()
     472                 : {
     473                 :     nsresult rv;
     474               0 :     nsCOMPtr<nsIFile> failoverFile; 
     475               0 :     nsCOMPtr<nsIOutputStream> outStr;
     476                 :     PRUint32 amt;
     477                 :     
     478                 :     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
     479               0 :                                 getter_AddRefs(failoverFile));
     480               0 :     if (NS_FAILED(rv)) 
     481               0 :         return rv;
     482                 :     
     483               0 :     failoverFile->AppendNative(NS_LITERAL_CSTRING("failover.jsc"));
     484                 :     
     485               0 :     rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
     486               0 :     if (NS_FAILED(rv)) 
     487               0 :         return rv;
     488               0 :     rv = outStr->Write(mBuf.get(),mBuf.Length(),&amt);
     489               0 :     outStr->Close();
     490               0 :     return rv;
     491                 : }
     492                 : 
     493               0 : nsresult nsAutoConfig::getEmailAddr(nsACString & emailAddr)
     494                 : {
     495                 :     
     496                 :     nsresult rv;
     497               0 :     nsXPIDLCString prefValue;
     498                 :     
     499                 :     /* Getting an email address through set of three preferences:
     500                 :        First getting a default account with 
     501                 :        "mail.accountmanager.defaultaccount"
     502                 :        second getting an associated id with the default account
     503                 :        Third getting an email address with id
     504                 :     */
     505                 :     
     506               0 :     rv = mPrefBranch->GetCharPref("mail.accountmanager.defaultaccount", 
     507               0 :                                   getter_Copies(prefValue));
     508               0 :     if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty()) {
     509               0 :         emailAddr = NS_LITERAL_CSTRING("mail.account.") +
     510               0 :             prefValue + NS_LITERAL_CSTRING(".identities");
     511               0 :         rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
     512               0 :                                       getter_Copies(prefValue));
     513               0 :         if (NS_FAILED(rv) || prefValue.IsEmpty())
     514               0 :             return PromptForEMailAddress(emailAddr);
     515               0 :         PRInt32 commandIndex = prefValue.FindChar(',');
     516               0 :         if (commandIndex != kNotFound)
     517               0 :           prefValue.Truncate(commandIndex);
     518               0 :         emailAddr = NS_LITERAL_CSTRING("mail.identity.") +
     519               0 :             prefValue + NS_LITERAL_CSTRING(".useremail");
     520               0 :         rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
     521               0 :                                       getter_Copies(prefValue));
     522               0 :         if (NS_FAILED(rv)  || prefValue.IsEmpty())
     523               0 :             return PromptForEMailAddress(emailAddr);
     524               0 :         emailAddr = prefValue;
     525                 :     }
     526                 :     else {
     527                 :         // look for 4.x pref in case we just migrated.
     528               0 :         rv = mPrefBranch->GetCharPref("mail.identity.useremail", 
     529               0 :                                   getter_Copies(prefValue));
     530               0 :         if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty())
     531               0 :             emailAddr = prefValue;
     532               0 :         else if (NS_FAILED(PromptForEMailAddress(emailAddr))  && (!mCurrProfile.IsEmpty()))
     533               0 :             emailAddr = mCurrProfile;
     534                 :     }
     535                 :     
     536               0 :     return NS_OK;
     537                 : }
     538                 :         
     539               0 : nsresult nsAutoConfig::PromptForEMailAddress(nsACString &emailAddress)
     540                 : {
     541                 :     nsresult rv;
     542               0 :     nsCOMPtr<nsIPromptService> promptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
     543               0 :     NS_ENSURE_SUCCESS(rv, rv);
     544               0 :     nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
     545               0 :     NS_ENSURE_SUCCESS(rv, rv);
     546                 : 
     547               0 :     nsCOMPtr<nsIStringBundle> bundle;
     548               0 :     rv = bundleService->CreateBundle("chrome://autoconfig/locale/autoconfig.properties",
     549               0 :                                 getter_AddRefs(bundle));
     550               0 :     NS_ENSURE_SUCCESS(rv, rv);
     551                 : 
     552               0 :     nsXPIDLString title;
     553               0 :     rv = bundle->GetStringFromName(NS_LITERAL_STRING("emailPromptTitle").get(), getter_Copies(title));
     554               0 :     NS_ENSURE_SUCCESS(rv, rv);
     555                 : 
     556               0 :     nsXPIDLString err;
     557               0 :     rv = bundle->GetStringFromName(NS_LITERAL_STRING("emailPromptMsg").get(), getter_Copies(err));
     558               0 :     NS_ENSURE_SUCCESS(rv, rv);
     559               0 :     bool check = false;
     560               0 :     nsXPIDLString emailResult;
     561                 :     bool success;
     562               0 :     rv = promptService->Prompt(nsnull, title.get(), err.get(), getter_Copies(emailResult), nsnull, &check, &success);
     563               0 :     if (!success)
     564               0 :       return NS_ERROR_FAILURE;
     565               0 :     NS_ENSURE_SUCCESS(rv, rv);
     566               0 :     LossyCopyUTF16toASCII(emailResult, emailAddress);
     567               0 :     return NS_OK;
     568                 : }

Generated by: LCOV version 1.7