Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Enumerations | Functions | Variables
nsAppRunner.cpp File Reference
#include "nsAppRunner.h"
#include "nsUpdateDriver.h"
#include "nsBuildID.h"
#include "plevent.h"
#include "prmem.h"
#include "prnetdb.h"
#include "prprf.h"
#include "prproces.h"
#include "prenv.h"
#include "nsIAppShellService.h"
#include "nsIAppStartup.h"
#include "nsIAppStartupNotifier.h"
#include "nsIArray.h"
#include "nsICategoryManager.h"
#include "nsIChromeRegistry.h"
#include "nsICommandLineRunner.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIContentHandler.h"
#include "nsIDialogParamBlock.h"
#include "nsIDOMWindow.h"
#include "nsIEventQueueService.h"
#include "nsIExtensionManager.h"
#include "nsIFastLoadService.h"
#include "nsIGenericFactory.h"
#include "nsIIOService.h"
#include "nsIObserverService.h"
#include "nsINativeAppSupport.h"
#include "nsIProcess.h"
#include "nsIProfileUnlocker.h"
#include "nsIPromptService.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsISupportsPrimitives.h"
#include "nsITimelineService.h"
#include "nsIToolkitChromeRegistry.h"
#include "nsIToolkitProfile.h"
#include "nsIToolkitProfileService.h"
#include "nsIURI.h"
#include "nsIWindowCreator.h"
#include "nsIWindowMediator.h"
#include "nsIWindowWatcher.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsEmbedCID.h"
#include "nsNetUtil.h"
#include "nsStaticComponents.h"
#include "nsXPCOM.h"
#include "nsXPIDLString.h"
#include "nsXPFEComponentsCID.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsXULAppAPI.h"
#include "nsXREDirProvider.h"
#include "nsToolkitCompsCID.h"
#include "nsINIParser.h"
#include "InstallCleanupDefines.h"
#include <stdlib.h>

Go to the source code of this file.

Classes

class  nsXULAppInfo
 The nsXULAppInfo object implements nsIFactory so that it can be its own singleton. More...
class  ScopedXPCOMStartup
 Because we're starting/stopping XPCOM several times in different scenarios, this class is a stack-based critter that makes sure that XPCOM is shut down during early returns. More...
class  nsSingletonFactory
 This is a little factory class that serves as a singleton-service-factory for the nativeappsupport object. More...

Defines

#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT   1
#define HELP_SPACER_1   "\t"
#define HELP_SPACER_2   "\t\t"
#define HELP_SPACER_4   "\t\t\t\t"
#define NS_ENSURE_TRUE_LOG(x, ret)
#define NS_ENSURE_SUCCESS_LOG(res, ret)   NS_ENSURE_TRUE_LOG(NS_SUCCEEDED(res), ret)
#define APPINFO_CID   { 0x95d89e3e, 0xa169, 0x41a3, { 0x8e, 0x56, 0x71, 0x99, 0x78, 0xe1, 0x5b, 0x12 } }
#define NS_ERROR_LAUNCHED_CHILD_PROCESS   NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
#define FILE_COMPATIBILITY_INFO   NS_LITERAL_CSTRING("compatibility.ini")

Enumerations

enum  RemoteResult { REMOTE_NOT_FOUND = 0, REMOTE_FOUND = 1, REMOTE_ARG_BAD = 2 }
enum  ArgResult { ARG_NONE = 0, ARG_FOUND = 1, ARG_BAD = 2 }

Functions

void ShowOSAlert (const char *aMessage)
static void SaveFileToEnv (const char *name, nsIFile *file)
static void SaveFileToEnvIfUnset (const char *name, nsIFile *file)
static PRBool strimatch (const char *lowerstr, const char *mixedstr)
static void RemoveArg (char **argv)
static ArgResult CheckArg (const char *aArg, PRBool aCheckOSInt=PR_FALSE, const char **aParam=nsnull)
 Check for a commandline flag.
static NS_METHOD AppInfoConstructor (nsISupports *aOuter, REFNSIID aIID, void **aResult)
static void DumpArbitraryHelp ()
static void DumpHelp ()
static int VerifyInstallation (nsIFile *aAppDir)
static void DumpVersion ()
nsresult XRE_GetBinaryPath (const char *argv0, nsILocalFile **aResult)
 Get the path of the running application binary and store it in aResult.
static nsresult LaunchChild (nsINativeAppSupport *aNative, PRBool aBlankCommandLine=PR_FALSE, int needElevation=0)
static nsresult ProfileLockedDialog (nsILocalFile *aProfileDir, nsILocalFile *aProfileLocalDir, nsIProfileUnlocker *aUnlocker, nsINativeAppSupport *aNative, nsIProfileLock **aResult)
static nsresult ShowProfileManager (nsIToolkitProfileService *aProfileSvc, nsINativeAppSupport *aNative)
static nsresult ImportProfiles (nsIToolkitProfileService *aPService, nsINativeAppSupport *aNative)
static nsresult SelectProfile (nsIProfileLock **aResult, nsINativeAppSupport *aNative, PRBool *aStartOffline)
static PRBool CheckCompatibility (nsIFile *aProfileDir, const nsCString &aVersion, const nsCString &aOSABI, nsIFile *aXULRunnerDir, nsIFile *aAppDir)
static void BuildVersion (nsCString &aBuf)
static void WriteVersion (nsIFile *aProfileDir, const nsCString &aVersion, const nsCString &aOSABI, nsIFile *aXULRunnerDir, nsIFile *aAppDir)
static PRBool ComponentsListChanged (nsIFile *aProfileDir)
static void RemoveComponentRegistries (nsIFile *aProfileDir, nsIFile *aLocalProfileDir, PRBool aRemoveEMFiles)
static void SaveStateForAppInitiatedRestart ()
static void RestoreStateForAppInitiatedRestart ()
int XRE_main (int argc, char *argv[], const nsXREAppData *aAppData)
 Begin an XUL application.

Variables

