From 8457830abdca9d5769e2ec1bdbfb793a05e6c5dd Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 21 Feb 2011 16:30:31 +0100 Subject: init commit --- .../p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp | 181 +++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/Archive/Tar/TarIn.cpp') 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; +} + +}} -- cgit v1.2.3