Mercurial > vba-linux
view src/win32/7zip/7z/CPP/7zip/Archive/Tar/TarIn.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // Archive/TarIn.cpp3 #include "StdAfx.h"5 #include "TarIn.h"6 #include "TarHeader.h"8 #include "Common/StringToInt.h"9 #include "Windows/Defs.h"11 #include "../../Common/StreamUtils.h"13 namespace NArchive {14 namespace NTar {16 static void MyStrNCpy(char *dest, const char *src, int size)17 {18 for (int i = 0; i < size; i++)19 {20 char c = src[i];21 dest[i] = c;22 if (c == 0)23 break;24 }25 }27 static bool OctalToNumber(const char *srcString, int size, UInt64 &res)28 {29 char sz[32];30 MyStrNCpy(sz, srcString, size);31 sz[size] = 0;32 const char *end;33 int i;34 for (i = 0; sz[i] == ' '; i++);35 res = ConvertOctStringToUInt64(sz + i, &end);36 return (*end == ' ' || *end == 0);37 }39 static bool OctalToNumber32(const char *srcString, int size, UInt32 &res)40 {41 UInt64 res64;42 if (!OctalToNumber(srcString, size, res64))43 return false;44 res = (UInt32)res64;45 return (res64 <= 0xFFFFFFFF);46 }48 #define RIF(x) { if (!(x)) return S_FALSE; }50 static bool IsRecordLast(const char *buf)51 {52 for (int i = 0; i < NFileHeader::kRecordSize; i++)53 if (buf[i] != 0)54 return false;55 return true;56 }58 static void ReadString(const char *s, int size, AString &result)59 {60 char temp[NFileHeader::kRecordSize + 1];61 MyStrNCpy(temp, s, size);62 temp[size] = '\0';63 result = temp;64 }66 static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize)67 {68 item.LongLinkSize = 0;69 char buf[NFileHeader::kRecordSize];70 char *p = buf;72 filled = false;74 processedSize = NFileHeader::kRecordSize;75 RINOK(ReadStream(stream, buf, &processedSize));76 if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf)))77 return S_OK;78 if (processedSize < NFileHeader::kRecordSize)79 return S_FALSE;81 ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;83 RIF(OctalToNumber32(p, 8, item.Mode)); p += 8;85 if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8;86 if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8;88 RIF(OctalToNumber(p, 12, item.Size)); p += 12;89 RIF(OctalToNumber32(p, 12, item.MTime)); p += 12;91 UInt32 checkSum;92 RIF(OctalToNumber32(p, 8, checkSum));93 memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8;95 item.LinkFlag = *p++;97 ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize;99 memcpy(item.Magic, p, 8); p += 8;101 ReadString(p, NFileHeader::kUserNameSize, item.UserName); p += NFileHeader::kUserNameSize;102 ReadString(p, NFileHeader::kUserNameSize, item.GroupName); p += NFileHeader::kUserNameSize;104 item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8;105 item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8;107 AString prefix;108 ReadString(p, NFileHeader::kPrefixSize, prefix);109 p += NFileHeader::kPrefixSize;110 if (!prefix.IsEmpty() && item.IsMagic() &&111 (item.LinkFlag != 'L' /* || prefix != "00000000000" */ ))112 item.Name = prefix + AString('/') + item.Name;114 if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)115 item.Size = 0;117 UInt32 checkSumReal = 0;118 for (int i = 0; i < NFileHeader::kRecordSize; i++)119 checkSumReal += (Byte)buf[i];121 if (checkSumReal != checkSum)122 return S_FALSE;124 filled = true;125 return S_OK;126 }128 HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item)129 {130 size_t processedSize;131 RINOK(GetNextItemReal(stream, filled, item, processedSize));132 if (!filled)133 return S_OK;134 // GNUtar extension135 if (item.LinkFlag == 'L')136 {137 if (item.Name.Compare(NFileHeader::kLongLink) != 0)138 if (item.Name.Compare(NFileHeader::kLongLink2) != 0)139 return S_FALSE;141 AString fullName;142 if (item.Size > (1 << 15))143 return S_FALSE;144 int packSize = (int)item.GetPackSize();145 char *buffer = fullName.GetBuffer(packSize + 1);147 RINOK(ReadStream_FALSE(stream, buffer, packSize));148 processedSize += packSize;149 buffer[item.Size] = '\0';150 fullName.ReleaseBuffer();152 UInt64 headerPosition = item.HeaderPosition;153 {154 size_t processedSize2;155 RINOK(GetNextItemReal(stream, filled, item, processedSize2));156 }157 item.LongLinkSize = (unsigned)processedSize;158 item.Name = fullName;159 item.HeaderPosition = headerPosition;160 }161 else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')162 {163 // pax Extended Header164 return S_OK;165 }166 else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)167 {168 // GNU Extensions to the Archive Format169 return S_OK;170 }171 else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))172 return S_FALSE;173 return S_OK;174 }176 }}