xulrunner/app/nsXULRunnerApp.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "nsXULAppAPI.h"
michael@0 6 #include "nsXPCOMGlue.h"
michael@0 7 #include <stdio.h>
michael@0 8 #include <stdlib.h>
michael@0 9 #ifdef XP_WIN
michael@0 10 #include <windows.h>
michael@0 11 #define snprintf _snprintf
michael@0 12 #define strcasecmp _stricmp
michael@0 13 #endif
michael@0 14
michael@0 15 #include "nsAppRunner.h"
michael@0 16 #include "nsIFile.h"
michael@0 17 #include "nsCOMPtr.h"
michael@0 18 #include "nsMemory.h"
michael@0 19 #include "nsCRTGlue.h"
michael@0 20 #include "nsStringAPI.h"
michael@0 21 #include "nsServiceManagerUtils.h"
michael@0 22 #include "plstr.h"
michael@0 23 #include "prprf.h"
michael@0 24 #include "prenv.h"
michael@0 25 #include "nsINIParser.h"
michael@0 26
michael@0 27 #ifdef XP_WIN
michael@0 28 #include "nsWindowsWMain.cpp"
michael@0 29 #endif
michael@0 30
michael@0 31 #include "BinaryPath.h"
michael@0 32
michael@0 33 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
michael@0 34
michael@0 35 using namespace mozilla;
michael@0 36
michael@0 37 /**
michael@0 38 * Output a string to the user. This method is really only meant to be used to
michael@0 39 * output last-ditch error messages designed for developers NOT END USERS.
michael@0 40 *
michael@0 41 * @param isError
michael@0 42 * Pass true to indicate severe errors.
michael@0 43 * @param fmt
michael@0 44 * printf-style format string followed by arguments.
michael@0 45 */
michael@0 46 static void Output(bool isError, const char *fmt, ... )
michael@0 47 {
michael@0 48 va_list ap;
michael@0 49 va_start(ap, fmt);
michael@0 50
michael@0 51 #if (defined(XP_WIN) && !MOZ_WINCONSOLE)
michael@0 52 char16_t msg[2048];
michael@0 53 _vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
michael@0 54
michael@0 55 UINT flags = MB_OK;
michael@0 56 if (isError)
michael@0 57 flags |= MB_ICONERROR;
michael@0 58 else
michael@0 59 flags |= MB_ICONINFORMATION;
michael@0 60
michael@0 61 MessageBoxW(nullptr, msg, L"XULRunner", flags);
michael@0 62 #else
michael@0 63 vfprintf(stderr, fmt, ap);
michael@0 64 #endif
michael@0 65
michael@0 66 va_end(ap);
michael@0 67 }
michael@0 68
michael@0 69 /**
michael@0 70 * Return true if |arg| matches the given argument name.
michael@0 71 */
michael@0 72 static bool IsArg(const char* arg, const char* s)
michael@0 73 {
michael@0 74 if (*arg == '-')
michael@0 75 {
michael@0 76 if (*++arg == '-')
michael@0 77 ++arg;
michael@0 78 return !strcasecmp(arg, s);
michael@0 79 }
michael@0 80
michael@0 81 #if defined(XP_WIN)
michael@0 82 if (*arg == '/')
michael@0 83 return !strcasecmp(++arg, s);
michael@0 84 #endif
michael@0 85
michael@0 86 return false;
michael@0 87 }
michael@0 88
michael@0 89 static nsresult
michael@0 90 GetGREVersion(const char *argv0,
michael@0 91 nsACString *aMilestone,
michael@0 92 nsACString *aVersion)
michael@0 93 {
michael@0 94 if (aMilestone)
michael@0 95 aMilestone->Assign("<Error>");
michael@0 96 if (aVersion)
michael@0 97 aVersion->Assign("<Error>");
michael@0 98
michael@0 99 nsCOMPtr<nsIFile> iniFile;
michael@0 100 nsresult rv = BinaryPath::GetFile(argv0, getter_AddRefs(iniFile));
michael@0 101 if (NS_FAILED(rv))
michael@0 102 return rv;
michael@0 103
michael@0 104 iniFile->SetNativeLeafName(NS_LITERAL_CSTRING("platform.ini"));
michael@0 105
michael@0 106 nsINIParser parser;
michael@0 107 rv = parser.Init(iniFile);
michael@0 108 if (NS_FAILED(rv))
michael@0 109 return rv;
michael@0 110
michael@0 111 if (aMilestone) {
michael@0 112 rv = parser.GetString("Build", "Milestone", *aMilestone);
michael@0 113 if (NS_FAILED(rv))
michael@0 114 return rv;
michael@0 115 }
michael@0 116 if (aVersion) {
michael@0 117 rv = parser.GetString("Build", "BuildID", *aVersion);
michael@0 118 if (NS_FAILED(rv))
michael@0 119 return rv;
michael@0 120 }
michael@0 121 return NS_OK;
michael@0 122 }
michael@0 123
michael@0 124 /**
michael@0 125 * A helper class which calls NS_LogInit/NS_LogTerm in its scope.
michael@0 126 */
michael@0 127 class ScopedLogging
michael@0 128 {
michael@0 129 public:
michael@0 130 ScopedLogging() { NS_LogInit(); }
michael@0 131 ~ScopedLogging() { NS_LogTerm(); }
michael@0 132 };
michael@0 133
michael@0 134 static void Usage(const char *argv0)
michael@0 135 {
michael@0 136 nsAutoCString milestone;
michael@0 137 GetGREVersion(argv0, &milestone, nullptr);
michael@0 138
michael@0 139 // display additional information (XXX make localizable?)
michael@0 140 Output(false,
michael@0 141 "Mozilla XULRunner %s\n\n"
michael@0 142 "Usage: " XULRUNNER_PROGNAME " [OPTIONS]\n"
michael@0 143 " " XULRUNNER_PROGNAME " APP-FILE [APP-OPTIONS...]\n"
michael@0 144 "\n"
michael@0 145 "OPTIONS\n"
michael@0 146 " --app specify APP-FILE (optional)\n"
michael@0 147 " -h, --help show this message\n"
michael@0 148 " -v, --version show version\n"
michael@0 149 " --gre-version print the GRE version string on stdout\n"
michael@0 150 "\n"
michael@0 151 "APP-FILE\n"
michael@0 152 " Application initialization file.\n"
michael@0 153 "\n"
michael@0 154 "APP-OPTIONS\n"
michael@0 155 " Application specific options.\n",
michael@0 156 milestone.get());
michael@0 157 }
michael@0 158
michael@0 159 XRE_GetFileFromPathType XRE_GetFileFromPath;
michael@0 160 XRE_CreateAppDataType XRE_CreateAppData;
michael@0 161 XRE_FreeAppDataType XRE_FreeAppData;
michael@0 162 XRE_mainType XRE_main;
michael@0 163
michael@0 164 static const nsDynamicFunctionLoad kXULFuncs[] = {
michael@0 165 { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
michael@0 166 { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
michael@0 167 { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
michael@0 168 { "XRE_main", (NSFuncPtr*) &XRE_main },
michael@0 169 { nullptr, nullptr }
michael@0 170 };
michael@0 171
michael@0 172 class AutoAppData
michael@0 173 {
michael@0 174 public:
michael@0 175 AutoAppData(nsIFile* aINIFile) : mAppData(nullptr) {
michael@0 176 nsresult rv = XRE_CreateAppData(aINIFile, &mAppData);
michael@0 177 if (NS_FAILED(rv))
michael@0 178 mAppData = nullptr;
michael@0 179 }
michael@0 180 ~AutoAppData() {
michael@0 181 if (mAppData)
michael@0 182 XRE_FreeAppData(mAppData);
michael@0 183 }
michael@0 184
michael@0 185 operator nsXREAppData*() const { return mAppData; }
michael@0 186 nsXREAppData* operator -> () const { return mAppData; }
michael@0 187
michael@0 188 private:
michael@0 189 nsXREAppData* mAppData;
michael@0 190 };
michael@0 191
michael@0 192 int main(int argc, char* argv[])
michael@0 193 {
michael@0 194 char exePath[MAXPATHLEN];
michael@0 195 nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
michael@0 196 if (NS_FAILED(rv)) {
michael@0 197 Output(true, "Couldn't calculate the application directory.\n");
michael@0 198 return 255;
michael@0 199 }
michael@0 200
michael@0 201 char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
michael@0 202 if (!lastSlash || (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
michael@0 203 return 255;
michael@0 204
michael@0 205 strcpy(++lastSlash, XPCOM_DLL);
michael@0 206
michael@0 207 rv = XPCOMGlueStartup(exePath);
michael@0 208 if (NS_FAILED(rv)) {
michael@0 209 Output(true, "Couldn't load XPCOM.\n");
michael@0 210 return 255;
michael@0 211 }
michael@0 212
michael@0 213 ScopedLogging log;
michael@0 214
michael@0 215 if (argc > 1 && (IsArg(argv[1], "h") ||
michael@0 216 IsArg(argv[1], "help") ||
michael@0 217 IsArg(argv[1], "?")))
michael@0 218 {
michael@0 219 Usage(argv[0]);
michael@0 220 return 0;
michael@0 221 }
michael@0 222
michael@0 223 if (argc == 2 && (IsArg(argv[1], "v") || IsArg(argv[1], "version")))
michael@0 224 {
michael@0 225 nsAutoCString milestone;
michael@0 226 nsAutoCString version;
michael@0 227 GetGREVersion(argv[0], &milestone, &version);
michael@0 228 Output(false, "Mozilla XULRunner %s - %s\n",
michael@0 229 milestone.get(), version.get());
michael@0 230 return 0;
michael@0 231 }
michael@0 232
michael@0 233 rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
michael@0 234 if (NS_FAILED(rv)) {
michael@0 235 Output(true, "Couldn't load XRE functions.\n");
michael@0 236 return 255;
michael@0 237 }
michael@0 238
michael@0 239 if (argc > 1) {
michael@0 240 nsAutoCString milestone;
michael@0 241 rv = GetGREVersion(argv[0], &milestone, nullptr);
michael@0 242 if (NS_FAILED(rv))
michael@0 243 return 2;
michael@0 244
michael@0 245 if (IsArg(argv[1], "gre-version")) {
michael@0 246 if (argc != 2) {
michael@0 247 Usage(argv[0]);
michael@0 248 return 1;
michael@0 249 }
michael@0 250
michael@0 251 printf("%s\n", milestone.get());
michael@0 252 return 0;
michael@0 253 }
michael@0 254
michael@0 255 if (IsArg(argv[1], "install-app")) {
michael@0 256 Output(true, "--install-app support has been removed. Use 'python install-app.py' instead.\n");
michael@0 257 return 1;
michael@0 258 }
michael@0 259 }
michael@0 260
michael@0 261 const char *appDataFile = getenv("XUL_APP_FILE");
michael@0 262
michael@0 263 if (!(appDataFile && *appDataFile)) {
michael@0 264 if (argc < 2) {
michael@0 265 Usage(argv[0]);
michael@0 266 return 1;
michael@0 267 }
michael@0 268
michael@0 269 if (IsArg(argv[1], "app")) {
michael@0 270 if (argc == 2) {
michael@0 271 Usage(argv[0]);
michael@0 272 return 1;
michael@0 273 }
michael@0 274 argv[1] = argv[0];
michael@0 275 ++argv;
michael@0 276 --argc;
michael@0 277 }
michael@0 278
michael@0 279 appDataFile = argv[1];
michael@0 280 argv[1] = argv[0];
michael@0 281 ++argv;
michael@0 282 --argc;
michael@0 283
michael@0 284 static char kAppEnv[MAXPATHLEN];
michael@0 285 snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile);
michael@0 286 putenv(kAppEnv);
michael@0 287 }
michael@0 288
michael@0 289 nsCOMPtr<nsIFile> appDataLF;
michael@0 290 rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appDataLF));
michael@0 291 if (NS_FAILED(rv)) {
michael@0 292 Output(true, "Error: unrecognized application.ini path.\n");
michael@0 293 return 2;
michael@0 294 }
michael@0 295
michael@0 296 AutoAppData appData(appDataLF);
michael@0 297 if (!appData) {
michael@0 298 Output(true, "Error: couldn't parse application.ini.\n");
michael@0 299 return 2;
michael@0 300 }
michael@0 301
michael@0 302 return XRE_main(argc, argv, appData, 0);
michael@0 303 }

mercurial