117980Swosch/*
217980Swosch * Copyright (c) 1995 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
317980Swosch * Copyright (c) 1989, 1993
417980Swosch *	The Regents of the University of California.  All rights reserved.
517980Swosch *
617980Swosch * This code is derived from software contributed to Berkeley by
717980Swosch * James A. Woods.
817980Swosch *
917980Swosch * Redistribution and use in source and binary forms, with or without
1017980Swosch * modification, are permitted provided that the following conditions
1117980Swosch * are met:
1217980Swosch * 1. Redistributions of source code must retain the above copyright
1317980Swosch *    notice, this list of conditions and the following disclaimer.
1417980Swosch * 2. Redistributions in binary form must reproduce the above copyright
1517980Swosch *    notice, this list of conditions and the following disclaimer in the
1617980Swosch *    documentation and/or other materials provided with the distribution.
1717980Swosch * 3. All advertising materials mentioning features or use of this software
1817980Swosch *    must display the following acknowledgement:
1917980Swosch *	This product includes software developed by the University of
2017980Swosch *	California, Berkeley and its contributors.
2117980Swosch * 4. Neither the name of the University nor the names of its contributors
2217980Swosch *    may be used to endorse or promote products derived from this software
2317980Swosch *    without specific prior written permission.
2417980Swosch *
2517980Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2617980Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2717980Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2817980Swosch * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2917980Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3017980Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3117980Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3217980Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3317980Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3417980Swosch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3517980Swosch * SUCH DAMAGE.
3617980Swosch *
3750477Speter * $FreeBSD: releng/10.3/usr.bin/locate/locate/util.c 275034 2014-11-25 12:45:31Z dim $
3817980Swosch */
3917980Swosch
4017980Swosch
4117980Swosch#include <stdlib.h>
4217980Swosch#include <string.h>
4317980Swosch#include <err.h>
4417980Swosch#include <sys/param.h>
4590868Smike#include <arpa/inet.h>
4617980Swosch#include <stdio.h>
4717980Swosch
4817980Swosch#include "locate.h"
4917980Swosch
5092920Simpchar 	**colon(char **, char*, char*);
5192920Simpchar 	*patprep(char *);
5292920Simpvoid print_matches(u_int);
5392920Simpu_char 	*tolower_word(u_char *);
5492920Simpint 	getwm(caddr_t);
5592920Simpint 	getwf(FILE *);
5692920Simpint	check_bigram_char(int);
5717980Swosch
5817980Swosch/*
5917980Swosch * Validate bigram chars. If the test failed the database is corrupt
6017980Swosch * or the database is obviously not a locate database.
6117980Swosch */
6217980Swoschint
6317980Swoschcheck_bigram_char(ch)
6417980Swosch	int ch;
6517980Swosch{
6617980Swosch	/* legal bigram: 0, ASCII_MIN ... ASCII_MAX */
6717980Swosch	if (ch == 0 ||
6817980Swosch	    (ch >= ASCII_MIN && ch <= ASCII_MAX))
6917980Swosch		return(ch);
7017980Swosch
7127574Scharnier	errx(1,
7227574Scharnier		"locate database header corrupt, bigram char outside 0, %d-%d: %d",
7327574Scharnier		ASCII_MIN, ASCII_MAX, ch);
7417980Swosch	exit(1);
7517980Swosch}
7617980Swosch
7717980Swosch/* split a colon separated string into a char vector
7817980Swosch *
7917980Swosch * "bla:foo" -> {"foo", "bla"}
8017980Swosch * "bla:"    -> {"foo", dot}
8117980Swosch * "bla"     -> {"bla"}
8217980Swosch * ""	     -> do nothing
8317980Swosch *
8417980Swosch */
8517980Swoschchar **
8617980Swoschcolon(dbv, path, dot)
8717980Swosch	char **dbv;
8817980Swosch	char *path;
8917980Swosch	char *dot; /* default for single ':' */
9017980Swosch{
9117980Swosch	int vlen, slen;
9217980Swosch	char *c, *ch, *p;
9317980Swosch	char **pv;
9417980Swosch
9517980Swosch	if (dbv == NULL) {
9617980Swosch		if ((dbv = malloc(sizeof(char **))) == NULL)
9717980Swosch			err(1, "malloc");
9817980Swosch		*dbv = NULL;
9917980Swosch	}
10017980Swosch
10117980Swosch	/* empty string */
10217980Swosch	if (*path == '\0') {
10327574Scharnier		warnx("empty database name, ignored");
10417980Swosch		return(dbv);
10517980Swosch	}
10617980Swosch
10717980Swosch	/* length of string vector */
10817980Swosch	for(vlen = 0, pv = dbv; *pv != NULL; pv++, vlen++);
10917980Swosch
11017980Swosch	for (ch = c = path; ; ch++) {
11117980Swosch		if (*ch == ':' ||
11217980Swosch		    (!*ch && !(*(ch - 1) == ':' && ch == 1+ path))) {
11317980Swosch			/* single colon -> dot */
11417980Swosch			if (ch == c)
11517980Swosch				p = dot;
11617980Swosch			else {
11717980Swosch				/* a string */
11817980Swosch				slen = ch - c;
11917980Swosch				if ((p = malloc(sizeof(char) * (slen + 1)))
12017980Swosch				    == NULL)
12117980Swosch					err(1, "malloc");
12217980Swosch				bcopy(c, p, slen);
12317980Swosch				*(p + slen) = '\0';
12417980Swosch			}
12517980Swosch			/* increase dbv with element p */
12617980Swosch			if ((dbv = realloc(dbv, sizeof(char **) * (vlen + 2)))
12717980Swosch			    == NULL)
12817980Swosch				err(1, "realloc");
12917980Swosch			*(dbv + vlen) = p;
13017980Swosch			*(dbv + ++vlen) = NULL;
13117980Swosch			c = ch + 1;
13217980Swosch		}
13317980Swosch		if (*ch == '\0')
13417980Swosch			break;
13517980Swosch	}
13617980Swosch	return (dbv);
13717980Swosch}
13817980Swosch
13917980Swoschvoid
14017980Swoschprint_matches(counter)
14117980Swosch	u_int counter;
14217980Swosch{
14317980Swosch	(void)printf("%d\n", counter);
14417980Swosch}
14517980Swosch
14617980Swosch
14717980Swosch/*
14817980Swosch * extract last glob-free subpattern in name for fast pre-match; prepend
14917980Swosch * '\0' for backwards match; return end of new pattern
15017980Swosch */
15117980Swoschstatic char globfree[100];
15217980Swosch
15317980Swoschchar *
15417980Swoschpatprep(name)
15517980Swosch	char *name;
15617980Swosch{
15717980Swosch	register char *endmark, *p, *subp;
15817980Swosch
15917980Swosch	subp = globfree;
16018829Swosch	*subp++ = '\0';   /* set first element to '\0' */
16117980Swosch	p = name + strlen(name) - 1;
16218829Swosch
16318829Swosch	/* skip trailing metacharacters */
16417980Swosch	for (; p >= name; p--)
165229403Sed		if (strchr(LOCATE_REG, *p) == NULL)
16617980Swosch			break;
16718829Swosch
16818829Swosch	/*
16918829Swosch	 * check if maybe we are in a character class
17018829Swosch	 *
17118829Swosch	 * 'foo.[ch]'
17218829Swosch	 *        |----< p
17318829Swosch	 */
17418829Swosch	if (p >= name &&
175229403Sed	    (strchr(p, '[') != NULL || strchr(p, ']') != NULL)) {
17618829Swosch		for (p = name; *p != '\0'; p++)
17718829Swosch			if (*p == ']' || *p == '[')
17817980Swosch				break;
17918829Swosch		p--;
18018829Swosch
18118829Swosch		/*
18218829Swosch		 * cannot find a non-meta character, give up
18318829Swosch		 * '*\*[a-z]'
18418829Swosch		 *    |-------< p
18518829Swosch		 */
186229403Sed		if (p >= name && strchr(LOCATE_REG, *p) != NULL)
18718829Swosch			p = name - 1;
18818829Swosch	}
18918829Swosch
19018829Swosch	if (p < name)
19118829Swosch		/* only meta chars: "???", force '/' search */
19217980Swosch		*subp++ = '/';
19318829Swosch
19417980Swosch	else {
19517980Swosch		for (endmark = p; p >= name; p--)
196229403Sed			if (strchr(LOCATE_REG, *p) != NULL)
19717980Swosch				break;
19817980Swosch		for (++p;
19917980Swosch		    (p <= endmark) && subp < (globfree + sizeof(globfree));)
20017980Swosch			*subp++ = *p++;
20117980Swosch	}
20217980Swosch	*subp = '\0';
20317980Swosch	return(--subp);
20417980Swosch}
20517980Swosch
20617980Swosch/* tolower word */
20717980Swoschu_char *
20817980Swoschtolower_word(word)
20917980Swosch	u_char *word;
21017980Swosch{
21117980Swosch	register u_char *p;
21217980Swosch
21317980Swosch	for(p = word; *p != '\0'; p++)
21417980Swosch		*p = TOLOWER(*p);
21517980Swosch
21617980Swosch	return(word);
21717980Swosch}
21817980Swosch
21917980Swosch
22017980Swosch/*
221228992Suqs * Read integer from mmap pointer.
222229655Suqs * Essentially a simple ``return *(int *)p'' but avoids sigbus
22317980Swosch * for integer alignment (SunOS 4.x, 5.x).
22417980Swosch *
225228992Suqs * Convert network byte order to host byte order if necessary.
226229655Suqs * So we can read a locate database on FreeBSD/i386 (little endian)
22717980Swosch * which was built on SunOS/sparc (big endian).
22817980Swosch */
22917980Swosch
230229655Suqsint
23117980Swoschgetwm(p)
23217980Swosch	caddr_t p;
23317980Swosch{
23498751Snaddy	union {
23598751Snaddy		char buf[INTSIZE];
23698751Snaddy		int i;
23798751Snaddy	} u;
238275034Sdim	register int i, hi;
23917980Swosch
240190657Sdelphij	for (i = 0; i < (int)INTSIZE; i++)
24198751Snaddy		u.buf[i] = *p++;
24217980Swosch
24398751Snaddy	i = u.i;
24417980Swosch
24517980Swosch	if (i > MAXPATHLEN || i < -(MAXPATHLEN)) {
246275034Sdim		hi = ntohl(i);
247275034Sdim		if (hi > MAXPATHLEN || hi < -(MAXPATHLEN))
248190657Sdelphij			errx(1, "integer out of +-MAXPATHLEN (%d): %u",
249275034Sdim			    MAXPATHLEN, abs(i) < abs(hi) ? i : hi);
250275034Sdim		return(hi);
25117980Swosch	}
25217980Swosch	return(i);
25317980Swosch}
25417980Swosch
25517980Swosch/*
25617980Swosch * Read integer from stream.
25717980Swosch *
258228992Suqs * Convert network byte order to host byte order if necessary.
25917980Swosch * So we can read on FreeBSD/i386 (little endian) a locate database
26017980Swosch * which was built on SunOS/sparc (big endian).
26117980Swosch */
26217980Swosch
26317980Swoschint
26417980Swoschgetwf(fp)
26517980Swosch	FILE *fp;
26617980Swosch{
267275034Sdim	register int word, hword;
26817980Swosch
26917980Swosch	word = getw(fp);
27017980Swosch
27117980Swosch	if (word > MAXPATHLEN || word < -(MAXPATHLEN)) {
272275034Sdim		hword = ntohl(word);
273275034Sdim		if (hword > MAXPATHLEN || hword < -(MAXPATHLEN))
274190657Sdelphij			errx(1, "integer out of +-MAXPATHLEN (%d): %u",
275275034Sdim			    MAXPATHLEN, abs(word) < abs(hword) ? word : hword);
276275034Sdim		return(hword);
27717980Swosch	}
27817980Swosch	return(word);
27917980Swosch}
280