pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/pkgtools/pkg_install/files Do not install a package if...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/023c2bd05f34
branches:  trunk
changeset: 535907:023c2bd05f34
user:      rillig <rillig%pkgsrc.org@localhost>
date:      Fri Nov 30 00:30:39 2007 +0000

description:
Do not install a package if some of the installed packages would
conflict with it. This fixes PR 37451.

diffstat:

 pkgtools/pkg_install/files/add/perform.c   |   17 +++-
 pkgtools/pkg_install/files/lib/Makefile.in |    4 +-
 pkgtools/pkg_install/files/lib/conflicts.c |  116 +++++++++++++++++++++++++++++
 pkgtools/pkg_install/files/lib/lib.h       |    6 +-
 4 files changed, 138 insertions(+), 5 deletions(-)

diffs (196 lines):

diff -r 53f9e5f08fe6 -r 023c2bd05f34 pkgtools/pkg_install/files/add/perform.c
--- a/pkgtools/pkg_install/files/add/perform.c  Thu Nov 29 23:41:35 2007 +0000
+++ b/pkgtools/pkg_install/files/add/perform.c  Fri Nov 30 00:30:39 2007 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: perform.c,v 1.67 2007/11/13 19:53:11 rillig Exp $      */
+/*     $NetBSD: perform.c,v 1.68 2007/11/30 00:30:39 rillig Exp $      */
 
 #if HAVE_CONFIG_H
 #include "config.h"
@@ -14,7 +14,7 @@
 #if 0
 static const char *rcsid = "from FreeBSD Id: perform.c,v 1.44 1997/10/13 15:03:46 jkh Exp";
 #else
-__RCSID("$NetBSD: perform.c,v 1.67 2007/11/13 19:53:11 rillig Exp $");
+__RCSID("$NetBSD: perform.c,v 1.68 2007/11/30 00:30:39 rillig Exp $");
 #endif
 #endif
 
@@ -670,6 +670,19 @@
                }
        }
 
+       /* See if any of the installed packages conflicts with this one. */
+       {
+               char *inst_pkgname, *inst_pattern;
+
+               if (some_installed_package_conflicts_with(PkgName, &inst_pkgname, &inst_pattern)) {
+                       warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.",
+                               inst_pkgname, inst_pattern, PkgName);
+                       free(inst_pkgname);
+                       free(inst_pattern);
+                       errc++;
+               }
+       }
+
        /* Quick pre-check if any conflicting dependencies are installed
         * (e.g. version X is installed, but version Y is required)
         */
diff -r 53f9e5f08fe6 -r 023c2bd05f34 pkgtools/pkg_install/files/lib/Makefile.in
--- a/pkgtools/pkg_install/files/lib/Makefile.in        Thu Nov 29 23:41:35 2007 +0000
+++ b/pkgtools/pkg_install/files/lib/Makefile.in        Fri Nov 30 00:30:39 2007 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.in,v 1.16 2007/08/08 22:33:39 joerg Exp $
+# $NetBSD: Makefile.in,v 1.17 2007/11/30 00:30:40 rillig Exp $
 
 srcdir=                @srcdir@
 
@@ -24,7 +24,7 @@
 
 LIB=   libinstall.a
 
-OBJS=  automatic.o dewey.o fexec.o file.o ftpio.o global.o iterate.o \
+OBJS=  automatic.o conflicts.o dewey.o fexec.o file.o ftpio.o global.o iterate.o \
        lpkg.o opattern.o path.o pen.o pexec.o pkgdb.o plist.o \
        str.o var.o version.o
 
diff -r 53f9e5f08fe6 -r 023c2bd05f34 pkgtools/pkg_install/files/lib/conflicts.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/pkg_install/files/lib/conflicts.c        Fri Nov 30 00:30:39 2007 +0000
@@ -0,0 +1,116 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <nbcompat.h>
+
+#if HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "dewey.h"
+#include "lib.h"
+
+struct package_conflict {
+       const char *pkgname;
+       char **conflicting_pkgname;
+       char **conflicting_pattern;
+};
+
+static void *
+nonnull(void *p) {
+
+       if (p == NULL) {
+               err(EXIT_FAILURE, "NullPointerException");
+               /* NOTREACHED */
+       }
+       return p;
+}
+
+static FILE *
+fopen_contents(const char *pkgname, const char *mode)
+{
+       char fname[MaxPathSize];
+       FILE *f;
+
+       snprintf(fname, sizeof(fname), "%s/%s/%s", _pkgdb_getPKGDB_DIR(), pkgname, CONTENTS_FNAME);
+       f = fopen(fname, mode);
+       if (f == NULL) {
+               err(EXIT_FAILURE, "%s", fname);
+               /* NOTREACHED */
+       }
+       return f;
+}
+
+
+static int
+check_package_conflict(const char *pkgname, void *v) {
+       struct package_conflict *conflict = v;
+       package_t pkg;
+       plist_t *p;
+       FILE *f;
+       int rv;
+
+       rv = 0;
+       pkg.head = NULL;
+       pkg.tail = NULL;
+
+       f = fopen_contents(pkgname, "r");
+       read_plist(&pkg, f);
+       (void)fclose(f);
+
+       for (p = pkg.head; p; p = p->next) {
+               if (p->type != PLIST_PKGCFL)
+                       continue;
+
+               if (pkg_match(p->name, conflict->pkgname) == 1) {
+                       *(conflict->conflicting_pkgname) = nonnull(strdup(pkgname));
+                       *(conflict->conflicting_pattern) = nonnull(strdup(p->name));
+                       rv = 1 /* nonzero, stop iterating */;
+                       break;
+               }
+       }
+
+       free_plist(&pkg);
+       return rv;
+}
+
+/**
+ * Checks if some installed package has a pkgcfl entry that matches
+ * PkgName.  If such an entry is found, the package name is returned in
+ * inst_pkgname, the matching pattern in inst_pattern, and the function
+ * returns a non-zero value. Otherwise, zero is returned and the result
+ * variables are set to NULL.
+ */
+int
+some_installed_package_conflicts_with(const char *pkgname, char **inst_pkgname, char **inst_pattern)
+{
+       struct package_conflict cfl;
+       int rv;
+
+       cfl.pkgname = pkgname;
+       *inst_pkgname = NULL;
+       *inst_pattern = NULL;
+       cfl.conflicting_pkgname = inst_pkgname;
+       cfl.conflicting_pattern = inst_pattern;
+       rv = iterate_pkg_db(check_package_conflict, &cfl);
+       if (rv == -1) {
+               errx(EXIT_FAILURE, "Couldn't read list of installed packages.");
+               /* NOTREACHED */
+       }
+       return *inst_pkgname != NULL;
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+       char *pkg, *patt;
+
+       if (some_installed_package_conflicts_with(argv[1], &pkg, &patt))
+               printf("yes: package %s conflicts with %s, pattern %s\n", pkg, argv[1], patt);
+       else
+               printf("no\n");
+       return 0;
+}
+void cleanup(int i) {}
+#endif
diff -r 53f9e5f08fe6 -r 023c2bd05f34 pkgtools/pkg_install/files/lib/lib.h
--- a/pkgtools/pkg_install/files/lib/lib.h      Thu Nov 29 23:41:35 2007 +0000
+++ b/pkgtools/pkg_install/files/lib/lib.h      Fri Nov 30 00:30:39 2007 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lib.h,v 1.37 2007/08/29 15:42:39 jlam Exp $ */
+/* $NetBSD: lib.h,v 1.38 2007/11/30 00:30:40 rillig Exp $ */
 
 /* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
 
@@ -288,6 +288,10 @@
 #define IS_STDIN(str)  ((str) != NULL && !strcmp((str), "-"))
 #define IS_FULLPATH(str)       ((str) != NULL && (str)[0] == '/')
 
+/* Conflict handling (conflicts.c) */
+int    some_installed_package_conflicts_with(const char *, char **, char **);
+
+
 /* Prototypes */
 /* Misc */
 void    cleanup(int);



Home | Main Index | Thread Index | Old Index