1.1 --- a/import.c Mon Feb 04 10:46:29 2008 -0500
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,379 +0,0 @@
1.4 -#define _GNU_SOURCE
1.5 -
1.6 -#include <string.h>
1.7 -#include <stdio.h>
1.8 -#include <sys/stat.h>
1.9 -#include <sys/mman.h>
1.10 -#include <unistd.h>
1.11 -#include <fcntl.h>
1.12 -#include <errno.h>
1.13 -
1.14 -#include <expat.h>
1.15 -#include <zlib.h>
1.16 -#include <rpm/rpmlib.h>
1.17 -#include <rpm/rpmdb.h>
1.18 -#include "razor.h"
1.19 -
1.20 -/* Import a yum filelist as a razor package set. */
1.21 -
1.22 -enum {
1.23 - YUM_STATE_BEGIN,
1.24 - YUM_STATE_PACKAGE_NAME,
1.25 - YUM_STATE_CHECKSUM,
1.26 - YUM_STATE_REQUIRES,
1.27 - YUM_STATE_PROVIDES,
1.28 - YUM_STATE_OBSOLETES,
1.29 - YUM_STATE_CONFLICTS,
1.30 - YUM_STATE_FILE
1.31 -};
1.32 -
1.33 -struct yum_context {
1.34 - XML_Parser primary_parser;
1.35 - XML_Parser filelists_parser;
1.36 - XML_Parser current_parser;
1.37 -
1.38 - struct razor_importer *importer;
1.39 - struct import_property_context *current_property_context;
1.40 - char name[256], buffer[512], *p;
1.41 - char pkgid[128];
1.42 - int state;
1.43 -};
1.44 -
1.45 -static void
1.46 -yum_primary_start_element(void *data, const char *name, const char **atts)
1.47 -{
1.48 - struct yum_context *ctx = data;
1.49 - const char *n, *version, *release;
1.50 - char buffer[128];
1.51 - int i;
1.52 -
1.53 - if (strcmp(name, "name") == 0) {
1.54 - ctx->state = YUM_STATE_PACKAGE_NAME;
1.55 - ctx->p = ctx->name;
1.56 - } else if (strcmp(name, "version") == 0) {
1.57 - version = NULL;
1.58 - release = NULL;
1.59 - for (i = 0; atts[i]; i += 2) {
1.60 - if (strcmp(atts[i], "ver") == 0)
1.61 - version = atts[i + 1];
1.62 - else if (strcmp(atts[i], "rel") == 0)
1.63 - release = atts[i + 1];
1.64 - }
1.65 - if (version == NULL || release == NULL) {
1.66 - fprintf(stderr, "invalid version tag, "
1.67 - "missing version or release attribute\n");
1.68 - return;
1.69 - }
1.70 -
1.71 - snprintf(buffer, sizeof buffer, "%s-%s", version, release);
1.72 - razor_importer_begin_package(ctx->importer, ctx->name, buffer);
1.73 - } else if (strcmp(name, "checksum") == 0) {
1.74 - ctx->p = ctx->pkgid;
1.75 - ctx->state = YUM_STATE_CHECKSUM;
1.76 - } else if (strcmp(name, "rpm:requires") == 0) {
1.77 - ctx->state = YUM_STATE_REQUIRES;
1.78 - } else if (strcmp(name, "rpm:provides") == 0) {
1.79 - ctx->state = YUM_STATE_PROVIDES;
1.80 - } else if (strcmp(name, "rpm:obsoletes") == 0) {
1.81 - ctx->state = YUM_STATE_OBSOLETES;
1.82 - } else if (strcmp(name, "rpm:conflicts") == 0) {
1.83 - ctx->state = YUM_STATE_CONFLICTS;
1.84 - } else if (strcmp(name, "rpm:entry") == 0 &&
1.85 - ctx->state != YUM_STATE_BEGIN) {
1.86 - n = NULL;
1.87 - version = NULL;
1.88 - release = NULL;
1.89 - for (i = 0; atts[i]; i += 2) {
1.90 - if (strcmp(atts[i], "name") == 0)
1.91 - n = atts[i + 1];
1.92 - else if (strcmp(atts[i], "ver") == 0)
1.93 - version = atts[i + 1];
1.94 - else if (strcmp(atts[i], "rel") == 0)
1.95 - release = atts[i + 1];
1.96 - }
1.97 -
1.98 - if (n == NULL) {
1.99 - fprintf(stderr, "invalid rpm:entry, "
1.100 - "missing name or version attributes\n");
1.101 - return;
1.102 - }
1.103 -
1.104 - if (version && release)
1.105 - snprintf(buffer, sizeof buffer,
1.106 - "%s-%s", version, release);
1.107 - else if (version)
1.108 - strcpy(buffer, version);
1.109 - else
1.110 - buffer[0] = '\0';
1.111 -
1.112 - switch (ctx->state) {
1.113 - case YUM_STATE_REQUIRES:
1.114 - razor_importer_add_property(ctx->importer, n, buffer,
1.115 - RAZOR_PROPERTY_REQUIRES);
1.116 - break;
1.117 - case YUM_STATE_PROVIDES:
1.118 - razor_importer_add_property(ctx->importer, n, buffer,
1.119 - RAZOR_PROPERTY_PROVIDES);
1.120 - break;
1.121 - case YUM_STATE_OBSOLETES:
1.122 - razor_importer_add_property(ctx->importer, n, buffer,
1.123 - RAZOR_PROPERTY_OBSOLETES);
1.124 - break;
1.125 - case YUM_STATE_CONFLICTS:
1.126 - razor_importer_add_property(ctx->importer, n, buffer,
1.127 - RAZOR_PROPERTY_CONFLICTS);
1.128 - break;
1.129 - }
1.130 - }
1.131 -}
1.132 -
1.133 -static void
1.134 -yum_primary_end_element (void *data, const char *name)
1.135 -{
1.136 - struct yum_context *ctx = data;
1.137 -
1.138 - switch (ctx->state) {
1.139 - case YUM_STATE_PACKAGE_NAME:
1.140 - case YUM_STATE_CHECKSUM:
1.141 - case YUM_STATE_FILE:
1.142 - ctx->state = YUM_STATE_BEGIN;
1.143 - break;
1.144 - }
1.145 -
1.146 - if (strcmp(name, "package") == 0) {
1.147 - XML_StopParser(ctx->current_parser, XML_TRUE);
1.148 - ctx->current_parser = ctx->filelists_parser;
1.149 - }
1.150 -}
1.151 -
1.152 -static void
1.153 -yum_character_data (void *data, const XML_Char *s, int len)
1.154 -{
1.155 - struct yum_context *ctx = data;
1.156 -
1.157 - switch (ctx->state) {
1.158 - case YUM_STATE_PACKAGE_NAME:
1.159 - case YUM_STATE_CHECKSUM:
1.160 - case YUM_STATE_FILE:
1.161 - memcpy(ctx->p, s, len);
1.162 - ctx->p += len;
1.163 - *ctx->p = '\0';
1.164 - break;
1.165 - }
1.166 -}
1.167 -
1.168 -static void
1.169 -yum_filelists_start_element(void *data, const char *name, const char **atts)
1.170 -{
1.171 - struct yum_context *ctx = data;
1.172 - const char *pkg, *pkgid;
1.173 - int i;
1.174 -
1.175 - if (strcmp(name, "package") == 0) {
1.176 - pkg = NULL;
1.177 - pkgid = NULL;
1.178 - for (i = 0; atts[i]; i += 2) {
1.179 - if (strcmp(atts[i], "name") == 0)
1.180 - pkg = atts[i + 1];
1.181 - else if (strcmp(atts[i], "pkgid") == 0)
1.182 - pkgid = atts[i + 1];
1.183 - }
1.184 - if (strcmp(pkgid, ctx->pkgid) != 0)
1.185 - fprintf(stderr, "primary.xml and filelists.xml "
1.186 - "mismatch for %s: %s vs %s",
1.187 - pkg, pkgid, ctx->pkgid);
1.188 - } else if (strcmp(name, "file") == 0) {
1.189 - ctx->state = YUM_STATE_FILE;
1.190 - ctx->p = ctx->buffer;
1.191 - }
1.192 -}
1.193 -
1.194 -
1.195 -static void
1.196 -yum_filelists_end_element (void *data, const char *name)
1.197 -{
1.198 - struct yum_context *ctx = data;
1.199 -
1.200 - ctx->state = YUM_STATE_BEGIN;
1.201 - if (strcmp(name, "package") == 0) {
1.202 - XML_StopParser(ctx->current_parser, XML_TRUE);
1.203 - ctx->current_parser = ctx->primary_parser;
1.204 - razor_importer_finish_package(ctx->importer);
1.205 - } else if (strcmp(name, "file") == 0)
1.206 - razor_importer_add_file(ctx->importer, ctx->buffer);
1.207 -
1.208 -}
1.209 -
1.210 -#define XML_BUFFER_SIZE 4096
1.211 -
1.212 -struct razor_set *
1.213 -razor_set_create_from_yum(void)
1.214 -{
1.215 - struct yum_context ctx;
1.216 - void *buf;
1.217 - int len, ret;
1.218 - gzFile primary, filelists;
1.219 - XML_ParsingStatus status;
1.220 -
1.221 - ctx.importer = razor_importer_new();
1.222 - ctx.state = YUM_STATE_BEGIN;
1.223 -
1.224 - ctx.primary_parser = XML_ParserCreate(NULL);
1.225 - XML_SetUserData(ctx.primary_parser, &ctx);
1.226 - XML_SetElementHandler(ctx.primary_parser,
1.227 - yum_primary_start_element,
1.228 - yum_primary_end_element);
1.229 - XML_SetCharacterDataHandler(ctx.primary_parser,
1.230 - yum_character_data);
1.231 -
1.232 - ctx.filelists_parser = XML_ParserCreate(NULL);
1.233 - XML_SetUserData(ctx.filelists_parser, &ctx);
1.234 - XML_SetElementHandler(ctx.filelists_parser,
1.235 - yum_filelists_start_element,
1.236 - yum_filelists_end_element);
1.237 - XML_SetCharacterDataHandler(ctx.filelists_parser,
1.238 - yum_character_data);
1.239 -
1.240 - primary = gzopen("primary.xml.gz", "rb");
1.241 - if (primary == NULL)
1.242 - return NULL;
1.243 - filelists = gzopen("filelists.xml.gz", "rb");
1.244 - if (filelists == NULL)
1.245 - return NULL;
1.246 -
1.247 - ctx.current_parser = ctx.primary_parser;
1.248 -
1.249 - do {
1.250 - XML_GetParsingStatus(ctx.current_parser, &status);
1.251 - switch (status.parsing) {
1.252 - case XML_SUSPENDED:
1.253 - ret = XML_ResumeParser(ctx.current_parser);
1.254 - break;
1.255 - case XML_PARSING:
1.256 - case XML_INITIALIZED:
1.257 - buf = XML_GetBuffer(ctx.current_parser,
1.258 - XML_BUFFER_SIZE);
1.259 - if (ctx.current_parser == ctx.primary_parser)
1.260 - len = gzread(primary, buf, XML_BUFFER_SIZE);
1.261 - else
1.262 - len = gzread(filelists, buf, XML_BUFFER_SIZE);
1.263 - if (len < 0) {
1.264 - fprintf(stderr,
1.265 - "couldn't read input: %s\n",
1.266 - strerror(errno));
1.267 - return NULL;
1.268 - }
1.269 -
1.270 - XML_ParseBuffer(ctx.current_parser, len, len == 0);
1.271 - break;
1.272 - case XML_FINISHED:
1.273 - break;
1.274 - }
1.275 - } while (status.parsing != XML_FINISHED);
1.276 -
1.277 -
1.278 - XML_ParserFree(ctx.primary_parser);
1.279 - XML_ParserFree(ctx.filelists_parser);
1.280 -
1.281 - gzclose(primary);
1.282 - gzclose(filelists);
1.283 -
1.284 - return razor_importer_finish(ctx.importer);
1.285 -}
1.286 -
1.287 -union rpm_entry {
1.288 - void *p;
1.289 - char *string;
1.290 - char **list;
1.291 - unsigned int *flags;
1.292 -};
1.293 -
1.294 -static void
1.295 -add_properties(struct razor_importer *importer,
1.296 - enum razor_property_type property_type,
1.297 - Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
1.298 -{
1.299 - union rpm_entry names, versions, flags;
1.300 - int_32 i, type, count;
1.301 -
1.302 - headerGetEntry(h, name_tag, &type, &names.p, &count);
1.303 - headerGetEntry(h, version_tag, &type, &versions.p, &count);
1.304 - headerGetEntry(h, flags_tag, &type, &flags.p, &count);
1.305 -
1.306 - for (i = 0; i < count; i++)
1.307 - razor_importer_add_property(importer,
1.308 - names.list[i],
1.309 - versions.list[i],
1.310 - property_type);
1.311 -}
1.312 -
1.313 -struct razor_set *
1.314 -razor_set_create_from_rpmdb(void)
1.315 -{
1.316 - struct razor_importer *importer;
1.317 - rpmdbMatchIterator iter;
1.318 - Header h;
1.319 - int_32 type, count, i;
1.320 - union rpm_entry name, version, release;
1.321 - union rpm_entry basenames, dirnames, dirindexes;
1.322 - char filename[PATH_MAX];
1.323 - rpmdb db;
1.324 -
1.325 - rpmReadConfigFiles(NULL, NULL);
1.326 -
1.327 - if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
1.328 - fprintf(stderr, "cannot open rpm database\n");
1.329 - exit(1);
1.330 - }
1.331 -
1.332 - importer = razor_importer_new();
1.333 -
1.334 - iter = rpmdbInitIterator(db, 0, NULL, 0);
1.335 - while (h = rpmdbNextIterator(iter), h != NULL) {
1.336 - headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
1.337 - headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
1.338 - headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
1.339 - snprintf(filename, sizeof filename, "%s-%s",
1.340 - version.string, release.string);
1.341 - razor_importer_begin_package(importer, name.string, filename);
1.342 -
1.343 - add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
1.344 - RPMTAG_REQUIRENAME,
1.345 - RPMTAG_REQUIREVERSION,
1.346 - RPMTAG_REQUIREFLAGS);
1.347 -
1.348 - add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
1.349 - RPMTAG_PROVIDENAME,
1.350 - RPMTAG_PROVIDEVERSION,
1.351 - RPMTAG_PROVIDEFLAGS);
1.352 -
1.353 - add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
1.354 - RPMTAG_OBSOLETENAME,
1.355 - RPMTAG_OBSOLETEVERSION,
1.356 - RPMTAG_OBSOLETEFLAGS);
1.357 -
1.358 - add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
1.359 - RPMTAG_CONFLICTNAME,
1.360 - RPMTAG_CONFLICTVERSION,
1.361 - RPMTAG_CONFLICTFLAGS);
1.362 -
1.363 - headerGetEntry(h, RPMTAG_BASENAMES, &type,
1.364 - &basenames.p, &count);
1.365 - headerGetEntry(h, RPMTAG_DIRNAMES, &type,
1.366 - &dirnames.p, &count);
1.367 - headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
1.368 - &dirindexes.p, &count);
1.369 - for (i = 0; i < count; i++) {
1.370 - snprintf(filename, sizeof filename, "%s%s",
1.371 - dirnames.list[dirindexes.flags[i]],
1.372 - basenames.list[i]);
1.373 - razor_importer_add_file(importer, filename);
1.374 - }
1.375 -
1.376 - razor_importer_finish_package(importer);
1.377 - }
1.378 -
1.379 - rpmdbClose(db);
1.380 -
1.381 - return razor_importer_finish(importer);
1.382 -}