Extend rpm dumper into an rpm importer.
8 #include <rpm/rpmlib.h>
12 #define RPM_LEAD_SIZE 96
15 unsigned char magic[4];
27 unsigned char magic[4];
28 unsigned char reserved[4];
33 struct rpm_header_index {
41 struct rpm_header_index *name;
42 struct rpm_header_index *version;
43 struct rpm_header_index *flags;
47 struct rpm_header *signature;
48 struct rpm_header *header;
50 struct rpm_header_index *name;
51 struct rpm_header_index *version;
52 struct rpm_header_index *release;
54 struct rpm_header_index *dirnames;
55 struct rpm_header_index *dirindexes;
56 struct rpm_header_index *basenames;
58 struct properties provides;
59 struct properties requires;
60 struct properties obsoletes;
61 struct properties conflicts;
68 #define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
71 import_properties(struct razor_importer *importer,
72 struct properties *properties,
73 const char *pool, unsigned long type)
75 const char *name, *version;
78 /* assert: count is the same for all arrays */
80 if (properties->name == NULL)
83 count = ntohl(properties->name->count);
84 name = pool + ntohl(properties->name->offset);
85 version = pool + ntohl(properties->version->offset);
86 for (i = 0; i < count; i++) {
87 razor_importer_add_property(importer, name, version, type);
88 name += strlen(name) + 1;
89 version += strlen(version) + 1;
94 import_files(struct razor_importer *importer, struct rpm *rpm)
96 const char *name, **dir;
101 /* assert: count is the same for all arrays */
103 if (rpm->dirnames == NULL)
106 count = ntohl(rpm->dirnames->count);
107 dir = calloc(count, sizeof *dir);
108 name = rpm->pool + ntohl(rpm->dirnames->offset);
109 for (i = 0; i < count; i++) {
111 name += strlen(name) + 1;
114 count = ntohl(rpm->basenames->count);
115 index = (unsigned long *) (rpm->pool + ntohl(rpm->dirindexes->offset));
116 name = rpm->pool + ntohl(rpm->basenames->offset);
117 for (i = 0; i < count; i++) {
118 snprintf(buffer, sizeof buffer,
119 "%s%s", dir[ntohl(*index)], name);
120 razor_importer_add_file(importer, buffer);
121 name += strlen(name) + 1;
127 razor_rpm_open(struct rpm *rpm, const char *filename)
129 struct rpm_header_index *base, *index;
131 int fd, nindex, hsize, i;
133 memset(rpm, 0, sizeof *rpm);
134 if (stat(filename, &buf) < 0) {
135 fprintf(stderr, "no such file %s (%m)\n", filename);
139 fd = open(filename, O_RDONLY);
141 fprintf(stderr, "couldn't open %s\n", filename);
144 rpm->size = buf.st_size;
145 rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
146 if (rpm->map == MAP_FAILED) {
147 fprintf(stderr, "couldn't mmap %s\n", filename);
152 rpm->signature = rpm->map + RPM_LEAD_SIZE;
153 nindex = ntohl(rpm->signature->nindex);
154 hsize = ntohl(rpm->signature->hsize);
155 rpm->header = (void *) (rpm->signature + 1) +
156 ALIGN(nindex * sizeof *index + hsize, 8);
158 nindex = ntohl(rpm->header->nindex);
159 base = (struct rpm_header_index *) (rpm->header + 1);
160 rpm->pool = (void *) base + nindex * sizeof *index;
162 for (i = 0; i < nindex; i++) {
164 switch (ntohl(index->tag)) {
169 rpm->version = index;
172 rpm->release = index;
175 case RPMTAG_REQUIRENAME:
176 rpm->requires.name = index;
178 case RPMTAG_REQUIREVERSION:
179 rpm->requires.version = index;
181 case RPMTAG_REQUIREFLAGS:
182 rpm->requires.flags = index;
185 case RPMTAG_PROVIDENAME:
186 rpm->provides.name = index;
188 case RPMTAG_PROVIDEVERSION:
189 rpm->provides.version = index;
191 case RPMTAG_PROVIDEFLAGS:
192 rpm->provides.flags = index;
195 case RPMTAG_OBSOLETENAME:
196 rpm->obsoletes.name = index;
198 case RPMTAG_OBSOLETEVERSION:
199 rpm->obsoletes.version = index;
201 case RPMTAG_OBSOLETEFLAGS:
202 rpm->obsoletes.flags = index;
205 case RPMTAG_CONFLICTNAME:
206 rpm->conflicts.name = index;
208 case RPMTAG_CONFLICTVERSION:
209 rpm->conflicts.version = index;
211 case RPMTAG_CONFLICTFLAGS:
212 rpm->conflicts.flags = index;
215 case RPMTAG_DIRINDEXES:
216 rpm->dirindexes = index;
218 case RPMTAG_BASENAMES:
219 rpm->basenames = index;
221 case RPMTAG_DIRNAMES:
222 rpm->dirnames = index;
231 razor_rpm_close(struct rpm *rpm)
233 return munmap(rpm->map, rpm->size);
237 razor_importer_add_rpm(struct razor_importer *importer, const char *filename)
241 if (razor_rpm_open(&rpm, filename) < 0) {
242 fprintf(stderr, "failed to open rpm %s (%m)\n", filename);
246 razor_importer_begin_package(importer,
247 rpm.pool + ntohl(rpm.name->offset),
248 rpm.pool + ntohl(rpm.version->offset));
250 import_properties(importer, &rpm.requires,
251 rpm.pool, RAZOR_PROPERTY_REQUIRES);
252 import_properties(importer, &rpm.provides,
253 rpm.pool, RAZOR_PROPERTY_PROVIDES);
254 import_properties(importer, &rpm.conflicts,
255 rpm.pool, RAZOR_PROPERTY_CONFLICTS);
256 import_properties(importer, &rpm.obsoletes,
257 rpm.pool, RAZOR_PROPERTY_OBSOLETES);
258 import_files(importer, &rpm);
260 razor_importer_finish_package(importer);
262 razor_rpm_close(&rpm);