summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/app.hxx4
-rw-r--r--desktop/source/app/app.cxx153
-rw-r--r--desktop/source/app/check_ext_deps.cxx19
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx2
-rw-r--r--desktop/source/deployment/inc/dp_misc.h3
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.cxx2
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx5
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx2
8 files changed, 164 insertions, 26 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index ea107e801ff2..25b635254f82 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -130,14 +130,12 @@ class Desktop : public Application
static sal_Bool isCrashReporterEnabled();
// first-start (ever) related methods
- static bool newInstallation();
-
static sal_Bool CheckExtensionDependencies();
static void DoRestartActionsIfNecessary( sal_Bool bQuickStart );
static void SetRestartState();
- void SynchronizeExtensionRepositories(bool force);
+ void SynchronizeExtensionRepositories();
void SetSplashScreenText( const ::rtl::OUString& rText );
void SetSplashScreenProgress( sal_Int32 );
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 991577f10dfa..6efc9f46acde 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -147,6 +147,145 @@ static sal_Bool _bCrashReporterEnabled = sal_True;
static ::rtl::OUString getBrandSharePreregBundledPathURL();
#endif
+namespace {
+
+void removeTree(OUString const & url) {
+ osl::Directory dir(url);
+ switch (dir.open()) {
+ case osl::FileBase::E_None:
+ break;
+ case osl::FileBase::E_NOENT:
+ return; //TODO: SAL_WARN if recursive
+ default:
+ throw css::uno::RuntimeException(
+ "cannot open directory " + url,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ for (;;) {
+ osl::DirectoryItem i;
+ osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
+ if (rc == osl::FileBase::E_NOENT) {
+ break;
+ }
+ if (rc != osl::FileBase::E_None) {
+ throw css::uno::RuntimeException(
+ "cannot iterate directory " + url,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ osl::FileStatus stat(
+ osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |
+ osl_FileStatus_Mask_FileURL);
+ if (i.getFileStatus(stat) != osl::FileBase::E_None) {
+ throw css::uno::RuntimeException(
+ "cannot stat in directory " + url,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (stat.getFileType() == osl::FileStatus::Directory) { //TODO: symlinks
+ removeTree(stat.getFileURL());
+ } else {
+ if (osl::File::remove(stat.getFileURL()) != osl::FileBase::E_None) {
+ throw css::uno::RuntimeException(
+ "cannot remove " + stat.getFileURL(),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+ }
+}
+
+// Remove any existing UserInstallation's user/extensions/bundled cache
+// remaining from old installations. Apparently due to the old
+// share/prereg/bundled mechanism (disabled since
+// 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying
+// share/prereg/bundled to avoid startup crashes"), that cache could contain
+// corrupted information (like a UNO component registered twice, which got
+// changed from active to passive registration in one LO version, but the
+// version of the corresponding bundled extension only incremented in a later LO
+// version). At least in theory, this function could be removed again once no
+// UserInstallation can be poisoned by that old share/prereg/bundled mechanism
+// any more. (But then Desktop::SynchronizeExtensionRepositories might need to
+// be revisited, see 2d2b19dea1ab401b1b4971ff5b12b87bb11fd666 "Force
+// ExtensionManager resync when the implementation changes" which effectively
+// got reverted again now. Now, a mismatch between a UserInstallation's
+// user/extensions/bundled and an installation's share/extensions will always be
+// detected here and lead to a removal of user/extensions/bundled, so that
+// Desktop::SynchronizeExtensionRepositories will then definitely resync
+// share/extensions.)
+void refreshBundledExtensionsDir() {
+ OUString buildId(
+ "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}");
+ rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure
+ OUString dir("$BUNDLED_EXTENSIONS_USER");
+ rtl::Bootstrap::expandMacros(dir); //TODO: detect failure
+ OUString url(dir + "/buildid");
+ osl::File f(url);
+ switch (f.open(osl_File_OpenFlag_Read)) {
+ case osl::FileBase::E_None:
+ {
+ rtl::ByteSequence s1;
+ osl::FileBase::RC rc = f.readLine(s1);
+ if (f.close() != osl::FileBase::E_None) {
+ SAL_WARN("desktop", "cannot close " + url + " after reading");
+ }
+ if (rc != osl::FileBase::E_None) {
+ throw css::uno::RuntimeException(
+ "cannot read from " + url,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ OUString s2(
+ reinterpret_cast< char const * >(s1.getConstArray()),
+ s1.getLength(), RTL_TEXTENCODING_ISO_8859_1);
+ // using ISO 8859-1 avoids any and all conversion errors; the
+ // content should only be a subset of ASCII, anyway
+ if (s2 == buildId) {
+ return;
+ }
+ break;
+ }
+ case osl::FileBase::E_NOENT:
+ break;
+ default:
+ throw css::uno::RuntimeException(
+ "cannot open " + url + " for reading",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ removeTree(dir);
+ switch (osl::Directory::createPath(dir)) {
+ case osl::FileBase::E_None:
+ case osl::FileBase::E_EXIST:
+ break;
+ default:
+ throw css::uno::RuntimeException(
+ "cannot create path " + dir,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create) !=
+ osl::FileBase::E_None)
+ {
+ throw css::uno::RuntimeException(
+ "cannot open " + url + " for writing",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ rtl::OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8));
+ // using UTF-8 avoids almost all conversion errors (and buildid
+ // containing single surrogate halves should never happen, anyway); the
+ // content should only be a subset of ASCII, anyway
+ sal_uInt64 n;
+ if (f.write(buf.getStr(), buf.getLength(), n) != osl::FileBase::E_None
+ || n != static_cast< sal_uInt32 >(buf.getLength()))
+ {
+ throw css::uno::RuntimeException(
+ "cannot write to " + url,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (f.close() != osl::FileBase::E_None) {
+ throw css::uno::RuntimeException(
+ "cannot close " + url + " after writing",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+}
+
// ----------------------------------------------------------------------------
ResMgr* Desktop::GetDesktopResManager()
@@ -625,6 +764,8 @@ void Desktop::Init()
RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
SetBootstrapStatus(BS_OK);
+ refreshBundledExtensionsDir();
+
// Check for lastsynchronized file for bundled extensions in the user directory
// and test if synchronzation is necessary!
#ifndef ANDROID
@@ -1616,14 +1757,10 @@ int Desktop::Main()
// Check if bundled or shared extensions were added /removed
// and process those extensions (has to be done before checking
// the extension dependencies!
- bool newInst = newInstallation();
- SynchronizeExtensionRepositories(newInst);
- if ( newInst )
- {
- bool bAbort = CheckExtensionDependencies();
- if ( bAbort )
- return EXIT_FAILURE;
- }
+ SynchronizeExtensionRepositories();
+ bool bAbort = CheckExtensionDependencies();
+ if ( bAbort )
+ return EXIT_FAILURE;
{
::comphelper::ComponentContext aContext( xSMgr );
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx
index 04b5cd75b1d6..dd01d9bbf4e5 100644
--- a/desktop/source/app/check_ext_deps.cxx
+++ b/desktop/source/app/check_ext_deps.cxx
@@ -347,9 +347,9 @@ static void impl_setNeedsCompatCheck()
// to check if we need checking the dependencies of the extensions again, we compare
// the build id of the office with the one of the last check
//------------------------------------------------------------------------------
-bool Desktop::newInstallation()
+static bool impl_needsCompatCheck()
{
- bool bNewInst = false;
+ bool bNeedsCheck = false;
rtl::OUString aLastCheckBuildID;
rtl::OUString aCurrentBuildID( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
rtl::Bootstrap::expandMacros( aCurrentBuildID );
@@ -371,18 +371,18 @@ bool Desktop::newInstallation()
result >>= aLastCheckBuildID;
if ( aLastCheckBuildID != aCurrentBuildID )
{
- bNewInst = true;
+ bNeedsCheck = true;
result <<= aCurrentBuildID;
pset->setPropertyValue( OUString("LastCompatibilityCheckID"), result );
Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
}
#ifdef DEBUG
- bNewInst = true;
+ bNeedsCheck = true;
#endif
}
catch (const com::sun::star::uno::Exception&) {}
- return bNewInst;
+ return bNeedsCheck;
}
//------------------------------------------------------------------------------
@@ -390,6 +390,11 @@ bool Desktop::newInstallation()
// When there are unresolved issues, we can't continue with startup
sal_Bool Desktop::CheckExtensionDependencies()
{
+ if (!impl_needsCompatCheck())
+ {
+ return false;
+ }
+
uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
bool bDependenciesValid = impl_checkDependencies( xContext );
@@ -408,10 +413,10 @@ sal_Bool Desktop::CheckExtensionDependencies()
return false;
}
-void Desktop::SynchronizeExtensionRepositories(bool force)
+void Desktop::SynchronizeExtensionRepositories()
{
RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories");
- dp_misc::syncRepositories( force, new SilentCommandEnv( this ) );
+ dp_misc::syncRepositories( new SilentCommandEnv( this ) );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
index 7795e3093cc3..29ded177175a 100644
--- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
@@ -1124,7 +1124,7 @@ void ExtensionCmdQueue::acceptLicense( const uno::Reference< deployment::XPackag
void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentContext > &xContext )
{
- dp_misc::syncRepositories( false, new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
+ dp_misc::syncRepositories( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
}
void ExtensionCmdQueue::stop()
diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h
index e9ad4a2b1d24..29fd14007d71 100644
--- a/desktop/source/deployment/inc/dp_misc.h
+++ b/desktop/source/deployment/inc/dp_misc.h
@@ -154,8 +154,7 @@ void TRACE(::rtl::OUString const & sText);
recently added or removed.
*/
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
-void syncRepositories(bool force,
- ::com::sun::star::uno::Reference<
+void syncRepositories(::com::sun::star::uno::Reference<
::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv);
}
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
index e5a16b7f6a0c..f2a6fce0a0ff 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.cxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -1223,7 +1223,7 @@ void ExtensionManager::reinstallDeployedExtensions(
xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv);
//We must sync here, otherwise we will get exceptions when extensions
//are removed.
- dp_misc::syncRepositories(false, xCmdEnv);
+ dp_misc::syncRepositories(xCmdEnv);
const uno::Sequence< Reference<deploy::XPackage> > extensions(
xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
index 9ed579fbb97c..b225db620b5c 100644
--- a/desktop/source/deployment/misc/dp_misc.cxx
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -591,7 +591,7 @@ void TRACE(::rtl::OString const & sText)
}
void syncRepositories(
- bool force, Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
{
OUString sDisable;
::rtl::Bootstrap::get( OUSTR( "DISABLE_EXTENSION_SYNCHRONIZATION" ), sDisable, OUString() );
@@ -602,8 +602,7 @@ void syncRepositories(
//synchronize shared before bundled otherewise there are
//more revoke and registration calls.
sal_Bool bModified = false;
- if (force
- || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))
+ if (needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))
|| needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
{
xExtensionManager =
diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
index 205e6ef82a31..2bd4d1b99214 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -432,7 +432,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main()
if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall"))
&& ! subCommand.equals(OUSTR("sync"))
&& ! dp_misc::office_is_running())
- dp_misc::syncRepositories(false, xCmdEnv);
+ dp_misc::syncRepositories(xCmdEnv);
if ( subcmd_add || subCommand == "remove" )
{