comparison 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
comparison
equal deleted inserted replaced
127:3c71e28c8eef 128:8897b7e3b108
4 The following macros must be set, when compiling this file: 4 The following macros must be set, when compiling this file:
5 CONFIGFILE 5 CONFIGFILE
6 SPOOLDIR 6 SPOOLDIR
7 VERSION 7 VERSION
8 8
9 $Id: configfile.c 155 2000-06-24 20:28:01Z bears $ 9 $Id: configfile.c 189 2000-08-09 21:19:17Z bears $
10 */ 10 */
11 11
12 #if HAVE_CONFIG_H 12 #if HAVE_CONFIG_H
13 #include <config.h> 13 #include <config.h>
14 #endif 14 #endif
15 15
16 #include "configfile.h" 16 #include "configfile.h"
17 17
18 #include <ctype.h> 18 #include <ctype.h>
19 #include <limits.h> 19 #include <limits.h>
20 #include <regex.h>
21 #include "filter.h"
20 #include "itemlist.h" 22 #include "itemlist.h"
21 #include "log.h" 23 #include "log.h"
22 #include "util.h" 24 #include "util.h"
23 #include "portable.h" 25 #include "portable.h"
24 #include "wildmat.h" 26 #include "wildmat.h"
552 config.maxAutoSubscribeMode += 5; 554 config.maxAutoSubscribeMode += 5;
553 } 555 }
554 config.autoSubscribeMode[ config.numAutoSubscribeMode++ ] = entry; 556 config.autoSubscribeMode[ config.numAutoSubscribeMode++ ] = entry;
555 } 557 }
556 558
559 static const char *
560 getToken( const char *line, Str value )
561 {
562 Bool isQuoted;
563 char quoteChar;
564 Bool seenEscape;
565 char *maxVal;
566
567 while ( *line != '\0' && isspace( *line ) )
568 line++;
569 if ( *line == '\0' )
570 return NULL;
571
572 maxVal = &value[ MAXCHAR ];
573 isQuoted = ( *line == '\'' || *line == '"' );
574 if ( isQuoted )
575 {
576 quoteChar = *line;
577 line++;
578
579 seenEscape = FALSE;
580 while ( *line != '\0'
581 && ( *line != quoteChar || seenEscape )
582 && value < maxVal )
583 {
584 if ( seenEscape )
585 {
586 *value++ = *line;
587 seenEscape = FALSE;
588 }
589 else
590 {
591 if ( *line == '\\' )
592 seenEscape = TRUE;
593 else
594 *value++ = *line;
595 }
596 line++;
597 }
598
599 if ( *line == quoteChar )
600 line++;
601 }
602 else
603 {
604 while ( *line != '\0' && ! isspace( *line ) && value < maxVal )
605 *value++ = *line++;
606 }
607 *value = '\0';
608 return line;
609 }
610
611 static void
612 getFilter( const char *line )
613 {
614 Str ruleBuf, value;
615 const char *l;
616 char *p, *ruleName;
617 Filter *f;
618 FilterRule rule;
619 Bool seenAction;
620
621 f = new_Filter();
622
623 /* Skip "filter" */
624 l = Utl_restOfLn( line, 1 );
625 seenAction = FALSE;
626
627 for(;;)
628 {
629 while ( *l != '\0' && isspace( *l ) )
630 l++;
631
632 if ( *l == '\0' )
633 break;
634
635 /* Get the rule title */
636 p = ruleBuf;
637 while ( *l != '\0' && *l != '=' && *l != '<' && *l != '>' )
638 *p++ = *l++;
639 *p = '\0';
640 ruleName = Utl_stripWhiteSpace( ruleBuf );
641 Utl_toLower( ruleName );
642
643 if ( *ruleName == '\0' )
644 goto synErr;
645
646 /* Do we know this rule? */
647 if ( strcmp( ruleName, "group" ) == 0 )
648 rule.type = RULE_NEWSGROUP;
649 else if ( strcmp( ruleName, "subject" ) == 0 )
650 rule.type = RULE_SUBJECT;
651 else if ( strcmp( ruleName, "from" ) == 0 )
652 rule.type = RULE_FROM;
653 else if ( strcmp( ruleName, "msgid" ) == 0 )
654 rule.type = RULE_MSGID;
655 else if ( strcmp( ruleName, "bytes" ) == 0 )
656 rule.type = RULE_BYTES_LT;
657 else if ( strcmp( ruleName, "lines" ) == 0 )
658 rule.type = RULE_LINES_LT;
659 else if ( strcmp( ruleName, "refs" ) == 0 )
660 rule.type = RULE_NOREFS_LT;
661 else if ( strcmp( ruleName, "xposts" ) == 0 )
662 rule.type = RULE_XPOSTS_LT;
663 else if ( strcmp( ruleName, "action" ) != 0 )
664 goto synErr;
665
666 if ( rule.type == RULE_BYTES_LT ||
667 rule.type == RULE_LINES_LT ||
668 rule.type == RULE_NOREFS_LT ||
669 rule.type == RULE_XPOSTS_LT )
670 {
671 if ( *l == '=' )
672 rule.type += 1;
673 else if ( *l == '>' )
674 rule.type += 2;
675 else if ( *l != '<' )
676 goto synErr;
677 }
678 else if ( *l != '=' )
679 goto synErr;
680
681 /* Skip past '=' (or '>' or '<') */
682 l++;
683
684 /* OK, we now have a valid rule. What value? */
685 l = getToken( l, value );
686 if ( l == NULL )
687 goto synErr;
688
689 if ( strcmp( ruleName, "action" ) == 0 )
690 {
691 if ( seenAction )
692 goto synErr;
693
694 Utl_toLower( value );
695 if ( strcmp( value, "full" ) == 0 )
696 f->action = FILTER_FULL;
697 else if ( strcmp( value, "over" ) == 0 )
698 f->action = FILTER_XOVER;
699 else if ( strcmp( value, "thread" ) == 0 )
700 f->action = FILTER_THREAD;
701 else if ( strcmp( value, "discard" ) == 0 )
702 f->action = FILTER_DISCARD;
703 seenAction = TRUE;
704 }
705 else if ( rule.type == RULE_NEWSGROUP )
706 Utl_allocAndCpy( &rule.data.grp, value );
707 else if ( rule.type >= RULE_SUBJECT && rule.type <= RULE_MSGID )
708 {
709 if ( regcomp( &rule.data.regex, value, REG_EXTENDED ) != 0 )
710 goto synErr;
711 }
712 else
713 {
714 char * endVal;
715
716 rule.data.amount = strtoul( value, &endVal, 0 );
717 if ( *endVal != '\0' && ! isspace( *endVal ) )
718 goto synErr;
719 }
720
721 if ( strcmp( ruleName, "action" ) != 0 )
722 {
723 Log_dbg( "Adding rule type %d value %s", rule.type, value );
724 Flt_addRule( f, rule );
725 }
726 }
727
728 Log_dbg( "Adding filter, action %d", f->action );
729 Flt_addFilter( f );
730 return;
731
732 synErr:
733 logSyntaxErr( line );
734 return;
735 }
736
557 void 737 void
558 Cfg_read( void ) 738 Cfg_read( void )
559 { 739 {
560 char *p; 740 char *p;
561 FILE *f; 741 FILE *f;
571 { 751 {
572 p = Utl_stripWhiteSpace( line ); 752 p = Utl_stripWhiteSpace( line );
573 Utl_stripComment( p ); 753 Utl_stripComment( p );
574 Utl_cpyStr( lowerLine, p ); 754 Utl_cpyStr( lowerLine, p );
575 Utl_toLower( lowerLine ); 755 Utl_toLower( lowerLine );
756 p = lowerLine;
576 if ( *p == '\0' ) 757 if ( *p == '\0' )
577 continue; 758 continue;
578 if ( sscanf( p, "%s", name ) != 1 ) 759 if ( sscanf( p, "%s", name ) != 1 )
579 Log_err( "Syntax error in %s: %s", file, line ); 760 Log_err( "Syntax error in %s: %s", file, line );
580 else if ( strcmp( "max-fetch", name ) == 0 ) 761 else if ( strcmp( "max-fetch", name ) == 0 )
598 else if ( strcmp( "post-locally", name ) == 0 ) 779 else if ( strcmp( "post-locally", name ) == 0 )
599 getBool( &config.postLocal, p ); 780 getBool( &config.postLocal, p );
600 else if ( strcmp( "default-auto-subscribe-mode", name ) == 0 ) 781 else if ( strcmp( "default-auto-subscribe-mode", name ) == 0 )
601 { 782 {
602 getStr( s, p ); 783 getStr( s, p );
603 Utl_toLower( s );
604 if ( ! isValidAutoSubscribeMode( s ) ) 784 if ( ! isValidAutoSubscribeMode( s ) )
605 { 785 {
606 logSyntaxErr( line ); 786 logSyntaxErr( line );
607 return; 787 return;
608 } 788 }
609 else 789 else
610 strcpy( config.defaultAutoSubscribeMode, s ); 790 strcpy( config.defaultAutoSubscribeMode, s );
611 } 791 }
612 else if ( strcmp( "server", name ) == 0 )
613 /* Server needs line not p,
614 because password may contain uppercase */
615 getServ( line );
616 else if ( strcmp( "mail-to", name ) == 0 ) 792 else if ( strcmp( "mail-to", name ) == 0 )
617 getStr( config.mailTo, p ); 793 getStr( config.mailTo, p );
618 else if ( strcmp( "path-header", name ) == 0 )
619 getStr( config.pathHeader, p );
620 else if ( strcmp( "expire", name ) == 0 ) 794 else if ( strcmp( "expire", name ) == 0 )
621 getExpire( p ); 795 getExpire( p );
622 else if ( strcmp( "auto-subscribe-mode", name ) == 0 ) 796 else if ( strcmp( "auto-subscribe-mode", name ) == 0 )
623 getAutoSubscribeMode( p ); 797 getAutoSubscribeMode( p );
624 else if ( strcmp( "getgroups", name ) == 0 ) 798 else if ( strcmp( "getgroups", name ) == 0 )
625 getGroups( p, TRUE ); 799 getGroups( p, TRUE );
626 else if ( strcmp( "omitgroups", name ) == 0 ) 800 else if ( strcmp( "omitgroups", name ) == 0 )
627 getGroups( p, FALSE ); 801 getGroups( p, FALSE );
802 /* The following need line because they may have uppercase data */
803 else if ( strcmp( "server", name ) == 0 )
804 getServ( line );
805 else if ( strcmp( "path-header", name ) == 0 )
806 getStr( config.pathHeader, p );
807 else if ( strcmp( "filter", name ) == 0 )
808 getFilter( line );
628 else 809 else
629 Log_err( "Unknown config option: %s", name ); 810 Log_err( "Unknown config option: %s", name );
630 } 811 }
631 fclose( f ); 812 fclose( f );
632 if ( ! config.numServ ) 813 if ( ! config.numServ )