import.c
changeset 73 0ff316e24339
parent 68 0587f1759f09
child 76 773e6a26707f
     1.1 --- a/import.c	Sun Nov 04 00:58:25 2007 -0400
     1.2 +++ b/import.c	Mon Nov 05 22:54:33 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  }