plover/yumrepository.c
changeset 109 2947214c450e
parent 99 0121592e2512
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/plover/yumrepository.c	Tue Apr 25 17:41:00 2023 +0100
     1.3 @@ -0,0 +1,554 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     1.7 + * Copyright (C) 2008  Red Hat, Inc
     1.8 + * Copyright (C) 2009, 2011, 2014, 2016, 2023 J. Ali Harlow <ali@juiblex.co.uk>
     1.9 + *
    1.10 + * This program is free software; you can redistribute it and/or modify
    1.11 + * it under the terms of the GNU General Public License as published by
    1.12 + * the Free Software Foundation; either version 2 of the License, or
    1.13 + * (at your option) any later version.
    1.14 + *
    1.15 + * This program is distributed in the hope that it will be useful,
    1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.18 + * GNU General Public License for more details.
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License along
    1.21 + * with this program; if not, write to the Free Software Foundation, Inc.,
    1.22 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + */
    1.24 +
    1.25 +#define _GNU_SOURCE
    1.26 +
    1.27 +#include "config.h"
    1.28 +#include <stdlib.h>
    1.29 +#include <string.h>
    1.30 +#include <stdio.h>
    1.31 +#include <stdint.h>
    1.32 +#include <sys/stat.h>
    1.33 +#include <unistd.h>
    1.34 +#include <fcntl.h>
    1.35 +#include <errno.h>
    1.36 +#include <glib.h>
    1.37 +#include <glib-object.h>
    1.38 +#include <expat.h>
    1.39 +#include <zlib.h>
    1.40 +#include <razor.h>
    1.41 +#include <plover/plover.h>
    1.42 +#include <plover/inputstream.h>
    1.43 +#include <plover/yumrepository.h>
    1.44 +#include <plover/uri-handler.h>
    1.45 +
    1.46 +G_DEFINE_TYPE(PloverYumRepository,plover_yum_repository,PLOVER_TYPE_REPOSITORY);
    1.47 +
    1.48 +typedef struct _PloverYumRepositoryPrivate {
    1.49 +    gchar *base_uri;
    1.50 +    struct comps *comps;
    1.51 +} PloverYumRepositoryPrivate;
    1.52 +
    1.53 +#define PLOVER_YUM_REPOSITORY_GET_PRIVATE(obj)\
    1.54 +				G_TYPE_INSTANCE_GET_PRIVATE(obj,\
    1.55 +				  PLOVER_TYPE_YUM_REPOSITORY,\
    1.56 +				  PloverYumRepositoryPrivate)
    1.57 +
    1.58 +enum {
    1.59 +	YUM_STATE_BEGIN,
    1.60 +	YUM_STATE_PACKAGE_NAME,
    1.61 +	YUM_STATE_PACKAGE_ARCH,
    1.62 +	YUM_STATE_SUMMARY,
    1.63 +	YUM_STATE_DESCRIPTION,
    1.64 +	YUM_STATE_URL,
    1.65 +	YUM_STATE_LICENSE,
    1.66 +	YUM_STATE_CHECKSUM,
    1.67 +	YUM_STATE_REQUIRES,
    1.68 +	YUM_STATE_PROVIDES,
    1.69 +	YUM_STATE_OBSOLETES,
    1.70 +	YUM_STATE_CONFLICTS,
    1.71 +	YUM_STATE_SKIPPING_PACKAGE,
    1.72 +	YUM_STATE_FILE
    1.73 +};
    1.74 +
    1.75 +struct yum_context {
    1.76 +	XML_Parser primary_parser;
    1.77 +	XML_Parser filelists_parser;
    1.78 +	XML_Parser current_parser;
    1.79 +
    1.80 +	struct razor_importer *importer;
    1.81 +	struct import_property_context *current_property_context;
    1.82 +	const char *base_uri;
    1.83 +	GTree *uris;
    1.84 +	char name[256], arch[64], summary[512], description[4096];
    1.85 +	char url[256], license[64], buffer[512], *p;
    1.86 +	char pkgid[128], evr[128];
    1.87 +	uint32_t property_type;
    1.88 +	int state;
    1.89 +
    1.90 +	int total, current;
    1.91 +};
    1.92 +
    1.93 +static void plover_yum_repository_finalize(GObject *obj)
    1.94 +{
    1.95 +    PloverYumRepositoryPrivate *priv=PLOVER_YUM_REPOSITORY_GET_PRIVATE(obj);
    1.96 +    plover_comps_free(priv->comps);
    1.97 +    g_free(priv->base_uri);
    1.98 +    if (G_OBJECT_CLASS(plover_yum_repository_parent_class)->finalize)
    1.99 +	G_OBJECT_CLASS(plover_yum_repository_parent_class)->finalize(obj);
   1.100 +}
   1.101 +
   1.102 +static void plover_yum_repository_class_init(PloverYumRepositoryClass *klass)
   1.103 +{
   1.104 +    GObjectClass *oclass=G_OBJECT_CLASS(klass);
   1.105 +    plover__uri_handler_init();
   1.106 +    oclass->finalize=plover_yum_repository_finalize;
   1.107 +    g_type_class_add_private(klass,sizeof(PloverYumRepositoryPrivate));
   1.108 +}
   1.109 +
   1.110 +static void plover_yum_repository_init(PloverYumRepository *repository)
   1.111 +{
   1.112 +}
   1.113 +
   1.114 +static uint32_t
   1.115 +yum_to_razor_relation (const char *flags)
   1.116 +{
   1.117 +	if (flags[0] == 'L') {
   1.118 +		if (flags[1] == 'T')
   1.119 +			return RAZOR_PROPERTY_LESS;
   1.120 +		else
   1.121 +			return RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL;
   1.122 +	} else if (flags[0] == 'G') {
   1.123 +		if (flags[1] == 'T')
   1.124 +			return RAZOR_PROPERTY_GREATER;
   1.125 +		else
   1.126 +			return RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL;
   1.127 +	} else
   1.128 +		return RAZOR_PROPERTY_EQUAL;
   1.129 +}
   1.130 +
   1.131 +static void
   1.132 +yum_primary_start_element(void *data, const char *name, const char **atts)
   1.133 +{
   1.134 +	struct yum_context *ctx = data;
   1.135 +	const char *n, *epoch, *version, *release;
   1.136 +	char buffer[128];
   1.137 +	char *s;
   1.138 +	gchar *nevra;
   1.139 +	uint32_t pre, relation, flags;
   1.140 +	int i;
   1.141 +
   1.142 +	if (ctx->state == YUM_STATE_SKIPPING_PACKAGE)
   1.143 +		return;
   1.144 +
   1.145 +	if (strcmp(name, "metadata") == 0) {
   1.146 +		for (i = 0; atts[i]; i += 2) {
   1.147 +			if (strcmp(atts[i], "packages") == 0)
   1.148 +				ctx->total = atoi(atts[i + 1]);
   1.149 +		}
   1.150 +	} else if (strcmp(name, "package") == 0) {
   1.151 +		*ctx->name=*ctx->arch=*ctx->summary=*ctx->description='\0';
   1.152 +		*ctx->url=*ctx->license='\0';
   1.153 +	} else if (strcmp(name, "name") == 0) {
   1.154 +		ctx->state = YUM_STATE_PACKAGE_NAME;
   1.155 +		ctx->p = ctx->name;
   1.156 +	} else if (strcmp(name, "arch") == 0) {
   1.157 +		ctx->state = YUM_STATE_PACKAGE_ARCH;
   1.158 +		ctx->p = ctx->arch;
   1.159 +	} else if (strcmp(name, "version") == 0) {
   1.160 +		epoch = NULL;
   1.161 +		version = NULL;
   1.162 +		release = NULL;
   1.163 +		for (i = 0; atts[i]; i += 2) {
   1.164 +			if (strcmp(atts[i], "epoch") == 0)
   1.165 +				epoch = atts[i + 1];
   1.166 +			else if (strcmp(atts[i], "ver") == 0)
   1.167 +				version = atts[i + 1];
   1.168 +			else if (strcmp(atts[i], "rel") == 0)
   1.169 +				release = atts[i + 1];
   1.170 +		}
   1.171 +		if (version == NULL || release == NULL) {
   1.172 +			fprintf(stderr, "invalid version tag, "
   1.173 +				"missing version or  release attribute\n");
   1.174 +			return;
   1.175 +		}
   1.176 +
   1.177 +		razor_build_evr(ctx->evr, sizeof ctx->evr, epoch, version,
   1.178 +				release);
   1.179 +		if (!strcmp(ctx->arch, "noarch") ||
   1.180 +		    !strcmp(ctx->arch, razor_system_arch())) {
   1.181 +			razor_importer_begin_package(ctx->importer, ctx->name,
   1.182 +						     ctx->evr, ctx->arch);
   1.183 +		} else
   1.184 +			ctx->state = YUM_STATE_SKIPPING_PACKAGE;
   1.185 +	} else if (strcmp(name, "summary") == 0) {
   1.186 +		ctx->p = ctx->summary;
   1.187 +		ctx->state = YUM_STATE_SUMMARY;
   1.188 +	} else if (strcmp(name, "description") == 0) {
   1.189 +		ctx->p = ctx->description;
   1.190 +		ctx->state = YUM_STATE_DESCRIPTION;
   1.191 +	} else if (strcmp(name, "url") == 0) {
   1.192 +		ctx->p = ctx->url;
   1.193 +		ctx->state = YUM_STATE_URL;
   1.194 +	} else if (strcmp(name, "checksum") == 0) {
   1.195 +		ctx->p = ctx->pkgid;
   1.196 +		ctx->state = YUM_STATE_CHECKSUM;
   1.197 +	} else if (strcmp(name, "location") == 0) {
   1.198 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) {
   1.199 +		    for (i = 0; atts[i]; i += 2)
   1.200 +			if (strcmp(atts[i], "href") == 0) {
   1.201 +			    nevra=g_strconcat(ctx->name,"-",ctx->evr,".",
   1.202 +			      ctx->arch,NULL);
   1.203 +			    s=razor_path_relative_to_uri(ctx->base_uri,
   1.204 +			      atts[i + 1],NULL);
   1.205 +			    g_tree_insert(ctx->uris,nevra,g_strdup(s));
   1.206 +			    free(s);
   1.207 +			    break;
   1.208 +			}
   1.209 +		}
   1.210 +	} else if (strcmp(name, "rpm:license") == 0) {
   1.211 +		ctx->p = ctx->license;
   1.212 +		ctx->state = YUM_STATE_LICENSE;
   1.213 +	} else if (strcmp(name, "rpm:requires") == 0) {
   1.214 +		ctx->state = YUM_STATE_REQUIRES;
   1.215 +		ctx->property_type = RAZOR_PROPERTY_REQUIRES;
   1.216 +	} else if (strcmp(name, "rpm:provides") == 0) {
   1.217 +		ctx->state = YUM_STATE_PROVIDES;
   1.218 +		ctx->property_type = RAZOR_PROPERTY_PROVIDES;
   1.219 +	} else if (strcmp(name, "rpm:obsoletes") == 0) {
   1.220 +		ctx->state = YUM_STATE_OBSOLETES;
   1.221 +		ctx->property_type = RAZOR_PROPERTY_OBSOLETES;
   1.222 +	} else if (strcmp(name, "rpm:conflicts") == 0) {
   1.223 +		ctx->state = YUM_STATE_CONFLICTS;
   1.224 +		ctx->property_type = RAZOR_PROPERTY_CONFLICTS;
   1.225 +	} else if (strcmp(name, "rpm:entry") == 0 &&
   1.226 +		   ctx->state != YUM_STATE_BEGIN) {
   1.227 +		n = NULL;
   1.228 +		epoch = NULL;
   1.229 +		version = NULL;
   1.230 +		release = NULL;
   1.231 +		relation = RAZOR_PROPERTY_EQUAL;
   1.232 +		pre = 0;
   1.233 +		for (i = 0; atts[i]; i += 2) {
   1.234 +			if (strcmp(atts[i], "name") == 0)
   1.235 +				n = atts[i + 1];
   1.236 +			else if (strcmp(atts[i], "epoch") == 0)
   1.237 +				epoch = atts[i + 1];
   1.238 +			else if (strcmp(atts[i], "ver") == 0)
   1.239 +				version = atts[i + 1];
   1.240 +			else if (strcmp(atts[i], "rel") == 0)
   1.241 +				release = atts[i + 1];
   1.242 +			else if (strcmp(atts[i], "flags") == 0)
   1.243 +				relation = yum_to_razor_relation(atts[i + 1]);
   1.244 +			else if (strcmp(atts[i], "pre") == 0)
   1.245 +				pre = RAZOR_PROPERTY_PRE;
   1.246 +		}
   1.247 +
   1.248 +		if (n == NULL) {
   1.249 +			fprintf(stderr, "invalid rpm:entry, "
   1.250 +				"missing name or version attributes\n");
   1.251 +			return;
   1.252 +		}
   1.253 +
   1.254 +		razor_build_evr(buffer, sizeof buffer, epoch, version, release);
   1.255 +		flags = ctx->property_type | relation | pre;
   1.256 +		razor_importer_add_property(ctx->importer, n, flags, buffer);
   1.257 +	}
   1.258 +}
   1.259 +
   1.260 +static void
   1.261 +yum_primary_end_element (void *data, const char *name)
   1.262 +{
   1.263 +	struct yum_context *ctx = data;
   1.264 +
   1.265 +	switch (ctx->state) {
   1.266 +	case YUM_STATE_PACKAGE_NAME:
   1.267 +	case YUM_STATE_PACKAGE_ARCH:
   1.268 +	case YUM_STATE_SUMMARY:
   1.269 +	case YUM_STATE_DESCRIPTION:
   1.270 +	case YUM_STATE_URL:
   1.271 +	case YUM_STATE_LICENSE:
   1.272 +	case YUM_STATE_CHECKSUM:
   1.273 +	case YUM_STATE_FILE:
   1.274 +		ctx->state = YUM_STATE_BEGIN;
   1.275 +		break;
   1.276 +	}
   1.277 +
   1.278 +	if (strcmp(name, "package") == 0) {
   1.279 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
   1.280 +			razor_importer_add_details(ctx->importer, ctx->summary,
   1.281 +						   ctx->description, ctx->url,
   1.282 +						   ctx->license);
   1.283 +
   1.284 +		XML_StopParser(ctx->current_parser, XML_TRUE);
   1.285 +		ctx->current_parser = ctx->filelists_parser;
   1.286 +	}
   1.287 +}
   1.288 +
   1.289 +static void
   1.290 +yum_character_data (void *data, const XML_Char *s, int len)
   1.291 +{
   1.292 +	struct yum_context *ctx = data;
   1.293 +
   1.294 +	switch (ctx->state) {
   1.295 +	case YUM_STATE_PACKAGE_NAME:
   1.296 +	case YUM_STATE_PACKAGE_ARCH:
   1.297 +	case YUM_STATE_SUMMARY:
   1.298 +	case YUM_STATE_DESCRIPTION:
   1.299 +	case YUM_STATE_URL:
   1.300 +	case YUM_STATE_LICENSE:
   1.301 +	case YUM_STATE_CHECKSUM:
   1.302 +	case YUM_STATE_FILE:
   1.303 +		memcpy(ctx->p, s, len);
   1.304 +		ctx->p += len;
   1.305 +		*ctx->p = '\0';
   1.306 +		break;
   1.307 +	}
   1.308 +}
   1.309 +
   1.310 +static void
   1.311 +yum_filelists_start_element(void *data, const char *name, const char **atts)
   1.312 +{
   1.313 +	struct yum_context *ctx = data;
   1.314 +	const char *pkg, *pkgid;
   1.315 +	int i;
   1.316 +
   1.317 +	if (strcmp(name, "package") == 0 &&
   1.318 +	    ctx->state != YUM_STATE_SKIPPING_PACKAGE) {
   1.319 +		pkg = NULL;
   1.320 +		pkgid = NULL;
   1.321 +		for (i = 0; atts[i]; i += 2) {
   1.322 +			if (strcmp(atts[i], "name") == 0)
   1.323 +				pkg = atts[i + 1];
   1.324 +			else if (strcmp(atts[i], "pkgid") == 0)
   1.325 +				pkgid = atts[i + 1];
   1.326 +		}
   1.327 +		if (strcmp(pkgid, ctx->pkgid) != 0)
   1.328 +			fprintf(stderr, "primary.xml and filelists.xml "
   1.329 +				"mismatch for %s: %s vs %s",
   1.330 +				pkg, pkgid, ctx->pkgid);
   1.331 +	} else if (strcmp(name, "file") == 0) {
   1.332 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
   1.333 +			ctx->state = YUM_STATE_FILE;
   1.334 +		ctx->p = ctx->buffer;
   1.335 +	}
   1.336 +}
   1.337 +
   1.338 +static void
   1.339 +yum_filelists_end_element (void *data, const char *name)
   1.340 +{
   1.341 +	struct yum_context *ctx = data;
   1.342 +
   1.343 +	if (strcmp(name, "package") == 0) {
   1.344 +		XML_StopParser(ctx->current_parser, XML_TRUE);
   1.345 +		ctx->current_parser = ctx->primary_parser;
   1.346 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
   1.347 +			razor_importer_finish_package(ctx->importer);
   1.348 +		ctx->state = YUM_STATE_BEGIN;
   1.349 +	} else if (strcmp(name, "file") == 0) {
   1.350 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
   1.351 +			razor_importer_add_file(ctx->importer, ctx->buffer);
   1.352 +	}
   1.353 +	if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
   1.354 +		ctx->state = YUM_STATE_BEGIN;
   1.355 +}
   1.356 +
   1.357 +static int plover_system_arch_is_x86(void)
   1.358 +{
   1.359 +    const char *arch=razor_system_arch();
   1.360 +    if (!arch || arch[0]!='i' || arch[1]<'3' || arch[1]>'6')
   1.361 +	return 0;
   1.362 +    else
   1.363 +	return !strcmp(arch+2,"86");
   1.364 +}
   1.365 +
   1.366 +#define XML_BUFFER_SIZE 4096
   1.367 +
   1.368 +PloverYumRepository *plover_yum_repository_new_from_uri(const char *base_uri,
   1.369 +  GError **error)
   1.370 +{
   1.371 +    struct yum_context ctx;
   1.372 +    gchar *s,**rpm_uris;
   1.373 +    GPtrArray *uris;
   1.374 +    char *uri;
   1.375 +    const char *name,*version,*arch;
   1.376 +    void *buf;
   1.377 +    gssize len;
   1.378 +    GInputStream *stream;
   1.379 +    GInputStream *primary,*filelists;
   1.380 +    GZlibDecompressor *decompressor;
   1.381 +    XML_ParsingStatus status;
   1.382 +    struct razor_set *razor;
   1.383 +    struct razor_package_iterator *iter;
   1.384 +    struct razor_package *pkg;
   1.385 +    PloverPackageSet *set;
   1.386 +    PloverYumRepository *repository;
   1.387 +    PloverYumRepositoryPrivate *priv;
   1.388 +    g_return_val_if_fail(plover__uri_validate(base_uri),NULL);
   1.389 +    ctx.importer=razor_importer_create();
   1.390 +    ctx.state=YUM_STATE_BEGIN;
   1.391 +    ctx.base_uri=base_uri;
   1.392 +    ctx.primary_parser=XML_ParserCreate(NULL);
   1.393 +    XML_SetUserData(ctx.primary_parser,&ctx);
   1.394 +    XML_SetElementHandler(ctx.primary_parser,yum_primary_start_element,
   1.395 +      yum_primary_end_element);
   1.396 +    XML_SetCharacterDataHandler(ctx.primary_parser,yum_character_data);
   1.397 +    ctx.filelists_parser=XML_ParserCreate(NULL);
   1.398 +    XML_SetUserData(ctx.filelists_parser,&ctx);
   1.399 +    XML_SetElementHandler(ctx.filelists_parser,yum_filelists_start_element,
   1.400 +      yum_filelists_end_element);
   1.401 +    XML_SetCharacterDataHandler(ctx.filelists_parser,yum_character_data);
   1.402 +    uri=razor_path_relative_to_uri(base_uri,"repodata/primary.xml.gz",NULL);
   1.403 +    stream=plover_razor_input_stream_new(uri,error);
   1.404 +    free(uri);
   1.405 +    if (!stream) {
   1.406 +	XML_ParserFree(ctx.primary_parser);
   1.407 +	XML_ParserFree(ctx.filelists_parser);
   1.408 +	return NULL;
   1.409 +    }
   1.410 +    decompressor=g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP);
   1.411 +    primary=g_converter_input_stream_new(G_INPUT_STREAM(stream),
   1.412 +      G_CONVERTER(decompressor));
   1.413 +    g_object_unref(stream);
   1.414 +    g_object_unref(decompressor);
   1.415 +    uri=razor_path_relative_to_uri(base_uri,"repodata/filelists.xml.gz",NULL);
   1.416 +    stream=plover_razor_input_stream_new(uri,error);
   1.417 +    free(uri);
   1.418 +    if (!stream) {
   1.419 +	g_object_unref(primary);
   1.420 +	XML_ParserFree(ctx.primary_parser);
   1.421 +	XML_ParserFree(ctx.filelists_parser);
   1.422 +	return NULL;
   1.423 +    }
   1.424 +    decompressor=g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP);
   1.425 +    filelists=g_converter_input_stream_new(G_INPUT_STREAM(stream),
   1.426 +      G_CONVERTER(decompressor));
   1.427 +    g_object_unref(stream);
   1.428 +    g_object_unref(decompressor);
   1.429 +    ctx.current_parser=ctx.primary_parser;
   1.430 +    ctx.uris=g_tree_new_full((GCompareDataFunc)strcmp,NULL,g_free,NULL);
   1.431 +    ctx.current=0;
   1.432 +    do
   1.433 +    {
   1.434 +	XML_GetParsingStatus(ctx.current_parser,&status);
   1.435 +	switch (status.parsing)
   1.436 +	{
   1.437 +	    case XML_SUSPENDED:
   1.438 +		XML_ResumeParser(ctx.current_parser);
   1.439 +		break;
   1.440 +	    case XML_PARSING:
   1.441 +	    case XML_INITIALIZED:
   1.442 +		buf=XML_GetBuffer(ctx.current_parser,XML_BUFFER_SIZE);
   1.443 +		if (ctx.current_parser==ctx.primary_parser)
   1.444 +		    len=g_input_stream_read(G_INPUT_STREAM(primary),buf,
   1.445 +		      XML_BUFFER_SIZE,NULL,error);
   1.446 +		else
   1.447 +		    len=g_input_stream_read(G_INPUT_STREAM(filelists),buf,
   1.448 +		      XML_BUFFER_SIZE,NULL,error);
   1.449 +		if (len<0)
   1.450 +		    return NULL;
   1.451 +		XML_ParseBuffer(ctx.current_parser,len,!len);
   1.452 +		break;
   1.453 +	    case XML_FINISHED:
   1.454 +		break;
   1.455 +	}
   1.456 +    } while (status.parsing!=XML_FINISHED);
   1.457 +    XML_ParserFree(ctx.primary_parser);
   1.458 +    XML_ParserFree(ctx.filelists_parser);
   1.459 +    g_object_unref(primary);
   1.460 +    g_object_unref(filelists);
   1.461 +    razor=razor_importer_finish(ctx.importer);
   1.462 +#if RAZOR_HEADER_VERSION_MIN<=1
   1.463 +    /*
   1.464 +     * Header version 1 is supported by plover v0.3 and is used on
   1.465 +     * 32-bit intel machines which allows the setup and update
   1.466 +     * applications from v0.3 to work. On other machines, we don't
   1.467 +     * want these old applications to work (since they would do
   1.468 +     * the wrong thing) and so we use the current header version
   1.469 +     * which they don't support.
   1.470 +     */
   1.471 +    if (plover_system_arch_is_x86())
   1.472 +	razor_set_set_header_version(razor,1);
   1.473 +#endif
   1.474 +    uris=g_ptr_array_new();
   1.475 +    iter=razor_package_iterator_create(razor);
   1.476 +    while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_NAME,&name,
   1.477 +      RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,RAZOR_DETAIL_LAST))
   1.478 +    {
   1.479 +	s=g_strconcat(name,"-",version,".",arch,NULL);
   1.480 +	g_ptr_array_add(uris,g_tree_lookup(ctx.uris,s));
   1.481 +	g_free(s);
   1.482 +    }
   1.483 +    razor_package_iterator_destroy(iter);
   1.484 +    g_ptr_array_add(uris,NULL);
   1.485 +    g_tree_unref(ctx.uris);
   1.486 +    rpm_uris=(gchar **)g_ptr_array_free(uris,FALSE);
   1.487 +    set=plover_package_set_new_from_razor(razor);
   1.488 +    razor_set_unref(razor);
   1.489 +    repository=g_object_new(PLOVER_TYPE_YUM_REPOSITORY,"package-set",set,
   1.490 +      "rpm-uris",rpm_uris,NULL);
   1.491 +    g_object_unref(set);
   1.492 +    g_strfreev(rpm_uris);
   1.493 +    priv=PLOVER_YUM_REPOSITORY_GET_PRIVATE(repository);
   1.494 +    priv->base_uri=g_strdup(base_uri);
   1.495 +    return repository;
   1.496 +}
   1.497 +
   1.498 +PloverYumRepository *plover_yum_repository_new_from_path(const char *base,
   1.499 +  GError **error)
   1.500 +{
   1.501 +    PloverYumRepository *repository;
   1.502 +    gchar *base_uri;
   1.503 +    GFile *file;
   1.504 +    file=g_file_new_for_path(base);
   1.505 +    base_uri=g_file_get_uri(file);
   1.506 +    g_object_unref(file);
   1.507 +    repository=plover_yum_repository_new_from_uri(base_uri,error);
   1.508 +    g_free(base_uri);
   1.509 +    return repository;
   1.510 +}
   1.511 +
   1.512 +/* Compatibility function: Depreciated in favour of
   1.513 + * plover_yum_repository_new_from_uri()
   1.514 + */
   1.515 +
   1.516 +PloverRepository *plover_repository_new_from_yum_uri(const char *base_uri,
   1.517 +  GError **error)
   1.518 +{
   1.519 +    PloverYumRepository *repository;
   1.520 +    repository=plover_yum_repository_new_from_uri(base_uri,error);
   1.521 +    return repository?PLOVER_REPOSITORY(repository):NULL;
   1.522 +}
   1.523 +
   1.524 +/* Compatibility function: Depreciated in favour of
   1.525 + * plover_yum_repository_new_from_path()
   1.526 + */
   1.527 +
   1.528 +PloverRepository *plover_repository_new_from_yum(const char *base,
   1.529 +  GError **error)
   1.530 +{
   1.531 +    PloverYumRepository *repository;
   1.532 +    repository=plover_yum_repository_new_from_path(base,error);
   1.533 +    return repository?PLOVER_REPOSITORY(repository):NULL;
   1.534 +}
   1.535 +
   1.536 +struct comps *plover_yum_repository_get_comps(PloverYumRepository *repository,
   1.537 +  GError **error)
   1.538 +{
   1.539 +    gchar *uri;
   1.540 +    PloverYumRepositoryPrivate *priv;
   1.541 +    g_return_val_if_fail(PLOVER_IS_YUM_REPOSITORY(repository),NULL);
   1.542 +    priv=PLOVER_YUM_REPOSITORY_GET_PRIVATE(repository);
   1.543 +    if (!priv->base_uri)
   1.544 +    {
   1.545 +	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
   1.546 +	  "No base URI set");
   1.547 +	return NULL;
   1.548 +    }
   1.549 +    if (!priv->comps)
   1.550 +    {
   1.551 +	uri=razor_path_relative_to_uri(priv->base_uri,"repodata/comps.xml",
   1.552 +	  NULL);
   1.553 +	priv->comps=plover_comps_new_from_uri(uri,error);
   1.554 +	free(uri);
   1.555 +    }
   1.556 +    return priv->comps;
   1.557 +}