From ccd495852c1f114e0dba295bc3d52ebfc041c810 Mon Sep 17 00:00:00 2001 From: Mariusz Mazur Date: Mon, 5 Jul 2004 10:24:22 +0000 Subject: [PATCH] - patch from mis for upgrading/installing through provides; needs testing Changed files: poldek-caplookup.patch -> 1.1 poldek.spec -> 1.156 --- poldek-caplookup.patch | 573 +++++++++++++++++++++++++++++++++++++++++ poldek.spec | 2 + 2 files changed, 575 insertions(+) create mode 100644 poldek-caplookup.patch diff --git a/poldek-caplookup.patch b/poldek-caplookup.patch new file mode 100644 index 0000000..12647cb --- /dev/null +++ b/poldek-caplookup.patch @@ -0,0 +1,573 @@ +Index: main.c +=================================================================== +RCS file: /cvsroot/installer/poldek/main.c,v +retrieving revision 1.110.4.14 +retrieving revision 1.110.4.15 +diff -u -r1.110.4.14 -r1.110.4.15 +--- main.c 6 Jun 2004 20:47:51 -0000 1.110.4.14 ++++ main.c 2 Jul 2004 17:42:39 -0000 1.110.4.15 +@@ -11,7 +11,7 @@ + */ + + /* +- $Id$ ++ $Id$ + */ + + #ifdef HAVE_CONFIG_H +@@ -223,8 +223,10 @@ + #define OPT_INST_DOWNGRADE 1058 + #define OPT_INST_UNIQNAMES 'Q' + +-#define OPT_RPMONLY_FORCE 1059 +-#define OPT_RPMONLY_NODEPS 1060 ++#define OPT_CAPLOOKUP 1059 ++#define OPT_RPMONLY_FORCE 1070 ++#define OPT_RPMONLY_NODEPS 1071 ++ + + #define OPT_UNINSTALL 'e' + +@@ -327,6 +329,9 @@ + {0,0,0,0, N_("Packages spec:"), 65}, + {"pset", OPT_PKGSET, "FILE", 0, N_("Take package set definition from FILE"), 65 }, + {"pkgset", 0, 0, OPTION_ALIAS | OPTION_HIDDEN, 0, 65 }, /* backward compat */ ++{"caplookup", OPT_CAPLOOKUP, 0, 0, ++ N_("Look into package capabilities & files to resolve packages"), 65 }, ++ + + // obsoleted by '#' + {"nevr", OPT_NEVR, "\"NAME [[E:][V[-R]]]\"", OPTION_HIDDEN, +@@ -385,7 +390,7 @@ + + {"nodeps", OPT_INST_NODEPS, 0, 0, + N_("Install packages with broken dependencies"), 71 }, +- ++ + {"force", OPT_INST_FORCE, 0, 0, + N_("Be unconcerned"), 71 }, + +@@ -560,6 +565,10 @@ + case OPT_PKGSET: + n_array_push(argsp->pkgdef_sets, arg); + break; ++ ++ case OPT_CAPLOOKUP: ++ argsp->inst.flags |= INSTS_CAPLOOKUP; ++ break; + + case 'l': + if (argsp->mjrmode != MODE_SRCLIST) +Index: pkgset-install.c +=================================================================== +RCS file: /cvsroot/installer/poldek/pkgset-install.c,v +retrieving revision 1.82.4.10 +retrieving revision 1.82.4.11 +diff -u -r1.82.4.10 -r1.82.4.11 +--- pkgset-install.c 22 Jun 2004 17:13:35 -0000 1.82.4.10 ++++ pkgset-install.c 2 Jul 2004 17:42:39 -0000 1.82.4.11 +@@ -11,7 +11,7 @@ + */ + + /* +- $Id$ ++ $Id$ + */ + + #ifdef HAVE_CONFIG_H +@@ -171,9 +171,11 @@ + logn(LOGERR, msg, pkg_snprintf_s(pkg), eqs, giveup); + install = -1; + +- } else if (is_hand_marked && !freshen) { /* msg without "freshen" */ +- msgn(0, msg, pkg_snprintf_s(pkg), eqs, skiped); +- ++ } else if (is_hand_marked) { ++ int vl = 0; ++ if (freshen) ++ vl = 1; ++ msgn(vl, msg, pkg_snprintf_s(pkg), eqs, skiped); + } + } + } +@@ -2331,11 +2333,10 @@ + } + } + +-static +-int unmark_name_dups(tn_array *pkgs) ++static int unmark_name_dups(tn_array *pkgs) + { + struct pkg *pkg, *pkg2; +- int i, n; ++ int i, n, nmarked; + + if (n_array_size(pkgs) < 2) + return 0; +@@ -2349,7 +2350,8 @@ + + if (!pkg_is_marked(pkg)) + continue; +- ++ ++ nmarked++; + DBGF("%s\n", pkg_snprintf_s(pkg)); + + +@@ -2360,6 +2362,7 @@ + + i++; + n++; ++ nmarked--; + if (i == n_array_size(pkgs)) + break; + pkg2 = n_array_nth(pkgs, i); +@@ -2367,9 +2370,100 @@ + } + } + +- return n; ++ return nmarked; ++} ++ ++static ++int prepare_icap(struct upgrade_s *upg, const char *capname, tn_array *pkgs) ++{ ++ int i, found = 0; ++ tn_array *dbpkgs; ++ struct capreq *cap = capreq_new_name_a(capname); ++ ++ dbpkgs = rpm_get_provides_dbpkgs(upg->inst->db->dbh, cap, NULL, 0); ++ if (dbpkgs == NULL) { ++ struct pkg *pkg; ++ if (upg->inst->flags & INSTS_FRESHEN) ++ return 0; ++ ++ pkg = n_array_nth(pkgs, 0); ++ pkg_hand_mark(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 dbpkg *dbpkg = n_array_nth(dbpkgs, i); ++ int n = n_array_bsearch_idx_ex(pkgs, dbpkg->pkg, ++ (tn_fn_cmp)pkg_cmp_name); ++ ++ DBGF("%s: %s\n", capname, pkg_snprintf_s0(dbpkg->pkg)); ++ ++ 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_snprintf_s(pkg), ++ pkg_snprintf_s0(dbpkg->pkg)); ++ if (pkg_cmp_name(pkg, dbpkg->pkg) != 0) ++ break; ++ ++ cmprc = pkg_cmp_name_evr(pkg, dbpkg->pkg); ++ if (cmprc > 0) ++ mark = 1; ++ ++ else if (cmprc == 0 && upg->inst->flags & INSTS_REINSTALL) ++ mark = 1; ++ ++ else if (cmprc < 0 && upg->inst->flags & INSTS_DOWNGRADE) ++ mark = 1; ++ ++ if (mark) { ++ found = 1; ++ msgn(1, "%s: marked as %s provider", pkg_snprintf_s(pkg), ++ capname); ++ ++ pkg_hand_mark(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_snprintf_s0(dbpkg->pkg), ++ pkg_snprintf_s(pkg)); ++ ++ } else { ++ n_assert(0); ++ ++ } ++ } ++ } ++l_end: ++ if (dbpkgs) ++ n_array_free(dbpkgs); ++ ++ return found; + } + ++static ++int prepare_icaps(struct upgrade_s *upg) ++{ ++ tn_array *keys; ++ int i; ++ ++ keys = n_hash_keys_cp(upg->inst->icaps); ++ for (i=0; i < n_array_size(keys); i++) { ++ const char *cap = n_array_nth(keys, i); ++ tn_array *pkgs = n_hash_get(upg->inst->icaps, cap); ++ prepare_icap(upg, cap, pkgs); ++ } ++ n_array_free(keys); ++ return 1; ++} + + int pkgset_install(struct pkgset *ps, struct inst_s *inst, + struct install_info *iinf) +@@ -2381,13 +2475,15 @@ + if (inst->flags & INSTS_INSTALL) + n_assert((inst->flags & INSTS_UPGRADE) == 0); + +- + packages_mark(ps->pkgs, 0, PKG_INTERNALMARK | PKG_INDIRMARK); + +- unmark_name_dups(ps->pkgs); +- +- mem_info(1, "ENTER pkgset_install:"); ++ mem_info(2, "ENTER pkgset_install:"); + init_upgrade_s(&upg, ps, inst); ++ prepare_icaps(&upg); ++ if (unmark_name_dups(ps->pkgs) == 0) { ++ msgn(1, _("Nothing to do")); ++ return 1; ++ } + + is_particle = inst->flags & INSTS_PARTICLE; + +@@ -2421,8 +2517,11 @@ + } + } + +- if (nmarked == 0) ++ if (nmarked == 0) { ++ msgn(1, _("Nothing to do")); + goto l_end; ++ } ++ + + if (nmarked == 1) + inst->flags &= ~INSTS_PARTICLE; +Index: pkgset.c +=================================================================== +RCS file: /cvsroot/installer/poldek/pkgset.c,v +retrieving revision 1.55.4.3 +retrieving revision 1.55.4.4 +diff -u -r1.55.4.3 -r1.55.4.4 +--- pkgset.c 6 Jun 2004 20:47:51 -0000 1.55.4.3 ++++ pkgset.c 2 Jul 2004 17:42:40 -0000 1.55.4.4 +@@ -11,7 +11,7 @@ + */ + + /* +- $Id$ ++ $Id$ + */ + + #include +@@ -150,6 +150,7 @@ + inst->rpmopts = n_array_new(4, free, (tn_fn_cmp)strcmp); + inst->hold_patterns = n_array_new(4, free, (tn_fn_cmp)strcmp); + inst->ign_patterns = n_array_new(4, free, (tn_fn_cmp)strcmp); ++ inst->icaps = n_hash_new(21, (tn_fn_free)n_array_free); + } + + struct pkgset *pkgset_new(unsigned optflags) +@@ -836,9 +837,40 @@ + return rc; + } + ++static int pkgset_mark_bycap(struct pkgset *ps, struct inst_s *inst, ++ const struct pkgdef *pdef) ++{ ++ tn_array *pkgs; ++ ++ n_assert(inst->flags & INSTS_CAPLOOKUP); ++ ++ pkgs = pkgset_lookup_cap(ps, pdef->pkg->name); ++ if (pkgs == NULL || n_array_size(pkgs) == 0) { ++ logn(LOGERR, _("mark: %s not found"), pdef->pkg->name); ++ if (pkgs) ++ n_array_free(pkgs); ++ return 0; ++ } ++ ++ if (verbose > 1) { ++ int i; ++ ++ msgn(2, "%s: %d package(s) found:", pdef->pkg->name, ++ n_array_size(pkgs)); ++ for (i=0; iicaps, pdef->pkg->name, pkgs); ++ return n_array_size(pkgs); ++} ++ ++ ++ + static +-int pkgset_mark_pkgdef_exact(struct pkgset *ps, const struct pkgdef *pdef, +- int nodeps) ++int pkgset_mark_pkgdef_exact(struct pkgset *ps, struct inst_s *inst, ++ const struct pkgdef *pdef, int nodeps) + { + int i, marked = 0, matched = 0; + struct pkg *pkg, tmpkg, *findedpkg; +@@ -851,10 +883,13 @@ + + i = n_array_bsearch_idx_ex(ps->pkgs, pdef->pkg, (tn_fn_cmp)pkg_cmp_name); + if (i < 0) { ++ if (inst->flags & INSTS_CAPLOOKUP) ++ return pkgset_mark_bycap(ps, inst, pdef); + logn(LOGERR, _("mark: %s not found"), pdef->pkg->name); + return 0; + } + ++ + findedpkg = pkg = n_array_nth(ps->pkgs, i); + + if (pkg_match_pkgdef(pkg, pdef)) { +@@ -877,9 +912,10 @@ + } + } + ++#if 0 + if (!marked && !matched) + logn(LOGERR, _("mark: %s: versions not match"), pdef->pkg->name); +- ++#endif + return marked; + } + +@@ -924,6 +960,29 @@ + return nerr; + } + ++static int pkgset_mark_verify_icaps(struct inst_s *inst) ++{ ++ tn_array *keys; ++ int i, j; ++ ++ keys = n_hash_keys_cp(inst->icaps); ++ for (i=0; iicaps, cap); ++ ++ for (j=0; j < n_array_size(pkgs); j++) { ++ struct pkg *pkg = n_array_nth(pkgs, j); ++ if (pkg_is_marked(pkg)) { ++ logn(LOGNOTICE, "%s: removed cap due to %s is marked", ++ cap, pkg_snprintf_s0(pkg)); ++ n_hash_remove(inst->icaps, cap); ++ break; ++ } ++ } ++ } ++ n_array_free(keys); ++ return n_hash_size(inst->icaps); ++} + + + int pkgset_mark_usrset(struct pkgset *ps, struct usrpkgset *ups, +@@ -931,6 +990,7 @@ + { + int i, nerr = 0, nodeps = 0, npatterns = 0; + ++ n_hash_clean(inst->icaps); + packages_mark(ps->pkgs, 0, PKG_INDIRMARK | PKG_DIRMARK); + //pkgset_mark(ps, PS_MARK_OFF_ALL); + +@@ -942,7 +1002,7 @@ + for (i=0; ipkgdefs); i++) { + struct pkgdef *pdef = n_array_nth(ups->pkgdefs, i); + if (pdef->tflags & (PKGDEF_REGNAME | PKGDEF_PKGFILE)) { +- if (!pkgset_mark_pkgdef_exact(ps, pdef, nodeps)) ++ if (!pkgset_mark_pkgdef_exact(ps, inst, pdef, nodeps)) + nerr++; + + } else if (pdef->tflags & PKGDEF_PATTERN) { +@@ -950,6 +1010,7 @@ + + } else if (pdef->tflags & PKGDEF_VIRTUAL) { /* VIRTUAL implies OPTIONAL */ + tn_array *avpkgs; ++ + + #if 0 + if (pdef->pkg == NULL) { +@@ -1010,7 +1071,7 @@ + if ((inst->flags & INSTS_CONFIRM_INST) && inst->ask_fn && + inst->ask_fn(0, "Install %s? [y/N]", pdef->pkg->name)); + #endif +- if (!pkgset_mark_pkgdef_exact(ps, pdef, nodeps)) ++ if (!pkgset_mark_pkgdef_exact(ps, inst, pdef, nodeps)) + nerr++; + + } else { +@@ -1036,7 +1097,8 @@ + logn(LOGERR, _("Buggy package set.")); + } + } +- ++ ++ pkgset_mark_verify_icaps(inst); + return nerr == 0; + } + +@@ -1056,8 +1118,40 @@ + return n_array_nth(ps->pkgs, i); + } + ++tn_array *pkgset_lookup_cap(struct pkgset *ps, const char *capname) ++{ ++ struct pkg **suspkgs, pkgsbuf[1024]; ++ int i, nsuspkgs = 0, found = 0; ++ tn_array *pkgs = NULL; ++ struct capreq *cap = capreq_new_name_a(capname); ++ ++ DBGF("%s\n", capname); ++ ++ found = psreq_lookup(ps, cap, &suspkgs, (struct pkg **)pkgsbuf, &nsuspkgs); ++ if (found && nsuspkgs) { ++ struct pkg **matches; ++ int nmatches = 0, strict; ++ ++ found = 0; ++ matches = alloca(sizeof(*matches) * nsuspkgs); ++ strict = ps->flags & PSVERIFY_MERCY ? 0 : 1; ++ if (psreq_match_pkgs(NULL, cap, strict, suspkgs, ++ nsuspkgs, matches, &nmatches)) { ++ found = 1; ++ pkgs = n_array_new(nmatches, NULL, ++ (tn_fn_cmp)pkg_cmp_name_evr_rev); ++ ++ if (nmatches > 0) { ++ for (i=0; i < nmatches; i++) ++ n_array_push(pkgs, matches[i]); ++ } ++ } ++ } ++ return pkgs; ++} ++ + +-tn_array *pkgset_lookup_cap(struct pkgset *ps, const char *capname) ++tn_array *pkgset_lookup_cap_OLD(struct pkgset *ps, const char *capname) + { + const struct capreq_idx_ent *ent; + tn_array *pkgs = NULL; +Index: pkgset.h +=================================================================== +RCS file: /cvsroot/installer/poldek/pkgset.h,v +retrieving revision 1.37.4.2 +retrieving revision 1.37.4.3 +diff -u -r1.37.4.2 -r1.37.4.3 +--- pkgset.h 16 Feb 2004 19:39:57 -0000 1.37.4.2 ++++ pkgset.h 2 Jul 2004 17:42:40 -0000 1.37.4.3 +@@ -1,4 +1,4 @@ +-/* $Id$ */ ++/* $Id$ */ + #ifndef POLDEK_PKGSET_H + #define POLDEK_PKGSET_H + +@@ -53,8 +53,8 @@ + #define INSTS_JUSTFETCH (1 << 10) + #define INSTS_JUSTPRINT (1 << 11) + #define INSTS_JUSTPRINT_N (1 << 12) /* names, not filenames */ +- + #define INSTS_JUSTPRINTS (INSTS_JUSTPRINT | INSTS_JUSTPRINT_N) ++#define INSTS_CAPLOOKUP (1 << 13) + + + #define INSTS_MKDBDIR (1 << 15) /* --mkdir */ +@@ -86,7 +86,8 @@ + tn_array *rpmopts; /* rpm cmdline opts (char *opts[]) */ + tn_array *rpmacros; /* rpm macros to pass to cmdline (char *opts[]) */ + tn_array *hold_patterns; +- tn_array *ign_patterns; ++ tn_array *ign_patterns; ++ tn_hash *icaps; + + int (*askpkg_fn)(const char *, struct pkg **pkgs, struct pkg *deflt); + int (*ask_fn)(int default_a, const char *, ...); +Index: rpm.c +=================================================================== +RCS file: /cvsroot/installer/poldek/Attic/rpm.c,v +retrieving revision 1.41.4.4 +retrieving revision 1.41.4.5 +diff -u -r1.41.4.4 -r1.41.4.5 +--- rpm.c 28 Jun 2004 20:18:39 -0000 1.41.4.4 ++++ rpm.c 2 Jul 2004 17:42:40 -0000 1.41.4.5 +@@ -11,7 +11,7 @@ + */ + + /* +- $Id$ ++ $Id$ + */ + + #ifdef HAVE_CONFIG_H +@@ -614,7 +614,7 @@ + + rpmdb_it_init(db, &it, RPMITER_CAP, capreq_name(cap)); + while ((dbrec = rpmdb_it_get(&it))) { +- if (dbpkg_array_has(unistdbpkgs, dbrec->recno)) ++ if (unistdbpkgs && dbpkg_array_has(unistdbpkgs, dbrec->recno)) + continue; + + if (dbpkgs == NULL) +Index: usrset.c +=================================================================== +RCS file: /cvsroot/installer/poldek/Attic/usrset.c,v +retrieving revision 1.12.6.1 +retrieving revision 1.12.6.2 +diff -u -r1.12.6.1 -r1.12.6.2 +--- usrset.c 30 Dec 2003 18:19:52 -0000 1.12.6.1 ++++ usrset.c 2 Jul 2004 17:42:40 -0000 1.12.6.2 +@@ -7,7 +7,7 @@ + */ + + /* +- $Id$ ++ $Id$ + */ + + #include +@@ -108,7 +108,7 @@ + if (*p == '\0' || *p == '#') + return 0; + +- while (*p && !isalnum(*p)) { ++ while (*p && !isalnum(*p) && *p != '/') { + switch (*p) { + case '~': + case '!': /* for backward compatybility */ +@@ -125,7 +125,7 @@ + p++; + } + +- if (!isalnum(*p)) { ++ if (!isalnum(*p) && *p != '/') { + if (nline > 0) + logn(LOGERR, _("%s:%d: syntax error"), fpath, nline); + else +@@ -168,7 +168,7 @@ + + + pdef = n_malloc(sizeof(*pdef) + +- (virtname ? strlen(virtname) + 1 : 0)); ++ (virtname ? strlen(virtname) + 1 : 0)); + pdef->tflags = tflags | deftyp; + + if (name == NULL) { diff --git a/poldek.spec b/poldek.spec index afdfc8d..0a444ed 100644 --- a/poldek.spec +++ b/poldek.spec @@ -22,6 +22,7 @@ Patch1: %{name}-retr_term.patch Patch2: %{name}-simplestatic.patch Patch3: %{name}-pkgorder.patch Patch4: %{name}-sigsegv.patch +Patch5: %{name}-caplookup.patch URL: http://team.pld.org.pl/~mis/poldek/ BuildRequires: automake BuildRequires: autoconf @@ -92,6 +93,7 @@ modu %patch2 -p0 %patch3 -p0 %patch4 -p0 +%patch5 -p0 %build %{__autopoint} -- 2.44.0