diff --git a/xulrunner/stub/nsXULStub.cpp b/xulrunner/stub/nsXULStub.cpp --- a/xulrunner/stub/nsXULStub.cpp +++ b/xulrunner/stub/nsXULStub.cpp @@ -107,16 +107,31 @@ static void Output(PRBool isError, const sizeof(wide_msg) / sizeof(wchar_t)); MessageBoxW(NULL, wide_msg, L"XULRunner", flags); #else vfprintf(stderr, fmt, ap); #endif va_end(ap); +} + +/** + * Return true if |arg| matches the given argument name. + */ +static PRBool IsArg(const char* arg, const char* s) +{ + if (*arg == '-') + { + if (*++arg == '-') + ++arg; + return !strcasecmp(arg, s); + } + + return PR_FALSE; } class AutoAppData { public: AutoAppData(nsILocalFile* aINIFile) : mAppData(nsnull) { nsresult rv = XRE_CreateAppData(aINIFile, &mAppData); if (NS_FAILED(rv)) @@ -211,45 +226,71 @@ main(int argc, char **argv) // p.Path returns a pointer, so use strcpy to store path in iniPath strcpy(iniPath, p.Path()); #else // 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) use realpath() on argv[0], which works unless we're loaded from the + // 1) if -app is specified, use realpath on passed value in order to properly + // hook the application.ini file to the stub logic. + // 2) use realpath() on argv[0], which works unless we're loaded from the // PATH - // 2) manually walk through the PATH and look for ourself - // 3) give up + // 3) manually walk through the PATH and look for ourself + // 4) give up + const char *appDataFile = getenv("XUL_APP_FILE"); struct stat fileStat; - if (!realpath(argv[0], iniPath) || stat(iniPath, &fileStat)) { - const char *path = getenv("PATH"); - if (!path) - return 1; + if (!(appDataFile && *appDataFile)) { + if (argc > 1 && IsArg(argv[1], "app")) { + if (argc == 2) { + Output(PR_FALSE, "specify APP-FILE (optional)\n"); + return 1; + } + argv[1] = argv[0]; + ++argv; + --argc; - char *pathdup = strdup(path); - if (!pathdup) - return 1; + appDataFile = argv[1]; + argv[1] = argv[0]; + ++argv; + --argc; - PRBool found = PR_FALSE; - char *token = strtok(pathdup, ":"); - while (token) { - sprintf(tmpPath, "%s/%s", token, argv[0]); - if (realpath(tmpPath, iniPath) && stat(iniPath, &fileStat) == 0) { - found = PR_TRUE; - break; + static char kAppEnv[MAXPATHLEN]; + snprintf(kAppEnv, MAXPATHLEN, "%s", appDataFile); + setenv("XUL_APP_FILE", kAppEnv, 1); + } + } + + if (!realpath(appDataFile, iniPath) || stat(iniPath, &fileStat)) { + if (!realpath(argv[0], iniPath) || stat(iniPath, &fileStat)) { + const char *path = getenv("PATH"); + if (!path) + return 1; + + char *pathdup = strdup(path); + if (!pathdup) + return 1; + + PRBool found = PR_FALSE; + char *token = strtok(pathdup, ":"); + while (token) { + sprintf(tmpPath, "%s/%s", token, argv[0]); + if (realpath(tmpPath, iniPath) && stat(iniPath, &fileStat) == 0) { + found = PR_TRUE; + break; + } + token = strtok(NULL, ":"); } - token = strtok(NULL, ":"); + free (pathdup); + if (!found) + return 1; } - free (pathdup); - if (!found) - return 1; } #endif lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); if (!lastSlash) return 1; *(++lastSlash) = '\0'; @@ -268,17 +309,17 @@ main(int argc, char **argv) #else greFound = (access(greDir, R_OK) == 0); #endif strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath)); #endif nsINIParser parser; - rv = parser.Init(iniPath); + rv = (appDataFile && *appDataFile) ? parser.Init(appDataFile) : parser.Init(iniPath); if (NS_FAILED(rv)) { fprintf(stderr, "Could not read application.ini\n"); return 1; } if (!greFound) { char minVersion[VERSION_MAXLEN];