Subject: bin/21544: new option added to locate(1) utility
To: None <gnats-bugs@gnats.netbsd.org>
From: None <majidf@netbsd.se>
List: netbsd-bugs
Date: 05/12/2003 06:14:42
>Number: 21544
>Category: bin
>Synopsis: added -i to locate(1)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon May 12 04:16:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: majidf@netbsd.se
>Release: NetBSD 1.6.1
>Organization:
netbsd.se
>Environment:
System: NetBSD arwa.netbsd.se 1.6.1 NetBSD 1.6.1 (GENERIC) #0: Wed Apr 9 03:02:04 UTC 2003 autobuild@tgm.daemon.org:/autobuild/netbsd-1-6/sparc/OBJ/autobuild/netbsd-1-6/src/sys/arch/sparc/compile/GENERIC sparc
Architecture: sparc
Machine: sparc
>Description:
Added a new option for the locate(1) utility that allows the user to
specify -i option so that locate ignores cases. This option is useful
sometimes and is quicker than piping to grep.
>How-To-Repeat:
>Fix:
--- locate.c Mon May 12 03:52:35 2003
+++ ../../nlocate/locate/locate.c Mon May 12 05:30:13 2003
@@ -105,10 +105,11 @@
static void add_db(const char *);
static int fastfind(FILE *, char *);
+static int fastfind_icase(FILE *, char*);
static char *patprep(const char *);
int main(int, char **);
-
+int f_icase = 0;
static void
add_db(const char *path)
@@ -146,11 +147,14 @@
LIST_INIT(&db_list);
- while ((c = getopt(argc, argv, "d:")) != EOF) {
+ while ((c = getopt(argc, argv, "id:")) != EOF) {
switch (c) {
case 'd':
locate_path = optarg;
break;
+ case 'i':
+ f_icase = 1;
+ break;
}
}
if (argc <= optind) {
@@ -172,7 +176,11 @@
exit(1);
for (; optind < argc; ++optind) {
LIST_FOREACH(dbp, &db_list, db_link) {
- rc = fastfind(dbp->db_fp, argv[optind]);
+ if (!f_icase) {
+ rc = fastfind(dbp->db_fp, argv[optind]);
+ } else {
+ rc = fastfind_icase(dbp->db_fp, argv[optind]);
+ }
if (rc > 0) {
/* some results found */
found = 1;
@@ -291,4 +299,64 @@
}
*subp = '\0';
return --subp;
+}
+
+static int
+fastfind_icase(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);
+
+ p = pathpart;
+ 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 */
+ for (p = path + count; (c = getc(fp)) > SWITCH;) {
+ /* sanity check */
+ if (p < path || p >= path + sizeof(path) - 2)
+ return -1; /* invalid database file */
+ if (c < PARITY)
+ *p++ = c;
+ else { /* bigrams are parity-marked */
+ c &= PARITY - 1;
+ /* sanity check */
+ if (c < 0 || c >= sizeof(bigram1))
+ return -1; /* invalid database file */
+ *p++ = bigram1[c], *p++ = bigram2[c];
+ }
+ }
+ *p-- = '\0';
+ if (p < path || count < 0)
+ return -1;
+ cutoff = (found ? path : path + count);
+ for (found = 0, s = p; s >= cutoff; s--)
+ if (tolower(*s) == tolower(*patend)) { /* fast first char check */
+ for (p = patend - 1, q = s - 1; *p != '\0';
+ p--, q--)
+ if (tolower(*q) != tolower(*p))
+ break;
+ if (*p == '\0') { /* fast match success */
+ found = 1;
+ if (!globflag ||
+ !fnmatch(pathpart, path, FNM_CASEFOLD)) {
+ (void)printf("%s\n", path);
+ ++printed;
+ }
+ break;
+ }
+ }
+ }
+ return printed;
}
>Release-Note:
>Audit-Trail:
>Unformatted: