From: Hans-Werner Paulsen Date: Mon, 20 Jul 2009 10:06:23 +0000 (+0200) Subject: Use Posix regex(3) within src/bucoord/commands.c X-Git-Tag: openafs-devel-1_5_61~74 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=fc695707f87143f2bfefd1260560cd6fdef613c0;p=packages%2Fo%2Fopenafs.git Use Posix regex(3) within src/bucoord/commands.c Normally pattern matching against volume names is done on the server, but if this fails, the client (src/bucoord/commands.c) is doing this. This program had no code to use regex(3) when HAVE_POSIX_REGEX is defined. This patch adds calls to regex(3) if HAVE_POSIX_REGEX is defined. For systems without POSIX regex there were two (slightly different) implementations in src/bucoord/regex.c and src/util/regex.c. The newer version src/bucoord/regex.c has been modified and moved to src/util/regex.c. Some header files and Makefiles have been removed/updated to work with this setup. Reviewed-on: http://gerrit.openafs.org/http://gerrit.openafs.org/99 Tested-by: Russ Allbery Reviewed-by: Russ Allbery Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear --- diff --git a/src/bucoord/Makefile.in b/src/bucoord/Makefile.in index 1700606c1..58561eead 100644 --- a/src/bucoord/Makefile.in +++ b/src/bucoord/Makefile.in @@ -48,12 +48,12 @@ btest: btest.o ${TOP_LIBDIR}/libbubasics.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/l btest.o: AFS_component_version_number.c -BACKSRCS = main.c config.c dsstub.c volstub.c commands.c regex.c server.c \ +BACKSRCS = main.c config.c dsstub.c volstub.c commands.c server.c \ dsvs.c dump.c restore.c ubik_db_if.c \ dump_sched.c vol_sets.c tape_hosts.c \ bc_status.c status.c dlq.c -BACKOBJS = main.o config.o dsstub.o volstub.o commands.o regex.o server.o \ +BACKOBJS = main.o config.o dsstub.o volstub.o commands.o server.o \ dsvs.o dump.o restore.o ubik_db_if.o dump_sched.o vol_sets.o \ tape_hosts.o bucoord_errs.o bc_status.o status.o dlq.o diff --git a/src/bucoord/NTMakefile b/src/bucoord/NTMakefile index 82b86213a..bf5d49fe4 100644 --- a/src/bucoord/NTMakefile +++ b/src/bucoord/NTMakefile @@ -47,7 +47,6 @@ EXEOBJS =\ $(OUT)\dsstub.obj \ $(OUT)\volstub.obj \ $(OUT)\commands.obj \ - $(OUT)\regex.obj \ $(OUT)\server.obj \ $(OUT)\dsvs.obj \ $(OUT)\dump.obj \ diff --git a/src/bucoord/commands.c b/src/bucoord/commands.c index fc8ecb881..c97a350b4 100644 --- a/src/bucoord/commands.c +++ b/src/bucoord/commands.c @@ -16,9 +16,6 @@ #define _REGEX_RE_COMP #endif #include -#if defined(AFS_LINUX24_ENV) -#include -#endif #include #ifdef AFS_NT40_ENV #include @@ -29,6 +26,7 @@ #endif #include #include +#include #include #include #include /* PA */ @@ -43,11 +41,13 @@ #include #include #include +#ifdef HAVE_POSIX_REGEX /* use POSIX regexp library */ +#include +#endif #include "bc.h" #include "error_macros.h" #include "bucoord_internal.h" #include "bucoord_prototypes.h" -#include "regex.h" extern struct bc_config *bc_globalConfig; extern struct bc_dumpTask bc_dumpTasks[BC_MAXSIMDUMPS]; @@ -440,6 +440,10 @@ EvalVolumeSet1(struct bc_config *aconfig, int foundentry = 0; struct serversort *servers = 0, *ss = 0; struct partitionsort *ps = 0; +#ifdef HAVE_POSIX_REGEX + regex_t re; + int need_regfree = 0; +#endif *avols = (struct bc_volumeDump *)0; ctve = (struct bc_volumeEntry *)0; /* no compiled entry */ @@ -486,6 +490,13 @@ EvalVolumeSet1(struct bc_config *aconfig, /* If the volume entry is not compiled, then compile it */ if (ctve != tve) { sprintf(patt, "^%s$", tve->name); +#ifdef HAVE_POSIX_REGEX + if (regcomp(&re, patt, REG_NOSUB) != 0) { + afs_com_err(whoami, 0, "Can't compile regular expression '%s'", patt); + return (-1); + } + need_regfree = 1; +#else errm = (char *)re_comp(patt); if (errm) { afs_com_err(whoami, 0, @@ -493,6 +504,7 @@ EvalVolumeSet1(struct bc_config *aconfig, patt, errm); return (-1); } +#endif ctve = tve; } @@ -502,8 +514,13 @@ EvalVolumeSet1(struct bc_config *aconfig, if (entry.serverFlags[srvpartpair] & ITSRWVOL) { if (entry.flags & RW_EXISTS) { sprintf(patt, "%s", entry.name); +#ifdef HAVE_POSIX_REGEX + code = regexec(&re, patt, 0, NULL, 0); + if (code == 0) { +#else code = re_exec(patt); if (code == 1) { +#endif found = 1; foundentry = srvpartpair; volType = RWVOL; @@ -516,8 +533,13 @@ EvalVolumeSet1(struct bc_config *aconfig, */ if (entry.flags & BACK_EXISTS) { sprintf(patt, "%s.backup", entry.name); +#ifdef HAVE_POSIX_REGEX + code = regexec(&re, patt, 0, NULL, 0); + if (code == 0) { +#else code = re_exec(patt); if (code == 1) { +#endif found = 1; foundentry = srvpartpair; volType = BACKVOL; @@ -533,8 +555,13 @@ EvalVolumeSet1(struct bc_config *aconfig, else if (!found && (entry.serverFlags[srvpartpair] & ITSROVOL) && (entry.flags & RO_EXISTS)) { sprintf(patt, "%s.readonly", entry.name); +#ifdef HAVE_POSIX_REGEX + code = regexec(&re, patt, 0, NULL, 0); + if (code == 0) { +#else code = re_exec(patt); if (code == 1) { +#endif found = 1; foundentry = srvpartpair; volType = ROVOL; @@ -596,6 +623,10 @@ EvalVolumeSet1(struct bc_config *aconfig, } /*f */ } /*ve */ } /*w */ +#ifdef HAVE_POSIX_REGEX + if (need_regfree) + regfree(&re); +#endif /* Randomly link the volumedump entries together */ randSPEntries(servers, avols); diff --git a/src/bucoord/regex.c b/src/bucoord/regex.c deleted file mode 100644 index 25dd0947f..000000000 --- a/src/bucoord/regex.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -/* - * routines to do regular expression matching - * - * Entry points: - * - * re_comp(s) - * char *s; - * ... returns 0 if the string s was compiled successfully, - * a pointer to an error message otherwise. - * If passed 0 or a null string returns without changing - * the currently compiled re (see note 11 below). - * - * re_exec(s) - * char *s; - * ... returns 1 if the string s matches the last compiled regular - * expression, - * 0 if the string s failed to match the last compiled - * regular expression, and - * -1 if the compiled regular expression was invalid - * (indicating an internal error). - * - * The strings passed to both re_comp and re_exec may have trailing or - * embedded newline characters; they are terminated by nulls. - * - * The identity of the author of these routines is lost in antiquity; - * this is essentially the same as the re code in the original V6 ed. - * - * The regular expressions recognized are described below. This description - * is essentially the same as that for ed. - * - * A regular expression specifies a set of strings of characters. - * A member of this set of strings is said to be matched by - * the regular expression. In the following specification for - * regular expressions the word `character' means any character but NUL. - * - * 1. Any character except a special character matches itself. - * Special characters are the regular expression delimiter plus - * \ [ . and sometimes ^ * $. - * 2. A . matches any character. - * 3. A \ followed by any character except a digit or ( ) - * matches that character. - * 4. A nonempty string s bracketed [s] (or [^s]) matches any - * character in (or not in) s. In s, \ has no special meaning, - * and ] may only appear as the first letter. A substring - * a-b, with a and b in ascending ASCII order, stands for - * the inclusive range of ASCII characters. - * 5. A regular expression of form 1-4 followed by * matches a - * sequence of 0 or more matches of the regular expression. - * 6. A regular expression, x, of form 1-8, bracketed \(x\) - * matches what x matches. - * 7. A \ followed by a digit n matches a copy of the string that the - * bracketed regular expression beginning with the nth \( matched. - * 8. A regular expression of form 1-8, x, followed by a regular - * expression of form 1-7, y matches a match for x followed by - * a match for y, with the x match being as long as possible - * while still permitting a y match. - * 9. A regular expression of form 1-8 preceded by ^ (or followed - * by $), is constrained to matches that begin at the left - * (or end at the right) end of a line. - * 10. A regular expression of form 1-9 picks out the longest among - * the leftmost matches in a line. - * 11. An empty regular expression stands for a copy of the last - * regular expression encountered. - */ - -#include "regex.h" - -/* - * constants for re's - */ -#define CBRA 1 -#define CCHR 2 -#define CDOT 4 -#define CCL 6 -#define NCCL 8 -#define CDOL 10 -#define CEOF 11 -#define CKET 12 -#define CBACK 18 - -#define CSTAR 01 - -#define ESIZE 512 -#define NBRA 9 - -static char expbuf[ESIZE], *braslist[NBRA], *braelist[NBRA]; -static char circf; - -static int advance(char *, char *); -static int backref(int i, char *); -static int cclass(char *, char, int); - -/* - * compile the regular expression argument into a dfa - */ -char * -re_comp(const char *sp) -{ - register int c; - register char *ep = expbuf; - int cclcnt, numbra = 0; - char *lastep = 0; - char bracket[NBRA]; - char *bracketp = &bracket[0]; - static char *retoolong = "Regular expression too long"; - -#define comerr(msg) {expbuf[0] = 0; numbra = 0; return(msg); } - - if (sp == 0 || *sp == '\0') { - if (*ep == 0) - return ("No previous regular expression"); - return (0); - } - if (*sp == '^') { - circf = 1; - sp++; - } else - circf = 0; - for (;;) { - if (ep >= &expbuf[ESIZE]) - comerr(retoolong); - if ((c = *sp++) == '\0') { - if (bracketp != bracket) - comerr("unmatched \\("); - *ep++ = CEOF; - *ep++ = 0; - return (0); - } - if (c != '*') - lastep = ep; - switch (c) { - - case '.': - *ep++ = CDOT; - continue; - - case '*': - if (lastep == 0 || *lastep == CBRA || *lastep == CKET) - goto defchar; - *lastep |= CSTAR; - continue; - - case '$': - if (*sp != '\0') - goto defchar; - *ep++ = CDOL; - continue; - - case '[': - *ep++ = CCL; - *ep++ = 0; - cclcnt = 1; - if ((c = *sp++) == '^') { - c = *sp++; - ep[-2] = NCCL; - } - do { - if (c == '\0') - comerr("missing ]"); - if (c == '-' && ep[-1] != 0) { - if ((c = *sp++) == ']') { - *ep++ = '-'; - cclcnt++; - break; - } - while (ep[-1] < c) { - *ep = ep[-1] + 1; - ep++; - cclcnt++; - if (ep >= &expbuf[ESIZE]) - comerr(retoolong); - } - } - *ep++ = c; - cclcnt++; - if (ep >= &expbuf[ESIZE]) - comerr(retoolong); - } while ((c = *sp++) != ']'); - lastep[1] = cclcnt; - continue; - - case '\\': - if ((c = *sp++) == '(') { - if (numbra >= NBRA) - comerr("too many \\(\\) pairs"); - *bracketp++ = numbra; - *ep++ = CBRA; - *ep++ = numbra++; - continue; - } - if (c == ')') { - if (bracketp <= bracket) - comerr("unmatched \\)"); - *ep++ = CKET; - *ep++ = *--bracketp; - continue; - } - if (c >= '1' && c < ('1' + NBRA)) { - *ep++ = CBACK; - *ep++ = c - '1'; - continue; - } - *ep++ = CCHR; - *ep++ = c; - continue; - - defchar: - default: - *ep++ = CCHR; - *ep++ = c; - } - } -} - -static int -cclass(char *set, char c, int af) -{ - register int n; - - if (c == 0) - return (0); - n = *set++; - while (--n) - if (*set++ == c) - return (af); - return (!af); -} - -static int -backref(int i, char *lp) -{ - register char *bp; - - bp = braslist[i]; - while (*bp++ == *lp++) - if (bp >= braelist[i]) - return (1); - return (0); -} - -/* - * try to match the next thing in the dfa - */ -static int -advance(char *lp, char *ep) -{ - register char *curlp; - int ct, i; - int rv; - - for (;;) - switch (*ep++) { - - case CCHR: - if (*ep++ == *lp++) - continue; - return (0); - - case CDOT: - if (*lp++) - continue; - return (0); - - case CDOL: - if (*lp == '\0') - continue; - return (0); - - case CEOF: - return (1); - - case CCL: - if (cclass(ep, *lp++, 1)) { - ep += *ep; - continue; - } - return (0); - - case NCCL: - if (cclass(ep, *lp++, 0)) { - ep += *ep; - continue; - } - return (0); - - case CBRA: - braslist[(int) *ep++] = lp; - continue; - - case CKET: - braelist[(int) *ep++] = lp; - continue; - - case CBACK: - if (braelist[i = *ep++] == 0) - return (-1); - if (backref(i, lp)) { - lp += braelist[i] - braslist[i]; - continue; - } - return (0); - - case CBACK | CSTAR: - if (braelist[i = *ep++] == 0) - return (-1); - curlp = lp; - ct = braelist[i] - braslist[i]; - while (backref(i, lp)) - lp += ct; - while (lp >= curlp) { - if ((rv = advance(lp, ep))) - return (rv); - lp -= ct; - } - continue; - - case CDOT | CSTAR: - curlp = lp; - while (*lp++); - goto star; - - case CCHR | CSTAR: - curlp = lp; - while (*lp++ == *ep); - ep++; - goto star; - - case CCL | CSTAR: - case NCCL | CSTAR: - curlp = lp; - while (cclass(ep, *lp++, ep[-1] == (CCL | CSTAR))); - ep += *ep; - goto star; - - star: - do { - lp--; - if ((rv = advance(lp, ep))) - return (rv); - } while (lp > curlp); - return (0); - - default: - return (-1); - } -} - -/* - * match the argument string against the compiled re - */ -int -re_exec(const char *p1) -{ - register char *p2 = expbuf; - register int c; - int rv; - - for (c = 0; c < NBRA; c++) { - braslist[c] = 0; - braelist[c] = 0; - } - if (circf) - return ((advance(p1, p2))); - /* - * fast check for first character - */ - if (*p2 == CCHR) { - c = p2[1]; - do { - if (*p1 != c) - continue; - if ((rv = advance(p1, p2))) - return (rv); - } while (*p1++); - return (0); - } - /* - * regular algorithm - */ - do - if ((rv = advance(p1, p2))) - return (rv); - while (*p1++); - return (0); -} - diff --git a/src/bucoord/regex.h b/src/bucoord/regex.h deleted file mode 100644 index 8fb6b0fca..000000000 --- a/src/bucoord/regex.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -#ifndef _BUCOORD_REGEX_H -#define _BUCOORD_REGEX_H -/* regex.c */ -extern char *re_comp(const char *sp); -extern int re_exec(const char *p1); -#endif diff --git a/src/util/afsutil.h b/src/util/afsutil.h index e4dfead76..bf4db4e14 100644 --- a/src/util/afsutil.h +++ b/src/util/afsutil.h @@ -121,14 +121,15 @@ extern char *vctime(const time_t * atime); /* Unbuffer output when Un*x would do line buffering. */ #define setlinebuf(S) setvbuf(S, NULL, _IONBF, 0) -/* regular expression parser for NT */ - extern char *re_comp(char *sp); - extern int rc_exec(char *p); - /* Abort on error, possibly trapping to debugger or dumping a trace. */ void afs_NTAbort(void); #endif /* AFS_NT40_ENV */ +#ifndef HAVE_POSIX_REGEX +extern char *re_comp(const char *sp); +extern int re_exec(const char *p1); +#endif + typedef char b32_string_t[8]; /* b64_string_t is 8 bytes, in stds.h */ typedef char lb64_string_t[12]; diff --git a/src/util/regex.c b/src/util/regex.c index 45999b21b..1c20f960a 100644 --- a/src/util/regex.c +++ b/src/util/regex.c @@ -7,15 +7,6 @@ * directory or online at http://www.openafs.org/dl/license10.html */ -/* - * regex.c -- regular expression patter matching functions - * - */ - -#include -#include - - /* * routines to do regular expression matching * @@ -81,6 +72,9 @@ * regular expression encountered. */ +#include +#include + /* * constants for re's */ @@ -102,19 +96,15 @@ static char expbuf[ESIZE], *braslist[NBRA], *braelist[NBRA]; static char circf; -/* forward defs -*/ - -static int advance(register char *lp, register char *ep); -static int backref(register int i, register char *lp); -static int cclass(register char *set, register char c, int af); - +static int advance(char *, char *); +static int backref(int i, char *); +static int cclass(char *, char, int); /* * compile the regular expression argument into a dfa */ char * -re_comp(register char *sp) +re_comp(const char *sp) { register int c; register char *ep = expbuf; @@ -124,7 +114,7 @@ re_comp(register char *sp) char *bracketp = &bracket[0]; static char *retoolong = "Regular expression too long"; -#define comperr(msg) {expbuf[0] = 0; numbra = 0; return(msg); } +#define comerr(msg) {expbuf[0] = 0; numbra = 0; return(msg); } if (sp == 0 || *sp == '\0') { if (*ep == 0) @@ -138,10 +128,10 @@ re_comp(register char *sp) circf = 0; for (;;) { if (ep >= &expbuf[ESIZE - 10 /* fudge factor */]) - comperr(retoolong); + comerr(retoolong); if ((c = *sp++) == '\0') { if (bracketp != bracket) - comperr("unmatched \\("); + comerr("unmatched \\("); *ep++ = CEOF; *ep++ = 0; return (0); @@ -176,7 +166,7 @@ re_comp(register char *sp) } do { if (c == '\0') - comperr("missing ]"); + comerr("missing ]"); if (c == '-' && ep[-1] != 0) { if ((c = *sp++) == ']') { *ep++ = '-'; @@ -188,13 +178,13 @@ re_comp(register char *sp) ep++; cclcnt++; if (ep >= &expbuf[ESIZE - 10 /* fudge factor */]) - comperr(retoolong); + comerr(retoolong); } } *ep++ = c; cclcnt++; if (ep >= &expbuf[ESIZE - 10 /* fudge factor */]) - comperr(retoolong); + comerr(retoolong); } while ((c = *sp++) != ']'); lastep[1] = cclcnt; continue; @@ -202,7 +192,7 @@ re_comp(register char *sp) case '\\': if ((c = *sp++) == '(') { if (numbra >= NBRA) - comperr("too many \\(\\) pairs"); + comerr("too many \\(\\) pairs"); *bracketp++ = numbra; *ep++ = CBRA; *ep++ = numbra++; @@ -210,7 +200,7 @@ re_comp(register char *sp) } if (c == ')') { if (bracketp <= bracket) - comperr("unmatched \\)"); + comerr("unmatched \\)"); *ep++ = CKET; *ep++ = *--bracketp; continue; @@ -232,42 +222,29 @@ re_comp(register char *sp) } } -/* - * match the argument string against the compiled re - */ -int -re_exec(register char *p1) +static int +cclass(char *set, char c, int af) { - register char *p2 = expbuf; - register int c; - int rv; + register int n; - for (c = 0; c < NBRA; c++) { - braslist[c] = 0; - braelist[c] = 0; - } - if (circf) - return ((advance(p1, p2))); - /* - * fast check for first character - */ - if (*p2 == CCHR) { - c = p2[1]; - do { - if (*p1 != c) - continue; - if ((rv = advance(p1, p2))) - return (rv); - } while (*p1++); + if (c == 0) return (0); - } - /* - * regular algorithm - */ - do - if ((rv = advance(p1, p2))) - return (rv); - while (*p1++); + n = *set++; + while (--n) + if (*set++ == c) + return (af); + return (!af); +} + +static int +backref(int i, char *lp) +{ + register char *bp; + + bp = braslist[i]; + while (*bp++ == *lp++) + if (bp >= braelist[i]) + return (1); return (0); } @@ -275,7 +252,7 @@ re_exec(register char *p1) * try to match the next thing in the dfa */ static int -advance(register char *lp, register char *ep) +advance(char *lp, char *ep) { register char *curlp; int ct, i; @@ -317,11 +294,11 @@ advance(register char *lp, register char *ep) return (0); case CBRA: - braslist[*ep++] = lp; + braslist[(int) *ep++] = lp; continue; case CKET: - braelist[*ep++] = lp; + braelist[(int) *ep++] = lp; continue; case CBACK: @@ -337,7 +314,7 @@ advance(register char *lp, register char *ep) if (braelist[i = *ep++] == 0) return (-1); curlp = lp; - ct = (int)(braelist[i] - braslist[i]); + ct = braelist[i] - braslist[i]; while (backref(i, lp)) lp += ct; while (lp >= curlp) { @@ -378,28 +355,42 @@ advance(register char *lp, register char *ep) } } -static int -backref(register int i, register char *lp) +/* + * match the argument string against the compiled re + */ +int +re_exec(const char *p1) { - register char *bp; + register char *p2 = expbuf; + register int c; + int rv; - bp = braslist[i]; - while (*bp++ == *lp++) - if (bp >= braelist[i]) - return (1); + for (c = 0; c < NBRA; c++) { + braslist[c] = 0; + braelist[c] = 0; + } + if (circf) + return ((advance(p1, p2))); + /* + * fast check for first character + */ + if (*p2 == CCHR) { + c = p2[1]; + do { + if (*p1 != c) + continue; + if ((rv = advance(p1, p2))) + return (rv); + } while (*p1++); + return (0); + } + /* + * regular algorithm + */ + do + if ((rv = advance(p1, p2))) + return (rv); + while (*p1++); return (0); } -static int -cclass(register char *set, register char c, int af) -{ - register int n; - - if (c == 0) - return (0); - n = *set++; - while (--n) - if (*set++ == c) - return (af); - return (!af); -}