Mercurial > noffle
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 ) |