int gArgc
char ** gArgv
static int gRestartArgc
static char ** gRestartArgv
PRBool gSafeMode = PR_FALSE
static const nsXULAppInfo kAppInfo
PRBool gLogConsoleErrors = PR_FALSE
static nsModuleComponentInfo kComponents []
static nsStaticModuleInfo const kXREStaticModules []
nsStaticModuleInfo const *const kPStaticModules = kXREStaticModules
PRUint32 const kStaticModuleCount = NS_ARRAY_LENGTH(kXREStaticModules)
static const nsCID kNativeAppSupportCID
static const nsCID kProfileServiceCID
static const char kProfileProperties [] = "chrome://mozapps/locale/profile/profileSelection.properties"
static const char kProfileManagerURL [] = "chrome://mozapps/content/profile/profileSelection.xul"
static PRBool gDoMigration = PR_FALSE
struct {
const char * name
char * value
gSavedVars []
const nsXREAppDatagAppData = nsnull

Define Documentation

#define APPINFO_CID   { 0x95d89e3e, 0xa169, 0x41a3, { 0x8e, 0x56, 0x71, 0x99, 0x78, 0xe1, 0x5b, 0x12 } }

Definition at line 771 of file nsAppRunner.cpp.

Definition at line 1983 of file nsAppRunner.cpp.

#define HELP_SPACER_1   "\t"

Definition at line 183 of file nsAppRunner.cpp.

#define HELP_SPACER_2   "\t\t"

Definition at line 184 of file nsAppRunner.cpp.

#define HELP_SPACER_4   "\t\t\t\t"

Definition at line 185 of file nsAppRunner.cpp.

Definition at line 732 of file nsAppRunner.cpp.

#define NS_ENSURE_TRUE_LOG (   x,
  ret 
)
Value:
PR_BEGIN_MACRO                                 \
  if (NS_UNLIKELY(!(x))) {                       \
    NS_WARNING("NS_ENSURE_TRUE(" #x ") failed"); \
    gLogConsoleErrors = PR_TRUE;                 \
    return ret;                                  \
  }                                              \
  PR_END_MACRO

Definition at line 723 of file nsAppRunner.cpp.

Definition at line 1381 of file nsAppRunner.cpp.

Definition at line 48 of file nsAppRunner.cpp.


Enumeration Type Documentation

enum ArgResult
Enumerator:
ARG_NONE 
ARG_FOUND 
ARG_BAD 

Definition at line 319 of file nsAppRunner.cpp.

               {
  ARG_NONE  = 0,
  ARG_FOUND = 1,
  ARG_BAD   = 2 // you wanted a param, but there isn't one
};
Enumerator:
REMOTE_NOT_FOUND 
REMOTE_FOUND 
REMOTE_ARG_BAD 

Definition at line 313 of file nsAppRunner.cpp.


Function Documentation

static NS_METHOD AppInfoConstructor ( nsISupports *  aOuter,
REFNSIID  aIID,
void **  aResult 
) [static]

Definition at line 707 of file nsAppRunner.cpp.

{
  NS_ENSURE_NO_AGGREGATION(aOuter);

  return NS_CONST_CAST(nsXULAppInfo*, &kAppInfo)->
    QueryInterface(aIID, aResult);
}
static void BuildVersion ( nsCString aBuf) [static]

Definition at line 2050 of file nsAppRunner.cpp.

{
  aBuf.Assign(gAppData->version);
  aBuf.Append('_');
  aBuf.Append(gAppData->buildID);
  aBuf.Append('/');
  aBuf.AppendLiteral(GRE_BUILD_ID);
}

Here is the caller graph for this function:

static ArgResult CheckArg ( const char *  aArg,
PRBool  aCheckOSInt = PR_FALSE,
const char **  aParam = nsnull 
) [static]

Check for a commandline flag.

If the flag takes a parameter, the parameter is returned in aParam. Flags may be in the form -arg or --arg (or /arg on win32/OS2).

Parameters:
aArgthe parameter to check. Must be lowercase.
aCheckOSIntif true returns ARG_BAD if the osint argument is present when aArg is also present.
ifnon-null, the -arg <data> will be stored in this pointer. This is not allocated, but rather a pointer to the argv data.

Definition at line 347 of file nsAppRunner.cpp.

{
  char **curarg = gArgv + 1; // skip argv[0]
  ArgResult ar = ARG_NONE;

  while (*curarg) {
    char *arg = curarg[0];

    if (arg[0] == '-'
#if defined(XP_WIN) || defined(XP_OS2)
        || *arg == '/'
#endif
        ) {
      ++arg;
      if (*arg == '-')
        ++arg;

      if (strimatch(aArg, arg)) {
        RemoveArg(curarg);
        if (!aParam) {
          ar = ARG_FOUND;
          break;
        }

        if (*curarg) {
          if (**curarg == '-'
#if defined(XP_WIN) || defined(XP_OS2)
              || **curarg == '/'
#endif
              )
            return ARG_BAD;

          *aParam = *curarg;
          RemoveArg(curarg);
          ar = ARG_FOUND;
          break;
        }
        return ARG_BAD;
      }
    }

    ++curarg;
  }

  if (aCheckOSInt && ar == ARG_FOUND) {
    ArgResult arOSInt = CheckArg("osint");
    if (arOSInt == ARG_FOUND) {
      ar = ARG_BAD;
      PR_fprintf(PR_STDERR, "Error: argument -osint is invalid\n");
    }
  }

  return ar;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool CheckCompatibility ( nsIFile aProfileDir,
const nsCString aVersion,
const nsCString aOSABI,
nsIFile aXULRunnerDir,
nsIFile aAppDir 
) [static]

Definition at line 1986 of file nsAppRunner.cpp.

{
  nsCOMPtr<nsIFile> file;
  aProfileDir->Clone(getter_AddRefs(file));
  if (!file)
    return PR_FALSE;
  file->AppendNative(FILE_COMPATIBILITY_INFO);

  nsINIParser parser;
  nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
  nsresult rv = parser.Init(localFile);
  if (NS_FAILED(rv))
    return PR_FALSE;

  nsCAutoString buf;
  rv = parser.GetString("Compatibility", "LastVersion", buf);
  if (NS_FAILED(rv))
    return PR_FALSE;

  if (!aVersion.Equals(buf))
    return PR_FALSE;

  rv = parser.GetString("Compatibility", "LastOSABI", buf);
  if (NS_FAILED(rv))
    return PR_FALSE;

  if (!aOSABI.Equals(buf))
    return PR_FALSE;

  rv = parser.GetString("Compatibility", "LastPlatformDir", buf);
  if (NS_FAILED(rv))
    return PR_FALSE;

  nsCOMPtr<nsILocalFile> lf;
  rv = NS_NewNativeLocalFile(buf, PR_FALSE,
                             getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return PR_FALSE;

  PRBool eq;
  rv = lf->Equals(aXULRunnerDir, &eq);
  if (NS_FAILED(rv) || !eq)
    return PR_FALSE;

  if (aAppDir) {
    rv = parser.GetString("Compatibility", "LastAppDir", buf);
    if (NS_FAILED(rv))
      return PR_FALSE;

    rv = NS_NewNativeLocalFile(buf, PR_FALSE,
                               getter_AddRefs(lf));
    if (NS_FAILED(rv))
      return PR_FALSE;

    rv = lf->Equals(aAppDir, &eq);
    if (NS_FAILED(rv) || !eq)
      return PR_FALSE;
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool ComponentsListChanged ( nsIFile aProfileDir) [static]

Definition at line 2113 of file nsAppRunner.cpp.

{
  nsCOMPtr<nsIFile> file;
  aProfileDir->Clone(getter_AddRefs(file));
  if (!file)
    return PR_TRUE;
  file->AppendNative(NS_LITERAL_CSTRING(".autoreg"));

  PRBool exists = PR_FALSE;
  file->Exists(&exists);
  return exists;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DumpArbitraryHelp ( ) [static]

Definition at line 955 of file nsAppRunner.cpp.

{
  nsresult rv;

  nsXREDirProvider dirProvider;
  dirProvider.Initialize(nsnull);

  ScopedXPCOMStartup xpcom;
  xpcom.Initialize();
  xpcom.DoAutoreg();

  nsCOMPtr<nsICommandLineRunner> cmdline
    (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
  if (!cmdline)
    return;

  nsCString text;
  rv = cmdline->GetHelpText(text);
  if (NS_SUCCEEDED(rv))
    printf("%s", text.get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DumpHelp ( ) [static]

Definition at line 981 of file nsAppRunner.cpp.

{
  printf("Usage: %s [ options ... ] [URL]\n", gArgv[0]);
  printf("       where options include:\n");
  printf("\n");

#ifdef MOZ_WIDGET_GTK
  /* insert gtk options above moz options, like any other gtk app
   *
   * note: this isn't a very cool way to do things -- i'd rather get
   * these straight from a user's gtk version -- but it seems to be
   * what most gtk apps do. -dr
   */

  printf("GTK options\n");
  printf("%s--gdk-debug=FLAGS%sGdk debugging flags to set\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--gdk-no-debug=FLAGS%sGdk debugging flags to unset\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--gtk-debug=FLAGS%sGtk+ debugging flags to set\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--gtk-no-debug=FLAGS%sGtk+ debugging flags to unset\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--gtk-module=MODULE%sLoad an additional Gtk module\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s-install%sInstall a private colormap\n", HELP_SPACER_1, HELP_SPACER_2);

  /* end gtk toolkit options */
#endif /* MOZ_WIDGET_GTK */
#if MOZ_WIDGET_XLIB
  printf("Xlib options\n");
  printf("%s-display=DISPLAY%sX display to use\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s-visual=VISUALID%sX visual to use\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s-install_colormap%sInstall own colormap\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s-sync%sMake X calls synchronous\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s-no-xshm%sDon't use X shared memory extension\n", HELP_SPACER_1, HELP_SPACER_2);

  /* end xlib toolkit options */
#endif /* MOZ_WIDGET_XLIB */
#ifdef MOZ_X11
  printf("X11 options\n");
  printf("%s--display=DISPLAY%sX display to use\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--sync%sMake X calls synchronous\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--no-xshm%sDon't use X shared memory extension\n", HELP_SPACER_1, HELP_SPACER_2);
  printf("%s--xim-preedit=STYLE\n", HELP_SPACER_1);
  printf("%s--xim-status=STYLE\n", HELP_SPACER_1);
#endif
#ifdef XP_UNIX
  printf("%s--g-fatal-warnings%sMake all warnings fatal\n", HELP_SPACER_1, HELP_SPACER_2);

  printf("\nMozilla options\n");
#endif

  printf("%s-height <value>%sSet height of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-h or -help%sPrint this message.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-width <value>%sSet width of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-v or -version%sPrint %s version.\n",HELP_SPACER_1,HELP_SPACER_2, gAppData->name);
  printf("%s-P <profile>%sStart with <profile>.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-ProfileManager%sStart with Profile Manager.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-UILocale <locale>%sStart with <locale> resources as UI Locale.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-contentLocale <locale>%sStart with <locale> resources as content Locale.\n",HELP_SPACER_1,HELP_SPACER_2);
  printf("%s-safe-mode%sDisables extensions and themes for this session.\n",HELP_SPACER_1,HELP_SPACER_2);
#if defined(XP_WIN) || defined(XP_OS2)
  printf("%s-console%sStart %s with a debugging console.\n",HELP_SPACER_1,HELP_SPACER_2,gAppData->name);
#endif

  // this works, but only after the components have registered.  so if you drop in a new command line handler, -help
  // won't not until the second run.
  // out of the bug, because we ship a component.reg file, it works correctly.
  DumpArbitraryHelp();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DumpVersion ( ) [static]

Definition at line 1122 of file nsAppRunner.cpp.

Here is the caller graph for this function:

static nsresult ImportProfiles ( nsIToolkitProfileService aPService,
nsINativeAppSupport aNative 
) [static]

Definition at line 1710 of file nsAppRunner.cpp.

{
  nsresult rv;

  PR_SetEnv("XRE_IMPORT_PROFILES=1");

  // try to import old-style profiles
  { // scope XPCOM
    ScopedXPCOMStartup xpcom;
    rv = xpcom.Initialize();
    if (NS_SUCCEEDED(rv)) {
      xpcom.DoAutoreg();
      xpcom.RegisterProfileService(aPService);

#ifdef XP_MACOSX
      SetupMacCommandLine(gRestartArgc, gRestartArgv);
#endif

      nsCOMPtr<nsIProfileMigrator> migrator
        (do_GetService(NS_PROFILEMIGRATOR_CONTRACTID));
      if (migrator) {
        migrator->Import();
      }
    }
  }

  aPService->Flush();
  return LaunchChild(aNative);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult LaunchChild ( nsINativeAppSupport aNative,
PRBool  aBlankCommandLine = PR_FALSE,
int  needElevation = 0 
) [static]

Definition at line 1476 of file nsAppRunner.cpp.

{
  aNative->Quit(); // release DDE mutex, if we're holding it

  // Restart this process by exec'ing it into the current process
  // if supported by the platform.  Otherwise, use NSPR.
 
  if (aBlankCommandLine) {
    gRestartArgc = 1;
    gRestartArgv[gRestartArgc] = nsnull;
  }

  PR_SetEnv("MOZ_LAUNCHED_CHILD=1");

#if defined(XP_MACOSX)
  LaunchChildMac(gRestartArgc, gRestartArgv);
#else
  nsCOMPtr<nsILocalFile> lf;
  nsresult rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return rv;

  nsCAutoString exePath;
  rv = lf->GetNativePath(exePath);
  if (NS_FAILED(rv))
    return rv;

#if defined(XP_WIN)
  if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, needElevation))
    return NS_ERROR_FAILURE;
#elif defined(XP_OS2) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
  // implementation of _execv() is broken with GCC 3.3.x on OS/2
  if (OS2LaunchChild(exePath.get(), gRestartArgc, gRestartArgv) == -1)
    return NS_ERROR_FAILURE;
#elif defined(XP_OS2)
  if (_execv(exePath.get(), gRestartArgv) == -1)
    return NS_ERROR_FAILURE;
#elif defined(XP_UNIX)
  if (execv(exePath.get(), gRestartArgv) == -1)
    return NS_ERROR_FAILURE;
#elif defined(XP_BEOS)
  extern char **environ;
  status_t res;
  res = resume_thread(load_image(gRestartArgc,(const char **)gRestartArgv,(const char **)environ));
  if (res != B_OK)
    return NS_ERROR_FAILURE;
#else
  PRProcess* process = PR_CreateProcess(exePath.get(), gRestartArgv,
                                        nsnull, nsnull);
  if (!process) return NS_ERROR_FAILURE;

  PRInt32 exitCode;
  PRStatus failed = PR_WaitProcess(process, &exitCode);
  if (failed || exitCode)
    return NS_ERROR_FAILURE;
#endif
#endif

  return NS_ERROR_LAUNCHED_CHILD_PROCESS;
}

Here is the call graph for this function:

static nsresult ProfileLockedDialog ( nsILocalFile aProfileDir,
nsILocalFile aProfileLocalDir,
nsIProfileUnlocker aUnlocker,
nsINativeAppSupport aNative,
nsIProfileLock **  aResult 
) [static]

Definition at line 1543 of file nsAppRunner.cpp.

{
  nsresult rv;

  ScopedXPCOMStartup xpcom;
  rv = xpcom.Initialize();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = xpcom.DoAutoreg();
  rv |= xpcom.InitEventQueue();
  rv |= xpcom.SetWindowCreator(aNative);
  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

  { //extra scoping is needed so we release these components before xpcom shutdown
    nsCOMPtr<nsIStringBundleService> sbs
      (do_GetService(NS_STRINGBUNDLE_CONTRACTID));
    NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE);

    nsCOMPtr<nsIStringBundle> sb;
    sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
    NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE);

    NS_ConvertUTF8toUTF16 appName(gAppData->name);
    const PRUnichar* params[] = {appName.get(), appName.get()};

    nsXPIDLString killMessage;
#ifndef XP_MACOSX
    static const PRUnichar kRestartNoUnlocker[] = {'r','e','s','t','a','r','t','M','e','s','s','a','g','e','N','o','U','n','l','o','c','k','e','r','\0'}; // "restartMessageNoUnlocker"
    static const PRUnichar kRestartUnlocker[] = {'r','e','s','t','a','r','t','M','e','s','s','a','g','e','U','n','l','o','c','k','e','r','\0'}; // "restartMessageUnlocker"
#else
    static const PRUnichar kRestartNoUnlocker[] = {'r','e','s','t','a','r','t','M','e','s','s','a','g','e','N','o','U','n','l','o','c','k','e','r','M','a','c','\0'}; // "restartMessageNoUnlockerMac"
    static const PRUnichar kRestartUnlocker[] = {'r','e','s','t','a','r','t','M','e','s','s','a','g','e','U','n','l','o','c','k','e','r','M','a','c','\0'}; // "restartMessageUnlockerMac"
#endif

    sb->FormatStringFromName(aUnlocker ? kRestartUnlocker : kRestartNoUnlocker,
                             params, 2, getter_Copies(killMessage));

    nsXPIDLString killTitle;
    sb->FormatStringFromName(NS_LITERAL_STRING("restartTitle").get(),
                             params, 1, getter_Copies(killTitle));

    if (!killMessage || !killTitle)
      return NS_ERROR_FAILURE;

    nsCOMPtr<nsIPromptService> ps
      (do_GetService(NS_PROMPTSERVICE_CONTRACTID));
    NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE);

    PRUint32 flags = nsIPromptService::BUTTON_TITLE_OK * nsIPromptService::BUTTON_POS_0;

    if (aUnlocker) {
      flags =
        nsIPromptService::BUTTON_TITLE_CANCEL * nsIPromptService::BUTTON_POS_0 +
        nsIPromptService::BUTTON_TITLE_IS_STRING * nsIPromptService::BUTTON_POS_1 +
        nsIPromptService::BUTTON_POS_1_DEFAULT;
    }

    PRInt32 button;
    rv = ps->ConfirmEx(nsnull, killTitle, killMessage, flags,
                       killTitle, nsnull, nsnull, nsnull, nsnull, &button);
    NS_ENSURE_SUCCESS_LOG(rv, rv);

    if (button == 1 && aUnlocker) {
      rv = aUnlocker->Unlock(nsIProfileUnlocker::FORCE_QUIT);
      if (NS_FAILED(rv)) return rv;

      return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nsnull, aResult);
    }

    return NS_ERROR_ABORT;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void RemoveArg ( char **  argv) [static]

Definition at line 325 of file nsAppRunner.cpp.

{
  do {
    *argv = *(argv + 1);
    ++argv;
  } while (*argv);

  --gArgc;
}

Here is the caller graph for this function:

static void RemoveComponentRegistries ( nsIFile aProfileDir,
nsIFile aLocalProfileDir,
PRBool  aRemoveEMFiles 
) [static]

Definition at line 2126 of file nsAppRunner.cpp.

{
  nsCOMPtr<nsIFile> file;
  aProfileDir->Clone(getter_AddRefs(file));
  if (!file)
    return;

  file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
  file->Remove(PR_FALSE);

  file->SetNativeLeafName(NS_LITERAL_CSTRING("xpti.dat"));
  file->Remove(PR_FALSE);

  file->SetNativeLeafName(NS_LITERAL_CSTRING(".autoreg"));
  file->Remove(PR_FALSE);

  if (aRemoveEMFiles) {
    file->SetNativeLeafName(NS_LITERAL_CSTRING("extensions.ini"));
    file->Remove(PR_FALSE);
  }

  aLocalProfileDir->Clone(getter_AddRefs(file));
  if (!file)
    return;

  file->AppendNative(NS_LITERAL_CSTRING("XUL" PLATFORM_FASL_SUFFIX));
  file->Remove(PR_FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2176 of file nsAppRunner.cpp.

{
  for (size_t i = 0; i < NS_ARRAY_LENGTH(gSavedVars); ++i) {
    if (gSavedVars[i].value)
      PR_SetEnv(gSavedVars[i].value);
  }
}

Here is the caller graph for this function:

static void SaveFileToEnv ( const char *  name,
nsIFile file 
) [static]

Definition at line 276 of file nsAppRunner.cpp.

{
  nsCAutoString path;
  file->GetNativePath(path);

  char *expr = PR_smprintf("%s=%s", name, path.get());
  if (expr)
    PR_SetEnv(expr);
  // We intentionally leak |expr| here since it is required by PR_SetEnv.
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void SaveFileToEnvIfUnset ( const char *  name,
nsIFile file 
) [static]

Definition at line 290 of file nsAppRunner.cpp.

{
  const char *val = PR_GetEnv(name);
  if (!(val && *val))
    SaveFileToEnv(name, file);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2167 of file nsAppRunner.cpp.

{
  for (size_t i = 0; i < NS_ARRAY_LENGTH(gSavedVars); ++i) {
    const char *s = PR_GetEnv(gSavedVars[i].name);
    if (s)
      gSavedVars[i].value = PR_smprintf("%s=%s", gSavedVars[i].name, s);
  }
}

Here is the caller graph for this function:

static nsresult SelectProfile ( nsIProfileLock **  aResult,
nsINativeAppSupport aNative,
PRBool aStartOffline 
) [static]

Definition at line 1753 of file nsAppRunner.cpp.

{
  nsresult rv;
  ArgResult ar;
  const char* arg;
  *aResult = nsnull;
  *aStartOffline = PR_FALSE;

  ar = CheckArg("offline", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -offline is invalid when argument -osint is specified\n");
    return NS_ERROR_FAILURE;
  }

  arg = PR_GetEnv("XRE_START_OFFLINE");
  if ((arg && *arg) || ar)
    *aStartOffline = PR_TRUE;


  arg = PR_GetEnv("XRE_PROFILE_PATH");
  if (arg && *arg) {
    nsCOMPtr<nsILocalFile> lf;
    rv = NS_NewNativeLocalFile(nsDependentCString(arg), PR_TRUE,
                               getter_AddRefs(lf));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsILocalFile> localDir;
    arg = PR_GetEnv("XRE_PROFILE_LOCAL_PATH");
    if (arg && *arg) {
      rv = NS_NewNativeLocalFile(nsDependentCString(arg), PR_TRUE,
                                 getter_AddRefs(localDir));
      NS_ENSURE_SUCCESS(rv, rv);
    } else {
      localDir = lf;
    }

    // Clear out flags that we handled (or should have handled!) last startup.
    const char *dummy;
    CheckArg("p", PR_FALSE, &dummy);
    CheckArg("profile", PR_FALSE, &dummy);
    CheckArg("profilemanager");

    return NS_LockProfilePath(lf, localDir, nsnull, aResult);
  }

  ar = CheckArg("migration", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -migration is invalid when argument -osint is specified\n");
    return NS_ERROR_FAILURE;
  } else if (ar == ARG_FOUND) {
    gDoMigration = PR_TRUE;
  }

  ar = CheckArg("profile", PR_TRUE, &arg);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -profile requires a path\n");
    return NS_ERROR_FAILURE;
  }
  if (ar) {
    nsCOMPtr<nsILocalFile> lf;
    rv = XRE_GetFileFromPath(arg, getter_AddRefs(lf));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIProfileUnlocker> unlocker;

    // If a profile path is specified directory on the command line, then
    // assume that the temp directory is the same as the given directory.
    rv = NS_LockProfilePath(lf, lf, getter_AddRefs(unlocker), aResult);
    if (NS_SUCCEEDED(rv))
      return rv;

    return ProfileLockedDialog(lf, lf, unlocker, aNative, aResult);
  }

  nsCOMPtr<nsIToolkitProfileService> profileSvc;
  rv = NS_NewToolkitProfileService(getter_AddRefs(profileSvc));
  NS_ENSURE_SUCCESS(rv, rv);

  ar = CheckArg("createprofile", PR_TRUE, &arg);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -createprofile requires a profile name\n");
    return NS_ERROR_FAILURE;
  }
  if (ar) {
    nsCOMPtr<nsIToolkitProfile> profile;

    const char* delim = strchr(arg, ' ');
    if (delim) {
      nsCOMPtr<nsILocalFile> lf;
      rv = NS_NewNativeLocalFile(nsDependentCString(delim + 1),
                                   PR_TRUE, getter_AddRefs(lf));
      if (NS_FAILED(rv)) {
        PR_fprintf(PR_STDERR, "Error: profile path not valid.");
        return rv;
      }
      
      // As with -profile, assume that the given path will be used for both the
      // main profile directory and the temp profile directory.
      rv = profileSvc->CreateProfile(lf, lf, nsDependentCSubstring(arg, delim),
                                     getter_AddRefs(profile));
    } else {
      rv = profileSvc->CreateProfile(nsnull, nsnull, nsDependentCString(arg),
                                     getter_AddRefs(profile));
    }
    if (NS_SUCCEEDED(rv)) {
      rv = NS_ERROR_ABORT;
      PR_fprintf(PR_STDERR, "Success: created profile '%s'\n", arg);
    }
    profileSvc->Flush();

    // XXXben need to ensure prefs.js exists here so the tinderboxes will
    //        not go orange.
    nsCOMPtr<nsILocalFile> prefsJSFile;
    profile->GetRootDir(getter_AddRefs(prefsJSFile));
    prefsJSFile->AppendNative(NS_LITERAL_CSTRING("prefs.js"));
    PRBool exists;
    prefsJSFile->Exists(&exists);
    if (!exists)
      prefsJSFile->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
    // XXXdarin perhaps 0600 would be better?

    return rv;
  }

  PRUint32 count;
  rv = profileSvc->GetProfileCount(&count);
  NS_ENSURE_SUCCESS(rv, rv);

  if (gAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR) {
    arg = PR_GetEnv("XRE_IMPORT_PROFILES");
    if (!count && (!arg || !*arg)) {
      return ImportProfiles(profileSvc, aNative);
    }
  }

  ar = CheckArg("p", PR_FALSE, &arg);
  if (ar == ARG_BAD) {
    ar = CheckArg("osint");
    if (ar == ARG_FOUND) {
      PR_fprintf(PR_STDERR, "Error: argument -p is invalid when argument -osint is specified\n");
      return NS_ERROR_FAILURE;
    }
    return ShowProfileManager(profileSvc, aNative);
  }
  if (ar) {
    ar = CheckArg("osint");
    if (ar == ARG_FOUND) {
      PR_fprintf(PR_STDERR, "Error: argument -p is invalid when argument -osint is specified\n");
      return NS_ERROR_FAILURE;
    }
    nsCOMPtr<nsIToolkitProfile> profile;
    rv = profileSvc->GetProfileByName(nsDependentCString(arg),
                                      getter_AddRefs(profile));
    if (NS_SUCCEEDED(rv)) {
      nsCOMPtr<nsIProfileUnlocker> unlocker;
      rv = profile->Lock(nsnull, aResult);
      if (NS_SUCCEEDED(rv))
        return NS_OK;

      nsCOMPtr<nsILocalFile> profileDir;
      rv = profile->GetRootDir(getter_AddRefs(profileDir));
      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsILocalFile> profileLocalDir;
      rv = profile->GetLocalDir(getter_AddRefs(profileLocalDir));
      NS_ENSURE_SUCCESS(rv, rv);

      return ProfileLockedDialog(profileDir, profileLocalDir, unlocker,
                                 aNative, aResult);
    }

    return ShowProfileManager(profileSvc, aNative);
  }

  ar = CheckArg("profilemanager", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -profilemanager is invalid when argument -osint is specified\n");
    return NS_ERROR_FAILURE;
  } else if (ar == ARG_FOUND) {
    return ShowProfileManager(profileSvc, aNative);
  }

  if (!count) {
    gDoMigration = PR_TRUE;

    // create a default profile
    nsCOMPtr<nsIToolkitProfile> profile;
    nsresult rv = profileSvc->CreateProfile(nsnull, // choose a default dir for us
                                            nsnull, // choose a default dir for us
                                            NS_LITERAL_CSTRING("default"),
                                            getter_AddRefs(profile));
    if (NS_SUCCEEDED(rv)) {
      profileSvc->Flush();
      rv = profile->Lock(nsnull, aResult);
      if (NS_SUCCEEDED(rv))
        return NS_OK;
    }
  }

  PRBool useDefault = PR_TRUE;
  if (count > 1)
    profileSvc->GetStartWithLastProfile(&useDefault);

  if (useDefault) {
    nsCOMPtr<nsIToolkitProfile> profile;
    // GetSelectedProfile will auto-select the only profile if there's just one
    profileSvc->GetSelectedProfile(getter_AddRefs(profile));
    if (profile) {
      nsCOMPtr<nsIProfileUnlocker> unlocker;
      rv = profile->Lock(getter_AddRefs(unlocker), aResult);
      if (NS_SUCCEEDED(rv))
        return NS_OK;

      nsCOMPtr<nsILocalFile> profileDir;
      rv = profile->GetRootDir(getter_AddRefs(profileDir));
      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsILocalFile> profileLocalDir;
      rv = profile->GetRootDir(getter_AddRefs(profileLocalDir));
      NS_ENSURE_SUCCESS(rv, rv);

      return ProfileLockedDialog(profileDir, profileLocalDir, unlocker,
                                 aNative, aResult);
    }
  }

  return ShowProfileManager(profileSvc, aNative);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ShowOSAlert ( const char *  aMessage)

Definition at line 183 of file showOSAlert.cpp.

{
#ifdef DEBUG_dbragg
printf("\n****Inside ShowOSAlert ***\n"); 
#endif 

    const PRInt32 max_len = 255;
    char message_copy[max_len+1] = { 0 };
    PRInt32 input_len = strlen(aMessage);
    PRInt32 copy_len = (input_len > max_len) ? max_len : input_len;
    strncpy(message_copy, aMessage, copy_len);
    message_copy[copy_len] = 0;

#if defined (XP_WIN)
    MessageBox(NULL, message_copy, NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND );
#elif (XP_MAC)
    short buttonClicked;
    StandardAlert(kAlertStopAlert, c2pstr(message_copy), nil, nil, &buttonClicked);
#elif defined (MOZ_WIDGET_GTK)
    NS_gtk_alert(message_copy, NULL, "OK");
#elif defined (XP_OS2)
    /* Set our app to be a PM app before attempting Win calls */
    PPIB ppib;
    PTIB ptib;
    DosGetInfoBlocks(&ptib, &ppib);
    ppib->pib_ultype = 3;
    HAB hab = WinInitialize(0);
    HMQ hmq = WinCreateMsgQueue(hmq,0);
    WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, message_copy, "", 0, MB_OK);
    WinDestroyMsgQueue(hmq);
    WinTerminate(hab);
#endif
    // It can't hurt to display the message on the console in any case,
    // even if we have already tried to display it in a GUI window.
    fprintf(stdout, "%s\n", aMessage);
}

Here is the caller graph for this function:

static nsresult ShowProfileManager ( nsIToolkitProfileService aProfileSvc,
nsINativeAppSupport aNative 
) [static]

Definition at line 1622 of file nsAppRunner.cpp.

{
  nsresult rv;

  nsCOMPtr<nsILocalFile> profD, profLD;

  {
    ScopedXPCOMStartup xpcom;
    rv = xpcom.Initialize();
    NS_ENSURE_SUCCESS(rv, rv);

    rv = xpcom.RegisterProfileService(aProfileSvc);
    rv |= xpcom.DoAutoreg();
    rv |= xpcom.InitEventQueue();
    rv |= xpcom.SetWindowCreator(aNative);
    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

#ifdef XP_MACOSX
    SetupMacCommandLine(gRestartArgc, gRestartArgv);
#endif

#ifdef XP_WIN
    ProcessDDE(aNative);
#endif

    { //extra scoping is needed so we release these components before xpcom shutdown
      nsCOMPtr<nsIWindowWatcher> windowWatcher
        (do_GetService(NS_WINDOWWATCHER_CONTRACTID));
      nsCOMPtr<nsIDialogParamBlock> ioParamBlock
        (do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID));
      nsCOMPtr<nsIMutableArray> dlgArray (do_CreateInstance(NS_ARRAY_CONTRACTID));
      NS_ENSURE_TRUE(windowWatcher && ioParamBlock && dlgArray, NS_ERROR_FAILURE);

      ioParamBlock->SetObjects(dlgArray);

      nsCOMPtr<nsIAppStartup> appStartup
        (do_GetService(NS_APPSTARTUP_CONTRACTID));
      NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE);

      appStartup->EnterLastWindowClosingSurvivalArea();

      nsCOMPtr<nsIDOMWindow> newWindow;
      rv = windowWatcher->OpenWindow(nsnull,
                                     kProfileManagerURL,
                                     "_blank",
                                     "centerscreen,chrome,modal,titlebar",
                                     ioParamBlock,
                                     getter_AddRefs(newWindow));

      appStartup->ExitLastWindowClosingSurvivalArea();

      NS_ENSURE_SUCCESS_LOG(rv, rv);

      aProfileSvc->Flush();

      PRInt32 dialogConfirmed;
      rv = ioParamBlock->GetInt(0, &dialogConfirmed);
      if (NS_FAILED(rv) || dialogConfirmed == 0) return NS_ERROR_ABORT;

      nsCOMPtr<nsIProfileLock> lock;
      rv = dlgArray->QueryElementAt(0, NS_GET_IID(nsIProfileLock),
                                    getter_AddRefs(lock));
      NS_ENSURE_SUCCESS_LOG(rv, rv);

      rv = lock->GetDirectory(getter_AddRefs(profD));
      NS_ENSURE_SUCCESS(rv, rv);

      rv = lock->GetLocalDirectory(getter_AddRefs(profLD));
      NS_ENSURE_SUCCESS(rv, rv);

      lock->Unlock();
    }
  }

  SaveFileToEnv("XRE_PROFILE_PATH", profD);
  SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);

  PRBool offline = PR_FALSE;
  aProfileSvc->GetStartOffline(&offline);
  if (offline) {
    PR_SetEnv("XRE_START_OFFLINE=1");
  }

  return LaunchChild(aNative);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool strimatch ( const char *  lowerstr,
const char *  mixedstr 
) [static]

Definition at line 298 of file nsAppRunner.cpp.

{
  while(*lowerstr) {
    if (!*mixedstr) return PR_FALSE; // mixedstr is shorter
    if (tolower(*mixedstr) != *lowerstr) return PR_FALSE; // no match

    ++lowerstr;
    ++mixedstr;
  }

  if (*mixedstr) return PR_FALSE; // lowerstr is shorter

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int VerifyInstallation ( nsIFile aAppDir) [static]

Definition at line 1050 of file nsAppRunner.cpp.

{
  static const char lastResortMessage[] =
    "A previous install did not complete correctly.  Finishing install.";

  // Maximum allowed / used length of alert message is 255 chars, due to restrictions on Mac.
  // Please make sure that file contents and fallback_alert_text are at most 255 chars.

  char message[256];
  PRInt32 numRead = 0;
  const char *messageToShow = lastResortMessage;

  nsresult rv;
  nsCOMPtr<nsIFile> messageFile;
  rv = aAppDir->Clone(getter_AddRefs(messageFile));
  if (NS_SUCCEEDED(rv)) {
    messageFile->AppendNative(NS_LITERAL_CSTRING("res"));
    messageFile->AppendNative(CLEANUP_MESSAGE_FILENAME);
    PRFileDesc* fd = 0;

    nsCOMPtr<nsILocalFile> lf (do_QueryInterface(messageFile));
    if (lf) {
      rv = lf->OpenNSPRFileDesc(PR_RDONLY, 0664, &fd);
      if (NS_SUCCEEDED(rv)) {
        numRead = PR_Read(fd, message, sizeof(message)-1);
        if (numRead > 0) {
          message[numRead] = 0;
          messageToShow = message;
        }
      }
    }
  }

  ShowOSAlert(messageToShow);

  nsCOMPtr<nsIFile> cleanupUtility;
  aAppDir->Clone(getter_AddRefs(cleanupUtility));
  if (!cleanupUtility) return 1;

  cleanupUtility->AppendNative(CLEANUP_UTIL);

  ScopedXPCOMStartup xpcom;
  rv = xpcom.Initialize();
  if (NS_FAILED(rv)) return 1;

  { // extra scoping needed to release things before xpcom shutdown
    //Create the process framework to run the cleanup utility
    nsCOMPtr<nsIProcess> cleanupProcess
      (do_CreateInstance(NS_PROCESS_CONTRACTID));
    rv = cleanupProcess->Init(cleanupUtility);
    if (NS_FAILED(rv)) return 1;

    rv = cleanupProcess->Run(PR_FALSE,nsnull, 0, nsnull);
    if (NS_FAILED(rv)) return 1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void WriteVersion ( nsIFile aProfileDir,
const nsCString aVersion,
const nsCString aOSABI,
nsIFile aXULRunnerDir,
nsIFile aAppDir 
) [static]

Definition at line 2060 of file nsAppRunner.cpp.

{
  nsCOMPtr<nsIFile> file;
  aProfileDir->Clone(getter_AddRefs(file));
  if (!file)
    return;
  file->AppendNative(FILE_COMPATIBILITY_INFO);

  nsCOMPtr<nsILocalFile> lf = do_QueryInterface(file);

  nsCAutoString platformDir;
  aXULRunnerDir->GetNativePath(platformDir);

  nsCAutoString appDir;
  if (aAppDir)
    aAppDir->GetNativePath(appDir);

  PRFileDesc *fd = nsnull;
  lf->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd);
  if (!fd) {
    NS_ERROR("could not create output stream");
    return;
  }

  static const char kHeader[] = "[Compatibility]" NS_LINEBREAK
                                "LastVersion=";

  PR_Write(fd, kHeader, sizeof(kHeader) - 1);
  PR_Write(fd, aVersion.get(), aVersion.Length());

  static const char kOSABIHeader[] = NS_LINEBREAK "LastOSABI=";
  PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1);
  PR_Write(fd, aOSABI.get(), aOSABI.Length());

  static const char kPlatformDirHeader[] = NS_LINEBREAK "LastPlatformDir=";

  PR_Write(fd, kPlatformDirHeader, sizeof(kPlatformDirHeader) - 1);
  PR_Write(fd, platformDir.get(), platformDir.Length());

  static const char kAppDirHeader[] = NS_LINEBREAK "LastAppDir=";
  if (aAppDir) {
    PR_Write(fd, kAppDirHeader, sizeof(kAppDirHeader) - 1);
    PR_Write(fd, appDir.get(), appDir.Length());
  }

  static const char kNL[] = NS_LINEBREAK;
  PR_Write(fd, kNL, sizeof(kNL) - 1);

  PR_Close(fd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult XRE_GetBinaryPath ( const char *  argv0,
nsILocalFile **  aResult 
)

Get the path of the running application binary and store it in aResult.

Parameters:
argv0The value passed as argv[0] of main(). This value is only used on *nix, and only when other methods of determining the binary path have failed.

Definition at line 1236 of file nsAppRunner.cpp.

{
  nsresult rv;
  nsCOMPtr<nsILocalFile> lf;

  // We need to use platform-specific hackery to find the
  // path of this executable. This is copied, with some modifications, from
  // nsGREDirServiceProvider.cpp

#ifdef XP_WIN
  char exePath[MAXPATHLEN];

  if (!::GetModuleFileName(0, exePath, MAXPATHLEN))
    return NS_ERROR_FAILURE;

  rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
                             getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return rv;

#elif defined(XP_MACOSX)
  if (gBinaryPath)
    return NS_NewNativeLocalFile(nsDependentCString(gBinaryPath), PR_FALSE,
                                 aResult);

  NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(lf));
  nsCOMPtr<nsILocalFileMac> lfm (do_QueryInterface(lf));
  if (!lfm)
    return NS_ERROR_FAILURE;

  // Works even if we're not bundled.
  CFBundleRef appBundle = CFBundleGetMainBundle();
  if (!appBundle)
    return NS_ERROR_FAILURE;

  CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
  if (!bundleURL)
    return NS_ERROR_FAILURE;

  FSRef fileRef;
  if (!CFURLGetFSRef(bundleURL, &fileRef)) {
    CFRelease(bundleURL);
    return NS_ERROR_FAILURE;
  }

  rv = lfm->InitWithFSRef(&fileRef);
  CFRelease(bundleURL);

  if (NS_FAILED(rv))
    return rv;

#elif defined(XP_UNIX)
  struct stat fileStat;
  char exePath[MAXPATHLEN];
  char tmpPath[MAXPATHLEN];

  rv = NS_ERROR_FAILURE;

  // on unix, there is no official way to get the path of the current binary.
  // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
  // multiple applications, we will try a series of techniques:
  //
  // 1) look for /proc/<pid>/exe which is a symlink to the executable on newer
  //    Linux kernels
  // 2) use realpath() on argv[0], which works unless we're loaded from the
  //    PATH
  // 3) manually walk through the PATH and look for ourself
  // 4) give up

// #ifdef __linux__
#if 0
  int r = readlink("/proc/self/exe", exePath, MAXPATHLEN);

  // apparently, /proc/self/exe can sometimes return weird data... check it
  if (r > 0 && r < MAXPATHLEN && stat(exePath, &fileStat) == 0) {
    rv = NS_OK;
  }

#endif
  if (NS_FAILED(rv) &&
      realpath(argv0, exePath) && stat(exePath, &fileStat) == 0) {
    rv = NS_OK;
  }

  if (NS_FAILED(rv)) {
    const char *path = getenv("PATH");
    if (!path)
      return NS_ERROR_FAILURE;

    char *pathdup = strdup(path);
    if (!pathdup)
      return NS_ERROR_OUT_OF_MEMORY;

    PRBool found = PR_FALSE;
    char *newStr = pathdup;
    char *token;
    while ( (token = nsCRT::strtok(newStr, ":", &newStr)) ) {
      sprintf(tmpPath, "%s/%s", token, argv0);
      if (realpath(tmpPath, exePath) && stat(exePath, &fileStat) == 0) {
        found = PR_TRUE;
        break;
      }
    }
    free(pathdup);
    if (!found)
      return NS_ERROR_FAILURE;
  }

  rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
                             getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return rv;

#elif defined(XP_OS2)
  PPIB ppib;
  PTIB ptib;
  char exePath[MAXPATHLEN];

  DosGetInfoBlocks( &ptib, &ppib);
  DosQueryModuleName( ppib->pib_hmte, MAXPATHLEN, exePath);
  rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
                             getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return rv;

#elif defined(XP_BEOS)
  int32 cookie = 0;
  image_info info;

  if(get_next_image_info(0, &cookie, &info) != B_OK)
    return NS_ERROR_FAILURE;

  rv = NS_NewNativeLocalFile(nsDependentCString(info.name), PR_TRUE,
                             getter_AddRefs(lf));
  if (NS_FAILED(rv))
    return rv;

#elif
#error Oops, you need platform-specific code here
#endif

  NS_ADDREF(*aResult = lf);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int XRE_main ( int  argc,
char *  argv[],
const nsXREAppData aAppData 
)

Begin an XUL application.

Does not return until the user exits the application.

Parameters:
argc/argvCommand-line parameters to pass to the application. These are in the "native" character set.
aAppDataInformation about the application to be run.
Returns:
A native result code suitable for returning from main().
Note:
If the binary is linked against the standalone XPCOM glue, XPCOMGlueStartup() should be called before this method.
XXXbsmedberg Nobody uses the glue yet, but there is a potential problem: on windows, the standalone glue calls SetCurrentDirectory, and relative paths on the command line won't be correct.

Definition at line 2204 of file nsAppRunner.cpp.

{
  nsresult rv;
  ArgResult ar;
  NS_TIMELINE_MARK("enter main");

#ifdef DEBUG
  if (PR_GetEnv("XRE_MAIN_BREAK"))
    NS_BREAK();
#endif

#ifdef XP_WIN32
  // Suppress the "DLL Foo could not be found" dialog, such that if dependent
  // libraries (such as GDI+) are not preset, we gracefully fail to load those
  // XPCOM components, instead of being ungraceful.
  SetErrorMode(SEM_FAILCRITICALERRORS);

#ifdef DEBUG
  // Disable small heap allocator to get heapwalk() giving us
  // accurate heap numbers. Win2k non-debug does not use small heap allocator.
  // Win2k debug seems to be still using it.
  // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__set_sbh_threshold.asp
  _set_sbh_threshold(0);
#endif
#endif

#if defined(XP_UNIX) || defined(XP_BEOS)
  InstallUnixSignalHandlers(argv[0]);
#endif

#ifdef MOZ_ACCESSIBILITY_ATK
  // Reset GTK_MODULES, strip atk-bridge if exists
  // Mozilla will load libatk-bridge.so later if necessary
  const char* gtkModules = PR_GetEnv("GTK_MODULES");
  if (gtkModules && *gtkModules) {
    nsCString gtkModulesStr(gtkModules);
    gtkModulesStr.ReplaceSubstring("atk-bridge", "");
    char* expr = PR_smprintf("GTK_MODULES=%s", gtkModulesStr.get());
    if (expr)
      PR_SetEnv(expr);
    // We intentionally leak |expr| here since it is required by PR_SetEnv.
  }
#endif

  // Unbuffer stdout, needed for tinderbox tests.
  setbuf(stdout, 0);

#if defined(FREEBSD)
  // Disable all SIGFPE's on FreeBSD, as it has non-IEEE-conformant fp
  // trap behavior that trips up on floating-point tests performed by
  // the JS engine.  See bugzilla bug 9967 details.
  fpsetmask(0);
#endif

  gArgc = argc;
  gArgv = argv;

  NS_ASSERTION(aAppData, "must specify XUL app data");

  // In the future when nsXREAppData is extended, this check will need to
  // have more finesse.
  if (aAppData->size < sizeof(nsXREAppData)) {
    NS_ERROR("aAppdata.size isn't set properly!");
    return 1;
  }

#ifdef XP_MACOSX
  // The xulrunner stub executable tricks CFBundleGetMainBundle on
  // purpose into lying about the main bundle path. It will set
  // XRE_BINARY_PATH to inform us of our real location.
  gBinaryPath = getenv("XRE_BINARY_PATH");

  if (gBinaryPath && !*gBinaryPath)
    gBinaryPath = nsnull;

  if (PR_GetEnv("MOZ_LAUNCHED_CHILD")) {
    // When the app relaunches, the original process exits.  This causes
    // the dock tile to stop bouncing, lose the "running" triangle, and
    // if the tile does not permanently reside in the Dock, even disappear.
    // This can be confusing to the user, who is expecting the app to launch.
    // Calling ReceiveNextEvent without requesting any event is enough to
    // cause a dock tile for the child process to appear.
    const EventTypeSpec kFakeEventList[] = { { INT_MAX, INT_MAX } };
    EventRef event;
    ::ReceiveNextEvent(GetEventTypeCount(kFakeEventList), kFakeEventList,
                       kEventDurationNoWait, PR_FALSE, &event);
  }

  if (CheckArg("foreground")) {
    // The original process communicates that it was in the foreground by
    // adding this argument.  This new process, which is taking over for
    // the old one, should make itself the active application.
    ProcessSerialNumber psn;
    if (::GetCurrentProcess(&psn) == noErr)
      ::SetFrontProcess(&psn);
  }
#endif

  PR_SetEnv("MOZ_LAUNCHED_CHILD=");

  gAppData = aAppData;

  gRestartArgc = gArgc;
  gRestartArgv = (char**) malloc(sizeof(char*) * (gArgc + 1));
  if (!gRestartArgv) return 1;

  int i;
  for (i = 0; i < gArgc; ++i) {
    gRestartArgv[i] = gArgv[i];
  }
  gRestartArgv[gArgc] = nsnull;

#if defined(XP_OS2)
  PRBool StartOS2App(int aArgc, char **aArgv);
  if (!StartOS2App(gArgc, gArgv))
    return 1;
  ScopedFPHandler handler;
#endif /* XP_OS2 */

  ar = CheckArg("safe-mode", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -safe-mode is invalid when argument -osint is specified\n");
    return 1;
  } else if (ar == ARG_FOUND) {
    gSafeMode = PR_TRUE;
  }

  // Handle -no-remote command line argument. Setup the environment to
  // better accommodate other components and various restart scenarios.
  ar = CheckArg("no-remote", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
    return 1;
  } else if (ar == ARG_FOUND) {
    PR_SetEnv("MOZ_NO_REMOTE=1");
  }

  // Handle -help and -version command line arguments.
  // They should return quickly, so we deal with them here.
  if (CheckArg("h") || CheckArg("help") || CheckArg("?")) {
    DumpHelp();
    return 0;
  }

  if (CheckArg("v") || CheckArg("version")) {
    DumpVersion();
    return 0;
  }
    
#ifdef NS_TRACE_MALLOC
  gArgc = argc = NS_TraceMallocStartupArgs(argc, argv);
#endif

  nsXREDirProvider dirProvider;
  {
    rv = dirProvider.Initialize(gAppData->directory);
    if (NS_FAILED(rv))
      return 1;
  }

  // Check for -register, which registers chrome and then exits immediately.

  ar = CheckArg("register", PR_TRUE);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: argument -register is invalid when argument -osint is specified\n");
    return 1;
  } else if (ar == ARG_FOUND) {
    ScopedXPCOMStartup xpcom;
    rv = xpcom.Initialize();
    NS_ENSURE_SUCCESS(rv, 1);

    {
      nsCOMPtr<nsIChromeRegistry> chromeReg
        (do_GetService("@mozilla.org/chrome/chrome-registry;1"));
      NS_ENSURE_TRUE(chromeReg, 1);

      chromeReg->CheckForNewChrome();
    }
    return 0;
  }

#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2)
  // setup for private colormap.  Ideally we'd like to do this
  // in nsAppShell::Create, but we need to get in before gtk
  // has been initialized to make sure everything is running
  // consistently.
#if defined(MOZ_WIDGET_GTK2)
  g_thread_init(NULL);
#endif
  if (CheckArg("install"))
    gdk_rgb_set_install(TRUE);

  // Initialize GTK+1/2 here for splash
#if defined(MOZ_WIDGET_GTK)
  gtk_set_locale();
#endif
  gtk_init(&gArgc, &gArgv);

#if defined(MOZ_WIDGET_GTK2)
  // g_set_application_name () is only defined in glib2.2 and higher.
  PRLibrary *glib2 = nsnull;
  _g_set_application_name_fn _g_set_application_name =
      (_g_set_application_name_fn)PR_FindFunctionSymbolAndLibrary("g_set_application_name", &glib2);
  if (_g_set_application_name) {
    _g_set_application_name(gAppData->name);
  }
  if (glib2) {
    PR_UnloadLibrary(glib2);
  }
#endif

  gtk_widget_set_default_visual(gdk_rgb_get_visual());
  gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
#endif /* MOZ_WIDGET_GTK || MOZ_WIDGET_GTK2 */

#if defined(MOZ_WIDGET_QT)
  QApplication qapp(argc, argv);
#endif

// #if defined(MOZ_WIDGET_XLIB)
// XXXtimeless fix me! How do we get a Display from here to nsAppShell.cpp ?
// #endif
    
  // Call the code to install our handler
#ifdef MOZ_JPROF
  setupProfilingStuff();
#endif

  // Try to allocate "native app support."
  nsCOMPtr<nsINativeAppSupport> nativeApp;
  rv = NS_CreateNativeAppSupport(getter_AddRefs(nativeApp));
  if (NS_FAILED(rv))
    return 1;

  PRBool canRun = PR_FALSE;
  rv = nativeApp->Start(&canRun);
  if (NS_FAILED(rv) || !canRun) {
    return 1;
  }

  //----------------------------------------------------------------
  // We need to check if a previous installation occured and
  // if so, make sure it finished and cleaned up correctly.
  //
  // If there is an xpicleanup.dat file left around, that means the
  // previous installation did not finish correctly. We must cleanup
  // before a valid mozilla can run.
  //
  // Show the user a platform-specific Alert message, then spawn the
  // xpicleanup utility, then exit.
  //----------------------------------------------------------------
  nsCOMPtr<nsIFile> registryFile;
  rv = dirProvider.GetAppDir()->Clone(getter_AddRefs(registryFile));
  if (NS_SUCCEEDED(rv)) {
    registryFile->AppendNative(CLEANUP_REGISTRY);

    PRBool exists;
    rv = registryFile->Exists(&exists);
    if (NS_SUCCEEDED(rv) && exists) {
      return VerifyInstallation(dirProvider.GetAppDir());
    }
  }

#ifdef MOZ_ENABLE_XREMOTE
  // handle -remote now that xpcom is fired up

  const char* xremotearg;
  ar = CheckArg("remote", PR_TRUE, &xremotearg);
  if (ar == ARG_BAD) {
    PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
    return 1;
  }
  if (ar) {
    return HandleRemoteArgument(xremotearg);
  }

  if (!PR_GetEnv("MOZ_NO_REMOTE")) {
    // Try to remote the entire command line. If this fails, start up normally.
    RemoteResult rr = RemoteCommandLine();
    if (rr == REMOTE_FOUND)
      return 0;
    else if (rr == REMOTE_ARG_BAD)
      return 1;
  }
#endif

#if defined(MOZ_UPDATER)
  // If this is a XULRunner app then the updater needs to know the base
  // directory that contains the application.ini file. This should be the
  // parent of the xulrunner directory on Windows/Linux and it should be the
  // Contents directory on MacOSX. Just in case someone packaged their app
  // incorrectly we'll pass the directory here.
  nsCOMPtr<nsIFile> greDir = dirProvider.GetAppDir();
  NS_ENSURE_TRUE(greDir, 1);

  nsCOMPtr<nsIFile> appDir;
  PRBool dummy;
  rv = dirProvider.GetFile("resource:app",
                           &dummy,
                           getter_AddRefs(appDir));
  if (NS_FAILED(rv)) {
    // This must not be a XULRunner app
    appDir = greDir;
  }

  // Check for and process any available updates
  nsCOMPtr<nsIFile> updRoot;
  PRBool persistent;
  rv = dirProvider.GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
                           getter_AddRefs(updRoot));
  // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
  if (NS_FAILED(rv))
    updRoot = dirProvider.GetAppDir();

  // Check for and process any available updates
  ProcessUpdates(greDir,
                 appDir,
                 updRoot,
                 gRestartArgc,
                 gRestartArgv);
#endif

  nsCOMPtr<nsIProfileLock> profileLock;
  PRBool startOffline = PR_FALSE;

  rv = SelectProfile(getter_AddRefs(profileLock), nativeApp, &startOffline);
  if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ||
      rv == NS_ERROR_ABORT) return 0;
  if (NS_FAILED(rv)) return 1;

  nsCOMPtr<nsILocalFile> profD;
  rv = profileLock->GetDirectory(getter_AddRefs(profD));
  NS_ENSURE_SUCCESS(rv, 1);

  nsCOMPtr<nsILocalFile> profLD;
  rv = profileLock->GetLocalDirectory(getter_AddRefs(profLD));
  NS_ENSURE_SUCCESS(rv, 1);

  rv = dirProvider.SetProfile(profD, profLD);
  NS_ENSURE_SUCCESS(rv, 1);


  PRBool upgraded = PR_FALSE;

  nsCAutoString version;
  BuildVersion(version);

#ifdef TARGET_OS_ABI
    NS_NAMED_LITERAL_CSTRING(osABI, TARGET_OS_ABI);
#else
    // No TARGET_XPCOM_ABI, but at least the OS is known
    NS_NAMED_LITERAL_CSTRING(osABI, OS_TARGET "_UNKNOWN");
#endif

  // Check for version compatibility with the last version of the app this 
  // profile was started with.  The format of the version stamp is defined
  // by the BuildVersion function.
  PRBool versionOK = CheckCompatibility(profD, version, osABI,
                                        dirProvider.GetAppDir(),
                                        gAppData->directory);

  // Every time a profile is loaded by a build with a different version,
  // it updates the compatibility.ini file saying what version last wrote
  // the compreg.dat.  On subsequent launches if the version matches, 
  // there is no need for re-registration.  If the user loads the same
  // profile in different builds the component registry must be
  // re-generated to prevent mysterious component loading failures.
  //
  if (gSafeMode) {
    RemoveComponentRegistries(profD, profLD, PR_FALSE);
    WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"), osABI,
                 dirProvider.GetAppDir(), gAppData->directory);
  }
  else if (versionOK) {
    if (ComponentsListChanged(profD)) {
      // Remove compreg.dat and xpti.dat, forcing component re-registration,
      // with the new list of additional components directories specified
      // in "components.ini" which we have just discovered changed since the
      // last time the application was run. 
      RemoveComponentRegistries(profD, profLD, PR_FALSE);
    }
    // Nothing need be done for the normal startup case.
  }
  else {
    // Remove compreg.dat and xpti.dat, forcing component re-registration
    // with the default set of components (this disables any potentially
    // troublesome incompatible XPCOM components). 
    RemoveComponentRegistries(profD, profLD, PR_TRUE);

    // Tell the Extension Manager it should check for incompatible 
    // Extensions and re-write the Components manifest ("components.ini")
    // with a list of XPCOM components for compatible extensions
    upgraded = PR_TRUE;

    // Write out version
    WriteVersion(profD, version, osABI,
                 dirProvider.GetAppDir(), gAppData->directory);
  }

  PRBool needsRestart = PR_FALSE;
  PRBool appInitiatedRestart = PR_FALSE;

  // Allows the user to forcefully bypass the restart process at their
  // own risk. Useful for debugging or for tinderboxes where child 
  // processes can be problematic.
  {
    // Start the real application
    ScopedXPCOMStartup xpcom;
    rv = xpcom.Initialize();
    NS_ENSURE_SUCCESS(rv, 1); 
    rv = xpcom.DoAutoreg();
    rv |= xpcom.InitEventQueue();
    rv |= xpcom.SetWindowCreator(nativeApp);
    NS_ENSURE_SUCCESS(rv, 1);

    {
      if (startOffline) {
        nsCOMPtr<nsIIOService> io (do_GetService("@mozilla.org/network/io-service;1"));
        NS_ENSURE_TRUE(io, 1);
        io->SetOffline(PR_TRUE);
      }

      {
        NS_TIMELINE_ENTER("startupNotifier");
        nsCOMPtr<nsIObserver> startupNotifier
          (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv));
        NS_ENSURE_SUCCESS(rv, 1);

        startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
        NS_TIMELINE_LEAVE("startupNotifier");
      }

      nsCOMPtr<nsIAppStartup> appStartup
        (do_GetService(NS_APPSTARTUP_CONTRACTID));
      NS_ENSURE_TRUE(appStartup, 1);

      // So we can open and close windows during startup
      appStartup->EnterLastWindowClosingSurvivalArea();

      if (gDoMigration) {
        nsCOMPtr<nsIFile> file;
        dirProvider.GetAppDir()->Clone(getter_AddRefs(file));
        file->AppendNative(NS_LITERAL_CSTRING("override.ini"));
        nsINIParser parser;
        nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
        nsresult rv = parser.Init(localFile);
        if (NS_SUCCEEDED(rv)) {
          nsCAutoString buf;
          rv = parser.GetString("XRE", "EnableProfileMigrator", buf);
          if (NS_SUCCEEDED(rv)) {
            if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
              gDoMigration = PR_FALSE;
            }
          }
        }
      }

      // Profile Migration
      if (gAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR && gDoMigration) {
        gDoMigration = PR_FALSE;
        nsCOMPtr<nsIProfileMigrator> pm
          (do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID));
        if (pm)
          pm->Migrate(&dirProvider);
      }
      dirProvider.DoStartup();

      nsCOMPtr<nsICommandLineRunner> cmdLine
        (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
      NS_ENSURE_TRUE(cmdLine, 1);

      nsCOMPtr<nsIFile> workingDir;
      rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
      NS_ENSURE_SUCCESS(rv, 1);

      rv = cmdLine->Init(gArgc, gArgv,
                         workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
      NS_ENSURE_SUCCESS(rv, 1);

      /* Special-case services that need early access to the command
         line. */
      nsCOMPtr<nsIObserver> chromeObserver
        (do_GetService("@mozilla.org/chrome/chrome-registry;1"));
      if (chromeObserver) {
        chromeObserver->Observe(cmdLine, "command-line-startup", nsnull);
      }

      NS_TIMELINE_ENTER("appStartup->CreateHiddenWindow");
      rv = appStartup->CreateHiddenWindow();
      NS_TIMELINE_LEAVE("appStartup->CreateHiddenWindow");
      NS_ENSURE_SUCCESS(rv, 1);

      // Extension Compatibility Checking and Startup
      if (gAppData->flags & NS_XRE_ENABLE_EXTENSION_MANAGER) {
        nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
        NS_ENSURE_TRUE(em, 1);

        ar = CheckArg("install-global-extension", PR_TRUE);
        if (ar == ARG_BAD) {
          PR_fprintf(PR_STDERR, "Error: argument -install-global-extension is invalid when argument -osint is specified\n");
          return 1;
        } else if (ar == ARG_FOUND) {
          // Do the required processing and then shut down.
          em->HandleCommandLineArgs(cmdLine);
          return 0;
        }

        ar = CheckArg("install-global-theme", PR_TRUE);
        if (ar == ARG_BAD) {
          PR_fprintf(PR_STDERR, "Error: argument -install-global-theme is invalid when argument -osint is specified\n");
          return 1;
        } else if (ar == ARG_FOUND) {
          // Do the required processing and then shut down.
          em->HandleCommandLineArgs(cmdLine);
          return 0;
        }

        if (upgraded) {
          rv = em->CheckForMismatches(&needsRestart);
          if (NS_FAILED(rv)) {
            needsRestart = PR_FALSE;
            upgraded = PR_FALSE;
          }
        }

        if (!upgraded || !needsRestart)
          em->Start(cmdLine, &needsRestart);
      }

      // We want to restart no more than 2 times. The first restart,
      // NO_EM_RESTART == "0" , and the second time, "1".
      char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
      if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
        if (upgraded || needsRestart) {
          NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
        }
        needsRestart = upgraded = PR_FALSE;
      }

      if (!upgraded && !needsRestart) {
        SaveStateForAppInitiatedRestart();

        // clear out any environment variables which may have been set 
        // during the relaunch process now that we know we won't be relaunching.
        PR_SetEnv("XRE_PROFILE_PATH=");
        PR_SetEnv("XRE_PROFILE_LOCAL_PATH=");
        PR_SetEnv("XRE_START_OFFLINE=");
        PR_SetEnv("XRE_IMPORT_PROFILES=");
        PR_SetEnv("NO_EM_RESTART=");
        PR_SetEnv("XUL_APP_FILE=");
        PR_SetEnv("XRE_BINARY_PATH=");

#ifdef XP_MACOSX
        // we re-initialize the command-line service and do appleevents munging
        // after we are sure that we're not restarting
        cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
        NS_ENSURE_TRUE(cmdLine, 1);

        SetupMacCommandLine(gArgc, gArgv);

        rv = cmdLine->Init(gArgc, gArgv,
                           workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
        NS_ENSURE_SUCCESS(rv, 1);

        // Kick off the prebinding update now that we know we won't be
        // relaunching.

        UpdatePrebinding();
#endif
        nsCOMPtr<nsIObserverService> obsService
          (do_GetService("@mozilla.org/observer-service;1"));
        if (obsService)
          obsService->NotifyObservers(nsnull, "final-ui-startup", nsnull);        

        rv = cmdLine->Run();
        NS_ENSURE_SUCCESS_LOG(rv, 1);

        nsCOMPtr<nsIWindowMediator> windowMediator
          (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv));
        NS_ENSURE_SUCCESS(rv, 1);

        // Make sure there exists at least 1 window.
        nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
        rv = windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
        NS_ENSURE_SUCCESS(rv, 1);

        PRBool more;
        windowEnumerator->HasMoreElements(&more);
        if (!more) {
          // We didn't open any windows. This is normally not a good thing,
          // so we force console logging to file.
          gLogConsoleErrors = PR_TRUE;
        }
        else {
#ifndef XP_MACOSX
          appStartup->ExitLastWindowClosingSurvivalArea();
#endif

#ifdef MOZ_ENABLE_XREMOTE
          // if we have X remote support and we have our one window up and
          // running start listening for requests on the proxy window.
          nsCOMPtr<nsIRemoteService> remoteService;
          remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
          if (remoteService)
            remoteService->Startup(gAppData->name, nsnull);
#endif /* MOZ_ENABLE_XREMOTE */

          // enable win32 DDE responses and Mac appleevents responses
          nativeApp->Enable();

          // Start main event loop
          NS_TIMELINE_ENTER("appStartup->Run");
          rv = appStartup->Run();
          NS_TIMELINE_LEAVE("appStartup->Run");
          if (NS_FAILED(rv)) {
            NS_ERROR("failed to run appstartup");
            gLogConsoleErrors = PR_TRUE;
          }

          // Check for an application initiated restart.  This is one that
          // corresponds to nsIAppStartup.quit(eRestart)
          if (rv == NS_SUCCESS_RESTART_APP) {
            needsRestart = PR_TRUE;
            appInitiatedRestart = PR_TRUE;
          }

#ifdef MOZ_ENABLE_XREMOTE
          // shut down the x remote proxy window
          if (remoteService)
            remoteService->Shutdown();
#endif /* MOZ_ENABLE_XREMOTE */
        }

#ifdef MOZ_TIMELINE
        // Make sure we print this out even if timeline is runtime disabled
        if (NS_FAILED(NS_TIMELINE_LEAVE("main1")))
          NS_TimelineForceMark("...main1");
#endif
      }
      else {
        // Upgrade condition (build id changes), but the restart hint was 
        // not set by the Extension Manager. This is because the compatibility
        // resolution for Extensions is different than for the component 
        // registry - major milestone vs. build id. 
        needsRestart = PR_TRUE;

#ifdef XP_WIN
        ProcessDDE(nativeApp);
#endif

#ifdef XP_MACOSX
        SetupMacCommandLine(gRestartArgc, gRestartArgv);
#endif
      }
    }

    profileLock->Unlock();
  }

  // Restart the app after XPCOM has been shut down cleanly. 
  if (needsRestart) {
    if (appInitiatedRestart) {
      RestoreStateForAppInitiatedRestart();
    }
    else {
      char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
      if (noEMRestart && *noEMRestart) {
        PR_SetEnv("NO_EM_RESTART=1");
      }
      else {
        PR_SetEnv("NO_EM_RESTART=0");
      }
    }

    // Ensure that these environment variables are set:
    SaveFileToEnvIfUnset("XRE_PROFILE_PATH", profD);
    SaveFileToEnvIfUnset("XRE_PROFILE_LOCAL_PATH", profLD);

#ifdef XP_MACOSX
    if (gBinaryPath) {
      static char kEnvVar[MAXPATHLEN];
      sprintf(kEnvVar, "XRE_BINARY_PATH=%s", gBinaryPath);
      PR_SetEnv(kEnvVar);
    }
#endif

    rv = LaunchChild(nativeApp, appInitiatedRestart, upgraded ? -1 : 0);
    return rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ? 0 : 1;
  }

  return NS_FAILED(rv) ? 1 : 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 2184 of file nsAppRunner.cpp.

Definition at line 260 of file nsAppRunner.cpp.

char** gArgv

Definition at line 261 of file nsAppRunner.cpp.

Definition at line 1750 of file nsAppRunner.cpp.

Definition at line 720 of file nsAppRunner.cpp.

int gRestartArgc [static]

Definition at line 263 of file nsAppRunner.cpp.

char** gRestartArgv [static]

Definition at line 264 of file nsAppRunner.cpp.

Definition at line 480 of file nsAppRunner.cpp.

struct { ... } gSavedVars[] [static]

Definition at line 706 of file nsAppRunner.cpp.

Initial value:

Definition at line 774 of file nsAppRunner.cpp.

Initial value:
  { 0xc4a446c, 0xee82, 0x41f2, { 0x8d, 0x4, 0xd3, 0x66, 0xd2, 0xc7, 0xa7, 0xd4 } }

Definition at line 822 of file nsAppRunner.cpp.

const char kProfileManagerURL[] = "chrome://mozapps/content/profile/profileSelection.xul" [static]

Definition at line 1618 of file nsAppRunner.cpp.

const char kProfileProperties[] = "chrome://mozapps/locale/profile/profileSelection.properties" [static]

Definition at line 1539 of file nsAppRunner.cpp.

Initial value:
  { 0x5f5e59ce, 0x27bc, 0x47eb, { 0x9d, 0x1f, 0xb0, 0x9c, 0xa9, 0x4, 0x98, 0x36 } }

Definition at line 826 of file nsAppRunner.cpp.

Definition at line 795 of file nsAppRunner.cpp.

Definition at line 796 of file nsAppRunner.cpp.

Initial value:
{
  {
    "Apprunner",
    Apprunner_NSGetModule
  }
}

Definition at line 787 of file nsAppRunner.cpp.