librazor/razor.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 23:13:09 2008 -0400 (2008-06-20)
changeset 257 0c3db660514d
parent 253 338a577cdfd2
child 259 5b0601d184ed
permissions -rw-r--r--
When uniquifying properties, also sort them on the owning package.

This ensures that whenever two packages provide or (or require, obsolete
or conflict) the same property, they appear in the same order in the
propertys list of packages.
rhughes@241
     1
/*
rhughes@241
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
rhughes@241
     3
 * Copyright (C) 2008  Red Hat, Inc
rhughes@241
     4
 *
rhughes@241
     5
 * This program is free software; you can redistribute it and/or modify
rhughes@241
     6
 * it under the terms of the GNU General Public License as published by
rhughes@241
     7
 * the Free Software Foundation; either version 2 of the License, or
rhughes@241
     8
 * (at your option) any later version.
rhughes@241
     9
 *
rhughes@241
    10
 * This program is distributed in the hope that it will be useful,
rhughes@241
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rhughes@241
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
rhughes@241
    13
 * GNU General Public License for more details.
rhughes@241
    14
 *
rhughes@241
    15
 * You should have received a copy of the GNU General Public License along
rhughes@241
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
rhughes@241
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
rhughes@241
    18
 */
rhughes@241
    19
rhughes@241
    20
#define _GNU_SOURCE
rhughes@241
    21
rhughes@241
    22
#include <stdlib.h>
rhughes@241
    23
#include <stddef.h>
rhughes@241
    24
#include <stdint.h>
rhughes@241
    25
#include <stdio.h>
rhughes@241
    26
#include <string.h>
rhughes@241
    27
#include <sys/types.h>
rhughes@241
    28
#include <sys/stat.h>
rhughes@241
    29
#include <sys/mman.h>
rhughes@241
    30
#include <unistd.h>
rhughes@241
    31
#include <fcntl.h>
rhughes@241
    32
#include <errno.h>
rhughes@241
    33
#include <ctype.h>
rhughes@241
    34
#include <fnmatch.h>
rhughes@241
    35
krh@253
    36
#include "razor-internal.h"
rhughes@241
    37
#include "razor.h"
rhughes@241
    38
krh@248
    39
void *
rhughes@241
    40
zalloc(size_t size)
rhughes@241
    41
{
rhughes@241
    42
	void *p;
rhughes@241
    43
rhughes@241
    44
	p = malloc(size);
rhughes@241
    45
	memset(p, 0, size);
rhughes@241
    46
rhughes@241
    47
	return p;
rhughes@241
    48
}
rhughes@241
    49
rhughes@241
    50
struct razor_set_section razor_sections[] = {
rhughes@241
    51
	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
rhughes@241
    52
	{ RAZOR_PACKAGES,	offsetof(struct razor_set, packages) },
rhughes@241
    53
	{ RAZOR_PROPERTIES,	offsetof(struct razor_set, properties) },
rhughes@241
    54
	{ RAZOR_FILES,		offsetof(struct razor_set, files) },
rhughes@241
    55
	{ RAZOR_PACKAGE_POOL,	offsetof(struct razor_set, package_pool) },
rhughes@241
    56
	{ RAZOR_PROPERTY_POOL,	offsetof(struct razor_set, property_pool) },
rhughes@241
    57
	{ RAZOR_FILE_POOL,	offsetof(struct razor_set, file_pool) },
rhughes@241
    58
};
rhughes@241
    59
rhughes@241
    60
struct razor_set *
rhughes@241
    61
razor_set_create(void)
rhughes@241
    62
{
rhughes@241
    63
	struct razor_set *set;
rhughes@241
    64
	struct razor_entry *e;
rhughes@241
    65
	char *empty;
rhughes@241
    66
rhughes@241
    67
	set = zalloc(sizeof *set);
rhughes@241
    68
rhughes@241
    69
	e = array_add(&set->files, sizeof *e);
rhughes@241
    70
	empty = array_add(&set->string_pool, 1);
rhughes@241
    71
	*empty = '\0';
rhughes@241
    72
	e->name = 0;
rhughes@241
    73
	e->flags = RAZOR_ENTRY_LAST;
rhughes@241
    74
	e->start = 0;
rhughes@241
    75
	list_set_empty(&e->packages);
rhughes@241
    76
rhughes@241
    77
	return set;
rhughes@241
    78
}
rhughes@241
    79
