Hello All!
I changed the Matche() function in match.c to work with REGCOMP(3)
(regular expressions). This adds several possibilities in the conf
file. Now you can write something like:
[Operator]
Mask = d-?ra[0-9x]?!~?d-?ra@.*\.d-ra\.net
The default Mask had to be changed slightly:
Mask = .*!ident(a)somewhere\.example\.com
Another advantage: The source code is much more shorter! Keep it as
simple as possible - but not simpler!
The patch:
Index: ngircd/doc/sample-ngircd.conf
===================================================================
RCS file: /srv/cvs/ngircd/ngircd/doc/sample-ngircd.conf,v
retrieving revision 1.37
diff -u -p -r1.37 sample-ngircd.conf
--- ngircd/doc/sample-ngircd.conf 9 Apr 2006 12:27:23 -0000 1.37
+++ ngircd/doc/sample-ngircd.conf 5 Oct 2006 16:14:45 -0000
@@ -115,7 +115,7 @@
;Password = ThePwd
# Optional Mask from which /OPER will be accepted
- ;Mask = *!ident(a)somewhere.example.com
+ ;Mask = .*!ident(a)somewhere\.example\.com
[Operator]
# More [Operator] sections, if you like ...
Index: ngircd/src/ngircd/match.c
===================================================================
RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/match.c,v
retrieving revision 1.4
diff -u -p -r1.4 match.c
--- ngircd/src/ngircd/match.c 31 Jul 2005 20:13:08 -0000 1.4
+++ ngircd/src/ngircd/match.c 5 Oct 2006 16:14:46 -0000
@@ -19,6 +19,8 @@ static char UNUSED id[] = "$Id: match.c,
#include "imp.h"
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
#include "exp.h"
#include "match.h"
@@ -33,9 +35,9 @@ static char UNUSED id[] = "$Id: match.c,
static int Matche PARAMS(( char *p, char *t ));
-static int Matche_After_Star PARAMS(( char *p, char *t ));
+#define MATCH_NONE 7 /* no match in regexec */
#define MATCH_PATTERN 6 /* bad pattern */
#define MATCH_LITERAL 5 /* match failure on literal match */
#define MATCH_RANGE 4 /* match failure on [..] construct */
@@ -52,202 +54,27 @@ Match( char *Pattern, char *String )
else return false;
} /* Match */
-
+/*
+ * p = pattern
+ * t = input text
+ *
+ * */
static int
Matche( char *p, char *t )
{
- register char range_start, range_end;
- bool invert;
- bool member_match;
- bool loop;
+ int erg, status;
+ regex_t preg;
- for( ; *p; p++, t++ )
+ status = regcomp(&preg, p, REG_EXTENDED|REG_NOSUB);
+ if ( status != 0 )
+ erg = MATCH_PATTERN;
+ else
{
- /* if this is the end of the text then this is the end of the match */
- if( ! *t )
- {
- return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT;
- }
-
- /* determine and react to pattern type */
- switch( *p )
- {
- case '?': /* single any character match */
- break;
-
- case '*': /* multiple any character match */
- return Matche_After_Star( p, t );
-
- case '[': /* [..] construct, single member/exclusion character match */
- /* move to beginning of range */
- p++;
-
- /* check if this is a member match or exclusion match */
- invert = false;
- if( *p == '!' || *p == '^' )
- {
- invert = true;
- p++;
- }
-
- /* if closing bracket here or at range start then we have a malformed pattern */
- if ( *p == ']' ) return MATCH_PATTERN;
-
- member_match = false;
- loop = true;
-
- while( loop )
- {
- /* if end of construct then loop is done */
- if( *p == ']' )
- {
- loop = false;
- continue;
- }
-
- /* matching a '!', '^', '-', '\' or a ']' */
- if( *p == '\\' ) range_start = range_end = *++p;
- else range_start = range_end = *p;
-
- /* if end of pattern then bad pattern (Missing ']') */
- if( ! *p ) return MATCH_PATTERN;
-
- /* check for range bar */
- if( *++p == '-' )
- {
- /* get the range end */
- range_end = *++p;
-
- /* if end of pattern or construct then bad pattern */
- if( range_end == '\0' || range_end == ']' ) return MATCH_PATTERN;
-
- /* special character range end */
- if( range_end == '\\' )
- {
- range_end = *++p;
-
- /* if end of text then we have a bad pattern */
- if ( ! range_end ) return MATCH_PATTERN;
- }
-
- /* move just beyond this range */
- p++;
- }
-
- /* if the text character is in range then match found. make sure the range
- * letters have the proper relationship to one another before comparison */
- if( range_start < range_end )
- {
- if( *t >= range_start && *t <= range_end )
- {
- member_match = true;
- loop = false;
- }
- }
- else
- {
- if( *t >= range_end && *t <= range_start )
- {
- member_match = true;
- loop = false;
- }
- }
- }
-
- /* if there was a match in an exclusion set then no match */
- /* if there was no match in a member set then no match */
- if(( invert && member_match ) || ! ( invert || member_match )) return MATCH_RANGE;
-
- /* if this is not an exclusion then skip the rest of the [...]
- * construct that already matched. */
- if( member_match )
- {
- while( *p != ']' )
- {
- /* bad pattern (Missing ']') */
- if( ! *p ) return MATCH_PATTERN;
-
- /* skip exact match */
- if( *p == '\\' )
- {
- p++;
-
- /* if end of text then we have a bad pattern */
- if( ! *p ) return MATCH_PATTERN;
- }
-
- /* move to next pattern char */
- p++;
- }
- }
- break;
- case '\\': /* next character is quoted and must match exactly */
- /* move pattern pointer to quoted char and fall through */
- p++;
-
- /* if end of text then we have a bad pattern */
- if( ! *p ) return MATCH_PATTERN;
-
- /* must match this character exactly */
- default:
- if( *p != *t ) return MATCH_LITERAL;
- }
+ status = regexec(&preg, t, (size_t)0, NULL, 0);
+ erg = status ? MATCH_NONE : MATCH_VALID;
}
- /* if end of text not reached then the pattern fails */
-
- if( *t ) return MATCH_END;
- else return MATCH_VALID;
+ regfree(&preg);
+ return erg;
} /* Matche */
-
-static int
-Matche_After_Star( char *p, char *t )
-{
- register int nextp, match = 0;
-
- /* pass over existing ? and * in pattern */
- while( *p == '?' || *p == '*' )
- {
- /* take one char for each ? and + */
- if (*p == '?')
- {
- /* if end of text then no match */
- if( ! *t++ ) return MATCH_ABORT;
- }
-
- /* move to next char in pattern */
- p++;
- }
-
- /* if end of pattern we have matched regardless of text left */
- if( ! *p ) return MATCH_VALID;
-
- /* get the next character to match which must be a literal or '[' */
- nextp = *p;
- if( nextp == '\\' )
- {
- nextp = p[1];
-
- /* if end of text then we have a bad pattern */
- if( ! nextp ) return MATCH_PATTERN;
- }
-
- /* Continue until we run out of text or definite result seen */
- do
- {
- /* a precondition for matching is that the next character
- * in the pattern match the next character in the text or that
- * the next pattern char is the beginning of a range. Increment
- * text pointer as we go here */
- if( nextp == *t || nextp == '[' ) match = Matche( p, t );
-
- /* if the end of text is reached then no match */
- if( ! *t++ ) match = MATCH_ABORT;
- } while( match != MATCH_VALID && match != MATCH_ABORT && match != MATCH_PATTERN );
-
- /* return result */
- return match;
-} /* Matche_After_Star */
-
-
/* -eof- */
Regards
Dieter