109109 * them. Helpers below facilitate that.
110110 */
111111
112+ unsigned short number_of_regex = 0 ;
113+ unsigned short number_of_db_regex = 0 ;
114+
112115static const char *
113116__alloc_and_copy_literal (const char * src , size_t len , bool keep_bs )
114117{
@@ -397,6 +400,9 @@ typedef enum {
397400 TOKEN_SEMICOLON ,
398401 TOKEN_LITERAL ,
399402 TOKEN_ARROW ,
403+ TOKEN_TILDA ,
404+ TOKEN_REGEX ,
405+ TOKEN_REGEX_CI ,
400406 _TOKEN_COUNT ,
401407} token_t ;
402408
@@ -588,9 +594,12 @@ read_next_token(TfwCfgParserState *ps)
588594 TOKEN_NEQSIGN );
589595 TFSM_COND_MOVE_EXIT (ps -> c == '>' && ps -> prev_c == '-' ,
590596 TOKEN_ARROW );
597+ TFSM_COND_MOVE_EXIT (ps -> c == '*' && ps -> prev_c == '~' ,
598+ TOKEN_REGEX_CI );
591599
592600 /* Special case to differ single equal sign from double one. */
593601 TFSM_COND_MOVE (ps -> c == '=' , TS_EQSIGN );
602+ TFSM_COND_MOVE (ps -> c == '~' , TS_TILDA );
594603
595604 /* Everything else is not a special character and therefore
596605 * it starts a literal. */
@@ -619,6 +628,14 @@ read_next_token(TfwCfgParserState *ps)
619628 TFSM_JMP_EXIT (TOKEN_EQSIGN );
620629 }
621630
631+ FSM_STATE (TS_TILDA ) {
632+ TFSM_COND_JMP_EXIT (!ps -> c , TOKEN_REGEX );
633+
634+ /* If this is double equal sign, eat second sign and exit. */
635+ TFSM_COND_MOVE_EXIT (ps -> c == '*' , TOKEN_REGEX_CI );
636+ TFSM_JMP_EXIT (TOKEN_REGEX );
637+ }
638+
622639 FSM_STATE (TS_COMMENT ) {
623640 TFSM_COND_JMP_EXIT (!ps -> c , TOKEN_NA );
624641
@@ -732,7 +749,21 @@ entry_set_cond(TfwCfgEntry *e, token_t cond_type, const char *src, int len)
732749 if (!(e -> name = alloc_and_copy_literal (name , name_len )))
733750 return - ENOMEM ;
734751
735- rule -> inv = cond_type == TOKEN_DEQSIGN ? false : true;
752+ switch (cond_type ) {
753+ case TOKEN_REGEX :
754+ rule -> regex = TFW_REGEX_REGULAR ;
755+ rule -> inv = false;
756+ break ;
757+ case TOKEN_REGEX_CI :
758+ rule -> regex = TFW_REGEX_CI ;
759+ rule -> inv = false;
760+ break ;
761+ default :
762+ rule -> regex = TFW_REGEX_NO ;
763+ rule -> inv = cond_type == TOKEN_DEQSIGN ? false : true;
764+ break ;
765+ }
766+
736767 return 0 ;
737768}
738769
@@ -806,8 +837,10 @@ parse_cfg_entry(TfwCfgParserState *ps)
806837
807838 FSM_STATE (PS_PLAIN_OR_RULE ) {
808839 PFSM_COND_MOVE (ps -> t == TOKEN_DEQSIGN ||
809- ps -> t == TOKEN_NEQSIGN ,
810- PS_RULE_COND );
840+ ps -> t == TOKEN_NEQSIGN ||
841+ ps -> t == TOKEN_REGEX ||
842+ ps -> t == TOKEN_REGEX_CI ,
843+ PS_RULE_COND );
811844 PFSM_COND_MOVE (ps -> t == TOKEN_LITERAL , PS_PLAIN_OR_LONG_RULE );
812845
813846 /* Jump to plain val/attr scheme to make remained checks
@@ -819,35 +852,41 @@ parse_cfg_entry(TfwCfgParserState *ps)
819852
820853 FSM_STATE (PS_PLAIN_OR_LONG_RULE ) {
821854 FSM_COND_JMP (ps -> t == TOKEN_DEQSIGN ||
822- ps -> t == TOKEN_NEQSIGN ,
823- PS_LONG_RULE_COND );
855+ ps -> t == TOKEN_NEQSIGN ||
856+ ps -> t == TOKEN_REGEX ||
857+ ps -> t == TOKEN_REGEX_CI ,
858+ PS_LONG_RULE_COND );
824859
825860 /* This is not rule (simple or extended), so jump to
826861 * plain val/attr scheme. */
827862 ps -> err = entry_set_name (& ps -> e );
828863 FSM_COND_JMP (ps -> err , PS_EXIT );
829864 FSM_COND_JMP (ps -> t == TOKEN_EQSIGN , PS_STORE_ATTR_PREV );
830865 FSM_COND_JMP (ps -> t == TOKEN_LITERAL ||
831- ps -> t == TOKEN_SEMICOLON ||
832- ps -> t == TOKEN_LBRACE ,
833- PS_STORE_VAL_PREV );
866+ ps -> t == TOKEN_SEMICOLON ||
867+ ps -> t == TOKEN_LBRACE ,
868+ PS_STORE_VAL_PREV );
834869
835870 ps -> err = - EINVAL ;
836871 FSM_JMP (PS_EXIT );
837872 }
838873
839874 FSM_STATE (PS_LONG_RULE_COND ) {
840875 ps -> err = entry_add_rule_param (& ps -> e .rule .fst_ext ,
841- ps -> prev_lit ,
842- ps -> prev_lit_len );
876+ ps -> prev_lit ,
877+ ps -> prev_lit_len );
843878 FSM_COND_JMP (ps -> err , PS_EXIT );
844879 PFSM_MOVE (PS_RULE_COND );
845880 }
846881
847882 FSM_STATE (PS_RULE_COND ) {
883+ FSM_COND_JMP (ps -> prev_t == TOKEN_REGEX ||
884+ ps -> prev_t == TOKEN_REGEX_CI ,
885+ PS_STORE_VAL_PREV_REGEX );
886+
848887 PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
849888 ps -> err = entry_set_cond (& ps -> e , ps -> prev_t , ps -> lit ,
850- ps -> lit_len );
889+ ps -> lit_len );
851890 FSM_COND_JMP (ps -> err , PS_EXIT );
852891 PFSM_MOVE (PS_RULE_COND_END );
853892 }
@@ -866,7 +905,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
866905 FSM_STATE (PS_RULE_ACTION ) {
867906 PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
868907 ps -> err = entry_add_rule_param (& ps -> e .rule .act , ps -> lit ,
869- ps -> lit_len );
908+ ps -> lit_len );
870909 FSM_COND_JMP (ps -> err , PS_EXIT );
871910 PFSM_MOVE (PS_RULE_ACTION_VAL );
872911 }
@@ -878,7 +917,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
878917 PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
879918
880919 ps -> err = entry_add_rule_param (& ps -> e .rule .val , ps -> lit ,
881- ps -> lit_len );
920+ ps -> lit_len );
882921 FSM_COND_JMP (ps -> err , PS_EXIT );
883922
884923 read_next_token (ps );
@@ -914,6 +953,38 @@ parse_cfg_entry(TfwCfgParserState *ps)
914953 FSM_JMP (PS_STORE_VAL_PREV );
915954 }
916955
956+ FSM_STATE (PS_STORE_VAL_PREV_REGEX ) {
957+ /* name val1 val2;
958+ * ^
959+ * We are here (but still need to store val1)
960+ * and name or condition.
961+ */
962+ T_DBG3 ("add value: %.*s\n" , ps -> prev_lit_len , ps -> prev_lit );
963+
964+ if (ps -> e .ftoken && !strcmp (ps -> e .ftoken , "location" )) {
965+ ps -> err = entry_set_name (& ps -> e );
966+
967+ if (!ps -> err ) {
968+ if (ps -> prev_t == TOKEN_REGEX )
969+ ps -> err = entry_add_val (& ps -> e , "regex" ,
970+ sizeof ("regex" ));
971+ if (ps -> prev_t == TOKEN_REGEX_CI )
972+ ps -> err = entry_add_val (& ps -> e ,
973+ "regex_ci" ,
974+ sizeof ("regex_ci" ));
975+ }
976+ FSM_COND_JMP (ps -> err , PS_EXIT );
977+ FSM_JMP (PS_VAL_OR_ATTR );
978+ }
979+
980+ /*If it is not location*/
981+ ps -> err = entry_set_cond (& ps -> e , ps -> prev_t ,
982+ ps -> lit , ps -> lit_len );
983+ FSM_COND_JMP (ps -> err , PS_EXIT );
984+ PFSM_MOVE (PS_RULE_COND_END );
985+
986+ }
987+
917988 FSM_STATE (PS_STORE_VAL_PREV ) {
918989 /* name val1 val2;
919990 * ^
0 commit comments