summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comphelper/source/misc/backupfilehelper.cxx640
-rw-r--r--desktop/source/app/app.cxx99
-rw-r--r--include/comphelper/backupfilehelper.hxx85
-rw-r--r--instsetoo_native/CustomTarget_setup.mk16
4 files changed, 625 insertions, 215 deletions
diff --git a/comphelper/source/misc/backupfilehelper.cxx b/comphelper/source/misc/backupfilehelper.cxx
index f45221351710..d5468f4cdce5 100644
--- a/comphelper/source/misc/backupfilehelper.cxx
+++ b/comphelper/source/misc/backupfilehelper.cxx
@@ -27,11 +27,12 @@
#include <zlib.h>
using namespace css;
-typedef std::shared_ptr< osl::File > FileSharedPtr;
static const sal_uInt32 BACKUP_FILE_HELPER_BLOCK_SIZE = 16384;
namespace
{
+ typedef std::shared_ptr< osl::File > FileSharedPtr;
+
OUString splitAtLastToken(const OUString& rSrc, sal_Unicode aToken, OUString& rRight)
{
const sal_Int32 nIndex(rSrc.lastIndexOf(aToken));
@@ -170,6 +171,41 @@ namespace
return false;
}
+ OUString createFileURL(const OUString& rURL, const OUString& rName, const OUString& rExt)
+ {
+ OUString aRetval;
+
+ if (!rURL.isEmpty() && !rName.isEmpty())
+ {
+ aRetval = rURL;
+ aRetval += "/";
+ aRetval += rName;
+
+ if (!rExt.isEmpty())
+ {
+ aRetval += ".";
+ aRetval += rExt;
+ }
+ }
+
+ return aRetval;
+ }
+
+ OUString createPackURL(const OUString& rURL, const OUString& rName)
+ {
+ OUString aRetval;
+
+ if (!rURL.isEmpty() && !rName.isEmpty())
+ {
+ aRetval = rURL;
+ aRetval += "/";
+ aRetval += rName;
+ aRetval += ".pack";
+ }
+
+ return aRetval;
+ }
+
bool fileExists(const OUString& rBaseURL)
{
if (!rBaseURL.isEmpty())
@@ -181,6 +217,51 @@ namespace
return false;
}
+
+ void scanDirsAndFiles(
+ const OUString& rDirURL,
+ std::set< OUString >& rDirs,
+ std::set< std::pair< OUString, OUString > >& rFiles)
+ {
+ if (!rDirURL.isEmpty())
+ {
+ osl::Directory aDirectory(rDirURL);
+
+ if (osl::FileBase::E_None == aDirectory.open())
+ {
+ osl::DirectoryItem aDirectoryItem;
+
+ while (osl::FileBase::E_None == aDirectory.getNextItem(aDirectoryItem))
+ {
+ osl::FileStatus aFileStatus(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName);
+
+ if (osl::FileBase::E_None == aDirectoryItem.getFileStatus(aFileStatus))
+ {
+ if (aFileStatus.isDirectory())
+ {
+ const OUString aFileName(aFileStatus.getFileName());
+
+ if (!aFileName.isEmpty())
+ {
+ rDirs.insert(aFileName);
+ }
+ }
+ else if (aFileStatus.isRegular())
+ {
+ OUString aFileName(aFileStatus.getFileName());
+ OUString aExtension;
+ aFileName = splitAtLastToken(aFileName, '.', aExtension);
+
+ if (!aFileName.isEmpty())
+ {
+ rFiles.insert(std::pair< OUString, OUString >(aFileName, aExtension));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
namespace
@@ -1176,61 +1257,134 @@ namespace comphelper
sal_uInt16 BackupFileHelper::mnMaxAllowedBackups = 10;
bool BackupFileHelper::mbExitWasCalled = false;
- BackupFileHelper::BackupFileHelper(
- const OUString& rBaseURL,
- sal_uInt16 nNumBackups)
- : mrBaseURL(rBaseURL),
- mnNumBackups(::std::min(::std::max(nNumBackups, sal_uInt16(1)), mnMaxAllowedBackups)),
- maBase(),
- maName(),
- maExt()
+ BackupFileHelper::BackupFileHelper()
+ : maInitialBaseURL(),
+ maUserConfigBaseURL(),
+ maRegModName(),
+ maExt(),
+ maDirs(),
+ maFiles(),
+ mnNumBackups(2),
+ mnMode(0),
+ mbActive(false),
+ mbExtensions(true),
+ mbCompress(true)
{
- }
+ OUString sTokenOut;
- void BackupFileHelper::setExitWasCalled()
- {
- mbExitWasCalled = true;
- }
+ // read configuration item 'SecureUserConfig' -> bool on/off
+ if (rtl::Bootstrap::get("SecureUserConfig", sTokenOut))
+ {
+ mbActive = sTokenOut.toBoolean();
+ }
- bool BackupFileHelper::getExitWasCalled()
- {
- return mbExitWasCalled;
- }
+ if (mbActive && rtl::Bootstrap::get("SecureUserConfigNumCopies", sTokenOut))
+ {
+ const sal_uInt16 nConfigNumCopies(static_cast<sal_uInt16>(sTokenOut.toUInt32()));
- bool BackupFileHelper::getSecureUserConfig(sal_uInt16& rnSecureUserConfigNumCopies)
- {
- // init to not active
- bool bRetval(false);
- rnSecureUserConfigNumCopies = 0;
- OUString sTokenOut;
+ // limit to range [1..mnMaxAllowedBackups]
+ mnNumBackups = ::std::min(::std::max(nConfigNumCopies, mnNumBackups), mnMaxAllowedBackups);
+ }
- if (rtl::Bootstrap::get("SecureUserConfig", sTokenOut))
+ if (mbActive && rtl::Bootstrap::get("SecureUserConfigMode", sTokenOut))
{
- bRetval = sTokenOut.toBoolean();
+ const sal_uInt16 nMode(static_cast<sal_uInt16>(sTokenOut.toUInt32()));
+
+ // limit to range [0..2]
+ mnMode = ::std::min(nMode, sal_uInt16(2));
}
- if (bRetval && rtl::Bootstrap::get("SecureUserConfigNumCopies", sTokenOut))
+ if (mbActive && rtl::Bootstrap::get("SecureUserConfigExtensions", sTokenOut))
{
- rnSecureUserConfigNumCopies = static_cast< sal_uInt16 >(sTokenOut.toUInt32());
+ mbExtensions = sTokenOut.toBoolean();
}
- return bRetval;
+ if (mbActive && rtl::Bootstrap::get("SecureUserConfigCompress", sTokenOut))
+ {
+ mbCompress = sTokenOut.toBoolean();
+ }
+
+ if (mbActive)
+ {
+ // try to access user layer configuration file URL, the one that
+ // points to registrymodifications.xcu
+ OUString conf("${CONFIGURATION_LAYERS}");
+ rtl::Bootstrap::expandMacros(conf);
+ const OUString aTokenUser("user:");
+ sal_Int32 nStart(conf.indexOf(aTokenUser));
+
+ if (-1 != nStart)
+ {
+ nStart += aTokenUser.getLength();
+ sal_Int32 nEnd(conf.indexOf(' ', nStart));
+
+ if (-1 == nEnd)
+ {
+ nEnd = conf.getLength();
+ }
+
+ maInitialBaseURL = conf.copy(nStart, nEnd - nStart);
+ maInitialBaseURL.startsWith("!", &maInitialBaseURL);
+ }
+
+ if (maInitialBaseURL.isEmpty())
+ {
+ // if not found, we are out of business
+ mbActive = false;
+ }
+ }
+
+ if (mbActive)
+ {
+ // split to path_to_user_config (maUserConfigBaseURL),
+ // name_of_regMod (maRegModName)
+ // and extension (maExt)
+ if (maUserConfigBaseURL.isEmpty() && !maInitialBaseURL.isEmpty())
+ {
+ // split URL at extension and at last path separator
+ maUserConfigBaseURL = splitAtLastToken(splitAtLastToken(maInitialBaseURL, '.', maExt), '/', maRegModName);
+ }
+
+ mbActive = !maUserConfigBaseURL.isEmpty() && !maRegModName.isEmpty();
+ }
}
- bool BackupFileHelper::tryPush(bool bCompress)
+ void BackupFileHelper::setExitWasCalled()
+ {
+ mbExitWasCalled = true;
+ }
+
+ bool BackupFileHelper::getExitWasCalled()
+ {
+ return mbExitWasCalled;
+ }
+
+ bool BackupFileHelper::tryPush()
{
bool bDidPush(false);
- if (splitBaseURL())
+ if (mbActive)
{
- // ensure directory existence
- osl::Directory::createPath(getPackDirName());
+ const OUString aPackURL(getPackURL());
- // try push for base file (usually registrymodifications)
- bDidPush = tryPush_basefile(bCompress);
+ // ensure dir and file vectors
+ fillDirFileInfo();
+
+ // proccess all files in question recursively
+ if (!maDirs.empty() || !maFiles.empty())
+ {
+ bDidPush = tryPush_Files(
+ maDirs,
+ maFiles,
+ maUserConfigBaseURL,
+ aPackURL);
+ }
// Try Push of ExtensionInfo
- bDidPush |= tryPush_extensionInfo(bCompress);
+ if (mbExtensions)
+ {
+ bDidPush |= tryPush_extensionInfo(aPackURL);
+ }
}
return bDidPush;
@@ -1240,13 +1394,28 @@ namespace comphelper
{
bool bPopPossible(false);
- if (splitBaseURL())
+ if (mbActive)
{
- // try for base file (usually registrymodifications)
- bPopPossible = isPopPossible_basefile();
+ const OUString aPackURL(getPackURL());
+
+ // ensure dir and file vectors
+ fillDirFileInfo();
+
+ // proccess all files in question recursively
+ if (!maDirs.empty() || !maFiles.empty())
+ {
+ bPopPossible = isPopPossible_files(
+ maDirs,
+ maFiles,
+ maUserConfigBaseURL,
+ aPackURL);
+ }
// try for ExtensionInfo
- bPopPossible |= isPopPossible_extensionInfo();
+ if (mbExtensions)
+ {
+ bPopPossible |= isPopPossible_extensionInfo(aPackURL);
+ }
}
return bPopPossible;
@@ -1256,53 +1425,116 @@ namespace comphelper
{
bool bDidPop(false);
- if (splitBaseURL())
+ if (mbActive)
{
- // try for base file (usually registrymodifications)
- bDidPop = tryPop_basefile();
+ const OUString aPackURL(getPackURL());
+
+ // ensure dir and file vectors
+ fillDirFileInfo();
+
+ // proccess all files in question recursively
+ if (!maDirs.empty() || !maFiles.empty())
+ {
+ bDidPop = tryPop_files(
+ maDirs,
+ maFiles,
+ maUserConfigBaseURL,
+ aPackURL);
+ }
// try for ExtensionInfo
- bDidPop |= tryPop_extensionInfo();
+ if (mbExtensions)
+ {
+ bDidPop |= tryPop_extensionInfo(aPackURL);
+ }
if (bDidPop)
{
// try removal of evtl. empty directory
- osl::Directory::remove(getPackDirName());
+ osl::Directory::remove(aPackURL);
}
}
return bDidPop;
}
- bool BackupFileHelper::splitBaseURL()
+ /////////////////// helpers ///////////////////////
+
+ const rtl::OUString BackupFileHelper::getPackURL() const
+ {
+ return rtl::OUString(maUserConfigBaseURL + "/pack");
+ }
+
+ /////////////////// file push helpers ///////////////////////
+
+ bool BackupFileHelper::tryPush_Files(
+ const std::set< OUString >& rDirs,
+ const std::set< std::pair< OUString, OUString > >& rFiles,
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
{
- if (maBase.isEmpty() && !mrBaseURL.isEmpty())
+ bool bDidPush(false);
+ osl::Directory::createPath(rTargetURL);
+
+ // proccess files
+ for (const auto& file : rFiles)
{
- // split URL at extension and at last path separator
- maBase = splitAtLastToken(splitAtLastToken(mrBaseURL, '.', maExt), '/', maName);
+ bDidPush |= tryPush_file(
+ rSourceURL,
+ rTargetURL,
+ file.first,
+ file.second);
}
- return !maBase.isEmpty() && !maName.isEmpty();
- }
+ // proccess dirs
+ for (const auto& dir : rDirs)
+ {
+ OUString aNewSourceURL(rSourceURL + "/" + dir);
+ OUString aNewTargetURL(rTargetURL + "/" + dir);
+ std::set< OUString > aNewDirs;
+ std::set< std::pair< OUString, OUString > > aNewFiles;
- const rtl::OUString BackupFileHelper::getPackDirName() const
- {
- return rtl::OUString(maBase + "/pack");
- }
+ scanDirsAndFiles(
+ aNewSourceURL,
+ aNewDirs,
+ aNewFiles);
- const rtl::OUString BackupFileHelper::getPackFileName(const rtl::OUString& rFileName) const
- {
- return rtl::OUString(getPackDirName() + "/" + rFileName + ".pack");
+ if (!aNewDirs.empty() || !aNewFiles.empty())
+ {
+ bDidPush |= tryPush_Files(
+ aNewDirs,
+ aNewFiles,
+ aNewSourceURL,
+ aNewTargetURL);
+ }
+ }
+
+ if (!bDidPush)
+ {
+ // try removal of evtl. empty directory
+ osl::Directory::remove(rTargetURL);
+ }
+
+ return bDidPush;
}
- bool BackupFileHelper::tryPush_basefile(bool bCompress)
+ bool BackupFileHelper::tryPush_file(
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL, // target dir without trailing '/'
+ const OUString& rName, // filename
+ const OUString& rExt // extension (or empty)
+ )
{
- if (fileExists(mrBaseURL))
+ const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
+
+ if (fileExists(aFileURL))
{
- PackedFile aPackedFile(getPackFileName(maName));
- FileSharedPtr aBaseFile(new osl::File(mrBaseURL));
+ const OUString aPackURL(createPackURL(rTargetURL, rName));
+ PackedFile aPackedFile(aPackURL);
+ FileSharedPtr aBaseFile(new osl::File(aFileURL));
- if (aPackedFile.tryPush(aBaseFile, bCompress))
+ if (aPackedFile.tryPush(aBaseFile, mbCompress))
{
// reduce to allowed number and flush
aPackedFile.tryReduceToNumBackups(mnNumBackups);
@@ -1315,37 +1547,66 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::tryPush_extensionInfo(bool bCompress)
+ /////////////////// file pop possibilities helper ///////////////////////
+
+ bool BackupFileHelper::isPopPossible_files(
+ const std::set< OUString >& rDirs,
+ const std::set< std::pair< OUString, OUString > >& rFiles,
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
{
- ExtensionInfo aExtensionInfo;
- OUString aTempURL;
- bool bRetval(false);
+ bool bPopPossible(false);
- // create current configuration and write to temp file - it exists until deleted
- if (aExtensionInfo.createTempFile(aTempURL))
+ // proccess files
+ for (const auto& file : rFiles)
{
- PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
- FileSharedPtr aBaseFile(new osl::File(aTempURL));
+ bPopPossible |= isPopPossible_file(
+ rSourceURL,
+ rTargetURL,
+ file.first,
+ file.second);
+ }
+
+ // proccess dirs
+ for (const auto& dir : rDirs)
+ {
+ OUString aNewSourceURL(rSourceURL + "/" + dir);
+ OUString aNewTargetURL(rTargetURL + "/" + dir);
+ std::set< OUString > aNewDirs;
+ std::set< std::pair< OUString, OUString > > aNewFiles;
+
+ scanDirsAndFiles(
+ aNewSourceURL,
+ aNewDirs,
+ aNewFiles);
- if (aPackedFile.tryPush(aBaseFile, bCompress))
+ if (!aNewDirs.empty() || !aNewFiles.empty())
{
- // reduce to allowed number and flush
- aPackedFile.tryReduceToNumBackups(mnNumBackups);
- aPackedFile.flush();
- bRetval = true;
+ bPopPossible |= isPopPossible_files(
+ aNewDirs,
+ aNewFiles,
+ aNewSourceURL,
+ aNewTargetURL);
}
}
- // delete temp file (in all cases)
- osl::File::remove(aTempURL);
- return bRetval;
+ return bPopPossible;
}
- bool BackupFileHelper::isPopPossible_basefile()
+ bool BackupFileHelper::isPopPossible_file(
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL, // target dir without trailing '/'
+ const OUString& rName, // filename
+ const OUString& rExt // extension (or empty)
+ )
{
- if (fileExists(mrBaseURL))
+ const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
+
+ if (fileExists(aFileURL))
{
- PackedFile aPackedFile(getPackFileName(maName));
+ const OUString aPackURL(createPackURL(rTargetURL, rName));
+ PackedFile aPackedFile(aPackURL);
return !aPackedFile.empty();
}
@@ -1353,20 +1614,73 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::isPopPossible_extensionInfo()
+ /////////////////// file pop helpers ///////////////////////
+
+ bool BackupFileHelper::tryPop_files(
+ const std::set< OUString >& rDirs,
+ const std::set< std::pair< OUString, OUString > >& rFiles,
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
{
- // extensionInfo always exists internally, no test needed
- PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
+ bool bDidPop(false);
- return !aPackedFile.empty();
+ // proccess files
+ for (const auto& file : rFiles)
+ {
+ bDidPop |= tryPop_file(
+ rSourceURL,
+ rTargetURL,
+ file.first,
+ file.second);
+ }
+
+ // proccess dirs
+ for (const auto& dir : rDirs)
+ {
+ OUString aNewSourceURL(rSourceURL + "/" + dir);
+ OUString aNewTargetURL(rTargetURL + "/" + dir);
+ std::set< OUString > aNewDirs;
+ std::set< std::pair< OUString, OUString > > aNewFiles;
+
+ scanDirsAndFiles(
+ aNewSourceURL,
+ aNewDirs,
+ aNewFiles);
+
+ if (!aNewDirs.empty() || !aNewFiles.empty())
+ {
+ bDidPop |= tryPop_files(
+ aNewDirs,
+ aNewFiles,
+ aNewSourceURL,
+ aNewTargetURL);
+ }
+ }
+
+ if (bDidPop)
+ {
+ // try removal of evtl. empty directory
+ osl::Directory::remove(rTargetURL);
+ }
+
+ return bDidPop;
}
- bool BackupFileHelper::tryPop_basefile()
+ bool BackupFileHelper::tryPop_file(
+ const OUString& rSourceURL, // source dir without trailing '/'
+ const OUString& rTargetURL, // target dir without trailing '/'
+ const OUString& rName, // filename
+ const OUString& rExt // extension (or empty)
+ )
{
- if (fileExists(mrBaseURL))
+ const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
+
+ if (fileExists(aFileURL))
{
- // try Pop for base file (usually registrymodifications)
- PackedFile aPackedFile(getPackFileName(maName));
+ // try Pop for base file
+ const OUString aPackURL(createPackURL(rTargetURL, rName));
+ PackedFile aPackedFile(aPackURL);
if (!aPackedFile.empty())
{
@@ -1385,8 +1699,8 @@ namespace comphelper
{
// copy over existing file by first deleting original
// and moving the temp file to old original
- osl::File::remove(mrBaseURL);
- osl::File::move(aTempURL, mrBaseURL);
+ osl::File::remove(aFileURL);
+ osl::File::move(aTempURL, aFileURL);
// reduce to allowed number and flush
aPackedFile.tryReduceToNumBackups(mnNumBackups);
@@ -1404,10 +1718,55 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::tryPop_extensionInfo()
+ /////////////////// ExtensionInfo helpers ///////////////////////
+
+ bool BackupFileHelper::tryPush_extensionInfo(
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
+ {
+ ExtensionInfo aExtensionInfo;
+ OUString aTempURL;
+ bool bRetval(false);
+
+ // create current configuration and write to temp file - it exists until deleted
+ if (aExtensionInfo.createTempFile(aTempURL))
+ {
+ const OUString aPackURL(createPackURL(rTargetURL, "ExtensionInfo"));
+ PackedFile aPackedFile(aPackURL);
+ FileSharedPtr aBaseFile(new osl::File(aTempURL));
+
+ if (aPackedFile.tryPush(aBaseFile, mbCompress))
+ {
+ // reduce to allowed number and flush
+ aPackedFile.tryReduceToNumBackups(mnNumBackups);
+ aPackedFile.flush();
+ bRetval = true;
+ }
+ }
+
+ // delete temp file (in all cases)
+ osl::File::remove(aTempURL);
+ return bRetval;
+ }
+
+ bool BackupFileHelper::isPopPossible_extensionInfo(
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
+ {
+ // extensionInfo always exists internally, no test needed
+ const OUString aPackURL(createPackURL(rTargetURL, "ExtensionInfo"));
+ PackedFile aPackedFile(aPackURL);
+
+ return !aPackedFile.empty();
+ }
+
+ bool BackupFileHelper::tryPop_extensionInfo(
+ const OUString& rTargetURL // target dir without trailing '/'
+ )
{
// extensionInfo always exists internally, no test needed
- PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
+ const OUString aPackURL(createPackURL(rTargetURL, "ExtensionInfo"));
+ PackedFile aPackedFile(aPackURL);
if (!aPackedFile.empty())
{
@@ -1436,7 +1795,9 @@ namespace comphelper
aCurrentExtensionInfo.createCurrent();
- // now we have loaded and current ExtensionInfo and may react on differences
+ // now we have loaded last_working (aLoadedExtensionInfo) and
+ // current (aCurrentExtensionInfo) ExtensionInfo and may react on
+ // differences by de/activating these as needed
@@ -1460,6 +1821,95 @@ namespace comphelper
return false;
}
+
+ /////////////////// FileDirInfo helpers ///////////////////////
+
+ void BackupFileHelper::fillDirFileInfo()
+ {
+ if (!maDirs.empty() || !maFiles.empty())
+ {
+ // already done
+ return;
+ }
+
+ // fill dir and file info list to work with dependent on work mode
+ switch (mnMode)
+ {
+ case 0:
+ {
+ // add registrymodifications (the orig file in maInitialBaseURL)
+ maFiles.insert(std::pair< OUString, OUString >(maRegModName, maExt));
+ break;
+ }
+ case 1:
+ {
+ // add registrymodifications (the orig file in maInitialBaseURL)
+ maFiles.insert(std::pair< OUString, OUString >(maRegModName, maExt));
+
+ // Add a selection of dirs containing User-Defined and thus
+ // valuable configuration information (see https://wiki.documentfoundation.org/UserProfile).
+ // This is clearly discussable in every single point and may be adapted/corrected
+ // over time. Main focus is to secure User-Defined/adapted values
+
+ // User-defined substitution table (Tools/AutoCorrect)
+ maDirs.insert("autocorr");
+
+ // User-Defined AutoText (Edit/AutoText)
+ maDirs.insert("autotext");
+
+ // User-defined Macros
+ maDirs.insert("basic");
+
+ // User-adapted toolbars for modules
+ maDirs.insert("config");
+
+ // Initial and User-defined Databases
+ maDirs.insert("database");
+
+ // User-Defined Galleries
+ maDirs.insert("gallery");
+
+ // most part of registry files
+ maDirs.insert("registry");
+
+ // User-Defined Scripts
+ maDirs.insert("Scripts");
+
+ // Template files
+ maDirs.insert("template");
+
+ // Custom Dictionaries
+ maDirs.insert("wordbook");
+
+ // Questionable - where and how is Extension stuff held and how
+ // does this interact with enabled/disabled states which are extra handled?
+ // Keep out of business until deeper evaluated
+ // maDirs.insert("extensions");
+ // maDirs.insert("uno-packages");
+ break;
+ }
+ case 2:
+ {
+ // whole directory. To do so, scan directory and exclude some dirs
+ // from which we know they do not need to be secured explicitely. This
+ // should alrteady include registrymodifications, too.
+ scanDirsAndFiles(
+ maUserConfigBaseURL,
+ maDirs,
+ maFiles);
+
+ // not really needed, can be abandoned
+ maDirs.erase("psprint");
+
+ // not really needed, can be abandoned
+ maDirs.erase("store");
+
+ // not really needed, can be abandoned
+ maDirs.erase("temp");
+ break;
+ }
+ }
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index b9e5401c7246..cd3fbfa96326 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -818,42 +818,6 @@ OUString Desktop::CreateErrorMsgString(
return MakeStartupErrorMessage( aMsg );
}
-// helper method to test if SecureUserConfig is active, detect the num copies
-// and extract the User's config directory URL
-bool testSecureUserConfigActive(sal_uInt16& rnSecureUserConfigNumCopies, OUString& raUserConfigDir)
-{
- // read configuration from soffice.ini
- if(comphelper::BackupFileHelper::getSecureUserConfig(rnSecureUserConfigNumCopies))
- {
- // try to asccess user layer configuration file
- OUString conf("${CONFIGURATION_LAYERS}");
- rtl::Bootstrap::expandMacros(conf);
- const OUString aTokenUser("user:");
- sal_Int32 nStart(conf.indexOf(aTokenUser));
-
- if (-1 != nStart)
- {
- nStart += aTokenUser.getLength();
- sal_Int32 nEnd(conf.indexOf(' ', nStart));
-
- if (-1 == nEnd)
- {
- nEnd = conf.getLength();
- }
-
- raUserConfigDir = conf.copy(nStart, nEnd - nStart);
- raUserConfigDir.startsWith("!", &raUserConfigDir);
- }
-
- if (!raUserConfigDir.isEmpty())
- {
- return true;
- }
- }
-
- return false;
-}
-
void Desktop::HandleBootstrapErrors(
BootstrapError aBootstrapError, OUString const & aErrorMessage )
{
@@ -987,43 +951,37 @@ void Desktop::HandleBootstrapErrors(
}
else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
{
- // test if SecureUserConfig is active
- sal_uInt16 nSecureUserConfigNumCopies(0);
- OUString aUserConfigDir;
bool bFireOriginalError(true);
+ comphelper::BackupFileHelper aBackupFileHelper;
- if (testSecureUserConfigActive(nSecureUserConfigNumCopies, aUserConfigDir))
+ // crerate BackupFileHelper and check if active and if pop is possible
+ if (aBackupFileHelper.isPopPossible())
{
- comphelper::BackupFileHelper aBackupFileHelper(aUserConfigDir, nSecureUserConfigNumCopies);
+ // for linux (and probably others?) we need to instantiate XDesktop2
+ // to be able to open a *.ui-file based dialog, so do this here locally.
+ // does no harm on win, so better always do this (in error case only anyways)
+ Reference< XComponentContext > xLocalContext = ::comphelper::getProcessComponentContext();
+ Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xLocalContext);
+
+ ScopedVclPtrInstance< MessageDialog > aQueryShouldRestore(
+ Application::GetDefDialogParent(),
+ "QueryTryToRestoreConfigurationDialog",
+ "desktop/ui/querytrytorestoreconfigurationdialog.ui");
- if (aBackupFileHelper.isPopPossible())
+ if (aQueryShouldRestore.get())
{
- // for linux (and probably others?) we need to instantiate XDesktop2
- // to be able to open a *.ui-file based dialog, so do this here locally.
- // does no harm on win, so better always do this (in error case only anyways)
- Reference< XComponentContext > xLocalContext = ::comphelper::getProcessComponentContext();
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xLocalContext);
-
- ScopedVclPtrInstance< MessageDialog > aQueryShouldRestore(
- Application::GetDefDialogParent(),
- "QueryTryToRestoreConfigurationDialog",
- "desktop/ui/querytrytorestoreconfigurationdialog.ui");
-
- if (aQueryShouldRestore.get())
+ if (!aErrorMessage.isEmpty())
{
- if (!aErrorMessage.isEmpty())
- {
- OUString aPrimaryText(aQueryShouldRestore->get_primary_text());
+ OUString aPrimaryText(aQueryShouldRestore->get_primary_text());
- aPrimaryText += "\n(\"" + aErrorMessage + "\")";
- aQueryShouldRestore->set_primary_text(aPrimaryText);
- }
+ aPrimaryText += "\n(\"" + aErrorMessage + "\")";
+ aQueryShouldRestore->set_primary_text(aPrimaryText);
+ }
- if (RET_YES == aQueryShouldRestore->Execute())
- {
- aBackupFileHelper.tryPop();
- bFireOriginalError = false;
- }
+ if (RET_YES == aQueryShouldRestore->Execute())
+ {
+ aBackupFileHelper.tryPop();
+ bFireOriginalError = false;
}
}
}
@@ -1863,16 +1821,9 @@ int Desktop::doShutdown()
// Test if SecureUserConfig is active. If yes and we are at this point, regular shutdown
// is in progress and the currently used configuration was working. Try to secure this
// working configuration for later eventually necessary restores
- sal_uInt16 nSecureUserConfigNumCopies(0);
- OUString aUserConfigDir;
+ comphelper::BackupFileHelper aBackupFileHelper;
- if (testSecureUserConfigActive(nSecureUserConfigNumCopies, aUserConfigDir))
- {
- // try to push registrymodifications.xcu
- comphelper::BackupFileHelper aBackupFileHelper(aUserConfigDir, nSecureUserConfigNumCopies);
-
- aBackupFileHelper.tryPush();
- }
+ aBackupFileHelper.tryPush();
}
// The acceptors in the AcceptorMap must be released (in DeregisterServices)
diff --git a/include/comphelper/backupfilehelper.hxx b/include/comphelper/backupfilehelper.hxx
index 503bfc672549..b1913f901822 100644
--- a/include/comphelper/backupfilehelper.hxx
+++ b/include/comphelper/backupfilehelper.hxx
@@ -16,6 +16,7 @@
#include <rtl/ustring.hxx>
#include <osl/file.hxx>
#include <memory>
+#include <set>
namespace comphelper
{
@@ -59,11 +60,20 @@ namespace comphelper
{
private:
// internal data
- const OUString& mrBaseURL;
- sal_uInt16 mnNumBackups;
- OUString maBase;
- OUString maName;
- OUString maExt;
+ OUString maInitialBaseURL;
+ OUString maUserConfigBaseURL;
+ OUString maRegModName;
+ OUString maExt;
+
+ std::set< OUString > maDirs;
+ std::set< std::pair< OUString, OUString > > maFiles;
+
+ sal_uInt16 mnNumBackups;
+ sal_uInt16 mnMode;
+
+ bool mbActive;
+ bool mbExtensions;
+ bool mbCompress;
// internal flag if _exit() was called already - a hint to evtl.
// not create copies of potentially not well-defined data. This
@@ -78,51 +88,26 @@ namespace comphelper
static sal_uInt16 mnMaxAllowedBackups;
public:
- /** Constructor to handle Backups of the given file
- *
- * @param rxContext
- * ComponentContext to use internally; needs to be handed
- * over due to usages after DeInit() and thus no access
- * anymore using comphelper::getProcessComponentContext()
- * @param rBaseURL
- * URL to an existing file that needs to be backed up
- *
- * @param nNumBackups
- * Specifies the maximum number of backups to allow for
- * the file. This value gets truncated to [1..max] where
- * max currently is 10 and defined in the implementation.
- * It is used in tryPush() and tryPop() calls to cleanup/
- * reduce the number of existing backups
+ /** Constructor to handle Backups of the given file, will internally
+ * detect configuration values and URL to initial registrymodifications
+ * and thus the User configuration directory
*/
- BackupFileHelper(
- const OUString& rBaseURL,
- sal_uInt16 nNumBackups = 5);
+ BackupFileHelper();
// allow to set static global flag when app had to call _exit()
static void setExitWasCalled();
static bool getExitWasCalled();
- // static helper to read config values - these are derived from
- // soffice.ini due to cui not being available in all cases. The
- // boolean SecureUserConfig is returned.
- // Default for SecureUserConfig is false
- // Default for SecureUserConfigNumCopies is 0 (zero)
- static bool getSecureUserConfig(sal_uInt16& rnSecureUserConfigNumCopies);
-
/** tries to create a new backup, if there is none yet, or if the
* last differs from the base file. It will then put a new verion
* on the 'stack' of copies and evtl. delete the oldest backup.
* Also may cleanup older backups when NumBackups given in the
* constructor has changed.
*
- * @param bCompress
- * Defines if the new backup will be compressed when
- * added. Default is true
- *
* @return bool
* returns true if a new backup was actually created
*/
- bool tryPush(bool bCompress = true);
+ bool tryPush();
/** finds out if a restore is possible
*
@@ -143,15 +128,27 @@ namespace comphelper
private:
// internal helper methods
- bool splitBaseURL();
- const rtl::OUString getPackDirName() const;
- const rtl::OUString getPackFileName(const rtl::OUString& rFileName) const;
- bool tryPush_basefile(bool bCompress);
- bool tryPush_extensionInfo(bool bCompress);
- bool isPopPossible_basefile();
- bool isPopPossible_extensionInfo();
- bool tryPop_basefile();
- bool tryPop_extensionInfo();
+ const rtl::OUString getPackURL() const;
+
+ // file push helpers
+ bool tryPush_Files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, const OUString& rSourceURL, const OUString& rTargetURL);
+ bool tryPush_file(const OUString& rSourceURL, const OUString& rTargetURL, const OUString& rName, const OUString& rExt);
+
+ // file pop possibilities helper
+ bool isPopPossible_files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, const OUString& rSourceURL, const OUString& rTargetURL);
+ static bool isPopPossible_file(const OUString& rSourceURL, const OUString& rTargetURL, const OUString& rName, const OUString& rExt);
+
+ // file pop helpers
+ bool tryPop_files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, const OUString& rSourceURL, const OUString& rTargetURL);
+ bool tryPop_file(const OUString& rSourceURL, const OUString& rTargetURL, const OUString& rName, const OUString& rExt);
+
+ // ExtensionInfo helpers
+ bool tryPush_extensionInfo(const OUString& rTargetURL);
+ static bool isPopPossible_extensionInfo(const OUString& rTargetURL);
+ bool tryPop_extensionInfo(const OUString& rTargetURL);
+
+ // FileDirInfo helpers
+ void fillDirFileInfo();
};
}
diff --git a/instsetoo_native/CustomTarget_setup.mk b/instsetoo_native/CustomTarget_setup.mk
index 26fc42792a03..5ce472632cdf 100644
--- a/instsetoo_native/CustomTarget_setup.mk
+++ b/instsetoo_native/CustomTarget_setup.mk
@@ -104,7 +104,16 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
) > $@
# for release-builds (building installers) adjust values in openoffice.lst.in
-# Added 'SecureUserConfig' flags to enable and safe three registrymodifications.xcu versions
+# Added 'SecureUserConfig' flags to enable and safe user config files
+# SecureUserConfig : boolean - switches securing on/off - default false
+# SecureUserConfigCompress : boolean - defines if backup data will be compressed - default true
+# SecureUserConfigNumCopies : integer - defines how many compressed copies of saved content will be kept - default 2
+# SecureUserConfigMode: integer - defines what to secure, default is 0
+# 0 : only registrymodifications.xcu
+# 1 : a selected amount of user-defined configs
+# 2 : everything in the user config directory
+# SecureUserConfigExtensions: boolean - defines to also safe the extension configuration (which extensions
+# are installed, which are activated) - default is true
$(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_rcfile,soffice) :
$(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),ECH,1)
( \
@@ -120,7 +129,10 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
&& echo 'ProgressTextColor=255,255,255' \
&& echo 'URE_BOOTSTRAP=$${ORIGIN}/$(call gb_Helper_get_rcfile,fundamental)' \
&& echo 'SecureUserConfig=true' \
- && echo 'SecureUserConfigNumCopies=3' \
+ && echo 'SecureUserConfigCompress=true' \
+ && echo 'SecureUserConfigNumCopies=2' \
+ && echo 'SecureUserConfigMode=0' \
+ && echo 'SecureUserConfigExtensions=true' \
) > $@
$(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_rcfile,uno) :