Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/pax-rpm.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* pax rpm format
24
*/
25
26
#include "format.h"
27
28
#define RPM_MAGIC 0xedabeedb
29
#define RPM_CIGAM 0xdbeeabed
30
31
#define RPM_HEAD_MAGIC 0x8eade801
32
33
typedef struct
34
{
35
uint32_t magic;
36
uint8_t major;
37
uint8_t minor;
38
int16_t type;
39
} Rpm_magic_t;
40
41
typedef struct
42
{
43
int16_t archnum;
44
char name[66];
45
int16_t osnum;
46
int16_t sigtype;
47
char pad[16];
48
} Rpm_lead_t;
49
50
typedef struct
51
{
52
int16_t archnum;
53
char name[66];
54
uint32_t specoff;
55
uint32_t speclen;
56
uint32_t archoff;
57
} Rpm_lead_old_t;
58
59
typedef struct
60
{
61
uint32_t entries;
62
uint32_t datalen;
63
} Rpm_head_t;
64
65
typedef struct
66
{
67
uint32_t tag;
68
uint32_t type;
69
uint32_t offset;
70
uint32_t size;
71
} Rpm_entry_t;
72
73
static int
74
rpm_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
75
{
76
Rpm_magic_t magic;
77
Rpm_magic_t verify;
78
Rpm_lead_t lead;
79
Rpm_lead_old_t lead_old;
80
Rpm_head_t head;
81
char* s;
82
int i;
83
int swap;
84
long num;
85
unsigned char zip[2];
86
87
if (size < sizeof(magic))
88
return 0;
89
memcpy(&magic, buf, sizeof(magic));
90
verify.magic = RPM_MAGIC;
91
if ((swap = swapop(&verify.magic, &magic.magic, sizeof(magic.magic))) < 0)
92
return 0;
93
message((-2, "%s: magic swap=%d magic=%08x major=%d minor=%d", ap->name, swap, magic.magic, magic.major, magic.minor));
94
if (magic.major == 1)
95
{
96
if (size < (sizeof(magic) + sizeof(lead_old)))
97
return 0;
98
paxread(pax, ap, NiL, (off_t)sizeof(magic), (off_t)sizeof(magic), 0);
99
if (paxread(pax, ap, &lead_old, (off_t)sizeof(lead_old), (off_t)sizeof(lead_old), 0) <= 0)
100
return 0;
101
if (swap)
102
swapmem(swap, &lead_old, &lead_old, sizeof(lead_old));
103
if (paxseek(pax, ap, (off_t)lead_old.archoff, SEEK_SET, 0) != (off_t)lead_old.archoff)
104
{
105
error(2, "%s: %s embedded archive seek error", ap->name, fp->name);
106
return -1;
107
}
108
}
109
else if (magic.major)
110
{
111
if (size < (sizeof(magic) + sizeof(lead)))
112
return 0;
113
paxread(pax, ap, NiL, (off_t)sizeof(magic), (off_t)sizeof(magic), 0);
114
if (paxread(pax, ap, &lead, (off_t)sizeof(lead), (off_t)sizeof(lead), 0) <= 0)
115
return 0;
116
memcpy(state.volume, lead.name, sizeof(state.volume) - 1);
117
if (swap & 1)
118
swapmem(swap & 1, &lead, &lead, sizeof(lead));
119
message((-2, "%s: lead name=%s archnum=%d osnum=%d sigtype=%d", ap->name, state.volume, lead.archnum, lead.osnum, lead.sigtype));
120
if (s = strrchr(ap->name, '/'))
121
s++;
122
else
123
s = ap->name;
124
if (!memcmp(s, state.volume, strlen(state.volume)))
125
state.volume[0] = 0;
126
switch (lead.sigtype)
127
{
128
case 0:
129
num = 0;
130
break;
131
case 1:
132
num = 256;
133
if (paxread(pax, ap, NiL, (off_t)num, (off_t)num, 0) <= 0)
134
{
135
error(2, "%s: %s format header %ld byte data block expected", ap->name, fp->name, num);
136
return -1;
137
}
138
break;
139
case 5:
140
for (;;)
141
{
142
if (paxread(pax, ap, zip, (off_t)sizeof(zip), (off_t)sizeof(zip), 0) <= 0)
143
{
144
error(2, "%s: %s format header magic expected at offset %ld", ap->name, fp->name, ap->io->offset + ap->io->count);
145
return -1;
146
}
147
if (zip[0] == 0x1f && zip[1] == 0x8b)
148
{
149
paxunread(pax, ap, zip, (off_t)sizeof(zip));
150
break;
151
}
152
num = (ap->io->count - 2) & 7;
153
message((-2, "%s: align pad=%ld", ap->name, num ? (8 - num) : num));
154
switch (num)
155
{
156
case 0:
157
paxunread(pax, ap, zip, (off_t)2);
158
break;
159
case 7:
160
paxunread(pax, ap, zip + 1, (off_t)1);
161
break;
162
case 6:
163
break;
164
default:
165
num = 6 - num;
166
if (paxread(pax, ap, NiL, (off_t)num, (off_t)num, 0) <= 0)
167
{
168
error(2, "%s: %s format header %ld byte pad expected", ap->name, fp->name, num);
169
return -1;
170
}
171
break;
172
}
173
if (paxread(pax, ap, &verify, (off_t)sizeof(verify), (off_t)sizeof(verify), 0) <= 0)
174
{
175
error(2, "%s: %s format header magic expected at offset %ld", ap->name, fp->name, ap->io->offset + ap->io->count);
176
return -1;
177
}
178
if (((unsigned char*)&verify)[0] == 0x1f && ((unsigned char*)&verify)[1] == 0x8b)
179
{
180
paxunread(pax, ap, &verify, (off_t)sizeof(verify));
181
break;
182
}
183
if (swap)
184
{
185
swapmem(swap, &verify.magic, &verify.magic, sizeof(verify.magic));
186
if (swap & 1)
187
swapmem(swap & 1, &verify.type, &verify.type, sizeof(verify.type));
188
}
189
message((-2, "%s: verify magic=%08x major=%d minor=%d type=%d", ap->name, verify.magic, verify.major, verify.minor, verify.type));
190
if (verify.magic != RPM_HEAD_MAGIC)
191
{
192
error(2, "%s: invalid %s format signature header magic", ap->name, fp->name);
193
return -1;
194
}
195
if (paxread(pax, ap, &head, (off_t)sizeof(head), (off_t)sizeof(head), 0) <= 0)
196
{
197
error(2, "%s: %s format signature header expected", ap->name, fp->name);
198
return -1;
199
}
200
if (swap)
201
swapmem(swap, &head, &head, sizeof(head));
202
num = head.entries * sizeof(Rpm_entry_t) + head.datalen;
203
message((-2, "%s: head entries=%lu datalen=%lu num=%lu", ap->name, head.entries, head.datalen, num));
204
if (paxread(pax, ap, NiL, (off_t)num, (off_t)num, 0) <= 0)
205
{
206
error(2, "%s: %s format header %ld byte data block expected", ap->name, fp->name, num);
207
return -1;
208
}
209
}
210
break;
211
default:
212
error(2, "%s: %s format version %d.%d signature type %d not supported", ap->name, fp->name, magic.major, magic.minor, lead.sigtype);
213
return -1;
214
}
215
}
216
else
217
{
218
error(2, "%s: %s format version %d.%d not supported", ap->name, fp->name, magic.major, magic.minor);
219
return -1;
220
}
221
ap->entry = 0;
222
ap->swap = 0;
223
ap->swapio = 0;
224
ap->volume--;
225
i = state.volume[0];
226
if (getprologue(ap) <= 0)
227
{
228
error(2, "%s: %s format embedded archive expected", ap->name, fp->name);
229
return -1;
230
}
231
state.volume[0] = i;
232
ap->package = strdup(sfprints("%s %d.%d", fp->name, magic.major, magic.minor));
233
return 1;
234
}
235
236
Format_t pax_rpm_format =
237
{
238
"rpm",
239
0,
240
"Redhat rpm package encapsulated cpio",
241
0,
242
ARCHIVE|IN,
243
DEFBUFFER,
244
DEFBLOCKS,
245
0,
246
PAXNEXT(rpm),
247
0,
248
0,
249
rpm_getprologue,
250
};
251
252
PAXLIB(rpm)
253
254