%{ 

/*	
 * $Header: /cvs-root-aide/aide/src/conf_yacc.y,v 1.20 1999/11/25 14:44:33 rammer Exp $
 */

#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include "list.h"
#include "gen_list.h"
#include "db_config.h"
#include "symboltable.h"
#include "commandconf.h"
#include "aide.h"

int retval=0;
void conferror(const char*);

extern char* conftext;
extern long conf_lineno;


%}
%union {
  char* s;
  int i;
}


%start lines


%token TDEFINE
%token TUNDEF
%token TIFDEF
%token TIFNDEF
%token TIFNHOST
%token TIFHOST
%token TELSE
%token TENDIF
%token TINCLUDE
%token TID
%token <s> TSTRING
%token '='

%token TNEWLINE
%token TVERBOSE
%token TCONFIG_FILE
%token TDATABASE
%token TDATABASE_OUT
%token TREPORT_URL
%token TUMASK
%token TTRUE
%token TFALSE

/* File rule */

%token <s> TSELRXRULE
%token <s> TEQURXRULE
%token <s> TNEGRXRULE

/* expr alkiot */

%token <i> TRIGHTS
%token <i> TUSER
%token <i> TGROUP
%token <i> TINODE
%token <i> TLINKCOUNT
%token <i> TSIZE
%token <i> TGROWINGSIZE
%token <i> TATIME
%token <i> TCTIME
%token <i> TMTIME

/* hash funktions */

%token <i> TTIGER
%token <i> TSHA1
%token <i> TRMD160
%token <i> TMD2
%token <i> TMD4
%token <i> TMD5

/* predefs */

%token <i> TL
%token <i> TR

/* For db_lex */
%token TDBSPEC
%token TUNKNOWN
%token TNAME
%token TERROR
%token TEOF

%type  <i> expr
%type  <i> hash
%type  <i> primary other

%left '+' '-'

%%

lines : | line lines;

line : rule | equrule | negrule | definestmt | undefstmt
       | ifdefstmt | ifndefstmt | ifhoststmt | ifnhoststmt
       | groupdef | TNEWLINE | db_in | db_out | verbose
       | report 
       | TDBSPEC {
          error(220,"Got @@dbspec.Stopping\n");
	  YYACCEPT;
          }
       | error {
	  conferror("Error while reading configuration");
	  YYABORT;
          } ;

rule : TSELRXRULE expr TNEWLINE
{ conf->selrxlst=append_rxlist($1,$2,conf->selrxlst); } ;

equrule : TEQURXRULE expr TNEWLINE
{ conf->equrxlst=append_rxlist($1,$2,conf->equrxlst); } ;

negrule : TNEGRXRULE TNEWLINE
{ conf->negrxlst=append_rxlist($1,0,conf->negrxlst); } |
          TNEGRXRULE expr TNEWLINE 
{ conf->negrxlst=append_rxlist($1,0,conf->negrxlst); };

expr :  expr '+' expr { $$ =$1  | $3 ; } |
        expr '-' expr { $$ =$1  & (~$3 ); } |
	primary { $$ =$1 ;} ;

primary : hash { $$ =$1 ; } |
	  other { $$ =$1 ; } |
	  TSTRING { if((retval=get_groupval($1))>=0) {
	    $$=retval;
	  }
	  else {
	    conferror("Error in expression");
	    YYABORT;
	  }
	  }

other : TRIGHTS { $$ =$1 ;} | TUSER {$$ =$1 ;} 
        | TGROUP {$$ =$1 ;} | TINODE {$$ =$1 ;}
        | TLINKCOUNT {$$ =$1 ;} | TSIZE {$$ =$1 ;} 
	| TGROWINGSIZE {$$ =$1 ;} | TATIME {$$ =$1 ;} 
        | TCTIME {$$ =$1 ;} | TMTIME {$$ =$1 ;} | TL {$$ = $1;}
        | TR {$$ = $1;} ;

hash : TTIGER { $$ =$1 ;} | TSHA1 { $$ =$1 ;} | TRMD160 { $$ =$1 ;}
	| TMD5 {$$ =$1 ;} ;

definestmt : TDEFINE TSTRING TSTRING { do_define($2,$3); };

undefstmt : TUNDEF TSTRING { do_undefine($2); } ;

ifdefstmt : TIFDEF TSTRING { 
  if(do_ifxdef(1,$2)==-1){
    error(0,"ifdef error\n");
    YYABORT; 
  };
 } ifstmtlist ;

ifndefstmt : TIFNDEF TSTRING { 
  if(do_ifxdef(0,$2)==-1){
    error(0,"ifndef error\n");
    YYABORT; 
  };
 } ifstmtlist { error(220,"Ifndef statement ended\n");}  ;

ifhoststmt : TIFHOST TSTRING { 
  if(do_ifxhost(1,$2)==-1){
    error(0,"ifhost error\n");
    YYABORT;
  };
 } ifstmtlist ;

ifnhoststmt : TIFNHOST TSTRING { 
  if(do_ifxhost(0,$2)==-1){
    error(0,"ifnhost error\n");
    YYABORT; 
  };
 } ifstmtlist ;

ifstmtlist : lines TENDIF { error(220,"Endif stmt matched\n");} |
             lines TELSE lines TENDIF {error(220,"Endifelse stmt matched");} ;

groupdef : TSTRING '=' expr { do_groupdef($1,$3); } ;

db_in : TDATABASE TSTRING { do_dbindef($2); };

db_out : TDATABASE_OUT TSTRING { do_dboutdef($2); };

verbose : TVERBOSE TSTRING { do_verbdef($2); };

report : TREPORT_URL TSTRING { do_repurldef($2); } ;

%%


void conferror(const char *msg){
  error(0,"%i:%s:%s\n",conf_lineno,msg,conftext);

}
