diff options
Diffstat (limited to 'desktop/source/app/updater.cxx')
-rw-r--r-- | desktop/source/app/updater.cxx | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx index 2748373e5f62..12bb4969a68c 100644 --- a/desktop/source/app/updater.cxx +++ b/desktop/source/app/updater.cxx @@ -28,15 +28,18 @@ #include <rtl/ustring.hxx> #include <unotools/tempfile.hxx> #include <unotools/configmgr.hxx> +#include <o3tl/char16_t2wchar_t.hxx> #include <osl/file.hxx> #include <rtl/process.h> #include <sal/log.hxx> +#include <tools/stream.hxx> #include <curl/curl.h> #include <orcus/json_document_tree.hpp> #include <orcus/config.hpp> -#include <orcus/pstring.hpp> + +#include <systools/curlinit.hxx> #include <comphelper/hash.hxx> #include <com/sun/star/container/XNameAccess.hpp> @@ -46,6 +49,7 @@ #include <functional> #include <memory> #include <set> +#include <string_view> namespace { @@ -83,7 +87,12 @@ const char* pSofficeExeName = "soffice.exe"; OUString normalizePath(const OUString& rPath) { - OUString aPath = rPath.replaceAll("//", "/"); + OUString aPath = rPath; +#if defined WNT + aPath = aPath.replace('\\', '/'); +#endif + + aPath = aPath.replaceAll("//", "/"); // remove final / if (aPath.endsWith("/")) @@ -105,7 +114,10 @@ OUString normalizePath(const OUString& rPath) aPath = aTempPath.copy(0, i) + aPath.copy(nIndex + 3); } - return aPath.replaceAll("\\", "/"); +#if defined WNT + aPath = aPath.replace('/', '\\'); +#endif + return aPath; } void CopyFileToDir(const OUString& rTempDirURL, const OUString & rFileName, const OUString& rOldDir) @@ -133,14 +145,17 @@ void CopyUpdaterToTempDir(const OUString& rInstallDirURL, const OUString& rTempD { OUString aUpdaterName = OUString::fromUtf8(pUpdaterName); CopyFileToDir(rTempDirURL, aUpdaterName, rInstallDirURL); + CopyFileToDir(rTempDirURL, u"updater.ini"_ustr, rInstallDirURL); } #ifdef UNX typedef char CharT; #define tstrncpy std::strncpy +char const * toStream(char const * s) { return s; } #elif defined(_WIN32) typedef wchar_t CharT; #define tstrncpy std::wcsncpy +OUString toStream(wchar_t const * s) { return OUString(o3tl::toU(s)); } #else #error "Need an implementation" #endif @@ -160,17 +175,14 @@ void createStr(const OUString& rStr, CharT** pArgs, size_t i) pArgs[i] = pStr; } -CharT** createCommandLine() +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(); @@ -226,6 +238,7 @@ CharT** createCommandLine() pArgs[nArgs - 1] = nullptr; + *argc = nArgs - 1; return pArgs; } @@ -285,14 +298,15 @@ bool isUserWritable(const OUString& rFileURL) bool update() { - utl::TempFile aTempDir(nullptr, true); + utl::TempFileNamed aTempDir(nullptr, true); OUString aTempDirURL = aTempDir.GetURL(); CopyUpdaterToTempDir(Updater::getExecutableDirURL(), aTempDirURL); OUString aUpdaterPath = getPathFromURL(aTempDirURL + "/" + OUString::fromUtf8(pUpdaterName)); Updater::log("Calling the updater with parameters: "); - CharT** pArgs = createCommandLine(); + int argc; + CharT** pArgs = createCommandLine(aUpdaterPath, &argc); bool bSuccess = true; const char* pUpdaterTestReplace = std::getenv("LIBO_UPDATER_TEST_REPLACE"); @@ -306,7 +320,7 @@ bool update() bSuccess = false; } #elif defined(_WIN32) - bSuccess = WinLaunchChild((wchar_t*)aUpdaterPath.getStr(), 8, pArgs); + bSuccess = WinLaunchChild((wchar_t*)aUpdaterPath.getStr(), argc, pArgs); #endif } else @@ -314,7 +328,7 @@ bool update() SAL_WARN("desktop.updater", "Updater executable path: " << aUpdaterPath); for (size_t i = 0; i < 8 + rtl_getAppCommandArgCount(); ++i) { - SAL_WARN("desktop.updater", pArgs[i]); + SAL_WARN("desktop.updater", toStream(pArgs[i])); } bSuccess = false; } @@ -389,9 +403,9 @@ public: } }; -OUString toOUString(const std::string& rStr) +OUString toOUString(const std::string_view& rStr) { - return OUString::fromUtf8(rStr.c_str()); + return OUString::fromUtf8(rStr); } update_file parse_update_file(orcus::json::node& rNode) @@ -420,12 +434,12 @@ update_file parse_update_file(orcus::json::node& rNode) } update_file aUpdateFile; - aUpdateFile.aURL = toOUString(aURLNode.string_value().str()); + aUpdateFile.aURL = toOUString(aURLNode.string_value()); if (aUpdateFile.aURL.isEmpty()) throw invalid_update_info(); - aUpdateFile.aHash = toOUString(aHashNode.string_value().str()); + aUpdateFile.aHash = toOUString(aHashNode.string_value()); aUpdateFile.nSize = static_cast<sal_uInt32>(aSizeNode.numeric_value()); return aUpdateFile; } @@ -452,7 +466,7 @@ update_info parse_response(const std::string& rResponse) { update_info aUpdateInfo; auto aMsgNode = aDocumentRoot.child("response"); - aUpdateInfo.aMessage = toOUString(aMsgNode.string_value().str()); + aUpdateInfo.aMessage = toOUString(aMsgNode.string_value()); return aUpdateInfo; } @@ -475,23 +489,23 @@ update_info parse_response(const std::string& rResponse) } orcus::json::node aLanguageNode = aDocumentRoot.child("languages"); - if (aUpdateNode.type() != orcus::json::node_t::object) + if (aLanguageNode.type() != orcus::json::node_t::object) { throw invalid_update_info(); } update_info aUpdateInfo; - aUpdateInfo.aFromBuildID = toOUString(aFromNode.string_value().str()); - aUpdateInfo.aSeeAlsoURL = toOUString(aSeeAlsoNode.string_value().str()); + aUpdateInfo.aFromBuildID = toOUString(aFromNode.string_value()); + aUpdateInfo.aSeeAlsoURL = toOUString(aSeeAlsoNode.string_value()); aUpdateInfo.aUpdateFile = parse_update_file(aUpdateNode); - std::vector<orcus::pstring> aLanguages = aLanguageNode.keys(); + std::vector<std::string_view> aLanguages = aLanguageNode.keys(); for (auto const& language : aLanguages) { language_file aLanguageFile; auto aLangEntry = aLanguageNode.child(language); - aLanguageFile.aLangCode = toOUString(language.str()); + aLanguageFile.aLangCode = toOUString(language); aLanguageFile.aUpdateFile = parse_update_file(aLangEntry); aUpdateInfo.aLanguageFiles.push_back(aLanguageFile); } @@ -546,6 +560,8 @@ std::string download_content(const OString& rURL, bool bFile, OUString& rHash) if (!curl) return std::string(); + ::InitCurl_easy(curl.get()); + curl_easy_setopt(curl.get(), CURLOPT_URL, rURL.getStr()); curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, kUserAgent); bool bUseProxy = false; @@ -562,11 +578,15 @@ std::string download_content(const OString& rURL, bool bFile, OUString& rHash) headerlist = curl_slist_append(headerlist, buf); curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headerlist); curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1); // follow redirects - // only allow redirect to http:// and https:// - curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + // only allow redirect to https:// +#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 85) + curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS_STR, "https"); +#else + curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); +#endif std::string response_body; - utl::TempFile aTempFile; + utl::TempFileNamed aTempFile; WriteDataFile aFile(aTempFile.GetStream(StreamMode::WRITE)); if (!bFile) { @@ -655,9 +675,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); @@ -743,6 +765,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(); } } } @@ -775,7 +805,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; @@ -783,7 +813,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; @@ -834,7 +864,7 @@ void Updater::log(const char* pMessage) OUString aUpdateLog = getUpdateInfoLog(); SvFileStream aLog(aUpdateLog, StreamMode::STD_READWRITE); aLog.Seek(aLog.Tell() + aLog.remainingSize()); // make sure we are at the end - aLog.WriteCharPtr(pMessage); + aLog.WriteOString(pMessage); } OUString Updater::getBuildID() |