2004-05-09 Michael Poole <mdpoole@troilus.org>
[ircu2.10.12-pk.git] / ircd / ircd_parser.y
index f748f015713a8b7150d9a32faed029dbf94e936b..f545c003cf61e7d2c4dd4f69a47459039b4103ac 100644 (file)
   struct DenyConf *dconf;
   struct ServerConf *sconf;
   struct qline *qconf = NULL;
+
+static void parse_error(char *pattern,...) {
+  static char error_buffer[1024];
+  va_list vl;
+  va_start(vl,pattern);
+  ircd_vsnprintf(NULL, error_buffer, sizeof(error_buffer), pattern, vl);
+  va_end(vl);
+  yyerror(error_buffer);
+}
+
 %}
 
 %token <text> QSTRING
 %token FEATURES
 %token QUARANTINE
 /* and now a lot of priviledges... */
-%token TPRIV_CHAN_LIMIT, TPRIV_MODE_LCHAN, TPRIV_DEOP_LCHAN, TPRIV_WALK_LCHAN
-%token TPRIV_KILL, TPRIV_LOCAL_KILL, TPRIV_REHASH, TPRIV_RESTART, TPRIV_DIE
-%token TPRIV_GLINE, TPRIV_LOCAL_GLINE, TPRIV_JUPE, TPRIV_LOCAL_JUPE
-%token TPRIV_LOCAL_OPMODE, TPRIV_OPMODE, TPRIV_SET, TPRIV_WHOX, TPRIV_BADCHAN
+%token TPRIV_CHAN_LIMIT TPRIV_MODE_LCHAN TPRIV_DEOP_LCHAN TPRIV_WALK_LCHAN
+%token TPRIV_KILL TPRIV_LOCAL_KILL TPRIV_REHASH TPRIV_RESTART TPRIV_DIE
+%token TPRIV_GLINE TPRIV_LOCAL_GLINE TPRIV_JUPE TPRIV_LOCAL_JUPE
+%token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN
 %token TPRIV_LOCAL_BADCHAN
-%token TPRIV_SEE_CHAN, TPRIV_SHOW_INVIS, TPRIV_SHOW_ALL_INVIS, TPRIV_PROPAGATE
-%token TPRIV_UNLIMIT_QUERY, TPRIV_DISPLAY, TPRIV_SEE_OPERS, TPRIV_WIDE_GLINE
+%token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE
+%token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE
 /* and some types... */
 %type <num> sizespec
-%type <num> timespec, timefactor, factoredtimes, factoredtime
-%type <num> expr, yesorno, privtype
+%type <num> timespec timefactor factoredtimes factoredtime
+%type <num> expr yesorno privtype
 %left '+' '-'
 %left '*' '/'
 
 blocks: blocks block | block;
 block: adminblock | generalblock | classblock | connectblock |
        serverblock | operblock | portblock | jupeblock | clientblock |
-       killblock | cruleblock | motdblock | featuresblock | quarantineblock;
+       killblock | cruleblock | motdblock | featuresblock | quarantineblock |
+       error;
 
 /* The timespec, sizespec and expr was ripped straight from
  * ircd-hybrid-7. */
@@ -191,51 +202,41 @@ timefactor: SECONDS { $$ = 1; }
 | DECADES { $$ = 60 * 60 * 24 * 365 * 10; };
 
 
