Subject: patch: pkg-info-wildcard-match
To: None <tech-pkg@NetBSD.ORG>
From: Hubert Feyrer <hubert.feyrer@rrzc1.rz.uni-regensburg.de>
List: tech-pkg
Date: 07/08/1998 08:52:30
Here is it, as promised:

This patches add wildcard-matching to 'pkg_info -e', and print out any
matches found if -q not given. Pass -q everywhere for now. 

	% pkg_info -e mtools-3.6 ; echo $?
	mtools-3.6
	0
	% pkg_info -e mtools-\* ; echo $?
	mtools-3.6
	0
	% pkg_info -qe mtools-\* ; echo $?
	0

This file (below) contains two patches:
 1. against src/usr.sbin/pkg_install
 2. against pkgsrc

Nothing uses this yet, please think of it, as we'll need something like 
this in the not so far future.

Please note the change in the semantics: "pkg_info -e" now prints the pkg 
names (as found in $PKG_DBDIR), in addition to setting the return status. 
If this behaviour is not wanted, the -q option needs to be passed, which 
this patches below do. More than one pkg is listed if it's installed 
(bogusly). 

Next we can modify pkg_add to warn if there is _any_ pkg like the one to 
be installed installed (and maybe even nuke it or do some symlink 
tricks), pkg_delete can be extended to nuke _any_ foo-* pkg, ...
(I don't have any fixed plans for this yet...)

Please let me know if you see any problems with this, else I'll commit it 
on the weekend.


 - Hubert, 19980706



diff -burx *CVS* pkg_install/add/perform.c pkg_install-E/add/perform.c
--- pkg_install/add/perform.c	Mon Jul  6 18:55:38 1998
+++ pkg_install-E/add/perform.c	Mon Jul  6 20:35:12 1998
@@ -240,7 +240,7 @@
 	    continue;
 	if (Verbose)
 	    printf("Package `%s' conflicts with `%s'.\n", PkgName, p->name);
-	if (!vsystem("/usr/sbin/pkg_info -e %s", p->name)) {
+	if (!vsystem("/usr/sbin/pkg_info -qe %s", p->name)) {
 	    warnx("Conflicting package `%s' installed, please use pkg_delete(1)\n\t first to remove it!\n",  p->name);
 	    ++code;
 	}
@@ -252,7 +252,7 @@
 	    continue;
 	if (Verbose)
 	    printf("Package `%s' depends on `%s'.\n", PkgName, p->name);
-	if (vsystem("pkg_info -e %s", p->name)) {
+	if (vsystem("/usr/sbin/pkg_info -qe %s", p->name)) {
 	    char path[FILENAME_MAX], *cp = NULL;
 
 	    if (!Fake) {
diff -burx *CVS* pkg_install/info/perform.c pkg_install-E/info/perform.c
--- pkg_install/info/perform.c	Sun Jun 21 19:35:34 1998
+++ pkg_install-E/info/perform.c	Mon Jul  6 20:25:09 1998
@@ -34,6 +34,9 @@
 
 #include <err.h>
 #include <signal.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fnmatch.h>
 
 static int pkg_do(char *);
 
@@ -50,10 +53,40 @@
 	tmp = DEF_LOG_DIR;
     /* Overriding action? */
     if (CheckPkg) {
+      if (!strpbrk(CheckPkg,"*?[]")) {
+	/* No shell meta character given - simple check */
 	char buf[FILENAME_MAX];
+	int error;
 
 	snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
-	return abs(access(buf, R_OK));
+	error=abs(access(buf, R_OK));
+	if (!error && !Quiet)
+	  printf("%s\n",CheckPkg);
+	return error;
+      }else{
+	/* Using glob-match */
+	int found;
+	DIR *d;
+	struct dirent *dp;
+
+	found=0;
+	d=opendir(tmp);
+	if (d == NULL) {
+	  warnx("can't opendir package dir '%s'", tmp);
+	  return !0;
+	}
+	  
+	while ((dp=readdir(d))){
+	  if (fnmatch(CheckPkg, dp->d_name, 0)==0) {
+	    if (!Quiet)
+	      printf("%s\n",dp->d_name);
+	    found=1;
+	  }
+	}
+	closedir(d);
+
+	return !found; /* negate logic for shell return code */
+      }
     }
     else if (AllInstalled) {
 	DIR *dirp;
diff -burx *CVS* pkg_install/info/pkg_info.1 pkg_install-E/info/pkg_info.1
--- pkg_install/info/pkg_info.1	Sun Jun 21 19:35:52 1998
+++ pkg_install-E/info/pkg_info.1	Mon Jul  6 20:22:47 1998
@@ -83,7 +83,16 @@
 .It Fl e Ar pkg-name
 If the package identified by
 .Ar pkg-name
-is currently installed, return 0, otherwise return 1.  This option
+is currently installed, return 0, otherwise return 1.
+If the give pkg-name contains a
+shell metacharacter, it will be matched against all installed
+packages using
+.Xr fnmatch 3 ,
+and any packages found installed are printed to stdout, one name per
+line. This printing can be turned off using the
+.Fl q
+option.
+This option
 allows you to easily test for the presence of another (perhaps
 prerequisite) package from a script.
 .It Fl l Ar str





















--- pkgsrc/mk/bsd.pkg.mk.BAK	Mon Jul  6 20:36:45 1998
+++ pkgsrc/mk/bsd.pkg.mk	Mon Jul  6 20:36:14 1998
@@ -969,7 +969,7 @@
 .if !defined(NO_PKG_REGISTER) && !defined(FORCE_PKG_REGISTER)
 .if defined(CONFLICTS)
 	@for i in ${CONFLICTS}; do \
-		if pkg_info -e $$i; then \
+		if pkg_info -qe $$i; then \
 			${ECHO_MSG} "===>  ${PKGNAME} conflicts with already installed $$i."; \
 			${ECHO_MSG} "      They install the same files into the same place, its therefor not"; \
 			${ECHO_MSG} "      usefull to install ${PKGNAME}. Please remove $$i first with"; \
@@ -1521,7 +1521,7 @@
 	@for dir in ${DEPENDS}; do					\
 		package=`${ECHO} $$dir | ${SED} -e 's/:.*//'`;		\
 		dir=`${ECHO} $$dir | ${SED} -e 's/.*://'`;		\
-		if /usr/sbin/pkg_info -e $$package; then		\
+		if /usr/sbin/pkg_info -qe $$package; then		\
 			${ECHO_MSG} "===>  ${PKGNAME} depends on installed package: $$package";	\
 		else							\
 			${ECHO_MSG} "===>  ${PKGNAME} depends on package: $$package";	\