-Index: ask.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/ask.c,v
-retrieving revision 1.6
-retrieving revision 1.7
-diff -u -r1.6 -r1.7
---- ask.c 14 Apr 2003 16:28:09 -0000 1.6
-+++ ask.c 3 Nov 2005 00:16:58 -0000 1.7
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -92,13 +92,18 @@
- *p++ = 'a' + i;
- i++;
- }
-+ *p++ = 'Q';
-
-- msg(-1, _("Which one do you want to install? [%c]"), 'a' + default_i);
-+ msg(-1, _("Which one do you want to install ('Q' to abort)? [%c]"),
-+ 'a' + default_i);
- a = poldek_term_ask(STDIN_FILENO, validchrs, NULL);
- msg(-1, "_\n");
-
- if (a == '\n')
- return default_i;
-+
-+ if (a == 'Q')
-+ return -1;
-
- a -= 'a';
- //printf("Selected %d\n", a);
-Index: pkgset-install.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/pkgset-install.c,v
-retrieving revision 1.148
-retrieving revision 1.149
-diff -u -r1.148 -r1.149
---- pkgset-install.c 1 Nov 2005 19:36:36 -0000 1.148
-+++ pkgset-install.c 3 Nov 2005 00:21:00 -0000 1.149
-@@ -1243,7 +1249,8 @@
-
- DBGF("req %s\n", capreq_snprintf_s(req));
-
-- if (upg->ts->getop(upg->ts, POLDEK_OP_EQPKG_ASKUSER) && upg->ts->askpkg_fn)
-+ if (upg->ts->getop(upg->ts, POLDEK_OP_EQPKG_ASKUSER) &&
-+ upg->ts->askpkg_fn)
- tomark_candidates_ptr = &tomark_candidates;
-
- if (find_req(pkg, req, &tomark, tomark_candidates_ptr, ps, upg)) {
-@@ -1301,6 +1308,14 @@
- int n;
- n = upg->ts->askpkg_fn(capreq_snprintf_s(req),
- tomark_candidates, tomark);
-+
-+ if (n == -1) { /* user abort */
-+ free(tomark_candidates);
-+ tomark_candidates = NULL;
-+ upg->nerr_fatal++;
-+ return 0;
-+ }
-+
- real_tomark = tomark_candidates[n];
- free(tomark_candidates);
- tomark_candidates = NULL;
-@@ -1437,12 +1452,15 @@
-
- if (pkg->reqs)
- process_pkg_reqs(indent, pkg, ps, upg, process_as);
--
-+
- if (process_as == PROCESS_AS_NEW) {
- process_pkg_conflicts(indent, pkg, ps, upg);
- //process_pkg_obsl(pkg, ps, upg, indent);
- }
-
-+ if (upg->nerr_fatal || sigint_reached())
-+ return 0;
-+
- DBGF("END PROCESSING [%d] %s as %s\n", indent, pkg_id(pkg),
- process_as == PROCESS_AS_NEW ? "NEW" : "ORPHAN");
-
-@@ -1532,7 +1550,14 @@
- struct pkg *real_tomark = tomark;
- if (tomark_candidates) {
- int n;
-- n = upg->ts->askpkg_fn(capreq_snprintf_s(req), tomark_candidates, tomark);
-+ n = upg->ts->askpkg_fn(capreq_snprintf_s(req), tomark_candidates,
-+ tomark);
-+ if (n == -1) {
-+ n_cfree(&tomark_candidates);
-+ upg->nerr_fatal++;
-+ goto l_end;
-+ }
-+
- real_tomark = tomark_candidates[n];
- n_cfree(&tomark_candidates);
- }
-@@ -1808,6 +1833,9 @@
-
- db = upg->ts->db;
-
-+ if (upg->nerr_fatal || sigint_reached())
-+ return 0;
-+
- if (!upg->ts->getop(upg->ts, POLDEK_OP_CONFLICTS))
- return 1;
-
-@@ -1850,7 +1878,9 @@
- if (n)
- pkg_set_unmetdeps(upg->unmetpms, pkg);
- }
--
-+
-+ if (upg->nerr_fatal || sigint_reached())
-+ return 0;
-
- if (pkg->cnfls != NULL)
- for (i = 0; i < n_array_size(pkg->cnfls); i++) {
-@@ -2317,103 +2347,8 @@
- return nmarked;
- }
-
--static
--int prepare_icap(struct poldek_ts *ts, const char *capname, tn_array *pkgs)
--{
-- int i, found = 0;
-- tn_array *dbpkgs;
-- struct capreq *cap;
--
-- capreq_new_name_a(capname, cap);
-- dbpkgs = pkgdb_get_provides_dbpkgs(ts->db, cap, NULL, 0);
-- if (dbpkgs == NULL) {
-- struct pkg *pkg;
-- if (ts->getop(ts, POLDEK_OP_FRESHEN))
-- return 0;
--
-- n_array_sort_ex(pkgs, (tn_fn_cmp)pkg_cmp_name_evr_rev);
-- pkg = n_array_nth(pkgs, 0);
-- pkg_hand_mark(ts->pms, pkg);
-- return 1;
-- }
--
-- n_array_sort_ex(pkgs, (tn_fn_cmp)pkg_cmp_name_evr_rev);
-- for (i=0; i < n_array_size(dbpkgs); i++) {
-- struct pkg *dbpkg = n_array_nth(dbpkgs, i);
-- int n = n_array_bsearch_idx_ex(pkgs, dbpkg,
-- (tn_fn_cmp)pkg_cmp_name);
--
-- DBGF("%s: %s\n", capname, pkg_id(dbpkg));
--
-- if (n < 0)
-- continue;
--
-- for (; n < n_array_size(pkgs); n++) {
-- struct pkg *pkg = n_array_nth(pkgs, n);
-- int cmprc, mark = 0;
--
-- DBGF("%s: %s cmp %s\n", capname, pkg_id(pkg),
-- pkg_id(dbpkg));
-- if (pkg_cmp_name(pkg, dbpkg) != 0)
-- break;
--
-- cmprc = pkg_cmp_name_evr(pkg, dbpkg);
-- if (cmprc > 0)
-- mark = 1;
--
-- else if (cmprc == 0 && poldek_ts_issetf(ts, POLDEK_TS_REINSTALL))
-- mark = 1;
--
-- else if (cmprc < 0 && poldek_ts_issetf(ts, POLDEK_TS_DOWNGRADE))
-- mark = 1;
--
-- if (mark) {
-- found = 1;
-- msgn(1, _("%s: marked as %s's provider"), pkg_id(pkg),
-- capname);
--
-- pkg_hand_mark(ts->pms, pkg);
-- goto l_end;
--
-- } else if (cmprc <= 0) {
-- char *eqs = cmprc == 0 ? "equal" : "newer";
-- msgn(1, _("%s: %s version of %s is installed (%s), skipped"),
-- capname, eqs, pkg_id(dbpkg),
-- pkg_id(pkg));
--
-- } else {
-- n_assert(0);
--
-- }
-- }
-- }
--l_end:
-- if (dbpkgs)
-- n_array_free(dbpkgs);
--
-- return found;
--}
--
--static
--int prepare_icaps(struct poldek_ts *ts)
--{
-- tn_array *keys;
-- tn_hash *icaps;
-- int i;
--
-- icaps = arg_packages_get_resolved_caps(ts->aps);
-- keys = n_hash_keys_cp(icaps);
-- for (i=0; i < n_array_size(keys); i++) {
-- const char *cap = n_array_nth(keys, i);
-- tn_array *pkgs = n_hash_get(icaps, cap);
-- prepare_icap(ts, cap, pkgs);
-- }
-- n_array_free(keys);
-- n_hash_free(icaps);
-- return 1;
--}
--
--
-+/* use install/ in_prepare_icaps() */
-+extern int in_prepare_icaps(struct poldek_ts *ts);
-
- int do_poldek_ts_install(struct poldek_ts *ts, struct poldek_iinf *iinf)
- {
-@@ -2424,7 +2359,9 @@
-
- n_assert(ts->type == POLDEK_TS_INSTALL);
-
-- prepare_icaps(ts);
-+ if (in_prepare_icaps(ts) == -1) /* user abort */
-+ return 1;
-+
- if (unmark_name_dups(ts->pms, ps->pkgs) == 0) {
- msgn(1, _("Nothing to do"));
- return 1;
-Index: install/conflicts.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/conflicts.c,v
-retrieving revision 1.1
-retrieving revision 1.2
-diff -u -r1.1 -r1.2
---- install/conflicts.c 9 Jul 2005 17:51:18 -0000 1.1
-+++ install/conflicts.c 3 Nov 2005 00:21:05 -0000 1.2
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #include "ictx.h"
-@@ -96,10 +96,13 @@
- if (found) {
- struct pkg *real_tomark = tomark;
- if (tomark_candidates) {
-- int n;
-- n = ictx->ts->askpkg_fn(capreq_snprintf_s(req), tomark_candidates, tomark);
-- real_tomark = tomark_candidates[n];
-+ real_tomark = in_choose_equiv(ictx->ts, req, tomark_candidates,
-+ tomark);
- n_cfree(&tomark_candidates);
-+ if (real_tomark == NULL) { /* user aborts */
-+ ictx->nerr_fatal++;
-+ found = 0;
-+ }
- }
- tomark = real_tomark;
-
-Index: install/icaps.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/icaps.c,v
-retrieving revision 1.1
-retrieving revision 1.2
-diff -u -r1.1 -r1.2
---- install/icaps.c 9 Jul 2005 17:51:18 -0000 1.1
-+++ install/icaps.c 3 Nov 2005 00:21:05 -0000 1.2
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #include "ictx.h"
-@@ -25,13 +25,32 @@
-
- capreq_new_name_a(capname, cap);
- dbpkgs = pkgdb_get_provides_dbpkgs(ts->db, cap, NULL, 0);
-+
- if (dbpkgs == NULL) {
-- struct pkg *pkg;
-+ struct pkg *pkg = NULL;
-+
- if (ts->getop(ts, POLDEK_OP_FRESHEN))
- return 0;
-
- n_array_sort_ex(pkgs, (tn_fn_cmp)pkg_cmp_name_evr_rev);
-- pkg = n_array_nth(pkgs, 0);
-+
-+ if (ts->getop(ts, POLDEK_OP_EQPKG_ASKUSER) && ts->askpkg_fn && n_array_size(pkgs) > 1) {
-+ struct pkg **candidates = alloca(sizeof(struct pkg *) *
-+ (n_array_size(pkgs) + 1));
-+ for (i=0; i < n_array_size(pkgs); i++)
-+ candidates[i] = n_array_nth(pkgs, i);
-+ candidates[i] = NULL;
-+
-+ pkg = in_choose_equiv(ts, cap, candidates, NULL);
-+ if (pkg == NULL) { /* user aborts */
-+ found = -1;
-+ goto l_end;
-+ }
-+ }
-+
-+ if (pkg == NULL)
-+ pkg = n_array_nth(pkgs, 0);
-+
- pkg_hand_mark(ts->pms, pkg);
- return 1;
- }
-@@ -65,7 +84,7 @@
-
- else if (cmprc < 0 && poldek_ts_issetf(ts, POLDEK_TS_DOWNGRADE))
- mark = 1;
--
-+
- if (mark) {
- found = 1;
- msgn(1, _("%s: marked as %s's provider"), pkg_id(pkg),
-@@ -82,10 +101,10 @@
-
- } else {
- n_assert(0);
--
- }
- }
- }
-+
- l_end:
- if (dbpkgs)
- n_array_free(dbpkgs);
-@@ -93,20 +112,26 @@
- return found;
- }
-
-+/* handles --caplookup */
- int in_prepare_icaps(struct poldek_ts *ts)
- {
- tn_array *keys;
- tn_hash *icaps;
-- int i;
--
-+ int i, rc = 1;
-+
- icaps = arg_packages_get_resolved_caps(ts->aps);
- keys = n_hash_keys_cp(icaps);
- for (i=0; i < n_array_size(keys); i++) {
- const char *cap = n_array_nth(keys, i);
- tn_array *pkgs = n_hash_get(icaps, cap);
-- prepare_icap(ts, cap, pkgs);
-+
-+ if (prepare_icap(ts, cap, pkgs) == -1) {
-+ rc = -1;
-+ break;
-+ }
- }
-+
- n_array_free(keys);
- n_hash_free(icaps);
-- return 1;
-+ return rc;
- }
-Index: install/ictx.h
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/ictx.h,v
-retrieving revision 1.2
-retrieving revision 1.3
-diff -u -r1.2 -r1.3
---- install/ictx.h 20 Oct 2005 18:19:16 -0000 1.2
-+++ install/ictx.h 3 Nov 2005 00:21:05 -0000 1.3
-@@ -138,4 +138,7 @@
- int in_process_package(int indent, struct install_ctx *ictx,
- struct pkg *pkg, int process_as);
-
-+
-+struct pkg *in_choose_equiv(struct poldek_ts *ts, struct capreq *cap,
-+ struct pkg **candidates, struct pkg *defaultpkg);
- #endif
-Index: install/install.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/install.c,v
-retrieving revision 1.3
-retrieving revision 1.4
-diff -u -r1.3 -r1.4
---- install/install.c 15 Sep 2005 18:00:35 -0000 1.3
-+++ install/install.c 3 Nov 2005 00:21:05 -0000 1.4
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #include <vfile/vfile.h>
-@@ -352,7 +352,9 @@
- struct install_ctx ictx;
- n_assert(ts->type == POLDEK_TS_INSTALL);
-
-- in_prepare_icaps(ts);
-+ if (in_prepare_icaps(ts) < 0) /* user aborts, no error */
-+ return 1;
-+
- if (unmark_name_dups(ts->pms, ts->ctx->ps->pkgs) == 0) {
- msgn(1, _("Nothing to do"));
- return 1;
-Index: install/misc.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/misc.c,v
-retrieving revision 1.4
-retrieving revision 1.5
-diff -u -r1.4 -r1.5
---- install/misc.c 20 Oct 2005 17:57:51 -0000 1.4
-+++ install/misc.c 3 Nov 2005 00:18:36 -0000 1.5
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #include "ictx.h"
-@@ -439,7 +439,7 @@
-
- l_end:
-
-- if (candidates && nsuspkgs) {
-+ if (candidates && nsuspkgs > 1) {
- n_assert(suspkgs);
- *candidates = suspkgs;
-
-@@ -460,3 +460,16 @@
- ictx->uninst_set->dbpkgs);
- }
-
-+struct pkg *in_choose_equiv(struct poldek_ts *ts, struct capreq *cap,
-+ struct pkg **candidates, struct pkg *defaultpkg)
-+{
-+ int n;
-+
-+ if (defaultpkg == NULL)
-+ defaultpkg = candidates[0];
-+
-+ n = ts->askpkg_fn(capreq_snprintf_s(cap), candidates, defaultpkg);
-+ if (n == -1)
-+ return NULL;
-+ return candidates[n];
-+}
-Index: install/requirements.c
-===================================================================
-RCS file: /cvsroot/installer/poldek/install/requirements.c,v
-retrieving revision 1.3
-retrieving revision 1.4
-diff -u -r1.3 -r1.4
---- install/requirements.c 20 Oct 2005 18:19:16 -0000 1.3
-+++ install/requirements.c 3 Nov 2005 00:21:05 -0000 1.4
-@@ -11,7 +11,7 @@
- */
-
- /*
-- $Id$
-+ $Id$
- */
-
- #include "ictx.h"
-@@ -165,12 +165,15 @@
-
- struct pkg *real_tomark = tomark;
- if (tomark_candidates) {
-- int n;
-- n = ictx->ts->askpkg_fn(capreq_snprintf_s(req),
-- tomark_candidates, tomark);
-- real_tomark = tomark_candidates[n];
-+ real_tomark = in_choose_equiv(ictx->ts, req, tomark_candidates,
-+ tomark);
- free(tomark_candidates);
- tomark_candidates = NULL;
-+
-+ if (real_tomark == NULL) { /* user abort */
-+ ictx->nerr_fatal++;
-+ return 0;
-+ }
- }
-
- if (in_is_marked_for_removal_by_req(ictx, real_tomark, req)) {