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