Subject: pkg/36986: Patch for pkgtools/pkgfind adding more options
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: Mathias De Belder <mathias@woei.be>
List: pkgsrc-bugs
Date: 09/13/2007 21:45:00
>Number:         36986
>Category:       pkg
>Synopsis:       Patch for pkgtools/pkgfind adding more options
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Sep 13 21:45:00 +0000 2007
>Originator:     Mathias De Belder
>Release:        NetBSD 4.0_BETA2
>Organization:
	
>Environment:
	
	
System: NetBSD rhand.lan 4.0_BETA2 NetBSD 4.0_BETA2 (GENERIC.MP) #0: Sat Aug 25 20:19:35 PDT 2007 builds@wb28:/home/builds/ab/netbsd-4/amd64/200708250002Z-obj/home/builds/ab/netbsd-4/src/sys/arch/amd64/compile/GENERIC.MP amd64
Architecture: x86_64
Machine: amd64
>Description:
In PR 26964, which contained a patch to add more features to pkgfind,
there was a comment that a '-D' and a '-P' flag could be useful to
respectively display the DESCR file or do a search in the PLIST file.

Say you saw someone use the `saidar' binary on another system. When you
search for `saidar' with the current pkgfind, nothing's returned.
However, when using the new `-P' option ('pkgfind -P saidar') you get:

$ ./pkgfind -P saidar
devel/libstatgrab: Provides a useful interface to system statistics

If you add the new `-D' option, the DESCR file of a matched package is
printed to stdout:

$ ./pkgfind -DP saidar

devel/libstatgrab: Provides a useful interface to system statistics
The libstatgrab library provides an easy to use interface for
[...]

>How-To-Repeat:
/	
>Fix:
Apply these two patches against ${PKGSRC_DIR}/pkgtools/pkgfind/files/:


--- /usr/pkgsrc/pkgtools/pkgfind/files/pkgfind.c	2005-09-01 20:09:26.000000000 +0200
+++ pkgfind.c	2007-09-13 23:21:02.000000000 +0200
@@ -29,7 +29,9 @@
  * pancake@phreaker.net ** changes 2004/09/14
  *
  * -C search in comments
+ * -D print DESCR file (if any) to stdout
  * -c case sensitive
+ * -P search in PLIST entries
  * -q quiet, don't output comment
  * -x exact matches
  */
