1.1 --- a/import.c Sun Nov 04 00:58:25 2007 -0400
1.2 +++ b/import.c Mon Nov 05 19:06:52 2007 -0500
1.3 @@ -9,6 +9,7 @@
1.4 #include <errno.h>
1.5
1.6 #include <expat.h>
1.7 +#include <zlib.h>
1.8 #include <rpm/rpmlib.h>
1.9 #include <rpm/rpmdb.h>
1.10 #include "sha1.h"
1.11 @@ -157,6 +158,7 @@
1.12 enum {
1.13 YUM_STATE_BEGIN,
1.14 YUM_STATE_PACKAGE_NAME,
1.15 + YUM_STATE_CHECKSUM,
1.16 YUM_STATE_REQUIRES,
1.17 YUM_STATE_PROVIDES,
1.18 YUM_STATE_OBSOLETES,
1.19 @@ -165,14 +167,19 @@
1.20 };
1.21
1.22 struct yum_context {
1.23 + XML_Parser primary_parser;
1.24 + XML_Parser filelists_parser;
1.25 + XML_Parser current_parser;
1.26 +
1.27 struct razor_importer *importer;
1.28 struct import_property_context *current_property_context;
1.29 char name[256], buffer[512], *p;
1.30 + char pkgid[128];
1.31 int state;
1.32 };
1.33
1.34 static void
1.35 -yum_start_element(void *data, const char *name, const char **atts)
1.36 +yum_primary_start_element(void *data, const char *name, const char **atts)
1.37 {
1.38 struct yum_context *ctx = data;
1.39 const char *n, *version, *release;
1.40 @@ -199,6 +206,9 @@
1.41
1.42 snprintf(buffer, sizeof buffer, "%s-%s", version, release);
1.43 razor_importer_begin_package(ctx->importer, ctx->name, buffer);
1.44 + } else if (strcmp(name, "checksum") == 0) {
1.45 + ctx->p = ctx->pkgid;
1.46 + ctx->state = YUM_STATE_CHECKSUM;
1.47 } else if (strcmp(name, "rpm:requires") == 0) {
1.48 ctx->state = YUM_STATE_REQUIRES;
1.49 } else if (strcmp(name, "rpm:provides") == 0) {
1.50 @@ -253,28 +263,26 @@
1.51 RAZOR_PROPERTY_CONFLICTS);
1.52 break;
1.53 }
1.54 - } else if (strcmp(name, "file") == 0) {
1.55 - ctx->state = YUM_STATE_FILE;
1.56 - ctx->p = ctx->buffer;
1.57 }
1.58 }
1.59
1.60 static void
1.61 -yum_end_element (void *data, const char *name)
1.62 +yum_primary_end_element (void *data, const char *name)
1.63 {
1.64 struct yum_context *ctx = data;
1.65
1.66 switch (ctx->state) {
1.67 case YUM_STATE_PACKAGE_NAME:
1.68 + case YUM_STATE_CHECKSUM:
1.69 case YUM_STATE_FILE:
1.70 ctx->state = YUM_STATE_BEGIN;
1.71 break;
1.72 }
1.73
1.74 - if (strcmp(name, "package") == 0)
1.75 - razor_importer_finish_package(ctx->importer);
1.76 - else if (strcmp(name, "file") == 0)
1.77 - razor_importer_add_file(ctx->importer, ctx->buffer);
1.78 + if (strcmp(name, "package") == 0) {
1.79 + XML_StopParser(ctx->current_parser, XML_TRUE);
1.80 + ctx->current_parser = ctx->filelists_parser;
1.81 + }
1.82 }
1.83
1.84 static void
1.85 @@ -284,6 +292,7 @@
1.86
1.87 switch (ctx->state) {
1.88 case YUM_STATE_PACKAGE_NAME:
1.89 + case YUM_STATE_CHECKSUM:
1.90 case YUM_STATE_FILE:
1.91 memcpy(ctx->p, s, len);
1.92 ctx->p += len;
1.93 @@ -292,41 +301,121 @@
1.94 }
1.95 }
1.96
1.97 +static void
1.98 +yum_filelists_start_element(void *data, const char *name, const char **atts)
1.99 +{
1.100 + struct yum_context *ctx = data;
1.101 + const char *pkg, *pkgid;
1.102 + int i;
1.103 +
1.104 + if (strcmp(name, "package") == 0) {
1.105 + pkg = NULL;
1.106 + pkgid = NULL;
1.107 + for (i = 0; atts[i]; i += 2) {
1.108 + if (strcmp(atts[i], "name") == 0)
1.109 + pkg = atts[i + 1];
1.110 + else if (strcmp(atts[i], "pkgid") == 0)
1.111 + pkgid = atts[i + 1];
1.112 + }
1.113 + if (strcmp(pkgid, ctx->pkgid) != 0)
1.114 + fprintf(stderr, "primary.xml and filelists.xml "
1.115 + "mismatch for %s: %s vs %s",
1.116 + pkg, pkgid, ctx->pkgid);
1.117 + } else if (strcmp(name, "file") == 0) {
1.118 + ctx->state = YUM_STATE_FILE;
1.119 + ctx->p = ctx->buffer;
1.120 + }
1.121 +}
1.122 +
1.123 +
1.124 +static void
1.125 +yum_filelists_end_element (void *data, const char *name)
1.126 +{
1.127 + struct yum_context *ctx = data;
1.128 +
1.129 + ctx->state = YUM_STATE_BEGIN;
1.130 + if (strcmp(name, "package") == 0) {
1.131 + XML_StopParser(ctx->current_parser, XML_TRUE);
1.132 + ctx->current_parser = ctx->primary_parser;
1.133 + razor_importer_finish_package(ctx->importer);
1.134 + } else if (strcmp(name, "file") == 0)
1.135 + razor_importer_add_file(ctx->importer, ctx->buffer);
1.136 +
1.137 +}
1.138 +
1.139 +#define XML_BUFFER_SIZE 4096
1.140 +
1.141 struct razor_set *
1.142 -razor_set_create_from_yum_filelist(int fd)
1.143 +razor_set_create_from_yum(void)
1.144 {
1.145 struct yum_context ctx;
1.146 - XML_Parser parser;
1.147 - char buf[4096];
1.148 - int len;
1.149 + void *buf;
1.150 + int len, ret;
1.151 + gzFile primary, filelists;
1.152 + XML_ParsingStatus status;
1.153
1.154 ctx.importer = razor_importer_new();
1.155 ctx.state = YUM_STATE_BEGIN;
1.156
1.157 - parser = XML_ParserCreate(NULL);
1.158 - XML_SetUserData(parser, &ctx);
1.159 - XML_SetElementHandler(parser, yum_start_element, yum_end_element);
1.160 - XML_SetCharacterDataHandler(parser, yum_character_data);
1.161 + ctx.primary_parser = XML_ParserCreate(NULL);
1.162 + XML_SetUserData(ctx.primary_parser, &ctx);
1.163 + XML_SetElementHandler(ctx.primary_parser,
1.164 + yum_primary_start_element,
1.165 + yum_primary_end_element);
1.166 + XML_SetCharacterDataHandler(ctx.primary_parser,
1.167 + yum_character_data);
1.168
1.169 - while (1) {
1.170 - len = read(fd, buf, sizeof buf);
1.171 - if (len < 0) {
1.172 - fprintf(stderr,
1.173 - "couldn't read input: %s\n", strerror(errno));
1.174 - return NULL;
1.175 - } else if (len == 0)
1.176 + ctx.filelists_parser = XML_ParserCreate(NULL);
1.177 + XML_SetUserData(ctx.filelists_parser, &ctx);
1.178 + XML_SetElementHandler(ctx.filelists_parser,
1.179 + yum_filelists_start_element,
1.180 + yum_filelists_end_element);
1.181 + XML_SetCharacterDataHandler(ctx.filelists_parser,
1.182 + yum_character_data);
1.183 +
1.184 + primary = gzopen("primary.xml.gz", "rb");
1.185 + if (primary == NULL)
1.186 + return NULL;
1.187 + filelists = gzopen("filelists.xml.gz", "rb");
1.188 + if (filelists == NULL)
1.189 + return NULL;
1.190 +
1.191 + ctx.current_parser = ctx.primary_parser;
1.192 +
1.193 + do {
1.194 + XML_GetParsingStatus(ctx.current_parser, &status);
1.195 + switch (status.parsing) {
1.196 + case XML_SUSPENDED:
1.197 + ret = XML_ResumeParser(ctx.current_parser);
1.198 break;
1.199 + case XML_PARSING:
1.200 + case XML_INITIALIZED:
1.201 + buf = XML_GetBuffer(ctx.current_parser,
1.202 + XML_BUFFER_SIZE);
1.203 + if (ctx.current_parser == ctx.primary_parser)
1.204 + len = gzread(primary, buf, XML_BUFFER_SIZE);
1.205 + else
1.206 + len = gzread(filelists, buf, XML_BUFFER_SIZE);
1.207 + if (len < 0) {
1.208 + fprintf(stderr,
1.209 + "couldn't read input: %s\n",
1.210 + strerror(errno));
1.211 + return NULL;
1.212 + }
1.213
1.214 - if (XML_Parse(parser, buf, len, 0) == XML_STATUS_ERROR) {
1.215 - fprintf(stderr,
1.216 - "%s at line %ld\n",
1.217 - XML_ErrorString(XML_GetErrorCode(parser)),
1.218 - XML_GetCurrentLineNumber(parser));
1.219 - return NULL;
1.220 + XML_ParseBuffer(ctx.current_parser, len, len == 0);
1.221 + break;
1.222 + case XML_FINISHED:
1.223 + break;
1.224 }
1.225 - }
1.226 + } while (status.parsing != XML_FINISHED);
1.227
1.228 - XML_ParserFree(parser);
1.229 +
1.230 + XML_ParserFree(ctx.primary_parser);
1.231 + XML_ParserFree(ctx.filelists_parser);
1.232 +
1.233 + gzclose(primary);
1.234 + gzclose(filelists);
1.235
1.236 return razor_importer_finish(ctx.importer);
1.237 }