summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar')
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.cpp338
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.h59
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandlerOut.cpp117
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.cpp25
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.h108
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp181
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.h18
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarItem.h69
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.cpp186
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.h28
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarRegister.cpp18
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.cpp139
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.h34
13 files changed, 1320 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.cpp
new file mode 100644
index 000000000..aa4b2aeca
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -0,0 +1,338 @@
+// TarHandler.cpp
+
+#include "StdAfx.h"
+
+#include "Common/ComTry.h"
+#include "Common/Defs.h"
+#include "Common/NewHandler.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
+
+#include "../Common/ItemNameUtils.h"
+
+#include "TarHandler.h"
+#include "TarIn.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NTar {
+
+STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsDir, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackSize, VT_UI8},
+ { NULL, kpidMTime, VT_FILETIME},
+ { NULL, kpidPosixAttrib, VT_UI4},
+ { NULL, kpidUser, VT_BSTR},
+ { NULL, kpidGroup, VT_BSTR},
+ { NULL, kpidLink, VT_BSTR}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_NO_Table
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidPhySize: if (_phySizeDefined) prop = _phySize; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
+HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
+{
+ UInt64 endPos = 0;
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+
+ _isGood = true;
+ UInt64 pos = 0;
+ for (;;)
+ {
+ CItemEx item;
+ bool filled;
+ item.HeaderPosition = pos;
+ RINOK(ReadItem(stream, filled, item));
+ if (!filled)
+ break;
+ _items.Add(item);
+
+ RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &pos));
+ if (pos > endPos)
+ return S_FALSE;
+ if (pos == endPos)
+ {
+ _isGood = false;
+ break;
+ }
+ if (callback != NULL)
+ {
+ if (_items.Size() == 1)
+ {
+ RINOK(callback->SetTotal(NULL, &endPos));
+ }
+ if (_items.Size() % 100 == 0)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(callback->SetCompleted(&numFiles, &pos));
+ }
+ }
+ }
+
+ if (_items.Size() == 0)
+ {
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ if (!callback)
+ return S_FALSE;
+ callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
+ if (!openVolumeCallback)
+ return S_FALSE;
+ NCOM::CPropVariant prop;
+ if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK)
+ return S_FALSE;
+ if (prop.vt != VT_BSTR)
+ return S_FALSE;
+ UString baseName = prop.bstrVal;
+ baseName = baseName.Right(4);
+ if (baseName.CompareNoCase(L".tar") != 0)
+ return S_FALSE;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ RINOK(Open2(stream, openArchiveCallback));
+ _stream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
+{
+ Close();
+ _seqStream = stream;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _phySizeDefined = false;
+ _curIndex = 0;
+ _latestIsRead = false;
+ _items.Clear();
+ _seqStream.Release();
+ _stream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = (_stream ? _items.Size() : (UInt32)(Int32)-1);
+ return S_OK;
+}
+
+CHandler::CHandler()
+{
+ copyCoderSpec = new NCompress::CCopyCoder();
+ copyCoder = copyCoderSpec;
+}
+
+HRESULT CHandler::SkipTo(UInt32 index)
+{
+ while (_curIndex < index || !_latestIsRead)
+ {
+ if (_latestIsRead)
+ {
+ UInt64 packSize = _latestItem.GetPackSize();
+ RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
+ _latestIsRead = false;
+ _curIndex++;
+ }
+ else
+ {
+ bool filled;
+ // item.HeaderPosition = pos;
+ RINOK(ReadItem(_seqStream, filled, _latestItem));
+ if (!filled)
+ return E_INVALIDARG;
+ _latestIsRead = true;
+ }
+ }
+ return S_OK;
+}
+
+static UString TarStringToUnicode(const AString &s)
+{
+ return MultiByteToUnicodeString(s, CP_OEMCP);
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+
+ const CItemEx *item;
+ if (_stream)
+ item = &_items[index];
+ else
+ {
+ if (index < _curIndex)
+ return E_INVALIDARG;
+ else
+ {
+ RINOK(SkipTo(index));
+ item = &_latestItem;
+ }
+ }
+
+ switch(propID)
+ {
+ case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break;
+ case kpidIsDir: prop = item->IsDir(); break;
+ case kpidSize: prop = item->Size; break;
+ case kpidPackSize: prop = item->GetPackSize(); break;
+ case kpidMTime:
+ if (item->MTime != 0)
+ {
+ FILETIME ft;
+ NTime::UnixTimeToFileTime(item->MTime, ft);
+ prop = ft;
+ }
+ break;
+ case kpidPosixAttrib: prop = item->Mode; break;
+ case kpidUser: prop = TarStringToUnicode(item->User); break;
+ case kpidGroup: prop = TarStringToUnicode(item->Group); break;
+ case kpidLink: prop = TarStringToUnicode(item->LinkName); break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+HRESULT CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ ISequentialInStream *stream = _seqStream;
+ bool seqMode = (_stream == NULL);
+ if (!seqMode)
+ stream = _stream;
+
+ bool testMode = (_aTestMode != 0);
+ bool allFilesMode = (numItems == (UInt32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (_stream && numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 totalPackSize;
+ totalSize = totalPackSize = 0;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(stream);
+
+ CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+
+ for (i = 0; i < numItems || seqMode; i++)
+ {
+ lps->InSize = totalPackSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+ const CItemEx *item;
+ if (seqMode)
+ {
+ HRESULT res = SkipTo(index);
+ if (res == E_INVALIDARG)
+ break;
+ RINOK(res);
+ item = &_latestItem;
+ }
+ else
+ item = &_items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ totalSize += item->Size;
+ totalPackSize += item->GetPackSize();
+ if (item->IsDir())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+ bool skipMode = false;
+ if (!testMode && !realOutStream)
+ {
+ if (!seqMode)
+ continue;
+ skipMode = true;
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ }
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ outStreamSpec->SetStream(realOutStream);
+ realOutStream.Release();
+ outStreamSpec->Init(skipMode ? 0 : item->Size, true);
+
+ if (!seqMode)
+ {
+ RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ }
+ streamSpec->Init(item->GetPackSize());
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+ if (seqMode)
+ {
+ _latestIsRead = false;
+ _curIndex++;
+ }
+ outStreamSpec->ReleaseStream();
+ RINOK(extractCallback->SetOperationResult(outStreamSpec->GetRem() == 0 ?
+ NArchive::NExtract::NOperationResult::kOK:
+ NArchive::NExtract::NOperationResult::kDataError));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ const CItemEx &item = _items[index];
+ return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream);
+ COM_TRY_END
+}
+
+}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.h
new file mode 100644
index 000000000..d2def9a1c
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandler.h
@@ -0,0 +1,59 @@
+// TarHandler.h
+
+#ifndef __TAR_HANDLER_H
+#define __TAR_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "../../Compress/CopyCoder.h"
+
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+class CHandler:
+ public IInArchive,
+ public IArchiveOpenSeq,
+ public IInArchiveGetStream,
+ public IOutArchive,
+ public CMyUnknownImp
+{
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _stream;
+ CMyComPtr<ISequentialInStream> _seqStream;
+ bool _isGood;
+
+ UInt32 _curIndex;
+ bool _latestIsRead;
+ CItemEx _latestItem;
+
+ UInt64 _phySize;
+ bool _phySizeDefined;
+
+ NCompress::CCopyCoder *copyCoderSpec;
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
+ HRESULT SkipTo(UInt32 index);
+
+public:
+ MY_UNKNOWN_IMP4(
+ IInArchive,
+ IArchiveOpenSeq,
+ IInArchiveGetStream,
+ IOutArchive
+ )
+
+ INTERFACE_IInArchive(;)
+ INTERFACE_IOutArchive(;)
+ STDMETHOD(OpenSeq)(ISequentialInStream *stream);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+
+ CHandler();
+};
+
+}}
+
+#endif
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
new file mode 100644
index 000000000..4c0cb5f83
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -0,0 +1,117 @@
+// TarHandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "TarHandler.h"
+#include "TarUpdate.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NTar {
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res)
+{
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(index, propId, &prop));
+ if (prop.vt == VT_BSTR)
+ res = UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP);
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *callback)
+{
+ COM_TRY_BEGIN
+ if ((_stream && !_isGood) || _seqStream)
+ return E_NOTIMPL;
+ CObjectVector<CUpdateItem> updateItems;
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ CUpdateItem ui;
+ Int32 newData;
+ Int32 newProps;
+ UInt32 indexInArchive;
+ if (!callback)
+ return E_FAIL;
+ RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
+ ui.NewProps = IntToBool(newProps);
+ ui.NewData = IntToBool(newData);
+ ui.IndexInArchive = indexInArchive;
+ ui.IndexInClient = i;
+
+ if (IntToBool(newProps))
+ {
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidIsDir, &prop));
+ if (prop.vt == VT_EMPTY)
+ ui.IsDir = false;
+ else if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ ui.IsDir = (prop.boolVal != VARIANT_FALSE);
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop));
+ if (prop.vt == VT_EMPTY)
+ ui.Mode = 0777 | (ui.IsDir ? 0040000 : 0100000);
+ else if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ ui.Mode = prop.ulVal;
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidMTime, &prop));
+ if (prop.vt == VT_EMPTY)
+ ui.Time = 0;
+ else if (prop.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ else if (!NTime::FileTimeToUnixTime(prop.filetime, ui.Time))
+ ui.Time = 0;
+ }
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidPath, &prop));
+ if (prop.vt == VT_BSTR)
+ ui.Name = UnicodeStringToMultiByte(NItemName::MakeLegalName(prop.bstrVal), CP_OEMCP);
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ if (ui.IsDir)
+ ui.Name += '/';
+ }
+ RINOK(GetPropString(callback, i, kpidUser, ui.User));
+ RINOK(GetPropString(callback, i, kpidGroup, ui.Group));
+ }
+ if (IntToBool(newData))
+ {
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ ui.Size = prop.uhVal.QuadPart;
+ }
+ updateItems.Add(ui);
+ }
+ return UpdateArchive(_stream, outStream, _items, updateItems, callback);
+ COM_TRY_END
+}
+
+}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.cpp
new file mode 100644
index 000000000..3275b284c
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.cpp
@@ -0,0 +1,25 @@
+// Archive/Tar/Header.h
+
+#include "StdAfx.h"
+
+#include "TarHeader.h"
+
+namespace NArchive {
+namespace NTar {
+namespace NFileHeader {
+
+ // The checksum field is filled with this while the checksum is computed.
+ const char *kCheckSumBlanks = " "; // 8 blanks, no null
+
+ const char *kLongLink = "././@LongLink";
+ const char *kLongLink2 = "@LongLink";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ const char *kUsTar = "ustar"; // 5 chars
+ const char *kGNUTar = "GNUtar "; // 7 chars and a null
+ const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null
+ }
+
+}}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.h
new file mode 100644
index 000000000..0b78bdc26
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarHeader.h
@@ -0,0 +1,108 @@
+// Archive/Tar/Header.h
+
+#ifndef __ARCHIVE_TAR_HEADER_H
+#define __ARCHIVE_TAR_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NTar {
+
+namespace NFileHeader
+{
+ const int kRecordSize = 512;
+ const int kNameSize = 100;
+ const int kUserNameSize = 32;
+ const int kGroupNameSize = 32;
+ const int kPrefixSize = 155;
+
+ /*
+ struct CHeader
+ {
+ char Name[kNameSize];
+ char Mode[8];
+ char UID[8];
+ char GID[8];
+ char Size[12];
+ char ModificationTime[12];
+ char CheckSum[8];
+ char LinkFlag;
+ char LinkName[kNameSize];
+ char Magic[8];
+ char UserName[kUserNameSize];
+ char GroupName[kGroupNameSize];
+ char DeviceMajor[8];
+ char DeviceMinor[8];
+ char Prefix[155];
+ };
+ union CRecord
+ {
+ CHeader Header;
+ Byte Padding[kRecordSize];
+ };
+ */
+
+ namespace NMode
+ {
+ const int kSetUID = 04000; // Set UID on execution
+ const int kSetGID = 02000; // Set GID on execution
+ const int kSaveText = 01000; // Save text (sticky bit)
+ }
+
+ namespace NFilePermissions
+ {
+ const int kUserRead = 00400; // read by owner
+ const int kUserWrite = 00200; // write by owner
+ const int kUserExecute = 00100; // execute/search by owner
+ const int kGroupRead = 00040; // read by group
+ const int kGroupWrite = 00020; // write by group
+ const int kGroupExecute = 00010; // execute/search by group
+ const int kOtherRead = 00004; // read by other
+ const int kOtherWrite = 00002; // write by other
+ const int kOtherExecute = 00001; // execute/search by other
+ }
+
+
+ // The linkflag defines the type of file
+ namespace NLinkFlag
+ {
+ const char kOldNormal = '\0'; // Normal disk file, Unix compatible
+ const char kNormal = '0'; // Normal disk file
+ const char kLink = '1'; // Link to previously dumped file
+ const char kSymbolicLink = '2'; // Symbolic link
+ const char kCharacter = '3'; // Character special file
+ const char kBlock = '4'; // Block special file
+ const char kDirectory = '5'; // Directory
+ const char kFIFO = '6'; // FIFO special file
+ const char kContiguous = '7'; // Contiguous file
+
+ const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR.
+ data: list of files created by the --incremental (-G) option
+ Each file name is preceded by either
+ - 'Y' (file should be in this archive)
+ - 'N' (file is a directory, or is not stored in the archive.)
+ Each file name is terminated by a null + an additional null after
+ the last file name. */
+
+ }
+ // Further link types may be defined later.
+
+ // The checksum field is filled with this while the checksum is computed.
+ extern const char *kCheckSumBlanks;// = " "; // 8 blanks, no null
+
+ extern const char *kLongLink; // = "././@LongLink";
+ extern const char *kLongLink2; // = "@LongLink";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ extern const char *kUsTar; // = "ustar"; // 5 chars
+ extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null
+ extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null
+ }
+
+}
+
+}}
+
+#endif
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp
new file mode 100644
index 000000000..376b3e7c8
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -0,0 +1,181 @@
+// TarIn.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringToInt.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "TarIn.h"
+
+namespace NArchive {
+namespace NTar {
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+static bool OctalToNumber(const char *srcString, int size, UInt64 &res)
+{
+ char sz[32];
+ MyStrNCpy(sz, srcString, size);
+ sz[size] = 0;
+ const char *end;
+ int i;
+ for (i = 0; sz[i] == ' '; i++);
+ res = ConvertOctStringToUInt64(sz + i, &end);
+ return (*end == ' ' || *end == 0);
+}
+
+static bool OctalToNumber32(const char *srcString, int size, UInt32 &res)
+{
+ UInt64 res64;
+ if (!OctalToNumber(srcString, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
+}
+
+#define RIF(x) { if (!(x)) return S_FALSE; }
+
+static bool IsRecordLast(const char *buf)
+{
+ for (int i = 0; i < NFileHeader::kRecordSize; i++)
+ if (buf[i] != 0)
+ return false;
+ return true;
+}
+
+static void ReadString(const char *s, int size, AString &result)
+{
+ char temp[NFileHeader::kRecordSize + 1];
+ MyStrNCpy(temp, s, size);
+ temp[size] = '\0';
+ result = temp;
+}
+
+static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize)
+{
+ item.LongLinkSize = 0;
+ char buf[NFileHeader::kRecordSize];
+ char *p = buf;
+
+ filled = false;
+
+ processedSize = NFileHeader::kRecordSize;
+ RINOK(ReadStream(stream, buf, &processedSize));
+ if (processedSize == 0 || (static_cast< int >( processedSize ) == NFileHeader::kRecordSize && IsRecordLast(buf)))
+ return S_OK;
+ if (static_cast< int >( processedSize ) < NFileHeader::kRecordSize)
+ return S_FALSE;
+
+ ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
+
+ RIF(OctalToNumber32(p, 8, item.Mode)); p += 8;
+
+ if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8;
+ if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8;
+
+ RIF(OctalToNumber(p, 12, item.Size)); p += 12;
+ RIF(OctalToNumber32(p, 12, item.MTime)); p += 12;
+
+ UInt32 checkSum;
+ RIF(OctalToNumber32(p, 8, checkSum));
+ memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8;
+
+ item.LinkFlag = *p++;
+
+ ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize;
+
+ memcpy(item.Magic, p, 8); p += 8;
+
+ ReadString(p, NFileHeader::kUserNameSize, item.User); p += NFileHeader::kUserNameSize;
+ ReadString(p, NFileHeader::kGroupNameSize, item.Group); p += NFileHeader::kGroupNameSize;
+
+ item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8;
+ item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8;
+
+ AString prefix;
+ ReadString(p, NFileHeader::kPrefixSize, prefix);
+ p += NFileHeader::kPrefixSize;
+ if (!prefix.IsEmpty() && item.IsMagic() &&
+ (item.LinkFlag != 'L' /* || prefix != "00000000000" */ ))
+ item.Name = prefix + AString('/') + item.Name;
+
+ if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)
+ item.Size = 0;
+
+ UInt32 checkSumReal = 0;
+ for (int i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += (Byte)buf[i];
+
+ if (checkSumReal != checkSum)
+ return S_FALSE;
+
+ filled = true;
+ return S_OK;
+}
+
+HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item)
+{
+ size_t processedSize;
+ RINOK(GetNextItemReal(stream, filled, item, processedSize));
+ if (!filled)
+ return S_OK;
+ // GNUtar extension
+ if (item.LinkFlag == 'L' || // NEXT file has a long name
+ item.LinkFlag == 'K') // NEXT file has a long linkname
+ {
+ if (item.Name.Compare(NFileHeader::kLongLink) != 0)
+ if (item.Name.Compare(NFileHeader::kLongLink2) != 0)
+ return S_FALSE;
+
+ AString fullName;
+ if (item.Size > (1 << 15))
+ return S_FALSE;
+ int packSize = (int)item.GetPackSize();
+ char *buffer = fullName.GetBuffer(packSize + 1);
+
+ RINOK(ReadStream_FALSE(stream, buffer, packSize));
+ processedSize += packSize;
+ buffer[item.Size] = '\0';
+ fullName.ReleaseBuffer();
+
+ UInt64 headerPosition = item.HeaderPosition;
+ if (item.LinkFlag == 'L')
+ {
+ size_t processedSize2;
+ RINOK(GetNextItemReal(stream, filled, item, processedSize2));
+ item.LongLinkSize = (unsigned)processedSize;
+ }
+ else
+ {
+ item.LongLinkSize = (unsigned)processedSize - NFileHeader::kRecordSize;
+ item.Size = 0;
+ }
+ item.Name = fullName;
+ item.HeaderPosition = headerPosition;
+ }
+ else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')
+ {
+ // pax Extended Header
+ return S_OK;
+ }
+ else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)
+ {
+ // GNU Extensions to the Archive Format
+ return S_OK;
+ }
+ else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
+ return S_FALSE;
+ return S_OK;
+}
+
+}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.h
new file mode 100644
index 000000000..cc6e3f5b5
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.h
@@ -0,0 +1,18 @@
+// Archive/TarIn.h
+
+#ifndef __ARCHIVE_TAR_IN_H
+#define __ARCHIVE_TAR_IN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo);
+
+}}
+
+#endif
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarItem.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarItem.h
new file mode 100644
index 000000000..afe8997db
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarItem.h
@@ -0,0 +1,69 @@
+// TarItem.h
+
+#ifndef __ARCHIVE_TAR_ITEM_H
+#define __ARCHIVE_TAR_ITEM_H
+
+#include "../Common/ItemNameUtils.h"
+
+#include "TarHeader.h"
+
+namespace NArchive {
+namespace NTar {
+
+struct CItem
+{
+ AString Name;
+ UInt64 Size;
+
+ UInt32 Mode;
+ UInt32 UID;
+ UInt32 GID;
+ UInt32 MTime;
+ UInt32 DeviceMajor;
+ UInt32 DeviceMinor;
+
+ AString LinkName;
+ AString User;
+ AString Group;
+
+ char Magic[8];
+ char LinkFlag;
+ bool DeviceMajorDefined;
+ bool DeviceMinorDefined;
+
+ bool IsDir() const
+ {
+ switch(LinkFlag)
+ {
+ case NFileHeader::NLinkFlag::kDirectory:
+ case NFileHeader::NLinkFlag::kDumpDir:
+ return true;
+ case NFileHeader::NLinkFlag::kOldNormal:
+ case NFileHeader::NLinkFlag::kNormal:
+ return NItemName::HasTailSlash(Name, CP_OEMCP);
+ }
+ return false;
+ }
+
+ bool IsMagic() const
+ {
+ for (int i = 0; i < 5; i++)
+ if (Magic[i] != NFileHeader::NMagic::kUsTar[i])
+ return false;
+ return true;
+ }
+
+ UInt64 GetPackSize() const { return (Size + 0x1FF) & (~((UInt64)0x1FF)); }
+};
+
+struct CItemEx: public CItem
+{
+ UInt64 HeaderPosition;
+ unsigned LongLinkSize;
+ UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }
+ UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }
+};
+
+}}
+
+#endif
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.cpp
new file mode 100644
index 000000000..1ec314c73
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.cpp
@@ -0,0 +1,186 @@
+// TarOut.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "TarOut.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
+{
+ return WriteStream(m_Stream, buffer, size);
+}
+
+void COutArchive::Create(ISequentialOutStream *outStream)
+{
+ m_Stream = outStream;
+}
+
+static AString MakeOctalString(UInt64 value)
+{
+ char s[32];
+ ConvertUInt64ToString(value, s, 8);
+ return AString(s) + ' ';
+}
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+static bool MakeOctalString8(char *s, UInt32 value)
+{
+ AString tempString = MakeOctalString(value);
+
+ const int kMaxSize = 8;
+ if (tempString.Length() >= kMaxSize)
+ return false;
+ int numSpaces = kMaxSize - (tempString.Length() + 1);
+ for(int i = 0; i < numSpaces; i++)
+ s[i] = ' ';
+ MyStringCopy(s + numSpaces, (const char *)tempString);
+ return true;
+}
+
+static bool MakeOctalString12(char *s, UInt64 value)
+{
+ AString tempString = MakeOctalString(value);
+ const int kMaxSize = 12;
+ if (tempString.Length() > kMaxSize)
+ return false;
+ int numSpaces = kMaxSize - tempString.Length();
+ for(int i = 0; i < numSpaces; i++)
+ s[i] = ' ';
+ memmove(s + numSpaces, (const char *)tempString, tempString.Length());
+ return true;
+}
+
+static bool CopyString(char *dest, const AString &src, int maxSize)
+{
+ if (src.Length() >= maxSize)
+ return false;
+ MyStringCopy(dest, (const char *)src);
+ return true;
+}
+
+#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
+
+HRESULT COutArchive::WriteHeaderReal(const CItem &item)
+{
+ char record[NFileHeader::kRecordSize];
+ char *cur = record;
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
+ record[i] = 0;
+
+ // RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize));
+ if (item.Name.Length() > NFileHeader::kNameSize)
+ return E_FAIL;
+ MyStrNCpy(cur, item.Name, NFileHeader::kNameSize);
+ cur += NFileHeader::kNameSize;
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode));
+ cur += 8;
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID));
+ cur += 8;
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID));
+ cur += 8;
+
+ RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size));
+ cur += 12;
+ RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.MTime));
+ cur += 12;
+
+ memmove(cur, NFileHeader::kCheckSumBlanks, 8);
+ cur += 8;
+
+ *cur++ = item.LinkFlag;
+
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize));
+ cur += NFileHeader::kNameSize;
+
+ memmove(cur, item.Magic, 8);
+ cur += 8;
+
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.User, NFileHeader::kUserNameSize));
+ cur += NFileHeader::kUserNameSize;
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.Group, NFileHeader::kGroupNameSize));
+ cur += NFileHeader::kGroupNameSize;
+
+
+ if (item.DeviceMajorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMajor));
+ cur += 8;
+
+ if (item.DeviceMinorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMinor));
+ cur += 8;
+
+
+ UInt32 checkSumReal = 0;
+ for(i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += Byte(record[i]);
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal));
+
+ return WriteBytes(record, NFileHeader::kRecordSize);
+}
+
+HRESULT COutArchive::WriteHeader(const CItem &item)
+{
+ int nameSize = item.Name.Length();
+ if (nameSize < NFileHeader::kNameSize)
+ return WriteHeaderReal(item);
+
+ CItem modifiedItem = item;
+ int nameStreamSize = nameSize + 1;
+ modifiedItem.Size = nameStreamSize;
+ modifiedItem.LinkFlag = 'L';
+ modifiedItem.Name = NFileHeader::kLongLink;
+ modifiedItem.LinkName.Empty();
+ RINOK(WriteHeaderReal(modifiedItem));
+ RINOK(WriteBytes(item.Name, nameStreamSize));
+ RINOK(FillDataResidual(nameStreamSize));
+
+ modifiedItem = item;
+ modifiedItem.Name = item.Name.Left(NFileHeader::kNameSize - 1);
+ return WriteHeaderReal(modifiedItem);
+}
+
+HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
+{
+ UInt32 lastRecordSize = UInt32(dataSize & (NFileHeader::kRecordSize - 1));
+ if (lastRecordSize == 0)
+ return S_OK;
+ UInt32 residualSize = NFileHeader::kRecordSize - lastRecordSize;
+ Byte residualBytes[NFileHeader::kRecordSize];
+ for (UInt32 i = 0; i < residualSize; i++)
+ residualBytes[i] = 0;
+ return WriteBytes(residualBytes, residualSize);
+}
+
+HRESULT COutArchive::WriteFinishHeader()
+{
+ Byte record[NFileHeader::kRecordSize];
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
+ record[i] = 0;
+ for (i = 0; i < 2; i++)
+ {
+ RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ }
+ return S_OK;
+}
+
+}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.h
new file mode 100644
index 000000000..ef837869b
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarOut.h
@@ -0,0 +1,28 @@
+// Archive/TarOut.h
+
+#ifndef __ARCHIVE_TAR_OUT_H
+#define __ARCHIVE_TAR_OUT_H
+
+#include "TarItem.h"
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NTar {
+
+class COutArchive
+{
+ CMyComPtr<ISequentialOutStream> m_Stream;
+ HRESULT WriteBytes(const void *buffer, UInt32 size);
+public:
+ void Create(ISequentialOutStream *outStream);
+ HRESULT WriteHeaderReal(const CItem &item);
+ HRESULT WriteHeader(const CItem &item);
+ HRESULT FillDataResidual(UInt64 dataSize);
+ HRESULT WriteFinishHeader();
+};
+
+}}
+
+#endif
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarRegister.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarRegister.cpp
new file mode 100644
index 000000000..3cc0d6052
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarRegister.cpp
@@ -0,0 +1,18 @@
+// TarRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterArc.h"
+
+#include "TarHandler.h"
+static IInArchive *CreateArc() { return new NArchive::NTar::CHandler; }
+#ifndef EXTRACT_ONLY
+static IOutArchive *CreateArcOut() { return new NArchive::NTar::CHandler; }
+#else
+#define CreateArcOut 0
+#endif
+
+static CArcInfo g_ArcInfo =
+{ L"Tar", L"tar", 0, 0xEE, { 'u', 's', 't', 'a', 'r' }, 5, false, CreateArc, CreateArcOut };
+
+REGISTER_ARC(Tar)
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.cpp
new file mode 100644
index 000000000..0577848f6
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -0,0 +1,139 @@
+// TarUpdate.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/ProgressUtils.h"
+
+#include "../../Compress/CopyCoder.h"
+
+#include "TarOut.h"
+#include "TarUpdate.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
+ const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+
+ UInt64 complexity = 0;
+
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &ui = updateItems[i];
+ if (ui.NewData)
+ complexity += ui.Size;
+ else
+ complexity += inputItems[ui.IndexInArchive].GetFullSize();
+ }
+
+ RINOK(updateCallback->SetTotal(complexity));
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(updateCallback, true);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->SetStream(inStream);
+
+ complexity = 0;
+
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ lps->InSize = lps->OutSize = complexity;
+ RINOK(lps->SetCur());
+
+ const CUpdateItem &ui = updateItems[i];
+ CItem item;
+ if (ui.NewProps)
+ {
+ item.Mode = ui.Mode;
+ item.Name = ui.Name;
+ item.User = ui.User;
+ item.Group = ui.Group;
+ if (ui.IsDir)
+ {
+ item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
+ item.Size = 0;
+ }
+ else
+ {
+ item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
+ item.Size = ui.Size;
+ }
+ item.MTime = ui.Time;
+ item.DeviceMajorDefined = false;
+ item.DeviceMinorDefined = false;
+ item.UID = 0;
+ item.GID = 0;
+ memmove(item.Magic, NFileHeader::NMagic::kEmpty, 8);
+ }
+ else
+ item = inputItems[ui.IndexInArchive];
+
+ if (ui.NewData)
+ {
+ item.Size = ui.Size;
+ if (item.Size == (UInt64)(Int64)-1)
+ return E_INVALIDARG;
+ }
+ else
+ item.Size = inputItems[ui.IndexInArchive].Size;
+
+ if (ui.NewData)
+ {
+ CMyComPtr<ISequentialInStream> fileInStream;
+ HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
+ if (res != S_FALSE)
+ {
+ RINOK(res);
+ RINOK(outArchive.WriteHeader(item));
+ if (!ui.IsDir)
+ {
+ RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
+ if (copyCoderSpec->TotalSize != item.Size)
+ return E_FAIL;
+ RINOK(outArchive.FillDataResidual(item.Size));
+ }
+ }
+ complexity += ui.Size;
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ }
+ else
+ {
+ const CItemEx &existItemInfo = inputItems[ui.IndexInArchive];
+ UInt64 size;
+ if (ui.NewProps)
+ {
+ RINOK(outArchive.WriteHeader(item));
+ RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ size = existItemInfo.Size;
+ }
+ else
+ {
+ RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL));
+ size = existItemInfo.GetFullSize();
+ }
+ streamSpec->Init(size);
+
+ RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
+ if (copyCoderSpec->TotalSize != size)
+ return E_FAIL;
+ RINOK(outArchive.FillDataResidual(existItemInfo.Size));
+ complexity += size;
+ }
+ }
+ return outArchive.WriteFinishHeader();
+}
+
+}}
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.h b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.h
new file mode 100644
index 000000000..fb217d196
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarUpdate.h
@@ -0,0 +1,34 @@
+// TarUpdate.h
+
+#ifndef __TAR_UPDATE_H
+#define __TAR_UPDATE_H
+
+#include "../IArchive.h"
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+struct CUpdateItem
+{
+ int IndexInArchive;
+ int IndexInClient;
+ UInt32 Time;
+ UInt32 Mode;
+ UInt64 Size;
+ AString Name;
+ AString User;
+ AString Group;
+ bool NewData;
+ bool NewProps;
+ bool IsDir;
+};
+
+HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif