* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: match.c,v 1.10.4.1.4.1.2.4 2002/11/12 18:01:19 martinea Exp $
+ * $Id: match.c,v 1.23 2006/05/25 01:47:12 johnfranks Exp $
*
* functions for checking and matching regular expressions
*/
#include "amanda.h"
#include "regex.h"
-char *validate_regexp(regex)
-char *regex;
+static int match_word(const char *glob, const char *word, const char separator);
+
+char *
+validate_regexp(
+ const char * regex)
{
regex_t regc;
int result;
if ((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
return errmsg;
}
return NULL;
}
-char *clean_regex(regex)
-char *regex;
+char *
+clean_regex(
+ const char * regex)
{
char *result;
int j;
result[j++]='\\';
result[j++]=regex[i];
}
- result[j++] = '\0';
+ result[j] = '\0';
return result;
}
-int match(regex, str)
-char *regex, *str;
+int
+match(
+ const char * regex,
+ const char * str)
{
regex_t regc;
int result;
if((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("regex \"%s\": %s", regex, errmsg);
+ /*NOTREACHED*/
}
if((result = regexec(®c, str, 0, 0, 0)) != 0
&& result != REG_NOMATCH) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("regex \"%s\": %s", regex, errmsg);
+ /*NOTREACHED*/
}
regfree(®c);
return result == 0;
}
-char *validate_glob(glob)
-char *glob;
+char *
+validate_glob(
+ const char * glob)
{
- char *regex = NULL;
+ char *regex;
regex_t regc;
int result;
static char errmsg[STR_SIZE];
regex = glob_to_regex(glob);
if ((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
amfree(regex);
return errmsg;
}
return NULL;
}
-int match_glob(glob, str)
-char *glob, *str;
+int
+match_glob(
+ const char * glob,
+ const char * str)
{
- char *regex = NULL;
+ char *regex;
regex_t regc;
int result;
char errmsg[STR_SIZE];
regex = glob_to_regex(glob);
if((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
- amfree(regex);
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
if((result = regexec(®c, str, 0, 0, 0)) != 0
&& result != REG_NOMATCH) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
- amfree(regex);
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
regfree(®c);
return result == 0;
}
-char *glob_to_regex(glob)
-char *glob;
+char *
+glob_to_regex(
+ const char * glob)
{
char *regex;
char *r;
last_ch = '\0';
for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
if (last_ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
ch = '\0'; /* so last_ch != '\\' next time */
} else if (last_ch == '[' && ch == '!') {
*r++ = '^';
} else if (ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
} else if (ch == '*' || ch == '?') {
*r++ = '[';
*r++ = '^';
|| ch == '$'
|| ch == '|') {
*r++ = '\\';
- *r++ = ch;
+ *r++ = (char)ch;
} else {
- *r++ = ch;
+ *r++ = (char)ch;
}
}
if (last_ch != '\\') {
}
-int match_word(glob, word, separator)
-char *glob, *word;
-char separator;
+int
+match_tar(
+ const char * glob,
+ const char * str)
+{
+ char *regex;
+ regex_t regc;
+ int result;
+ char errmsg[STR_SIZE];
+
+ regex = tar_to_regex(glob);
+ if((result = regcomp(®c, regex,
+ REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
+ error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
+ }
+
+ if((result = regexec(®c, str, 0, 0, 0)) != 0
+ && result != REG_NOMATCH) {
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
+ error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
+ }
+
+ regfree(®c);
+ amfree(regex);
+
+ return result == 0;
+}
+
+char *
+tar_to_regex(
+ const char * glob)
+{
+ char *regex;
+ char *r;
+ size_t len;
+ int ch;
+ int last_ch;
+
+ /*
+ * Allocate an area to convert into. The worst case is a five to
+ * one expansion.
+ */
+ len = strlen(glob);
+ regex = alloc(1 + len * 5 + 1 + 1);
+
+ /*
+ * Do the conversion:
+ *
+ * ? -> [^/]
+ * * -> .*
+ * [!...] -> [^...]
+ *
+ * The following are given a leading backslash to protect them
+ * unless they already have a backslash:
+ *
+ * ( ) { } + . ^ $ |
+ *
+ * Put a leading ^ and trailing $ around the result. If the last
+ * non-escaped character is \ leave the $ off to cause a syntax
+ * error when the regex is compiled.
+ */
+
+ r = regex;
+ *r++ = '^';
+ last_ch = '\0';
+ for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
+ if (last_ch == '\\') {
+ *r++ = (char)ch;
+ ch = '\0'; /* so last_ch != '\\' next time */
+ } else if (last_ch == '[' && ch == '!') {
+ *r++ = '^';
+ } else if (ch == '\\') {
+ *r++ = (char)ch;
+ } else if (ch == '*') {
+ *r++ = '.';
+ *r++ = '*';
+ } else if (ch == '?') {
+ *r++ = '[';
+ *r++ = '^';
+ *r++ = '/';
+ *r++ = ']';
+ } else if (ch == '('
+ || ch == ')'
+ || ch == '{'
+ || ch == '}'
+ || ch == '+'
+ || ch == '.'
+ || ch == '^'
+ || ch == '$'
+ || ch == '|') {
+ *r++ = '\\';
+ *r++ = (char)ch;
+ } else {
+ *r++ = (char)ch;
+ }
+ }
+ if (last_ch != '\\') {
+ *r++ = '$';
+ }
+ *r = '\0';
+
+ return regex;
+}
+
+
+static int
+match_word(
+ const char * glob,
+ const char * word,
+ const char separator)
{
char *regex;
char *r;
size_t lenword;
char *nword;
char *nglob;
- char *g, *w;
+ char *g;
+ const char *w;
int i;
lenword = strlen(word);
for (ch = *g++; ch != '\0'; last_ch = ch, ch = *g++) {
next_ch = *g;
if (last_ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
ch = '\0'; /* so last_ch != '\\' next time */
} else if (last_ch == '[' && ch == '!') {
*r++ = '^';
} else if (ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
} else if (ch == '*' || ch == '?') {
if(ch == '*' && next_ch == '*') {
*r++ = '.';
*r++ = '\\';
*r++ = separator;
}
- *r++ = ch;
+ *r++ = (char)ch;
} else if ( ch == '('
|| ch == ')'
|| ch == '{'
|| ch == '$'
|| ch == '|') {
*r++ = '\\';
- *r++ = ch;
+ *r++ = (char)ch;
} else {
- *r++ = ch;
+ *r++ = (char)ch;
}
}
if(last_ch != '\\') {
}
-int match_host(glob, host)
-char *glob, *host;
+int
+match_host(
+ const char * glob,
+ const char * host)
{
char *lglob, *lhost;
- char *c, *d;
+ char *c;
+ const char *d;
int i;
lglob = (char *)alloc(strlen(glob)+1);
c = lglob, d=glob;
while( *d != '\0')
- *c++ = tolower(*d++);
+ *c++ = (char)tolower(*d++);
*c = *d;
lhost = (char *)alloc(strlen(host)+1);
c = lhost, d=host;
while( *d != '\0')
- *c++ = tolower(*d++);
+ *c++ = (char)tolower(*d++);
*c = *d;
- i = match_word(lglob, lhost, '.');
+ i = match_word(lglob, lhost, (int)'.');
amfree(lglob);
amfree(lhost);
return i;
}
-int match_disk(glob, disk)
-char *glob, *disk;
+int
+match_disk(
+ const char * glob,
+ const char * disk)
{
- int i;
- i = match_word(glob, disk, '/');
- return i;
+ return match_word(glob, disk, '/');
}
-int match_datestamp(dateexp, datestamp)
-char *dateexp, *datestamp;
+int
+match_datestamp(
+ const char * dateexp,
+ const char * datestamp)
{
char *dash;
size_t len, len_suffix;
- int len_prefix;
+ size_t len_prefix;
char firstdate[100], lastdate[100];
char mydateexp[100];
int match_exact;
if(strlen(dateexp) >= 100 || strlen(dateexp) < 1) {
error("Illegal datestamp expression %s",dateexp);
+ /*NOTREACHED*/
}
if(dateexp[0] == '^') {
if((dash = strchr(mydateexp,'-'))) {
if(match_exact == 1) {
error("Illegal datestamp expression %s",dateexp);
+ /*NOTREACHED*/
}
- len = dash - mydateexp;
+ len = (size_t)(dash - mydateexp);
len_suffix = strlen(dash) - 1;
len_prefix = len - len_suffix;
- if(len_prefix < 0) {
- error("Illegal datestamp expression %s",dateexp);
- }
-
dash++;
strncpy(firstdate, mydateexp, len);
firstdate[len] = '\0';
}
}
}
+
+
+int
+match_level(
+ const char * levelexp,
+ const char * level)
+{
+ char *dash;
+ size_t len, len_suffix;
+ size_t len_prefix;
+ char lowend[100], highend[100];
+ char mylevelexp[100];
+ int match_exact;
+
+ if(strlen(levelexp) >= 100 || strlen(levelexp) < 1) {
+ error("Illegal level expression %s",levelexp);
+ /*NOTREACHED*/
+ }
+
+ if(levelexp[0] == '^') {
+ strncpy(mylevelexp, levelexp+1, strlen(levelexp)-1);
+ mylevelexp[strlen(levelexp)-1] = '\0';
+ }
+ else {
+ strncpy(mylevelexp, levelexp, strlen(levelexp));
+ mylevelexp[strlen(levelexp)] = '\0';
+ }
+
+ if(mylevelexp[strlen(mylevelexp)] == '$') {
+ match_exact = 1;
+ mylevelexp[strlen(mylevelexp)] = '\0';
+ }
+ else
+ match_exact = 0;
+
+ if((dash = strchr(mylevelexp,'-'))) {
+ if(match_exact == 1) {
+ error("Illegal level expression %s",levelexp);
+ /*NOTREACHED*/
+ }
+ len = (size_t)(dash - mylevelexp);
+ len_suffix = strlen(dash) - 1;
+ len_prefix = len - len_suffix;
+
+ dash++;
+ strncpy(lowend, mylevelexp, len);
+ lowend[len] = '\0';
+ strncpy(highend, mylevelexp, len_prefix);
+ strncpy(&(highend[len_prefix]), dash, len_suffix);
+ highend[len] = '\0';
+ return ((strncmp(level, lowend, strlen(lowend)) >= 0) &&
+ (strncmp(level, highend , strlen(highend)) <= 0));
+ }
+ else {
+ if(match_exact == 1) {
+ return (strcmp(level, mylevelexp) == 0);
+ }
+ else {
+ return (strncmp(level, mylevelexp, strlen(mylevelexp)) == 0);
+ }
+ }
+}