@@ -65,11 +67,13 @@ static int		checkskip(const struct diren
 static int		partialmatch(const char *, const char *);
 static int		exactmatch(const char *, const char *);
 static void		usage(void);
+static void		print_file(const char*);
+static int		find_plist_entry(const char *, const char *);
 
 static int		(*match)(const char *, const char *);
 
 static const char	*search;
-static int		cflag, qflag;
+static int		cflag, dflag, pflag, qflag;
 
 int
 main(int argc, char *argv[])
@@ -86,11 +90,14 @@ main(int argc, char *argv[])
 
 	cflag = qflag = 0;
 
-	while ((ch = getopt(argc, argv, "Ccn:Mqx")) != -1) {
+	while ((ch = getopt(argc, argv, "CDcn:MPqx")) != -1) {
 		switch (ch) {
 		case 'C':	/* search in comments */
 			search = "COMMENT";
 			break;
+		case 'D':	/* print DESCR file to stdout */
+			dflag = 1;
+			break;
 		case 'c':	/* case sensitive */
 			cflag = 1;
 			break;
@@ -100,6 +107,9 @@ main(int argc, char *argv[])
 		case 'M':	/* search for maintainer */
 			search = "MAINTAINER";
 			break;
+		case 'P':	/* search in PLIST file */
+			pflag = 1;
+			break;
 		case 'q':	/* quiet, don't output comment */
 			qflag = 1;
 			break;
@@ -130,7 +140,7 @@ static void
 pkgfind(const char *path, const char *pkg, int count)
 {
 	struct dirent **cat, **list = NULL;
-	int ncat, nlist, i, j;
+	int ncat, nlist, i, j, plistfound = 0;
 	char tmp[PATH_MAX];
 	char *text = NULL;
 	struct stat sb;
@@ -166,16 +176,20 @@ pkgfind(const char *path, const char *pk
 					if (getstring(tmp, search, &text) == 0)
 						continue;
 				}
+			} else if (pflag) {
+			    (void)strncat(tmp, "/PLIST", sizeof(tmp));
+			    plistfound = find_plist_entry(tmp, pkg);
+			    text = 0;
 			} else {
 				text = list[j]->d_name;
 			}
-			if ((*match)(text, pkg)) {
+			if (plistfound || (*match)(text, pkg)) {
 				showpkg(path, cat[i]->d_name, list[j]->d_name);
 				if (count != 0 && --count < 1) {
 					i = ncat;
 					break;
 				}
-			}
+			}  
 			free(list[j]);
 		}
 		free(cat[i]);
@@ -187,12 +201,15 @@ pkgfind(const char *path, const char *pk
 static void
 showpkg(const char *path, const char *cat, const char *pkg)
 {
-	char *mk, *comment = NULL;
-	size_t len;
+	char *mk, *desc, *comment = NULL;
+	size_t len, desclen;
 
 	len = strlen(path) + strlen(cat) + strlen(pkg) +
 	   strlen("Makefile") + 3 + 1;
 
+	desclen = strlen(path) + strlen(cat) + strlen(pkg) +
+		  strlen("DESCR") + 4;
+
 	if (!qflag) {
 		if ((mk = malloc(len)) == NULL)
 			err(EXIT_FAILURE, "malloc");
@@ -212,6 +229,62 @@ showpkg(const char *path, const char *ca
 		(void)printf("%s/%s: %s\n", cat, pkg, comment);
 	else
 		(void)printf("%s/%s\n", cat, pkg);
+
+	if (dflag) {
+	    if ((desc = malloc(len)) == NULL) {
+		err(EXIT_FAILURE, "malloc");
+	    }
+	    (void) snprintf(desc, desclen, "%s/%s/%s/DESCR", path, cat, pkg);
+	    print_file(desc);
+	    free(desc);
+	}
+}
+
+static void
+print_file(const char *file)
+{
+	FILE*	fp;
+	char	data[BUFSIZ+1];
+	ssize_t nread = 0;
+
+	if ( (fp = fopen(file, "r")) == NULL ) {
+	    warnx("Couldn't open %s for reading\n", file);
+	    return;
+	}
+	while ((nread = fread(data, 1, BUFSIZ, fp))) {
+	    data[nread] = 0;
+	    fprintf(stdout, "%s", data);
+	}
+	if (ferror(fp)) {
+	    warnx("Couldn't finish reading %s\n", file);
+	} else {
+	    fprintf(stdout, "\n");
+	}
+	fclose(fp);
+}
+
+static int
+find_plist_entry(const char *file, const char *string)
+{
+	char line[BUFSIZ];
+	FILE *fp;
+	int found = 0;;
+
+	if ((fp = fopen(file, "r")) == NULL) {
+	    return 0;
+	}
+	while (fgets(line, BUFSIZ, fp) != NULL) {
+	    if ((*match)(line, string)) { 
+		found = 1;
+		break; 
+	    }
+	}
+	if (ferror(fp)) {
+	    warnx("Couldn't finish reading %s\n", file);
+	}
+	fclose(fp);
+
+	return found;
 }
 
 static int
@@ -287,7 +360,7 @@ exactmatch(const char *s, const char *fi
 static void
 usage(void)
 {
-	(void)fprintf(stderr, "Usage: %s [-CcMqx] [-n number] keyword [...]\n",
+	(void)fprintf(stderr, "Usage: %s [-CcMPqxD] [-n number] keyword [...]\n",
 	    getprogname());
 	exit(EXIT_FAILURE);
 }


--- /usr/pkgsrc/pkgtools/pkgfind/files/pkgfind.1	2005-05-25 18:53:59.000000000 +0200
+++ pkgfind.1	2007-09-13 22:09:04.000000000 +0200
@@ -58,10 +58,20 @@ Search in the
 field, instead of looking at package names.
 .It Fl c
 Do case sensitive searches.
+.It Fl D
+Show the contents of the
+.Dq DESCR
+file when a match is found.
 .It Fl M
 Search in the
 .Dq MAINTAINER
 field, instead of looking at package names.
+.It Fl P
+Search in the
+.Dq PLIST
+file, instead of looking at package names.
+Usefeful when you only know the name of
+a file contained in a package.
 .It Fl n Ar number
 Stop searching after
 .Ar number

>Unformatted: