1.1 --- a/rpm.c Sun Jun 15 23:15:59 2008 -0400
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,748 +0,0 @@
1.4 -/*
1.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
1.6 - * Copyright (C) 2008 Red Hat, Inc
1.7 - *
1.8 - * This program is free software; you can redistribute it and/or modify
1.9 - * it under the terms of the GNU General Public License as published by
1.10 - * the Free Software Foundation; either version 2 of the License, or
1.11 - * (at your option) any later version.
1.12 - *
1.13 - * This program is distributed in the hope that it will be useful,
1.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 - * GNU General Public License for more details.
1.17 - *
1.18 - * You should have received a copy of the GNU General Public License along
1.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
1.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.21 - */
1.22 -
1.23 -#include <stdio.h>
1.24 -#include <stddef.h>
1.25 -#include <string.h>
1.26 -#include <errno.h>
1.27 -#include <sys/stat.h>
1.28 -#include <sys/mman.h>
1.29 -#include <sys/types.h>
1.30 -#include <sys/wait.h>
1.31 -#include <fcntl.h>
1.32 -#include <unistd.h>
1.33 -#include <arpa/inet.h>
1.34 -#include <rpm/rpmlib.h>
1.35 -#include <rpm/rpmdb.h>
1.36 -#include <zlib.h>
1.37 -
1.38 -#include "razor.h"
1.39 -#include "razor-internal.h"
1.40 -
1.41 -#define RPM_LEAD_SIZE 96
1.42 -
1.43 -struct rpm_header {
1.44 - unsigned char magic[4];
1.45 - unsigned char reserved[4];
1.46 - int nindex;
1.47 - int hsize;
1.48 -};
1.49 -
1.50 -struct rpm_header_index {
1.51 - int tag;
1.52 - int type;
1.53 - int offset;
1.54 - int count;
1.55 -};
1.56 -
1.57 -struct razor_rpm {
1.58 - struct rpm_header *signature;
1.59 - struct rpm_header *header;
1.60 - const char **dirs;
1.61 - const char *pool;
1.62 - void *map;
1.63 - size_t size;
1.64 - void *payload;
1.65 -};
1.66 -
1.67 -static struct rpm_header_index *
1.68 -razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
1.69 -{
1.70 - struct rpm_header_index *index, *end;
1.71 -
1.72 - index = (struct rpm_header_index *) (rpm->header + 1);
1.73 - end = index + ntohl(rpm->header->nindex);
1.74 - while (index < end) {
1.75 - if (ntohl(index->tag) == tag)
1.76 - return index;
1.77 - index++;
1.78 - }
1.79 -
1.80 - return NULL;
1.81 -}
1.82 -
1.83 -static const void *
1.84 -razor_rpm_get_indirect(struct razor_rpm *rpm,
1.85 - unsigned int tag, unsigned int *count)
1.86 -{
1.87 - struct rpm_header_index *index;
1.88 -
1.89 - index = razor_rpm_get_header(rpm, tag);
1.90 - if (index != NULL) {
1.91 - if (count)
1.92 - *count = ntohl(index->count);
1.93 -
1.94 - return rpm->pool + ntohl(index->offset);
1.95 - }
1.96 -
1.97 - return NULL;
1.98 -}
1.99 -
1.100 -static enum razor_version_relation
1.101 -rpm_to_razor_flags (uint_32 flags)
1.102 -{
1.103 - switch (flags & (RPMSENSE_LESS | RPMSENSE_EQUAL | RPMSENSE_GREATER)) {
1.104 - case RPMSENSE_LESS:
1.105 - return RAZOR_VERSION_LESS;
1.106 - case RPMSENSE_LESS|RPMSENSE_EQUAL:
1.107 - return RAZOR_VERSION_LESS_OR_EQUAL;
1.108 - case RPMSENSE_EQUAL:
1.109 - return RAZOR_VERSION_EQUAL;
1.110 - case RPMSENSE_GREATER|RPMSENSE_EQUAL:
1.111 - return RAZOR_VERSION_GREATER_OR_EQUAL;
1.112 - case RPMSENSE_GREATER:
1.113 - return RAZOR_VERSION_GREATER;
1.114 - }
1.115 -
1.116 - /* FIXME? */
1.117 - return RAZOR_VERSION_EQUAL;
1.118 -}
1.119 -
1.120 -static void
1.121 -import_properties(struct razor_importer *importer, unsigned long type,
1.122 - struct razor_rpm *rpm,
1.123 - int name_tag, int version_tag, int flags_tag)
1.124 -{
1.125 - const char *name, *version;
1.126 - const uint_32 *flags;
1.127 - uint_32 f;
1.128 - unsigned int i, count;
1.129 -
1.130 - name = razor_rpm_get_indirect(rpm, name_tag, &count);
1.131 - if (name == NULL)
1.132 - return;
1.133 -
1.134 - flags = razor_rpm_get_indirect(rpm, flags_tag, &count);
1.135 -
1.136 - version = razor_rpm_get_indirect(rpm, version_tag, &count);
1.137 - for (i = 0; i < count; i++) {
1.138 - f = rpm_to_razor_flags(ntohl(flags[i]));
1.139 - razor_importer_add_property(importer, name, f, version, type);
1.140 - name += strlen(name) + 1;
1.141 - version += strlen(version) + 1;
1.142 - }
1.143 -}
1.144 -
1.145 -static void
1.146 -import_files(struct razor_importer *importer, struct razor_rpm *rpm)
1.147 -{
1.148 - const char *name;
1.149 - const uint32_t *index;
1.150 - unsigned int i, count;
1.151 - char buffer[256];
1.152 -
1.153 - /* assert: count is the same for all arrays */
1.154 -
1.155 - index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
1.156 - name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
1.157 - for (i = 0; i < count; i++) {
1.158 - snprintf(buffer, sizeof buffer,
1.159 - "%s%s", rpm->dirs[ntohl(*index)], name);
1.160 - razor_importer_add_file(importer, buffer);
1.161 - name += strlen(name) + 1;
1.162 - index++;
1.163 - }
1.164 -}
1.165 -
1.166 -struct razor_rpm *
1.167 -razor_rpm_open(const char *filename)
1.168 -{
1.169 - struct razor_rpm *rpm;
1.170 - struct rpm_header_index *base, *index;
1.171 - struct stat buf;
1.172 - unsigned int count, i, nindex, hsize;
1.173 - const char *name;
1.174 - int fd;
1.175 -
1.176 - rpm = malloc(sizeof *rpm);
1.177 - memset(rpm, 0, sizeof *rpm);
1.178 -
1.179 - fd = open(filename, O_RDONLY);
1.180 - if (fd < 0) {
1.181 - fprintf(stderr, "couldn't open %s\n", filename);
1.182 - return NULL;
1.183 - }
1.184 -
1.185 - if (fstat(fd, &buf) < 0) {
1.186 - fprintf(stderr, "failed to stat %s (%m)\n", filename);
1.187 - return NULL;
1.188 - }
1.189 -
1.190 - rpm->size = buf.st_size;
1.191 - rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
1.192 - if (rpm->map == MAP_FAILED) {
1.193 - fprintf(stderr, "couldn't mmap %s\n", filename);
1.194 - return NULL;
1.195 - }
1.196 - close(fd);
1.197 -
1.198 - rpm->signature = rpm->map + RPM_LEAD_SIZE;
1.199 - nindex = ntohl(rpm->signature->nindex);
1.200 - hsize = ntohl(rpm->signature->hsize);
1.201 - rpm->header = (void *) (rpm->signature + 1) +
1.202 - ALIGN(nindex * sizeof *index + hsize, 8);
1.203 - nindex = ntohl(rpm->header->nindex);
1.204 - hsize = ntohl(rpm->header->hsize);
1.205 - rpm->payload = (void *) (rpm->header + 1) +
1.206 - nindex * sizeof *index + hsize;
1.207 -
1.208 - base = (struct rpm_header_index *) (rpm->header + 1);
1.209 - rpm->pool = (void *) base + nindex * sizeof *index;
1.210 -
1.211 - /* Look up dir names now so we can index them directly. */
1.212 - name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
1.213 - if (name) {
1.214 - rpm->dirs = calloc(count, sizeof *rpm->dirs);
1.215 - for (i = 0; i < count; i++) {
1.216 - rpm->dirs[i] = name;
1.217 - name += strlen(name) + 1;
1.218 - }
1.219 - } else {
1.220 - name = razor_rpm_get_indirect(rpm, RPMTAG_OLDFILENAMES,
1.221 - &count);
1.222 - if (name) {
1.223 - fprintf(stderr, "old filenames not supported\n");
1.224 - return NULL;
1.225 - }
1.226 - }
1.227 -
1.228 - return rpm;
1.229 -}
1.230 -
1.231 -struct cpio_file_header {
1.232 - char magic[6];
1.233 - char inode[8];
1.234 - char mode[8];
1.235 - char uid[8];
1.236 - char gid[8];
1.237 - char nlink[8];
1.238 - char mtime[8];
1.239 - char filesize[8];
1.240 - char devmajor[8];
1.241 - char devminor[8];
1.242 - char rdevmajor[8];
1.243 - char rdevminor[8];
1.244 - char namesize[8];
1.245 - char checksum[8];
1.246 - char filename[0];
1.247 -};
1.248 -
1.249 -/* gzip flags */
1.250 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
1.251 -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
1.252 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
1.253 -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
1.254 -#define COMMENT 0x10 /* bit 4 set: file comment present */
1.255 -#define RESERVED 0xE0 /* bits 5..7: reserved */
1.256 -
1.257 -struct installer {
1.258 - const char *root;
1.259 - struct razor_rpm *rpm;
1.260 - z_stream stream;
1.261 - unsigned char buffer[32768];
1.262 - size_t rest, length;
1.263 -};
1.264 -
1.265 -static int
1.266 -installer_inflate(struct installer *installer)
1.267 -{
1.268 - size_t length;
1.269 - int err;
1.270 -
1.271 - if (installer->rest > sizeof installer->buffer)
1.272 - length = sizeof installer->buffer;
1.273 - else
1.274 - length = installer->rest;
1.275 -
1.276 - installer->stream.next_out = installer->buffer;
1.277 - installer->stream.avail_out = length;
1.278 - err = inflate(&installer->stream, Z_SYNC_FLUSH);
1.279 - if (err != Z_OK && err != Z_STREAM_END) {
1.280 - fprintf(stderr, "inflate error: %d (%m)\n", err);
1.281 - return -1;
1.282 - }
1.283 -
1.284 - installer->rest -= length;
1.285 - installer->length = length;
1.286 -
1.287 - return 0;
1.288 -}
1.289 -
1.290 -static int
1.291 -installer_align(struct installer *installer, size_t size)
1.292 -{
1.293 - unsigned char buffer[4];
1.294 - int err;
1.295 -
1.296 - installer->stream.next_out = buffer;
1.297 - installer->stream.avail_out =
1.298 - (size - installer->stream.total_out) & (size - 1);
1.299 -
1.300 - if (installer->stream.avail_out == 0)
1.301 - return 0;
1.302 -
1.303 - err = inflate(&installer->stream, Z_SYNC_FLUSH);
1.304 - if (err != Z_OK && err != Z_STREAM_END) {
1.305 - fprintf(stderr, "inflate error: %d (%m)\n", err);
1.306 - return -1;
1.307 - }
1.308 -
1.309 - return 0;
1.310 -}
1.311 -
1.312 -static int
1.313 -create_path(struct installer *installer, const char *path, unsigned int mode)
1.314 -{
1.315 - char buffer[PATH_MAX];
1.316 - struct stat buf;
1.317 - int fd, ret;
1.318 -
1.319 - if (razor_create_dir(installer->root, path) < 0)
1.320 - return -1;
1.321 -
1.322 - snprintf(buffer, sizeof buffer, "%s%s", installer->root, path);
1.323 -
1.324 - switch (mode >> 12) {
1.325 - case REG:
1.326 - /* FIXME: handle the case where a file is already there. */
1.327 - fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, mode & 0x1ff);
1.328 - if (fd < 0){
1.329 - fprintf(stderr, "failed to create file %s\n", buffer);
1.330 - return -1;
1.331 - }
1.332 - while (installer->rest > 0) {
1.333 - if (installer_inflate(installer)) {
1.334 - fprintf(stderr, "failed to inflate\n");
1.335 - return -1;
1.336 - }
1.337 - if (razor_write(fd, installer->buffer,
1.338 - installer->length)) {
1.339 - fprintf(stderr, "failed to write payload\n");
1.340 - return -1;
1.341 - }
1.342 - }
1.343 - if (close(fd) < 0) {
1.344 - fprintf(stderr, "failed to close %s: %m\n", buffer);
1.345 - return -1;
1.346 - }
1.347 - return 0;
1.348 - case XDIR:
1.349 - ret = mkdir(buffer, mode & 0x1ff);
1.350 - if (ret == 0 || errno != EEXIST)
1.351 - return ret;
1.352 - if (stat(buffer, &buf) || !S_ISDIR(buf.st_mode)) {
1.353 - /* FIXME: also check that mode match. */
1.354 - fprintf(stderr,
1.355 - "%s exists but is not a directory\n", buffer);
1.356 - return -1;
1.357 - }
1.358 - return 0;
1.359 - case PIPE:
1.360 - case CDEV:
1.361 - case BDEV:
1.362 - case SOCK:
1.363 - printf("%s: unhandled file type %d\n", buffer, mode >> 12);
1.364 - return 0;
1.365 - case LINK:
1.366 - if (installer_inflate(installer)) {
1.367 - fprintf(stderr, "failed to inflate\n");
1.368 - return -1;
1.369 - }
1.370 - if (installer->length >= sizeof installer->buffer) {
1.371 - fprintf(stderr, "link name too long\n");
1.372 - return -1;
1.373 - }
1.374 - installer->buffer[installer->length] = '\0';
1.375 - if (symlink((const char *) installer->buffer, buffer)) {
1.376 - fprintf(stderr, "failed to create symlink, %m\n");
1.377 - return -1;
1.378 - }
1.379 - return 0;
1.380 - default:
1.381 - printf("%s: unknown file type %d\n", buffer, mode >> 12);
1.382 - return 0;
1.383 - }
1.384 -}
1.385 -
1.386 -static int
1.387 -run_script(struct installer *installer,
1.388 - unsigned int program_tag, unsigned int script_tag)
1.389 -{
1.390 - int pid, status, fd[2];
1.391 - const char *script = NULL, *program = NULL;
1.392 -
1.393 - program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
1.394 - script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
1.395 - if (program == NULL && script == NULL) {
1.396 - return 0;
1.397 - } else if (program == NULL) {
1.398 - program = "/bin/sh";
1.399 - }
1.400 -
1.401 - if (pipe(fd) < 0) {
1.402 - fprintf(stderr, "failed to create pipe\n");
1.403 - return -1;
1.404 - }
1.405 - pid = fork();
1.406 - if (pid < 0) {
1.407 - fprintf(stderr, "failed to fork, %m\n");
1.408 - } else if (pid == 0) {
1.409 - if (dup2(fd[0], STDIN_FILENO) < 0) {
1.410 - fprintf(stderr, "failed redirect stdin, %m\n");
1.411 - return -1;
1.412 - }
1.413 - if (close(fd[0]) < 0 || close(fd[1]) < 0) {
1.414 - fprintf(stderr, "failed to close pipe, %m\n");
1.415 - return -1;
1.416 - }
1.417 - if (chroot(installer->root) < 0) {
1.418 - fprintf(stderr, "failed to chroot to %s, %m\n",
1.419 - installer->root);
1.420 - return -1;
1.421 - }
1.422 - printf("executing program %s in chroot %s\n",
1.423 - program, installer->root);
1.424 - if (execl(program, program, NULL)) {
1.425 - fprintf(stderr, "failed to exec %s, %m\n", program);
1.426 - exit(-1);
1.427 - }
1.428 - } else {
1.429 - if (script && razor_write(fd[1], script, strlen(script)) < 0) {
1.430 - fprintf(stderr, "failed to pipe script, %m\n");
1.431 - return -1;
1.432 - }
1.433 - if (close(fd[0]) || close(fd[1])) {
1.434 - fprintf(stderr, "failed to close pipe, %m\n");
1.435 - return -1;
1.436 - }
1.437 - if (wait(&status) < 0) {
1.438 - fprintf(stderr, "wait for child failed, %m");
1.439 - return -1;
1.440 - }
1.441 - if (status)
1.442 - printf("script exited with status %d\n", status);
1.443 - }
1.444 -
1.445 - return 0;
1.446 -}
1.447 -
1.448 -static int
1.449 -installer_init(struct installer *installer)
1.450 -{
1.451 - unsigned char *gz_header;
1.452 - int method, flags, err;
1.453 -
1.454 - gz_header = installer->rpm->payload;
1.455 - if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
1.456 - fprintf(stderr, "payload section doesn't have gz header\n");
1.457 - return -1;
1.458 - }
1.459 -
1.460 - method = gz_header[2];
1.461 - flags = gz_header[3];
1.462 -
1.463 - if (method != Z_DEFLATED || flags != 0) {
1.464 - fprintf(stderr,
1.465 - "unknown payload compression method or flags set\n");
1.466 - return -1;
1.467 - }
1.468 -
1.469 - installer->stream.zalloc = NULL;
1.470 - installer->stream.zfree = NULL;
1.471 - installer->stream.opaque = NULL;
1.472 -
1.473 - installer->stream.next_in = gz_header + 10;
1.474 - installer->stream.avail_in =
1.475 - (installer->rpm->map + installer->rpm->size) -
1.476 - (void *) installer->stream.next_in;
1.477 - installer->stream.next_out = NULL;
1.478 - installer->stream.avail_out = 0;
1.479 -
1.480 - err = inflateInit2(&installer->stream, -MAX_WBITS);
1.481 - if (err != Z_OK) {
1.482 - fprintf(stderr, "inflateInit error: %d\n", err);
1.483 - return -1;
1.484 - }
1.485 -
1.486 - return 0;
1.487 -}
1.488 -
1.489 -static int
1.490 -installer_finish(struct installer *installer)
1.491 -{
1.492 - int err;
1.493 -
1.494 - err = inflateEnd(&installer->stream);
1.495 -
1.496 - if (err != Z_OK) {
1.497 - fprintf(stderr, "inflateEnd error: %d\n", err);
1.498 - return -1;
1.499 - }
1.500 -
1.501 - return 0;
1.502 -}
1.503 -
1.504 -static unsigned long
1.505 -fixed_hex_to_ulong(const char *hex, int length)
1.506 -{
1.507 - long l;
1.508 - int i;
1.509 -
1.510 - for (i = 0, l = 0; i < length; i++) {
1.511 - if (hex[i] < 'a')
1.512 - l = l * 16 + hex[i] - '0';
1.513 - else
1.514 - l = l * 16 + hex[i] - 'a' + 10;
1.515 - }
1.516 -
1.517 - return l;
1.518 -}
1.519 -
1.520 -int
1.521 -razor_rpm_install(struct razor_rpm *rpm, const char *root)
1.522 -{
1.523 - struct installer installer;
1.524 - struct cpio_file_header *header;
1.525 - struct stat buf;
1.526 - unsigned int mode;
1.527 - char *path;
1.528 - size_t filesize;
1.529 -
1.530 - installer.rpm = rpm;
1.531 - installer.root = root;
1.532 -
1.533 - /* FIXME: Only do this before a transaction, not per rpm. */
1.534 - if (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode)) {
1.535 - fprintf(stderr,
1.536 - "root installation directory \"%s\" does not exist\n",
1.537 - root);
1.538 - return -1;
1.539 - }
1.540 -
1.541 - if (installer_init(&installer))
1.542 - return -1;
1.543 -
1.544 - run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN);
1.545 -
1.546 - while (installer.stream.avail_in > 0) {
1.547 - installer.rest = sizeof *header;
1.548 - if (installer_inflate(&installer))
1.549 - return -1;
1.550 -
1.551 - header = (struct cpio_file_header *) installer.buffer;
1.552 - mode = fixed_hex_to_ulong(header->mode, sizeof header->mode);
1.553 - filesize = fixed_hex_to_ulong(header->filesize,
1.554 - sizeof header->filesize);
1.555 -
1.556 - installer.rest = fixed_hex_to_ulong(header->namesize,
1.557 - sizeof header->namesize);
1.558 -
1.559 - if (installer_inflate(&installer) ||
1.560 - installer_align(&installer, 4))
1.561 - return -1;
1.562 -
1.563 - path = (char *) installer.buffer;
1.564 - /* This convention is so lame... */
1.565 - if (strcmp(path, "TRAILER!!!") == 0)
1.566 - break;
1.567 -
1.568 - installer.rest = filesize;
1.569 - if (create_path(&installer, path + 1, mode) < 0)
1.570 - return -1;
1.571 - if (installer_align(&installer, 4))
1.572 - return -1;
1.573 - }
1.574 -
1.575 - if (installer_finish(&installer))
1.576 - return -1;
1.577 -
1.578 - run_script(&installer, RPMTAG_POSTINPROG, RPMTAG_POSTIN);
1.579 -
1.580 - return 0;
1.581 -}
1.582 -
1.583 -int
1.584 -razor_rpm_close(struct razor_rpm *rpm)
1.585 -{
1.586 - int err;
1.587 -
1.588 - free(rpm->dirs);
1.589 - err = munmap(rpm->map, rpm->size);
1.590 - free(rpm);
1.591 -
1.592 - return err;
1.593 -}
1.594 -
1.595 -int
1.596 -razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
1.597 -{
1.598 - const char *name, *version, *release, *arch;
1.599 - const uint_32 *epoch;
1.600 - char evr[128], buf[16];
1.601 -
1.602 - name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
1.603 - epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL);
1.604 - version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
1.605 - release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
1.606 - arch = razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL);
1.607 -
1.608 - if (epoch) {
1.609 - snprintf(buf, sizeof buf, "%u", ntohl(*epoch));
1.610 - razor_build_evr(evr, sizeof evr, buf, version, release);
1.611 - } else {
1.612 - razor_build_evr(evr, sizeof evr, NULL, version, release);
1.613 - }
1.614 - razor_importer_begin_package(importer, name, evr, arch);
1.615 -
1.616 - import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
1.617 - RPMTAG_REQUIRENAME,
1.618 - RPMTAG_REQUIREVERSION,
1.619 - RPMTAG_REQUIREFLAGS);
1.620 -
1.621 - import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
1.622 - RPMTAG_PROVIDENAME,
1.623 - RPMTAG_PROVIDEVERSION,
1.624 - RPMTAG_PROVIDEFLAGS);
1.625 -
1.626 - import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
1.627 - RPMTAG_OBSOLETENAME,
1.628 - RPMTAG_OBSOLETEVERSION,
1.629 - RPMTAG_OBSOLETEFLAGS);
1.630 -
1.631 - import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
1.632 - RPMTAG_CONFLICTNAME,
1.633 - RPMTAG_CONFLICTVERSION,
1.634 - RPMTAG_CONFLICTFLAGS);
1.635 -
1.636 - import_files(importer, rpm);
1.637 -
1.638 - razor_importer_finish_package(importer);
1.639 -
1.640 - return 0;
1.641 -}
1.642 -
1.643 -union rpm_entry {
1.644 - void *p;
1.645 - char *string;
1.646 - char **list;
1.647 - uint_32 *flags;
1.648 - uint_32 integer;
1.649 -};
1.650 -
1.651 -static void
1.652 -add_properties(struct razor_importer *importer,
1.653 - enum razor_property_type property_type,
1.654 - Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
1.655 -{
1.656 - union rpm_entry names, versions, flags;
1.657 - int_32 i, type, count;
1.658 -
1.659 - headerGetEntry(h, name_tag, &type, &names.p, &count);
1.660 - headerGetEntry(h, version_tag, &type, &versions.p, &count);
1.661 - headerGetEntry(h, flags_tag, &type, &flags.p, &count);
1.662 -
1.663 - for (i = 0; i < count; i++)
1.664 - razor_importer_add_property(importer,
1.665 - names.list[i],
1.666 - rpm_to_razor_flags (flags.flags[i]),
1.667 - versions.list[i],
1.668 - property_type);
1.669 -}
1.670 -
1.671 -struct razor_set *
1.672 -razor_set_create_from_rpmdb(void)
1.673 -{
1.674 - struct razor_importer *importer;
1.675 - rpmdbMatchIterator iter;
1.676 - Header h;
1.677 - int_32 type, count, i;
1.678 - union rpm_entry name, epoch, version, release, arch;
1.679 - union rpm_entry basenames, dirnames, dirindexes;
1.680 - char filename[PATH_MAX], evr[128], buf[16];
1.681 - rpmdb db;
1.682 -
1.683 - rpmReadConfigFiles(NULL, NULL);
1.684 -
1.685 - if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
1.686 - fprintf(stderr, "cannot open rpm database\n");
1.687 - exit(1);
1.688 - }
1.689 -
1.690 - importer = razor_importer_new();
1.691 -
1.692 - iter = rpmdbInitIterator(db, 0, NULL, 0);
1.693 - while (h = rpmdbNextIterator(iter), h != NULL) {
1.694 - headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
1.695 - headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count);
1.696 - headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
1.697 - headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
1.698 - headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count);
1.699 -
1.700 - if (epoch.flags != NULL) {
1.701 - snprintf(buf, sizeof buf, "%u", *epoch.flags);
1.702 - razor_build_evr(evr, sizeof evr,
1.703 - buf, version.string, release.string);
1.704 - } else {
1.705 - razor_build_evr(evr, sizeof evr,
1.706 - NULL, version.string, release.string);
1.707 - }
1.708 -
1.709 - razor_importer_begin_package(importer,
1.710 - name.string, evr, arch.string);
1.711 -
1.712 - add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
1.713 - RPMTAG_REQUIRENAME,
1.714 - RPMTAG_REQUIREVERSION,
1.715 - RPMTAG_REQUIREFLAGS);
1.716 -
1.717 - add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
1.718 - RPMTAG_PROVIDENAME,
1.719 - RPMTAG_PROVIDEVERSION,
1.720 - RPMTAG_PROVIDEFLAGS);
1.721 -
1.722 - add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
1.723 - RPMTAG_OBSOLETENAME,
1.724 - RPMTAG_OBSOLETEVERSION,
1.725 - RPMTAG_OBSOLETEFLAGS);
1.726 -
1.727 - add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
1.728 - RPMTAG_CONFLICTNAME,
1.729 - RPMTAG_CONFLICTVERSION,
1.730 - RPMTAG_CONFLICTFLAGS);
1.731 -
1.732 - headerGetEntry(h, RPMTAG_BASENAMES, &type,
1.733 - &basenames.p, &count);
1.734 - headerGetEntry(h, RPMTAG_DIRNAMES, &type,
1.735 - &dirnames.p, &count);
1.736 - headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
1.737 - &dirindexes.p, &count);
1.738 - for (i = 0; i < count; i++) {
1.739 - snprintf(filename, sizeof filename, "%s%s",
1.740 - dirnames.list[dirindexes.flags[i]],
1.741 - basenames.list[i]);
1.742 - razor_importer_add_file(importer, filename);
1.743 - }
1.744 -
1.745 - razor_importer_finish_package(importer);
1.746 - }
1.747 -
1.748 - rpmdbClose(db);
1.749 -
1.750 - return razor_importer_finish(importer);
1.751 -}