--- mozilla/toolkit/mozapps/extensions/src/nsExtensionManager.js.in.nox 2005-02-01 12:50:53 +0300 +++ mozilla/toolkit/mozapps/extensions/src/nsExtensionManager.js.in 2005-02-01 13:03:08 +0300 @@ -238,16 +238,24 @@ function stripPrefix(aURI, aItemType) return val; } function stripPropertyPrefix(aProperty, aPrefix) { return aProperty.substr(aPrefix.length, aProperty.length); } +function getFileFromURLSpec(aURLStr) +{ + var ioServ = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + var fph = ioServ.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); + return fph.getFileFromURLSpec(aURLStr); +} + function getURLSpecFromFile(aFile) { var ioServ = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var fph = ioServ.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); return fph.getURLSpecFromFile(aFile); } @@ -889,49 +897,54 @@ nsExtensionInstaller.prototype = { // Utility services and helpers _rdf : null, _writer : null, // Extension metadata _extensionID : null, _isProfile : true, _extDirKey : KEY_PROFILEDIR, + + // legion: if this set to true, do only update all meta information + _isUpdateOnly : false, // Source and target datasources _metadataDS : null, _extensionDS : null, // RDF objects and properties _provTypePackage : null, _provTypeSkin : null, _provTypeLocale : null, _sourceResource : null, _fileProperty : null, - install: function nsExtensionInstaller_install (aExtensionID, aIsProfile) + install: function nsExtensionInstaller_install (aExtensionID, aIsProfile, aUpdateOnly) { // Initialize the installer for this extension this._extensionID = aExtensionID; this._isProfile = aIsProfile; + this._isUpdateOnly = aUpdateOnly; this._extDirKey = getDirKey(this._isProfile); // Create a logger to log install operations for uninstall this._writer = new nsInstallLogWriter(this._extensionID, this._isProfile); this._writer.open(); // Move files from the staging dir into the extension's final home. // This function generates uninstall log files and creates backups of // existing files. // XXXben - would like to add exception handling here to test for file // I/O failures on uninstall log so that if there's a crash // and the uninstall log is incorrectly/incompletely written // we can roll back. It's not critical that we do so right now // since if this throws the extension's chrome is never // registered. - this._installExtensionFiles(); + if (!this._isUpdateOnly) + this._installExtensionFiles(); // Load the metadata datasource var metadataFile = getFile(this._extDirKey, [DIR_EXTENSIONS, aExtensionID, FILE_INSTALL_MANIFEST]); this._metadataDS = getInstallManifest(metadataFile); if (!this._metadataDS) return; @@ -1451,16 +1464,70 @@ nsThemeInstaller.prototype = { this._extensionDS.doneInstallingTheme(this._themeID); } else if (this._themeID == 0) showIncompatibleError(themeMetadata); zipReader.close(); themeManifest.remove(false); chromeManifest.remove(false); + }, + + // legion: This function must refresh all the metadata for already installed theme. + updateMetadata: function nsThemeInstaller_updateMetadata (aThemeID) + { + this._themeID = aThemeID; + var isProfile = this._extensionDS.isProfileItem(this._themeID); + var extDirKey = isProfile ? KEY_PROFILEDIR : KEY_APPDIR; + var chromeDir = getDir(extDirKey, [DIR_EXTENSIONS, this._themeID, DIR_CHROME]); + + var zipReader = Components.classes["@mozilla.org/libjar/zip-reader;1"] + .createInstance(Components.interfaces.nsIZipReader); + var jarFile = null; + if (chromeDir.directoryEntries.hasMoreElements()) { + jarFile = chromeDir.directoryEntries.getNext().QueryInterface(Components.interfaces.nsIFile); + + if (jarFile.exists()) { + zipReader.init(jarFile); + zipReader.open(); + try { + zipReader.getEntry(FILE_INSTALL_MANIFEST); + } + catch (e) { + dump("*** nsThemeInstaller::updateMetadata() - Not found JAR file for: " + this._themeID + "\n"); + } + zipReader.close(); + } + } + if (jarFile && jarFile.exists()) { + var destinationFile = getFile(extDirKey, [DIR_EXTENSIONS, this._themeID, DIR_CHROME, jarFile.leafName]); + var themeManifest = getFile(extDirKey, + [DIR_EXTENSIONS, DIR_TEMP, getRandomFileName("install", "rdf")]); + zipReader.init(jarFile); + zipReader.open(); + zipReader.extract(FILE_INSTALL_MANIFEST, themeManifest); + + var themeMetadata = getInstallManifest(themeManifest); + + // Use the Chrome Registry API to install the theme there + var filePath = "jar:" + getURLSpecFromFile(destinationFile) + "!/"; + var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.nsIXULChromeRegistry); + cr.installSkin(filePath, isProfile, false); + + // Insert the theme into the theme list. + this._extensionDS.insertForthcomingItem(this._themeID, nsIUpdateItem.TYPE_THEME, + isProfile); + + // Add metadata for the extension to the global extension metadata set + this._extensionDS.addItemMetadata(this._themeID, nsIUpdateItem.TYPE_THEME, + themeMetadata, isProfile); + zipReader.close(); + themeManifest.remove(false); + } } }; /////////////////////////////////////////////////////////////////////////////// // // nsThemeUninstaller // function nsThemeUninstaller(aExtensionDS) @@ -1707,23 +1774,40 @@ nsExtensionManager.prototype = { return needsRestart; }, handleCommandLineArgs: function nsExtensionManager_handleCommandLineArgs () { var cmdLineSvc = Components.classes["@mozilla.org/appshell/commandLineService;1"] .getService(Components.interfaces.nsICmdLineService); var globalExtension = cmdLineSvc.getCmdLineValue("-install-global-extension"); - if (globalExtension) - this._checkForGlobalInstalls(globalExtension, nsIUpdateItem.TYPE_EXTENSION); - + if (globalExtension) { + var extensionFile = getFileFromURLSpec(globalExtension).path; + this._checkForGlobalInstalls(extensionFile, nsIUpdateItem.TYPE_EXTENSION); + } + + var extensionID = cmdLineSvc.getCmdLineValue("-uninstall-global-extension"); + if (extensionID) { + this._checkForGlobalUnInstalls(extensionID, nsIUpdateItem.TYPE_EXTENSION); + } + var globalTheme = cmdLineSvc.getCmdLineValue("-install-global-theme"); - if (globalTheme) - this._checkForGlobalInstalls(globalTheme, nsIUpdateItem.TYPE_THEME); - + if (globalTheme) { + var themeFile = getFileFromURLSpec(globalTheme).path; + this._checkForGlobalInstalls(themeFile, nsIUpdateItem.TYPE_THEME); + } + + var themeID = cmdLineSvc.getCmdLineValue("-uninstall-global-theme"); + if (themeID) + this._checkForGlobalUnInstalls(themeID, nsIUpdateItem.TYPE_THEME); + + var update = cmdLineSvc.getCmdLineValue("-update-register"); + if (update) + this.updateRegister(); + var showList = cmdLineSvc.getCmdLineValue("-list-global-items"); if (showList) this._showGlobalItemList(); var locked = cmdLineSvc.getCmdLineValue("-lock-item"); if (locked) { this._ensureDS(); this._ds.lockUnlockItem(locked, true); @@ -1732,16 +1816,45 @@ nsExtensionManager.prototype = { var unlocked = cmdLineSvc.getCmdLineValue("-unlock-item"); if (unlocked) { this._ensureDS(); this._ds.lockUnlockItem(unlocked, false); } this._finishOperations(); }, + + // legion: function fix broken metadata. Its may happen, + // if the user execute regchome or for some other reasons. + updateRegister: function nsExtensionManager_updateRegister () + { + this._ensureDS(); + var items = null; + + // Update extensions + try { + items = this.getItemList(null, nsIUpdateItem.TYPE_EXTENSION, {}); + for (var i = 0; i < items.length; ++i) + this._finalizeInstall(items[i].id, true); + } + catch(e) { + dump("*** nsExtensionManager::updateRegister() - Update extensions faild: " + e + "\n"); + } + + // Update themes + try { + var installer = new nsThemeInstaller(this._ds, this); + items = this.getItemList(null, nsIUpdateItem.TYPE_THEME, {}); + for (var i = 0; i < items.length; ++i) + installer.updateMetadata(items[i].id); + } + catch(e) { + dump("*** nsExtensionManager::updateRegister() - Update themes faild: " + e + "\n"); + } + }, register: function nsExtensionManager_register () { if (!this._started) { // Loads the datasource and installs any pre-configured items. this._ds = new nsExtensionsDataSource(); this._ds.loadExtensions(false); @@ -1874,17 +1987,33 @@ nsExtensionManager.prototype = { if (aItemType & nsIUpdateItem.TYPE_EXTENSION) this.installExtension(file, nsIExtensionManager.FLAG_INSTALL_GLOBAL); else if (aItemType & nsIUpdateItem.TYPE_THEME) this.installTheme(file, nsIExtensionManager.FLAG_INSTALL_GLOBAL); } else dump("Invalid XPI/JAR Path: " + aPath + "\n"); }, - + + _checkForGlobalUnInstalls: function nsExtensionManager__checkForGlobalUnInstalls (aItemID, aItemType) + { + this._ensureDS(); + + // We must make this hack to upgrade Components Manifest. + this._ds.setItemProperty(aItemID, + this._ds._emR("downloadURL"), + null, this._isProfile, + aItemType); + + if (aItemType & nsIUpdateItem.TYPE_EXTENSION) + this.uninstallExtension(aItemID); + else if (aItemType & nsIUpdateItem.TYPE_THEME) + this.uninstallTheme(aItemID); + }, + _showGlobalItemList: function nsExtensionManager__showGlobalItemList () { this._ensureDS(); var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"] .getService(Components.interfaces.nsIStringBundleService); var bundle = sbs.createBundle("chrome://mozapps/locale/extensions/extensions.properties"); @@ -1898,17 +2027,22 @@ nsExtensionManager.prototype = { for (var i = 0; i < items.length; ++i) dump(" " + items[i].id + " " + items[i].name + " " + items[i].version + "\n"); dump("\n\n"); }, _finishOperations: function nsExtensionManager__finishOperations () { - var win = this._showProgressWindow(); + var win; + var cmdLineSvc = Components.classes["@mozilla.org/appshell/commandLineService;1"] + .getService(Components.interfaces.nsICmdLineService); + var nox = cmdLineSvc.getCmdLineValue("-nox"); + if (!nox) + win = this._showProgressWindow(); try { // An existing autoreg file is an indication that something major has // happened to the extensions datasource (install/uninstall/enable/disable) // and as such we must load it now and see what needs to happen. this._ensureDS(); // Look for items that need to be installed @@ -1946,17 +2080,18 @@ nsExtensionManager.prototype = { // If no additional restart is required, it implies that there are // no new components that need registering so we can inform the app // not to do any extra startup checking next time round. this._writeCompatibilityManifest(needsRestart); } catch (e) { dump("*** nsExtensionManager::_finishOperations - failure, catching exception so finalize window can close " + e +"\n"); } - win.close(); + if (!nox) + win.close(); return needsRestart; }, // XXXben - this is actually a cheap stunt to load all the chrome registry // services required to register/unregister packages... the synchronous // nature of this code ensures the window will never actually appear // on screen. @@ -2512,30 +2647,30 @@ nsExtensionManager.prototype = { // if the source file was readonly, fix the permissions if (!extensionFile.isWritable()) { extensionFile.permissions = 0644; } }, // This function is called on the next startup - _finalizeInstall: function nsExtensionManager__finalizeInstall (aExtensionID) + _finalizeInstall: function nsExtensionManager__finalizeInstall (aExtensionID, aUpdateOnly) { var isProfile = this._ds.isProfileItem(aExtensionID); if (aExtensionID == 0 || aExtensionID == -1) { this._ds.removeCorruptItem(aExtensionID, nsIUpdateItem.TYPE_EXTENSION, isProfile); return; } if (!this._extInstaller) this._extInstaller = new nsExtensionInstaller(this._ds); - this._extInstaller.install(aExtensionID, isProfile); + this._extInstaller.install(aExtensionID, isProfile, aUpdateOnly); // Update the Components Manifest this._writeComponentManifest(isProfile); // Update the Defaults Manifest this._writeDefaults(isProfile); }, --- mozilla/toolkit/xre/nsAppRunner.cpp.nox 2004-11-03 02:27:24 +0300 +++ mozilla/toolkit/xre/nsAppRunner.cpp 2005-02-01 13:05:30 +0300 @@ -33,17 +33,16 @@ * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ - #include "nsAppRunner.h" #ifdef XP_MACOSX #include "MacLaunchHelper.h" #endif #ifdef XP_OS2 #include "private/pprthred.h" @@ -1399,16 +1398,17 @@ SelectProfile(nsIProfileLock* *aResult, return rv; } PRUint32 count; rv = profileSvc->GetProfileCount(&count); NS_ENSURE_SUCCESS(rv, rv); + if (!CheckArg("nox")) { arg = PR_GetEnv("XRE_IMPORT_PROFILES"); if (!count && (!arg || !*arg)) { return ImportProfiles(profileSvc, aNative); } ar = CheckArg("p", &arg); if (ar == ARG_BAD) { return ShowProfileManager(profileSvc, aNative); @@ -1424,17 +1424,17 @@ SelectProfile(nsIProfileLock* *aResult, } return ShowProfileManager(profileSvc, aNative); } if (CheckArg("profilemanager")) { return ShowProfileManager(profileSvc, aNative); } - + } // ! CheckArg("nox") if (!count) { gDoMigration = PR_TRUE; // create a default profile nsCOMPtr profile; nsresult rv = profileSvc->CreateProfile(nsnull, // choose a default dir for us NS_LITERAL_CSTRING("default"), @@ -1457,16 +1457,21 @@ SelectProfile(nsIProfileLock* *aResult, profileSvc->GetSelectedProfile(getter_AddRefs(profile)); if (profile) { rv = profile->Lock(aResult); if (NS_SUCCEEDED(rv)) return NS_OK; } } + if (CheckArg("nox")) { + PR_fprintf(PR_STDERR, "Error: can't select profile.\n"); + return NS_ERROR_ABORT; + } + return ShowProfileManager(profileSvc, aNative); } #define FILE_COMPATIBILITY_INFO NS_LITERAL_STRING("compatibility.ini") static void GetVersion(nsIFile* aProfileDir, char* aVersion, int aVersionLength) { nsCOMPtr compatibilityFile; @@ -1632,50 +1637,53 @@ int xre_main(int argc, char* argv[], con NS_ENSURE_TRUE(em, 1); em->Register(); } return 0; } #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2) + if (!CheckArg("nox")) { // 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 (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); gtk_widget_set_default_visual(gdk_rgb_get_visual()); gtk_widget_set_default_colormap(gdk_rgb_get_cmap()); + } // !CheckArg("nox") #endif /* MOZ_WIDGET_GTK || MOZ_WIDGET_GTK2 */ // Call the code to install our handler #ifdef MOZ_JPROF setupProfilingStuff(); #endif // Try to allocate "native app support." nsCOMPtr nativeApp; + if (!CheckArg("nox")) { 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; } - + } // !CheckArg("nox") //---------------------------------------------------------------- // 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. // @@ -1766,16 +1774,53 @@ int xre_main(int argc, char* argv[], con // Extensions and re-write the Components manifest ("components.ini") // with a list of XPCOM components for compatible extensions upgraded = PR_TRUE; // The Extension Manager will write the Compatibility manifest with // the current app version. } + if (CheckArg("nox")) { + // XPCOM + ScopedXPCOMStartup xpcom; + rv = xpcom.Initialize(); + rv |= xpcom.DoAutoreg(); + rv |= xpcom.InitEventQueue(); + NS_ENSURE_SUCCESS(rv, 1); + + dirProvider.Initialize(); + dirProvider.DoStartup(); + + nsCOMPtr cmdLineArgs + (do_GetService("@mozilla.org/appshell/commandLineService;1")); + NS_ENSURE_TRUE(cmdLineArgs, 1); + + rv = cmdLineArgs->Initialize(gArgc, gArgv); + + if (NS_FAILED(rv)) { + if (rv == NS_ERROR_INVALID_ARG) + DumpHelp(); + return rv; + } + + // Extension Compatibility Checking and Startup + nsCOMPtr em(do_GetService("@mozilla.org/extensions/manager;1")); + NS_ENSURE_TRUE(em, 1); + + if (CheckArg("install-global-extension") || CheckArg("uninstall-global-extension") || + CheckArg("install-global-theme") || CheckArg("uninstall-global-theme") || + CheckArg("lock-item") || CheckArg("unlock-item") || + CheckArg("list-global-items") || CheckArg("update-register")) { + // Do the required processing and then shut down. + em->HandleCommandLineArgs(); + } + return 0; + } + PRBool needsRestart = 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. PRBool noRestart = PR_FALSE; { // Start the real application