-sizespec:      expr    
-               = {
+sizespec:      expr    {
                        $$ = $1;
                }
-               | expr BYTES
-               = { 
+               | expr BYTES  { 
                        $$ = $1;
                }
-               | expr KBYTES
-               = {
+               | expr KBYTES {
                        $$ = $1 * 1024;
                }
-               | expr MBYTES
-               = {
+               | expr MBYTES {
                        $$ = $1 * 1024 * 1024;
                }
-               | expr GBYTES
-               = {
+               | expr GBYTES {
                        $$ = $1 * 1024 * 1024 * 1024;
                }
-               | expr TBYTES
-               = {
+               | expr TBYTES {
                        $$ = $1 * 1024 * 1024 * 1024;
                }
                ;
 
 /* this is an arithmatic expression */
 expr: NUMBER
-               
+               { 
                        $$ = $1;
                }
-               | expr '+' expr
-               = { 
+               | expr '+' expr { 
                        $$ = $1 + $3;
                }
-               | expr '-' expr
-               = { 
+               | expr '-' expr { 
                        $$ = $1 - $3;
                }
-               | expr '*' expr
-               = { 
+               | expr '*' expr { 
                        $$ = $1 * $3;
                }
-               | expr '/' expr
-               = { 
+               | expr '/' expr { 
                        $$ = $1 / $3;
                }
 /* leave this out until we find why it makes BSD yacc dump core -larne
@@ -243,15 +244,14 @@ expr: NUMBER
                = {
                        $$ = -$2;
                } */
-               | '(' expr ')'
-               = {
+               | '(' expr ')' {
                        $$ = $2;
                }
                ;
 
 jupeblock: JUPE '{' jupeitems '}' ';' ;
 jupeitems: jupeitem jupeitems | jupeitem;
-jupeitem: jupenick;
+jupeitem: jupenick | error;
 jupenick: NICK '=' QSTRING
 {
   addNickJupes(yylval.text);
@@ -259,17 +259,23 @@ jupenick: NICK '=' QSTRING
 
 generalblock: GENERAL '{' generalitems '}' ';' ;
 generalitems: generalitem generalitems | generalitem;
-generalitem: generalnumeric | generalname | generalvhost | generaldesc;
+generalitem: generalnumeric | generalname | generalvhost | generaldesc | error;
 generalnumeric: NUMERIC '=' NUMBER ';'
 {
   if (localConf.numeric == 0)
     localConf.numeric = yylval.num;
+  else
+    parse_error("Redefinition of server numeric %i (%i)",yylval.num,
+               localConf.numeric);
 };
 
 generalname: NAME '=' QSTRING ';'
 {
   if (localConf.name == NULL)
     DupString(localConf.name, yylval.text);
+  else
+    parse_error("Redefinition of server name %s (%s)",yylval.text,
+               localConf.name);
 };
 
 generaldesc: DESCRIPTION '=' QSTRING ';'
@@ -296,7 +302,7 @@ adminblock: ADMIN '{' adminitems '}'
     DupString(localConf.contact, "");
 } ';';
 adminitems: adminitems adminitem | adminitem;
-adminitem: adminlocation | admincontact;
+adminitem: adminlocation | admincontact | error;
 adminlocation: LOCATION '=' QSTRING ';'
 {
  if (localConf.location1 == NULL)
@@ -324,10 +330,13 @@ classblock: CLASS {
   {
    add_class(name, tping, tconn, maxlinks, sendq);
   }
+  else {
+   parse_error("Missing name in class block");
+  }
 } ';';
 classitems: classitem classitems | classitem;
 classitem: classname | classpingfreq | classconnfreq | classmaxlinks |
-           classsendq;
+           classsendq | error;
 classname: NAME '=' QSTRING ';'
 {
   MyFree(name);
@@ -380,11 +389,12 @@ connectblock: CONNECT
    MyFree(pass);
    MyFree(host);
    name = pass = host = NULL;
+   parse_error("Bad connect block");
  }
 }';';
 connectitems: connectitem connectitems | connectitem;
 connectitem: connectname | connectpass | connectclass | connecthost
-              | connectport;
+              | connectport | error;
 connectname: NAME '=' QSTRING ';'
 {
  MyFree(name);
@@ -421,6 +431,7 @@ serverblock: SERVER
    MyFree(aconf->name);
    MyFree(aconf);
    aconf = NULL;
+   parse_error("Bad server block");
  }
  else
  {
@@ -430,7 +441,7 @@ serverblock: SERVER
 } ';';
 serveritems: serveritem serveritems | serveritem;
 serveritem: servername | servermask | serverhub | serverleaf |
-             serveruworld;
+             serveruworld | error;
 servername: NAME '=' QSTRING
 {
  MyFree(aconf->name);
@@ -456,6 +467,8 @@ serverleaf: LEAF '=' YES ';'
 {
  if (!(aconf->status & CONF_HUB && aconf->status & CONF_UWORLD))
   aconf->status |= CONF_LEAF;
+ else
+  parse_error("Server is both leaf and a hub");
 }
 | LEAF '=' NO ';'
 {
@@ -494,7 +507,7 @@ operblock: OPER
   }
 };
 operitems: operitem | operitems operitem;
-operitem: opername | operpass | operlocal | operhost | operclass | operpriv;
+operitem: opername | operpass | operlocal | operhost | operclass | operpriv | error;
 
 opername: NAME '=' QSTRING ';'
 {
@@ -602,10 +615,11 @@ portblock: PORT {
   {
     MyFree(host);
     MyFree(pass);
+    parse_error("Bad port block");
   }
 };
 portitems: portitem portitems | portitem;
-portitem: portnumber | portvhost | portmask | portserver | porthidden;
+portitem: portnumber | portvhost | portmask | portserver | porthidden | error;
 portnumber: PORT '=' NUMBER ';'
 {
   port = yylval.num;
@@ -664,10 +678,11 @@ clientblock: CLIENT
    MyFree(aconf->passwd);
    MyFree(aconf);
    aconf = NULL;
+   parse_error("Bad client block");
   }
 } ';';
 clientitems: clientitem clientitems | clientitem;
-clientitem: clienthost | clientclass | clientpass | clientip;
+clientitem: clienthost | clientclass | clientpass | clientip | error;
 clientip: IP '=' QSTRING ';'
 {
   MyFree(aconf->host);
@@ -711,10 +726,11 @@ killblock: KILL
     MyFree(dconf->message);
     MyFree(dconf);
     dconf = NULL;
+    parse_error("Bad kill block");
   }
 } ';';
 killitems: killitem killitems | killitem;
-killitem: killuhost | killreal | killreasonfile | killreason;
+killitem: killuhost | killreal | killreasonfile | killreason | error;
 killuhost: HOST '=' QSTRING ';'
 {
   char *u, *h;
@@ -798,11 +814,12 @@ cruleblock: CRULE
   {
     MyFree(host);
     MyFree(pass);
+    parse_error("Bad CRule block");
   }
 } ';';
 
 cruleitems: cruleitem cruleitems | cruleitem;
-cruleitem: cruleserver | crulerule | cruleall;
+cruleitem: cruleserver | crulerule | cruleall | error;
 
 cruleserver: SERVER '=' QSTRING ';'
 {
@@ -837,7 +854,7 @@ motdblock: MOTD {
 } ';';
 
 motditems: motditem motditems | motditem;
-motditem: motdhost | motdfile;
+motditem: motdhost | motdfile | error;
 motdhost: HOST '=' QSTRING ';'
 {
   DupString(host, yylval.text);