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.bergmann@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 b9cf9c2..9ef08e8 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 925b6b7..3221d68 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 2fe188b..2d301c5 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 8b5a09e..a6bc698 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 0000000..5ae65db
--- /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 ac4a7e6..5b0d081 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 bad31b0..a8b9283 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/. */
--- onlineupdate/source/service/serviceinstall.cpp
+++ onlineupdate/source/service/serviceinstall.cpp
@@ -25,7 +25,7 @@
#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."));
// 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);
- 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'\0'};
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'\0'};
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'\0'};
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'\0'};
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;
}
char icon_path[PATH_MAX];
diff --git a/external/onlineupdate/updater.ini b/external/onlineupdate/updater.ini
new file mode 100644
index 0000000..8ee6ad9c
--- /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.