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