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 = 3; + 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) {