| Summary: | [patch] pkg_info: prefix search for a package | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Edwin Groothuis <mavetju> | ||||
| Component: | bin | Assignee: | Maxim Sobolev <sobomax> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.2-RELEASE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
Edwin Groothuis
2001-01-28 17:00:01 UTC
On Sun, Jan 28, 2001 at 05:51:36PM +0100, mavetju@chello.nl wrote: > > >Number: 24695 > >Category: bin > >Synopsis: [patch] pkg_info: prefix search for a package > >Originator: Edwin Groothuis > >Release: FreeBSD 4.2-RELEASE i386 > >Organization: > - > >Environment: > > pkg_install, HEAD tag > main.c: 1.27 > pkg_info.1: 1.31 > perform.c: 1.32 > > > >Description: > > Sometimes I need to find the know the description or the > version of an installed package. Of course, pkg_info -a | > grep string works fine, but userfriendly? By adding the -F > option (fuzzy search), it will not check for the full name > of the package but use the given pkg-name as a prefix in > the package to search for. > > >How-To-Repeat: > > [~] edwin@p6>pkg_info -F screen > Information for screen-3.9.5: > > Comment: > A multi-screen window manager > [...] Hmm.. I've been meaning to try and do something like this for a long time, but I haven't been able to find the time :) Still, now that I've taken a look at code someone has actually written, there are a couple of comments. Shouldn't the FuzzySearch opendir/readdir logic be outside of the pkg_do() routine, and call pkg_do() once for every file it finds? Currently you stop at the very first file you find, which might not be so good if multiple versions of a package are installed, or if the user deliberately tries to query several packages with a common prefix (e.g. mysql-client/ mysql-server). Apart from that, it's great that you've actually taken the time and implemented this :) G'luck, Peter -- This inert sentence is my body, but my soul is alive, dancing in the sparks of your brain. On Sun, Jan 28, 2001 at 07:44:49PM +0200, Peter Pentchev wrote: > Shouldn't the FuzzySearch opendir/readdir logic be outside of the pkg_do() > routine, and call pkg_do() once for every file it finds? Currently you > stop at the very first file you find, which might not be so good if Yes, besides that pkg_do actually consists of two functions in one: find the right files and display the information on them. I've pulled them apart and I've added your suggestion. > multiple versions of a package are installed, or if the user deliberately > tries to query several packages with a common prefix (e.g. mysql-client/ > mysql-server). That's something I hadn't thought about yet :-) Here is a new patch, which implements your suggestion. It euh... has two things now in it: pkg_info -F stringsomehwereinthepackagename pkg_info -P stringprefixofthepackagename So people looking for the twenty versions of mysql are happy with the -P and people which are looking for all packages related to mysql are happy with the -F. Edwin -- Edwin Groothuis | Interested in MUDs? Visit Fatal Dimensions: mavetju@chello.nl | http://fataldimensions.nl.eu.org/ ------------------+ telnet://fataldimensions.nl.eu.org:4000 Index: main.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pkg_install/info/main.c,v retrieving revision 1.27 diff -u -r1.27 main.c --- main.c 2000/12/05 11:02:19 1.27 +++ main.c 2001/01/28 21:55:10 @@ -28,11 +28,13 @@ "$FreeBSD: src/usr.sbin/pkg_install/info/main.c,v 1.27 2000/12/05 11:02:19 sobomax Exp $"; #endif -static char Options[] = "acdDe:fhiIkl:LmopqrRst:v"; +static char Options[] = "acdDe:fFhiIkl:LmopPqrRst:v"; int Flags = 0; Boolean AllInstalled = FALSE; Boolean Quiet = FALSE; +Boolean FuzzySearch = FALSE; +Boolean PrefixSearch = FALSE; char *InfoPrefix = ""; char PlayPen[FILENAME_MAX]; char *CheckPkg = NULL; @@ -72,6 +74,10 @@ Flags |= SHOW_PREFIX; break; + case 'P': + PrefixSearch = TRUE; + break; + case 'c': Flags |= SHOW_COMMENT; break; @@ -86,6 +92,10 @@ case 'f': Flags |= SHOW_PLIST; + break; + + case 'F': + FuzzySearch = TRUE; break; case 'i': Index: perform.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/pkg_install/info/perform.c,v retrieving revision 1.32 diff -u -r1.32 perform.c --- perform.c 2000/10/23 07:01:31 1.32 +++ perform.c 2001/01/28 21:55:10 @@ -32,6 +32,7 @@ static int fname_cmp(const FTSENT **, const FTSENT **); static int pkg_do(char *); +static int pkg_info(char *, Boolean); int pkg_perform(char **pkgs) @@ -86,8 +87,6 @@ Boolean installed = FALSE, isTMP = FALSE; char log_dir[FILENAME_MAX]; char fname[FILENAME_MAX]; - Package plist; - FILE *fp; struct stat sb; char *cp = NULL; int code = 0; @@ -137,9 +136,49 @@ /* It's not an ininstalled package, try and find it among the installed */ else { char *tmp; + extern Boolean FuzzySearch, PrefixSearch; + + tmp = getenv(PKG_DBDIR); + if (tmp == NULL) + tmp = DEF_LOG_DIR; + sprintf(log_dir, "%s/%s", tmp, pkg); + installed = TRUE; - sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, - pkg); + /* If doing a prefix-search / fuzzy-search, go through all the files + * in the pkg_db directory (as indicated by tmp) and see if they + * matches the given description, then dump the information of it. + */ + if (FuzzySearch == TRUE || PrefixSearch == TRUE) { + DIR *dirp = opendir(tmp); + struct dirent *dp; + Boolean found = FALSE; + char *thispkg; + + while ((dp = readdir(dirp)) != NULL) { + if ((FuzzySearch == TRUE && strstr(dp->d_name, pkg) != NULL ) || + (PrefixSearch == TRUE && + strncmp(pkg, dp->d_name, strlen(pkg)) == 0 )) { + sprintf(log_dir, "%s/%s", tmp, dp->d_name); + thispkg = dp->d_name; + + if (chdir(log_dir) == FAIL) { + warnx("can't change directory to '%s'!", log_dir); + return 1; + } + pkg_info(thispkg, installed); + found++; + } + } + closedir(dirp); + + if (found==0) { + warnx("can't find a package prefixed with `%s'!", pkg); + return 1; + } + leave_playpen(); + return 0; + } + if (!fexists(log_dir)) { warnx("can't find package `%s' installed or in a file!", pkg); return 1; @@ -148,16 +187,28 @@ warnx("can't change directory to '%s'!", log_dir); return 1; } - installed = TRUE; } + code = pkg_info(pkg, installed); + bail: + leave_playpen(); + if (isTMP) + unlink(fname); + return code; +} + +static int +pkg_info(char *pkg, Boolean installed) { + Package plist; + FILE *fp; + int code = 0; + /* Suck in the contents list */ plist.head = plist.tail = NULL; fp = fopen(CONTENTS_FNAME, "r"); if (!fp) { warnx("unable to open %s file", CONTENTS_FNAME); - code = 1; - goto bail; + return 1; } /* If we have a prefix, add it now */ read_plist(&plist, fp); @@ -211,10 +262,6 @@ puts(InfoPrefix); } free_plist(&plist); - bail: - leave_playpen(); - if (isTMP) - unlink(fname); return code; } Index: pkg_info.1 =================================================================== RCS file: /home/ncvs/src/usr.sbin/pkg_install/info/pkg_info.1,v retrieving revision 1.31 diff -u -r1.31 pkg_info.1 --- pkg_info.1 2000/12/27 15:30:19 1.31 +++ pkg_info.1 2001/01/28 21:55:11 @@ -24,13 +24,13 @@ .Nm pkg_info .Nd a utility for displaying information on software packages .Sh SYNOPSIS -.Nm -.Op Fl cdDfiIkLmopqrRsv +.Nm pkg_info +.Op Fl cdDfFiIkLmopPqrRsv .Op Fl e Ar package .Op Fl l Ar prefix .Op Fl t Ar template .Ar pkg-name [pkg-name ...] -.Nm +.Nm pkg_info .Fl a .Op Ar flags .Sh DESCRIPTION @@ -54,6 +54,14 @@ Show all currently installed packages. .It Fl v Turn on verbose output. +.It Fl P +Threat the +.Ar pkg-name +as a prefix of the name of the package being searched for. +.It Fl F +Threat the +.Ar pkg-name +as a string somewhere in the name of the package being searched for. .It Fl p Show the installation prefix for each package. .It Fl q On Sun, Jan 28, 2001 at 10:56:19PM +0100, Edwin Groothuis wrote:
> On Sun, Jan 28, 2001 at 07:44:49PM +0200, Peter Pentchev wrote:
> > Shouldn't the FuzzySearch opendir/readdir logic be outside of the pkg_do()
> > routine, and call pkg_do() once for every file it finds? Currently you
> > stop at the very first file you find, which might not be so good if
>
> Yes, besides that pkg_do actually consists of two functions in one:
> find the right files and display the information on them. I've
> pulled them apart and I've added your suggestion.
>
> > multiple versions of a package are installed, or if the user deliberately
> > tries to query several packages with a common prefix (e.g. mysql-client/
> > mysql-server).
>
> That's something I hadn't thought about yet :-)
>
> Here is a new patch, which implements your suggestion. It euh...
> has two things now in it:
>
> pkg_info -F stringsomehwereinthepackagename
> pkg_info -P stringprefixofthepackagename
>
> So people looking for the twenty versions of mysql are happy with
> the -P and people which are looking for all packages related to
> mysql are happy with the -F.
This one works great!
Hmm.. now to find somebody to look over the patch and possibly even
commit it.. :)
G'luck,
Peter
--
I've heard that this sentence is a rumor.
Responsible Changed From-To: freebsd-bugs->sobomax I'll take this. State Changed From-To: open->closed State Changed From-To: closed->open State Changed From-To: open->closed Another similar, but more generic feature has been comitted. I have to give you a credit for the great idea. Thanks and please keep doing! |