rhughes@241
    80
struct razor_set *
rhughes@241
    81
razor_set_open(const char *filename)
rhughes@241
    82
{
rhughes@241
    83
	struct razor_set *set;
rhughes@241
    84
	struct razor_set_section *s;
rhughes@241
    85
	struct stat stat;
rhughes@241
    86
	struct array *array;
rhughes@241
    87
	int fd;
rhughes@241
    88
rhughes@241
    89
	set = zalloc(sizeof *set);
rhughes@241
    90
	fd = open(filename, O_RDONLY);
rhughes@241
    91
	if (fstat(fd, &stat) < 0)
rhughes@241
    92
		return NULL;
rhughes@241
    93
	set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
rhughes@241
    94
	if (set->header == MAP_FAILED) {
rhughes@241
    95
		free(set);
rhughes@241
    96
		return NULL;
rhughes@241
    97
	}
rhughes@241
    98
rhughes@241
    99
	for (s = set->header->sections; ~s->type; s++) {
rhughes@241
   100
		if (s->type >= ARRAY_SIZE(razor_sections))
rhughes@241
   101
			continue;
rhughes@241
   102
		if (s->type != razor_sections[s->type].type)
rhughes@241
   103
			continue;
rhughes@241
   104
		array = (void *) set + razor_sections[s->type].offset;
rhughes@241
   105
		array->data = (void *) set->header + s->offset;
rhughes@241
   106
		array->size = s->size;
rhughes@241
   107
		array->alloc = s->size;
rhughes@241
   108
	}
rhughes@241
   109
	close(fd);
rhughes@241
   110
rhughes@241
   111
	return set;
rhughes@241
   112
}
rhughes@241
   113
rhughes@241
   114
void
rhughes@241
   115
razor_set_destroy(struct razor_set *set)
rhughes@241
   116
{
rhughes@241
   117
	unsigned int size;
rhughes@241
   118
	struct array *a;
rhughes@241
   119
	int i;
rhughes@241
   120
rhughes@241
   121
	if (set->header) {
rhughes@241
   122
		for (i = 0; set->header->sections[i].type; i++)
rhughes@241
   123
			;
rhughes@241
   124
		size = set->header->sections[i].type;
rhughes@241
   125
		munmap(set->header, size);
rhughes@241
   126
	} else {
rhughes@241
   127
		for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
rhughes@241
   128
			a = (void *) set + razor_sections[i].offset;
rhughes@241
   129
			free(a->data);
rhughes@241
   130
		}
rhughes@241
   131
	}
rhughes@241
   132
rhughes@241
   133
	free(set);
rhughes@241
   134
}
rhughes@241
   135
rhughes@241
   136
int
rhughes@241
   137
razor_set_write_to_fd(struct razor_set *set, int fd)
rhughes@241
   138
{
rhughes@241
   139
	char data[4096];
rhughes@241
   140
	struct razor_set_header *header = (struct razor_set_header *) data;
rhughes@241
   141
	struct array *a;
rhughes@241
   142
	uint32_t offset;
rhughes@241
   143
	int i;
rhughes@241
   144
rhughes@241
   145
	memset(data, 0, sizeof data);
rhughes@241
   146
	header->magic = RAZOR_MAGIC;
rhughes@241
   147
	header->version = RAZOR_VERSION;
rhughes@241
   148
	offset = sizeof data;
rhughes@241
   149
rhughes@241
   150
	for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
rhughes@241
   151
		if (razor_sections[i].type != i)
rhughes@241
   152
			continue;
rhughes@241
   153
		a = (void *) set + razor_sections[i].offset;
rhughes@241
   154
		header->sections[i].type = i;
rhughes@241
   155
		header->sections[i].offset = offset;
rhughes@241
   156
		header->sections[i].size = a->size;
rhughes@241
   157
		offset += ALIGN(a->size, 4096);
rhughes@241
   158
	}
rhughes@241
   159
rhughes@241
   160
	header->sections[i].type = ~0;
rhughes@241
   161
	header->sections[i].offset = 0;
rhughes@241
   162
	header->sections[i].size = 0;
rhughes@241
   163
rhughes@241
   164
	razor_write(fd, data, sizeof data);
rhughes@241
   165
	memset(data, 0, sizeof data);
rhughes@241
   166
	for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
rhughes@241
   167
		if (razor_sections[i].type != i)
