2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "razor-internal.h"
37 provider_satisfies_requirement(struct razor_property *provider,
38 const char *provider_strings,
43 const char *provided = &provider_strings[provider->version];
48 if (flags & RAZOR_PROPERTY_LESS)
54 cmp = razor_versioncmp(provided, required);
56 switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
57 case RAZOR_PROPERTY_LESS:
60 case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
63 /* fall through: FIXME, make sure this is correct */
65 case RAZOR_PROPERTY_EQUAL:
69 /* "foo == 1.1" is satisfied by "foo 1.1-2" */
70 len = strlen(required);
71 if (!strncmp(required, provided, len) && provided[len] == '-')
75 case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
78 case RAZOR_PROPERTY_GREATER:
82 /* shouldn't happen */
86 #define TRANS_PACKAGE_PRESENT 1
87 #define TRANS_PACKAGE_UPDATE 2
88 #define TRANS_PROPERTY_SATISFIED 0x80000000
90 struct transaction_set {
91 struct razor_set *set;
96 struct razor_transaction {
97 int package_count, errors;
98 struct transaction_set system, upstream;
100 struct razor_merger *merger;
104 transaction_set_init(struct transaction_set *ts, struct razor_set *set)
108 ts->set = razor_set_ref(set);
109 count = set->packages.size / sizeof (struct razor_package);
110 ts->packages = zalloc(count * sizeof *ts->packages);
111 count = set->properties.size / sizeof (struct razor_property);
112 ts->properties = zalloc(count * sizeof *ts->properties);
116 transaction_set_release(struct transaction_set *ts)
118 razor_set_unref(ts->set);
120 free(ts->properties);
124 transaction_set_install_package(struct transaction_set *ts,
125 struct razor_package *package)
127 struct razor_package *pkgs;
131 pkgs = ts->set->packages.data;
133 if (ts->packages[i] & TRANS_PACKAGE_PRESENT)
136 ts->packages[i] |= TRANS_PACKAGE_PRESENT;
138 prop = list_first(&package->properties, &ts->set->property_pool);
140 ts->properties[prop->data]++;
141 prop = list_next(prop);
146 transaction_set_remove_package(struct transaction_set *ts,
147 struct razor_package *package)
149 struct razor_package *pkgs;
153 pkgs = ts->set->packages.data;
155 if (!(ts->packages[i] & TRANS_PACKAGE_PRESENT))
158 ts->packages[i] &= ~TRANS_PACKAGE_PRESENT;
160 prop = list_first(&package->properties, &ts->set->property_pool);
162 ts->properties[prop->data]--;
163 prop = list_next(prop);
167 RAZOR_EXPORT struct razor_transaction *
168 razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
170 struct razor_transaction *trans;
171 struct razor_package *p, *spkgs, *pend;
173 trans = zalloc(sizeof *trans);
174 transaction_set_init(&trans->system, system);
175 transaction_set_init(&trans->upstream, upstream);
177 spkgs = trans->system.set->packages.data;
178 pend = trans->system.set->packages.data +
179 trans->system.set->packages.size;
180 for (p = spkgs; p < pend; p++)
181 transaction_set_install_package(&trans->system, p);
187 razor_transaction_install_package(struct razor_transaction *trans,
188 struct razor_package *package)
190 assert (trans != NULL);
191 assert (package != NULL);
193 transaction_set_install_package(&trans->upstream, package);
198 razor_transaction_remove_package(struct razor_transaction *trans,
199 struct razor_package *package)
201 assert (trans != NULL);
202 assert (package != NULL);
204 transaction_set_remove_package(&trans->system, package);
209 razor_transaction_update_package(struct razor_transaction *trans,
210 struct razor_package *package)
212 struct razor_package *spkgs, *upkgs, *end;
214 assert (trans != NULL);
215 assert (package != NULL);
217 spkgs = trans->system.set->packages.data;
218 upkgs = trans->upstream.set->packages.data;
219 end = trans->system.set->packages.data +
220 trans->system.set->packages.size;
221 if (spkgs <= package && package < end)
222 trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
224 trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
228 struct razor_property *p, *start, *end;
234 prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
236 pi->p = ts->set->properties.data;
237 pi->start = ts->set->properties.data;
238 pi->end = ts->set->properties.data + ts->set->properties.size;
239 pi->pool = ts->set->string_pool.data;
240 pi->present = ts->properties;
244 prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
246 while (pi->p < pi->end) {
247 if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
248 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
258 static struct razor_property *
259 prop_iter_seek_to(struct prop_iter *pi,
260 uint32_t flags, const char *match)
264 while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
267 if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
271 while (pi->p < pi->end &&
272 pi->p->name == name &&
273 (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
276 if (pi->p == pi->end || pi->p->name != name)
282 /* Remove packages from set that provide any of the matching (same
283 * name and type) providers from ppi onwards that match the
284 * requirement that rpi points to. */
286 remove_matching_providers(struct razor_transaction *trans,
287 struct prop_iter *ppi,
291 struct razor_property *p;
292 struct razor_package *pkg;
293 struct razor_package_iterator pkg_iter;
294 struct razor_set *set;
298 if (ppi->present == trans->system.properties)
299 set = trans->system.set;
301 set = trans->upstream.set;
303 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
306 p->name == ppi->p->name &&
307 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
309 if (!ppi->present[p - ppi->start])
311 if (!provider_satisfies_requirement(p, ppi->pool,
315 razor_package_iterator_init_for_property(&pkg_iter, set, p);
316 while (razor_package_iterator_next(&pkg_iter, &pkg,
317 RAZOR_DETAIL_NAME, &n,
318 RAZOR_DETAIL_VERSION, &v,
319 RAZOR_DETAIL_LAST)) {
321 fprintf(stderr, "removing %s-%s\n", n, v);
323 razor_transaction_remove_package(trans, pkg);
329 flag_matching_providers(struct razor_transaction *trans,
330 struct prop_iter *ppi,
331 struct razor_property *r,
332 struct prop_iter *rpi,
335 struct razor_property *p;
336 struct razor_package *pkg, *pkgs;
337 struct razor_package_iterator pkg_iter;
338 struct razor_set *set;
339 const char *name, *version;
340 uint32_t *flags, type;
342 if (ppi->present == trans->system.properties) {
343 set = trans->system.set;
344 flags = trans->system.packages;
346 set = trans->upstream.set;
347 flags = trans->upstream.packages;
350 pkgs = (struct razor_package *) set->packages.data;
351 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
354 p->name == ppi->p->name &&
355 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
357 if (!ppi->present[p - ppi->start])
359 if (!provider_satisfies_requirement(p, ppi->pool,
361 &rpi->pool[r->version]))
364 razor_package_iterator_init_for_property(&pkg_iter, set, p);
365 while (razor_package_iterator_next(&pkg_iter, &pkg,
366 RAZOR_DETAIL_NAME, &name,
367 RAZOR_DETAIL_VERSION, &version,
368 RAZOR_DETAIL_LAST)) {
371 fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
375 rpi->pool + r->version);
377 flags[pkg - pkgs] |= flag;
382 static struct razor_package *
383 pick_matching_provider(struct razor_set *set,
384 struct prop_iter *ppi,
388 struct razor_property *p;
389 struct razor_package *pkgs;
393 /* This is where we decide which pkgs to pull in to satisfy a
394 * requirement. There may be several different providers
395 * (different versions) and each version of a provider may
396 * come from a number of packages. We pick the first package
397 * from the first provider that matches. */
399 pkgs = set->packages.data;
400 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
403 p->name == ppi->p->name &&
404 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
405 ppi->present[p - ppi->start] == 0;
407 if (!provider_satisfies_requirement(p, ppi->pool,
411 i = list_first(&p->packages, &set->package_pool);
413 return &pkgs[i->data];
420 remove_obsoleted_packages(struct razor_transaction *trans)
422 struct razor_property *up;
423 struct prop_iter spi, upi;
425 prop_iter_init(&spi, &trans->system);
426 prop_iter_init(&upi, &trans->upstream);
428 while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
429 if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
430 &upi.pool[up->name]))
432 remove_matching_providers(trans, &spi, up->flags,
433 &upi.pool[up->version]);
438 any_provider_satisfies_requirement(struct prop_iter *ppi,
442 struct razor_property *p;
445 type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
448 p->name == ppi->p->name &&
449 (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
451 if (ppi->present[p - ppi->start] > 0 &&
452 provider_satisfies_requirement(p, ppi->pool,
461 clear_requires_flags(struct transaction_set *ts)
463 struct razor_property *p;
468 count = ts->set->properties.size / sizeof *p;
469 p = ts->set->properties.data;
470 pool = ts->set->string_pool.data;
471 for (i = 0; i < count; i++) {
472 ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
473 sub = strchr(&pool[p[i].name], '(');
474 if (sub && sub[strlen(sub) - 1] == ')') {
475 sub = strdup(sub + 1);
476 sub[strlen(sub) - 1] = '\0';
477 if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
478 ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
479 if (strncmp(&pool[p[i].name], "lua(", 4) == 0 &&
480 razor_get_lua_loader(sub) &&
481 p[i].flags & RAZOR_PROPERTY_SCRIPT_MASK)
482 ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
489 mark_satisfied_requires(struct razor_transaction *trans,
490 struct transaction_set *rts,
491 struct transaction_set *pts)
493 struct prop_iter rpi, ppi;
494 struct razor_property *rp;
496 prop_iter_init(&rpi, rts);
497 prop_iter_init(&ppi, pts);
499 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
500 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
501 &rpi.pool[rp->name]))
504 if (any_provider_satisfies_requirement(&ppi, rp->flags,
505 &rpi.pool[rp->version]))
506 rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
511 mark_all_satisfied_requires(struct razor_transaction *trans)
513 clear_requires_flags(&trans->system);
514 clear_requires_flags(&trans->upstream);
515 mark_satisfied_requires(trans, &trans->system, &trans->system);
516 mark_satisfied_requires(trans, &trans->system, &trans->upstream);
517 mark_satisfied_requires(trans, &trans->upstream, &trans->system);
518 mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
522 update_unsatisfied_packages(struct razor_transaction *trans)
524 struct razor_package *spkgs, *pkg;
525 struct razor_property *sp;
526 struct prop_iter spi;
527 struct razor_package_iterator pkg_iter;
530 spkgs = trans->system.set->packages.data;
531 prop_iter_init(&spi, &trans->system);
533 while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
534 if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
537 razor_package_iterator_init_for_property(&pkg_iter,
540 while (razor_package_iterator_next(&pkg_iter, &pkg,
541 RAZOR_DETAIL_NAME, &name,
542 RAZOR_DETAIL_LAST)) {
543 if (!(trans->system.packages[pkg - spkgs] & TRANS_PACKAGE_PRESENT))
547 fprintf(stderr, "updating %s because %s %s %s "
549 name, spi.pool + sp->name,
550 razor_property_relation_to_string(sp),
551 spi.pool + sp->version);
553 trans->system.packages[pkg - spkgs] |=
554 TRANS_PACKAGE_UPDATE;
560 razor_transaction_update_all(struct razor_transaction *trans)
562 struct razor_package *p;
565 assert (trans != NULL);
567 count = trans->system.set->packages.size / sizeof *p;
568 for (i = 0; i < count; i++)
569 trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
573 update_conflicted_packages(struct razor_transaction *trans)
575 struct razor_package *pkg, *spkgs;
576 struct razor_property *up, *sp;
577 struct prop_iter spi, upi;
578 struct razor_package_iterator pkg_iter;
579 const char *name, *version;
581 spkgs = trans->system.set->packages.data;
582 prop_iter_init(&spi, &trans->system);
583 prop_iter_init(&upi, &trans->upstream);
585 while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
586 if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
587 &spi.pool[sp->name]))
590 if (!any_provider_satisfies_requirement(&upi, sp->flags,
591 &spi.pool[sp->version]))
594 razor_package_iterator_init_for_property(&pkg_iter,
597 while (razor_package_iterator_next(&pkg_iter, &pkg,
598 RAZOR_DETAIL_NAME, &name,
599 RAZOR_DETAIL_VERSION, &version,
600 RAZOR_DETAIL_LAST)) {
602 fprintf(stderr, "updating %s %s because it "
603 "conflicts with %s\n",
604 name, version, spi.pool + sp->name);
606 trans->system.packages[pkg - spkgs] |=
607 TRANS_PACKAGE_UPDATE;
611 prop_iter_init(&spi, &trans->system);
612 prop_iter_init(&upi, &trans->upstream);
614 while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
615 sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
616 &upi.pool[upi.p->name]);
619 flag_matching_providers(trans, &spi, up, &upi,
620 TRANS_PACKAGE_UPDATE);
625 pull_in_requirements(struct razor_transaction *trans,
626 struct prop_iter *rpi, struct prop_iter *ppi)
628 struct razor_property *rp, *pp;
629 struct razor_package *pkg, *upkgs;
631 upkgs = trans->upstream.set->packages.data;
632 while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
633 if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
636 pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
637 &rpi->pool[rp->name]);
640 pkg = pick_matching_provider(trans->upstream.set,
642 &rpi->pool[rp->version]);
646 rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
649 fprintf(stderr, "pulling in %s-%s.%s which provides %s %s %s "
650 "to satisfy %s %s %s\n",
651 ppi->pool + pkg->name,
652 ppi->pool + pkg->version,
653 ppi->pool + pkg->arch,
654 ppi->pool + pp->name,
655 razor_property_relation_to_string(pp),
656 ppi->pool + pp->version,
657 &rpi->pool[rp->name],
658 razor_property_relation_to_string(rp),
659 &rpi->pool[rp->version]);
662 trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
667 pull_in_all_requirements(struct razor_transaction *trans)
669 struct prop_iter rpi, ppi;
671 prop_iter_init(&rpi, &trans->system);
672 prop_iter_init(&ppi, &trans->upstream);
673 pull_in_requirements(trans, &rpi, &ppi);
675 prop_iter_init(&rpi, &trans->upstream);
676 prop_iter_init(&ppi, &trans->upstream);
677 pull_in_requirements(trans, &rpi, &ppi);
681 flush_scheduled_system_updates(struct razor_transaction *trans)
683 struct razor_package_iterator *pi;
684 struct razor_package *p, *pkg, *spkgs;
685 struct prop_iter ppi;
686 const char *name, *version;
688 spkgs = trans->system.set->packages.data;
689 pi = razor_package_iterator_create(trans->system.set);
690 prop_iter_init(&ppi, &trans->upstream);
692 while (razor_package_iterator_next(pi, &p,
693 RAZOR_DETAIL_NAME, &name,
694 RAZOR_DETAIL_VERSION, &version,
695 RAZOR_DETAIL_LAST)) {
696 if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
698 trans->system.packages[p - spkgs] &= ~TRANS_PACKAGE_UPDATE;
700 if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
703 if (any_provider_satisfies_requirement(&ppi,
704 RAZOR_PROPERTY_GREATER,
706 razor_transaction_remove_package(trans, p);
710 pkg = pick_matching_provider(trans->upstream.set, &ppi,
711 RAZOR_PROPERTY_GREATER, version);
715 razor_transaction_remove_package(trans, p);
716 razor_transaction_install_package(trans, pkg);
719 razor_package_iterator_destroy(pi);
723 flush_scheduled_upstream_updates(struct razor_transaction *trans)
725 struct razor_package_iterator *pi;
726 struct razor_package *p, *upkgs;
727 struct prop_iter spi;
728 const char *name, *version;
730 upkgs = trans->upstream.set->packages.data;
731 pi = razor_package_iterator_create(trans->upstream.set);
732 prop_iter_init(&spi, &trans->system);
734 while (razor_package_iterator_next(pi, &p,
735 RAZOR_DETAIL_NAME, &name,
736 RAZOR_DETAIL_VERSION, &version,
737 RAZOR_DETAIL_LAST)) {
738 if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
740 trans->upstream.packages[p - upkgs] &= ~TRANS_PACKAGE_UPDATE;
742 if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
743 remove_matching_providers(trans,
747 razor_transaction_install_package(trans, p);
749 fprintf(stderr, "installing %s-%s\n", name, version);
753 razor_package_iterator_destroy(pi);
757 razor_transaction_resolve(struct razor_transaction *trans)
761 flush_scheduled_system_updates(trans);
762 flush_scheduled_upstream_updates(trans);
764 while (last < trans->changes) {
765 last = trans->changes;
766 remove_obsoleted_packages(trans);
767 mark_all_satisfied_requires(trans);
768 update_unsatisfied_packages(trans);
769 update_conflicted_packages(trans);
770 pull_in_all_requirements(trans);
771 flush_scheduled_system_updates(trans);
772 flush_scheduled_upstream_updates(trans);
775 return trans->changes;
779 describe_unsatisfied(struct razor_set *set, struct razor_property *rp,
780 razor_unsatisfied_callback_t callback, void *data)
782 struct razor_package_iterator pi;
783 struct razor_package *pkg;
784 const char *name, *version, *arch, *pool;
785 const char *requirement;
788 pool = set->string_pool.data;
789 if (pool[rp->version] == '\0')
790 requirement = &pool[rp->name];
792 s = razor_concat(&pool[rp->name], " ",
793 razor_property_relation_to_string(rp), " ",
794 &pool[rp->version], NULL);
798 razor_package_iterator_init_for_property(&pi, set, rp);
799 while (razor_package_iterator_next(&pi, &pkg,
800 RAZOR_DETAIL_NAME, &name,
801 RAZOR_DETAIL_VERSION, &version,
802 RAZOR_DETAIL_ARCH, &arch,
804 callback(requirement, pkg, name, version, arch, data);
811 razor_transaction_unsatisfied(struct razor_transaction *trans,
812 razor_unsatisfied_callback_t callback, void *data)
814 struct prop_iter rpi;
815 struct razor_property *rp;
818 flush_scheduled_system_updates(trans);
819 flush_scheduled_upstream_updates(trans);
820 mark_all_satisfied_requires(trans);
823 prop_iter_init(&rpi, &trans->system);
824 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
825 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
827 describe_unsatisfied(trans->system.set, rp,
833 prop_iter_init(&rpi, &trans->upstream);
834 while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
835 if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
837 describe_unsatisfied(trans->upstream.set, rp,
847 describe_unsatisfied_callback(const char *requirement,
848 struct razor_package *package, const char *name,
849 const char *version, const char *arch, void *data)
853 fprintf(fp, "%s is needed by %s-%s.%s\n", requirement,
854 name, version, arch);
858 razor_transaction_describe(struct razor_transaction *trans)
860 return razor_transaction_unsatisfied(trans,
861 describe_unsatisfied_callback,
866 razor_transaction_unsatisfied_property(struct razor_transaction *trans,
872 struct razor_property *p;
874 prop_iter_init(&pi, &trans->system);
875 while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
876 if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
878 strcmp(&pi.pool[p->name], name) == 0 &&
879 strcmp(&pi.pool[p->version], version) == 0)
884 prop_iter_init(&pi, &trans->upstream);
885 while (prop_iter_next(&pi, flags & RAZOR_PROPERTY_TYPE_MASK, &p)) {
886 if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
888 strcmp(&pi.pool[p->name], name) == 0 &&
889 strcmp(&pi.pool[p->version], version) == 0)
897 RAZOR_EXPORT struct razor_set *
898 razor_transaction_commit(struct razor_transaction *trans)
900 struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
904 s = trans->system.set->packages.data;
905 spkgs = trans->system.set->packages.data;
906 send = trans->system.set->packages.data +
907 trans->system.set->packages.size;
908 spool = trans->system.set->string_pool.data;
910 u = trans->upstream.set->packages.data;
911 upkgs = trans->upstream.set->packages.data;
912 uend = trans->upstream.set->packages.data +
913 trans->upstream.set->packages.size;
914 upool = trans->upstream.set->string_pool.data;
916 trans->merger = razor_merger_create(trans->system.set,
917 trans->upstream.set);
918 while (s < send || u < uend) {
919 if (s < send && u < uend)
920 cmp = strcmp(&spool[s->name], &upool[u->name]);
927 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
928 razor_merger_add_package(trans->merger, s);
930 } else if (cmp == 0) {
931 if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
932 razor_merger_add_package(trans->merger, s);
933 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
934 razor_merger_add_package(trans->merger, u);
939 if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
940 razor_merger_add_package(trans->merger, u);
945 return razor_merger_commit(trans->merger);
949 razor_transaction_fixup_package(struct razor_transaction *trans,
950 struct razor_package *package,
951 struct razor_rpm *rpm)
953 const char *preunprog, *preun, *postunprog, *postun;
955 razor_rpm_get_details(rpm,
956 RAZOR_DETAIL_PREUNPROG, &preunprog,
957 RAZOR_DETAIL_PREUN, &preun,
958 RAZOR_DETAIL_POSTUNPROG, &postunprog,
959 RAZOR_DETAIL_POSTUN, &postun,
962 razor_merger_package_add_script(trans->merger, package,
963 RAZOR_PROPERTY_PREUN,
965 razor_merger_package_add_script(trans->merger, package,
966 RAZOR_PROPERTY_POSTUN,
971 razor_transaction_destroy(struct razor_transaction *trans)
973 assert (trans != NULL);
976 razor_merger_destroy(trans->merger);
977 transaction_set_release(&trans->system);
978 transaction_set_release(&trans->upstream);