summaryrefslogtreecommitdiff
path: root/pkgtools/pkgconflict
diff options
context:
space:
mode:
authorwennmach <wennmach@pkgsrc.org>2001-04-02 18:04:03 +0000
committerwennmach <wennmach@pkgsrc.org>2001-04-02 18:04:03 +0000
commit9b1b05a7390365c8db2760f28966e9fa918ce50c (patch)
treefb9c108cf5298854a21eb990f5598bb9cd25b25b /pkgtools/pkgconflict
parente76d22cfd5bbd6c36a8294c79ae58e6f30d2c804 (diff)
downloadpkgsrc-9b1b05a7390365c8db2760f28966e9fa918ce50c.tar.gz
Initial import of pkgconflict, a script to find conflicting packages
in pkgsrc.
Diffstat (limited to 'pkgtools/pkgconflict')
-rw-r--r--pkgtools/pkgconflict/Makefile30
-rw-r--r--pkgtools/pkgconflict/files/Makefile11
-rw-r--r--pkgtools/pkgconflict/files/dewey_cmp.c273
-rwxr-xr-xpkgtools/pkgconflict/files/pkgconflict151
-rw-r--r--pkgtools/pkgconflict/pkg/DESCR12
-rw-r--r--pkgtools/pkgconflict/pkg/PLIST3
6 files changed, 480 insertions, 0 deletions
diff --git a/pkgtools/pkgconflict/Makefile b/pkgtools/pkgconflict/Makefile
new file mode 100644
index 00000000000..4bd51a6c99b
--- /dev/null
+++ b/pkgtools/pkgconflict/Makefile
@@ -0,0 +1,30 @@
+# $NetBSD: Makefile,v 1.1.1.1 2001/04/02 18:04:03 wennmach Exp $
+#
+
+DISTNAME= pkgconflict-0.1
+CATEGORIES= pkgtools
+MASTER_SITES= # empty
+DISTFILES= # empty
+
+MAINTAINER= wennmach@netbsd.org
+COMMENT= Script to find conflicting packages in pkgsrc
+
+DEPENDS+= postgresql>=7.0:../../databases/postgresql
+
+NO_WRKSUBDIR= yes
+NO_CHECKSUM= yes
+NO_PATCH= yes
+NO_CONFIGURE= yes
+
+post-extract:
+ @for FILE in Makefile dewey_cmp.c pkgconflict \
+ ; do \
+ ${SED} -e 's|@PREFIX@|${PREFIX}|' ${FILESDIR}/$$FILE \
+ >${WRKSRC}/$$FILE; \
+ done
+
+do-install:
+ ${INSTALL_SCRIPT} ${WRKSRC}/dewey_cmp.so ${PREFIX}/lib
+ ${INSTALL_SCRIPT} ${WRKSRC}/pkgconflict ${PREFIX}/bin
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/pkgtools/pkgconflict/files/Makefile b/pkgtools/pkgconflict/files/Makefile
new file mode 100644
index 00000000000..388a8e72b78
--- /dev/null
+++ b/pkgtools/pkgconflict/files/Makefile
@@ -0,0 +1,11 @@
+# $NetBSD: Makefile,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $
+
+PGINCLUDE=@PREFIX@/include/pgsql
+
+.c.o:
+ cc -I${PGINCLUDE} -Wall -fpic -c $<
+
+all: dewey_cmp.so
+
+dewey_cmp.so: dewey_cmp.o
+ cc -shared -o dewey_cmp.so dewey_cmp.o
diff --git a/pkgtools/pkgconflict/files/dewey_cmp.c b/pkgtools/pkgconflict/files/dewey_cmp.c
new file mode 100644
index 00000000000..f23c520977f
--- /dev/null
+++ b/pkgtools/pkgconflict/files/dewey_cmp.c
@@ -0,0 +1,273 @@
+/* $NetBSD: dewey_cmp.c,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $ */
+
+/*
+ * Implement the comparision of a package name with a dewey pattern
+ * for use with PostgreSQL.
+ *
+ * Author: Lex Wennmacher,
+ * almost entirely based on the dewey routines written by: Hubert Feyrer
+ * (taken from: basesrc/usr.sbin/pkg_install/lib/str.c, version 1.28
+ */
+
+#include <sys/cdefs.h>
+#if 0
+static const char *rcsid = "Id: str.c,v 1.5 1997/10/08 07:48:21 charnier Exp";
+#else
+__RCSID("$NetBSD: dewey_cmp.c,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $");
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Miscellaneous string utilities.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/queue.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fnmatch.h>
+
+int pmatch(const char *, const char *);
+
+typedef enum deweyop_t {
+ GT,
+ GE,
+ LT,
+ LE
+} deweyop_t;
+
+/*
+ * Compare two dewey decimal numbers
+ */
+static int
+deweycmp(char *a, deweyop_t op, char *b)
+{
+ int ad;
+ int bd;
+ char *a_nb;
+ char *b_nb;
+ int in_nb = 0;
+ int cmp;
+
+ assert(a != NULL);
+ assert(b != NULL);
+
+ /* Null out 'n' in any "nb" suffixes for initial pass */
+ if ((a_nb = strstr(a, "nb")))
+ *a_nb = 0;
+ if ((b_nb = strstr(b, "nb")))
+ *b_nb = 0;
+
+ for (;;) {
+ if (*a == 0 && *b == 0) {
+ if (!in_nb && (a_nb || b_nb)) {
+ /*
+ * If exact match on first pass, test
+ * "nb<X>" suffixes in second pass
+ */
+ in_nb = 1;
+ if (a_nb)
+ a = a_nb + 2; /* Skip "nb" suffix */
+ if (b_nb)
+ b = b_nb + 2; /* Skip "nb" suffix */
+ } else {
+ cmp = 0;
+ break;
+ }
+ }
+
+ ad = bd = 0;
+ for (; *a && *a != '.'; a++) {
+ ad = (ad * 10) + (*a - '0');
+ }
+ for (; *b && *b != '.'; b++) {
+ bd = (bd * 10) + (*b - '0');
+ }
+ if ((cmp = ad - bd) != 0) {
+ break;
+ }
+ if (*a == '.')
+ ++a;
+ if (*b == '.')
+ ++b;
+ }
+ /* Replace any nulled 'n' */
+ if (a_nb)
+ *a_nb = 'n';
+ if (b_nb)
+ *b_nb = 'n';
+ return (op == GE) ? cmp >= 0 : (op == GT) ? cmp > 0 :
+ (op == LE) ? cmp <= 0 : cmp < 0;
+}
+
+/*
+ * Perform alternate match on "pkg" against "pattern",
+ * calling pmatch (recursively) to resolve any other patterns.
+ * Return 1 on match, 0 otherwise
+ */
+static int
+alternate_match(const char *pattern, const char *pkg)
+{
+ char *sep;
+ char buf[FILENAME_MAX];
+ char *last;
+ char *alt;
+ char *cp;
+ int cnt;
+ int found;
+
+ if ((sep = strchr(pattern, '{')) == (char *) NULL) {
+ errx(1, "alternate_match(): '{' expected in `%s'", pattern);
+ }
+ (void)strncpy(buf, pattern, (size_t) (sep - pattern));
+ alt = &buf[sep - pattern];
+ last = (char *) NULL;
+ for (cnt = 0, cp = sep; *cp && last == (char *) NULL; cp++) {
+ if (*cp == '{') {
+ cnt++;
+ } else if (*cp == '}' && --cnt == 0 && last == (char *) NULL) {
+ last = cp + 1;
+ }
+ }
+ if (cnt != 0) {
+ errx(1, "Malformed alternate `%s'", pattern);
+ }
+ for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) {
+ for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' &&
+ *sep != ','); sep++) {
+ if (*sep == '{') {
+ cnt++;
+ } else if (*sep == '}') {
+ cnt--;
+ }
+ }
+ (void)snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s",
+ (int)(sep - cp), cp, last);
+ if (pmatch(buf, pkg) == 1) {
+ found = 1;
+ }
+ }
+ return found;
+}
+
+/*
+ * Perform dewey match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+dewey_match(const char *pattern, const char *pkg)
+{
+ deweyop_t op;
+ char *cp;
+ char *sep;
+ char *ver;
+ char name[FILENAME_MAX];
+ int n;
+
+ if ((sep = strpbrk(pattern, "<>")) == NULL) {
+ errx(1, "dewey_match(): '<' or '>' expected in `%s'", pattern);
+ }
+ (void)snprintf(name, sizeof(name), "%.*s", (int)(sep - pattern),
+ pattern);
+ op = (*sep == '>') ? (*(sep + 1) == '=') ? GE : GT : (*(sep + 1) == '=')
+ ? LE : LT;
+ ver = (op == GE || op == LE) ? sep + 2 : sep + 1;
+ n = (int) (sep - pattern);
+ if ((cp = strrchr(pkg, '-')) != (char *) NULL) {
+ if (strncmp(pkg, name, (size_t)(cp - pkg)) == 0 &&
+ n == cp - pkg) {
+ if (deweycmp(cp + 1, op, ver)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Perform glob match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+glob_match(const char *pattern, const char *pkg)
+{
+ return fnmatch(pattern, pkg, FNM_PERIOD) == 0;
+}
+
+/*
+ * Perform simple match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+simple_match(const char *pattern, const char *pkg)
+{
+ return strcmp(pattern, pkg) == 0;
+}
+
+/*
+ * Match pkg against pattern, return 1 if matching, 0 else
+ */
+int
+pmatch(const char *pattern, const char *pkg)
+{
+ if (strchr(pattern, '{') != (char *) NULL) {
+ /* emulate csh-type alternates */
+ return alternate_match(pattern, pkg);
+ }
+ if (strpbrk(pattern, "<>") != (char *) NULL) {
+ /* perform relational dewey match on version number */
+ return dewey_match(pattern, pkg);
+ }
+ if (strpbrk(pattern, "*?[]") != (char *) NULL) {
+ /* glob match */
+ return glob_match(pattern, pkg);
+ }
+
+ /* no alternate, dewey or glob match -> simple compare */
+ return simple_match(pattern, pkg);
+}
+
+
+/* pkg_cmp is used to implement the ~~~ operator in PostgreSQL */
+#include <postgres.h>
+
+bool
+pkg_cmp(text *pkg, text *pattern)
+{
+
+/* Make sure that the strings are \0 terminated */
+ pkg->vl_dat[pkg->vl_len] = '\0';
+ pattern->vl_dat[pattern->vl_len] = '\0';
+
+ if (pmatch((const char *)&(pattern->vl_dat),
+ (const char *)&(pkg->vl_dat)) == 1)
+ return true;
+
+ return false;
+}
diff --git a/pkgtools/pkgconflict/files/pkgconflict b/pkgtools/pkgconflict/files/pkgconflict
new file mode 100755
index 00000000000..e8bd539394d
--- /dev/null
+++ b/pkgtools/pkgconflict/files/pkgconflict
@@ -0,0 +1,151 @@
+#!/bin/csh -f
+# $NetBSD: pkgconflict,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $
+#
+# pkgconflict: A script to find conflicting packages in pkgsrc
+# Author: Lex Wennmacher <wennmach@netbsd.org>
+#
+
+set PREFIX=@PREFIX@
+
+if ($#argv > 1) then
+ echo Usage: pkgconflict [BASEDIR]
+ exit -1
+endif
+
+# BASEDIR is the directory where the packages databases live
+# The default location in /var/db/pkg, but can be changed to
+# a different directory, e. g. to the place where the bulk builds
+# saved the packages databases
+if ($#argv == 1) then
+ set BASEDIR=$1
+else
+ set BASEDIR="/var/db/pkg"
+endif
+
+if (! -d $BASEDIR) then
+ echo pkgconflict: error: BASEDIR, $BASEDIR, does not exist.
+ exit -1
+endif
+
+psql -l >& /dev/null
+if ($status != 0) then
+ echo pkgconflict: error: PostgreSQL must be installed and configured."
+ exit -1
+endif
+
+if (! -x $PREFIX/lib/dewey_cmp.so) then
+ echo pkgconflict: error: no executable $PREFIX/lib/dewey_cmp.so
+ exit -1
+endif
+
+set testfile=.test.$$
+rm -f $testfile
+touch $testfile
+if (! -e $testfile) then
+# XXX if (! -w .) should be simpler, but I'm not sure if it really works
+ echo pkgconflict: error: local directory must be writable.
+ exit -1
+endif
+rm -f $testfile
+
+echo pkgconflict: started `date`
+echo " "
+
+if (! -d RCS) mkdir RCS
+
+rm -f pkgfiles
+touch pkgfiles
+
+rm -f registered_conflicts
+touch registered_conflicts
+
+foreach dir ($BASEDIR/*)
+ if (-d $dir) then
+ set basename=$dir:t
+ echo processig $basename
+ set contents=$dir/+CONTENTS
+ if (-e $contents) then
+ setenv BASENAME $basename
+ setenv BASEDIR `grep "^@cwd" $contents | awk '{print $2}'`
+# do not break the following line
+ awk '/^[^@].*$/ {print ENVIRON["BASENAME"] "\t" ENVIRON["BASEDIR"] "/" $1}' \
+ $contents >> pkgfiles
+ grep "^@pkgcfl" $contents \
+ | awk '{print ENVIRON["BASENAME"] "\t" $2}' \
+ >> registered_conflicts
+ endif
+ endif
+end
+
+echo " "
+
+if (-e CFL-big) ci -l -t-version0 -m"script-based checkin" CFL-big
+rm -f CFL-big
+
+if (-e CFL-small) ci -l -t-version0 -m"script-based checkin" CFL-small
+rm -f CFL-small
+
+echo " "
+echo pkgconflict: Done processing packages `date`
+echo pkgconflict: Invoking PostgreSQL to generate database summaries.
+echo " "
+
+set DATABASE=tmp.$$
+createdb $DATABASE
+psql $DATABASE << --EOI--
+create function
+ pkg_cmp(varchar, varchar)
+ returns bool
+ as '$PREFIX/lib/dewey_cmp.so'
+ language 'C';
+create operator ~~~ (
+ leftarg = varchar,
+ rightarg = varchar,
+ procedure = pkg_cmp);
+create table pkgfiles (
+ pkg varchar(40), file varchar(120));
+copy pkgfiles from '`pwd`/pkgfiles';
+create table registered_conflicts (
+ pkg varchar(40), pkgpat varchar(40));
+copy registered_conflicts from '`pwd`/registered_conflicts';
+\o CFL-big
+\qecho 'CFL-big table generated `date`'
+\qecho 'This table contains:'
+\qecho ' a pair of conflicting packages (first 2 columns)'
+\qecho ' name of the common file (third column)'
+\qecho ' '
+select
+ p1.pkg, p2.pkg, p1.file
+ from pkgfiles p1, pkgfiles p2, registered_conflicts r
+ where (p1.pkg <> p2.pkg)
+ and (p1.file = p2.file)
+ and (p1.pkg = r.pkg)
+ and not (p1.pkg ~~~ r.pkgpat)
+ order by 1 asc;
+\o CFL-small
+\qecho 'CFL-small table generated `date`'
+\qecho 'This table contains:'
+\qecho ' a pair of conflicting packages (unique) (first 2 columns)'
+\qecho ' the number of conflicting files (third column)'
+\qecho ' '
+select
+ distinct on (p1.pkg, p2.pkg)
+ p1.pkg, p2.pkg, count(p1.file)
+ from pkgfiles p1, pkgfiles p2, registered_conflicts r
+ where (p1.pkg <> p2.pkg)
+ and (p1.file = p2.file)
+ and (p1.pkg = r.pkg)
+ and not (p1.pkg ~~~ r.pkgpat)
+ group by p1.pkg, p2.pkg
+ order by 1 asc;
+\o null
+drop table pkgfiles;
+drop table registered_conflicts;
+\q
+--EOI--
+dropdb $DATABASE
+rm -f null pkgfiles registered_conflicts
+
+echo " "
+echo pkgconflict: Done `date`.
+exit
diff --git a/pkgtools/pkgconflict/pkg/DESCR b/pkgtools/pkgconflict/pkg/DESCR
new file mode 100644
index 00000000000..5a70ac207fe
--- /dev/null
+++ b/pkgtools/pkgconflict/pkg/DESCR
@@ -0,0 +1,12 @@
+$NetBSD: DESCR,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $
+
+pkgconflict is a script that searches for conflicting packages.
+
+In a first step it gathers the package and file names of all known
+packages. The source for this step is either the contents of
+/var/db/pkg, or a directory where the builk builds savet the
+package databases.
+
+In a second step, it calls a database system, PostgreSQL, to
+determine which packages have common file names. Packages with
+registered CONFLICT lines are filtered out.
diff --git a/pkgtools/pkgconflict/pkg/PLIST b/pkgtools/pkgconflict/pkg/PLIST
new file mode 100644
index 00000000000..4966818d7e8
--- /dev/null
+++ b/pkgtools/pkgconflict/pkg/PLIST
@@ -0,0 +1,3 @@
+@comment $NetBSD: PLIST,v 1.1.1.1 2001/04/02 18:04:04 wennmach Exp $
+lib/dewey_cmp.so
+bin/pkgconflict