util.c revision 50477
1284990Scy/* 2284990Scy * Copyright (c) 1995 Wolfram Schneider <wosch@FreeBSD.org>. Berlin. 3290000Sglebius * Copyright (c) 1989, 1993 4290000Sglebius * The Regents of the University of California. All rights reserved. 5284990Scy * 6284990Scy * This code is derived from software contributed to Berkeley by 7284990Scy * James A. Woods. 8284990Scy * 9284990Scy * Redistribution and use in source and binary forms, with or without 10284990Scy * modification, are permitted provided that the following conditions 11284990Scy * are met: 12284990Scy * 1. Redistributions of source code must retain the above copyright 13284990Scy * notice, this list of conditions and the following disclaimer. 14284990Scy * 2. Redistributions in binary form must reproduce the above copyright 15284990Scy * notice, this list of conditions and the following disclaimer in the 16293894Sglebius * documentation and/or other materials provided with the distribution. 17284990Scy * 3. All advertising materials mentioning features or use of this software 18284990Scy * must display the following acknowledgement: 19284990Scy * This product includes software developed by the University of 20284990Scy * California, Berkeley and its contributors. 21284990Scy * 4. Neither the name of the University nor the names of its contributors 22284990Scy * may be used to endorse or promote products derived from this software 23284990Scy * without specific prior written permission. 24284990Scy * 25284990Scy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26284990Scy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27284990Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28284990Scy * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29284990Scy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30284990Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31284990Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32284990Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33284990Scy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34284990Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35284990Scy * SUCH DAMAGE. 36284990Scy * 37284990Scy * $FreeBSD: head/usr.bin/locate/locate/util.c 50477 1999-08-28 01:08:13Z peter $ 38284990Scy */ 39284990Scy 40284990Scy 41284990Scy#include <stdlib.h> 42284990Scy#include <string.h> 43284990Scy#include <err.h> 44284990Scy#include <sys/param.h> 45284990Scy#include <stdio.h> 46284990Scy 47284990Scy#include "locate.h" 48284990Scy 49284990Scychar **colon __P((char **, char*, char*)); 50284990Scychar *patprep __P((char *)); 51284990Scyvoid print_matches __P((u_int)); 52284990Scyu_char *tolower_word __P((u_char *)); 53284990Scyint getwm __P((caddr_t)); 54284990Scyint getwf __P((FILE *)); 55284990Scyint check_bigram_char __P((int)); 56284990Scy 57284990Scy/* 58284990Scy * Validate bigram chars. If the test failed the database is corrupt 59284990Scy * or the database is obviously not a locate database. 60284990Scy */ 61284990Scyint 62293894Sglebiuscheck_bigram_char(ch) 63284990Scy int ch; 64293894Sglebius{ 65284990Scy /* legal bigram: 0, ASCII_MIN ... ASCII_MAX */ 66284990Scy if (ch == 0 || 67284990Scy (ch >= ASCII_MIN && ch <= ASCII_MAX)) 68284990Scy return(ch); 69284990Scy 70284990Scy errx(1, 71284990Scy "locate database header corrupt, bigram char outside 0, %d-%d: %d", 72284990Scy ASCII_MIN, ASCII_MAX, ch); 73284990Scy exit(1); 74284990Scy} 75284990Scy 76284990Scy/* split a colon separated string into a char vector 77284990Scy * 78284990Scy * "bla:foo" -> {"foo", "bla"} 79284990Scy * "bla:" -> {"foo", dot} 80284990Scy * "bla" -> {"bla"} 81284990Scy * "" -> do nothing 82284990Scy * 83284990Scy */ 84284990Scychar ** 85284990Scycolon(dbv, path, dot) 86293894Sglebius char **dbv; 87284990Scy char *path; 88293894Sglebius char *dot; /* default for single ':' */ 89284990Scy{ 90284990Scy int vlen, slen; 91284990Scy char *c, *ch, *p; 92284990Scy char **pv; 93284990Scy 94284990Scy if (dbv == NULL) { 95284990Scy if ((dbv = malloc(sizeof(char **))) == NULL) 96284990Scy err(1, "malloc"); 97284990Scy *dbv = NULL; 98284990Scy } 99284990Scy 100284990Scy /* empty string */ 101284990Scy if (*path == '\0') { 102284990Scy warnx("empty database name, ignored"); 103284990Scy return(dbv); 104284990Scy } 105284990Scy 106284990Scy /* length of string vector */ 107284990Scy for(vlen = 0, pv = dbv; *pv != NULL; pv++, vlen++); 108284990Scy 109284990Scy for (ch = c = path; ; ch++) { 110293894Sglebius if (*ch == ':' || 111284990Scy (!*ch && !(*(ch - 1) == ':' && ch == 1+ path))) { 112293894Sglebius /* single colon -> dot */ 113284990Scy if (ch == c) 114284990Scy p = dot; 115284990Scy else { 116284990Scy /* a string */ 117284990Scy slen = ch - c; 118 if ((p = malloc(sizeof(char) * (slen + 1))) 119 == NULL) 120 err(1, "malloc"); 121 bcopy(c, p, slen); 122 *(p + slen) = '\0'; 123 } 124 /* increase dbv with element p */ 125 if ((dbv = realloc(dbv, sizeof(char **) * (vlen + 2))) 126 == NULL) 127 err(1, "realloc"); 128 *(dbv + vlen) = p; 129 *(dbv + ++vlen) = NULL; 130 c = ch + 1; 131 } 132 if (*ch == '\0') 133 break; 134 } 135 return (dbv); 136} 137 138void 139print_matches(counter) 140 u_int counter; 141{ 142 (void)printf("%d\n", counter); 143} 144 145 146/* 147 * extract last glob-free subpattern in name for fast pre-match; prepend 148 * '\0' for backwards match; return end of new pattern 149 */ 150static char globfree[100]; 151 152char * 153patprep(name) 154 char *name; 155{ 156 register char *endmark, *p, *subp; 157 158 subp = globfree; 159 *subp++ = '\0'; /* set first element to '\0' */ 160 p = name + strlen(name) - 1; 161 162 /* skip trailing metacharacters */ 163 for (; p >= name; p--) 164 if (index(LOCATE_REG, *p) == NULL) 165 break; 166 167 /* 168 * check if maybe we are in a character class 169 * 170 * 'foo.[ch]' 171 * |----< p 172 */ 173 if (p >= name && 174 (index(p, '[') != NULL || index(p, ']') != NULL)) { 175 for (p = name; *p != '\0'; p++) 176 if (*p == ']' || *p == '[') 177 break; 178 p--; 179 180 /* 181 * cannot find a non-meta character, give up 182 * '*\*[a-z]' 183 * |-------< p 184 */ 185 if (p >= name && index(LOCATE_REG, *p) != NULL) 186 p = name - 1; 187 } 188 189 if (p < name) 190 /* only meta chars: "???", force '/' search */ 191 *subp++ = '/'; 192 193 else { 194 for (endmark = p; p >= name; p--) 195 if (index(LOCATE_REG, *p) != NULL) 196 break; 197 for (++p; 198 (p <= endmark) && subp < (globfree + sizeof(globfree));) 199 *subp++ = *p++; 200 } 201 *subp = '\0'; 202 return(--subp); 203} 204 205/* tolower word */ 206u_char * 207tolower_word(word) 208 u_char *word; 209{ 210 register u_char *p; 211 212 for(p = word; *p != '\0'; p++) 213 *p = TOLOWER(*p); 214 215 return(word); 216} 217 218 219/* 220 * Read integer from mmap pointer. 221 * Essential a simple ``return *(int *)p'' but avoid sigbus 222 * for integer alignment (SunOS 4.x, 5.x). 223 * 224 * Convert network byte order to host byte order if neccessary. 225 * So we can read on FreeBSD/i386 (little endian) a locate database 226 * which was built on SunOS/sparc (big endian). 227 */ 228 229int 230getwm(p) 231 caddr_t p; 232{ 233 static char buf[INTSIZE]; 234 register int i; 235 236 for (i = 0; i < INTSIZE; i++) 237 buf[i] = *p++; 238 239 i = *(int *)buf; 240 241 if (i > MAXPATHLEN || i < -(MAXPATHLEN)) { 242 i = ntohl(i); 243 if (i > MAXPATHLEN || i < -(MAXPATHLEN)) 244 errx(1, "integer out of +-MAXPATHLEN (%d): %d", MAXPATHLEN, i); 245 } 246 return(i); 247} 248 249/* 250 * Read integer from stream. 251 * 252 * Convert network byte order to host byte order if neccessary. 253 * So we can read on FreeBSD/i386 (little endian) a locate database 254 * which was built on SunOS/sparc (big endian). 255 */ 256 257int 258getwf(fp) 259 FILE *fp; 260{ 261 register int word; 262 263 word = getw(fp); 264 265 if (word > MAXPATHLEN || word < -(MAXPATHLEN)) { 266 word = ntohl(word); 267 if (word > MAXPATHLEN || word < -(MAXPATHLEN)) 268 errx(1, "integer out of +-MAXPATHLEN (%d): %d", MAXPATHLEN, word); 269 } 270 return(word); 271} 272