|
krh@74
|
1 |
#include <stdio.h>
|
|
krh@74
|
2 |
#include <string.h>
|
|
krh@74
|
3 |
#include <sys/stat.h>
|
|
krh@74
|
4 |
#include <sys/mman.h>
|
|
krh@74
|
5 |
#include <fcntl.h>
|
|
krh@74
|
6 |
#include <unistd.h>
|
|
krh@74
|
7 |
#include <arpa/inet.h>
|
|
krh@74
|
8 |
#include <rpm/rpmlib.h>
|
|
krh@74
|
9 |
|
|
krh@75
|
10 |
#include "razor.h"
|
|
krh@75
|
11 |
|
|
krh@74
|
12 |
#define RPM_LEAD_SIZE 96
|
|
krh@74
|
13 |
|
|
krh@74
|
14 |
struct rpm_lead {
|
|
krh@74
|
15 |
unsigned char magic[4];
|
|
krh@74
|
16 |
unsigned char major;
|
|
krh@74
|
17 |
unsigned char minor;
|
|
krh@74
|
18 |
short type;
|
|
krh@74
|
19 |
short archnum;
|
|
krh@74
|
20 |
char name[66];
|
|
krh@74
|
21 |
short osnum;
|
|
krh@74
|
22 |
short signature_type;
|
|
krh@74
|
23 |
char reserved[16];
|
|
krh@74
|
24 |
};
|
|
krh@74
|
25 |
|
|
krh@74
|
26 |
struct rpm_header {
|
|
krh@74
|
27 |
unsigned char magic[4];
|
|
krh@74
|
28 |
unsigned char reserved[4];
|
|
krh@74
|
29 |
int nindex;
|
|
krh@74
|
30 |
int hsize;
|
|
krh@74
|
31 |
};
|
|
krh@74
|
32 |
|
|
krh@74
|
33 |
struct rpm_header_index {
|
|
krh@74
|
34 |
int tag;
|
|
krh@74
|
35 |
int type;
|
|
krh@74
|
36 |
int offset;
|
|
krh@74
|
37 |
int count;
|
|
krh@74
|
38 |
};
|
|
krh@74
|
39 |
|
|
krh@75
|
40 |
struct properties {
|
|
krh@75
|
41 |
struct rpm_header_index *name;
|
|
krh@75
|
42 |
struct rpm_header_index *version;
|
|
krh@75
|
43 |
struct rpm_header_index *flags;
|
|
krh@75
|
44 |
};
|
|
krh@75
|
45 |
|
|
krh@75
|
46 |
struct rpm {
|
|
krh@75
|
47 |
struct rpm_header *signature;
|
|
krh@75
|
48 |
struct rpm_header *header;
|
|
krh@75
|
49 |
|
|
krh@75
|
50 |
struct rpm_header_index *name;
|
|
krh@75
|
51 |
struct rpm_header_index *version;
|
|
krh@75
|
52 |
struct rpm_header_index *release;
|
|
krh@75
|
53 |
|
|
krh@75
|
54 |
struct rpm_header_index *dirnames;
|
|
krh@75
|
55 |
struct rpm_header_index *dirindexes;
|
|
krh@75
|
56 |
struct rpm_header_index *basenames;
|
|
krh@75
|
57 |
|
|
krh@75
|
58 |
struct properties provides;
|
|
krh@75
|
59 |
struct properties requires;
|
|
krh@75
|
60 |
struct properties obsoletes;
|
|
krh@75
|
61 |
struct properties conflicts;
|
|
krh@75
|
62 |
|
|
krh@75
|
63 |
const char *pool;
|
|
krh@75
|
64 |
void *map;
|
|
krh@75
|
65 |
size_t size;
|
|
krh@75
|
66 |
};
|
|
krh@75
|
67 |
|
|
krh@74
|
68 |
#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
|
|
krh@74
|
69 |
|
|
krh@75
|
70 |
static void
|
|
krh@75
|
71 |
import_properties(struct razor_importer *importer,
|
|
krh@75
|
72 |
struct properties *properties,
|
|
krh@75
|
73 |
const char *pool, unsigned long type)
|
|
krh@75
|
74 |
{
|
|
krh@75
|
75 |
const char *name, *version;
|
|
krh@75
|
76 |
int i, count;
|
|
krh@75
|
77 |
|
|
krh@75
|
78 |
/* assert: count is the same for all arrays */
|
|
krh@75
|
79 |
|
|
krh@75
|
80 |
if (properties->name == NULL)
|
|
krh@75
|
81 |
return;
|
|
krh@75
|
82 |
|
|
krh@75
|
83 |
count = ntohl(properties->name->count);
|
|
krh@75
|
84 |
name = pool + ntohl(properties->name->offset);
|
|
krh@75
|
85 |
version = pool + ntohl(properties->version->offset);
|
|
krh@75
|
86 |
for (i = 0; i < count; i++) {
|
|
krh@75
|
87 |
razor_importer_add_property(importer, name, version, type);
|
|
krh@75
|
88 |
name += strlen(name) + 1;
|
|
krh@75
|
89 |
version += strlen(version) + 1;
|
|
krh@75
|
90 |
}
|
|
krh@75
|
91 |
}
|
|
krh@75
|
92 |
|
|
krh@75
|
93 |
static void
|
|
krh@75
|
94 |
import_files(struct razor_importer *importer, struct rpm *rpm)
|
|
krh@75
|
95 |
{
|
|
krh@75
|
96 |
const char *name, **dir;
|
|
krh@75
|
97 |
unsigned long *index;
|
|
krh@75
|
98 |
int i, count;
|
|
krh@75
|
99 |
char buffer[256];
|
|
krh@75
|
100 |
|
|
krh@75
|
101 |
/* assert: count is the same for all arrays */
|
|
krh@75
|
102 |
|
|
krh@75
|
103 |
if (rpm->dirnames == NULL)
|
|
krh@75
|
104 |
return;
|
|
krh@75
|
105 |
|
|
krh@75
|
106 |
count = ntohl(rpm->dirnames->count);
|
|
krh@75
|
107 |
dir = calloc(count, sizeof *dir);
|
|
krh@75
|
108 |
name = rpm->pool + ntohl(rpm->dirnames->offset);
|
|
krh@75
|
109 |
for (i = 0; i < count; i++) {
|
|
krh@75
|
110 |
dir[i] = name;
|
|
krh@75
|
111 |
name += strlen(name) + 1;
|
|
krh@75
|
112 |
}
|
|
krh@75
|
113 |
|
|
krh@75
|
114 |
count = ntohl(rpm->basenames->count);
|
|
krh@75
|
115 |
index = (unsigned long *) (rpm->pool + ntohl(rpm->dirindexes->offset));
|
|
krh@75
|
116 |
name = rpm->pool + ntohl(rpm->basenames->offset);
|
|
krh@75
|
117 |
for (i = 0; i < count; i++) {
|
|
krh@75
|
118 |
snprintf(buffer, sizeof buffer,
|
|
krh@75
|
119 |
"%s%s", dir[ntohl(*index)], name);
|
|
krh@75
|
120 |
razor_importer_add_file(importer, buffer);
|
|
krh@75
|
121 |
name += strlen(name) + 1;
|
|
krh@75
|
122 |
index++;
|
|
krh@75
|
123 |
}
|
|
krh@75
|
124 |
}
|
|
krh@75
|
125 |
|
|
krh@75
|
126 |
static int
|
|
krh@75
|
127 |
razor_rpm_open(struct rpm *rpm, const char *filename)
|
|
krh@74
|
128 |
{
|
|
krh@74
|
129 |
struct rpm_header_index *base, *index;
|
|
krh@75
|
130 |
struct stat buf;
|
|
krh@75
|
131 |
int fd, nindex, hsize, i;
|
|
krh@74
|
132 |
|
|
krh@75
|
133 |
memset(rpm, 0, sizeof *rpm);
|
|
krh@75
|
134 |
if (stat(filename, &buf) < 0) {
|
|
krh@75
|
135 |
fprintf(stderr, "no such file %s (%m)\n", filename);
|
|
krh@75
|
136 |
return -1;
|
|
krh@75
|
137 |
}
|
|
krh@74
|
138 |
|
|
krh@75
|
139 |
fd = open(filename, O_RDONLY);
|
|
krh@75
|
140 |
if (fd < 0) {
|
|
krh@75
|
141 |
fprintf(stderr, "couldn't open %s\n", filename);
|
|
krh@75
|
142 |
return -1;
|
|
krh@75
|
143 |
}
|
|
krh@75
|
144 |
rpm->size = buf.st_size;
|
|
krh@75
|
145 |
rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
krh@75
|
146 |
if (rpm->map == MAP_FAILED) {
|
|
krh@75
|
147 |
fprintf(stderr, "couldn't mmap %s\n", filename);
|
|
krh@75
|
148 |
return -1;
|
|
krh@75
|
149 |
}
|
|
krh@75
|
150 |
close(fd);
|
|
krh@75
|
151 |
|
|
krh@75
|
152 |
rpm->signature = rpm->map + RPM_LEAD_SIZE;
|
|
krh@75
|
153 |
nindex = ntohl(rpm->signature->nindex);
|
|
krh@75
|
154 |
hsize = ntohl(rpm->signature->hsize);
|
|
krh@75
|
155 |
rpm->header = (void *) (rpm->signature + 1) +
|
|
krh@75
|
156 |
ALIGN(nindex * sizeof *index + hsize, 8);
|
|
krh@75
|
157 |
|
|
krh@75
|
158 |
nindex = ntohl(rpm->header->nindex);
|
|
krh@75
|
159 |
base = (struct rpm_header_index *) (rpm->header + 1);
|
|
krh@75
|
160 |
rpm->pool = (void *) base + nindex * sizeof *index;
|
|
krh@75
|
161 |
|
|
krh@74
|
162 |
for (i = 0; i < nindex; i++) {
|
|
krh@74
|
163 |
index = base + i;
|
|
krh@75
|
164 |
switch (ntohl(index->tag)) {
|
|
krh@74
|
165 |
case RPMTAG_NAME:
|
|
krh@75
|
166 |
rpm->name = index;
|
|
krh@74
|
167 |
break;
|
|
krh@74
|
168 |
case RPMTAG_VERSION:
|
|
krh@75
|
169 |
rpm->version = index;
|
|
krh@74
|
170 |
break;
|
|
krh@74
|
171 |
case RPMTAG_RELEASE:
|
|
krh@75
|
172 |
rpm->release = index;
|
|
krh@74
|
173 |
break;
|
|
krh@75
|
174 |
|
|
krh@74
|
175 |
case RPMTAG_REQUIRENAME:
|
|
krh@75
|
176 |
rpm->requires.name = index;
|
|
krh@74
|
177 |
break;
|
|
krh@75
|
178 |
case RPMTAG_REQUIREVERSION:
|
|
krh@75
|
179 |
rpm->requires.version = index;
|
|
krh@74
|
180 |
break;
|
|
krh@75
|
181 |
case RPMTAG_REQUIREFLAGS:
|
|
krh@75
|
182 |
rpm->requires.flags = index;
|
|
krh@75
|
183 |
break;
|
|
krh@74
|
184 |
|
|
krh@75
|
185 |
case RPMTAG_PROVIDENAME:
|
|
krh@75
|
186 |
rpm->provides.name = index;
|
|
krh@74
|
187 |
break;
|
|
krh@75
|
188 |
case RPMTAG_PROVIDEVERSION:
|
|
krh@75
|
189 |
rpm->provides.version = index;
|
|
krh@75
|
190 |
break;
|
|
krh@75
|
191 |
case RPMTAG_PROVIDEFLAGS:
|
|
krh@75
|
192 |
rpm->provides.flags = index;
|
|
krh@75
|
193 |
break;
|
|
krh@75
|
194 |
|
|
krh@75
|
195 |
case RPMTAG_OBSOLETENAME:
|
|
krh@75
|
196 |
rpm->obsoletes.name = index;
|
|
krh@75
|
197 |
break;
|
|
krh@75
|
198 |
case RPMTAG_OBSOLETEVERSION:
|
|
krh@75
|
199 |
rpm->obsoletes.version = index;
|
|
krh@75
|
200 |
break;
|
|
krh@75
|
201 |
case RPMTAG_OBSOLETEFLAGS:
|
|
krh@75
|
202 |
rpm->obsoletes.flags = index;
|
|
krh@75
|
203 |
break;
|
|
krh@75
|
204 |
|
|
krh@75
|
205 |
case RPMTAG_CONFLICTNAME:
|
|
krh@75
|
206 |
rpm->conflicts.name = index;
|
|
krh@75
|
207 |
break;
|
|
krh@75
|
208 |
case RPMTAG_CONFLICTVERSION:
|
|
krh@75
|
209 |
rpm->conflicts.version = index;
|
|
krh@75
|
210 |
break;
|
|
krh@75
|
211 |
case RPMTAG_CONFLICTFLAGS:
|
|
krh@75
|
212 |
rpm->conflicts.flags = index;
|
|
krh@75
|
213 |
break;
|
|
krh@75
|
214 |
|
|
krh@75
|
215 |
case RPMTAG_DIRINDEXES:
|
|
krh@75
|
216 |
rpm->dirindexes = index;
|
|
krh@75
|
217 |
break;
|
|
krh@75
|
218 |
case RPMTAG_BASENAMES:
|
|
krh@75
|
219 |
rpm->basenames = index;
|
|
krh@75
|
220 |
break;
|
|
krh@75
|
221 |
case RPMTAG_DIRNAMES:
|
|
krh@75
|
222 |
rpm->dirnames = index;
|
|
krh@74
|
223 |
break;
|
|
krh@74
|
224 |
}
|
|
krh@74
|
225 |
}
|
|
krh@75
|
226 |
|
|
krh@75
|
227 |
return 0;
|
|
krh@74
|
228 |
}
|
|
krh@74
|
229 |
|
|
krh@75
|
230 |
static int
|
|
krh@75
|
231 |
razor_rpm_close(struct rpm *rpm)
|
|
krh@74
|
232 |
{
|
|
krh@75
|
233 |
return munmap(rpm->map, rpm->size);
|
|
krh@75
|
234 |
}
|
|
krh@74
|
235 |
|
|
krh@75
|
236 |
int
|
|
krh@75
|
237 |
razor_importer_add_rpm(struct razor_importer *importer, const char *filename)
|
|
krh@75
|
238 |
{
|
|
krh@75
|
239 |
struct rpm rpm;
|
|
krh@75
|
240 |
|
|
krh@75
|
241 |
if (razor_rpm_open(&rpm, filename) < 0) {
|
|
krh@75
|
242 |
fprintf(stderr, "failed to open rpm %s (%m)\n", filename);
|
|
krh@75
|
243 |
return -1;
|
|
krh@74
|
244 |
}
|
|
krh@74
|
245 |
|
|
krh@75
|
246 |
razor_importer_begin_package(importer,
|
|
krh@75
|
247 |
rpm.pool + ntohl(rpm.name->offset),
|
|
krh@75
|
248 |
rpm.pool + ntohl(rpm.version->offset));
|
|
krh@74
|
249 |
|
|
krh@75
|
250 |
import_properties(importer, &rpm.requires,
|
|
krh@75
|
251 |
rpm.pool, RAZOR_PROPERTY_REQUIRES);
|
|
krh@75
|
252 |
import_properties(importer, &rpm.provides,
|
|
krh@75
|
253 |
rpm.pool, RAZOR_PROPERTY_PROVIDES);
|
|
krh@75
|
254 |
import_properties(importer, &rpm.conflicts,
|
|
krh@75
|
255 |
rpm.pool, RAZOR_PROPERTY_CONFLICTS);
|
|
krh@75
|
256 |
import_properties(importer, &rpm.obsoletes,
|
|
krh@75
|
257 |
rpm.pool, RAZOR_PROPERTY_OBSOLETES);
|
|
krh@75
|
258 |
import_files(importer, &rpm);
|
|
krh@74
|
259 |
|
|
krh@75
|
260 |
razor_importer_finish_package(importer);
|
|
krh@74
|
261 |
|
|
krh@75
|
262 |
razor_rpm_close(&rpm);
|
|
krh@74
|
263 |
|
|
krh@75
|
264 |
return 0;
|
|
krh@74
|
265 |
}
|