xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/RpmHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // RpmHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyBuffer.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/IntToString.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StringConvert.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/UTFConvert.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariant.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariantUtils.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/TimeUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #include "HandlerCont.h"
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker // #define Z7_RPM_SHOW_METADATA
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker #define Get16(p) GetBe16(p)
27*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetBe32(p)
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
30*f6dc9357SAndroid Build Coastguard Worker namespace NRpm {
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNameSize = 66;
33*f6dc9357SAndroid Build Coastguard Worker static const unsigned kLeadSize = kNameSize + 30;
34*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_HeaderSig_Size = 16;
35*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_Entry_Size = 16;
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #define RPMSIG_NONE         0  // Old signature
38*f6dc9357SAndroid Build Coastguard Worker #define RPMSIG_PGP262_1024  1  // Old signature
39*f6dc9357SAndroid Build Coastguard Worker #define RPMSIG_HEADERSIG    5  // New signature
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker enum
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker   kRpmType_Bin = 0,
44*f6dc9357SAndroid Build Coastguard Worker   kRpmType_Src = 1
45*f6dc9357SAndroid Build Coastguard Worker };
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker // There are two sets of TAGs: signature tags and header tags
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker // ----- Signature TAGs -----
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker #define RPMSIGTAG_SIZE 1000 // Header + Payload size (32bit)
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker // ----- Header TAGs -----
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_NAME       1000
56*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_VERSION    1001
57*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_RELEASE    1002
58*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_BUILDTIME  1006
59*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_OS         1021  // string (old version used int?)
60*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_ARCH       1022  // string (old version used int?)
61*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_PAYLOADFORMAT      1124
62*f6dc9357SAndroid Build Coastguard Worker #define RPMTAG_PAYLOADCOMPRESSOR  1125
63*f6dc9357SAndroid Build Coastguard Worker // #define RPMTAG_PAYLOADFLAGS       1126
64*f6dc9357SAndroid Build Coastguard Worker 
65*f6dc9357SAndroid Build Coastguard Worker enum
66*f6dc9357SAndroid Build Coastguard Worker {
67*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_NULL,
68*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_CHAR,
69*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_INT8,
70*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_INT16,
71*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_INT32,
72*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_INT64,
73*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_STRING,
74*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_BIN,
75*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_STRING_ARRAY,
76*f6dc9357SAndroid Build Coastguard Worker   k_EntryType_I18NSTRING
77*f6dc9357SAndroid Build Coastguard Worker };
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker static const char * const k_CPUs[] =
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker     "noarch"
82*f6dc9357SAndroid Build Coastguard Worker   , "i386"
83*f6dc9357SAndroid Build Coastguard Worker   , "alpha"
84*f6dc9357SAndroid Build Coastguard Worker   , "sparc"
85*f6dc9357SAndroid Build Coastguard Worker   , "mips"
86*f6dc9357SAndroid Build Coastguard Worker   , "ppc"
87*f6dc9357SAndroid Build Coastguard Worker   , "m68k"
88*f6dc9357SAndroid Build Coastguard Worker   , "sgi"
89*f6dc9357SAndroid Build Coastguard Worker   , "rs6000"
90*f6dc9357SAndroid Build Coastguard Worker   , "ia64"
91*f6dc9357SAndroid Build Coastguard Worker   , "sparc64"  // 10 ???
92*f6dc9357SAndroid Build Coastguard Worker   , "mipsel"
93*f6dc9357SAndroid Build Coastguard Worker   , "arm"
94*f6dc9357SAndroid Build Coastguard Worker   , "m68kmint"
95*f6dc9357SAndroid Build Coastguard Worker   , "s390"
96*f6dc9357SAndroid Build Coastguard Worker   , "s390x"
97*f6dc9357SAndroid Build Coastguard Worker   , "ppc64"
98*f6dc9357SAndroid Build Coastguard Worker   , "sh"
99*f6dc9357SAndroid Build Coastguard Worker   , "xtensa"
100*f6dc9357SAndroid Build Coastguard Worker   , "aarch64"       // 19
101*f6dc9357SAndroid Build Coastguard Worker   , "mipsr6"        // 20
102*f6dc9357SAndroid Build Coastguard Worker   , "mips64r6"      // 21
103*f6dc9357SAndroid Build Coastguard Worker   , "riscv64"       // 22
104*f6dc9357SAndroid Build Coastguard Worker   , "loongarch64"   // 23
105*f6dc9357SAndroid Build Coastguard Worker   // , "24"
106*f6dc9357SAndroid Build Coastguard Worker   // , "25"
107*f6dc9357SAndroid Build Coastguard Worker   // , "loongarch64"   // 26  : why 23 and 26 for loongarch64?
108*f6dc9357SAndroid Build Coastguard Worker   // 255 for some non specified arch
109*f6dc9357SAndroid Build Coastguard Worker };
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker static const char * const k_OS[] =
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker     "0"
114*f6dc9357SAndroid Build Coastguard Worker   , "Linux"
115*f6dc9357SAndroid Build Coastguard Worker   , "Irix"
116*f6dc9357SAndroid Build Coastguard Worker   , "solaris"
117*f6dc9357SAndroid Build Coastguard Worker   , "SunOS"
118*f6dc9357SAndroid Build Coastguard Worker   , "AmigaOS" // AIX
119*f6dc9357SAndroid Build Coastguard Worker   , "HP-UX"
120*f6dc9357SAndroid Build Coastguard Worker   , "osf"
121*f6dc9357SAndroid Build Coastguard Worker   , "FreeBSD"
122*f6dc9357SAndroid Build Coastguard Worker   , "SCO_SV"
123*f6dc9357SAndroid Build Coastguard Worker   , "Irix64"
124*f6dc9357SAndroid Build Coastguard Worker   , "NextStep"
125*f6dc9357SAndroid Build Coastguard Worker   , "bsdi"
126*f6dc9357SAndroid Build Coastguard Worker   , "machten"
127*f6dc9357SAndroid Build Coastguard Worker   , "cygwin32-NT"
128*f6dc9357SAndroid Build Coastguard Worker   , "cygwin32-95"
129*f6dc9357SAndroid Build Coastguard Worker   , "MP_RAS"
130*f6dc9357SAndroid Build Coastguard Worker   , "MiNT"
131*f6dc9357SAndroid Build Coastguard Worker   , "OS/390"
132*f6dc9357SAndroid Build Coastguard Worker   , "VM/ESA"
133*f6dc9357SAndroid Build Coastguard Worker   , "Linux/390"  // "Linux/ESA"
134*f6dc9357SAndroid Build Coastguard Worker   , "Darwin" // "MacOSX" 21
135*f6dc9357SAndroid Build Coastguard Worker };
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker struct CLead
138*f6dc9357SAndroid Build Coastguard Worker {
139*f6dc9357SAndroid Build Coastguard Worker   Byte Major;
140*f6dc9357SAndroid Build Coastguard Worker   // Byte Minor;
141*f6dc9357SAndroid Build Coastguard Worker   UInt16 Type;
142*f6dc9357SAndroid Build Coastguard Worker   UInt16 Cpu;
143*f6dc9357SAndroid Build Coastguard Worker   UInt16 Os;
144*f6dc9357SAndroid Build Coastguard Worker   UInt16 SignatureType;
145*f6dc9357SAndroid Build Coastguard Worker   char Name[kNameSize];
146*f6dc9357SAndroid Build Coastguard Worker   // char Reserved[16];
147*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NRpm::CLead148*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
149*f6dc9357SAndroid Build Coastguard Worker   {
150*f6dc9357SAndroid Build Coastguard Worker     Major = p[4];
151*f6dc9357SAndroid Build Coastguard Worker     // Minor = p[5];
152*f6dc9357SAndroid Build Coastguard Worker     Type = Get16(p + 6);
153*f6dc9357SAndroid Build Coastguard Worker     Cpu= Get16(p + 8);
154*f6dc9357SAndroid Build Coastguard Worker     memcpy(Name, p + 10, kNameSize);
155*f6dc9357SAndroid Build Coastguard Worker     p += 10 + kNameSize;
156*f6dc9357SAndroid Build Coastguard Worker     Os = Get16(p);
157*f6dc9357SAndroid Build Coastguard Worker     SignatureType = Get16(p + 2);
158*f6dc9357SAndroid Build Coastguard Worker   }
159*f6dc9357SAndroid Build Coastguard Worker 
IsSupportedNArchive::NRpm::CLead160*f6dc9357SAndroid Build Coastguard Worker   bool IsSupported() const { return Major >= 3 && Type <= 1; }
161*f6dc9357SAndroid Build Coastguard Worker };
162*f6dc9357SAndroid Build Coastguard Worker 
163*f6dc9357SAndroid Build Coastguard Worker struct CEntry
164*f6dc9357SAndroid Build Coastguard Worker {
165*f6dc9357SAndroid Build Coastguard Worker   UInt32 Tag;
166*f6dc9357SAndroid Build Coastguard Worker   UInt32 Type;
167*f6dc9357SAndroid Build Coastguard Worker   UInt32 Offset;
168*f6dc9357SAndroid Build Coastguard Worker   UInt32 Count;
169*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NRpm::CEntry170*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
171*f6dc9357SAndroid Build Coastguard Worker   {
172*f6dc9357SAndroid Build Coastguard Worker     Tag = Get32(p + 0);
173*f6dc9357SAndroid Build Coastguard Worker     Type = Get32(p + 4);
174*f6dc9357SAndroid Build Coastguard Worker     Offset = Get32(p + 8);
175*f6dc9357SAndroid Build Coastguard Worker     Count = Get32(p + 12);
176*f6dc9357SAndroid Build Coastguard Worker   }
177*f6dc9357SAndroid Build Coastguard Worker };
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_RPM_SHOW_METADATA
181*f6dc9357SAndroid Build Coastguard Worker struct CMetaFile
182*f6dc9357SAndroid Build Coastguard Worker {
183*f6dc9357SAndroid Build Coastguard Worker   UInt32 Tag;
184*f6dc9357SAndroid Build Coastguard Worker   UInt32 Offset;
185*f6dc9357SAndroid Build Coastguard Worker   UInt32 Size;
186*f6dc9357SAndroid Build Coastguard Worker };
187*f6dc9357SAndroid Build Coastguard Worker #endif
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker Z7_class_CHandler_final: public CHandlerCont
190*f6dc9357SAndroid Build Coastguard Worker {
191*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IInArchive_Cont)
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker   UInt64 _headersSize; // is equal to start offset of payload data
194*f6dc9357SAndroid Build Coastguard Worker   UInt64 _payloadSize;
195*f6dc9357SAndroid Build Coastguard Worker   UInt64 _size;
196*f6dc9357SAndroid Build Coastguard Worker     // _size = _payloadSize, if (_payloadSize_Defined)
197*f6dc9357SAndroid Build Coastguard Worker     // _size = (fileSize - _headersSize), if (!_payloadSize_Defined)
198*f6dc9357SAndroid Build Coastguard Worker   UInt64 _phySize; // _headersSize + _payloadSize, if (_phySize_Defined)
199*f6dc9357SAndroid Build Coastguard Worker   UInt32 _headerPlusPayload_Size;
200*f6dc9357SAndroid Build Coastguard Worker   UInt32 _buildTime;
201*f6dc9357SAndroid Build Coastguard Worker 
202*f6dc9357SAndroid Build Coastguard Worker   bool _payloadSize_Defined;
203*f6dc9357SAndroid Build Coastguard Worker   bool _phySize_Defined;
204*f6dc9357SAndroid Build Coastguard Worker   bool _headerPlusPayload_Size_Defined;
205*f6dc9357SAndroid Build Coastguard Worker   bool _time_Defined;
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker   Byte _payloadSig[6]; // start data of payload
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker   AString _name;    // p7zip
210*f6dc9357SAndroid Build Coastguard Worker   AString _version; // 9.20.1
211*f6dc9357SAndroid Build Coastguard Worker   AString _release; // 8.1.1
212*f6dc9357SAndroid Build Coastguard Worker   AString _arch;    // x86_64
213*f6dc9357SAndroid Build Coastguard Worker   AString _os;      // linux
214*f6dc9357SAndroid Build Coastguard Worker 
215*f6dc9357SAndroid Build Coastguard Worker   AString _format;      // cpio
216*f6dc9357SAndroid Build Coastguard Worker   AString _compressor;  // xz, gzip, bzip2, lzma, zstd
217*f6dc9357SAndroid Build Coastguard Worker 
218*f6dc9357SAndroid Build Coastguard Worker   CLead _lead;
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_RPM_SHOW_METADATA
221*f6dc9357SAndroid Build Coastguard Worker   AString _metadata;
222*f6dc9357SAndroid Build Coastguard Worker   CRecordVector<CMetaFile> _metaFiles;
223*f6dc9357SAndroid Build Coastguard Worker   #endif
224*f6dc9357SAndroid Build Coastguard Worker 
225*f6dc9357SAndroid Build Coastguard Worker   void SetTime(NCOM::CPropVariant &prop) const
226*f6dc9357SAndroid Build Coastguard Worker   {
227*f6dc9357SAndroid Build Coastguard Worker     if (_time_Defined && _buildTime != 0)
228*f6dc9357SAndroid Build Coastguard Worker       PropVariant_SetFrom_UnixTime(prop, _buildTime);
229*f6dc9357SAndroid Build Coastguard Worker   }
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker   void SetStringProp(const AString &s, NCOM::CPropVariant &prop) const
232*f6dc9357SAndroid Build Coastguard Worker   {
233*f6dc9357SAndroid Build Coastguard Worker     UString us;
234*f6dc9357SAndroid Build Coastguard Worker     if (!ConvertUTF8ToUnicode(s, us))
235*f6dc9357SAndroid Build Coastguard Worker       us = GetUnicodeString(s);
236*f6dc9357SAndroid Build Coastguard Worker     if (!us.IsEmpty())
237*f6dc9357SAndroid Build Coastguard Worker       prop = us;
238*f6dc9357SAndroid Build Coastguard Worker   }
239*f6dc9357SAndroid Build Coastguard Worker 
240*f6dc9357SAndroid Build Coastguard Worker   void AddCPU(AString &s) const;
241*f6dc9357SAndroid Build Coastguard Worker   AString GetBaseName() const;
242*f6dc9357SAndroid Build Coastguard Worker   void AddSubFileExtension(AString &res) const;
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker   HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader);
245*f6dc9357SAndroid Build Coastguard Worker   HRESULT Open2(ISequentialInStream *stream);
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker   virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const Z7_override
248*f6dc9357SAndroid Build Coastguard Worker   {
249*f6dc9357SAndroid Build Coastguard Worker     pos = _headersSize;
250*f6dc9357SAndroid Build Coastguard Worker     size = _size;
251*f6dc9357SAndroid Build Coastguard Worker     return NExtract::NOperationResult::kOK;
252*f6dc9357SAndroid Build Coastguard Worker   }
253*f6dc9357SAndroid Build Coastguard Worker };
254*f6dc9357SAndroid Build Coastguard Worker 
255*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
256*f6dc9357SAndroid Build Coastguard Worker {
257*f6dc9357SAndroid Build Coastguard Worker   kpidHeadersSize,
258*f6dc9357SAndroid Build Coastguard Worker   kpidCpu,
259*f6dc9357SAndroid Build Coastguard Worker   kpidHostOS,
260*f6dc9357SAndroid Build Coastguard Worker   kpidCTime
261*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_RPM_SHOW_METADATA
262*f6dc9357SAndroid Build Coastguard Worker   , kpidComment
263*f6dc9357SAndroid Build Coastguard Worker   #endif
264*f6dc9357SAndroid Build Coastguard Worker };
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
267*f6dc9357SAndroid Build Coastguard Worker {
268*f6dc9357SAndroid Build Coastguard Worker   kpidPath,
269*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
270*f6dc9357SAndroid Build Coastguard Worker   kpidCTime
271*f6dc9357SAndroid Build Coastguard Worker };
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
274*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker void CHandler::AddCPU(AString &s) const
277*f6dc9357SAndroid Build Coastguard Worker {
278*f6dc9357SAndroid Build Coastguard Worker   if (!_arch.IsEmpty())
279*f6dc9357SAndroid Build Coastguard Worker     s += _arch;
280*f6dc9357SAndroid Build Coastguard Worker   else
281*f6dc9357SAndroid Build Coastguard Worker   {
282*f6dc9357SAndroid Build Coastguard Worker     if (_lead.Type == kRpmType_Bin)
283*f6dc9357SAndroid Build Coastguard Worker     {
284*f6dc9357SAndroid Build Coastguard Worker       if (_lead.Cpu < Z7_ARRAY_SIZE(k_CPUs))
285*f6dc9357SAndroid Build Coastguard Worker         s += k_CPUs[_lead.Cpu];
286*f6dc9357SAndroid Build Coastguard Worker       else
287*f6dc9357SAndroid Build Coastguard Worker         s.Add_UInt32(_lead.Cpu);
288*f6dc9357SAndroid Build Coastguard Worker     }
289*f6dc9357SAndroid Build Coastguard Worker   }
290*f6dc9357SAndroid Build Coastguard Worker }
291*f6dc9357SAndroid Build Coastguard Worker 
292*f6dc9357SAndroid Build Coastguard Worker AString CHandler::GetBaseName() const
293*f6dc9357SAndroid Build Coastguard Worker {
294*f6dc9357SAndroid Build Coastguard Worker   AString s;
295*f6dc9357SAndroid Build Coastguard Worker   if (!_name.IsEmpty())
296*f6dc9357SAndroid Build Coastguard Worker   {
297*f6dc9357SAndroid Build Coastguard Worker     s = _name;
298*f6dc9357SAndroid Build Coastguard Worker     if (!_version.IsEmpty())
299*f6dc9357SAndroid Build Coastguard Worker     {
300*f6dc9357SAndroid Build Coastguard Worker       s.Add_Minus();
301*f6dc9357SAndroid Build Coastguard Worker       s += _version;
302*f6dc9357SAndroid Build Coastguard Worker     }
303*f6dc9357SAndroid Build Coastguard Worker     if (!_release.IsEmpty())
304*f6dc9357SAndroid Build Coastguard Worker     {
305*f6dc9357SAndroid Build Coastguard Worker       s.Add_Minus();
306*f6dc9357SAndroid Build Coastguard Worker       s += _release;
307*f6dc9357SAndroid Build Coastguard Worker     }
308*f6dc9357SAndroid Build Coastguard Worker   }
309*f6dc9357SAndroid Build Coastguard Worker   else
310*f6dc9357SAndroid Build Coastguard Worker     s.SetFrom_CalcLen(_lead.Name, kNameSize);
311*f6dc9357SAndroid Build Coastguard Worker 
312*f6dc9357SAndroid Build Coastguard Worker   s.Add_Dot();
313*f6dc9357SAndroid Build Coastguard Worker   if (_lead.Type == kRpmType_Src)
314*f6dc9357SAndroid Build Coastguard Worker     s += "src";
315*f6dc9357SAndroid Build Coastguard Worker   else
316*f6dc9357SAndroid Build Coastguard Worker     AddCPU(s);
317*f6dc9357SAndroid Build Coastguard Worker   return s;
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker 
320*f6dc9357SAndroid Build Coastguard Worker void CHandler::AddSubFileExtension(AString &res) const
321*f6dc9357SAndroid Build Coastguard Worker {
322*f6dc9357SAndroid Build Coastguard Worker   if (!_format.IsEmpty())
323*f6dc9357SAndroid Build Coastguard Worker     res += _format;
324*f6dc9357SAndroid Build Coastguard Worker   else
325*f6dc9357SAndroid Build Coastguard Worker     res += "cpio";
326*f6dc9357SAndroid Build Coastguard Worker   res.Add_Dot();
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker   const char *s;
329*f6dc9357SAndroid Build Coastguard Worker 
330*f6dc9357SAndroid Build Coastguard Worker   if (!_compressor.IsEmpty())
331*f6dc9357SAndroid Build Coastguard Worker   {
332*f6dc9357SAndroid Build Coastguard Worker     s = _compressor;
333*f6dc9357SAndroid Build Coastguard Worker     if (_compressor == "bzip2")
334*f6dc9357SAndroid Build Coastguard Worker       s = "bz2";
335*f6dc9357SAndroid Build Coastguard Worker     else if (_compressor == "gzip")
336*f6dc9357SAndroid Build Coastguard Worker       s = "gz";
337*f6dc9357SAndroid Build Coastguard Worker     else if (_compressor == "zstd")
338*f6dc9357SAndroid Build Coastguard Worker       s = "zst";
339*f6dc9357SAndroid Build Coastguard Worker   }
340*f6dc9357SAndroid Build Coastguard Worker   else
341*f6dc9357SAndroid Build Coastguard Worker   {
342*f6dc9357SAndroid Build Coastguard Worker     const Byte *p = _payloadSig;
343*f6dc9357SAndroid Build Coastguard Worker     if (p[0] == 0x1F && p[1] == 0x8B && p[2] == 8)
344*f6dc9357SAndroid Build Coastguard Worker       s = "gz";
345*f6dc9357SAndroid Build Coastguard Worker     else if (p[0] == 0xFD && p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' && p[5] == 0)
346*f6dc9357SAndroid Build Coastguard Worker       s = "xz";
347*f6dc9357SAndroid Build Coastguard Worker     else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h' && p[3] >= '1' && p[3] <= '9')
348*f6dc9357SAndroid Build Coastguard Worker       s = "bz2";
349*f6dc9357SAndroid Build Coastguard Worker     else if (p[0] == 0x28 && p[1] == 0xb5 && p[2] == 0x2f && p[3] == 0xfd)
350*f6dc9357SAndroid Build Coastguard Worker       s = "zst";
351*f6dc9357SAndroid Build Coastguard Worker     else
352*f6dc9357SAndroid Build Coastguard Worker       s = "lzma";
353*f6dc9357SAndroid Build Coastguard Worker   }
354*f6dc9357SAndroid Build Coastguard Worker 
355*f6dc9357SAndroid Build Coastguard Worker   res += s;
356*f6dc9357SAndroid Build Coastguard Worker }
357*f6dc9357SAndroid Build Coastguard Worker 
358*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
359*f6dc9357SAndroid Build Coastguard Worker {
360*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
361*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
362*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
363*f6dc9357SAndroid Build Coastguard Worker   {
364*f6dc9357SAndroid Build Coastguard Worker     case kpidMainSubfile: prop = (UInt32)0; break;
365*f6dc9357SAndroid Build Coastguard Worker 
366*f6dc9357SAndroid Build Coastguard Worker     case kpidHeadersSize: prop = _headersSize; break;
367*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize: if (_phySize_Defined) prop = _phySize; break;
368*f6dc9357SAndroid Build Coastguard Worker 
369*f6dc9357SAndroid Build Coastguard Worker     case kpidMTime:
370*f6dc9357SAndroid Build Coastguard Worker     case kpidCTime:
371*f6dc9357SAndroid Build Coastguard Worker       SetTime(prop);
372*f6dc9357SAndroid Build Coastguard Worker       break;
373*f6dc9357SAndroid Build Coastguard Worker 
374*f6dc9357SAndroid Build Coastguard Worker     case kpidCpu:
375*f6dc9357SAndroid Build Coastguard Worker       {
376*f6dc9357SAndroid Build Coastguard Worker         AString s;
377*f6dc9357SAndroid Build Coastguard Worker         AddCPU(s);
378*f6dc9357SAndroid Build Coastguard Worker         /*
379*f6dc9357SAndroid Build Coastguard Worker         if (_lead.Type == kRpmType_Src)
380*f6dc9357SAndroid Build Coastguard Worker           s = "src";
381*f6dc9357SAndroid Build Coastguard Worker         */
382*f6dc9357SAndroid Build Coastguard Worker         SetStringProp(s, prop);
383*f6dc9357SAndroid Build Coastguard Worker         break;
384*f6dc9357SAndroid Build Coastguard Worker       }
385*f6dc9357SAndroid Build Coastguard Worker 
386*f6dc9357SAndroid Build Coastguard Worker     case kpidHostOS:
387*f6dc9357SAndroid Build Coastguard Worker       {
388*f6dc9357SAndroid Build Coastguard Worker         if (!_os.IsEmpty())
389*f6dc9357SAndroid Build Coastguard Worker           SetStringProp(_os, prop);
390*f6dc9357SAndroid Build Coastguard Worker         else
391*f6dc9357SAndroid Build Coastguard Worker         {
392*f6dc9357SAndroid Build Coastguard Worker           TYPE_TO_PROP(k_OS, _lead.Os, prop);
393*f6dc9357SAndroid Build Coastguard Worker         }
394*f6dc9357SAndroid Build Coastguard Worker         break;
395*f6dc9357SAndroid Build Coastguard Worker       }
396*f6dc9357SAndroid Build Coastguard Worker 
397*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_RPM_SHOW_METADATA
398*f6dc9357SAndroid Build Coastguard Worker     // case kpidComment: SetStringProp(_metadata, prop); break;
399*f6dc9357SAndroid Build Coastguard Worker     #endif
400*f6dc9357SAndroid Build Coastguard Worker 
401*f6dc9357SAndroid Build Coastguard Worker     case kpidName:
402*f6dc9357SAndroid Build Coastguard Worker     {
403*f6dc9357SAndroid Build Coastguard Worker       SetStringProp(GetBaseName() + ".rpm", prop);
404*f6dc9357SAndroid Build Coastguard Worker       break;
405*f6dc9357SAndroid Build Coastguard Worker     }
406*f6dc9357SAndroid Build Coastguard Worker   }
407*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
408*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
409*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
410*f6dc9357SAndroid Build Coastguard Worker }
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
416*f6dc9357SAndroid Build Coastguard Worker   if (index == 0)
417*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
418*f6dc9357SAndroid Build Coastguard Worker   {
419*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
420*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
421*f6dc9357SAndroid Build Coastguard Worker       prop = _size;
422*f6dc9357SAndroid Build Coastguard Worker       break;
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker     case kpidMTime:
425*f6dc9357SAndroid Build Coastguard Worker     case kpidCTime:
426*f6dc9357SAndroid Build Coastguard Worker       SetTime(prop);
427*f6dc9357SAndroid Build Coastguard Worker       break;
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker     case kpidPath:
430*f6dc9357SAndroid Build Coastguard Worker     {
431*f6dc9357SAndroid Build Coastguard Worker       AString s (GetBaseName());
432*f6dc9357SAndroid Build Coastguard Worker       s.Add_Dot();
433*f6dc9357SAndroid Build Coastguard Worker       AddSubFileExtension(s);
434*f6dc9357SAndroid Build Coastguard Worker       SetStringProp(s, prop);
435*f6dc9357SAndroid Build Coastguard Worker       break;
436*f6dc9357SAndroid Build Coastguard Worker     }
437*f6dc9357SAndroid Build Coastguard Worker 
438*f6dc9357SAndroid Build Coastguard Worker     /*
439*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension:
440*f6dc9357SAndroid Build Coastguard Worker     {
441*f6dc9357SAndroid Build Coastguard Worker       prop = GetSubFileExtension();
442*f6dc9357SAndroid Build Coastguard Worker       break;
443*f6dc9357SAndroid Build Coastguard Worker     }
444*f6dc9357SAndroid Build Coastguard Worker     */
445*f6dc9357SAndroid Build Coastguard Worker   }
446*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_RPM_SHOW_METADATA
447*f6dc9357SAndroid Build Coastguard Worker   else
448*f6dc9357SAndroid Build Coastguard Worker   {
449*f6dc9357SAndroid Build Coastguard Worker     index--;
450*f6dc9357SAndroid Build Coastguard Worker     if (index > _metaFiles.Size())
451*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
452*f6dc9357SAndroid Build Coastguard Worker     const CMetaFile &meta = _metaFiles[index];
453*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
454*f6dc9357SAndroid Build Coastguard Worker     {
455*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:
456*f6dc9357SAndroid Build Coastguard Worker       case kpidPackSize:
457*f6dc9357SAndroid Build Coastguard Worker         prop = meta.Size;
458*f6dc9357SAndroid Build Coastguard Worker         break;
459*f6dc9357SAndroid Build Coastguard Worker 
460*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime:
461*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime:
462*f6dc9357SAndroid Build Coastguard Worker         SetTime(prop);
463*f6dc9357SAndroid Build Coastguard Worker         break;
464*f6dc9357SAndroid Build Coastguard Worker 
465*f6dc9357SAndroid Build Coastguard Worker       case kpidPath:
466*f6dc9357SAndroid Build Coastguard Worker       {
467*f6dc9357SAndroid Build Coastguard Worker         AString s ("[META]");
468*f6dc9357SAndroid Build Coastguard Worker         s.Add_PathSepar();
469*f6dc9357SAndroid Build Coastguard Worker         s.Add_UInt32(meta.Tag);
470*f6dc9357SAndroid Build Coastguard Worker         prop = s;
471*f6dc9357SAndroid Build Coastguard Worker         break;
472*f6dc9357SAndroid Build Coastguard Worker       }
473*f6dc9357SAndroid Build Coastguard Worker     }
474*f6dc9357SAndroid Build Coastguard Worker   }
475*f6dc9357SAndroid Build Coastguard Worker   #endif
476*f6dc9357SAndroid Build Coastguard Worker 
477*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
478*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
479*f6dc9357SAndroid Build Coastguard Worker }
480*f6dc9357SAndroid Build Coastguard Worker 
481*f6dc9357SAndroid Build Coastguard Worker 
482*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
483*f6dc9357SAndroid Build Coastguard Worker {
484*f6dc9357SAndroid Build Coastguard Worker   UInt32 numEntries;
485*f6dc9357SAndroid Build Coastguard Worker   UInt32 dataLen;
486*f6dc9357SAndroid Build Coastguard Worker   {
487*f6dc9357SAndroid Build Coastguard Worker     char buf[k_HeaderSig_Size];
488*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size))
489*f6dc9357SAndroid Build Coastguard Worker     if (Get32(buf) != 0x8EADE801) // buf[3] = 0x01 - is version
490*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
491*f6dc9357SAndroid Build Coastguard Worker     // reserved = Get32(buf + 4);
492*f6dc9357SAndroid Build Coastguard Worker     numEntries = Get32(buf + 8);
493*f6dc9357SAndroid Build Coastguard Worker     dataLen = Get32(buf + 12);
494*f6dc9357SAndroid Build Coastguard Worker     if (numEntries >= 1 << 24)
495*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
496*f6dc9357SAndroid Build Coastguard Worker   }
497*f6dc9357SAndroid Build Coastguard Worker   size_t indexSize = (size_t)numEntries * k_Entry_Size;
498*f6dc9357SAndroid Build Coastguard Worker   size_t headerSize = indexSize + dataLen;
499*f6dc9357SAndroid Build Coastguard Worker   if (headerSize < dataLen)
500*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
501*f6dc9357SAndroid Build Coastguard Worker   CByteBuffer buffer(headerSize);
502*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream_FALSE(stream, buffer, headerSize))
503*f6dc9357SAndroid Build Coastguard Worker 
504*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numEntries; i++)
505*f6dc9357SAndroid Build Coastguard Worker   {
506*f6dc9357SAndroid Build Coastguard Worker     CEntry entry;
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker     entry.Parse(buffer + (size_t)i * k_Entry_Size);
509*f6dc9357SAndroid Build Coastguard Worker     if (entry.Offset > dataLen)
510*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
511*f6dc9357SAndroid Build Coastguard Worker 
512*f6dc9357SAndroid Build Coastguard Worker     const Byte *p = buffer + indexSize + entry.Offset;
513*f6dc9357SAndroid Build Coastguard Worker     size_t rem = dataLen - entry.Offset;
514*f6dc9357SAndroid Build Coastguard Worker 
515*f6dc9357SAndroid Build Coastguard Worker     if (!isMainHeader)
516*f6dc9357SAndroid Build Coastguard Worker     {
517*f6dc9357SAndroid Build Coastguard Worker       if (entry.Tag == RPMSIGTAG_SIZE &&
518*f6dc9357SAndroid Build Coastguard Worker           entry.Type == k_EntryType_INT32)
519*f6dc9357SAndroid Build Coastguard Worker       {
520*f6dc9357SAndroid Build Coastguard Worker         if (rem < 4 || entry.Count != 1)
521*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
522*f6dc9357SAndroid Build Coastguard Worker         _headerPlusPayload_Size = Get32(p);
523*f6dc9357SAndroid Build Coastguard Worker         _headerPlusPayload_Size_Defined = true;
524*f6dc9357SAndroid Build Coastguard Worker       }
525*f6dc9357SAndroid Build Coastguard Worker     }
526*f6dc9357SAndroid Build Coastguard Worker     else
527*f6dc9357SAndroid Build Coastguard Worker     {
528*f6dc9357SAndroid Build Coastguard Worker       #ifdef Z7_RPM_SHOW_METADATA
529*f6dc9357SAndroid Build Coastguard Worker       {
530*f6dc9357SAndroid Build Coastguard Worker         _metadata.Add_UInt32(entry.Tag);
531*f6dc9357SAndroid Build Coastguard Worker         _metadata += ": ";
532*f6dc9357SAndroid Build Coastguard Worker       }
533*f6dc9357SAndroid Build Coastguard Worker       #endif
534*f6dc9357SAndroid Build Coastguard Worker 
535*f6dc9357SAndroid Build Coastguard Worker       if (entry.Type == k_EntryType_STRING)
536*f6dc9357SAndroid Build Coastguard Worker       {
537*f6dc9357SAndroid Build Coastguard Worker         if (entry.Count != 1)
538*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
539*f6dc9357SAndroid Build Coastguard Worker         size_t j;
540*f6dc9357SAndroid Build Coastguard Worker         for (j = 0; j < rem && p[j] != 0; j++);
541*f6dc9357SAndroid Build Coastguard Worker         if (j == rem)
542*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
543*f6dc9357SAndroid Build Coastguard Worker         AString s((const char *)p);
544*f6dc9357SAndroid Build Coastguard Worker         switch (entry.Tag)
545*f6dc9357SAndroid Build Coastguard Worker         {
546*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_NAME: _name = s; break;
547*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_VERSION: _version = s; break;
548*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_RELEASE: _release = s; break;
549*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_ARCH: _arch = s; break;
550*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_OS: _os = s; break;
551*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_PAYLOADFORMAT: _format = s; break;
552*f6dc9357SAndroid Build Coastguard Worker           case RPMTAG_PAYLOADCOMPRESSOR: _compressor = s; break;
553*f6dc9357SAndroid Build Coastguard Worker         }
554*f6dc9357SAndroid Build Coastguard Worker 
555*f6dc9357SAndroid Build Coastguard Worker         #ifdef Z7_RPM_SHOW_METADATA
556*f6dc9357SAndroid Build Coastguard Worker         _metadata += s;
557*f6dc9357SAndroid Build Coastguard Worker         #endif
558*f6dc9357SAndroid Build Coastguard Worker       }
559*f6dc9357SAndroid Build Coastguard Worker       else if (entry.Type == k_EntryType_INT32)
560*f6dc9357SAndroid Build Coastguard Worker       {
561*f6dc9357SAndroid Build Coastguard Worker         if (rem / 4 < entry.Count)
562*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
563*f6dc9357SAndroid Build Coastguard Worker         if (entry.Tag == RPMTAG_BUILDTIME)
564*f6dc9357SAndroid Build Coastguard Worker         {
565*f6dc9357SAndroid Build Coastguard Worker           if (entry.Count != 1)
566*f6dc9357SAndroid Build Coastguard Worker             return S_FALSE;
567*f6dc9357SAndroid Build Coastguard Worker           _buildTime = Get32(p);
568*f6dc9357SAndroid Build Coastguard Worker           _time_Defined = true;
569*f6dc9357SAndroid Build Coastguard Worker         }
570*f6dc9357SAndroid Build Coastguard Worker 
571*f6dc9357SAndroid Build Coastguard Worker         #ifdef Z7_RPM_SHOW_METADATA
572*f6dc9357SAndroid Build Coastguard Worker         for (UInt32 t = 0; t < entry.Count; t++)
573*f6dc9357SAndroid Build Coastguard Worker         {
574*f6dc9357SAndroid Build Coastguard Worker           if (t != 0)
575*f6dc9357SAndroid Build Coastguard Worker             _metadata.Add_Space();
576*f6dc9357SAndroid Build Coastguard Worker           _metadata.Add_UInt32(Get32(p + t * 4));
577*f6dc9357SAndroid Build Coastguard Worker         }
578*f6dc9357SAndroid Build Coastguard Worker         #endif
579*f6dc9357SAndroid Build Coastguard Worker       }
580*f6dc9357SAndroid Build Coastguard Worker 
581*f6dc9357SAndroid Build Coastguard Worker       #ifdef Z7_RPM_SHOW_METADATA
582*f6dc9357SAndroid Build Coastguard Worker 
583*f6dc9357SAndroid Build Coastguard Worker       else if (
584*f6dc9357SAndroid Build Coastguard Worker           entry.Type == k_EntryType_STRING_ARRAY ||
585*f6dc9357SAndroid Build Coastguard Worker           entry.Type == k_EntryType_I18NSTRING)
586*f6dc9357SAndroid Build Coastguard Worker       {
587*f6dc9357SAndroid Build Coastguard Worker         const Byte *p2 = p;
588*f6dc9357SAndroid Build Coastguard Worker         size_t rem2 = rem;
589*f6dc9357SAndroid Build Coastguard Worker         for (UInt32 t = 0; t < entry.Count; t++)
590*f6dc9357SAndroid Build Coastguard Worker         {
591*f6dc9357SAndroid Build Coastguard Worker           if (rem2 == 0)
592*f6dc9357SAndroid Build Coastguard Worker             return S_FALSE;
593*f6dc9357SAndroid Build Coastguard Worker           if (t != 0)
594*f6dc9357SAndroid Build Coastguard Worker             _metadata.Add_LF();
595*f6dc9357SAndroid Build Coastguard Worker           size_t j;
596*f6dc9357SAndroid Build Coastguard Worker           for (j = 0; j < rem2 && p2[j] != 0; j++);
597*f6dc9357SAndroid Build Coastguard Worker           if (j == rem2)
598*f6dc9357SAndroid Build Coastguard Worker             return S_FALSE;
599*f6dc9357SAndroid Build Coastguard Worker           _metadata += (const char *)p2;
600*f6dc9357SAndroid Build Coastguard Worker           j++;
601*f6dc9357SAndroid Build Coastguard Worker           p2 += j;
602*f6dc9357SAndroid Build Coastguard Worker           rem2 -= j;
603*f6dc9357SAndroid Build Coastguard Worker         }
604*f6dc9357SAndroid Build Coastguard Worker       }
605*f6dc9357SAndroid Build Coastguard Worker       else if (entry.Type == k_EntryType_INT16)
606*f6dc9357SAndroid Build Coastguard Worker       {
607*f6dc9357SAndroid Build Coastguard Worker         if (rem / 2 < entry.Count)
608*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
609*f6dc9357SAndroid Build Coastguard Worker         for (UInt32 t = 0; t < entry.Count; t++)
610*f6dc9357SAndroid Build Coastguard Worker         {
611*f6dc9357SAndroid Build Coastguard Worker           if (t != 0)
612*f6dc9357SAndroid Build Coastguard Worker             _metadata.Add_Space();
613*f6dc9357SAndroid Build Coastguard Worker           _metadata.Add_UInt32(Get16(p + t * 2));
614*f6dc9357SAndroid Build Coastguard Worker         }
615*f6dc9357SAndroid Build Coastguard Worker       }
616*f6dc9357SAndroid Build Coastguard Worker       else if (entry.Type == k_EntryType_BIN)
617*f6dc9357SAndroid Build Coastguard Worker       {
618*f6dc9357SAndroid Build Coastguard Worker         if (rem < entry.Count)
619*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
620*f6dc9357SAndroid Build Coastguard Worker         for (UInt32 t = 0; t < entry.Count; t++)
621*f6dc9357SAndroid Build Coastguard Worker         {
622*f6dc9357SAndroid Build Coastguard Worker           const unsigned b = p[t];
623*f6dc9357SAndroid Build Coastguard Worker           _metadata += GET_HEX_CHAR_UPPER(b >> 4);
624*f6dc9357SAndroid Build Coastguard Worker           _metadata += GET_HEX_CHAR_UPPER(b & 0xF);
625*f6dc9357SAndroid Build Coastguard Worker         }
626*f6dc9357SAndroid Build Coastguard Worker       }
627*f6dc9357SAndroid Build Coastguard Worker       else
628*f6dc9357SAndroid Build Coastguard Worker       {
629*f6dc9357SAndroid Build Coastguard Worker         // p = p;
630*f6dc9357SAndroid Build Coastguard Worker       }
631*f6dc9357SAndroid Build Coastguard Worker 
632*f6dc9357SAndroid Build Coastguard Worker       _metadata.Add_LF();
633*f6dc9357SAndroid Build Coastguard Worker       #endif
634*f6dc9357SAndroid Build Coastguard Worker     }
635*f6dc9357SAndroid Build Coastguard Worker 
636*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_RPM_SHOW_METADATA
637*f6dc9357SAndroid Build Coastguard Worker     CMetaFile meta;
638*f6dc9357SAndroid Build Coastguard Worker     meta.Offset = entry.Offset;
639*f6dc9357SAndroid Build Coastguard Worker     meta.Tag = entry.Tag;
640*f6dc9357SAndroid Build Coastguard Worker     meta.Size = entry.Count;
641*f6dc9357SAndroid Build Coastguard Worker     _metaFiles.Add(meta);
642*f6dc9357SAndroid Build Coastguard Worker     #endif
643*f6dc9357SAndroid Build Coastguard Worker   }
644*f6dc9357SAndroid Build Coastguard Worker 
645*f6dc9357SAndroid Build Coastguard Worker   headerSize += k_HeaderSig_Size;
646*f6dc9357SAndroid Build Coastguard Worker   _headersSize += headerSize;
647*f6dc9357SAndroid Build Coastguard Worker   if (isMainHeader && _headerPlusPayload_Size_Defined)
648*f6dc9357SAndroid Build Coastguard Worker   {
649*f6dc9357SAndroid Build Coastguard Worker     if (_headerPlusPayload_Size < headerSize)
650*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
651*f6dc9357SAndroid Build Coastguard Worker     _payloadSize = _headerPlusPayload_Size - headerSize;
652*f6dc9357SAndroid Build Coastguard Worker     _size = _payloadSize;
653*f6dc9357SAndroid Build Coastguard Worker     _phySize = _headersSize + _payloadSize;
654*f6dc9357SAndroid Build Coastguard Worker     _payloadSize_Defined = true;
655*f6dc9357SAndroid Build Coastguard Worker     _phySize_Defined = true;
656*f6dc9357SAndroid Build Coastguard Worker   }
657*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
658*f6dc9357SAndroid Build Coastguard Worker }
659*f6dc9357SAndroid Build Coastguard Worker 
660*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::Open2(ISequentialInStream *stream)
661*f6dc9357SAndroid Build Coastguard Worker {
662*f6dc9357SAndroid Build Coastguard Worker   {
663*f6dc9357SAndroid Build Coastguard Worker     Byte buf[kLeadSize];
664*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, buf, kLeadSize))
665*f6dc9357SAndroid Build Coastguard Worker     if (Get32(buf) != 0xEDABEEDB)
666*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
667*f6dc9357SAndroid Build Coastguard Worker     _lead.Parse(buf);
668*f6dc9357SAndroid Build Coastguard Worker     if (!_lead.IsSupported())
669*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
670*f6dc9357SAndroid Build Coastguard Worker   }
671*f6dc9357SAndroid Build Coastguard Worker 
672*f6dc9357SAndroid Build Coastguard Worker   _headersSize = kLeadSize;
673*f6dc9357SAndroid Build Coastguard Worker 
674*f6dc9357SAndroid Build Coastguard Worker   if (_lead.SignatureType == RPMSIG_NONE)
675*f6dc9357SAndroid Build Coastguard Worker   {
676*f6dc9357SAndroid Build Coastguard Worker 
677*f6dc9357SAndroid Build Coastguard Worker   }
678*f6dc9357SAndroid Build Coastguard Worker   else if (_lead.SignatureType == RPMSIG_PGP262_1024)
679*f6dc9357SAndroid Build Coastguard Worker   {
680*f6dc9357SAndroid Build Coastguard Worker     Byte temp[256];
681*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, temp, sizeof(temp)))
682*f6dc9357SAndroid Build Coastguard Worker   }
683*f6dc9357SAndroid Build Coastguard Worker   else if (_lead.SignatureType == RPMSIG_HEADERSIG)
684*f6dc9357SAndroid Build Coastguard Worker   {
685*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadHeader(stream, false))
686*f6dc9357SAndroid Build Coastguard Worker     unsigned pos = (unsigned)_headersSize & 7;
687*f6dc9357SAndroid Build Coastguard Worker     if (pos != 0)
688*f6dc9357SAndroid Build Coastguard Worker     {
689*f6dc9357SAndroid Build Coastguard Worker       Byte temp[8];
690*f6dc9357SAndroid Build Coastguard Worker       unsigned num = 8 - pos;
691*f6dc9357SAndroid Build Coastguard Worker       RINOK(ReadStream_FALSE(stream, temp, num))
692*f6dc9357SAndroid Build Coastguard Worker       _headersSize += num;
693*f6dc9357SAndroid Build Coastguard Worker     }
694*f6dc9357SAndroid Build Coastguard Worker   }
695*f6dc9357SAndroid Build Coastguard Worker   else
696*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
697*f6dc9357SAndroid Build Coastguard Worker 
698*f6dc9357SAndroid Build Coastguard Worker   return ReadHeader(stream, true);
699*f6dc9357SAndroid Build Coastguard Worker }
700*f6dc9357SAndroid Build Coastguard Worker 
701*f6dc9357SAndroid Build Coastguard Worker 
702*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *))
703*f6dc9357SAndroid Build Coastguard Worker {
704*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
705*f6dc9357SAndroid Build Coastguard Worker   {
706*f6dc9357SAndroid Build Coastguard Worker     Close();
707*f6dc9357SAndroid Build Coastguard Worker     RINOK(Open2(inStream))
708*f6dc9357SAndroid Build Coastguard Worker 
709*f6dc9357SAndroid Build Coastguard Worker     // start of payload is allowed to be unaligned
710*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig)))
711*f6dc9357SAndroid Build Coastguard Worker 
712*f6dc9357SAndroid Build Coastguard Worker     if (!_payloadSize_Defined)
713*f6dc9357SAndroid Build Coastguard Worker     {
714*f6dc9357SAndroid Build Coastguard Worker       UInt64 endPos;
715*f6dc9357SAndroid Build Coastguard Worker       RINOK(InStream_GetSize_SeekToEnd(inStream, endPos))
716*f6dc9357SAndroid Build Coastguard Worker       _size = endPos - _headersSize;
717*f6dc9357SAndroid Build Coastguard Worker     }
718*f6dc9357SAndroid Build Coastguard Worker     _stream = inStream;
719*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
720*f6dc9357SAndroid Build Coastguard Worker   }
721*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
722*f6dc9357SAndroid Build Coastguard Worker }
723*f6dc9357SAndroid Build Coastguard Worker 
724*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
725*f6dc9357SAndroid Build Coastguard Worker {
726*f6dc9357SAndroid Build Coastguard Worker   _headersSize = 0;
727*f6dc9357SAndroid Build Coastguard Worker   _payloadSize = 0;
728*f6dc9357SAndroid Build Coastguard Worker   _size = 0;
729*f6dc9357SAndroid Build Coastguard Worker   _phySize = 0;
730*f6dc9357SAndroid Build Coastguard Worker   _headerPlusPayload_Size = 0;
731*f6dc9357SAndroid Build Coastguard Worker 
732*f6dc9357SAndroid Build Coastguard Worker   _payloadSize_Defined = false;
733*f6dc9357SAndroid Build Coastguard Worker   _phySize_Defined = false;
734*f6dc9357SAndroid Build Coastguard Worker   _headerPlusPayload_Size_Defined = false;
735*f6dc9357SAndroid Build Coastguard Worker   _time_Defined = false;
736*f6dc9357SAndroid Build Coastguard Worker 
737*f6dc9357SAndroid Build Coastguard Worker   _name.Empty();
738*f6dc9357SAndroid Build Coastguard Worker   _version.Empty();
739*f6dc9357SAndroid Build Coastguard Worker   _release.Empty();
740*f6dc9357SAndroid Build Coastguard Worker   _arch.Empty();
741*f6dc9357SAndroid Build Coastguard Worker   _os.Empty();
742*f6dc9357SAndroid Build Coastguard Worker 
743*f6dc9357SAndroid Build Coastguard Worker   _format.Empty();
744*f6dc9357SAndroid Build Coastguard Worker   _compressor.Empty();
745*f6dc9357SAndroid Build Coastguard Worker 
746*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_RPM_SHOW_METADATA
747*f6dc9357SAndroid Build Coastguard Worker   _metadata.Empty();
748*f6dc9357SAndroid Build Coastguard Worker   _metaFiles.Size();
749*f6dc9357SAndroid Build Coastguard Worker   #endif
750*f6dc9357SAndroid Build Coastguard Worker 
751*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
752*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
753*f6dc9357SAndroid Build Coastguard Worker }
754*f6dc9357SAndroid Build Coastguard Worker 
755*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
756*f6dc9357SAndroid Build Coastguard Worker {
757*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1
758*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_RPM_SHOW_METADATA
759*f6dc9357SAndroid Build Coastguard Worker     + _metaFiles.Size()
760*f6dc9357SAndroid Build Coastguard Worker   #endif
761*f6dc9357SAndroid Build Coastguard Worker   ;
762*f6dc9357SAndroid Build Coastguard Worker 
763*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
764*f6dc9357SAndroid Build Coastguard Worker }
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[] = { 0xED, 0xAB, 0xEE, 0xDB};
767*f6dc9357SAndroid Build Coastguard Worker 
768*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I(
769*f6dc9357SAndroid Build Coastguard Worker   "Rpm", "rpm", NULL, 0xEB,
770*f6dc9357SAndroid Build Coastguard Worker   k_Signature,
771*f6dc9357SAndroid Build Coastguard Worker   0,
772*f6dc9357SAndroid Build Coastguard Worker   0,
773*f6dc9357SAndroid Build Coastguard Worker   NULL)
774*f6dc9357SAndroid Build Coastguard Worker 
775*f6dc9357SAndroid Build Coastguard Worker }}
776