Kaydet (Commit) 7db23b63 authored tarafından Armin Le Grand's avatar Armin Le Grand

profilesafe: Collect copies in single *.pack file

Enhanced helper classes for BackupFileHelper to
allow writing a stack of rescued last valid
configuration files to a single file package.
Added configuration values for enabling this and
defining the number of entries, added max entry
limitation. Using FileSize and CRC32 now to dectect
if config file did change. To make this work I added
sorting to writing the configuration so that with no
change the same configuration file is written.
Use std::vector for better mem performance for sorting,
defined static const for buffer size of manipulation,
prepare inflate/deflate usages. Fixes to setPos, warnings

Change-Id: Ib286e2a3f25b0085a1e3ae4f50c9ff1ff3a5dcf5
üst 9fa4eff9
...@@ -643,18 +643,22 @@ Components::~Components() ...@@ -643,18 +643,22 @@ Components::~Components()
(*i)->setAlive(false); (*i)->setAlive(false);
} }
// test backup of registrymodifications
static bool bFeatureSecureUserConfig(true);
if (!bExitWasCalled && if (!bExitWasCalled &&
bFeatureSecureUserConfig &&
ModificationTarget::File == modificationTarget_ && ModificationTarget::File == modificationTarget_ &&
!modificationFileUrl_.isEmpty()) !modificationFileUrl_.isEmpty())
{ {
static sal_uInt16 nNumCopies(5); // test backup of registrymodifications
comphelper::BackupFileHelper aBackupFileHelper(modificationFileUrl_, nNumCopies); sal_uInt16 nSecureUserConfigNumCopies(0);
// read configuration from soffice.ini
const bool bSecureUserConfig(comphelper::BackupFileHelper::getSecureUserConfig(nSecureUserConfigNumCopies));
aBackupFileHelper.tryPush(); if (bSecureUserConfig)
{
comphelper::BackupFileHelper aBackupFileHelper(modificationFileUrl_, nSecureUserConfigNumCopies);
aBackupFileHelper.tryPush();
}
} }
} }
......
...@@ -400,6 +400,16 @@ void writeNode( ...@@ -400,6 +400,16 @@ void writeNode(
} }
} }
// helpers to allow sorting of configmgr::Modifications::Node
typedef std::pair< const rtl::OUString, configmgr::Modifications::Node > ModNodePairEntry;
struct PairEntrySorter
{
bool operator() (const ModNodePairEntry* pValue1, const ModNodePairEntry* pValue2) const
{
return pValue1->first.compareTo(pValue2->first) < 0;
}
};
void writeModifications( void writeModifications(
Components & components, TempFile &handle, Components & components, TempFile &handle,
OUString const & parentPathRepresentation, OUString const & parentPathRepresentation,
...@@ -459,11 +469,27 @@ void writeModifications( ...@@ -459,11 +469,27 @@ void writeModifications(
OUString pathRep( OUString pathRep(
parentPathRepresentation + "/" + parentPathRepresentation + "/" +
Data::createSegment(node->getTemplateName(), nodeName)); Data::createSegment(node->getTemplateName(), nodeName));
for (const auto & i : modifications.children)
// copy configmgr::Modifications::Node's to a sortable list. Use pointers
// to just reference the data instead of copying it
std::vector< const ModNodePairEntry* > ModNodePairEntryVector;
ModNodePairEntryVector.reserve(modifications.children.size());
for (const auto& rCand : modifications.children)
{
ModNodePairEntryVector.push_back(&rCand);
}
// sort the list
std::sort(ModNodePairEntryVector.begin(), ModNodePairEntryVector.end(), PairEntrySorter());
// now use the list to write entries in sorted order
// instead of random as from the unordered map
for (const auto & i : ModNodePairEntryVector)
{ {
writeModifications( writeModifications(
components, handle, pathRep, node, i.first, components, handle, pathRep, node, i->first,
node->getMember(i.first), i.second); node->getMember(i->first), i->second);
} }
} }
} }
...@@ -601,9 +627,31 @@ void writeModFile( ...@@ -601,9 +627,31 @@ void writeModFile(
//TODO: Do not write back information about those removed items that did not //TODO: Do not write back information about those removed items that did not
// come from the .xcs/.xcu files, anyway (but had been added dynamically // come from the .xcs/.xcu files, anyway (but had been added dynamically
// instead): // instead):
for (Modifications::Node::Children::const_iterator j(
data.modifications.getRoot().children.begin()); // For profilesafemode it is necessary to detect changes in the
j != data.modifications.getRoot().children.end(); ++j) // registrymodifications file, this is done based on file size in bytes and crc32.
// Unfortunately this write is based on writing unordered map entries, which creates
// valid and semantically equal XML-Files, bubt with different crc32 checksums. For
// the future usage it will be preferrable to have easily comparable config files
// which is guaranteed by writing the entries in sorted order. Indeed with this change
// (and in the recursive writeModifications call) the same config files get written
// copy configmgr::Modifications::Node's to a sortable list. Use pointers
// to just reference the data instead of copying it
std::vector< const ModNodePairEntry* > ModNodePairEntryVector;
ModNodePairEntryVector.reserve(data.modifications.getRoot().children.size());
for (const auto& rCand : data.modifications.getRoot().children)
{
ModNodePairEntryVector.push_back(&rCand);
}
// sort the list
std::sort(ModNodePairEntryVector.begin(), ModNodePairEntryVector.end(), PairEntrySorter());
// now use the list to write entries in sorted order
// instead of random as from the unordered map
for (const auto& j : ModNodePairEntryVector)
{ {
writeModifications( writeModifications(
components, tmp, "", rtl::Reference< Node >(), j->first, components, tmp, "", rtl::Reference< Node >(), j->first,
......
...@@ -948,11 +948,13 @@ void Desktop::HandleBootstrapErrors( ...@@ -948,11 +948,13 @@ void Desktop::HandleBootstrapErrors(
else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN ) else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
{ {
// test restore of registrymodifications // test restore of registrymodifications
static bool bFeatureSecureUserConfig(true); sal_uInt16 nSecureUserConfigNumCopies(0);
static sal_uInt16 nNumCopies(5);
bool bFireOriginalError(true); bool bFireOriginalError(true);
if (bFeatureSecureUserConfig) // read configuration from soffice.ini
const bool bSecureUserConfig(comphelper::BackupFileHelper::getSecureUserConfig(nSecureUserConfigNumCopies));
if (bSecureUserConfig)
{ {
// try to asccess user layer configuration file // try to asccess user layer configuration file
OUString conf("${CONFIGURATION_LAYERS}"); OUString conf("${CONFIGURATION_LAYERS}");
...@@ -977,7 +979,7 @@ void Desktop::HandleBootstrapErrors( ...@@ -977,7 +979,7 @@ void Desktop::HandleBootstrapErrors(
if (!aUser.isEmpty()) if (!aUser.isEmpty())
{ {
comphelper::BackupFileHelper aBackupFileHelper(aUser, nNumCopies); comphelper::BackupFileHelper aBackupFileHelper(aUser, nSecureUserConfigNumCopies);
if (aBackupFileHelper.isPopPossible()) if (aBackupFileHelper.isPopPossible())
{ {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <comphelper/comphelperdllapi.h> #include <comphelper/comphelperdllapi.h>
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <osl/file.hxx> #include <osl/file.hxx>
#include <memory>
namespace comphelper namespace comphelper
{ {
...@@ -45,12 +46,11 @@ namespace comphelper ...@@ -45,12 +46,11 @@ namespace comphelper
{ {
private: private:
// internal data // internal data
const OUString& mrBaseURL; const OUString& mrBaseURL;
sal_uInt16 mnNumBackups; sal_uInt16 mnNumBackups;
OUString maBase; OUString maBase;
OUString maExt; OUString maName;
osl::File maBaseFile; OUString maExt;
bool mbBaseFileIsOpen;
// internal flag if _exit() was called already - a hint to evtl. // internal flag if _exit() was called already - a hint to evtl.
// not create copies of potentially not well-defined data. This // not create copies of potentially not well-defined data. This
...@@ -67,6 +67,10 @@ namespace comphelper ...@@ -67,6 +67,10 @@ namespace comphelper
public: public:
/** Constructor to handle Backups of the given file /** 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 * @param rBaseURL
* URL to an existing file that needs to be backed up * URL to an existing file that needs to be backed up
* *
...@@ -77,12 +81,21 @@ namespace comphelper ...@@ -77,12 +81,21 @@ namespace comphelper
* It is used in tryPush() and tryPop() calls to cleanup/ * It is used in tryPush() and tryPop() calls to cleanup/
* reduce the number of existing backups * reduce the number of existing backups
*/ */
BackupFileHelper(const OUString& rBaseURL, sal_uInt16 nNumBackups = 5); BackupFileHelper(
const OUString& rBaseURL,
sal_uInt16 nNumBackups = 5);
// allow to set flag when app had to call _exit() // allow to set static global flag when app had to call _exit()
static void setExitWasCalled(); static void setExitWasCalled();
static bool getExitWasCalled(); 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 /** 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 * last differs from the base file. It will then put a new verion
* on the 'stack' of copies and evtl. delete the oldest backup. * on the 'stack' of copies and evtl. delete the oldest backup.
...@@ -113,14 +126,9 @@ namespace comphelper ...@@ -113,14 +126,9 @@ namespace comphelper
private: private:
// internal helper methods // internal helper methods
rtl::OUString getName(sal_uInt16 n);
bool firstExists();
void pop();
void push();
bool isDifferentOrNew();
bool equalsBase(osl::File& rLastFile);
bool splitBaseURL(); bool splitBaseURL();
bool baseFileOpen(); bool baseFileExists();
rtl::OUString getName();
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment