Repository.mk | 1 desktop/source/app/updater.cxx | 26 ++- external/onlineupdate/Executable_update_service.mk | 2 external/onlineupdate/Module_onlineupdate.mk | 1 external/onlineupdate/Package_updater_ini.mk | 16 ++ external/onlineupdate/README.md | 9 + external/onlineupdate/lo.patch | 151 ++++++++++++++++++--- external/onlineupdate/updater.ini | 12 + 8 files changed, 189 insertions(+), 29 deletions(-)
New commits: commit d125fc2a2178b100253ea089b7ad30acafccfb57 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Tue Dec 19 16:50:42 2023 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Wed Dec 20 08:09:06 2023 +0100 Improve --enable-online-update-mar Windows MOZ_MAINTENANCE_SERVICE feature To get the MOZ_MAINTENANCE_SERVICE mode going at all, update.status needs to contain a "pending-service" token. For Mozilla, code in its toolkit/mozapps/update/UpdateService.sys.mjs takes care of writing that. For us, lets always write that in update_checker() (even on Linux, where it's apparently harmless). Then, the MOZ_MAINTENANCE_SERVICE code is rather picky with its various sanity checks: Among other things, it expects argv[0] to be a full path to the updater executable, and it expects the update.mar (and its status and log files) to be in a directory hierarchy named updates/0/ rather than patch/. So get all that fixed in desktop/source/app/updater.cxx. And patch in external/onlineupdate/lo.patch where it expects to find the updater executable (just updater.exe vs. our program/updater.exe). And we shouldn't interfere with the upstream Mozilla maintenance service, so also rename that in external/onlineupdate/lo.patch. And `update_service install` wants to read version resources from the update_service.exe, so provide that (via gb_Executable_add_default_nativeres). Also, `update_service install` wants to read a MozillaMaintenanceDescription value from an updater.ini, so provide one (with contents of that value inspired by Mozilla's browser/locales/en-US/updater/updater.ini). As we now have an updater.ini anyway (and which apparently works fine with Unix line ends on both Linux and Windows), also use it on Linux and drop the onlineupdate/source/update/updater/progressui_gtk.cpp again from external/onlineupdate/lo.patch. And update external/onlineupdate/README.md how to manually execute that test against an updater.ini. Change-Id: I0e3e5e5311be61e1224cda700af2e5d751113a99 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160996 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> (cherry picked from commit 290f8f908dc8178c8bc34a8bf909246f591a13aa) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161014 diff --git a/Repository.mk b/Repository.mk index b9cf9c2ddb9c..9ef08e814a20 100644 --- a/Repository.mk +++ b/Repository.mk @@ -1096,6 +1096,7 @@ $(eval $(call gb_Helper_register_packages_for_install,brand,\ readlicense_oo_files \ readlicense_oo_license \ $(call gb_Helper_optional,DESKTOP,setup_native_packinfo) \ + $(if $(ENABLE_ONLINE_UPDATE_MAR),updater_ini) \ )) ifeq ($(USING_X11), TRUE) diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx index 925b6b7116a4..3221d688a47f 100644 --- a/desktop/source/app/updater.cxx +++ b/desktop/source/app/updater.cxx @@ -32,6 +32,7 @@ #include <osl/file.hxx> #include <rtl/process.h> #include <sal/log.hxx> +#include <tools/stream.hxx> #include <curl/curl.h> @@ -173,17 +174,14 @@ void createStr(const OUString& rStr, CharT** pArgs, size_t i) pArgs[i] = pStr; } -CharT** createCommandLine(int * argc) +CharT** createCommandLine(OUString const & argv0, int * argc) { OUString aInstallDir = Updater::getInstallationPath(); size_t nCommandLineArgs = rtl_getAppCommandArgCount(); size_t nArgs = 8 + nCommandLineArgs; CharT** pArgs = new CharT*[nArgs]; - { - OUString aUpdaterName = OUString::fromUtf8(pUpdaterName); - createStr(aUpdaterName, pArgs, 0); - } + createStr(argv0, pArgs, 0); { // directory with the patch log OUString aPatchDir = Updater::getPatchDirURL(); @@ -307,7 +305,7 @@ bool update() Updater::log("Calling the updater with parameters: "); int argc; - CharT** pArgs = createCommandLine(&argc); + CharT** pArgs = createCommandLine(aUpdaterPath, &argc); bool bSuccess = true; const char* pUpdaterTestReplace = std::getenv("LIBO_UPDATER_TEST_REPLACE"); @@ -676,9 +674,11 @@ void download_file(const OUString& rURL, size_t nFileSize, const OUString& rHash throw invalid_hash(rHash, aHash); } - OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/"); + OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/"); rtl::Bootstrap::expandMacros(aPatchDirURL); osl::Directory::create(aPatchDirURL); + aPatchDirURL += "0/"; + osl::Directory::create(aPatchDirURL); OUString aDestFile = aPatchDirURL + aFileName; Updater::log("Destination File: " + aDestFile); @@ -764,6 +764,14 @@ void update_checker() comphelper::ConfigurationChanges::create()); officecfg::Office::Update::Update::SeeAlso::set(aSeeAlsoURL, batch); batch->commit(); + OUString const statUrl = Updater::getPatchDirURL() + "update.status"; + SvFileStream stat(statUrl, StreamMode::WRITE | StreamMode::TRUNC); + stat.WriteOString("pending-service"); + stat.Flush(); + if (auto const e = stat.GetError()) { + Updater::log("Writing <" + statUrl + "> failed with " + e.toString()); + } + stat.Close(); } } } @@ -796,7 +804,7 @@ void update_checker() OUString Updater::getUpdateInfoLog() { - OUString aUpdateInfoURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/updating.log"); + OUString aUpdateInfoURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/updating.log"); rtl::Bootstrap::expandMacros(aUpdateInfoURL); return aUpdateInfoURL; @@ -804,7 +812,7 @@ OUString Updater::getUpdateInfoLog() OUString Updater::getPatchDirURL() { - OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/"); + OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/0/"); rtl::Bootstrap::expandMacros(aPatchDirURL); return aPatchDirURL; diff --git a/external/onlineupdate/Executable_update_service.mk b/external/onlineupdate/Executable_update_service.mk index 2fe188bbc024..2d301c5acead 100644 --- a/external/onlineupdate/Executable_update_service.mk +++ b/external/onlineupdate/Executable_update_service.mk @@ -78,4 +78,6 @@ $(eval $(call gb_Executable_add_defs,update_service, \ $(eval $(call gb_Executable_set_warnings_disabled,update_service)) +$(eval $(call gb_Executable_add_default_nativeres,update_service)) + # vim:set shiftwidth=4 tabstop=4 noexpandtab: */ diff --git a/external/onlineupdate/Module_onlineupdate.mk b/external/onlineupdate/Module_onlineupdate.mk index 8b5a09efc0ae..a6bc698aa3ca 100644 --- a/external/onlineupdate/Module_onlineupdate.mk +++ b/external/onlineupdate/Module_onlineupdate.mk @@ -24,6 +24,7 @@ $(eval $(call gb_Module_add_targets,onlineupdate,\ Executable_updater \ Executable_mbsdiff \ CustomTarget_generated \ + Package_updater_ini \ )) endif diff --git a/external/onlineupdate/Package_updater_ini.mk b/external/onlineupdate/Package_updater_ini.mk new file mode 100644 index 000000000000..5ae65db8b4bd --- /dev/null +++ b/external/onlineupdate/Package_updater_ini.mk @@ -0,0 +1,16 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Package_Package,updater_ini,$(SRCDIR)/external/onlineupdate)) + +$(eval $(call gb_Package_add_files,updater_ini,$(LIBO_BIN_FOLDER), \ + updater.ini \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/external/onlineupdate/README.md b/external/onlineupdate/README.md index ac4a7e65ba3d..5b0d08146efb 100644 --- a/external/onlineupdate/README.md +++ b/external/onlineupdate/README.md @@ -33,3 +33,12 @@ updater. * The `update` directory is inside of the user profile resulting in recursive copying. * During the replacement request the updater log is in the user profile, which changes location from the actual location to a backup location. + +## Executable_test_updater_dialog + +To run that manual test, do +``` +$ cp instdir/program/updater.ini workdir/LinkTarget/Executable/test_updater_dialog.ini +$ workdir/LinkTarget/Executable/test_updater_dialog +$ rm workdir/LinkTarget/Executable/test_updater_dialog.ini +``` diff --git a/external/onlineupdate/lo.patch b/external/onlineupdate/lo.patch index bad31b0aacfc..a8b92830419c 100644 --- a/external/onlineupdate/lo.patch +++ b/external/onlineupdate/lo.patch @@ -1,21 +1,132 @@ ---- onlineupdate/source/update/updater/progressui_gtk.cpp -+++ onlineupdate/source/update/updater/progressui_gtk.cpp -@@ -5,6 +5,7 @@ - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - #include <gtk/gtk.h> -+#include <string.h> - #include <unistd.h> - #include "mozilla/Sprintf.h" - #include "mozilla/Atomics.h" -@@ -52,8 +53,8 @@ - char ini_path[PATH_MAX]; - SprintfLiteral(ini_path, "%s.ini", (*pargv)[0]); - if (ReadStrings(ini_path, &sStrings) != OK) { -- sEnableUI = false; -- return -1; -+ sStrings.title.reset(strdup("LibreOffice Update")); -+ sStrings.info.reset(strdup("Please wait while we update your installation.")); - } +--- onlineupdate/source/service/serviceinstall.cpp ++++ onlineupdate/source/service/serviceinstall.cpp +@@ -25,7 +25,7 @@ + + // This uninstall key is defined originally in maintenanceservice_installer.nsi + #define MAINT_UNINSTALL_KEY \ +- L"Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenan" \ ++ L"Software\Microsoft\Windows\CurrentVersion\Uninstall\LibreOfficeMaintenan" \ + L"ceService" + + static BOOL UpdateUninstallerVersionString(LPWSTR versionString) { +@@ -201,7 +201,7 @@ + size_t currentServicePathLen = wcslen(currentServicePath); + bool doesServiceHaveCorrectPath = + currentServicePathLen > 2 && +- !wcsstr(currentServicePath, L"maintenanceservice_tmp.exe") && ++ !wcsstr(currentServicePath, L"update_service_tmp.exe") && + currentServicePath[0] == L'\"' && + currentServicePath[currentServicePathLen - 1] == L'\"'; + +@@ -222,7 +222,7 @@ + LOG_WARN(("Couldn't remove file spec. (%lu)", GetLastError())); + return FALSE; + } +- if (!PathAppendSafe(fixedPath, L"maintenanceservice.exe")) { ++ if (!PathAppendSafe(fixedPath, L"update_service.exe")) { + LOG_WARN(("Couldn't append file spec. (%lu)", GetLastError())); + return FALSE; + } +@@ -561,7 +561,7 @@ + + // The service can be in a stopped state but the exe still in use + // so make sure the process is really gone before proceeding +- WaitForProcessExit(L"maintenanceservice.exe", 30); ++ WaitForProcessExit(L"update_service.exe", 30); + LOG(("Done waiting for service stop, last service state: %lu", lastState)); + + return lastState == SERVICE_STOPPED; +--- onlineupdate/source/service/serviceinstall.h ++++ onlineupdate/source/service/serviceinstall.h +@@ -4,7 +4,7 @@ + + #include "readstrings.h" + +-#define SVC_DISPLAY_NAME L"Mozilla Maintenance Service" ++#define SVC_DISPLAY_NAME L"LibreOffice Maintenance Service" + + enum SvcInstallAction { UpgradeSvc, InstallSvc, ForceInstallSvc }; + BOOL SvcInstall(SvcInstallAction action); +--- onlineupdate/source/update/common/pathhash.cpp ++++ onlineupdate/source/update/common/pathhash.cpp +@@ -119,7 +119,7 @@ + delete[] lowercasePath; + + LPCWSTR baseRegPath = +- L"SOFTWARE\Mozilla\" ++ L"SOFTWARE\LibreOffice\" + L"MaintenanceService\"; + wcsncpy(registryPath, baseRegPath, MAX_PATH); + BinaryDataToHexString(hash, hashSize, registryPath + wcslen(baseRegPath)); +--- onlineupdate/source/update/common/updatehelper.cpp ++++ onlineupdate/source/update/common/updatehelper.cpp +@@ -78,7 +78,7 @@ + wcsncpy(outBuf, progFilesX86, MAX_PATH + 1); + CoTaskMemFree(progFilesX86); - char icon_path[PATH_MAX]; +- if (!PathAppendSafe(outBuf, L"Mozilla Maintenance Service")) { ++ if (!PathAppendSafe(outBuf, L"LibreOffice Maintenance Service")) { + return FALSE; + } + +@@ -311,7 +311,7 @@ + // Obtain the temp path of the maintenance service binary + WCHAR tmpService[MAX_PATH + 1] = {L' + if (!PathGetSiblingFilePath(tmpService, serviceConfig.lpBinaryPathName, +- L"maintenanceservice_tmp.exe")) { ++ L"update_service_tmp.exe")) { + return FALSE; + } + +@@ -322,7 +322,7 @@ + // Get the new maintenance service path from the install dir + WCHAR newMaintServicePath[MAX_PATH + 1] = {L' + wcsncpy(newMaintServicePath, installDir, MAX_PATH); +- PathAppendSafe(newMaintServicePath, L"maintenanceservice.exe"); ++ PathAppendSafe(newMaintServicePath, L"update_service.exe"); + + // Copy the temp file in alongside the maintenace service. + // This is a requirement for maintenance service upgrades. +@@ -429,7 +429,7 @@ + // 2) The command being executed, which is "software-update" + // 3) The path to updater.exe (from argv[0]) + LPCWSTR* updaterServiceArgv = new LPCWSTR[argc + 2]; +- updaterServiceArgv[0] = L"MozillaMaintenance"; ++ updaterServiceArgv[0] = L"LibreOfficeMaintenance"; + updaterServiceArgv[1] = L"software-update"; + + for (int i = 0; i < argc; ++i) { +--- onlineupdate/source/update/common/updatehelper.h ++++ onlineupdate/source/update/common/updatehelper.h +@@ -24,9 +24,9 @@ + #define PATCH_DIR_PATH L"\updates\0" + + #ifdef MOZ_MAINTENANCE_SERVICE +-# define SVC_NAME L"MozillaMaintenance" ++# define SVC_NAME L"LibreOfficeMaintenance" + +-# define BASE_SERVICE_REG_KEY L"SOFTWARE\Mozilla\MaintenanceService" ++# define BASE_SERVICE_REG_KEY L"SOFTWARE\LibreOffice\MaintenanceService" + + // The test only fallback key, as its name implies, is only present on machines + // that will use automated tests. Since automated tests always run from a +--- onlineupdate/source/service/workmonitor.cpp ++++ onlineupdate/source/service/workmonitor.cpp +@@ -328,7 +328,7 @@ + // The installation dir that we are installing to is installDir. + WCHAR installDirUpdater[MAX_PATH + 1] = {L' + wcsncpy(installDirUpdater, installDir, MAX_PATH); +- if (!PathAppendSafe(installDirUpdater, L"updater.exe")) { ++ if (!PathAppendSafe(installDirUpdater, L"program\updater.exe")) { + LOG_WARN(("Install directory updater could not be determined.")); + return false; + } +@@ -746,7 +746,7 @@ + + WCHAR installDirUpdater[MAX_PATH + 1] = {L' + wcsncpy(installDirUpdater, installDir, MAX_PATH); +- if (!PathAppendSafe(installDirUpdater, L"updater.exe")) { ++ if (!PathAppendSafe(installDirUpdater, L"program\updater.exe")) { + LOG_WARN(("Install directory updater could not be determined.")); + result = FALSE; + } diff --git a/external/onlineupdate/updater.ini b/external/onlineupdate/updater.ini new file mode 100644 index 000000000000..8ee6ad9cc298 --- /dev/null +++ b/external/onlineupdate/updater.ini @@ -0,0 +1,12 @@ +; +; This file is part of the LibreOffice project. +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; + +[Strings] +Title=LibreOffice Update +Info=Please wait while we update your installation. +MozillaMaintenanceDescription=The LibreOffice Maintenace Service helps ensure that you have the latest and most secure version of LibreOffice on your computer.