summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/source/misc/backupfilehelper.cxx766
1 files changed, 648 insertions, 118 deletions
diff --git a/comphelper/source/misc/backupfilehelper.cxx b/comphelper/source/misc/backupfilehelper.cxx
index 8b842deee4d9..f45221351710 100644
--- a/comphelper/source/misc/backupfilehelper.cxx
+++ b/comphelper/source/misc/backupfilehelper.cxx
@@ -8,15 +8,25 @@
*/
#include <sal/config.h>
-
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/deployment/XPackage.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/deployment/XExtensionManager.hpp>
+#include <com/sun/star/task/XAbortChannel.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/deployment/ExtensionManager.hpp>
#include <rtl/ustring.hxx>
#include <rtl/bootstrap.hxx>
#include <comphelper/backupfilehelper.hxx>
#include <rtl/crc.h>
#include <algorithm>
#include <deque>
+#include <vector>
#include <zlib.h>
+using namespace css;
typedef std::shared_ptr< osl::File > FileSharedPtr;
static const sal_uInt32 BACKUP_FILE_HELPER_BLOCK_SIZE = 16384;
@@ -84,6 +94,403 @@ namespace
return nCrc32;
}
+
+ bool read_sal_uInt32(FileSharedPtr& rFile, sal_uInt32& rTarget)
+ {
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseRead(0);
+
+ // read rTarget
+ if (osl::File::E_None == rFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
+ {
+ rTarget = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool write_sal_uInt32(oslFileHandle& rHandle, sal_uInt32 nSource)
+ {
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseWritten(0);
+
+ // write nSource
+ aArray[0] = sal_uInt8((nSource & 0xff000000) >> 24);
+ aArray[1] = sal_uInt8((nSource & 0x00ff0000) >> 16);
+ aArray[2] = sal_uInt8((nSource & 0x0000ff00) >> 8);
+ aArray[3] = sal_uInt8(nSource & 0x000000ff);
+
+ if (osl_File_E_None == osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool read_OString(FileSharedPtr& rFile, OString& rTarget)
+ {
+ sal_uInt32 nLength(0);
+
+ if (!read_sal_uInt32(rFile, nLength))
+ {
+ return false;
+ }
+
+ std::vector< sal_Char > aTarget(nLength);
+ sal_uInt64 nBaseRead(0);
+
+ // read rTarget
+ if (osl::File::E_None == rFile->read(static_cast<void*>(&aTarget[0]), nLength, nBaseRead) && nLength == nBaseRead)
+ {
+ rTarget = OString(&aTarget[0], static_cast< sal_Int32 >(nLength));
+ return true;
+ }
+
+ return false;
+ }
+
+ bool write_OString(oslFileHandle& rHandle, const OString& rSource)
+ {
+ const sal_uInt32 nLength(rSource.getLength());
+
+ if (!write_sal_uInt32(rHandle, nLength))
+ {
+ return false;
+ }
+
+ sal_uInt64 nBaseWritten(0);
+
+ if (osl_File_E_None == osl_writeFile(rHandle, static_cast<const void*>(rSource.getStr()), nLength, &nBaseWritten) && nLength == nBaseWritten)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool fileExists(const OUString& rBaseURL)
+ {
+ if (!rBaseURL.isEmpty())
+ {
+ FileSharedPtr aBaseFile(new osl::File(rBaseURL));
+
+ return (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read));
+ }
+
+ return false;
+ }
+}
+
+namespace
+{
+ enum PackageState { REGISTERED, NOT_REGISTERED, AMBIGUOUS, NOT_AVAILABLE };
+
+ class ExtensionInfoEntry
+ {
+ private:
+ PackageState meState; // REGISTERED, NOT_REGISTERED, AMBIGUOUS, NOT_AVAILABLE
+ OString maRepositoryName; // user|shared|bundled
+ OString maName;
+ OString maIdentifier;
+ OString maVersion;
+
+ public:
+ ExtensionInfoEntry()
+ : meState(NOT_AVAILABLE),
+ maRepositoryName(),
+ maName(),
+ maIdentifier(),
+ maVersion()
+ {
+ }
+
+ ExtensionInfoEntry(const uno::Reference< deployment::XPackage >& rxPackage)
+ : meState(NOT_AVAILABLE),
+ maRepositoryName(OUStringToOString(rxPackage->getRepositoryName(), RTL_TEXTENCODING_ASCII_US)),
+ maName(OUStringToOString(rxPackage->getName(), RTL_TEXTENCODING_ASCII_US)),
+ maIdentifier(OUStringToOString(rxPackage->getIdentifier().Value, RTL_TEXTENCODING_ASCII_US)),
+ maVersion(OUStringToOString(rxPackage->getVersion(), RTL_TEXTENCODING_ASCII_US))
+ {
+ const beans::Optional< beans::Ambiguous< sal_Bool > > option(
+ rxPackage->isRegistered(uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >()));
+
+ if (option.IsPresent)
+ {
+ ::beans::Ambiguous< sal_Bool > const& reg = option.Value;
+
+ if (reg.IsAmbiguous)
+ {
+ meState = AMBIGUOUS;
+ }
+ else
+ {
+ meState = reg.Value ? REGISTERED : NOT_REGISTERED;
+ }
+ }
+ else
+ {
+ meState = NOT_AVAILABLE;
+ }
+ }
+
+ bool operator<(const ExtensionInfoEntry& rComp) const
+ {
+ if (0 == maRepositoryName.compareTo(rComp.maRepositoryName))
+ {
+ if (0 == maName.compareTo(rComp.maName))
+ {
+ if (0 == maVersion.compareTo(rComp.maVersion))
+ {
+ if (0 == maIdentifier.compareTo(rComp.maIdentifier))
+ {
+ return meState < rComp.meState;
+ }
+ else
+ {
+ return 0 > maIdentifier.compareTo(rComp.maIdentifier);
+ }
+ }
+ else
+ {
+ return 0 > maVersion.compareTo(rComp.maVersion);
+ }
+ }
+ else
+ {
+ return 0 > maName.compareTo(rComp.maName);
+ }
+ }
+ else
+ {
+ return 0 > maRepositoryName.compareTo(rComp.maRepositoryName);
+ }
+ }
+
+ bool read_entry(FileSharedPtr& rFile)
+ {
+ // read meState
+ sal_uInt32 nState(0);
+
+ if (read_sal_uInt32(rFile, nState))
+ {
+ meState = static_cast< PackageState >(nState);
+ }
+ else
+ {
+ return false;
+ }
+
+ // read maRepositoryName;
+ if (!read_OString(rFile, maRepositoryName))
+ {
+ return false;
+ }
+
+ // read maName;
+ if (!read_OString(rFile, maName))
+ {
+ return false;
+ }
+
+ // read maIdentifier;
+ if (!read_OString(rFile, maIdentifier))
+ {
+ return false;
+ }
+
+ // read maVersion;
+ if (!read_OString(rFile, maVersion))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool write_entry(oslFileHandle& rHandle) const
+ {
+ // write meState
+ const sal_uInt32 nState(meState);
+
+ if (!write_sal_uInt32(rHandle, nState))
+ {
+ return false;
+ }
+
+ // write maRepositoryName
+ if (!write_OString(rHandle, maRepositoryName))
+ {
+ return false;
+ }
+
+ // write maName;
+ if (!write_OString(rHandle, maName))
+ {
+ return false;
+ }
+
+ // write maIdentifier;
+ if (!write_OString(rHandle, maIdentifier))
+ {
+ return false;
+ }
+
+ // write maVersion;
+ if (!write_OString(rHandle, maVersion))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ typedef ::std::vector< ExtensionInfoEntry > ExtensionInfoEntryVector;
+
+ class ExtensionInfo
+ {
+ private:
+ ExtensionInfoEntryVector maEntries;
+
+ public:
+ ExtensionInfo()
+ : maEntries()
+ {
+ }
+
+ void reset()
+ {
+ // clear all data
+ maEntries.clear();
+ }
+
+ void createCurrent()
+ {
+ // clear all data
+ reset();
+
+ // create content from current extension configuration
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< deployment::XExtensionManager > m_xExtensionManager = deployment::ExtensionManager::get(xContext);
+
+ try
+ {
+ xAllPackages = m_xExtensionManager->getAllExtensions(uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >());
+ }
+ catch (const deployment::DeploymentException &)
+ {
+ return;
+ }
+ catch (const ucb::CommandFailedException &)
+ {
+ return;
+ }
+ catch (const ucb::CommandAbortedException &)
+ {
+ return;
+ }
+ catch (const lang::IllegalArgumentException & e)
+ {
+ throw uno::RuntimeException(e.Message, e.Context);
+ }
+
+ for (sal_Int32 i = 0; i < xAllPackages.getLength(); ++i)
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for (sal_Int32 j = 0; j < xPackageList.getLength(); ++j)
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+
+ if (xPackage.is())
+ {
+ maEntries.push_back(ExtensionInfoEntry(xPackage));
+ }
+ }
+ }
+
+ if (!maEntries.empty())
+ {
+ // sort the list
+ std::sort(maEntries.begin(), maEntries.end());
+ }
+ }
+
+ bool read_entries(FileSharedPtr& rFile)
+ {
+ // read NumExtensionEntries
+ sal_uInt32 nExtEntries(0);
+
+ if (!read_sal_uInt32(rFile, nExtEntries))
+ {
+ return false;
+ }
+
+ for (sal_uInt32 a(0); a < nExtEntries; a++)
+ {
+ ExtensionInfoEntry aNewEntry;
+
+ if (aNewEntry.read_entry(rFile))
+ {
+ maEntries.push_back(aNewEntry);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool write_entries(oslFileHandle& rHandle) const
+ {
+ const sal_uInt32 nExtEntries(maEntries.size());
+
+ if (!write_sal_uInt32(rHandle, nExtEntries))
+ {
+ return false;
+ }
+
+ for (const auto& a : maEntries)
+ {
+ if (!a.write_entry(rHandle))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool createTempFile(OUString& rTempFileName)
+ {
+ oslFileHandle aHandle;
+ bool bRetval(false);
+
+ // create current configuration
+ if (maEntries.empty())
+ {
+ createCurrent();
+ }
+
+ // open target temp file and write current configuration to it - it exists until deleted
+ if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &rTempFileName))
+ {
+ bRetval = write_entries(aHandle);
+
+ // close temp file - it exists until deleted
+ osl_closeFile(aHandle);
+ }
+
+ return bRetval;
+ }
+ };
}
namespace
@@ -91,12 +498,12 @@ namespace
class PackedFileEntry
{
private:
- sal_uInt32 mnFullFileSize; // size in bytes of unpacked original file
- sal_uInt32 mnPackFileSize; // size in bytes in file backup package (smaller if compressed, same if not)
- sal_uInt32 mnOffset; // offset in File (zero identifies new file)
- sal_uInt32 mnCrc32; // checksum
- FileSharedPtr maFile; // file where to find the data (at offset)
- bool mbDoCompress; // flag if this file is scheduled to be compredded when written
+ sal_uInt32 mnFullFileSize; // size in bytes of unpacked original file
+ sal_uInt32 mnPackFileSize; // size in bytes in file backup package (smaller if compressed, same if not)
+ sal_uInt32 mnOffset; // offset in File (zero identifies new file)
+ sal_uInt32 mnCrc32; // checksum
+ FileSharedPtr maFile; // file where to find the data (at offset)
+ bool mbDoCompress; // flag if this file is scheduled to be compredded when written
bool copy_content_straight(oslFileHandle& rTargetHandle)
{
@@ -336,93 +743,67 @@ namespace
return mnOffset;
}
+ void setOffset(sal_uInt32 nOffset)
+ {
+ mnOffset = nOffset;
+ }
+
+ static sal_uInt32 getEntrySize()
+ {
+ return 12;
+ }
+
sal_uInt32 getCrc32() const
{
return mnCrc32;
}
- bool read_header(
- FileSharedPtr& rFile,
- sal_uInt32 nOffset)
+ bool read_header(FileSharedPtr& rFile)
{
- mnOffset = nOffset;
- maFile = rFile;
-
- if (maFile)
+ if (!rFile)
{
- sal_uInt8 aArray[4];
- sal_uInt64 nBaseRead(0);
+ return false;
+ }
- // read and compute full file size
- if (osl::File::E_None == maFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
- {
- mnFullFileSize = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
- }
- else
- {
- return false;
- }
+ maFile = rFile;
- // read and compute entry crc32
- if (osl::File::E_None == maFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
- {
- mnCrc32 = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
- }
- else
- {
- return false;
- }
+ // read and compute full file size
+ if (!read_sal_uInt32(rFile, mnFullFileSize))
+ {
+ return false;
+ }
- // read and compute packed size
- if (osl::File::E_None == maFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
- {
- mnPackFileSize = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
- }
- else
- {
- return false;
- }
+ // read and compute entry crc32
+ if (!read_sal_uInt32(rFile, mnCrc32))
+ {
+ return false;
+ }
- return true;
+ // read and compute packed size
+ if (!read_sal_uInt32(rFile, mnPackFileSize))
+ {
+ return false;
}
- return false;
+ return true;
}
- bool write_header(oslFileHandle& rHandle)
+ bool write_header(oslFileHandle& rHandle) const
{
- sal_uInt8 aArray[4];
- sal_uInt64 nBaseWritten(0);
-
// write full file size
- aArray[0] = sal_uInt8((mnFullFileSize & 0xff000000) >> 24);
- aArray[1] = sal_uInt8((mnFullFileSize & 0x00ff0000) >> 16);
- aArray[2] = sal_uInt8((mnFullFileSize & 0x0000ff00) >> 8);
- aArray[3] = sal_uInt8(mnFullFileSize & 0x000000ff);
-
- if (osl_File_E_None != osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ if (!write_sal_uInt32(rHandle, mnFullFileSize))
{
return false;
}
// write crc32
- aArray[0] = sal_uInt8((mnCrc32 & 0xff000000) >> 24);
- aArray[1] = sal_uInt8((mnCrc32 & 0x00ff0000) >> 16);
- aArray[2] = sal_uInt8((mnCrc32 & 0x0000ff00) >> 8);
- aArray[3] = sal_uInt8(mnCrc32 & 0x000000ff);
-
- if (osl_File_E_None != osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ if (!write_sal_uInt32(rHandle, mnCrc32))
{
return false;
}
// write packed file size
- aArray[0] = sal_uInt8((mnPackFileSize & 0xff000000) >> 24);
- aArray[1] = sal_uInt8((mnPackFileSize & 0x00ff0000) >> 16);
- aArray[2] = sal_uInt8((mnPackFileSize & 0x0000ff00) >> 8);
- aArray[3] = sal_uInt8(mnPackFileSize & 0x000000ff);
-
- if (osl_File_E_None != osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ if (!write_sal_uInt32(rHandle, mnPackFileSize))
{
return false;
}
@@ -509,23 +890,16 @@ namespace
// if there are entries (and less than max), read them
if (nEntries >= 1 && nEntries <= 10)
{
- // offset in souce file starts with 8 Byte for header + numEntries and
- // 12 byte for each entry (size, crc32 and PackedSize)
- sal_uInt32 nOffset(8 + (12 * nEntries));
-
for (sal_uInt32 a(0); a < nEntries; a++)
{
// create new entry, read header (size, crc and PackedSize),
// set offset and source file
PackedFileEntry aEntry;
- if (aEntry.read_header(aSourceFile, nOffset))
+ if (aEntry.read_header(aSourceFile))
{
// add to local data
maPackedFileEntryVector.push_back(aEntry);
-
- // increase offset for next entry
- nOffset += aEntry.getPackFileSize();
}
else
{
@@ -539,6 +913,21 @@ namespace
// on read error clear local data
maPackedFileEntryVector.clear();
}
+ else
+ {
+ // calculate and set offsets to file binary content
+ sal_uInt32 nHeaderSize(8);
+
+ nHeaderSize += maPackedFileEntryVector.size() * PackedFileEntry::getEntrySize();
+
+ sal_uInt32 nOffset(nHeaderSize);
+
+ for (auto& b : maPackedFileEntryVector)
+ {
+ b.setOffset(nOffset);
+ nOffset += b.getPackFileSize();
+ }
+ }
}
}
}
@@ -571,7 +960,7 @@ namespace
oslFileHandle aHandle;
OUString aTempURL;
- // open target temp file
+ // open target temp file - it exists until deleted
if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &aTempURL))
{
sal_uInt8 aArray[4];
@@ -586,27 +975,25 @@ namespace
if (osl_File_E_None == osl_writeFile(aHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
{
const sal_uInt32 nSize(maPackedFileEntryVector.size());
- aArray[0] = sal_uInt8((nSize & 0xff000000) >> 24);
- aArray[1] = sal_uInt8((nSize & 0x00ff0000) >> 16);
- aArray[2] = sal_uInt8((nSize & 0x0000ff00) >> 8);
- aArray[3] = sal_uInt8(nSize & 0x000000ff);
// write number of entries
- if (osl_File_E_None == osl_writeFile(aHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
+ if (write_sal_uInt32(aHandle, nSize))
{
if (bRetval)
{
// write placeholder for headers. Due to the fact that
// PackFileSize for newly added files gets set during
// writing the content entry, write headers after content
- // is written. To do so, write placeholders here. We know
- // the number of entries to write
- const sal_uInt32 nWriteSize(3 * maPackedFileEntryVector.size());
+ // is written. To do so, write placeholders here
+ sal_uInt32 nWriteSize(0);
+
+ nWriteSize += maPackedFileEntryVector.size() * PackedFileEntry::getEntrySize();
+
aArray[0] = aArray[1] = aArray[2] = aArray[3] = 0;
for (sal_uInt32 a(0); bRetval && a < nWriteSize; a++)
{
- if (osl_File_E_None != osl_writeFile(aHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ if (osl_File_E_None != osl_writeFile(aHandle, static_cast<const void*>(aArray), 1, &nBaseWritten) || 1 != nBaseWritten)
{
bRetval = false;
}
@@ -653,7 +1040,7 @@ namespace
}
}
- // close temp file (in all cases)
+ // close temp file (in all cases) - it exists until deleted
osl_closeFile(aHandle);
if (bRetval)
@@ -690,11 +1077,17 @@ namespace
bool bNeedToAdd(false);
sal_uInt32 nCrc32(0);
- if (!maPackedFileEntryVector.empty())
+ if (maPackedFileEntryVector.empty())
+ {
+ // no backup yet, add as 1st backup
+ bNeedToAdd = true;
+ }
+ else
{
// already backups there, check if different from last entry
const PackedFileEntry& aLastEntry = maPackedFileEntryVector.back();
+ // check if file is different
if (aLastEntry.getFullFileSize() != static_cast<sal_uInt32>(nFileSize))
{
// different size, different file
@@ -712,11 +1105,6 @@ namespace
}
}
}
- else
- {
- // no backup yet, add
- bNeedToAdd = true;
- }
if (bNeedToAdd)
{
@@ -829,16 +1217,89 @@ namespace comphelper
return bRetval;
}
- rtl::OUString BackupFileHelper::getName()
+ bool BackupFileHelper::tryPush(bool bCompress)
{
- return OUString(maBase + "/." + maName + ".pack");
+ bool bDidPush(false);
+
+ if (splitBaseURL())
+ {
+ // ensure directory existence
+ osl::Directory::createPath(getPackDirName());
+
+ // try push for base file (usually registrymodifications)
+ bDidPush = tryPush_basefile(bCompress);
+
+ // Try Push of ExtensionInfo
+ bDidPush |= tryPush_extensionInfo(bCompress);
+ }
+
+ return bDidPush;
}
- bool BackupFileHelper::tryPush(bool bCompress)
+ bool BackupFileHelper::isPopPossible()
+ {
+ bool bPopPossible(false);
+
+ if (splitBaseURL())
+ {
+ // try for base file (usually registrymodifications)
+ bPopPossible = isPopPossible_basefile();
+
+ // try for ExtensionInfo
+ bPopPossible |= isPopPossible_extensionInfo();
+ }
+
+ return bPopPossible;
+ }
+
+ bool BackupFileHelper::tryPop()
+ {
+ bool bDidPop(false);
+
+ if (splitBaseURL())
+ {
+ // try for base file (usually registrymodifications)
+ bDidPop = tryPop_basefile();
+
+ // try for ExtensionInfo
+ bDidPop |= tryPop_extensionInfo();
+
+ if (bDidPop)
+ {
+ // try removal of evtl. empty directory
+ osl::Directory::remove(getPackDirName());
+ }
+ }
+
+ return bDidPop;
+ }
+
+ bool BackupFileHelper::splitBaseURL()
+ {
+ if (maBase.isEmpty() && !mrBaseURL.isEmpty())
+ {
+ // split URL at extension and at last path separator
+ maBase = splitAtLastToken(splitAtLastToken(mrBaseURL, '.', maExt), '/', maName);
+ }
+
+ return !maBase.isEmpty() && !maName.isEmpty();
+ }
+
+ const rtl::OUString BackupFileHelper::getPackDirName() const
+ {
+ return rtl::OUString(maBase + "/pack");
+ }
+
+ const rtl::OUString BackupFileHelper::getPackFileName(const rtl::OUString& rFileName) const
+ {
+ return rtl::OUString(getPackDirName() + "/" + rFileName + ".pack");
+ }
+
+ bool BackupFileHelper::tryPush_basefile(bool bCompress)
{
- if (splitBaseURL() && baseFileExists())
+ if (fileExists(mrBaseURL))
{
- PackedFile aPackedFile(getName());
+ PackedFile aPackedFile(getPackFileName(maName));
FileSharedPtr aBaseFile(new osl::File(mrBaseURL));
if (aPackedFile.tryPush(aBaseFile, bCompress))
@@ -854,11 +1315,37 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::isPopPossible()
+ bool BackupFileHelper::tryPush_extensionInfo(bool bCompress)
+ {
+ ExtensionInfo aExtensionInfo;
+ OUString aTempURL;
+ bool bRetval(false);
+
+ // create current configuration and write to temp file - it exists until deleted
+ if (aExtensionInfo.createTempFile(aTempURL))
+ {
+ PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
+ FileSharedPtr aBaseFile(new osl::File(aTempURL));
+
+ if (aPackedFile.tryPush(aBaseFile, bCompress))
+ {
+ // 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_basefile()
{
- if (splitBaseURL() && baseFileExists())
+ if (fileExists(mrBaseURL))
{
- PackedFile aPackedFile(getName());
+ PackedFile aPackedFile(getPackFileName(maName));
return !aPackedFile.empty();
}
@@ -866,23 +1353,32 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::tryPop()
+ bool BackupFileHelper::isPopPossible_extensionInfo()
+ {
+ // extensionInfo always exists internally, no test needed
+ PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
+
+ return !aPackedFile.empty();
+ }
+
+ bool BackupFileHelper::tryPop_basefile()
{
- if (splitBaseURL() && baseFileExists())
+ if (fileExists(mrBaseURL))
{
- PackedFile aPackedFile(getName());
+ // try Pop for base file (usually registrymodifications)
+ PackedFile aPackedFile(getPackFileName(maName));
if (!aPackedFile.empty())
{
oslFileHandle aHandle;
OUString aTempURL;
- // open target temp file
+ // open target temp file - it exists until deleted
if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &aTempURL))
{
bool bRetval(aPackedFile.tryPop(aHandle));
- // close temp file (in all cases)
+ // close temp file (in all cases) - it exists until deleted
osl_closeFile(aHandle);
if (bRetval)
@@ -908,24 +1404,58 @@ namespace comphelper
return false;
}
- bool BackupFileHelper::splitBaseURL()
+ bool BackupFileHelper::tryPop_extensionInfo()
{
- if (maBase.isEmpty() && !mrBaseURL.isEmpty())
+ // extensionInfo always exists internally, no test needed
+ PackedFile aPackedFile(getPackFileName("ExtensionInfo"));
+
+ if (!aPackedFile.empty())
{
- // split URL at extension and at last path separator
- maBase = splitAtLastToken(splitAtLastToken(mrBaseURL, '.', maExt), '/', maName);
- }
+ oslFileHandle aHandle;
+ OUString aTempURL;
- return !maBase.isEmpty() && !maName.isEmpty();
- }
+ // open target temp file - it exists until deleted
+ if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &aTempURL))
+ {
+ bool bRetval(aPackedFile.tryPop(aHandle));
- bool BackupFileHelper::baseFileExists()
- {
- if (!mrBaseURL.isEmpty())
- {
- FileSharedPtr aBaseFile(new osl::File(mrBaseURL));
+ // close temp file (in all cases) - it exists until deleted
+ osl_closeFile(aHandle);
- return (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read));
+ if (bRetval)
+ {
+ // last config is in temp file, load it to ExtensionInfo
+ ExtensionInfo aLoadedExtensionInfo;
+ FileSharedPtr aBaseFile(new osl::File(aTempURL));
+
+ if (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read))
+ {
+ if (aLoadedExtensionInfo.read_entries(aBaseFile))
+ {
+ ExtensionInfo aCurrentExtensionInfo;
+
+ aCurrentExtensionInfo.createCurrent();
+
+ // now we have loaded and current ExtensionInfo and may react on differences
+
+
+
+
+
+ bRetval = true;
+ }
+ }
+
+ // reduce to allowed number and flush
+ aPackedFile.tryReduceToNumBackups(mnNumBackups);
+ aPackedFile.flush();
+ }
+
+ // delete temp file (in all cases - it may be moved already)
+ osl::File::remove(aTempURL);
+
+ return bRetval;
+ }
}
return false;