1.1 --- a/rpm.c Wed Nov 07 00:33:56 2007 -0500
1.2 +++ b/rpm.c Thu Nov 08 17:14:19 2007 -0500
1.3 @@ -7,6 +7,8 @@
1.4 #include <arpa/inet.h>
1.5 #include <rpm/rpmlib.h>
1.6
1.7 +#include "razor.h"
1.8 +
1.9 #define RPM_LEAD_SIZE 96
1.10
1.11 struct rpm_lead {
1.12 @@ -35,92 +37,229 @@
1.13 int count;
1.14 };
1.15
1.16 +struct properties {
1.17 + struct rpm_header_index *name;
1.18 + struct rpm_header_index *version;
1.19 + struct rpm_header_index *flags;
1.20 +};
1.21 +
1.22 +struct rpm {
1.23 + struct rpm_header *signature;
1.24 + struct rpm_header *header;
1.25 +
1.26 + struct rpm_header_index *name;
1.27 + struct rpm_header_index *version;
1.28 + struct rpm_header_index *release;
1.29 +
1.30 + struct rpm_header_index *dirnames;
1.31 + struct rpm_header_index *dirindexes;
1.32 + struct rpm_header_index *basenames;
1.33 +
1.34 + struct properties provides;
1.35 + struct properties requires;
1.36 + struct properties obsoletes;
1.37 + struct properties conflicts;
1.38 +
1.39 + const char *pool;
1.40 + void *map;
1.41 + size_t size;
1.42 +};
1.43 +
1.44 #define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
1.45
1.46 -static void dump_header(struct rpm_header *header)
1.47 +static void
1.48 +import_properties(struct razor_importer *importer,
1.49 + struct properties *properties,
1.50 + const char *pool, unsigned long type)
1.51 +{
1.52 + const char *name, *version;
1.53 + int i, count;
1.54 +
1.55 + /* assert: count is the same for all arrays */
1.56 +
1.57 + if (properties->name == NULL)
1.58 + return;
1.59 +
1.60 + count = ntohl(properties->name->count);
1.61 + name = pool + ntohl(properties->name->offset);
1.62 + version = pool + ntohl(properties->version->offset);
1.63 + for (i = 0; i < count; i++) {
1.64 + razor_importer_add_property(importer, name, version, type);
1.65 + name += strlen(name) + 1;
1.66 + version += strlen(version) + 1;
1.67 + }
1.68 +}
1.69 +
1.70 +static void
1.71 +import_files(struct razor_importer *importer, struct rpm *rpm)
1.72 +{
1.73 + const char *name, **dir;
1.74 + unsigned long *index;
1.75 + int i, count;
1.76 + char buffer[256];
1.77 +
1.78 + /* assert: count is the same for all arrays */
1.79 +
1.80 + if (rpm->dirnames == NULL)
1.81 + return;
1.82 +
1.83 + count = ntohl(rpm->dirnames->count);
1.84 + dir = calloc(count, sizeof *dir);
1.85 + name = rpm->pool + ntohl(rpm->dirnames->offset);
1.86 + for (i = 0; i < count; i++) {
1.87 + dir[i] = name;
1.88 + name += strlen(name) + 1;
1.89 + }
1.90 +
1.91 + count = ntohl(rpm->basenames->count);
1.92 + index = (unsigned long *) (rpm->pool + ntohl(rpm->dirindexes->offset));
1.93 + name = rpm->pool + ntohl(rpm->basenames->offset);
1.94 + for (i = 0; i < count; i++) {
1.95 + snprintf(buffer, sizeof buffer,
1.96 + "%s%s", dir[ntohl(*index)], name);
1.97 + razor_importer_add_file(importer, buffer);
1.98 + name += strlen(name) + 1;
1.99 + index++;
1.100 + }
1.101 +}
1.102 +
1.103 +static int
1.104 +razor_rpm_open(struct rpm *rpm, const char *filename)
1.105 {
1.106 struct rpm_header_index *base, *index;
1.107 - int i, j, nindex, tag, offset, type, count;
1.108 - char *pool, *name;
1.109 + struct stat buf;
1.110 + int fd, nindex, hsize, i;
1.111
1.112 - nindex = ntohl(header->nindex);
1.113 - printf("header index records: %d\n", nindex);
1.114 - printf("header storage size: %d\n", ntohl(header->hsize));
1.115 - base = (struct rpm_header_index *) (header + 1);
1.116 - pool = (void *) (header + 1) + nindex * sizeof *index;
1.117 + memset(rpm, 0, sizeof *rpm);
1.118 + if (stat(filename, &buf) < 0) {
1.119 + fprintf(stderr, "no such file %s (%m)\n", filename);
1.120 + return -1;
1.121 + }
1.122
1.123 - printf("headers:\n");
1.124 + fd = open(filename, O_RDONLY);
1.125 + if (fd < 0) {
1.126 + fprintf(stderr, "couldn't open %s\n", filename);
1.127 + return -1;
1.128 + }
1.129 + rpm->size = buf.st_size;
1.130 + rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
1.131 + if (rpm->map == MAP_FAILED) {
1.132 + fprintf(stderr, "couldn't mmap %s\n", filename);
1.133 + return -1;
1.134 + }
1.135 + close(fd);
1.136 +
1.137 + rpm->signature = rpm->map + RPM_LEAD_SIZE;
1.138 + nindex = ntohl(rpm->signature->nindex);
1.139 + hsize = ntohl(rpm->signature->hsize);
1.140 + rpm->header = (void *) (rpm->signature + 1) +
1.141 + ALIGN(nindex * sizeof *index + hsize, 8);
1.142 +
1.143 + nindex = ntohl(rpm->header->nindex);
1.144 + base = (struct rpm_header_index *) (rpm->header + 1);
1.145 + rpm->pool = (void *) base + nindex * sizeof *index;
1.146 +
1.147 for (i = 0; i < nindex; i++) {
1.148 index = base + i;
1.149 - tag = ntohl(index->tag);
1.150 - offset = ntohl(index->offset);
1.151 - type = ntohl(index->type);
1.152 - count = ntohl(index->count);
1.153 - printf(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
1.154 - tag, type, offset, count);
1.155 -
1.156 - switch (tag) {
1.157 + switch (ntohl(index->tag)) {
1.158 case RPMTAG_NAME:
1.159 - name = "name";
1.160 + rpm->name = index;
1.161 break;
1.162 case RPMTAG_VERSION:
1.163 - name = "version";
1.164 + rpm->version = index;
1.165 break;
1.166 case RPMTAG_RELEASE:
1.167 - name = "release";
1.168 + rpm->release = index;
1.169 break;
1.170 +
1.171 case RPMTAG_REQUIRENAME:
1.172 - name = "requires";
1.173 + rpm->requires.name = index;
1.174 break;
1.175 - default:
1.176 - name = "unknown";
1.177 + case RPMTAG_REQUIREVERSION:
1.178 + rpm->requires.version = index;
1.179 break;
1.180 - }
1.181 + case RPMTAG_REQUIREFLAGS:
1.182 + rpm->requires.flags = index;
1.183 + break;
1.184
1.185 - switch (type) {
1.186 - case RPM_STRING_TYPE:
1.187 - printf(" (%s %s)\n", name, pool + offset);
1.188 + case RPMTAG_PROVIDENAME:
1.189 + rpm->provides.name = index;
1.190 break;
1.191 - case RPM_STRING_ARRAY_TYPE:
1.192 - printf(" (%s", name);
1.193 - for (j = 0; j < count; j++) {
1.194 - printf(" %s", pool + offset);
1.195 - offset += strlen(pool + offset) + 1;
1.196 - }
1.197 - printf(")\n");
1.198 + case RPMTAG_PROVIDEVERSION:
1.199 + rpm->provides.version = index;
1.200 + break;
1.201 + case RPMTAG_PROVIDEFLAGS:
1.202 + rpm->provides.flags = index;
1.203 + break;
1.204 +
1.205 + case RPMTAG_OBSOLETENAME:
1.206 + rpm->obsoletes.name = index;
1.207 + break;
1.208 + case RPMTAG_OBSOLETEVERSION:
1.209 + rpm->obsoletes.version = index;
1.210 + break;
1.211 + case RPMTAG_OBSOLETEFLAGS:
1.212 + rpm->obsoletes.flags = index;
1.213 + break;
1.214 +
1.215 + case RPMTAG_CONFLICTNAME:
1.216 + rpm->conflicts.name = index;
1.217 + break;
1.218 + case RPMTAG_CONFLICTVERSION:
1.219 + rpm->conflicts.version = index;
1.220 + break;
1.221 + case RPMTAG_CONFLICTFLAGS:
1.222 + rpm->conflicts.flags = index;
1.223 + break;
1.224 +
1.225 + case RPMTAG_DIRINDEXES:
1.226 + rpm->dirindexes = index;
1.227 + break;
1.228 + case RPMTAG_BASENAMES:
1.229 + rpm->basenames = index;
1.230 + break;
1.231 + case RPMTAG_DIRNAMES:
1.232 + rpm->dirnames = index;
1.233 break;
1.234 }
1.235 }
1.236 +
1.237 + return 0;
1.238 }
1.239
1.240 -void
1.241 -razor_rpm_dump(const char *filename)
1.242 +static int
1.243 +razor_rpm_close(struct rpm *rpm)
1.244 {
1.245 - struct stat buf;
1.246 - void *p;
1.247 - int fd, nindex, hsize;
1.248 - struct rpm_header *signature, *header;
1.249 - struct rpm_header_index *index;
1.250 + return munmap(rpm->map, rpm->size);
1.251 +}
1.252
1.253 - if (stat(filename, &buf) < 0) {
1.254 - fprintf(stderr, "no such file %s\n", filename);
1.255 - return;
1.256 +int
1.257 +razor_importer_add_rpm(struct razor_importer *importer, const char *filename)
1.258 +{
1.259 + struct rpm rpm;
1.260 +
1.261 + if (razor_rpm_open(&rpm, filename) < 0) {
1.262 + fprintf(stderr, "failed to open rpm %s (%m)\n", filename);
1.263 + return -1;
1.264 }
1.265
1.266 - fd = open(filename, O_RDONLY);
1.267 - p = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1.268 - close(fd);
1.269 + razor_importer_begin_package(importer,
1.270 + rpm.pool + ntohl(rpm.name->offset),
1.271 + rpm.pool + ntohl(rpm.version->offset));
1.272
1.273 - printf("%s: %ldkB\n", filename, buf.st_size / 1024);
1.274 - signature = p + RPM_LEAD_SIZE;
1.275 + import_properties(importer, &rpm.requires,
1.276 + rpm.pool, RAZOR_PROPERTY_REQUIRES);
1.277 + import_properties(importer, &rpm.provides,
1.278 + rpm.pool, RAZOR_PROPERTY_PROVIDES);
1.279 + import_properties(importer, &rpm.conflicts,
1.280 + rpm.pool, RAZOR_PROPERTY_CONFLICTS);
1.281 + import_properties(importer, &rpm.obsoletes,
1.282 + rpm.pool, RAZOR_PROPERTY_OBSOLETES);
1.283 + import_files(importer, &rpm);
1.284
1.285 - nindex = ntohl(signature->nindex);
1.286 - hsize = ntohl(signature->hsize);
1.287 - header = (void *) (signature + 1) +
1.288 - ALIGN(nindex * sizeof *index + hsize, 8);
1.289 + razor_importer_finish_package(importer);
1.290
1.291 - dump_header(signature);
1.292 - dump_header(header);
1.293 + razor_rpm_close(&rpm);
1.294
1.295 - munmap(p, buf.st_size);
1.296 + return 0;
1.297 }