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 -}
2.1 --- a/main.c Mon Feb 04 10:46:29 2008 -0500
2.2 +++ b/main.c Mon Feb 04 14:25:45 2008 -0500
2.3 @@ -14,6 +14,10 @@
2.4 static const char *rawhide_repo_filename = "rawhide.repo";
2.5 static const char *updated_repo_filename = "system-updated.repo";
2.6
2.7 +static const char *relations[] = {
2.8 + "<", "<=", "=", ">=", ">"
2.9 +};
2.10 +
2.11 static int
2.12 command_list(int argc, const char *argv[])
2.13 {
2.14 @@ -46,6 +50,7 @@
2.15 struct razor_property_iterator *pi;
2.16 const char *name, *version;
2.17 enum razor_property_type type;
2.18 + enum razor_version_relation relation;
2.19
2.20 set = razor_set_open(repo_filename);
2.21 if (package_name)
2.22 @@ -55,13 +60,15 @@
2.23
2.24 pi = razor_property_iterator_create(set, package);
2.25 while (razor_property_iterator_next(pi, &property,
2.26 - &name, &version, &type)) {
2.27 + &name, &relation, &version,
2.28 + &type)) {
2.29 if (type != required_type)
2.30 continue;
2.31 if (version[0] == '\0')
2.32 printf("%s\n", name);
2.33 else
2.34 - printf("%s-%s\n", name, version);
2.35 + printf("%s %s %s\n", name, relations[relation],
2.36 + version);
2.37 }
2.38 razor_property_iterator_destroy(pi);
2.39
2.40 @@ -168,6 +175,7 @@
2.41 struct razor_property_iterator *pi;
2.42 const char *name, *version;
2.43 enum razor_property_type type;
2.44 + enum razor_version_relation relation;
2.45
2.46 if (ref_name == NULL)
2.47 return 0;
2.48 @@ -178,10 +186,12 @@
2.49
2.50 pi = razor_property_iterator_create(set, NULL);
2.51 while (razor_property_iterator_next(pi, &property,
2.52 - &name, &version, &type)) {
2.53 + &name, &relation, &version,
2.54 + &type)) {
2.55 if (strcmp(ref_name, name) != 0)
2.56 continue;
2.57 - if (ref_version && strcmp(ref_version, version) != 0)
2.58 + if (ref_version && relation == RAZOR_VERSION_EQUAL &&
2.59 + strcmp(ref_version, version) != 0)
2.60 continue;
2.61 if (ref_type != type)
2.62 continue;
3.1 --- a/razor.c Mon Feb 04 10:46:29 2008 -0500
3.2 +++ b/razor.c Mon Feb 04 14:25:45 2008 -0500
3.3 @@ -58,6 +58,7 @@
3.4
3.5 struct razor_property {
3.6 uint32_t name;
3.7 + uint32_t relation;
3.8 uint32_t version;
3.9 uint32_t packages;
3.10 };
3.11 @@ -440,7 +441,9 @@
3.12
3.13 void
3.14 razor_importer_add_property(struct razor_importer *importer,
3.15 - const char *name, const char *version,
3.16 + const char *name,
3.17 + enum razor_version_relation relation,
3.18 + const char *version,
3.19 enum razor_property_type type)
3.20 {
3.21 struct razor_property *p;
3.22 @@ -448,6 +451,7 @@
3.23
3.24 p = array_add(&importer->set->properties, sizeof *p);
3.25 p->name = hashtable_tokenize(&importer->table, name) | (type << 30);
3.26 + p->relation = relation;
3.27 p->version = hashtable_tokenize(&importer->table, version);
3.28 p->packages = importer->package -
3.29 (struct razor_package *) importer->set->packages.data;
3.30 @@ -642,10 +646,13 @@
3.31 struct razor_set *set = data;
3.32 char *pool = set->string_pool.data;
3.33
3.34 - if (prop1->name == prop2->name)
3.35 - return versioncmp(&pool[prop1->version],
3.36 - &pool[prop2->version]);
3.37 - else if ((prop1->name & RAZOR_ENTRY_MASK) == (prop2->name & RAZOR_ENTRY_MASK))
3.38 + if (prop1->name == prop2->name) {
3.39 + if (prop1->relation == prop2->relation)
3.40 + return versioncmp(&pool[prop1->version],
3.41 + &pool[prop2->version]);
3.42 + else
3.43 + return prop1->relation - prop2->relation;
3.44 + } else if ((prop1->name & RAZOR_ENTRY_MASK) == (prop2->name & RAZOR_ENTRY_MASK))
3.45 return (prop1->name >> 30) - (prop2->name >> 30);
3.46 else
3.47 return strcmp(&pool[prop1->name & RAZOR_ENTRY_MASK],
3.48 @@ -671,9 +678,11 @@
3.49 rmap = malloc(count * sizeof *map);
3.50 pkgs = zalloc(count * sizeof *pkgs);
3.51 for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
3.52 - if (rp->name != up->name || rp->version != up->version) {
3.53 + if (rp->name != up->name || rp->relation != up->relation ||
3.54 + rp->version != up->version) {
3.55 up++;
3.56 up->name = rp->name;
3.57 + up->relation = rp->relation;
3.58 up->version = rp->version;
3.59 }
3.60
3.61 @@ -1061,7 +1070,9 @@
3.62 int
3.63 razor_property_iterator_next(struct razor_property_iterator *pi,
3.64 struct razor_property **property,
3.65 - const char **name, const char **version,
3.66 + const char **name,
3.67 + enum razor_version_relation *relation,
3.68 + const char **version,
3.69 enum razor_property_type *type)
3.70 {
3.71 char *pool;
3.72 @@ -1082,6 +1093,7 @@
3.73 pool = pi->set->string_pool.data;
3.74 *property = p;
3.75 *name = &pool[p->name & RAZOR_ENTRY_MASK];
3.76 + *relation = p->relation;
3.77 *version = &pool[p->version];
3.78 *type = p->name >> 30;
3.79 } else {
3.80 @@ -1443,12 +1455,14 @@
3.81
3.82 static uint32_t
3.83 add_property(struct razor_merger *merger,
3.84 - const char *name, const char *version, int type)
3.85 + const char *name, enum razor_version_relation relation,
3.86 + const char *version, int type)
3.87 {
3.88 struct razor_property *p;
3.89
3.90 p = array_add(&merger->set->properties, sizeof *p);
3.91 p->name = hashtable_tokenize(&merger->table, name) | (type << 30);
3.92 + p->relation = relation;
3.93 p->version = hashtable_tokenize(&merger->table, version);
3.94
3.95 return p - (struct razor_property *) merger->set->properties.data;
3.96 @@ -1494,21 +1508,26 @@
3.97 else
3.98 cmp = 1;
3.99 if (cmp == 0)
3.100 + cmp = p1->relation - p2->relation;
3.101 + if (cmp == 0)
3.102 cmp = versioncmp(&pool1[p1->version],
3.103 &pool2[p2->version]);
3.104 if (cmp < 0) {
3.105 map1[i++] = add_property(merger,
3.106 &pool1[p1->name & RAZOR_ENTRY_MASK],
3.107 + p1->relation,
3.108 &pool1[p1->version],
3.109 (p1->name >> 30));
3.110 } else if (cmp > 0) {
3.111 map2[j++] = add_property(merger,
3.112 &pool2[p2->name & RAZOR_ENTRY_MASK],
3.113 + p2->relation,
3.114 &pool2[p2->version],
3.115 (p2->name >> 30));
3.116 } else {
3.117 map1[i++] = map2[j++] = add_property(merger,
3.118 &pool1[p1->name & RAZOR_ENTRY_MASK],
3.119 + p1->relation,
3.120 &pool1[p1->version],
3.121 (p1->name >> 30));
3.122 }
4.1 --- a/razor.h Mon Feb 04 10:46:29 2008 -0500
4.2 +++ b/razor.h Mon Feb 04 14:25:45 2008 -0500
4.3 @@ -14,6 +14,14 @@
4.4 RAZOR_PROPERTY_OBSOLETES
4.5 };
4.6
4.7 +enum razor_version_relation {
4.8 + RAZOR_VERSION_LESS,
4.9 + RAZOR_VERSION_LESS_OR_EQUAL,
4.10 + RAZOR_VERSION_EQUAL,
4.11 + RAZOR_VERSION_GREATER_OR_EQUAL,
4.12 + RAZOR_VERSION_GREATER
4.13 +};
4.14 +
4.15 struct razor_set *razor_set_create(void);
4.16 struct razor_set *razor_set_open(const char *filename);
4.17 void razor_set_destroy(struct razor_set *set);
4.18 @@ -43,7 +51,9 @@
4.19 struct razor_package *package);
4.20 int razor_property_iterator_next(struct razor_property_iterator *pi,
4.21 struct razor_property **property,
4.22 - const char **name, const char **version,
4.23 + const char **name,
4.24 + enum razor_version_relation *relation,
4.25 + const char **version,
4.26 enum razor_property_type *type);
4.27 void
4.28 razor_property_iterator_destroy(struct razor_property_iterator *pi);
4.29 @@ -76,7 +86,9 @@
4.30 void razor_importer_begin_package(struct razor_importer *importer,
4.31 const char *name, const char *version);
4.32 void razor_importer_add_property(struct razor_importer *importer,
4.33 - const char *name, const char *version,
4.34 + const char *name,
4.35 + enum razor_version_relation relation,
4.36 + const char *version,
4.37 enum razor_property_type type);
4.38 void razor_importer_add_file(struct razor_importer *importer,
4.39 const char *name);
5.1 --- a/rpm.c Mon Feb 04 10:46:29 2008 -0500
5.2 +++ b/rpm.c Mon Feb 04 14:25:45 2008 -0500
5.3 @@ -9,6 +9,7 @@
5.4 #include <unistd.h>
5.5 #include <arpa/inet.h>
5.6 #include <rpm/rpmlib.h>
5.7 +#include <rpm/rpmdb.h>
5.8 #include <zlib.h>
5.9
5.10 #include "razor.h"
5.11 @@ -73,22 +74,47 @@
5.12 return NULL;
5.13 }
5.14
5.15 +static enum razor_version_relation
5.16 +rpm_to_razor_flags (uint_32 flags)
5.17 +{
5.18 + switch (flags & (RPMSENSE_LESS | RPMSENSE_EQUAL | RPMSENSE_GREATER)) {
5.19 + case RPMSENSE_LESS:
5.20 + return RAZOR_VERSION_LESS;
5.21 + case RPMSENSE_LESS|RPMSENSE_EQUAL:
5.22 + return RAZOR_VERSION_LESS_OR_EQUAL;
5.23 + case RPMSENSE_EQUAL:
5.24 + return RAZOR_VERSION_EQUAL;
5.25 + case RPMSENSE_GREATER|RPMSENSE_EQUAL:
5.26 + return RAZOR_VERSION_GREATER_OR_EQUAL;
5.27 + case RPMSENSE_GREATER:
5.28 + return RAZOR_VERSION_GREATER;
5.29 + }
5.30 +
5.31 + /* FIXME? */
5.32 + return RAZOR_VERSION_EQUAL;
5.33 +}
5.34 +
5.35 static void
5.36 import_properties(struct razor_importer *importer, unsigned long type,
5.37 struct razor_rpm *rpm,
5.38 int name_tag, int version_tag, int flags_tag)
5.39 {
5.40 const char *name, *version;
5.41 + uint_32 flags;
5.42 unsigned int i, count;
5.43
5.44 name = razor_rpm_get_indirect(rpm, name_tag, &count);
5.45 if (name == NULL)
5.46 return;
5.47
5.48 + flags = *(uint_32 *)razor_rpm_get_indirect(rpm, flags_tag, &count);
5.49 +
5.50 /* FIXME: Concat version and release. */
5.51 version = razor_rpm_get_indirect(rpm, version_tag, &count);
5.52 for (i = 0; i < count; i++) {
5.53 - razor_importer_add_property(importer, name, version, type);
5.54 + razor_importer_add_property(importer, name,
5.55 + rpm_to_razor_flags (flags),
5.56 + version, type);
5.57 name += strlen(name) + 1;
5.58 version += strlen(version) + 1;
5.59 }
5.60 @@ -534,3 +560,101 @@
5.61
5.62 return 0;
5.63 }
5.64 +
5.65 +union rpm_entry {
5.66 + void *p;
5.67 + char *string;
5.68 + char **list;
5.69 + uint_32 *flags;
5.70 +};
5.71 +
5.72 +static void
5.73 +add_properties(struct razor_importer *importer,
5.74 + enum razor_property_type property_type,
5.75 + Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
5.76 +{
5.77 + union rpm_entry names, versions, flags;
5.78 + int_32 i, type, count;
5.79 +
5.80 + headerGetEntry(h, name_tag, &type, &names.p, &count);
5.81 + headerGetEntry(h, version_tag, &type, &versions.p, &count);
5.82 + headerGetEntry(h, flags_tag, &type, &flags.p, &count);
5.83 +
5.84 + for (i = 0; i < count; i++)
5.85 + razor_importer_add_property(importer,
5.86 + names.list[i],
5.87 + rpm_to_razor_flags (flags.flags[i]),
5.88 + versions.list[i],
5.89 + property_type);
5.90 +}
5.91 +
5.92 +struct razor_set *
5.93 +razor_set_create_from_rpmdb(void)
5.94 +{
5.95 + struct razor_importer *importer;
5.96 + rpmdbMatchIterator iter;
5.97 + Header h;
5.98 + int_32 type, count, i;
5.99 + union rpm_entry name, version, release;
5.100 + union rpm_entry basenames, dirnames, dirindexes;
5.101 + char filename[PATH_MAX];
5.102 + rpmdb db;
5.103 +
5.104 + rpmReadConfigFiles(NULL, NULL);
5.105 +
5.106 + if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
5.107 + fprintf(stderr, "cannot open rpm database\n");
5.108 + exit(1);
5.109 + }
5.110 +
5.111 + importer = razor_importer_new();
5.112 +
5.113 + iter = rpmdbInitIterator(db, 0, NULL, 0);
5.114 + while (h = rpmdbNextIterator(iter), h != NULL) {
5.115 + headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
5.116 + headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
5.117 + headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
5.118 + snprintf(filename, sizeof filename, "%s-%s",
5.119 + version.string, release.string);
5.120 + razor_importer_begin_package(importer, name.string, filename);
5.121 +
5.122 + add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
5.123 + RPMTAG_REQUIRENAME,
5.124 + RPMTAG_REQUIREVERSION,
5.125 + RPMTAG_REQUIREFLAGS);
5.126 +
5.127 + add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
5.128 + RPMTAG_PROVIDENAME,
5.129 + RPMTAG_PROVIDEVERSION,
5.130 + RPMTAG_PROVIDEFLAGS);
5.131 +
5.132 + add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
5.133 + RPMTAG_OBSOLETENAME,
5.134 + RPMTAG_OBSOLETEVERSION,
5.135 + RPMTAG_OBSOLETEFLAGS);
5.136 +
5.137 + add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
5.138 + RPMTAG_CONFLICTNAME,
5.139 + RPMTAG_CONFLICTVERSION,
5.140 + RPMTAG_CONFLICTFLAGS);
5.141 +
5.142 + headerGetEntry(h, RPMTAG_BASENAMES, &type,
5.143 + &basenames.p, &count);
5.144 + headerGetEntry(h, RPMTAG_DIRNAMES, &type,
5.145 + &dirnames.p, &count);
5.146 + headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
5.147 + &dirindexes.p, &count);
5.148 + for (i = 0; i < count; i++) {
5.149 + snprintf(filename, sizeof filename, "%s%s",
5.150 + dirnames.list[dirindexes.flags[i]],
5.151 + basenames.list[i]);
5.152 + razor_importer_add_file(importer, filename);
5.153 + }
5.154 +
5.155 + razor_importer_finish_package(importer);
5.156 + }
5.157 +
5.158 + rpmdbClose(db);
5.159 +
5.160 + return razor_importer_finish(importer);
5.161 +}
6.1 --- a/test-driver.c Mon Feb 04 10:46:29 2008 -0500
6.2 +++ b/test-driver.c Mon Feb 04 14:25:45 2008 -0500
6.3 @@ -95,7 +95,8 @@
6.4 exit(-1);
6.5 }
6.6
6.7 - razor_importer_add_property(ctx->importer, name, version, type);
6.8 + razor_importer_add_property(ctx->importer, name,
6.9 + RAZOR_VERSION_EQUAL, version, type);
6.10 }
6.11
6.12 static void
6.13 @@ -190,6 +191,7 @@
6.14 struct razor_property *property;
6.15 const char *name, *version;
6.16 enum razor_property_type type;
6.17 + enum razor_version_relation relation;
6.18
6.19 if (ctx->package_iterator != NULL) {
6.20 if (razor_package_iterator_next(ctx->package_iterator,
6.21 @@ -206,7 +208,8 @@
6.22 if (ctx->property_iterator != NULL) {
6.23 if (razor_property_iterator_next(ctx->property_iterator,
6.24 &property,
6.25 - &name, &version, &type)) {
6.26 + &name, &relation, &version,
6.27 + &type)) {
6.28 fprintf(stderr, "too few properties in set\n");
6.29 exit(-1);
6.30 }
6.31 @@ -251,6 +254,7 @@
6.32 struct razor_property *property;
6.33 const char *name, *version, *ref_name, *ref_version;
6.34 enum razor_property_type type;
6.35 + enum razor_version_relation relation;
6.36 int same_version;
6.37
6.38 if (ctx->property_iterator == NULL) {
6.39 @@ -262,7 +266,7 @@
6.40
6.41 get_atts(atts, "name", &ref_name, "eq", &ref_version, NULL);
6.42 if (!razor_property_iterator_next(ctx->property_iterator, &property,
6.43 - &name, &version, &type)) {
6.44 + &name, &relation, &version, &type)) {
6.45 fprintf(stderr, "too many properties in set\n");
6.46 exit(-1);
6.47 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/yum.c Mon Feb 04 14:25:45 2008 -0500
7.3 @@ -0,0 +1,312 @@
7.4 +#define _GNU_SOURCE
7.5 +
7.6 +#include <string.h>
7.7 +#include <stdio.h>
7.8 +#include <sys/stat.h>
7.9 +#include <sys/mman.h>
7.10 +#include <unistd.h>
7.11 +#include <fcntl.h>
7.12 +#include <errno.h>
7.13 +
7.14 +#include <expat.h>
7.15 +#include <zlib.h>
7.16 +#include "razor.h"
7.17 +
7.18 +/* Import a yum filelist as a razor package set. */
7.19 +
7.20 +enum {
7.21 + YUM_STATE_BEGIN,
7.22 + YUM_STATE_PACKAGE_NAME,
7.23 + YUM_STATE_CHECKSUM,
7.24 + YUM_STATE_REQUIRES,
7.25 + YUM_STATE_PROVIDES,
7.26 + YUM_STATE_OBSOLETES,
7.27 + YUM_STATE_CONFLICTS,
7.28 + YUM_STATE_FILE
7.29 +};
7.30 +
7.31 +struct yum_context {
7.32 + XML_Parser primary_parser;
7.33 + XML_Parser filelists_parser;
7.34 + XML_Parser current_parser;
7.35 +
7.36 + struct razor_importer *importer;
7.37 + struct import_property_context *current_property_context;
7.38 + char name[256], buffer[512], *p;
7.39 + char pkgid[128];
7.40 + int state;
7.41 +};
7.42 +
7.43 +static enum razor_version_relation
7.44 +yum_to_razor_flags (const char *flags)
7.45 +{
7.46 + /* FIXME? */
7.47 + if (!flags)
7.48 + return RAZOR_VERSION_EQUAL;
7.49 +
7.50 + if (flags[0] == 'L') {
7.51 + if (flags[1] == 'T')
7.52 + return RAZOR_VERSION_LESS;
7.53 + else
7.54 + return RAZOR_VERSION_LESS_OR_EQUAL;
7.55 + } else if (flags[0] == 'G') {
7.56 + if (flags[1] == 'T')
7.57 + return RAZOR_VERSION_GREATER;
7.58 + else
7.59 + return RAZOR_VERSION_GREATER_OR_EQUAL;
7.60 + } else
7.61 + return RAZOR_VERSION_EQUAL;
7.62 +}
7.63 +
7.64 +static void
7.65 +yum_primary_start_element(void *data, const char *name, const char **atts)
7.66 +{
7.67 + struct yum_context *ctx = data;
7.68 + const char *n, *version, *release, *flags;
7.69 + char buffer[128];
7.70 + int i;
7.71 +
7.72 + if (strcmp(name, "name") == 0) {
7.73 + ctx->state = YUM_STATE_PACKAGE_NAME;
7.74 + ctx->p = ctx->name;
7.75 + } else if (strcmp(name, "version") == 0) {
7.76 + version = NULL;
7.77 + release = NULL;
7.78 + for (i = 0; atts[i]; i += 2) {
7.79 + if (strcmp(atts[i], "ver") == 0)
7.80 + version = atts[i + 1];
7.81 + else if (strcmp(atts[i], "rel") == 0)
7.82 + release = atts[i + 1];
7.83 + }
7.84 + if (version == NULL || release == NULL) {
7.85 + fprintf(stderr, "invalid version tag, "
7.86 + "missing version or release attribute\n");
7.87 + return;
7.88 + }
7.89 +
7.90 + snprintf(buffer, sizeof buffer, "%s-%s", version, release);
7.91 + razor_importer_begin_package(ctx->importer, ctx->name, buffer);
7.92 + } else if (strcmp(name, "checksum") == 0) {
7.93 + ctx->p = ctx->pkgid;
7.94 + ctx->state = YUM_STATE_CHECKSUM;
7.95 + } else if (strcmp(name, "rpm:requires") == 0) {
7.96 + ctx->state = YUM_STATE_REQUIRES;
7.97 + } else if (strcmp(name, "rpm:provides") == 0) {
7.98 + ctx->state = YUM_STATE_PROVIDES;
7.99 + } else if (strcmp(name, "rpm:obsoletes") == 0) {
7.100 + ctx->state = YUM_STATE_OBSOLETES;
7.101 + } else if (strcmp(name, "rpm:conflicts") == 0) {
7.102 + ctx->state = YUM_STATE_CONFLICTS;
7.103 + } else if (strcmp(name, "rpm:entry") == 0 &&
7.104 + ctx->state != YUM_STATE_BEGIN) {
7.105 + n = NULL;
7.106 + version = NULL;
7.107 + release = NULL;
7.108 + flags = NULL;
7.109 + for (i = 0; atts[i]; i += 2) {
7.110 + if (strcmp(atts[i], "name") == 0)
7.111 + n = atts[i + 1];
7.112 + else if (strcmp(atts[i], "ver") == 0)
7.113 + version = atts[i + 1];
7.114 + else if (strcmp(atts[i], "rel") == 0)
7.115 + release = atts[i + 1];
7.116 + else if (strcmp(atts[i], "flags") == 0)
7.117 + flags = atts[i + 1];
7.118 + }
7.119 +
7.120 + if (n == NULL) {
7.121 + fprintf(stderr, "invalid rpm:entry, "
7.122 + "missing name or version attributes\n");
7.123 + return;
7.124 + }
7.125 +
7.126 + if (version && release)
7.127 + snprintf(buffer, sizeof buffer,
7.128 + "%s-%s", version, release);
7.129 + else if (version)
7.130 + strcpy(buffer, version);
7.131 + else
7.132 + buffer[0] = '\0';
7.133 +
7.134 + switch (ctx->state) {
7.135 + case YUM_STATE_REQUIRES:
7.136 + razor_importer_add_property(ctx->importer, n,
7.137 + yum_to_razor_flags (flags),
7.138 + buffer,
7.139 + RAZOR_PROPERTY_REQUIRES);
7.140 + break;
7.141 + case YUM_STATE_PROVIDES:
7.142 + razor_importer_add_property(ctx->importer, n,
7.143 + yum_to_razor_flags (flags),
7.144 + buffer,
7.145 + RAZOR_PROPERTY_PROVIDES);
7.146 + break;
7.147 + case YUM_STATE_OBSOLETES:
7.148 + razor_importer_add_property(ctx->importer, n,
7.149 + yum_to_razor_flags (flags),
7.150 + buffer,
7.151 + RAZOR_PROPERTY_OBSOLETES);
7.152 + break;
7.153 + case YUM_STATE_CONFLICTS:
7.154 + razor_importer_add_property(ctx->importer, n,
7.155 + yum_to_razor_flags (flags),
7.156 + buffer,
7.157 + RAZOR_PROPERTY_CONFLICTS);
7.158 + break;
7.159 + }
7.160 + }
7.161 +}
7.162 +
7.163 +static void
7.164 +yum_primary_end_element (void *data, const char *name)
7.165 +{
7.166 + struct yum_context *ctx = data;
7.167 +
7.168 + switch (ctx->state) {
7.169 + case YUM_STATE_PACKAGE_NAME:
7.170 + case YUM_STATE_CHECKSUM:
7.171 + case YUM_STATE_FILE:
7.172 + ctx->state = YUM_STATE_BEGIN;
7.173 + break;
7.174 + }
7.175 +
7.176 + if (strcmp(name, "package") == 0) {
7.177 + XML_StopParser(ctx->current_parser, XML_TRUE);
7.178 + ctx->current_parser = ctx->filelists_parser;
7.179 + }
7.180 +}
7.181 +
7.182 +static void
7.183 +yum_character_data (void *data, const XML_Char *s, int len)
7.184 +{
7.185 + struct yum_context *ctx = data;
7.186 +
7.187 + switch (ctx->state) {
7.188 + case YUM_STATE_PACKAGE_NAME:
7.189 + case YUM_STATE_CHECKSUM:
7.190 + case YUM_STATE_FILE:
7.191 + memcpy(ctx->p, s, len);
7.192 + ctx->p += len;
7.193 + *ctx->p = '\0';
7.194 + break;
7.195 + }
7.196 +}
7.197 +
7.198 +static void
7.199 +yum_filelists_start_element(void *data, const char *name, const char **atts)
7.200 +{
7.201 + struct yum_context *ctx = data;
7.202 + const char *pkg, *pkgid;
7.203 + int i;
7.204 +
7.205 + if (strcmp(name, "package") == 0) {
7.206 + pkg = NULL;
7.207 + pkgid = NULL;
7.208 + for (i = 0; atts[i]; i += 2) {
7.209 + if (strcmp(atts[i], "name") == 0)
7.210 + pkg = atts[i + 1];
7.211 + else if (strcmp(atts[i], "pkgid") == 0)
7.212 + pkgid = atts[i + 1];
7.213 + }
7.214 + if (strcmp(pkgid, ctx->pkgid) != 0)
7.215 + fprintf(stderr, "primary.xml and filelists.xml "
7.216 + "mismatch for %s: %s vs %s",
7.217 + pkg, pkgid, ctx->pkgid);
7.218 + } else if (strcmp(name, "file") == 0) {
7.219 + ctx->state = YUM_STATE_FILE;
7.220 + ctx->p = ctx->buffer;
7.221 + }
7.222 +}
7.223 +
7.224 +
7.225 +static void
7.226 +yum_filelists_end_element (void *data, const char *name)
7.227 +{
7.228 + struct yum_context *ctx = data;
7.229 +
7.230 + ctx->state = YUM_STATE_BEGIN;
7.231 + if (strcmp(name, "package") == 0) {
7.232 + XML_StopParser(ctx->current_parser, XML_TRUE);
7.233 + ctx->current_parser = ctx->primary_parser;
7.234 + razor_importer_finish_package(ctx->importer);
7.235 + } else if (strcmp(name, "file") == 0)
7.236 + razor_importer_add_file(ctx->importer, ctx->buffer);
7.237 +
7.238 +}
7.239 +
7.240 +#define XML_BUFFER_SIZE 4096
7.241 +
7.242 +struct razor_set *
7.243 +razor_set_create_from_yum(void)
7.244 +{
7.245 + struct yum_context ctx;
7.246 + void *buf;
7.247 + int len, ret;
7.248 + gzFile primary, filelists;
7.249 + XML_ParsingStatus status;
7.250 +
7.251 + ctx.importer = razor_importer_new();
7.252 + ctx.state = YUM_STATE_BEGIN;
7.253 +
7.254 + ctx.primary_parser = XML_ParserCreate(NULL);
7.255 + XML_SetUserData(ctx.primary_parser, &ctx);
7.256 + XML_SetElementHandler(ctx.primary_parser,
7.257 + yum_primary_start_element,
7.258 + yum_primary_end_element);
7.259 + XML_SetCharacterDataHandler(ctx.primary_parser,
7.260 + yum_character_data);
7.261 +
7.262 + ctx.filelists_parser = XML_ParserCreate(NULL);
7.263 + XML_SetUserData(ctx.filelists_parser, &ctx);
7.264 + XML_SetElementHandler(ctx.filelists_parser,
7.265 + yum_filelists_start_element,
7.266 + yum_filelists_end_element);
7.267 + XML_SetCharacterDataHandler(ctx.filelists_parser,
7.268 + yum_character_data);
7.269 +
7.270 + primary = gzopen("primary.xml.gz", "rb");
7.271 + if (primary == NULL)
7.272 + return NULL;
7.273 + filelists = gzopen("filelists.xml.gz", "rb");
7.274 + if (filelists == NULL)
7.275 + return NULL;
7.276 +
7.277 + ctx.current_parser = ctx.primary_parser;
7.278 +
7.279 + do {
7.280 + XML_GetParsingStatus(ctx.current_parser, &status);
7.281 + switch (status.parsing) {
7.282 + case XML_SUSPENDED:
7.283 + ret = XML_ResumeParser(ctx.current_parser);
7.284 + break;
7.285 + case XML_PARSING:
7.286 + case XML_INITIALIZED:
7.287 + buf = XML_GetBuffer(ctx.current_parser,
7.288 + XML_BUFFER_SIZE);
7.289 + if (ctx.current_parser == ctx.primary_parser)
7.290 + len = gzread(primary, buf, XML_BUFFER_SIZE);
7.291 + else
7.292 + len = gzread(filelists, buf, XML_BUFFER_SIZE);
7.293 + if (len < 0) {
7.294 + fprintf(stderr,
7.295 + "couldn't read input: %s\n",
7.296 + strerror(errno));
7.297 + return NULL;
7.298 + }
7.299 +
7.300 + XML_ParseBuffer(ctx.current_parser, len, len == 0);
7.301 + break;
7.302 + case XML_FINISHED:
7.303 + break;
7.304 + }
7.305 + } while (status.parsing != XML_FINISHED);
7.306 +
7.307 +
7.308 + XML_ParserFree(ctx.primary_parser);
7.309 + XML_ParserFree(ctx.filelists_parser);
7.310 +
7.311 + gzclose(primary);
7.312 + gzclose(filelists);
7.313 +
7.314 + return razor_importer_finish(ctx.importer);
7.315 +}