/* common section */
nl \n
ws [ \t]+
-socket [\/][a-zA-Z0-9\/]+
-topic [\"][a-zA-Z0-9/]+[\"]
+special [()+\|\?\*,]
+sstring [a-zA-Z0-9]
+socket \/{sstring}[^{special}][a-zA-Z0-9\/\.]+
+quotedstring \"[^"\n]*\"
+bracketstring \<[^>]*\>
+comment ^\#[^\n]*
%%
-any { return(ANY); }
-drop { yylval.number=0;return (ACTION);}
-pass { yylval.number=1;return (ACTION);}
-in { yylval.number=0;return (DIR);}
-out { yylval.number=1;return (DIR);}
-{topic} { yylval.string=strdup(yytext);return WORD;}
-{socket} { yylval.string=strdup(yytext);return SOCKET;}
-"FROM" { return FROM;}
-"ANY" { return ANY;}
+"DROP" { yylval.number=0;return (ACTION);}
+"PASS" { yylval.number=1;return (ACTION);}
+"IN" { return (IN);}
+"OUT" { return (OUT);}
+"ANY" { return (ANY);}
+{bracketstring} { yylval.string=strndup(yytext+1, yyleng -2);return WORD;}
+{ws}"FROM"{ws}{socket}$ { yylval.string=strdup(yytext);return SOCKET;}
+^"LOG" { return LOG;}
+"QUICK" { return QUICK;}
{ws} { ; }
{nl} { ; }
-
+{comment} { return COMMENT; }
%%
+
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <string.h>
#include <netdb.h>
extern FILE *yyin;
+extern FILE *yyout;
+extern int yylineno;
+extern int yy_flex_debug;
static size_t errors;
enum filter_dir {
};
static size_t parsed_lines;
+static size_t errors;
+static size_t nrule;
%}
%union {
};
%token ACTION IN OUT FROM QUICK LOG SOCKET
-%token TOPIC WORD
+%token TOPIC WORD WORD2
%token ANY FROM
%token SLASH HYPHEN
-%token <string> WORD SOCKET
-%token <number> NUMBER
-%type <number> ACTION DIR QUICK LOG
-%type <string> from topic
+%type <number> ACTION QUICK LOG get_dir get_log get_quick
+%type <string> get_from get_topic WORD SOCKET
%%
ruleset: /* empty */
- |
- ruleset mqttrule
+ | ruleset mqttrule
+ | ruleset comment
+ | ruleset error { errors++; }
;
-mqttrule : ACTION DIR topic from
+comment: COMMENT '\n'
+ {
+ };
+mqttrule : get_log ACTION get_quick get_dir get_topic get_from
{
parsed_lines++;
struct mqtt_rule r;
memset(&r, 0, sizeof(r));
- r.action = $1;
- r.dir = $2;
- if ($3)
- strlcpy(r.topic, $3, sizeof r.topic);
- if ($4)
- strlcpy(r.from, $4, sizeof r.from);
-
- printf("%s %s <from> %s.\n", r.action == GTW_DROP ? "Drop" : "pass", r.topic[0]!=0 ? r.topic :"*", r.from[0]!=0 ? r.from : "<all>");
+ r.action = $2;
+ r.dir = $4;
+ if ($5)
+ strlcpy(r.topic, $5, sizeof r.topic);
+ if ($6)
+ strlcpy(r.from, $6, sizeof r.from);
+
+ ++nrule;
+ if ($1==1) {
+ printf("\t#%zu: %c %s %c %s <from> %s;\n", nrule, $3?'!':' ', r.action == GTW_DROP ? "Drop" : "pass",
+ r.dir==GTW_INOUT ? '=' : r.dir==GTW_IN ? '<' :'>',
+ r.topic[0]!=0 ? r.topic :"*", r.from[0]!=0 ? r.from : "<all>");
+ }
};
-topic : ANY {$$=NULL;}
- | WORD {$$=$1;}
- ;
+get_quick : /*empty*/ {$$=0;}
+ | QUICK {$$=1;}
+ ;
+get_log : /*empty*/ {$$=0;}
+ | LOG {$$ = 1;}
+ ;
-from : /* empty */ {$$=NULL;}
- | FROM SOCKET {$$ = $2;}
+get_topic : ANY {$$=NULL;}
+ | WORD {$$=$1;}
+ ;
+
+get_from : /*empty*/ {$$=NULL;}
+ | SOCKET {$$ = $1;}
+ ;
+
+get_dir : /*empty*/ {$$=GTW_INOUT;}
+ | IN {$$=GTW_IN;}
+ | OUT {$$=GTW_OUT;}
;
%%
yyerror(msg)
char *msg;
{
- fprintf(stderr, "while parsing \"%s\"\n",
+ fprintf(stderr, "while parsing line %d: error occured \"%s\"\n",
+ yylineno,
msg);
return;
else
yyin = stdin;
- yyparse();
- printf("\n#%zu.\n", parsed_lines);
+ int devNull = open("/dev/null", O_WRONLY);
+ int dup2Result = dup2(devNull, STDERR_FILENO);
+ yyparse();
+ printf("#%zu. R: %zu\tE: %zu\n", parsed_lines, nrule, errors);
}