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.cxx9
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.hxx1
-rw-r--r--desktop/source/deployment/manager/dp_manager.cxx22
-rw-r--r--desktop/source/deployment/manager/dp_manager.h2
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx7
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx2
11 files changed, 176 insertions, 48 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index 06dc4c76d027..22866ef6b689 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -126,14 +126,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 c3152ee79805..84f60b8eef55 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -152,6 +152,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 >());
+ }
+ 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()
@@ -633,6 +772,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
@@ -1607,14 +1748,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 df358d791a69..2410c1ba8670 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 290df139a250..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));
@@ -1278,7 +1278,7 @@ void ExtensionManager::synchronizeBundledPrereg(
Reference<deploy::XPackageManager> xMgr =
xPackageManagerFactory->getPackageManager(OUSTR("bundled_prereg"));
- xMgr->synchronize(false, xAbortChannel, xCmdEnv);
+ xMgr->synchronize(xAbortChannel, xCmdEnv);
progressBundled.update(OUSTR("\n\n"));
uno::Sequence<Reference<deploy::XPackage> > extensions = xMgr->getDeployedPackages(
@@ -1317,7 +1317,6 @@ void ExtensionManager::synchronizeBundledPrereg(
}
sal_Bool ExtensionManager::synchronize(
- sal_Bool forceBundled,
Reference<task::XAbortChannel> const & xAbortChannel,
Reference<ucb::XCommandEnvironment> const & xCmdEnv )
throw (deploy::DeploymentException,
@@ -1334,13 +1333,13 @@ sal_Bool ExtensionManager::synchronize(
String sSynchronizingShared(StrSyncRepository::get());
sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared"));
dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
- bModified = getSharedRepository()->synchronize(false, xAbortChannel, xCmdEnv);
+ bModified = getSharedRepository()->synchronize(xAbortChannel, xCmdEnv);
progressShared.update(OUSTR("\n\n"));
String sSynchronizingBundled(StrSyncRepository::get());
sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
- bModified |= getBundledRepository()->synchronize(forceBundled, xAbortChannel, xCmdEnv);
+ bModified |= getBundledRepository()->synchronize(xAbortChannel, xCmdEnv);
progressBundled.update(OUSTR("\n\n"));
//Always determine the active extension. This is necessary for the
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
index 05fcde825fbf..800d91f437b6 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.hxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -193,7 +193,6 @@ public:
css::uno::RuntimeException);
virtual sal_Bool SAL_CALL synchronize(
- sal_Bool forceBundled,
css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
throw (css::deployment::DeploymentException,
diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx
index d7c8a2a3a154..a088f516c8a7 100644
--- a/desktop/source/deployment/manager/dp_manager.cxx
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -1248,7 +1248,6 @@ void PackageManagerImpl::reinstallDeployedPackages(
return m_readOnly;
}
bool PackageManagerImpl::synchronizeRemovedExtensions(
- bool force,
Reference<task::XAbortChannel> const & xAbortChannel,
Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
{
@@ -1272,19 +1271,15 @@ bool PackageManagerImpl::synchronizeRemovedExtensions(
if (bShared)
url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
- bool bRemoved = force;
-
+ bool bRemoved = false;
//Check if the URL to the extension is still the same
- if (!bRemoved)
- {
- ::ucbhelper::Content contentExtension;
+ ::ucbhelper::Content contentExtension;
- if (!create_ucb_content(
- &contentExtension, url,
- Reference<XCommandEnvironment>(), false))
- {
- bRemoved = true;
- }
+ if (!create_ucb_content(
+ &contentExtension, url,
+ Reference<XCommandEnvironment>(), false))
+ {
+ bRemoved = true;
}
//The folder is in the extension database, but it can still be deleted.
@@ -1469,7 +1464,6 @@ bool PackageManagerImpl::synchronizeAddedExtensions(
}
sal_Bool PackageManagerImpl::synchronize(
- sal_Bool force,
Reference<task::XAbortChannel> const & xAbortChannel,
Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
throw (css::deployment::DeploymentException,
@@ -1482,7 +1476,7 @@ sal_Bool PackageManagerImpl::synchronize(
if (m_context.equals(OUSTR("user")))
return bModified;
bModified |=
- synchronizeRemovedExtensions(force, xAbortChannel, xCmdEnv);
+ synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
return bModified;
diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h
index cb3cbe82357b..b88b51111062 100644
--- a/desktop/source/deployment/manager/dp_manager.h
+++ b/desktop/source/deployment/manager/dp_manager.h
@@ -82,7 +82,6 @@ class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper
css::uno::Reference<css::deployment::XPackage> const & package);
bool synchronizeRemovedExtensions(
- bool force,
css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
@@ -240,7 +239,6 @@ public:
throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL synchronize(
- sal_Bool force,
css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
throw (css::deployment::DeploymentException,
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
index 6f47e3df9c2c..ba9c98384c1d 100644
--- a/desktop/source/deployment/misc/dp_misc.cxx
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -546,7 +546,7 @@ void TRACE(::rtl::OUString 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() );
@@ -557,8 +557,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 =
@@ -568,7 +567,7 @@ void syncRepositories(
if (xExtensionManager.is())
{
bModified = xExtensionManager->synchronize(
- force, Reference<task::XAbortChannel>(), xCmdEnv);
+ Reference<task::XAbortChannel>(), xCmdEnv);
}
}
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" )
{