Mercurial > noffle
diff src/configfile.c @ 128:8897b7e3b108 noffle
[svn] Add article filtering
author | bears |
---|---|
date | Wed, 09 Aug 2000 22:19:17 +0100 |
parents | 6f681d41734c |
children | 7dfbb1c20a81 |
line wrap: on
line diff
--- a/src/configfile.c Tue Jul 25 13:14:54 2000 +0100 +++ b/src/configfile.c Wed Aug 09 22:19:17 2000 +0100 @@ -6,7 +6,7 @@ SPOOLDIR VERSION - $Id: configfile.c 155 2000-06-24 20:28:01Z bears $ + $Id: configfile.c 189 2000-08-09 21:19:17Z bears $ */ #if HAVE_CONFIG_H @@ -17,6 +17,8 @@ #include <ctype.h> #include <limits.h> +#include <regex.h> +#include "filter.h" #include "itemlist.h" #include "log.h" #include "util.h" @@ -554,6 +556,184 @@ config.autoSubscribeMode[ config.numAutoSubscribeMode++ ] = entry; } +static const char * +getToken( const char *line, Str value ) +{ + Bool isQuoted; + char quoteChar; + Bool seenEscape; + char *maxVal; + + while ( *line != '\0' && isspace( *line ) ) + line++; + if ( *line == '\0' ) + return NULL; + + maxVal = &value[ MAXCHAR ]; + isQuoted = ( *line == '\'' || *line == '"' ); + if ( isQuoted ) + { + quoteChar = *line; + line++; + + seenEscape = FALSE; + while ( *line != '\0' + && ( *line != quoteChar || seenEscape ) + && value < maxVal ) + { + if ( seenEscape ) + { + *value++ = *line; + seenEscape = FALSE; + } + else + { + if ( *line == '\\' ) + seenEscape = TRUE; + else + *value++ = *line; + } + line++; + } + + if ( *line == quoteChar ) + line++; + } + else + { + while ( *line != '\0' && ! isspace( *line ) && value < maxVal ) + *value++ = *line++; + } + *value = '\0'; + return line; +} + +static void +getFilter( const char *line ) +{ + Str ruleBuf, value; + const char *l; + char *p, *ruleName; + Filter *f; + FilterRule rule; + Bool seenAction; + + f = new_Filter(); + + /* Skip "filter" */ + l = Utl_restOfLn( line, 1 ); + seenAction = FALSE; + + for(;;) + { + while ( *l != '\0' && isspace( *l ) ) + l++; + + if ( *l == '\0' ) + break; + + /* Get the rule title */ + p = ruleBuf; + while ( *l != '\0' && *l != '=' && *l != '<' && *l != '>' ) + *p++ = *l++; + *p = '\0'; + ruleName = Utl_stripWhiteSpace( ruleBuf ); + Utl_toLower( ruleName ); + + if ( *ruleName == '\0' ) + goto synErr; + + /* Do we know this rule? */ + if ( strcmp( ruleName, "group" ) == 0 ) + rule.type = RULE_NEWSGROUP; + else if ( strcmp( ruleName, "subject" ) == 0 ) + rule.type = RULE_SUBJECT; + else if ( strcmp( ruleName, "from" ) == 0 ) + rule.type = RULE_FROM; + else if ( strcmp( ruleName, "msgid" ) == 0 ) + rule.type = RULE_MSGID; + else if ( strcmp( ruleName, "bytes" ) == 0 ) + rule.type = RULE_BYTES_LT; + else if ( strcmp( ruleName, "lines" ) == 0 ) + rule.type = RULE_LINES_LT; + else if ( strcmp( ruleName, "refs" ) == 0 ) + rule.type = RULE_NOREFS_LT; + else if ( strcmp( ruleName, "xposts" ) == 0 ) + rule.type = RULE_XPOSTS_LT; + else if ( strcmp( ruleName, "action" ) != 0 ) + goto synErr; + + if ( rule.type == RULE_BYTES_LT || + rule.type == RULE_LINES_LT || + rule.type == RULE_NOREFS_LT || + rule.type == RULE_XPOSTS_LT ) + { + if ( *l == '=' ) + rule.type += 1; + else if ( *l == '>' ) + rule.type += 2; + else if ( *l != '<' ) + goto synErr; + } + else if ( *l != '=' ) + goto synErr; + + /* Skip past '=' (or '>' or '<') */ + l++; + + /* OK, we now have a valid rule. What value? */ + l = getToken( l, value ); + if ( l == NULL ) + goto synErr; + + if ( strcmp( ruleName, "action" ) == 0 ) + { + if ( seenAction ) + goto synErr; + + Utl_toLower( value ); + if ( strcmp( value, "full" ) == 0 ) + f->action = FILTER_FULL; + else if ( strcmp( value, "over" ) == 0 ) + f->action = FILTER_XOVER; + else if ( strcmp( value, "thread" ) == 0 ) + f->action = FILTER_THREAD; + else if ( strcmp( value, "discard" ) == 0 ) + f->action = FILTER_DISCARD; + seenAction = TRUE; + } + else if ( rule.type == RULE_NEWSGROUP ) + Utl_allocAndCpy( &rule.data.grp, value ); + else if ( rule.type >= RULE_SUBJECT && rule.type <= RULE_MSGID ) + { + if ( regcomp( &rule.data.regex, value, REG_EXTENDED ) != 0 ) + goto synErr; + } + else + { + char * endVal; + + rule.data.amount = strtoul( value, &endVal, 0 ); + if ( *endVal != '\0' && ! isspace( *endVal ) ) + goto synErr; + } + + if ( strcmp( ruleName, "action" ) != 0 ) + { + Log_dbg( "Adding rule type %d value %s", rule.type, value ); + Flt_addRule( f, rule ); + } + } + + Log_dbg( "Adding filter, action %d", f->action ); + Flt_addFilter( f ); + return; + +synErr: + logSyntaxErr( line ); + return; +} + void Cfg_read( void ) { @@ -573,6 +753,7 @@ Utl_stripComment( p ); Utl_cpyStr( lowerLine, p ); Utl_toLower( lowerLine ); + p = lowerLine; if ( *p == '\0' ) continue; if ( sscanf( p, "%s", name ) != 1 ) @@ -600,7 +781,6 @@ else if ( strcmp( "default-auto-subscribe-mode", name ) == 0 ) { getStr( s, p ); - Utl_toLower( s ); if ( ! isValidAutoSubscribeMode( s ) ) { logSyntaxErr( line ); @@ -609,14 +789,8 @@ else strcpy( config.defaultAutoSubscribeMode, s ); } - else if ( strcmp( "server", name ) == 0 ) - /* Server needs line not p, - because password may contain uppercase */ - getServ( line ); else if ( strcmp( "mail-to", name ) == 0 ) getStr( config.mailTo, p ); - else if ( strcmp( "path-header", name ) == 0 ) - getStr( config.pathHeader, p ); else if ( strcmp( "expire", name ) == 0 ) getExpire( p ); else if ( strcmp( "auto-subscribe-mode", name ) == 0 ) @@ -625,6 +799,13 @@ getGroups( p, TRUE ); else if ( strcmp( "omitgroups", name ) == 0 ) getGroups( p, FALSE ); + /* The following need line because they may have uppercase data */ + else if ( strcmp( "server", name ) == 0 ) + getServ( line ); + else if ( strcmp( "path-header", name ) == 0 ) + getStr( config.pathHeader, p ); + else if ( strcmp( "filter", name ) == 0 ) + getFilter( line ); else Log_err( "Unknown config option: %s", name ); }