X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fbregex.c;h=6df0c745563a84bdfcaeb317fa11ceebaba70304;hb=4132c9f33642f579d89700f36caced609d374d51;hp=cc981403043b71ba077c78951013008da60914ab;hpb=44e115222f274997972374abe35570413cd58b2b;p=bacula%2Fbacula diff --git a/bacula/src/lib/bregex.c b/bacula/src/lib/bregex.c index cc98140304..6df0c74556 100644 --- a/bacula/src/lib/bregex.c +++ b/bacula/src/lib/bregex.c @@ -26,11 +26,40 @@ * Peters, Guido van Rossum, Ka-Ping Yee, Sjoerd Mullender, and * probably one or two others that I'm forgetting. * - * $Id$ - * * This file modified to work with Bacula and C++ by * Kern Sibbald, April 2006 + * + * This file modified to work with REG_ICASE and Bacula by + * Eric Bollengier April 2007 */ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2006-2010 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ + #include "bacula.h" #include "bregex.h" @@ -488,51 +517,51 @@ void re_compile_initialize(void) plain_ops[(int)'\174'] = Ror; } else { quoted_ops[(int)'\174'] = Ror; - plain_ops[(int)'*'] = Rstar; - if (regexp_syntax & RE_BK_PLUS_QM) { - quoted_ops[(int)'+'] = Rplus; - quoted_ops[(int)'?'] = Roptional; - } else { - plain_ops[(int)'+'] = Rplus; - plain_ops[(int)'?'] = Roptional; - } - if (regexp_syntax & RE_NEWLINE_OR) { - plain_ops[(int)'\n'] = Ror; - } - plain_ops[(int)'\133'] = Ropenset; - plain_ops[(int)'\136'] = Rbol; - plain_ops[(int)'$'] = Reol; - plain_ops[(int)'.'] = Ranychar; - if (!(regexp_syntax & RE_NO_GNU_EXTENSIONS)) { - quoted_ops[(int)'w'] = Rwordchar; - quoted_ops[(int)'W'] = Rnotwordchar; - quoted_ops[(int)'<'] = Rwordbeg; - quoted_ops[(int)'>'] = Rwordend; - quoted_ops[(int)'b'] = Rwordbound; - quoted_ops[(int)'B'] = Rnotwordbound; - quoted_ops[(int)'`'] = Rbegbuf; - quoted_ops[(int)'\''] = Rendbuf; - } - if (regexp_syntax & RE_ANSI_HEX) { - quoted_ops[(int)'v'] = Rextended_memory; - } - for (a = 0; a < Rnum_ops; a++) { - precedences[a] = 4; - } - if (regexp_syntax & RE_TIGHT_VBAR) { - precedences[Ror] = 3; - precedences[Rbol] = 2; - precedences[Reol] = 2; - } else { - precedences[Ror] = 2; - precedences[Rbol] = 3; - precedences[Reol] = 3; - } - precedences[Rclosepar] = 1; - precedences[Rend] = 0; - regexp_context_indep_ops = (regexp_syntax & RE_CONTEXT_INDEP_OPS) != 0; - regexp_ansi_sequences = (regexp_syntax & RE_ANSI_HEX) != 0; } + plain_ops[(int)'*'] = Rstar; + if (regexp_syntax & RE_BK_PLUS_QM) { + quoted_ops[(int)'+'] = Rplus; + quoted_ops[(int)'?'] = Roptional; + } else { + plain_ops[(int)'+'] = Rplus; + plain_ops[(int)'?'] = Roptional; + } + if (regexp_syntax & RE_NEWLINE_OR) { + plain_ops[(int)'\n'] = Ror; + } + plain_ops[(int)'\133'] = Ropenset; + plain_ops[(int)'\136'] = Rbol; + plain_ops[(int)'$'] = Reol; + plain_ops[(int)'.'] = Ranychar; + if (!(regexp_syntax & RE_NO_GNU_EXTENSIONS)) { + quoted_ops[(int)'w'] = Rwordchar; + quoted_ops[(int)'W'] = Rnotwordchar; + quoted_ops[(int)'<'] = Rwordbeg; + quoted_ops[(int)'>'] = Rwordend; + quoted_ops[(int)'b'] = Rwordbound; + quoted_ops[(int)'B'] = Rnotwordbound; + quoted_ops[(int)'`'] = Rbegbuf; + quoted_ops[(int)'\''] = Rendbuf; + } + if (regexp_syntax & RE_ANSI_HEX) { + quoted_ops[(int)'v'] = Rextended_memory; + } + for (a = 0; a < Rnum_ops; a++) { + precedences[a] = 4; + } + if (regexp_syntax & RE_TIGHT_VBAR) { + precedences[Ror] = 3; + precedences[Rbol] = 2; + precedences[Reol] = 2; + } else { + precedences[Ror] = 2; + precedences[Rbol] = 3; + precedences[Reol] = 3; + } + precedences[Rclosepar] = 1; + precedences[Rend] = 0; + regexp_context_indep_ops = (regexp_syntax & RE_CONTEXT_INDEP_OPS) != 0; + regexp_ansi_sequences = (regexp_syntax & RE_ANSI_HEX) != 0; } int re_set_syntax(int syntax) { @@ -1071,7 +1100,7 @@ const char *re_compile_pattern(regex_t * bufp, unsigned char *regex) alloc = bufp->allocated; if (alloc == 0 || pattern == NULL) { alloc = 256; - pattern = (unsigned char *)malloc(alloc); + bufp->buffer = pattern = (unsigned char *)malloc(alloc); if (!pattern) goto out_of_memory; } @@ -1431,13 +1460,39 @@ if (translate) \ int regcomp(regex_t * bufp, const char *regex, int cflags) { memset(bufp, 0, sizeof(regex_t)); - re_compile_pattern(bufp, (unsigned char *)regex); + bufp->cflags = cflags; + if (bufp->cflags & REG_ICASE) { + char *p, *lcase = bstrdup(regex); + for( p = lcase; *p ; p++) { + *p = tolower(*p); + } + re_compile_pattern(bufp, (unsigned char *)lcase); + bfree(lcase); + } else { + re_compile_pattern(bufp, (unsigned char *)regex); + } if (got_error) { return -1; } return 0; } +void re_registers_to_regmatch(regexp_registers_t old_regs, + regmatch_t pmatch[], + size_t nmatch) +{ + size_t i=0; + + /* We have to set the last entry to -1 */ + nmatch = nmatch - 1; + for (i=0; (i < nmatch) && (old_regs->start[i] > -1) ; i++) { + pmatch[i].rm_so = old_regs->start[i]; + pmatch[i].rm_eo = old_regs->end[i]; + } + + pmatch[i].rm_eo = pmatch[i].rm_so = -1; +} + int regexec(regex_t * preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { @@ -1445,6 +1500,9 @@ int regexec(regex_t * preg, const char *string, size_t nmatch, int len = strlen(string); struct re_registers regs; stat = re_search(preg, (unsigned char *)string, len, 0, len, ®s); + if (stat >= 0) { + re_registers_to_regmatch(®s, pmatch, nmatch); + } /* stat is the start position in the string base 0 where * the pattern was found or negative if not found. */ @@ -1459,6 +1517,14 @@ size_t regerror(int errcode, regex_t * preg, char *errbuf, size_t errbuf_size) void regfree(regex_t * preg) { + if (preg->lcase) { + free_pool_memory(preg->lcase); + preg->lcase = NULL; + } + if (preg->buffer) { + free(preg->buffer); + preg->buffer = NULL; + } } int re_match(regex_t * bufp, unsigned char *string, int size, int pos, @@ -1857,7 +1923,7 @@ int re_match(regex_t * bufp, unsigned char *string, int size, int pos, #undef PREFETCH #undef NEXTCHAR -int re_search(regex_t * bufp, unsigned char *string, int size, int pos, +int re_search(regex_t * bufp, unsigned char *str, int size, int pos, int range, regexp_registers_t regs) { unsigned char *fastmap; @@ -1868,6 +1934,21 @@ int re_search(regex_t * bufp, unsigned char *string, int size, int pos, int dir; int ret; unsigned char anchor; + unsigned char *string = str; + + if (bufp->cflags & REG_ICASE) { /* we must use string in lowercase */ + int len = strlen((const char *)str); + if (!bufp->lcase) { + bufp->lcase = get_pool_memory(PM_FNAME); + } + bufp->lcase = check_pool_memory_size(bufp->lcase, len+1); + unsigned char *dst = (unsigned char *)bufp->lcase; + while (*string) { + *dst++ = tolower(*string++); + } + *dst = '\0'; + string = (unsigned char *)bufp->lcase; + } // assert(size >= 0 && pos >= 0); // assert(pos + range >= 0 && pos + range <= size); /* Bugfix by ylo */