rhughes@241
   168
			continue;
rhughes@241
   169
		a = (void *) set + razor_sections[i].offset;
rhughes@241
   170
		razor_write(fd, a->data, a->size);
rhughes@241
   171
		razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
rhughes@241
   172
	}
rhughes@241
   173
rhughes@241
   174
	return 0;
rhughes@241
   175
}
rhughes@241
   176
rhughes@241
   177
int
rhughes@241
   178
razor_set_write(struct razor_set *set, const char *filename)
rhughes@241
   179
{
rhughes@241
   180
	int fd, status;
rhughes@241
   181
rhughes@241
   182
	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
rhughes@241
   183
	if (fd < 0)
rhughes@241
   184
		return -1;
rhughes@241
   185
rhughes@241
   186
	status = razor_set_write_to_fd(set, fd);
rhughes@241
   187
	if (status) {
rhughes@241
   188
	    close(fd);
rhughes@241
   189
	    return status;
rhughes@241
   190
	}
rhughes@241
   191
rhughes@241
   192
	return close(fd);
rhughes@241
   193
}
rhughes@241
   194
rhughes@241
   195
void
rhughes@241
   196
razor_build_evr(char *evr_buf, int size, const char *epoch,
rhughes@241
   197
		const char *version, const char *release)
rhughes@241
   198
{
rhughes@241
   199
	int len;
rhughes@241
   200
rhughes@241
   201
	if (!version || !*version) {
rhughes@241
   202
		*evr_buf = '\0';
rhughes@241
   203
		return;
rhughes@241
   204
	}
rhughes@241
   205
rhughes@241
   206
	if (epoch && *epoch && strcmp(epoch, "0") != 0) {
rhughes@241
   207
		len = snprintf(evr_buf, size, "%s:", epoch);
rhughes@241
   208
		evr_buf += len;
rhughes@241
   209
		size -= len;
rhughes@241
   210
	}
rhughes@241
   211
	len = snprintf(evr_buf, size, "%s", version);
rhughes@241
   212
	evr_buf += len;
rhughes@241
   213
	size -= len;
rhughes@241
   214
	if (release && *release)
rhughes@241
   215
		snprintf(evr_buf, size, "-%s", release);
rhughes@241
   216
}
rhughes@241
   217
krh@248
   218
int
krh@248
   219
razor_versioncmp(const char *s1, const char *s2)
rhughes@241
   220
{
rhughes@241
   221
	const char *p1, *p2;
rhughes@241
   222
	long n1, n2;
rhughes@241
   223
	int res;
rhughes@241
   224
rhughes@241
   225
	n1 = strtol(s1, (char **) &p1, 10);
rhughes@241
   226
	n2 = strtol(s2, (char **) &p2, 10);
rhughes@241
   227
rhughes@241
   228
	/* Epoch; if one but not the other has an epoch set, default
rhughes@241
   229
	 * the epoch-less version to 0. */
rhughes@241
   230
	res = (*p1 == ':') - (*p2 == ':');
rhughes@241
   231
	if (res < 0) {
rhughes@241
   232
		n1 = 0;
rhughes@241
   233
		p1 = s1;
rhughes@241
   234
		p2++;
rhughes@241
   235
	} else if (res > 0) {
rhughes@241
   236
		p1++;
rhughes@241
   237
		n2 = 0;
rhughes@241
   238
		p2 = s2;
rhughes@241
   239
	}
rhughes@241
   240
rhughes@241
   241
	if (n1 != n2)
rhughes@241
   242
		return n1 - n2;
rhughes@241
   243
	while (*p1 && *p2) {
rhughes@241
   244
		if (*p1 != *p2)
rhughes@241
   245
			return *p1 - *p2;
rhughes@241
   246
		p1++;
rhughes@241
   247
		p2++;
rhughes@241
   248
		if (isdigit(*p1) && isdigit(*p2))
krh@248
   249
			return razor_versioncmp(p1, p2);
rhughes@241
   250
	}
rhughes@241
   251
rhughes@241
   252
	return *p1 - *p2;
rhughes@241
   253
}
rhughes@241
   254
rhughes@241
   255
struct razor_package *
rhughes@241
   256
razor_set_get_package(struct razor_set *set, const char *package)
rhughes@241
   257
{
rhughes@241
   258
	struct razor_package_iterator *pi;
rhughes@241
   259
	struct razor_package *p;
rhughes@241
   260
	const char *name, *version, *arch;
rhughes@241
   261
rhughes@241
   262
	pi = razor_package_iterator_create(set);
rhughes@241
   263
	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
rhughes@241
   264
		if (strcmp(package, name) == 0)
rhughes@241
   265
			break;
rhughes@241
   266
	}
rhughes@241
   267
	razor_package_iterator_destroy(pi);
rhughes@241
   268
rhughes@241
   269
	return p;
rhughes@241
   270
}
rhughes@241
   271
krh@248
   272
struct razor_entry *
krh@248
   273
razor_set_find_entry(struct razor_set *set,
krh@248
   274
		     struct razor_entry *dir, const char *pattern)
rhughes@241
   275
{
rhughes@241
   276
	struct razor_entry *e;
rhughes@241
   277
	const char *n, *pool = set->string_pool.data;
rhughes@241
   278
	int len;
rhughes@241
   279
rhughes@241
   280
	e = (struct razor_entry *) set->files.data + dir->start;
rhughes@241
   281
	do {
rhughes@241
   282
		n = pool + e->name;
rhughes@241
   283
		if (strcmp(pattern + 1, n) == 0)
rhughes@241
   284
			return e;
rhughes@241
   285
		len = strlen(n);
rhughes@241
   286
		if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
rhughes@241
   287
		    pattern[len + 1] == '/') {
krh@248
   288
			return razor_set_find_entry(set, e, pattern + len + 1);
rhughes@241
   289
		}
rhughes@241
   290
	} while (!((e++)->flags & RAZOR_ENTRY_LAST));
rhughes@241
   291
rhughes@241
   292
	return NULL;
rhughes@241
   293
}
rhughes@241
   294
rhughes@241
   295
static void
rhughes@241
   296
list_dir(struct razor_set *set, struct razor_entry *dir,
rhughes@241
   297
	 char *prefix, const char *pattern)
rhughes@241
   298
{
rhughes@241
   299
	struct razor_entry *e;
rhughes@241
   300
	const char *n, *pool = set->string_pool.data;
rhughes@241
   301
rhughes@241
   302
	e = (struct razor_entry *) set->files.data + dir->start;
rhughes@241
   303
	do {
rhughes@241
   304
		n = pool + e->name;
rhughes@241
   305
		if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
rhughes@241
   306
			continue;
rhughes@241
   307
		printf("%s/%s\n", prefix, n);
rhughes@241
   308
		if (e->start) {
rhughes@241
   309
			char *sub = prefix + strlen (prefix);
rhughes@241
   310
			*sub = '/';
rhughes@241
   311
			strcpy (sub + 1, n);
rhughes@241
   312
			list_dir(set, e, prefix, pattern);
rhughes@241
   313
			*sub = '\0';
rhughes@241
   314
		}
rhughes@241
   315
	} while (!((e++)->flags & RAZOR_ENTRY_LAST));
rhughes@241
   316
}
rhughes@241
   317
rhughes@241
   318
void
rhughes@241
   319
razor_set_list_files(struct razor_set *set, const char *pattern)
rhughes@241
   320
{
rhughes@241
   321
	struct razor_entry *e;
rhughes@241
   322
	char buffer[512], *p, *base;
rhughes@241
   323
rhughes@241
   324
	if (pattern == NULL || !strcmp (pattern, "/")) {
rhughes@241
   325
		buffer[0] = '\0';
rhughes@241
   326
		list_dir(set, set->files.data, buffer, NULL);
rhughes@241
   327
		return;
rhughes@241
   328
	}
rhughes@241
   329
rhughes@241
   330
	strcpy(buffer, pattern);
krh@248
   331
	e = razor_set_find_entry(set, set->files.data, buffer);
rhughes@241
   332
	if (e && e->start > 0) {
rhughes@241
   333
		base = NULL;
rhughes@241
   334
	} else {
rhughes@241
   335
		p = strrchr(buffer, '/');
rhughes@241
   336
		if (p) {
rhughes@241
   337
			*p = '\0';
rhughes@241
   338
			base = p + 1;
rhughes@241
   339
		} else {
rhughes@241
   340
			base = NULL;
rhughes@241
   341
		}
rhughes@241
   342
	}
krh@248
   343
	e = razor_set_find_entry(set, set->files.data, buffer);
rhughes@241
   344
	if (e->start != 0)
rhughes@241
   345
		list_dir(set, e, buffer, base);
rhughes@241
   346
}
rhughes@241
   347
rhughes@241
   348
static struct list *
rhughes@241
   349
list_package_files(struct razor_set *set, struct list *r,
rhughes@241
   350
		   struct razor_entry *dir, uint32_t end,
rhughes@241
   351
		   char *prefix)
rhughes@241
   352
{
rhughes@241
   353
	struct razor_entry *e, *f, *entries;
rhughes@241
   354
	uint32_t next, file;
rhughes@241
   355
	char *pool;
rhughes@241
   356
	int len;
rhughes@241
   357
rhughes@241
   358
	entries = (struct razor_entry *) set->files.data;
rhughes@241
   359
	pool = set->string_pool.data;
rhughes@241
   360
rhughes@241
   361
	e = entries + dir->start;
rhughes@241
   362
	do {
rhughes@241
   363
		if (entries + r->data == e) {
rhughes@241
   364
			printf("%s/%s\n", prefix, pool + e->name);
rhughes@241
   365
			r = list_next(r);
rhughes@241
   366
			if (!r)
rhughes@241
   367
				return NULL;
rhughes@241
   368
			if (r->data >= end)
rhughes@241
   369
				return r;
rhughes@241
   370
		}
rhughes@241
   371
	} while (!((e++)->flags & RAZOR_ENTRY_LAST));
rhughes@241
   372
rhughes@241
   373
	e = entries + dir->start;
rhughes@241
   374
	do {
rhughes@241
   375
		if (e->start == 0)
rhughes@241
   376
			continue;
rhughes@241
   377
rhughes@241
   378
		if (e->flags & RAZOR_ENTRY_LAST)
rhughes@241
   379
			next = end;
rhughes@241
   380
		else {
rhughes@241
   381
			f = e + 1;
rhughes@241
   382
			while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST))
rhughes@241
   383
				f++;
rhughes@241
   384
			if (f->start == 0)
rhughes@241
   385
				next = end;
rhughes@241
   386
			else
rhughes@241
   387
				next = f->start;
rhughes@241
   388
		}
rhughes@241
   389
rhughes@241
   390
		file = r->data;
rhughes@241
   391
		if (e->start <= file && file < next) {
rhughes@241
   392
			len = strlen(prefix);
rhughes@241
   393
			prefix[len] = '/';
rhughes@241
   394
			strcpy(prefix + len + 1, pool + e->name);
rhughes@241
   395
			r = list_package_files(set, r, e, next, prefix);
rhughes@241
   396
			prefix[len] = '\0';
rhughes@241
   397
		}
rhughes@241
   398
	} while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL);
rhughes@241
   399
rhughes@241
   400
	return r;
rhughes@241
   401
}
rhughes@241
   402
rhughes@241
   403
void
rhughes@241
   404
razor_set_list_package_files(struct razor_set *set, const char *name)
rhughes@241
   405
{
rhughes@241
   406
	struct razor_package *package;
rhughes@241
   407
	struct list *r;
rhughes@241
   408
	uint32_t end;
rhughes@241
   409
	char buffer[512];
rhughes@241
   410
rhughes@241
   411
	package = razor_set_get_package(set, name);
rhughes@241
   412
rhughes@241
   413
	r = list_first(&package->files, &set->file_pool);
rhughes@241
   414
	end = set->files.size / sizeof (struct razor_entry);
rhughes@241
   415
	buffer[0] = '\0';
rhughes@241
   416
	list_package_files(set, r, set->files.data, end, buffer);
rhughes@241
   417
}
rhughes@241
   418
rhughes@241
   419
/* The diff order matters.  We should sort the packages so that a
rhughes@241
   420
 * REMOVE of a package comes before the INSTALL, and so that all
rhughes@241
   421
 * requires for a package have been installed before the package.
rhughes@241
   422
 **/
rhughes@241
   423
rhughes@241
   424
void
rhughes@241
   425
razor_set_diff(struct razor_set *set, struct razor_set *upstream,
krh@253
   426
	       razor_diff_callback_t callback, void *data)
rhughes@241
   427
{
rhughes@241
   428
 	struct razor_package_iterator *pi1, *pi2;
rhughes@241
   429
 	struct razor_package *p1, *p2;
rhughes@241
   430
	const char *name1, *name2, *version1, *version2, *arch1, *arch2;
rhughes@241
   431
	int res;
rhughes@241
   432
rhughes@241
   433
	pi1 = razor_package_iterator_create(set);
rhughes@241
   434
	pi2 = razor_package_iterator_create(upstream);
rhughes@241
   435
rhughes@241
   436
	razor_package_iterator_next(pi1, &p1, &name1, &version1, &arch1);
rhughes@241
   437
	razor_package_iterator_next(pi2, &p2, &name2, &version2, &arch2);
rhughes@241
   438
rhughes@241
   439
	while (p1 || p2) {
rhughes@241
   440
		if (p1 && p2) {
rhughes@241
   441
			res = strcmp(name1, name2);
rhughes@241
   442
			if (res == 0)
krh@248
   443
				res = razor_versioncmp(version1, version2);
rhughes@241
   444
		} else {
rhughes@241
   445
			res = 0;
rhughes@241
   446
		}
rhughes@241
   447
rhughes@241
   448
		if (p2 == NULL || res < 0)
krh@253
   449
			callback(RAZOR_DIFF_ACTION_REMOVE,
krh@253
   450
				 p1, name1, version1, arch1, data);
rhughes@241
   451
		else if (p1 == NULL || res > 0)
krh@253
   452
			callback(RAZOR_DIFF_ACTION_ADD,
krh@253
   453
				 p2, name2, version2, arch2, data);
rhughes@241
   454
rhughes@241
   455
		if (p1 != NULL && res <= 0)
rhughes@241
   456
			razor_package_iterator_next(pi1, &p1,
rhughes@241
   457
						    &name1, &version1, &arch1);
rhughes@241
   458
		if (p2 != NULL && res >= 0)
rhughes@241
   459
			razor_package_iterator_next(pi2, &p2,
rhughes@241
   460
						    &name2, &version2, &arch2);
rhughes@241
   461
	}
rhughes@241
   462
rhughes@241
   463
	razor_package_iterator_destroy(pi1);
rhughes@241
   464
	razor_package_iterator_destroy(pi2);
rhughes@241
   465
}
krh@254
   466
krh@254
   467
static void
krh@254
   468
add_new_package(enum razor_diff_action action,
krh@254
   469
		struct razor_package *package,
krh@254
   470
		const char *name,
krh@254
   471
		const char *version,
krh@254
   472
		const char *arch,
krh@254
   473
		void *data)
krh@254
   474
{
krh@254
   475
	if (action == RAZOR_DIFF_ACTION_ADD)
krh@254
   476
		razor_package_query_add_package(data, package);
krh@254
   477
}
krh@254
   478
krh@254
   479
struct razor_package_iterator *
krh@254
   480
razor_set_create_remove_iterator(struct razor_set *set,
krh@254
   481
				 struct razor_set *next)
krh@254
   482
{
krh@254
   483
	struct razor_package_query *query;
krh@254
   484
	struct razor_package_iterator *pi;
krh@254
   485
krh@254
   486
	query = razor_package_query_create(set);
krh@254
   487
	razor_set_diff(next, set, add_new_package, query);
krh@254
   488
krh@254
   489
	pi = razor_package_query_finish(query);
krh@254
   490
krh@254
   491
	/* FIXME: We need to figure out the right install order here,
krh@254
   492
	 * so the post and pre scripts can run. */
krh@254
   493
krh@254
   494
	/* sort */
krh@254
   495
krh@254
   496
	return pi;
krh@254
   497
}
krh@254
   498
krh@254
   499
struct razor_package_iterator *
krh@254
   500
razor_set_create_install_iterator(struct razor_set *set,
krh@254
   501
				  struct razor_set *next)
krh@254
   502
{
krh@254
   503
	struct razor_package_query *query;
krh@254
   504
	struct razor_package_iterator *pi;
krh@254
   505
krh@254
   506
	query = razor_package_query_create(next);
krh@254
   507
	razor_set_diff(set, next, add_new_package, query);
krh@254
   508
krh@254
   509
	pi = razor_package_query_finish(query);
krh@254
   510
krh@254
   511
	/* FIXME: We need to figure out the right install order here,
krh@254
   512
	 * so the post and pre scripts can run. */
krh@254
   513
krh@254
   514
	/* sort */
krh@254
   515
krh@254
   516
	return pi;
krh@254
   517
}