NetBSD Problem Report #8176
Received: (qmail 5059 invoked from network); 8 Aug 1999 14:44:47 -0000
Message-Id: <199908081443.AAA00829@zen.quick.com.au>
Date: Mon, 9 Aug 1999 00:43:09 +1000 (EST)
From: "Simon J. Gerraty" <sjg@quick.com.au>
Reply-To: sjg@quick.com.au
To: gnats-bugs@gnats.netbsd.org
Subject: locate does not support alternate databases
X-Send-Pr-Version: 3.95
>Number: 8176
>Category: bin
>Synopsis: locate(1) does not support alternate databases
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: closed
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Aug 08 07:50:00 +0000 1999
>Closed-Date: Mon Aug 16 06:09:41 +0000 1999
>Last-Modified: Mon Aug 16 06:11:00 +0000 1999
>Originator: Simon J. Gerraty
>Release: 1999年07月30日
>Organization:
Zen Programming...
>Environment:
System: NetBSD zen.quick.com.au 1.3.2 NetBSD 1.3.2 (ZEN-PUC) #4: Thu Feb 11 17:34:27 EST 1999 root@zen.quick.com.au:/u3/NetBSD/1.3.2/src/sys/arch/i386/compile/ZEN-PUC i386
>Description:
It should be possible for users to create a private database for use with
locate(1) for their home directory.
GNU's locate for instance supports $LOCATE_PATH as well as command line
options for specifying an alternate database - list of alternate databases
actually.
>How-To-Repeat:
>Fix:
If no one objects to using $LOCATE_PATH and/or -d "dbpath" I'm happy to
code it up.
>Release-Note:
>Audit-Trail:
From: "Simon J. Gerraty" <sjg@quick.com.au>
To: gnats-bugs@gnats.netbsd.org, gnats-admin@netbsd.org
Cc: sjg@quick.com.au
Subject: Re: bin/8176: locate does not support alternate databases
Date: 1999年8月09日 02:04:21 +1000
Ok, here is a patch that adds support for -d "path" and $LOCATE_PATH.
Index: locate.1
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/locate/locate/locate.1,v
retrieving revision 1.7
diff -u -b -r1.7 locate.1
--- locate.1 1999年03月22日 18:16:39 1.7
+++ locate.1 1999年08月08日 16:03:21
@@ -41,6 +41,7 @@
.Nd find files
.Sh SYNOPSIS
.Nm
+.Op Fl d Ar dbpath
.Ar pattern
.Sh DESCRIPTION
.Nm
@@ -61,10 +62,21 @@
.Pp
As a special case, a pattern containing no globbing characters (``foo'')
is matched as though it were ``*foo*''.
+
+Options:
+.Bl -tag -width flag
+.It Fl d Ar dbpath
+Sets the list of databases to search to
+.Ar dbpath
+which can name one or more database files separated by ``:''.
+The environment variable
+.Ar LOCATE_PATH
+has the same effect.
+.El
.Sh FILES
.Bl -tag -width /usr/libexec/locate.updatedb -compact
.It Pa /var/db/locate.database
-Database
+Default database
.It /usr/libexec/locate.updatedb
Script to update database.
.El
Index: locate.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/locate/locate/locate.c,v
retrieving revision 1.8
diff -u -b -r1.8 locate.c
--- locate.c 1997年10月19日 04:11:56 1.8
+++ locate.c 1999年08月08日 16:03:25
@@ -82,37 +82,90 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "locate.h"
#include "pathnames.h"
-void fastfind __P((char *));
+typedef struct list_entry {
+ struct list_entry *le_next;
+ void *le_data;
+} LIST_ENTRY;
+#ifndef NEW
+# define NEW(type) (type *) malloc(sizeof (type))
+#endif
+
+LIST_ENTRY *add_db __P((LIST_ENTRY *, char *));
+void fastfind __P((FILE *, char *));
int main __P((int, char **));
char *patprep __P((char *));
+
+
+LIST_ENTRY *
+add_db(list, path)
+ LIST_ENTRY *list;
+ char *path;
+{
+ FILE *fp;
+ LIST_ENTRY *lp = 0;
-FILE *fp;
+ if ((fp = fopen(path, "r"))) {
+ lp = NEW(LIST_ENTRY);
+ lp->le_next = list;
+ lp->le_data = fp;
+ list = lp;
+ } else {
+ (void)fprintf(stderr, "locate: no database file %s.\n", path);
+ }
+
+ return list;
+}
int
main(argc, argv)
int argc;
char *argv[];
{
- if (argc != 2) {
- (void)fprintf(stderr, "usage: locate pattern\n");
+ char *_path_fcodes = getenv("LOCATE_PATH");
+ char *cp;
+ LIST_ENTRY *list = 0;
+ LIST_ENTRY *lp;
+ int c;
+
+ while ((c = getopt(argc, argv, "d:")) != EOF) {
+ switch (c) {
+ case 'd':
+ _path_fcodes = optarg;
+ break;
+ }
+ }
+ if (argc <= optind) {
+ (void)fprintf(stderr, "usage: locate [-d dbpath] pattern ...\n");
exit(1);
+ }
+ if (!_path_fcodes)
+ _path_fcodes = _PATH_FCODES;
+ if ((cp = strrchr(_path_fcodes, ':'))) {
+ _path_fcodes = strdup(_path_fcodes);
+ while ((cp = strrchr(_path_fcodes, ':'))) {
+ *cp++ = '0円';
+ list = add_db(list, cp);
}
- if (!(fp = fopen(_PATH_FCODES, "r"))) {
- (void)fprintf(stderr, "locate: no database file %s.\n",
- _PATH_FCODES);
+ }
+ list = add_db(list, _path_fcodes);
+ if (!list)
exit(1);
+ for (; optind < argc; ++optind) {
+ for (lp = list; lp; lp = lp->le_next) {
+ fastfind(lp->le_data, argv[optind]);
+ }
}
- while (*++argv)
- fastfind(*argv);
exit(0);
}
void
-fastfind(pathpart)
+fastfind(fp, pathpart)
+ FILE *fp;
char *pathpart;
{
char *p, *s;
@@ -121,6 +174,8 @@
char *cutoff, *patend, *q;
char bigram1[NBG], bigram2[NBG], path[MAXPATHLEN];
+ rewind(fp);
+
for (c = 0, p = bigram1, s = bigram2; c < NBG; c++)
p[c] = getc(fp), s[c] = getc(fp);
From: "Simon J. Gerraty" <sjg@quick.com.au>
To: gnats-bugs@gnats.netbsd.org, gnats-admin@netbsd.org
Cc: sjg@quick.com.au
Subject: Re: bin/8176: locate does not support alternate databases
Date: 1999年8月15日 02:07:54 +1000
Forget the previous patch - should have used queue(3).
The following does that and also exits(0) only if a match is found.
Only feed back I've had to date has been positive btw.
Index: locate.1
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/locate/locate/locate.1,v
retrieving revision 1.7
diff -c -b -r1.7 locate.1
*** locate.1 1999年03月22日 18:16:39 1.7
--- locate.1 1999年08月14日 16:00:46
***************
*** 41,46 ****
--- 41,47 ----
.Nd find files
.Sh SYNOPSIS
.Nm
+ .Op Fl d Ar dbpath
.Ar pattern
.Sh DESCRIPTION
.Nm
***************
*** 61,70 ****
.Pp
As a special case, a pattern containing no globbing characters (``foo'')
is matched as though it were ``*foo*''.
.Sh FILES
.Bl -tag -width /usr/libexec/locate.updatedb -compact
.It Pa /var/db/locate.database
! Database
.It /usr/libexec/locate.updatedb
Script to update database.
.El
--- 62,86 ----
.Pp
As a special case, a pattern containing no globbing characters (``foo'')
is matched as though it were ``*foo*''.
+ .Pp
+ .Nm
+ exits with a successful status if a match is found.
+
+ Options:
+ .Bl -tag -width flag
+ .It Fl d Ar dbpath
+ Sets the list of databases to search to
+ .Ar dbpath
+ which can name one or more database files separated by ``:'',
+ an empty component in the list represents the default database.
+ The environment variable
+ .Ar LOCATE_PATH
+ has the same effect.
+ .El
.Sh FILES
.Bl -tag -width /usr/libexec/locate.updatedb -compact
.It Pa /var/db/locate.database
! Default database
.It /usr/libexec/locate.updatedb
Script to update database.
.El
Index: locate.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/locate/locate/locate.c,v
retrieving revision 1.8
diff -c -b -r1.8 locate.c
*** locate.c 1997年10月19日 04:11:56 1.8
--- locate.c 1999年08月14日 16:00:46
***************
*** 82,126 ****
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "locate.h"
#include "pathnames.h"
! void fastfind __P((char *));
int main __P((int, char **));
char *patprep __P((char *));
! FILE *fp;
int
main(argc, argv)
int argc;
char *argv[];
{
! if (argc != 2) {
! (void)fprintf(stderr, "usage: locate pattern\n");
exit(1);
}
! if (!(fp = fopen(_PATH_FCODES, "r"))) {
! (void)fprintf(stderr, "locate: no database file %s.\n",
! _PATH_FCODES);
exit(1);
}
! while (*++argv)
! fastfind(*argv);
! exit(0);
}
! void
! fastfind(pathpart)
char *pathpart;
{
char *p, *s;
int c;
! int count, found, globflag;
char *cutoff, *patend, *q;
char bigram1[NBG], bigram2[NBG], path[MAXPATHLEN];
for (c = 0, p = bigram1, s = bigram2; c < NBG; c++)
p[c] = getc(fp), s[c] = getc(fp);
--- 82,186 ----
#include <unistd.h>
#include <stdio.h>
#include <string.h>
+ #include <stdlib.h>
+ #include <sys/queue.h>
#include "locate.h"
#include "pathnames.h"
!
! struct locate_db {
! LIST_ENTRY(locate_db) db_link;
! FILE *db_fp;
! };
! LIST_HEAD(db_list, locate_db) db_list;
!
! #ifndef NEW
! # define NEW(type) (type *) malloc(sizeof (type))
! #endif
!
! void add_db __P((char *));
! int fastfind __P((FILE *, char *));
int main __P((int, char **));
char *patprep __P((char *));
+
! void
! add_db(path)
! char *path;
! {
! FILE *fp;
! struct locate_db *dbp;
+ if (!(path && *path))
+ path = _PATH_FCODES;
+ if ((fp = fopen(path, "r"))) {
+ dbp = NEW(struct locate_db);
+ dbp->db_fp = fp;
+ LIST_INSERT_HEAD(&db_list, dbp, db_link);
+ } else {
+ (void)fprintf(stderr, "locate: no database file %s.\n", path);
+ }
+ }
+
int
main(argc, argv)
int argc;
char *argv[];
{
! char *locate_path = getenv("LOCATE_PATH");
! char *cp;
! struct locate_db *dbp;
! int c;
! int found = 0;
!
! LIST_INIT(&db_list);
!
! while ((c = getopt(argc, argv, "d:")) != EOF) {
! switch (c) {
! case 'd':
! locate_path = optarg;
! break;
! }
! }
! if (argc <= optind) {
! (void)fprintf(stderr, "usage: locate [-d dbpath] pattern ...\n");
exit(1);
+ }
+ if (!locate_path)
+ locate_path = _PATH_FCODES;
+ if ((cp = strrchr(locate_path, ':'))) {
+ locate_path = strdup(locate_path);
+ while ((cp = strrchr(locate_path, ':'))) {
+ *cp++ = '0円';
+ add_db(cp);
+ }
}
! add_db(locate_path);
! if (db_list.lh_first == NULL)
exit(1);
+ for (; optind < argc; ++optind) {
+ for (dbp = db_list.lh_first; dbp != NULL;
+ dbp = dbp->db_link.le_next) {
+ found |= fastfind(dbp->db_fp, argv[optind]);
}
! }
! exit(found == 0);
}
! int
! fastfind(fp, pathpart)
! FILE *fp;
char *pathpart;
{
char *p, *s;
int c;
! int count, found, globflag, printed;
char *cutoff, *patend, *q;
char bigram1[NBG], bigram2[NBG], path[MAXPATHLEN];
+ rewind(fp);
+
for (c = 0, p = bigram1, s = bigram2; c < NBG; c++)
p[c] = getc(fp), s[c] = getc(fp);
***************
*** 128,134 ****
globflag = strchr(p, '*') || strchr(p, '?') || strchr(p, '[');
patend = patprep(p);
! found = 0;
for (c = getc(fp), count = 0; c != EOF;) {
count += ((c == SWITCH) ? getw(fp) : c) - OFFSET;
/* overlay old path */
--- 188,194 ----
globflag = strchr(p, '*') || strchr(p, '?') || strchr(p, '[');
patend = patprep(p);
! found = printed = 0;
for (c = getc(fp), count = 0; c != EOF;) {
count += ((c == SWITCH) ? getw(fp) : c) - OFFSET;
/* overlay old path */
***************
*** 150,161 ****
if (*p == '0円') { /* fast match success */
found = 1;
if (!globflag ||
! !fnmatch(pathpart, path, 0))
(void)printf("%s\n", path);
break;
}
}
}
}
/*
--- 210,224 ----
if (*p == '0円') { /* fast match success */
found = 1;
if (!globflag ||
! !fnmatch(pathpart, path, 0)) {
(void)printf("%s\n", path);
+ ++printed;
+ }
break;
}
}
}
+ return (printed);
}
/*
State-Changed-From-To: open->closed
State-Changed-By: sjg
State-Changed-When: Sun Aug 15 23:09:41 PDT 1999
State-Changed-Why:
Patch applied.
>Unformatted: