poldek: poldek/install3/.cvsignore (NEW), poldek/install3/Makefile...
mis
mis at pld-linux.org
Wed Jan 23 23:56:24 CET 2008
Author: mis Date: Wed Jan 23 22:56:24 2008 GMT
Module: poldek Tag: HEAD
---- Log message:
- refactored, improved depsolver (NFY)
---- Files affected:
poldek/poldek/install3:
.cvsignore (NONE -> 1.1) (NEW), Makefile.am (NONE -> 1.1) (NEW), conflicts.c (NONE -> 1.1) (NEW), ictx.c (NONE -> 1.1) (NEW), ictx.h (NONE -> 1.1) (NEW), install.c (NONE -> 1.1) (NEW), install.h (NONE -> 1.1) (NEW), iset.c (NONE -> 1.1) (NEW), iset.h (NONE -> 1.1) (NEW), mark.c (NONE -> 1.1) (NEW), misc.c (NONE -> 1.1) (NEW), obsoletes.c (NONE -> 1.1) (NEW), preinstall.c (NONE -> 1.1) (NEW), process.c (NONE -> 1.1) (NEW), requirements.c (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: poldek/poldek/install3/.cvsignore
diff -u /dev/null poldek/poldek/install3/.cvsignore:1.1
--- /dev/null Wed Jan 23 23:56:24 2008
+++ poldek/poldek/install3/.cvsignore Wed Jan 23 23:56:18 2008
@@ -0,0 +1,6 @@
+Makefile.in
+Makefile
+.deps
+*.lo
+.libs
+*.la
================================================================
Index: poldek/poldek/install3/Makefile.am
diff -u /dev/null poldek/poldek/install3/Makefile.am:1.1
--- /dev/null Wed Jan 23 23:56:24 2008
+++ poldek/poldek/install3/Makefile.am Wed Jan 23 23:56:19 2008
@@ -0,0 +1,25 @@
+# $Id$
+
+INCLUDES = @TRURL_INCLUDE@ @TNDB_INCLUDE@ -I$(top_srcdir)
+AM_CFLAGS = @AM_CFLAGS@
+
+LIBS=
+noinst_LTLIBRARIES = libinstall3.la
+libinstall3_la_SOURCES = install.h install.c \
+ iset.c iset.h \
+ ictx.c ictx.h mark.c misc.c \
+ conflicts.c preinstall.c \
+ obsoletes.c requirements.c \
+ process.c
+
+dist-hook:
+ rm -rf $(distdir)/.deps
+
+clean-local:
+ -rm -f core *.o *.bak *~ *% *\# TAGS gmon.out \#* *\#
+
+
+MAINTAINERCLEANFILES = mkinstalldirs install-sh missing *.tar.gz *.spec \
+ config.h.in configure Makefile.in config.h \
+ config.sub config.guess aclocal.m4 \
+ libtool ltconfig ltmain.sh stamp-h* depcomp *.1
================================================================
Index: poldek/poldek/install3/conflicts.c
diff -u /dev/null poldek/poldek/install3/conflicts.c:1.1
--- /dev/null Wed Jan 23 23:56:24 2008
+++ poldek/poldek/install3/conflicts.c Wed Jan 23 23:56:19 2008
@@ -0,0 +1,308 @@
+/*
+ Copyright (C) 2000 - 2008 Pawel A. Gajda <mis at pld-linux.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2 as
+ published by the Free Software Foundation (see file COPYING for details).
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ $Id$
+*/
+
+#include "ictx.h"
+
+static
+int find_replacement(struct i3ctx *ictx, struct pkg *pkg,
+ struct pkg **rpkg)
+{
+ tn_array *pkgs;
+ struct pkgset *ps;
+ int i;
+
+ ps = ictx->ts->ctx->ps;
+ *rpkg = NULL;
+
+ /* simply higest version */
+ if ((pkgs = pkgset_search(ps, PS_SEARCH_NAME, pkg->name))) {
+ for (i=0; i < n_array_size(pkgs); i++) {
+ struct pkg *p = n_array_nth(pkgs, i);
+ if (!pkg_is_kind_of(p, pkg))
+ continue;
+
+ if (pkg_cmp_evr(p, pkg) > 0) {
+ *rpkg = p;
+ break;
+ }
+ }
+ }
+
+ if (*rpkg == NULL && (pkgs = pkgset_search(ps, PS_SEARCH_OBSL, pkg->name))) {
+ for (i=0; i < n_array_size(pkgs); i++) {
+ struct pkg *p = n_array_nth(pkgs, i);
+ if (pkg_caps_obsoletes_pkg_caps(p, pkg) &&
+ pkg_cmp_name_evr(p, pkg) > 0) { /* XXX bug propably, testit */
+ *rpkg = p;
+ break;
+ }
+ }
+ n_array_free(pkgs);
+ }
+
+ if (*rpkg && i3_is_marked(ictx, *rpkg)) {
+ *rpkg = NULL;
+ return 1;
+ }
+
+ return (*rpkg != NULL);
+}
+
+/* trying to resolve conflict by package upgrade */
+static int resolve_conflict(int indent, struct i3ctx *ictx,
+ struct pkg *pkg, const struct capreq *cnfl,
+ struct pkg *dbpkg)
+{
+ struct capreq *req = NULL;
+ struct pkg *tomark = NULL;
+ tn_array *candidates = NULL;
+ int found = 0, by_replacement = 0;
+
+ if (!ictx->ts->getop(ictx->ts, POLDEK_OP_FOLLOW))
+ return 0;
+
+ if (!capreq_versioned(cnfl))
+ return 0;
+
+ req = capreq_clone(NULL, cnfl);
+
+#if 0 /* debug */
+ printf("B %s -> ", capreq_snprintf_s(req));
+ capreq_revrel(req);
+ printf("%s -> ", capreq_snprintf_s(req));
+ capreq_revrel(req);
+ printf("%s\n", capreq_snprintf_s(req));
+#endif
+
+ DBGF("find_req %s %s\n", pkg_id(pkg), capreq_snprintf_s(req));
+ capreq_revrel(req);
+ DBGF("find_req %s %s\n", pkg_id(pkg), capreq_snprintf_s(req));
+
+ if (i3_is_user_choosable_equiv(ictx->ts))
+ candidates = pkgs_array_new(8);
+
+ found = i3_find_req(indent, ictx, pkg, req, &tomark, candidates);
+ capreq_revrel(req);
+
+ if (!found) {
+ found = find_replacement(ictx, dbpkg, &tomark);
+ by_replacement = 1;
+
+ } else {
+ struct pkg *real_tomark = tomark;
+
+ /* tomark == NULL ? req satsfied by already installed set */
+ if (tomark && candidates && n_array_size(candidates) > 1) {
+ real_tomark = i3_choose_equiv(ictx->ts, req, candidates, tomark);
+ n_array_cfree(&candidates);
+ if (real_tomark == NULL) { /* user aborts */
+ ictx->abort = 1;
+ found = 0;
+ }
+ }
+ tomark = real_tomark;
+ }
+
+ if (!found)
+ goto l_end;
+
+ if (tomark == NULL) /* already in inset */
+ goto l_end;
+
+ found = 0;
+ if (by_replacement || pkg_obsoletes_pkg(tomark, dbpkg)) {
+ struct i3pkg *i3tomark;
+
+ found = 1;
+ i3tomark = i3pkg_new(tomark, 0, pkg, req, I3PKGBY_REQ);
+ i3_process_package(indent, ictx, i3tomark);
+ }
+
+l_end:
+ n_array_cfree(&candidates);
+ capreq_free(req);
+ return found;
+}
+
+
+/* check if cnfl conflicts with db */
+static
+int find_db_conflicts_cnfl_with_db(int indent, struct i3ctx *ictx,
+ struct pkg *pkg, const struct capreq *cnfl)
+{
+ int i, ncnfl = 0;
+ tn_hash *ht = NULL;
+ tn_array *dbpkgs = NULL;
+
+ pkgdb_search(ictx->ts->db, &dbpkgs, PMTAG_CAP, capreq_name(cnfl),
+ iset_packages(ictx->unset), PKG_LDWHOLE_FLDEPDIRS);
+
+ if (dbpkgs == NULL)
+ return 0;
+
+ msgn_i(4, indent, "Processing conflict %s:%s...", pkg_id(pkg),
+ capreq_snprintf_s(cnfl));
+
+ if (ictx->ts->getop(ictx->ts, POLDEK_OP_ALLOWDUPS) &&
+ n_array_size(dbpkgs) > 1) {
+
+ ht = n_hash_new(21, NULL);
+ n_hash_ctl(ht, TN_HASH_NOCPKEY);
+
+ for (i=0; i<n_array_size(dbpkgs); i++) {
+ struct pkg *dbpkg = n_array_nth(dbpkgs, i);
+ if (n_hash_exists(ht, dbpkg->name))
+ continue;
+
+ if (!pkg_match_req(dbpkg, cnfl, 1)) {
+ msgn_i(5, indent, "%s: conflict disarmed by %s",
+ capreq_snprintf_s(cnfl), pkg_id(dbpkg));
+ n_hash_insert(ht, dbpkg->name, pkg);
+ }
+ }
+ }
+
+ for (i=0; i < n_array_size(dbpkgs); i++) {
+ struct pkg *dbpkg = n_array_nth(dbpkgs, i);
+
+ msg_i(6, indent, "%d. %s (%s) <-> %s ?\n", i, pkg_id(pkg),
+ capreq_snprintf_s(cnfl), pkg_id(dbpkg));
+
+ if (ht && n_hash_exists(ht, dbpkg->name))
+ continue;
+
+ if (poldek_conf_MULTILIB && !pkg_is_colored_like(pkg, dbpkg))
+ continue;
+
+ if (pkg_match_req(dbpkg, cnfl, 1)) {
+ if (!resolve_conflict(indent, ictx, pkg, cnfl, dbpkg)) {
+ i3_error(ictx, pkg, I3ERR_DBCONFLICT,
+ _("%s (cnfl %s) conflicts with installed %s"),
+ pkg_id(pkg), capreq_snprintf_s(cnfl), pkg_id(dbpkg));
+
+ logn(LOGERR, _("%s (cnfl %s) conflicts with installed %s"),
+ pkg_id(pkg), capreq_snprintf_s(cnfl), pkg_id(dbpkg));
+ ncnfl++;
+ }
+ }
+ }
+
+ if (ht)
+ n_hash_free(ht);
+
+ n_array_free(dbpkgs);
+
+ return ncnfl;
+}
+
+/* check if db conflicts with cap */
+static
+int find_db_conflicts_dbcnfl_with_cap(int indent, struct i3ctx *ictx,
+ struct pkg *pkg, const struct capreq *cap)
+{
+ int i, j, ncnfl = 0;
+ tn_array *dbpkgs = NULL;
+
+ pkgdb_search(ictx->ts->db, &dbpkgs, PMTAG_CNFL, capreq_name(cap),
+ iset_packages(ictx->unset), PKG_LDWHOLE_FLDEPDIRS);
+
+ if (dbpkgs == NULL)
+ return 0;
+
+ for (i = 0; i < n_array_size(dbpkgs); i++) {
+ struct pkg *dbpkg = n_array_nth(dbpkgs, i);
+
+ msg(6, "%s (%s) <-> %s ?\n", pkg_id(pkg),
+ capreq_snprintf_s(cap), pkg_id(dbpkg));
+
+ for (j = 0; j < n_array_size(dbpkg->cnfls); j++) {
+ struct capreq *cnfl = n_array_nth(dbpkg->cnfls, j);
+ if (cap_match_req(cap, cnfl, 1)) {
+ if (resolve_conflict(indent, ictx, pkg, cnfl, dbpkg))
+ continue;
+
+ i3_error(ictx, pkg, I3ERR_DBCONFLICT,
+ _("%s (cap %s) conflicts with installed %s (%s)"),
+ pkg_id(pkg), capreq_snprintf_s(cap),
+ pkg_id(dbpkg), capreq_snprintf_s0(cnfl));
+ ncnfl++;
+ }
+ }
+ }
+
+ n_array_free(dbpkgs);
+ return ncnfl;
+}
+
+int i3_process_pkg_conflicts(int indent, struct i3ctx *ictx, struct i3pkg *i3pkg)
+{
+ struct pkgdb *db;
+ struct pkg *pkg = i3pkg->pkg;
+ int i, n, ncnfl = 0;
+
+ db = ictx->ts->db;
+
+ if (!ictx->ts->getop(ictx->ts, POLDEK_OP_CONFLICTS))
+ return 1;
+
+ /* conflicts in install set */
+ if (pkg->cnflpkgs != NULL)
+ for (i = 0; i < n_array_size(pkg->cnflpkgs); i++) {
+ struct reqpkg *cpkg = n_array_nth(pkg->cnflpkgs, i);
+
+ if ((cpkg->flags & REQPKG_CONFLICT) == 0)
+ continue;
+
+ if (i3_is_marked(ictx, cpkg->pkg)) {
+ i3_error(ictx, pkg, I3ERR_CONFLICT, _("%s conflicts with %s"),
+ pkg_id(pkg), pkg_id(cpkg->pkg));
+ ncnfl++;
+ }
+ }
+
+
+ /* conflicts with db packages */
+
+ for (i = 0; i < n_array_size(pkg->caps); i++) {
+ struct capreq *cap = n_array_nth(pkg->caps, i);
+
+ if ((ictx->ps->flags & PSET_VRFY_MERCY) && capreq_is_bastard(cap))
+ continue;
+
+ msg_i(3, indent, "cap %s\n", capreq_snprintf_s(cap));
+ n = find_db_conflicts_dbcnfl_with_cap(indent, ictx, pkg, cap);
+ ncnfl += n;
+ }
+
+
+ if (pkg->cnfls != NULL)
+ for (i = 0; i < n_array_size(pkg->cnfls); i++) {
+ struct capreq *cnfl = n_array_nth(pkg->cnfls, i);
+
+ if (capreq_is_obsl(cnfl))
+ continue;
+
+ msg_i(3, indent, "cnfl %s\n", capreq_snprintf_s(cnfl));
+
+ n = find_db_conflicts_cnfl_with_db(indent, ictx, pkg, cnfl);
+ ncnfl += n;
+ }
+
+ /* XXX: find file-based conflicts should be here, but it is too slow;
+ rpmlib checks conflicts in special way and it is not available via API */
+
+ return ncnfl == 0;
+}
================================================================
Index: poldek/poldek/install3/ictx.c
diff -u /dev/null poldek/poldek/install3/ictx.c:1.1
--- /dev/null Wed Jan 23 23:56:24 2008
+++ poldek/poldek/install3/ictx.c Wed Jan 23 23:56:19 2008
@@ -0,0 +1,229 @@
+/*
+ Copyright (C) 2000 - 2008 Pawel A. Gajda <mis at pld-linux.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2 as
+ published by the Free Software Foundation (see file COPYING for details).
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ $Id$
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include <trurl/trurl.h>
+#include <sigint/sigint.h>
+
+#include "i18n.h"
+#include "log.h"
+#include "pkg.h"
+#include "pkgset.h"
+#include "pkgmisc.h"
+#include "misc.h"
+#include "pkgset-req.h"
+#include "poldek.h"
+#include "poldek_intern.h"
+#include "pm/pm.h"
+
+#include "ictx.h"
+
+struct i3err {
+ struct pkg *pkg;
+ unsigned code;
+ char *message;
+ char _message[0];
+};
+
+static void *i3err_new(unsigned errcode, struct pkg *pkg,
+ const char *fmt, va_list args)
+{
+ struct i3err *e;
+ char message[1024];
+ int n = 0;
+
+ if (fmt)
+ n = n_vsnprintf(message, sizeof(message), fmt, args);
+
+ e = n_malloc(sizeof(*e) + n + 1);
+ e->pkg = pkg_link(pkg);
+ e->code = errcode;
+ e->message = NULL;
+
+ if (fmt) {
+ memcpy(e->_message, message, n + 1);
+ e->message = e->_message;
+ }
+
+ return e;
+}
+
+static void i3err_free(struct i3err *e)
+{
+ pkg_free(e->pkg);
+ free(e);
+}
+
+void i3_error(struct i3ctx *ictx, struct pkg *pkg,
+ unsigned errcode, const char *fmt, ...)
+{
+ struct i3err *e;
+ tn_array *errors;
+
+ va_list args;
+
+ va_start(args, fmt);
+ e = i3err_new(errcode, pkg, fmt, args);
+ va_end(args);
+
+ if ((errors = n_hash_get(ictx->errors, pkg_id(pkg))) == NULL) {
+ errors = n_array_new(2, (tn_fn_free)i3err_free, NULL);
+ n_hash_insert(ictx->errors, pkg_id(pkg), errors);
+ }
+
+ n_array_push(errors, e);
+ if (e->message)
+ logn(LOGERR, "%s", e->message);
+}
+
+void i3_forget_error(struct i3ctx *ictx, const struct pkg *pkg)
+{
+ n_hash_remove(ictx->errors, pkg_id(pkg));
+}
+
+int i3_get_nerrors(struct i3ctx *ictx, unsigned errcodeclass)
+{
+ tn_array *keys;
+ int i, j, n = 0;
+
+ keys = n_hash_keys(ictx->errors);
+ for (i=0; i < n_array_size(keys); i++) {
+ tn_array *errors = n_hash_get(ictx->errors, n_array_nth(keys, i));
+
+ for (j=0; j < n_array_size(errors); j++) {
+ struct i3err *e = n_array_nth(errors, j);
+ if (e->code & errcodeclass)
+ n++;
+ }
+ }
+
+ return n;
+}
+
+#if 0 /* unused */
+static int i3pkg_cmp(struct i3pkg *n1, struct i3pkg *n2)
+{
+ return strcmp(pkg_id(n1->pkg), pkg_id(n2->pkg));
+}
+#endif
+
+
+struct i3pkg *i3pkg_new(struct pkg *pkg, unsigned flags,
+ struct pkg *bypkg, const struct capreq *byreq,
+ enum i3_byflag byflag)
+{
+ struct i3pkg *i3pkg = n_calloc(sizeof(*i3pkg), 1);
+
+ i3pkg->flags = flags;
+ i3pkg->pkg = pkg_link(pkg);
+
+ i3pkg->markedby = n_array_new(2, (tn_fn_free)i3pkg_free, NULL);
+ i3pkg->obsoletedby = pkgs_array_new_ex(2, pkg_cmp_recno);
+
+ if (bypkg) {
+ i3pkg->bypkg = pkg_link(bypkg);
+ i3pkg->byreq = byreq;
+ i3pkg->byflag = byflag;
+ }
+
+
+ return i3pkg;
+}
+
+void i3pkg_free(struct i3pkg *i3pkg)
+{
+ pkg_free(i3pkg->pkg);
+
+ n_array_cfree(&i3pkg->markedby);
+ n_array_cfree(&i3pkg->obsoletedby);
+
+ if (i3pkg->bypkg)
+ pkg_free(i3pkg->bypkg);
+
+ //if (i3pkg->candidates)
+ // n_hash_free(i3pkg->candidates);
+ free(i3pkg);
+}
+
+#if 0 /* unused */
+void i3pkg_register_candidates(struct i3pkg *i3pkg, const struct capreq *req,
+ tn_array *candidates)
+{
+ char *strreq = NULL;
+ capreq_stra(req, &strreq);
+
+ if (i3pkg->candidates == NULL)
+ i3pkg->candidates = n_hash_new(8, (tn_fn_free)n_array_free);
+
+ n_hash_insert(i3pkg->candidates, strreq, candidates);
+}
+#endif
+
+
+void i3ctx_init(struct i3ctx *ictx, struct poldek_ts *ts)
+{
+ ictx->i3pkg_stack = n_array_new(32, (tn_fn_free)i3pkg_free, NULL);
+
+ ictx->inset = iset_new();
+ ictx->unset = iset_new();
+
+ ictx->ma_flags = 0;
+ if (ts->getop(ts, POLDEK_OP_VRFYMERCY))
+ ictx->ma_flags = POLDEK_MA_PROMOTE_VERSION;
+
+ ictx->ts = ts;
+ ictx->ps = ts->ctx->ps;
+
+ ictx->processed = pkgmark_set_new(0, PKGMARK_SET_IDPTR);
+ ictx->errors = n_hash_new(8, (tn_fn_free)n_array_free);
+ ictx->abort = 0;
+}
+
+void i3ctx_destroy(struct i3ctx *ictx)
+{
+ n_array_cfree(&ictx->i3pkg_stack);
+ iset_free(ictx->inset);
+ iset_free(ictx->unset);
+
+ ictx->ts = NULL;
+ ictx->ps = NULL;
+ pkgmark_set_free(ictx->processed);
+ memset(ictx, 0, sizeof(*ictx));
+}
+
+void i3ctx_reset(struct i3ctx *ictx)
+{
+ n_array_clean(ictx->i3pkg_stack);
+
+ iset_free(ictx->inset);
+ ictx->inset = iset_new();
+
+ iset_free(ictx->unset);
+ ictx->unset = iset_new();
+
+ pkgmark_set_free(ictx->processed);
+ ictx->processed = pkgmark_set_new(0, PKGMARK_SET_IDPTR);
+
+ ictx->abort = 0;
+}
================================================================
Index: poldek/poldek/install3/ictx.h
diff -u /dev/null poldek/poldek/install3/ictx.h:1.1
--- /dev/null Wed Jan 23 23:56:24 2008
+++ poldek/poldek/install3/ictx.h Wed Jan 23 23:56:19 2008
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list