Subject: bin/21545: 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:49:04
>Number:         21545
>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:50: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.

	This pr is a fix to the previous fix where I forgot to add the -i option
	in the help message printed. This pr containes the updated patch and
	also update for the locate(1) manual. 
>How-To-Repeat:
>Fix:

diff for locate.c:

--- locate.c	Mon May 12 03:52:35 2003
+++ ../../nlocate/locate/locate.c	Mon May 12 06:25:09 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,15 +147,18 @@
 	
 	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) {
-		(void)fprintf(stderr, "Usage: %s [-d dbpath] pattern ...\n",
+		(void)fprintf(stderr, "Usage: %s [-i] [-d dbpath] pattern ...\n",
 		    getprogname());
 		exit(1);
 	}
@@ -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;
 }


diff for locate.1:

--- ../../nlocate/locate/locate.1	Thu Apr 10 03:23:11 2003
+++ locate.1	Mon May 12 06:31:56 2003
@@ -41,6 +41,7 @@
 .Nd find files
 .Sh SYNOPSIS
 .Nm
+.Op Fl i
 .Op Fl d Ar dbpath
 .Ar pattern
 .Sh DESCRIPTION
@@ -65,6 +66,8 @@
 .Pp
 Options:
 .Bl -tag -width flag
+.It Fl i
+Ignore case distinctions in PATTERN
 .It Fl d Ar dbpath
 Sets the list of databases to search to
 .Ar dbpath
>Release-Note:
>Audit-Trail:
>Unformatted: