1 |
/* $MidnightBSD$ */ |
2 |
/* |
3 |
* Copyright (c) 1995 Wolfram Schneider <wosch@FreeBSD.org>. Berlin. |
4 |
* Copyright (c) 1989, 1993 |
5 |
* The Regents of the University of California. All rights reserved. |
6 |
* |
7 |
* This code is derived from software contributed to Berkeley by |
8 |
* James A. Woods. |
9 |
* |
10 |
* Redistribution and use in source and binary forms, with or without |
11 |
* modification, are permitted provided that the following conditions |
12 |
* are met: |
13 |
* 1. Redistributions of source code must retain the above copyright |
14 |
* notice, this list of conditions and the following disclaimer. |
15 |
* 2. Redistributions in binary form must reproduce the above copyright |
16 |
* notice, this list of conditions and the following disclaimer in the |
17 |
* documentation and/or other materials provided with the distribution. |
18 |
* 3. All advertising materials mentioning features or use of this software |
19 |
* must display the following acknowledgement: |
20 |
* This product includes software developed by the University of |
21 |
* California, Berkeley and its contributors. |
22 |
* 4. Neither the name of the University nor the names of its contributors |
23 |
* may be used to endorse or promote products derived from this software |
24 |
* without specific prior written permission. |
25 |
* |
26 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
27 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
28 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
29 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
30 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
31 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
32 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
33 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
34 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
35 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
36 |
* SUCH DAMAGE. |
37 |
* |
38 |
* $FreeBSD: stable/10/usr.bin/locate/locate/util.c 275034 2014-11-25 12:45:31Z dim $ |
39 |
*/ |
40 |
|
41 |
|
42 |
#include <stdlib.h> |
43 |
#include <string.h> |
44 |
#include <err.h> |
45 |
#include <sys/param.h> |
46 |
#include <arpa/inet.h> |
47 |
#include <stdio.h> |
48 |
|
49 |
#include "locate.h" |
50 |
|
51 |
char **colon(char **, char*, char*); |
52 |
char *patprep(char *); |
53 |
void print_matches(u_int); |
54 |
u_char *tolower_word(u_char *); |
55 |
int getwm(caddr_t); |
56 |
int getwf(FILE *); |
57 |
int check_bigram_char(int); |
58 |
|
59 |
/* |
60 |
* Validate bigram chars. If the test failed the database is corrupt |
61 |
* or the database is obviously not a locate database. |
62 |
*/ |
63 |
int |
64 |
check_bigram_char(ch) |
65 |
int ch; |
66 |
{ |
67 |
/* legal bigram: 0, ASCII_MIN ... ASCII_MAX */ |
68 |
if (ch == 0 || |
69 |
(ch >= ASCII_MIN && ch <= ASCII_MAX)) |
70 |
return(ch); |
71 |
|
72 |
errx(1, |
73 |
"locate database header corrupt, bigram char outside 0, %d-%d: %d", |
74 |
ASCII_MIN, ASCII_MAX, ch); |
75 |
exit(1); |
76 |
} |
77 |
|
78 |
/* split a colon separated string into a char vector |
79 |
* |
80 |
* "bla:foo" -> {"foo", "bla"} |
81 |
* "bla:" -> {"foo", dot} |
82 |
* "bla" -> {"bla"} |
83 |
* "" -> do nothing |
84 |
* |
85 |
*/ |
86 |
char ** |
87 |
colon(dbv, path, dot) |
88 |
char **dbv; |
89 |
char *path; |
90 |
char *dot; /* default for single ':' */ |
91 |
{ |
92 |
int vlen, slen; |
93 |
char *c, *ch, *p; |
94 |
char **pv; |
95 |
|
96 |
if (dbv == NULL) { |
97 |
if ((dbv = malloc(sizeof(char **))) == NULL) |
98 |
err(1, "malloc"); |
99 |
*dbv = NULL; |
100 |
} |
101 |
|
102 |
/* empty string */ |
103 |
if (*path == '\0') { |
104 |
warnx("empty database name, ignored"); |
105 |
return(dbv); |
106 |
} |
107 |
|
108 |
/* length of string vector */ |
109 |
for(vlen = 0, pv = dbv; *pv != NULL; pv++, vlen++); |
110 |
|
111 |
for (ch = c = path; ; ch++) { |
112 |
if (*ch == ':' || |
113 |
(!*ch && !(*(ch - 1) == ':' && ch == 1+ path))) { |
114 |
/* single colon -> dot */ |
115 |
if (ch == c) |
116 |
p = dot; |
117 |
else { |
118 |
/* a string */ |
119 |
slen = ch - c; |
120 |
if ((p = malloc(sizeof(char) * (slen + 1))) |
121 |
== NULL) |
122 |
err(1, "malloc"); |
123 |
bcopy(c, p, slen); |
124 |
*(p + slen) = '\0'; |
125 |
} |
126 |
/* increase dbv with element p */ |
127 |
if ((dbv = realloc(dbv, sizeof(char **) * (vlen + 2))) |
128 |
== NULL) |
129 |
err(1, "realloc"); |
130 |
*(dbv + vlen) = p; |
131 |
*(dbv + ++vlen) = NULL; |
132 |
c = ch + 1; |
133 |
} |
134 |
if (*ch == '\0') |
135 |
break; |
136 |
} |
137 |
return (dbv); |
138 |
} |
139 |
|
140 |
void |
141 |
print_matches(counter) |
142 |
u_int counter; |
143 |
{ |
144 |
(void)printf("%d\n", counter); |
145 |
} |
146 |
|
147 |
|
148 |
/* |
149 |
* extract last glob-free subpattern in name for fast pre-match; prepend |
150 |
* '\0' for backwards match; return end of new pattern |
151 |
*/ |
152 |
static char globfree[100]; |
153 |
|
154 |
char * |
155 |
patprep(name) |
156 |
char *name; |
157 |
{ |
158 |
register char *endmark, *p, *subp; |
159 |
|
160 |
subp = globfree; |
161 |
*subp++ = '\0'; /* set first element to '\0' */ |
162 |
p = name + strlen(name) - 1; |
163 |
|
164 |
/* skip trailing metacharacters */ |
165 |
for (; p >= name; p--) |
166 |
if (strchr(LOCATE_REG, *p) == NULL) |
167 |
break; |
168 |
|
169 |
/* |
170 |
* check if maybe we are in a character class |
171 |
* |
172 |
* 'foo.[ch]' |
173 |
* |----< p |
174 |
*/ |
175 |
if (p >= name && |
176 |
(strchr(p, '[') != NULL || strchr(p, ']') != NULL)) { |
177 |
for (p = name; *p != '\0'; p++) |
178 |
if (*p == ']' || *p == '[') |
179 |
break; |
180 |
p--; |
181 |
|
182 |
/* |
183 |
* cannot find a non-meta character, give up |
184 |
* '*\*[a-z]' |
185 |
* |-------< p |
186 |
*/ |
187 |
if (p >= name && strchr(LOCATE_REG, *p) != NULL) |
188 |
p = name - 1; |
189 |
} |
190 |
|
191 |
if (p < name) |
192 |
/* only meta chars: "???", force '/' search */ |
193 |
*subp++ = '/'; |
194 |
|
195 |
else { |
196 |
for (endmark = p; p >= name; p--) |
197 |
if (strchr(LOCATE_REG, *p) != NULL) |
198 |
break; |
199 |
for (++p; |
200 |
(p <= endmark) && subp < (globfree + sizeof(globfree));) |
201 |
*subp++ = *p++; |
202 |
} |
203 |
*subp = '\0'; |
204 |
return(--subp); |
205 |
} |
206 |
|
207 |
/* tolower word */ |
208 |
u_char * |
209 |
tolower_word(word) |
210 |
u_char *word; |
211 |
{ |
212 |
register u_char *p; |
213 |
|
214 |
for(p = word; *p != '\0'; p++) |
215 |
*p = TOLOWER(*p); |
216 |
|
217 |
return(word); |
218 |
} |
219 |
|
220 |
|
221 |
/* |
222 |
* Read integer from mmap pointer. |
223 |
* Essentially a simple ``return *(int *)p'' but avoids sigbus |
224 |
* for integer alignment (SunOS 4.x, 5.x). |
225 |
* |
226 |
* Convert network byte order to host byte order if necessary. |
227 |
* So we can read a locate database on FreeBSD/i386 (little endian) |
228 |
* which was built on SunOS/sparc (big endian). |
229 |
*/ |
230 |
|
231 |
int |
232 |
getwm(p) |
233 |
caddr_t p; |
234 |
{ |
235 |
union { |
236 |
char buf[INTSIZE]; |
237 |
int i; |
238 |
} u; |
239 |
register int i, hi; |
240 |
|
241 |
for (i = 0; i < (int)INTSIZE; i++) |
242 |
u.buf[i] = *p++; |
243 |
|
244 |
i = u.i; |
245 |
|
246 |
if (i > MAXPATHLEN || i < -(MAXPATHLEN)) { |
247 |
hi = ntohl(i); |
248 |
if (hi > MAXPATHLEN || hi < -(MAXPATHLEN)) |
249 |
errx(1, "integer out of +-MAXPATHLEN (%d): %u", |
250 |
MAXPATHLEN, abs(i) < abs(hi) ? i : hi); |
251 |
return(hi); |
252 |
} |
253 |
return(i); |
254 |
} |
255 |
|
256 |
/* |
257 |
* Read integer from stream. |
258 |
* |
259 |
* Convert network byte order to host byte order if necessary. |
260 |
* So we can read on FreeBSD/i386 (little endian) a locate database |
261 |
* which was built on SunOS/sparc (big endian). |
262 |
*/ |
263 |
|
264 |
int |
265 |
getwf(fp) |
266 |
FILE *fp; |
267 |
{ |
268 |
register int word, hword; |
269 |
|
270 |
word = getw(fp); |
271 |
|
272 |
if (word > MAXPATHLEN || word < -(MAXPATHLEN)) { |
273 |
hword = ntohl(word); |
274 |
if (hword > MAXPATHLEN || hword < -(MAXPATHLEN)) |
275 |
errx(1, "integer out of +-MAXPATHLEN (%d): %u", |
276 |
MAXPATHLEN, abs(word) < abs(hword) ? word : hword); |
277 |
return(hword); |
278 |
} |
279 |
return(word); |
280 |
} |