Mercurial > vba-linux
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Archive/Tar/TarIn.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,176 @@ 1.4 +// Archive/TarIn.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "TarIn.h" 1.9 +#include "TarHeader.h" 1.10 + 1.11 +#include "Common/StringToInt.h" 1.12 +#include "Windows/Defs.h" 1.13 + 1.14 +#include "../../Common/StreamUtils.h" 1.15 + 1.16 +namespace NArchive { 1.17 +namespace NTar { 1.18 + 1.19 +static void MyStrNCpy(char *dest, const char *src, int size) 1.20 +{ 1.21 + for (int i = 0; i < size; i++) 1.22 + { 1.23 + char c = src[i]; 1.24 + dest[i] = c; 1.25 + if (c == 0) 1.26 + break; 1.27 + } 1.28 +} 1.29 + 1.30 +static bool OctalToNumber(const char *srcString, int size, UInt64 &res) 1.31 +{ 1.32 + char sz[32]; 1.33 + MyStrNCpy(sz, srcString, size); 1.34 + sz[size] = 0; 1.35 + const char *end; 1.36 + int i; 1.37 + for (i = 0; sz[i] == ' '; i++); 1.38 + res = ConvertOctStringToUInt64(sz + i, &end); 1.39 + return (*end == ' ' || *end == 0); 1.40 +} 1.41 + 1.42 +static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) 1.43 +{ 1.44 + UInt64 res64; 1.45 + if (!OctalToNumber(srcString, size, res64)) 1.46 + return false; 1.47 + res = (UInt32)res64; 1.48 + return (res64 <= 0xFFFFFFFF); 1.49 +} 1.50 + 1.51 +#define RIF(x) { if (!(x)) return S_FALSE; } 1.52 + 1.53 +static bool IsRecordLast(const char *buf) 1.54 +{ 1.55 + for (int i = 0; i < NFileHeader::kRecordSize; i++) 1.56 + if (buf[i] != 0) 1.57 + return false; 1.58 + return true; 1.59 +} 1.60 + 1.61 +static void ReadString(const char *s, int size, AString &result) 1.62 +{ 1.63 + char temp[NFileHeader::kRecordSize + 1]; 1.64 + MyStrNCpy(temp, s, size); 1.65 + temp[size] = '\0'; 1.66 + result = temp; 1.67 +} 1.68 + 1.69 +static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, size_t &processedSize) 1.70 +{ 1.71 + item.LongLinkSize = 0; 1.72 + char buf[NFileHeader::kRecordSize]; 1.73 + char *p = buf; 1.74 + 1.75 + filled = false; 1.76 + 1.77 + processedSize = NFileHeader::kRecordSize; 1.78 + RINOK(ReadStream(stream, buf, &processedSize)); 1.79 + if (processedSize == 0 || (processedSize == NFileHeader::kRecordSize && IsRecordLast(buf))) 1.80 + return S_OK; 1.81 + if (processedSize < NFileHeader::kRecordSize) 1.82 + return S_FALSE; 1.83 + 1.84 + ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize; 1.85 + 1.86 + RIF(OctalToNumber32(p, 8, item.Mode)); p += 8; 1.87 + 1.88 + if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8; 1.89 + if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8; 1.90 + 1.91 + RIF(OctalToNumber(p, 12, item.Size)); p += 12; 1.92 + RIF(OctalToNumber32(p, 12, item.MTime)); p += 12; 1.93 + 1.94 + UInt32 checkSum; 1.95 + RIF(OctalToNumber32(p, 8, checkSum)); 1.96 + memcpy(p, NFileHeader::kCheckSumBlanks, 8); p += 8; 1.97 + 1.98 + item.LinkFlag = *p++; 1.99 + 1.100 + ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; 1.101 + 1.102 + memcpy(item.Magic, p, 8); p += 8; 1.103 + 1.104 + ReadString(p, NFileHeader::kUserNameSize, item.UserName); p += NFileHeader::kUserNameSize; 1.105 + ReadString(p, NFileHeader::kUserNameSize, item.GroupName); p += NFileHeader::kUserNameSize; 1.106 + 1.107 + item.DeviceMajorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMajor)); p += 8; 1.108 + item.DeviceMinorDefined = (p[0] != 0); RIF(OctalToNumber32(p, 8, item.DeviceMinor)); p += 8; 1.109 + 1.110 + AString prefix; 1.111 + ReadString(p, NFileHeader::kPrefixSize, prefix); 1.112 + p += NFileHeader::kPrefixSize; 1.113 + if (!prefix.IsEmpty() && item.IsMagic() && 1.114 + (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) 1.115 + item.Name = prefix + AString('/') + item.Name; 1.116 + 1.117 + if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) 1.118 + item.Size = 0; 1.119 + 1.120 + UInt32 checkSumReal = 0; 1.121 + for (int i = 0; i < NFileHeader::kRecordSize; i++) 1.122 + checkSumReal += (Byte)buf[i]; 1.123 + 1.124 + if (checkSumReal != checkSum) 1.125 + return S_FALSE; 1.126 + 1.127 + filled = true; 1.128 + return S_OK; 1.129 +} 1.130 + 1.131 +HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item) 1.132 +{ 1.133 + size_t processedSize; 1.134 + RINOK(GetNextItemReal(stream, filled, item, processedSize)); 1.135 + if (!filled) 1.136 + return S_OK; 1.137 + // GNUtar extension 1.138 + if (item.LinkFlag == 'L') 1.139 + { 1.140 + if (item.Name.Compare(NFileHeader::kLongLink) != 0) 1.141 + if (item.Name.Compare(NFileHeader::kLongLink2) != 0) 1.142 + return S_FALSE; 1.143 + 1.144 + AString fullName; 1.145 + if (item.Size > (1 << 15)) 1.146 + return S_FALSE; 1.147 + int packSize = (int)item.GetPackSize(); 1.148 + char *buffer = fullName.GetBuffer(packSize + 1); 1.149 + 1.150 + RINOK(ReadStream_FALSE(stream, buffer, packSize)); 1.151 + processedSize += packSize; 1.152 + buffer[item.Size] = '\0'; 1.153 + fullName.ReleaseBuffer(); 1.154 + 1.155 + UInt64 headerPosition = item.HeaderPosition; 1.156 + { 1.157 + size_t processedSize2; 1.158 + RINOK(GetNextItemReal(stream, filled, item, processedSize2)); 1.159 + } 1.160 + item.LongLinkSize = (unsigned)processedSize; 1.161 + item.Name = fullName; 1.162 + item.HeaderPosition = headerPosition; 1.163 + } 1.164 + else if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X') 1.165 + { 1.166 + // pax Extended Header 1.167 + return S_OK; 1.168 + } 1.169 + else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir) 1.170 + { 1.171 + // GNU Extensions to the Archive Format 1.172 + return S_OK; 1.173 + } 1.174 + else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0)) 1.175 + return S_FALSE; 1.176 + return S_OK; 1.177 +} 1.178 + 1.179 +}}