1.1 --- a/yum.c Sun Jun 15 18:16:20 2008 -0400
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,366 +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 -#define _GNU_SOURCE
1.24 -
1.25 -#include <string.h>
1.26 -#include <stdio.h>
1.27 -#include <sys/stat.h>
1.28 -#include <sys/mman.h>
1.29 -#include <unistd.h>
1.30 -#include <fcntl.h>
1.31 -#include <errno.h>
1.32 -
1.33 -#include <expat.h>
1.34 -#include <zlib.h>
1.35 -#include "razor.h"
1.36 -
1.37 -/* Import a yum filelist as a razor package set. */
1.38 -
1.39 -enum {
1.40 - YUM_STATE_BEGIN,
1.41 - YUM_STATE_PACKAGE_NAME,
1.42 - YUM_STATE_PACKAGE_ARCH,
1.43 - YUM_STATE_SUMMARY,
1.44 - YUM_STATE_DESCRIPTION,
1.45 - YUM_STATE_URL,
1.46 - YUM_STATE_LICENSE,
1.47 - YUM_STATE_CHECKSUM,
1.48 - YUM_STATE_REQUIRES,
1.49 - YUM_STATE_PROVIDES,
1.50 - YUM_STATE_OBSOLETES,
1.51 - YUM_STATE_CONFLICTS,
1.52 - YUM_STATE_FILE
1.53 -};
1.54 -
1.55 -struct yum_context {
1.56 - XML_Parser primary_parser;
1.57 - XML_Parser filelists_parser;
1.58 - XML_Parser current_parser;
1.59 -
1.60 - struct razor_importer *importer;
1.61 - struct import_property_context *current_property_context;
1.62 - char name[256], arch[64], summary[512], description[4096];
1.63 - char url[256], license[64], buffer[512], *p;
1.64 - char pkgid[128];
1.65 - int state;
1.66 -};
1.67 -
1.68 -static enum razor_version_relation
1.69 -yum_to_razor_flags (const char *flags)
1.70 -{
1.71 - /* FIXME? */
1.72 - if (!flags)
1.73 - return RAZOR_VERSION_EQUAL;
1.74 -
1.75 - if (flags[0] == 'L') {
1.76 - if (flags[1] == 'T')
1.77 - return RAZOR_VERSION_LESS;
1.78 - else
1.79 - return RAZOR_VERSION_LESS_OR_EQUAL;
1.80 - } else if (flags[0] == 'G') {
1.81 - if (flags[1] == 'T')
1.82 - return RAZOR_VERSION_GREATER;
1.83 - else
1.84 - return RAZOR_VERSION_GREATER_OR_EQUAL;
1.85 - } else
1.86 - return RAZOR_VERSION_EQUAL;
1.87 -}
1.88 -
1.89 -static void
1.90 -yum_primary_start_element(void *data, const char *name, const char **atts)
1.91 -{
1.92 - struct yum_context *ctx = data;
1.93 - const char *n, *epoch, *version, *release, *flags;
1.94 - char buffer[128];
1.95 - int i;
1.96 -
1.97 - if (strcmp(name, "name") == 0) {
1.98 - ctx->state = YUM_STATE_PACKAGE_NAME;
1.99 - ctx->p = ctx->name;
1.100 - } else if (strcmp(name, "arch") == 0) {
1.101 - ctx->state = YUM_STATE_PACKAGE_ARCH;
1.102 - ctx->p = ctx->arch;
1.103 - } else if (strcmp(name, "version") == 0) {
1.104 - epoch = NULL;
1.105 - version = NULL;
1.106 - release = NULL;
1.107 - for (i = 0; atts[i]; i += 2) {
1.108 - if (strcmp(atts[i], "epoch") == 0)
1.109 - epoch = atts[i + 1];
1.110 - else if (strcmp(atts[i], "ver") == 0)
1.111 - version = atts[i + 1];
1.112 - else if (strcmp(atts[i], "rel") == 0)
1.113 - release = atts[i + 1];
1.114 - }
1.115 - if (version == NULL || release == NULL) {
1.116 - fprintf(stderr, "invalid version tag, "
1.117 - "missing version or release attribute\n");
1.118 - return;
1.119 - }
1.120 -
1.121 - razor_build_evr(buffer, sizeof buffer, epoch, version, release);
1.122 - razor_importer_begin_package(ctx->importer,
1.123 - ctx->name, buffer, ctx->arch);
1.124 - } else if (strcmp(name, "summary") == 0) {
1.125 - ctx->p = ctx->summary;
1.126 - ctx->state = YUM_STATE_SUMMARY;
1.127 - } else if (strcmp(name, "description") == 0) {
1.128 - ctx->p = ctx->description;
1.129 - ctx->state = YUM_STATE_DESCRIPTION;
1.130 - } else if (strcmp(name, "url") == 0) {
1.131 - ctx->p = ctx->url;
1.132 - ctx->state = YUM_STATE_URL;
1.133 - } else if (strcmp(name, "checksum") == 0) {
1.134 - ctx->p = ctx->pkgid;
1.135 - ctx->state = YUM_STATE_CHECKSUM;
1.136 - } else if (strcmp(name, "rpm:license") == 0) {
1.137 - ctx->p = ctx->license;
1.138 - ctx->state = YUM_STATE_LICENSE;
1.139 - } else if (strcmp(name, "rpm:requires") == 0) {
1.140 - ctx->state = YUM_STATE_REQUIRES;
1.141 - } else if (strcmp(name, "rpm:provides") == 0) {
1.142 - ctx->state = YUM_STATE_PROVIDES;
1.143 - } else if (strcmp(name, "rpm:obsoletes") == 0) {
1.144 - ctx->state = YUM_STATE_OBSOLETES;
1.145 - } else if (strcmp(name, "rpm:conflicts") == 0) {
1.146 - ctx->state = YUM_STATE_CONFLICTS;
1.147 - } else if (strcmp(name, "rpm:entry") == 0 &&
1.148 - ctx->state != YUM_STATE_BEGIN) {
1.149 - n = NULL;
1.150 - epoch = NULL;
1.151 - version = NULL;
1.152 - release = NULL;
1.153 - flags = NULL;
1.154 - for (i = 0; atts[i]; i += 2) {
1.155 - if (strcmp(atts[i], "name") == 0)
1.156 - n = atts[i + 1];
1.157 - else if (strcmp(atts[i], "epoch") == 0)
1.158 - epoch = atts[i + 1];
1.159 - else if (strcmp(atts[i], "ver") == 0)
1.160 - version = atts[i + 1];
1.161 - else if (strcmp(atts[i], "rel") == 0)
1.162 - release = atts[i + 1];
1.163 - else if (strcmp(atts[i], "flags") == 0)
1.164 - flags = atts[i + 1];
1.165 - }
1.166 -
1.167 - if (n == NULL) {
1.168 - fprintf(stderr, "invalid rpm:entry, "
1.169 - "missing name or version attributes\n");
1.170 - return;
1.171 - }
1.172 -
1.173 - razor_build_evr(buffer, sizeof buffer, epoch, version, release);
1.174 - switch (ctx->state) {
1.175 - case YUM_STATE_REQUIRES:
1.176 - razor_importer_add_property(ctx->importer, n,
1.177 - yum_to_razor_flags (flags),
1.178 - buffer,
1.179 - RAZOR_PROPERTY_REQUIRES);
1.180 - break;
1.181 - case YUM_STATE_PROVIDES:
1.182 - razor_importer_add_property(ctx->importer, n,
1.183 - yum_to_razor_flags (flags),
1.184 - buffer,
1.185 - RAZOR_PROPERTY_PROVIDES);
1.186 - break;
1.187 - case YUM_STATE_OBSOLETES:
1.188 - razor_importer_add_property(ctx->importer, n,
1.189 - yum_to_razor_flags (flags),
1.190 - buffer,
1.191 - RAZOR_PROPERTY_OBSOLETES);
1.192 - break;
1.193 - case YUM_STATE_CONFLICTS:
1.194 - razor_importer_add_property(ctx->importer, n,
1.195 - yum_to_razor_flags (flags),
1.196 - buffer,
1.197 - RAZOR_PROPERTY_CONFLICTS);
1.198 - break;
1.199 - }
1.200 - }
1.201 -}
1.202 -
1.203 -static void
1.204 -yum_primary_end_element (void *data, const char *name)
1.205 -{
1.206 - struct yum_context *ctx = data;
1.207 -
1.208 - switch (ctx->state) {
1.209 - case YUM_STATE_PACKAGE_NAME:
1.210 - case YUM_STATE_PACKAGE_ARCH:
1.211 - case YUM_STATE_SUMMARY:
1.212 - case YUM_STATE_DESCRIPTION:
1.213 - case YUM_STATE_URL:
1.214 - case YUM_STATE_LICENSE:
1.215 - case YUM_STATE_CHECKSUM:
1.216 - case YUM_STATE_FILE:
1.217 - ctx->state = YUM_STATE_BEGIN;
1.218 - break;
1.219 - }
1.220 -
1.221 - if (strcmp(name, "package") == 0) {
1.222 - razor_importer_add_details(ctx->importer, ctx->summary,
1.223 - ctx->description, ctx->url,
1.224 - ctx->license);
1.225 -
1.226 - XML_StopParser(ctx->current_parser, XML_TRUE);
1.227 - ctx->current_parser = ctx->filelists_parser;
1.228 - }
1.229 -}
1.230 -
1.231 -static void
1.232 -yum_character_data (void *data, const XML_Char *s, int len)
1.233 -{
1.234 - struct yum_context *ctx = data;
1.235 -
1.236 - switch (ctx->state) {
1.237 - case YUM_STATE_PACKAGE_NAME:
1.238 - case YUM_STATE_PACKAGE_ARCH:
1.239 - case YUM_STATE_SUMMARY:
1.240 - case YUM_STATE_DESCRIPTION:
1.241 - case YUM_STATE_URL:
1.242 - case YUM_STATE_LICENSE:
1.243 - case YUM_STATE_CHECKSUM:
1.244 - case YUM_STATE_FILE:
1.245 - memcpy(ctx->p, s, len);
1.246 - ctx->p += len;
1.247 - *ctx->p = '\0';
1.248 - break;
1.249 - }
1.250 -}
1.251 -
1.252 -static void
1.253 -yum_filelists_start_element(void *data, const char *name, const char **atts)
1.254 -{
1.255 - struct yum_context *ctx = data;
1.256 - const char *pkg, *pkgid;
1.257 - int i;
1.258 -
1.259 - if (strcmp(name, "package") == 0) {
1.260 - pkg = NULL;
1.261 - pkgid = NULL;
1.262 - for (i = 0; atts[i]; i += 2) {
1.263 - if (strcmp(atts[i], "name") == 0)
1.264 - pkg = atts[i + 1];
1.265 - else if (strcmp(atts[i], "pkgid") == 0)
1.266 - pkgid = atts[i + 1];
1.267 - }
1.268 - if (strcmp(pkgid, ctx->pkgid) != 0)
1.269 - fprintf(stderr, "primary.xml and filelists.xml "
1.270 - "mismatch for %s: %s vs %s",
1.271 - pkg, pkgid, ctx->pkgid);
1.272 - } else if (strcmp(name, "file") == 0) {
1.273 - ctx->state = YUM_STATE_FILE;
1.274 - ctx->p = ctx->buffer;
1.275 - }
1.276 -}
1.277 -
1.278 -
1.279 -static void
1.280 -yum_filelists_end_element (void *data, const char *name)
1.281 -{
1.282 - struct yum_context *ctx = data;
1.283 -
1.284 - ctx->state = YUM_STATE_BEGIN;
1.285 - if (strcmp(name, "package") == 0) {
1.286 - XML_StopParser(ctx->current_parser, XML_TRUE);
1.287 - ctx->current_parser = ctx->primary_parser;
1.288 - razor_importer_finish_package(ctx->importer);
1.289 - } else if (strcmp(name, "file") == 0)
1.290 - razor_importer_add_file(ctx->importer, ctx->buffer);
1.291 -
1.292 -}
1.293 -
1.294 -#define XML_BUFFER_SIZE 4096
1.295 -
1.296 -struct razor_set *
1.297 -razor_set_create_from_yum(void)
1.298 -{
1.299 - struct yum_context ctx;
1.300 - void *buf;
1.301 - int len, ret;
1.302 - gzFile primary, filelists;
1.303 - XML_ParsingStatus status;
1.304 -
1.305 - ctx.importer = razor_importer_new();
1.306 - ctx.state = YUM_STATE_BEGIN;
1.307 -
1.308 - ctx.primary_parser = XML_ParserCreate(NULL);
1.309 - XML_SetUserData(ctx.primary_parser, &ctx);
1.310 - XML_SetElementHandler(ctx.primary_parser,
1.311 - yum_primary_start_element,
1.312 - yum_primary_end_element);
1.313 - XML_SetCharacterDataHandler(ctx.primary_parser,
1.314 - yum_character_data);
1.315 -
1.316 - ctx.filelists_parser = XML_ParserCreate(NULL);
1.317 - XML_SetUserData(ctx.filelists_parser, &ctx);
1.318 - XML_SetElementHandler(ctx.filelists_parser,
1.319 - yum_filelists_start_element,
1.320 - yum_filelists_end_element);
1.321 - XML_SetCharacterDataHandler(ctx.filelists_parser,
1.322 - yum_character_data);
1.323 -
1.324 - primary = gzopen("primary.xml.gz", "rb");
1.325 - if (primary == NULL)
1.326 - return NULL;
1.327 - filelists = gzopen("filelists.xml.gz", "rb");
1.328 - if (filelists == NULL)
1.329 - return NULL;
1.330 -
1.331 - ctx.current_parser = ctx.primary_parser;
1.332 -
1.333 - do {
1.334 - XML_GetParsingStatus(ctx.current_parser, &status);
1.335 - switch (status.parsing) {
1.336 - case XML_SUSPENDED:
1.337 - ret = XML_ResumeParser(ctx.current_parser);
1.338 - break;
1.339 - case XML_PARSING:
1.340 - case XML_INITIALIZED:
1.341 - buf = XML_GetBuffer(ctx.current_parser,
1.342 - XML_BUFFER_SIZE);
1.343 - if (ctx.current_parser == ctx.primary_parser)
1.344 - len = gzread(primary, buf, XML_BUFFER_SIZE);
1.345 - else
1.346 - len = gzread(filelists, buf, XML_BUFFER_SIZE);
1.347 - if (len < 0) {
1.348 - fprintf(stderr,
1.349 - "couldn't read input: %s\n",
1.350 - strerror(errno));
1.351 - return NULL;
1.352 - }
1.353 -
1.354 - XML_ParseBuffer(ctx.current_parser, len, len == 0);
1.355 - break;
1.356 - case XML_FINISHED:
1.357 - break;
1.358 - }
1.359 - } while (status.parsing != XML_FINISHED);
1.360 -
1.361 -
1.362 - XML_ParserFree(ctx.primary_parser);
1.363 - XML_ParserFree(ctx.filelists_parser);
1.364 -
1.365 - gzclose(primary);
1.366 - gzclose(filelists);
1.367 -
1.368 - return razor_importer_finish(ctx.importer);
1.369 -}