librazor/transaction.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Aug 23 11:13:48 2014 +0100 (2014-08-23)
changeset 440 48204dea0b9f
parent 432 2d8fecb8f024
child 442 c4bcba8023a9
permissions -rw-r--r--
Remove INTLLIBS from librazor_la_LIBADD.

This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
krh@248
     1
/*
krh@248
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
krh@248
     3
 * Copyright (C) 2008  Red Hat, Inc
ali@432
     4
 * Copyright (C) 2009, 2011, 2012  J. Ali Harlow <ali@juiblex.co.uk>
krh@248
     5
 *
krh@248
     6
 * This program is free software; you can redistribute it and/or modify
krh@248
     7
 * it under the terms of the GNU General Public License as published by
krh@248
     8
 * the Free Software Foundation; either version 2 of the License, or
krh@248
     9
 * (at your option) any later version.
krh@248
    10
 *
krh@248
    11
 * This program is distributed in the hope that it will be useful,
krh@248
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
krh@248
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
krh@248
    14
 * GNU General Public License for more details.
krh@248
    15
 *
krh@248
    16
 * You should have received a copy of the GNU General Public License along
krh@248
    17
 * with this program; if not, write to the Free Software Foundation, Inc.,
krh@248
    18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
krh@248
    19
 */
krh@248
    20
krh@248
    21
#define _GNU_SOURCE
krh@248
    22
ali@438
    23
#include "config.h"
krh@248
    24
#include <stdlib.h>
krh@248
    25
#include <stddef.h>
krh@248
    26
#include <stdint.h>
krh@248
    27
#include <stdio.h>
krh@248
    28
#include <string.h>
krh@248
    29
#include <sys/types.h>
krh@248
    30
#include <sys/stat.h>
krh@248
    31
#include <unistd.h>
krh@248
    32
#include <fcntl.h>
krh@248
    33
#include <errno.h>
krh@248
    34
#include <ctype.h>
richard@301
    35
#include <assert.h>
krh@248
    36
krh@248
    37
#include "razor-internal.h"
krh@248
    38
#include "razor.h"
krh@248
    39
krh@248
    40
static int
krh@248
    41
provider_satisfies_requirement(struct razor_property *provider,
krh@248
    42
			       const char *provider_strings,
krh@248
    43
			       uint32_t flags,
krh@248
    44
			       const char *required)
krh@248
    45
{
krh@248
    46
	int cmp, len;
krh@248
    47
	const char *provided = &provider_strings[provider->version];
krh@248
    48
krh@248
    49
	if (!*required)
krh@248
    50
		return 1;
krh@248
    51
	if (!*provided) {
krh@248
    52
		if (flags & RAZOR_PROPERTY_LESS)
krh@248
    53
			return 0;
krh@248
    54
		else
krh@248
    55
			return 1;
krh@248
    56
	}
krh@248
    57
krh@248
    58
	cmp = razor_versioncmp(provided, required);
krh@248
    59
krh@248
    60
	switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
krh@248
    61
	case RAZOR_PROPERTY_LESS:
krh@248
    62
		return cmp < 0;
krh@248
    63
krh@248
    64
	case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
krh@248
    65
		if (cmp <= 0)
krh@248
    66
			return 1;
krh@248
    67
		/* fall through: FIXME, make sure this is correct */
krh@248
    68
krh@248
    69
	case RAZOR_PROPERTY_EQUAL:
krh@248
    70
		if (cmp == 0)
krh@248
    71
			return 1;
krh@248
    72
krh@248
    73
		/* "foo == 1.1" is satisfied by "foo 1.1-2" */
krh@248
    74
		len = strlen(required);
krh@248
    75
		if (!strncmp(required, provided, len) && provided[len] == '-')
krh@248
    76
			return 1;
krh@248
    77
		return 0;
krh@248
    78
krh@248
    79
	case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
krh@248
    80
		return cmp >= 0;
krh@248
    81
krh@248
    82
	case RAZOR_PROPERTY_GREATER:
krh@248
    83
		return cmp > 0;
krh@248
    84
	}
krh@248
    85
krh@248
    86
	/* shouldn't happen */
krh@248
    87
	return 0;
krh@248
    88
}
krh@248
    89
krh@248
    90
#define TRANS_PACKAGE_PRESENT		1
krh@248
    91
#define TRANS_PACKAGE_UPDATE		2
krh@248
    92
#define TRANS_PROPERTY_SATISFIED	0x80000000
krh@248
    93
krh@248
    94
struct transaction_set {
krh@248
    95
	struct razor_set *set;
krh@248
    96
	uint32_t *packages;
krh@248
    97
	uint32_t *properties;
krh@248
    98
};
krh@248
    99
krh@248
   100
struct razor_transaction {
krh@248
   101
	int package_count, errors;
krh@248
   102
	struct transaction_set system, upstream;
krh@248
   103
	int changes;
ali@369
   104
	struct razor_merger *merger;
krh@248
   105
};
krh@248
   106
krh@248
   107
static void
krh@248
   108
transaction_set_init(struct transaction_set *ts, struct razor_set *set)
krh@248
   109
{
krh@248
   110
	int count;
krh@248
   111
ali@403
   112
	ts->set = razor_set_ref(set);
krh@248
   113
	count = set->packages.size / sizeof (struct razor_package);
krh@248
   114
	ts->packages = zalloc(count * sizeof *ts->packages);
krh@248
   115
	count = set->properties.size / sizeof (struct razor_property);
krh@248
   116
	ts->properties = zalloc(count * sizeof *ts->properties);
krh@248
   117
}
krh@248
   118
krh@248
   119
static void
krh@248
   120
transaction_set_release(struct transaction_set *ts)
krh@248
   121
{
ali@403
   122
	razor_set_unref(ts->set);
krh@248
   123
	free(ts->packages);
krh@248
   124
	free(ts->properties);
krh@248
   125
}
krh@248
   126
krh@248
   127
static void
krh@248
   128
transaction_set_install_package(struct transaction_set *ts,
krh@248
   129
				struct razor_package *package)
krh@248
   130
{
krh@248
   131
	struct razor_package *pkgs;
krh@248
   132
	struct list *prop;
krh@248
   133
	int i;
krh@248
   134
krh@248
   135
	pkgs = ts->set->packages.data;
krh@248
   136
	i = package - pkgs;
ali@432
   137
	if (ts->packages[i] & TRANS_PACKAGE_PRESENT)
krh@248
   138
		return;
krh@248
   139
ali@432
   140
	ts->packages[i] |= TRANS_PACKAGE_PRESENT;
krh@248
   141
krh@248
   142
	prop = list_first(&package->properties, &ts->set->property_pool);
krh@248
   143
	while (prop) {
krh@248
   144
		ts->properties[prop->data]++;
krh@248
   145
		prop = list_next(prop);
krh@248
   146
	}
krh@248
   147
}
krh@248
   148
krh@248
   149
static void
krh@248
   150
transaction_set_remove_package(struct transaction_set *ts,
krh@248
   151
			       struct razor_package *package)
krh@248
   152
{
krh@248
   153
	struct razor_package *pkgs;
krh@248
   154
	struct list *prop;
krh@248
   155
	int i;
krh@248
   156
krh@248
   157
	pkgs = ts->set->packages.data;
krh@248
   158
	i = package - pkgs;
ali@432
   159
	if (!(ts->packages[i] & TRANS_PACKAGE_PRESENT))
krh@248
   160
		return;
krh@248
   161
ali@432
   162
	ts->packages[i] &= ~TRANS_PACKAGE_PRESENT;
krh@248
   163
krh@248
   164
	prop = list_first(&package->properties, &ts->set->property_pool);
krh@248
   165
	while (prop) {
krh@248
   166
		ts->properties[prop->data]--;
krh@248
   167
		prop = list_next(prop);
krh@248
   168
	}
krh@248
   169
}
krh@248
   170
krh@269
   171
RAZOR_EXPORT struct razor_transaction *
krh@248
   172
razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
krh@248
   173
{
krh@248
   174
	struct razor_transaction *trans;
krh@248
   175
	struct razor_package *p, *spkgs, *pend;
krh@248
   176
krh@248
   177
	trans = zalloc(sizeof *trans);
krh@248
   178
	transaction_set_init(&trans->system, system);
krh@248
   179
	transaction_set_init(&trans->upstream, upstream);
krh@248
   180
krh@248
   181
	spkgs = trans->system.set->packages.data;
krh@248
   182
	pend = trans->system.set->packages.data +
krh@248
   183
		trans->system.set->packages.size;
krh@248
   184
	for (p = spkgs; p < pend; p++)
krh@248
   185
		transaction_set_install_package(&trans->system, p);
krh@248
   186
krh@248
   187
	return trans;
krh@248
   188
}
krh@248
   189
krh@269
   190
RAZOR_EXPORT void
krh@248
   191
razor_transaction_install_package(struct razor_transaction *trans,
krh@248
   192
				  struct razor_package *package)
krh@248
   193
{
richard@301
   194
	assert (trans != NULL);
richard@301
   195
	assert (package != NULL);
richard@301
   196
krh@248
   197
	transaction_set_install_package(&trans->upstream, package);
krh@248
   198
	trans->changes++;
krh@248
   199
}
krh@248
   200
krh@269
   201
RAZOR_EXPORT void
krh@248
   202
razor_transaction_remove_package(struct razor_transaction *trans,
krh@248
   203
				 struct razor_package *package)
krh@248
   204
{
richard@301
   205
	assert (trans != NULL);
richard@301
   206
	assert (package != NULL);
richard@301
   207
krh@248
   208
	transaction_set_remove_package(&trans->system, package);
krh@248
   209
	trans->changes++;
krh@248
   210
}
krh@248
   211
krh@269
   212
RAZOR_EXPORT void
krh@248
   213
razor_transaction_update_package(struct razor_transaction *trans,
krh@248
   214
				  struct razor_package *package)
krh@248
   215
{
krh@248
   216
	struct razor_package *spkgs, *upkgs, *end;
krh@248
   217
richard@301
   218
	assert (trans != NULL);
richard@301
   219
	assert (package != NULL);
richard@301
   220
krh@248
   221
	spkgs = trans->system.set->packages.data;
krh@248
   222
	upkgs = trans->upstream.set->packages.data;
krh@248
   223
	end = trans->system.set->packages.data +
krh@248
   224
		trans->system.set->packages.size;
krh@248
   225
	if (spkgs <= package && package < end)
krh@248
   226
		trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
krh@248
   227
	else
krh@248
   228
		trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
krh@248
   229
}
krh@248
   230
krh@248
   231
struct prop_iter {
krh@248
   232
	struct razor_property *p, *start, *end;
krh@248
   233
	const char *pool;
krh@248
   234
	uint32_t *present;
krh@248
   235
};
krh@248
   236
krh@248
   237
static void
krh@248
   238
prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
krh@248
   239
{
krh@248
   240
	pi->p = ts->set->properties.data;
krh@248
   241
	pi->start = ts->set->properties.data;
krh@248
   242
	pi->end = ts->set->properties.data + ts->set->properties.size;
krh@248
   243
	pi->pool = ts->set->string_pool.data;
krh@248
   244
	pi->present = ts->properties;
krh@248
   245
}
krh@248
   246
krh@248
   247
static int
krh@248
   248
prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
krh@248
   249
{
krh@248
   250
	while (pi->p < pi->end) {
krh@248
   251
		if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
krh@248
   252
		    (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
krh@248
   253
			*p = pi->p++;
krh@248
   254
			return 1;
krh@248
   255
		}
krh@248
   256
		pi->p++;
krh@248
   257
	}
krh@248
   258
krh@248
   259
	return 0;
krh@248
   260
}
krh@248
   261
krh@248
   262
static struct razor_property *
krh@248
   263
prop_iter_seek_to(struct prop_iter *pi,
krh@248
   264
		  uint32_t flags, const char *match)
krh@248
   265
{
krh@248
   266
	uint32_t name;
krh@248
   267
krh@248
   268
	while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
krh@248
   269
		pi->p++;
krh@248
   270
krh@248
   271
	if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
krh@248
   272
		return NULL;
krh@248
   273
krh@248
   274
	name = pi->p->name;
krh@248
   275
	while (pi->p < pi->end &&
krh@248
   276
	       pi->p->name == name &&
krh@248
   277
	       (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
krh@248
   278
		pi->p++;
krh@248
   279
krh@248
   280
	if (pi->p == pi->end || pi->p->name != name)
krh@248
   281
		return NULL;
krh@248
   282
krh@248
   283
	return pi->p;
krh@248
   284
}
krh@248
   285
krh@248
   286
/* Remove packages from set that provide any of the matching (same
krh@248
   287
 * name and type) providers from ppi onwards that match the
krh@248
   288
 * requirement that rpi points to. */
krh@248
   289
static void
krh@248
   290
remove_matching_providers(struct razor_transaction *trans,
krh@248
   291
			  struct prop_iter *ppi,
krh@248
   292
			  uint32_t flags,
krh@248
   293
			  const char *version)
krh@248
   294
{
krh@248
   295
	struct razor_property *p;
krh@248
   296
	struct razor_package *pkg, *pkgs;
krh@248
   297
	struct razor_package_iterator pkg_iter;
krh@248
   298
	struct razor_set *set;
richard@302
   299
	const char *n, *v;
krh@248
   300
	uint32_t type;
krh@248
   301
krh@248
   302
	if (ppi->present == trans->system.properties)
krh@248
   303
		set = trans->system.set;
krh@248
   304
	else
krh@248
   305
		set = trans->upstream.set;
krh@248
   306
krh@248
   307
	pkgs = (struct razor_package *) set->packages.data;
krh@248
   308
	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
krh@248
   309
	for (p = ppi->p;
krh@248
   310
	     p < ppi->end &&
krh@248
   311
	     p->name == ppi->p->name &&
krh@248
   312
	     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
krh@248
   313
	     p++) {
krh@248
   314
		if (!ppi->present[p - ppi->start])
krh@248
   315
			continue;
krh@248
   316
		if (!provider_satisfies_requirement(p, ppi->pool,
krh@248
   317
						    flags, version))
krh@248
   318
			continue;
krh@248
   319
krh@248
   320
		razor_package_iterator_init_for_property(&pkg_iter, set, p);
richard@302
   321
		while (razor_package_iterator_next(&pkg_iter, &pkg,
richard@302
   322
						   RAZOR_DETAIL_NAME, &n,
richard@307
   323
						   RAZOR_DETAIL_VERSION, &v,
richard@307
   324
						   RAZOR_DETAIL_LAST)) {
ali@403
   325
#if 0
krh@248
   326
			fprintf(stderr, "removing %s-%s\n", n, v);
ali@403
   327
#endif
krh@248
   328
			razor_transaction_remove_package(trans, pkg);
krh@248
   329
		}
krh@248
   330
	}
krh@248
   331
}
krh@248
   332
krh@248
   333
static void
krh@248
   334
flag_matching_providers(struct razor_transaction *trans,
krh@248
   335
			struct prop_iter *ppi,
krh@248
   336
			struct razor_property *r,
krh@248
   337
			struct prop_iter *rpi,
krh@248
   338
			unsigned int flag)
krh@248
   339
{
krh@248
   340
	struct razor_property *p;
krh@248
   341
	struct razor_package *pkg, *pkgs;
krh@248
   342
	struct razor_package_iterator pkg_iter;
krh@248
   343
	struct razor_set *set;
richard@302
   344
	const char *name, *version;
krh@248
   345
	uint32_t *flags, type;
krh@248
   346
krh@248
   347
	if (ppi->present == trans->system.properties) {
krh@248
   348
		set = trans->system.set;
krh@248
   349
		flags = trans->system.packages;
krh@248
   350
	} else {
krh@248
   351
		set = trans->upstream.set;
krh@248
   352
		flags = trans->upstream.packages;
krh@248
   353
	}
krh@248
   354
krh@248
   355
	pkgs = (struct razor_package *) set->packages.data;
krh@248
   356
	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
krh@248
   357
	for (p = ppi->p;
krh@248
   358
	     p < ppi->end &&
krh@248
   359
		     p->name == ppi->p->name &&
krh@248
   360
		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
krh@248
   361
	     p++) {
krh@248
   362
		if (!ppi->present[p - ppi->start])
krh@248
   363
			continue;
krh@248
   364
		if (!provider_satisfies_requirement(p, ppi->pool,
krh@248
   365
						    r->flags,
krh@248
   366
						    &rpi->pool[r->version]))
krh@248
   367
			continue;
krh@248
   368
krh@248
   369
		razor_package_iterator_init_for_property(&pkg_iter, set, p);
krh@248
   370
		while (razor_package_iterator_next(&pkg_iter, &pkg,
richard@302
   371
						   RAZOR_DETAIL_NAME, &name,
richard@307
   372
						   RAZOR_DETAIL_VERSION, &version,
richard@307
   373
						   RAZOR_DETAIL_LAST)) {
krh@248
   374
ali@403
   375
#if 0
krh@248
   376
			fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
krh@248
   377
				name, version,
krh@248
   378
				ppi->pool + p->name,
krh@248
   379
				rpi->pool + r->name,
krh@248
   380
				rpi->pool + r->version);
ali@403
   381
#endif
krh@248
   382
			flags[pkg - pkgs] |= flag;
krh@248
   383
		}
krh@248
   384
	}
krh@248
   385
}
krh@248
   386
krh@248
   387
static struct razor_package *
krh@248
   388
pick_matching_provider(struct razor_set *set,
krh@248
   389
		       struct prop_iter *ppi,
krh@248
   390
		       uint32_t flags,
krh@248
   391
		       const char *version)
krh@248
   392
{
krh@248
   393
	struct razor_property *p;
krh@248
   394
	struct razor_package *pkgs;
krh@248
   395
	struct list *i;
krh@248
   396
	uint32_t type;
krh@248
   397
krh@248
   398
	/* This is where we decide which pkgs to pull in to satisfy a
krh@248
   399
	 * requirement.  There may be several different providers
krh@248
   400
	 * (different versions) and each version of a provider may
krh@248
   401
	 * come from a number of packages.  We pick the first package
krh@248
   402
	 * from the first provider that matches. */
krh@248
   403
krh@248
   404
	pkgs = set->packages.data;
krh@248
   405
	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
krh@248
   406
	for (p = ppi->p;
krh@248
   407
	     p < ppi->end &&
krh@248
   408
		     p->name == ppi->p->name &&
krh@248
   409
		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
krh@248
   410
		     ppi->present[p - ppi->start] == 0;
krh@248
   411
	     p++) {
krh@248
   412
		if (!provider_satisfies_requirement(p, ppi->pool,
krh@248
   413
						    flags, version))
krh@248
   414
			continue;
krh@248
   415
krh@248
   416
		i = list_first(&p->packages, &set->package_pool);
krh@248
   417
krh@248
   418
		return &pkgs[i->data];
krh@248
   419
	}
krh@248
   420
krh@248
   421
	return NULL;
krh@248
   422
}
krh@248
   423
krh@248
   424
static void
krh@248
   425
remove_obsoleted_packages(struct razor_transaction *trans)
krh@248
   426
{
krh@248
   427
	struct razor_property *up;
krh@248
   428
	struct razor_package *spkgs;
krh@248
   429
	struct prop_iter spi, upi;
krh@248
   430
krh@248
   431
	spkgs = trans->system.set->packages.data;
krh@248
   432
	prop_iter_init(&spi, &trans->system);
krh@248
   433
	prop_iter_init(&upi, &trans->upstream);
krh@248
   434
krh@248
   435
	while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
krh@248
   436
		if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
krh@248
   437
				       &upi.pool[up->name]))
krh@248
   438
			continue;
krh@248
   439
		remove_matching_providers(trans, &spi, up->flags,
krh@248
   440
					  &upi.pool[up->version]);
krh@248
   441
	}
krh@248
   442
}
krh@248
   443
krh@248
   444
static int
krh@248
   445
any_provider_satisfies_requirement(struct prop_iter *ppi,
krh@248
   446
				   uint32_t flags,
krh@248
   447
				   const char *version)
krh@248
   448
{
krh@248
   449
	struct razor_property *p;
krh@248
   450
	uint32_t type;
krh@248
   451
krh@248
   452
	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
krh@248
   453
	for (p = ppi->p;
krh@248
   454
	     p < ppi->end &&
krh@248
   455
		     p->name == ppi->p->name &&
krh@248
   456
		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
krh@248
   457
	     p++) {
krh@248
   458
		if (ppi->present[p - ppi->start] > 0 &&
krh@248
   459
		    provider_satisfies_requirement(p, ppi->pool,
krh@248
   460
						   flags, version))
krh@248
   461
			return 1;
krh@248
   462
	}
krh@248
   463
krh@248
   464
	return 0;
krh@248
   465
}
krh@248
   466
krh@248
   467
static void
krh@248
   468
clear_requires_flags(struct transaction_set *ts)
krh@248
   469
{
krh@248
   470
	struct razor_property *p;
krh@248
   471
	const char *pool;
krh@248
   472
	int i, count;
ali@368
   473
	char *sub;
krh@248
   474
krh@248
   475
	count = ts->set->properties.size / sizeof *p;
krh@248
   476
	p = ts->set->properties.data;
krh@248
   477
	pool = ts->set->string_pool.data;
krh@248
   478
	for (i = 0; i < count; i++) {
krh@248
   479
		ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
ali@368
   480
		sub = strchr(&pool[p[i].name], '(');
ali@368
   481
		if (sub && sub[strlen(sub) - 1] == ')') {
ali@368
   482
			sub = strdup(sub + 1);
ali@368
   483
			sub[strlen(sub) - 1] = '\0';
ali@368
   484
			if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
ali@368
   485
				ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
ali@368
   486
			if (strncmp(&pool[p[i].name], "lua(", 4) == 0 &&
ali@368
   487
			    razor_get_lua_loader(sub) &&
ali@368
   488
			    p[i].flags & RAZOR_PROPERTY_SCRIPT_MASK)
ali@368
   489
				ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
ali@368
   490
			free(sub);
ali@368
   491
		}
krh@248
   492
	}
krh@248
   493
}
krh@248
   494
krh@248
   495
static void
krh@248
   496
mark_satisfied_requires(struct razor_transaction *trans,
krh@248
   497
			struct transaction_set *rts,
krh@248
   498
			struct transaction_set *pts)
krh@248
   499
{
krh@248
   500
	struct prop_iter rpi, ppi;
krh@248
   501
	struct razor_property *rp;
krh@248
   502
krh@248
   503
	prop_iter_init(&rpi, rts);
krh@248
   504
	prop_iter_init(&ppi, pts);
krh@248
   505
krh@248
   506
	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
krh@248
   507
		if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
krh@248
   508
				       &rpi.pool[rp->name]))
krh@248
   509
			continue;
krh@248
   510
krh@248
   511
		if (any_provider_satisfies_requirement(&ppi, rp->flags,
krh@248
   512
						       &rpi.pool[rp->version]))
krh@248
   513
			rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
krh@248
   514
	}
krh@248
   515
}
krh@248
   516
krh@248
   517
static void
krh@248
   518
mark_all_satisfied_requires(struct razor_transaction *trans)
krh@248
   519
{
krh@248
   520
	clear_requires_flags(&trans->system);
krh@248
   521
	clear_requires_flags(&trans->upstream);
krh@248
   522
	mark_satisfied_requires(trans, &trans->system, &trans->system);
krh@248
   523
	mark_satisfied_requires(trans, &trans->system, &trans->upstream);
krh@248
   524
	mark_satisfied_requires(trans, &trans->upstream, &trans->system);
krh@248
   525
	mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
krh@248
   526
}
krh@248
   527
krh@248
   528
static void
krh@248
   529
update_unsatisfied_packages(struct razor_transaction *trans)
krh@248
   530
{
krh@248
   531
	struct razor_package *spkgs, *pkg;
krh@248
   532
	struct razor_property *sp;
krh@248
   533
	struct prop_iter spi;
krh@248
   534
	struct razor_package_iterator pkg_iter;
richard@302
   535
	const char *name;
krh@248
   536
krh@248
   537
	spkgs = trans->system.set->packages.data;
krh@248
   538
	prop_iter_init(&spi, &trans->system);
krh@248
   539
krh@248
   540
	while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
krh@248
   541
		if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
krh@248
   542
			continue;
krh@248
   543
krh@248
   544
		razor_package_iterator_init_for_property(&pkg_iter,
krh@248
   545
							 trans->system.set,
krh@248
   546
							 sp);
krh@248
   547
		while (razor_package_iterator_next(&pkg_iter, &pkg,
richard@307
   548
						   RAZOR_DETAIL_NAME, &name,
richard@307
   549
						   RAZOR_DETAIL_LAST)) {
ali@432
   550
			if (!(trans->system.packages[pkg - spkgs] & TRANS_PACKAGE_PRESENT))
ali@432
   551
				continue;
ali@432
   552
ali@403
   553
#if 0
krh@248
   554
			fprintf(stderr, "updating %s because %s %s %s "
krh@248
   555
				"isn't satisfied\n",
krh@248
   556
				name, spi.pool + sp->name,
krh@248
   557
				razor_property_relation_to_string(sp),
krh@248
   558
				spi.pool + sp->version);
ali@403
   559
#endif
krh@248
   560
			trans->system.packages[pkg - spkgs] |=
krh@248
   561
				TRANS_PACKAGE_UPDATE;
krh@248
   562
		}
krh@248
   563
	}
krh@248
   564
}
krh@248
   565
krh@269
   566
RAZOR_EXPORT void
krh@248
   567
razor_transaction_update_all(struct razor_transaction *trans)
krh@248
   568
{
krh@248
   569
	struct razor_package *p;
krh@248
   570
	int i, count;
krh@248
   571
richard@301
   572
	assert (trans != NULL);
richard@301
   573
krh@248
   574
	count = trans->system.set->packages.size / sizeof *p;
krh@248
   575
	for (i = 0; i < count; i++)
krh@248
   576
		trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
krh@248
   577
}
krh@248
   578
krh@248
   579
static void
krh@248
   580
update_conflicted_packages(struct razor_transaction *trans)
krh@248
   581
{
krh@248
   582
	struct razor_package *pkg, *spkgs;
krh@248
   583
	struct razor_property *up, *sp;
krh@248
   584
	struct prop_iter spi, upi;
krh@248
   585
	struct razor_package_iterator pkg_iter;
richard@302
   586
	const char *name, *version;
krh@248
   587
krh@248
   588
	spkgs = trans->system.set->packages.data;
krh@248
   589
	prop_iter_init(&spi, &trans->system);
krh@248
   590
	prop_iter_init(&upi, &trans->upstream);
krh@248
   591
krh@248
   592
	while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
krh@248
   593
		if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
krh@248
   594
				       &spi.pool[sp->name]))
krh@248
   595
			continue;
krh@248
   596
krh@248
   597
		if (!any_provider_satisfies_requirement(&upi, sp->flags,
krh@248
   598
							&spi.pool[sp->version]))
krh@248
   599
			continue;
krh@248
   600
krh@248
   601
		razor_package_iterator_init_for_property(&pkg_iter,
krh@248
   602
							 trans->system.set,
krh@248
   603
							 sp);
krh@248
   604
		while (razor_package_iterator_next(&pkg_iter, &pkg,
richard@302
   605
						   RAZOR_DETAIL_NAME, &name,
richard@307
   606
						   RAZOR_DETAIL_VERSION, &version,
richard@307
   607
						   RAZOR_DETAIL_LAST)) {
ali@403
   608
#if 0
jbowes@286
   609
			fprintf(stderr, "updating %s %s because it "
jbowes@286
   610
				"conflicts with %s\n",
krh@248
   611
				name, version, spi.pool + sp->name);
ali@403
   612
#endif
krh@248
   613
			trans->system.packages[pkg - spkgs] |=
krh@248
   614
				TRANS_PACKAGE_UPDATE;
krh@248
   615
		}
krh@248
   616
	}
krh@248
   617
krh@248
   618
	prop_iter_init(&spi, &trans->system);
krh@248
   619
	prop_iter_init(&upi, &trans->upstream);
krh@248
   620
krh@248
   621
	while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
krh@248
   622
		sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
krh@248
   623
				       &upi.pool[upi.p->name]);
krh@248
   624
krh@248
   625
		if (sp)
krh@248
   626
			flag_matching_providers(trans, &spi, up, &upi,
krh@248
   627
						TRANS_PACKAGE_UPDATE);
krh@248
   628
	}
krh@248
   629
}
krh@248
   630
krh@248
   631
static void
krh@248
   632
pull_in_requirements(struct razor_transaction *trans,
krh@248
   633
		     struct prop_iter *rpi, struct prop_iter *ppi)
krh@248
   634
{
krh@248
   635
	struct razor_property *rp, *pp;
krh@248
   636
	struct razor_package *pkg, *upkgs;
krh@248
   637
krh@248
   638
	upkgs = trans->upstream.set->packages.data;
krh@248
   639
	while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
krh@248
   640
		if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
krh@248
   641
			continue;
krh@248
   642
krh@248
   643
		pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
krh@248
   644
				       &rpi->pool[rp->name]);
krh@248
   645
		if (pp == NULL)
krh@248
   646
			continue;
krh@248
   647
		pkg = pick_matching_provider(trans->upstream.set,
krh@248
   648
					     ppi, rp->flags,
krh@248
   649
					     &rpi->pool[rp->version]);
krh@248
   650
		if (pkg == NULL)
krh@248
   651
			continue;
krh@248
   652
krh@248
   653
		rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
krh@248
   654
ali@403
   655
#if 0
krh@257
   656
		fprintf(stderr, "pulling in %s-%s.%s which provides %s %s %s "
krh@248
   657
			"to satisfy %s %s %s\n",
krh@248
   658
			ppi->pool + pkg->name,
krh@257
   659
			ppi->pool + pkg->version,
krh@257
   660
			ppi->pool + pkg->arch,
krh@248
   661
			ppi->pool + pp->name,
krh@248
   662
			razor_property_relation_to_string(pp),
krh@248
   663
			ppi->pool + pp->version,
krh@248
   664
			&rpi->pool[rp->name],
krh@248
   665
			razor_property_relation_to_string(rp),
krh@248
   666
			&rpi->pool[rp->version]);
ali@403
   667
#endif
krh@248
   668
krh@248
   669
		trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
krh@248
   670
	}
krh@248
   671
}
krh@248
   672
krh@248
   673
static void
krh@248
   674
pull_in_all_requirements(struct razor_transaction *trans)
krh@248
   675
{
krh@248
   676
	struct prop_iter rpi, ppi;
krh@248
   677
krh@248
   678
	prop_iter_init(&rpi, &trans->system);
krh@248
   679
	prop_iter_init(&ppi, &trans->upstream);
krh@248
   680
	pull_in_requirements(trans, &rpi, &ppi);
krh@248
   681
krh@248
   682
	prop_iter_init(&rpi, &trans->upstream);
krh@248
   683
	prop_iter_init(&ppi, &trans->upstream);
krh@248
   684
	pull_in_requirements(trans, &rpi, &ppi);
krh@248
   685
}
krh@248
   686
krh@248
   687
static void
krh@248
   688
flush_scheduled_system_updates(struct razor_transaction *trans)
krh@248
   689
{
krh@248
   690
 	struct razor_package_iterator *pi;
krh@248
   691
 	struct razor_package *p, *pkg, *spkgs;
krh@248
   692
	struct prop_iter ppi;
richard@302
   693
	const char *name, *version;
krh@248
   694
krh@248
   695
	spkgs = trans->system.set->packages.data;
krh@248
   696
	pi = razor_package_iterator_create(trans->system.set);
krh@248
   697
	prop_iter_init(&ppi, &trans->upstream);
krh@248
   698
richard@302
   699
	while (razor_package_iterator_next(pi, &p,
richard@302
   700
					   RAZOR_DETAIL_NAME, &name,
richard@307
   701
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   702
					   RAZOR_DETAIL_LAST)) {
krh@248
   703
		if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
krh@248
   704
			continue;
ali@432
   705
		trans->system.packages[p - spkgs] &= ~TRANS_PACKAGE_UPDATE;
krh@248
   706
krh@248
   707
		if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
krh@248
   708
			continue;
krh@248
   709
ali@386
   710
		if (any_provider_satisfies_requirement(&ppi,
ali@386
   711
						       RAZOR_PROPERTY_GREATER,
ali@386
   712
						       version)) {
ali@386
   713
			razor_transaction_remove_package(trans, p);
ali@386
   714
			continue;
ali@386
   715
		}
ali@386
   716
krh@248
   717
		pkg = pick_matching_provider(trans->upstream.set, &ppi,
krh@248
   718
					     RAZOR_PROPERTY_GREATER, version);
krh@248
   719
		if (pkg == NULL)
krh@248
   720
			continue;
krh@248
   721
krh@248
   722
		razor_transaction_remove_package(trans, p);
krh@248
   723
		razor_transaction_install_package(trans, pkg);
krh@248
   724
	}
krh@248
   725
krh@248
   726
	razor_package_iterator_destroy(pi);
krh@248
   727
}
krh@248
   728
krh@248
   729
static void
krh@248
   730
flush_scheduled_upstream_updates(struct razor_transaction *trans)
krh@248
   731
{
krh@248
   732
 	struct razor_package_iterator *pi;
krh@248
   733
 	struct razor_package *p, *upkgs;
krh@248
   734
	struct prop_iter spi;
richard@302
   735
	const char *name, *version;
krh@248
   736
krh@248
   737
	upkgs = trans->upstream.set->packages.data;
krh@248
   738
	pi = razor_package_iterator_create(trans->upstream.set);
krh@248
   739
	prop_iter_init(&spi, &trans->system);
krh@248
   740
richard@302
   741
	while (razor_package_iterator_next(pi, &p,
richard@302
   742
					   RAZOR_DETAIL_NAME, &name,
richard@307
   743
					   RAZOR_DETAIL_VERSION, &version,
richard@307
   744
					   RAZOR_DETAIL_LAST)) {
krh@248
   745
		if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
krh@248
   746
			continue;
ali@432
   747
		trans->upstream.packages[p - upkgs] &= ~TRANS_PACKAGE_UPDATE;
krh@248
   748
krh@248
   749
		if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
krh@248
   750
			remove_matching_providers(trans,
krh@248
   751
						  &spi,
krh@248
   752
						  RAZOR_PROPERTY_LESS,
krh@248
   753
						  version);
krh@248
   754
		razor_transaction_install_package(trans, p);
ali@403
   755
#if 0
krh@248
   756
		fprintf(stderr, "installing %s-%s\n", name, version);
ali@403
   757
#endif
krh@248
   758
	}
krh@248
   759
}
krh@248
   760
krh@269
   761
RAZOR_EXPORT int
krh@248
   762
razor_transaction_resolve(struct razor_transaction *trans)
krh@248
   763
{
krh@248
   764
	int last = 0;
krh@248
   765
krh@248
   766
	flush_scheduled_system_updates(trans);
krh@248
   767
	flush_scheduled_upstream_updates(trans);
krh@248
   768
krh@248
   769
	while (last < trans->changes) {
krh@248
   770
		last = trans->changes;
krh@248
   771
		remove_obsoleted_packages(trans);
krh@248
   772
		mark_all_satisfied_requires(trans);
krh@248
   773
		update_unsatisfied_packages(trans);
krh@248
   774
		update_conflicted_packages(trans);
krh@248
   775
		pull_in_all_requirements(trans);
krh@248
   776
		flush_scheduled_system_updates(trans);
krh@248
   777
		flush_scheduled_upstream_updates(trans);
krh@248
   778
	}
krh@248
   779
krh@248
   780
	return trans->changes;
krh@248
   781
}
krh@248
   782
krh@248
   783
static void
krh@248
   784
describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
krh@248
   785
{
krh@248
   786
	struct razor_package_iterator pi;
krh@248
   787
	struct razor_package *pkg;
krh@248
   788
	const char *name, *version, *arch, *pool;
krh@248
   789
krh@248
   790
	pool = set->string_pool.data;
krh@248
   791
	if (pool[rp->version] == '\0') {
krh@248
   792
		razor_package_iterator_init_for_property(&pi, set, rp);
krh@248
   793
		while (razor_package_iterator_next(&pi, &pkg,
richard@302
   794
						   RAZOR_DETAIL_NAME, &name,
richard@302
   795
						   RAZOR_DETAIL_VERSION, &version,
richard@307
   796
						   RAZOR_DETAIL_ARCH, &arch,
richard@307
   797
						   RAZOR_DETAIL_LAST))
krh@248
   798
			fprintf(stderr, "%s is needed by %s-%s.%s\n",
krh@248
   799
				&pool[rp->name],
krh@248
   800
				name, version, arch);
krh@248
   801
	} else {
krh@248
   802
		razor_package_iterator_init_for_property(&pi, set, rp);
krh@248
   803
		while (razor_package_iterator_next(&pi, &pkg,
richard@302
   804
						   RAZOR_DETAIL_NAME, &name,
richard@302
   805
						   RAZOR_DETAIL_VERSION, &version,
richard@307
   806
						   RAZOR_DETAIL_ARCH, &arch,
richard@307
   807
						   RAZOR_DETAIL_LAST))
krh@248
   808
			fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
krh@248
   809
				&pool[rp->name],
krh@248
   810
				razor_property_relation_to_string(rp),
krh@248
   811
				&pool[rp->version],
krh@248
   812
				name, version, arch);
krh@248
   813
	}
krh@248
   814
}
krh@248
   815
krh@269
   816
RAZOR_EXPORT int
krh@248
   817
razor_transaction_describe(struct razor_transaction *trans)
krh@248
   818
{
krh@248
   819
	struct prop_iter rpi;
krh@248
   820
	struct razor_property *rp;
krh@248
   821
	int unsatisfied;
krh@248
   822
krh@248
   823
	flush_scheduled_system_updates(trans);
krh@248
   824
	flush_scheduled_upstream_updates(trans);
krh@248
   825
	mark_all_satisfied_requires(trans);
krh@248
   826
krh@248
   827
	unsatisfied = 0;
krh@248
   828
	prop_iter_init(&rpi, &trans->system);
krh@248
   829
	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
krh@248
   830
		if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
krh@248
   831
			describe_unsatisfied(trans->system.set, rp);
krh@248
   832
		        unsatisfied++;
krh@248
   833
		}
krh@248
   834
	}
krh@248
   835
krh@248
   836
	prop_iter_init(&rpi, &trans->upstream);
krh@248
   837
	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
krh@248
   838
		if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
krh@248
   839
			describe_unsatisfied(trans->upstream.set, rp);
krh@248
   840
			unsatisfied++;
krh@248
   841
		}
krh@248
   842
	}
krh@248
   843
krh@248
   844
	return unsatisfied;
krh@248
   845
}
krh@248
   846
krh@269
   847
RAZOR_EXPORT int
krh@248
   848
razor_transaction_unsatisfied_property(struct razor_transaction *trans,
krh@248
   849
				       const char *name,
krh@248
   850
				       uint32_t flags,
krh@248
   851
				       const char *version)
krh@248
   852
{
krh@248
   853
	struct prop_iter pi;
krh@248
   854
	struct razor_property *p;
krh@248
   855
krh@248
   856
	prop_iter_init(&pi, &trans->system);
jbowes@284
   857
	while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
krh@248
   858
		if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
krh@248
   859
		    p->flags == flags &&
krh@248
   860
		    strcmp(&pi.pool[p->name], name) == 0 &&
krh@248
   861
		    strcmp(&pi.pool[p->version], version) == 0)
krh@248
   862
krh@248
   863
			return 1;
krh@248
   864
	}
krh@248
   865
krh@248
   866
	prop_iter_init(&pi, &trans->upstream);
jbowes@284
   867
	while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
krh@248
   868
		if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
krh@248
   869
		    p->flags == flags &&
krh@248
   870
		    strcmp(&pi.pool[p->name], name) == 0 &&
krh@248
   871
		    strcmp(&pi.pool[p->version], version) == 0)
krh@248
   872
krh@248
   873
			return 1;
krh@248
   874
	}
krh@248
   875
krh@248
   876
	return 0;
krh@248
   877
}
krh@248
   878
krh@269
   879
RAZOR_EXPORT struct razor_set *
ali@369
   880
razor_transaction_commit(struct razor_transaction *trans)
krh@248
   881
{
krh@248
   882
	struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
krh@248
   883
	char *upool, *spool;
krh@248
   884
	int cmp;
krh@248
   885
krh@248
   886
	s = trans->system.set->packages.data;
krh@248
   887
	spkgs = trans->system.set->packages.data;
krh@248
   888
	send = trans->system.set->packages.data +
krh@248
   889
		trans->system.set->packages.size;
krh@248
   890
	spool = trans->system.set->string_pool.data;
krh@248
   891
krh@248
   892
	u = trans->upstream.set->packages.data;
krh@248
   893
	upkgs = trans->upstream.set->packages.data;
krh@248
   894
	uend = trans->upstream.set->packages.data +
krh@248
   895
		trans->upstream.set->packages.size;
krh@248
   896
	upool = trans->upstream.set->string_pool.data;
krh@248
   897
ali@369
   898
	trans->merger = razor_merger_create(trans->system.set,
ali@369
   899
					    trans->upstream.set);
krh@248
   900
	while (s < send || u < uend) {
krh@248
   901
		if (s < send && u < uend)
krh@248
   902
			cmp = strcmp(&spool[s->name], &upool[u->name]);
krh@248
   903
		else if (s < send)
krh@248
   904
			cmp = -1;
krh@248
   905
		else
krh@248
   906
			cmp = 1;
krh@248
   907
krh@248
   908
		if (cmp < 0) {
krh@248
   909
			if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
ali@369
   910
				razor_merger_add_package(trans->merger, s);
krh@248
   911
			s++;
krh@248
   912
		} else if (cmp == 0) {
krh@248
   913
			if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
ali@369
   914
				razor_merger_add_package(trans->merger, s);
krh@248
   915
			if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
ali@369
   916
				razor_merger_add_package(trans->merger, u);
krh@248
   917
krh@248
   918
			s++;
krh@248
   919
			u++;
krh@248
   920
		} else {
krh@248
   921
			if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
ali@369
   922
				razor_merger_add_package(trans->merger, u);
krh@248
   923
			u++;
krh@248
   924
		}
krh@248
   925
	}
krh@248
   926
ali@369
   927
	return razor_merger_commit(trans->merger);
ali@369
   928
}
krh@248
   929
ali@369
   930
RAZOR_EXPORT void
ali@369
   931
razor_transaction_fixup_package(struct razor_transaction *trans,
ali@369
   932
				struct razor_package *package,
ali@369
   933
				struct razor_rpm *rpm)
ali@369
   934
{
ali@369
   935
	const char *preunprog, *preun, *postunprog, *postun;
ali@369
   936
ali@369
   937
	razor_rpm_get_details(rpm,
ali@369
   938
			      RAZOR_DETAIL_PREUNPROG, &preunprog,
ali@369
   939
			      RAZOR_DETAIL_PREUN, &preun,
ali@369
   940
			      RAZOR_DETAIL_POSTUNPROG, &postunprog,
ali@369
   941
			      RAZOR_DETAIL_POSTUN, &postun,
ali@369
   942
			      RAZOR_DETAIL_LAST);
ali@369
   943
ali@369
   944
	razor_merger_package_add_script(trans->merger, package,
ali@369
   945
					RAZOR_PROPERTY_PREUN,
ali@369
   946
					preunprog, preun);
ali@369
   947
	razor_merger_package_add_script(trans->merger, package,
ali@369
   948
					RAZOR_PROPERTY_POSTUN,
ali@369
   949
					postunprog, postun);
krh@248
   950
}
krh@248
   951
krh@269
   952
RAZOR_EXPORT void
krh@248
   953
razor_transaction_destroy(struct razor_transaction *trans)
krh@248
   954
{
richard@301
   955
	assert (trans != NULL);
richard@301
   956
ali@369
   957
	if (trans->merger)
ali@369
   958
		razor_merger_destroy(trans->merger);
krh@248
   959
	transaction_set_release(&trans->system);
krh@248
   960
	transaction_set_release(&trans->upstream);
krh@248
   961
	free(trans);
krh@248
   962
}