parser.y (24788B)
1 /* Parser of crossroads configuration files */ 2 3 %{ 4 /* Prologue */ 5 #include "crossroads.h" 6 7 #define YYSTYPE Confsets 8 9 /* Static parser vars */ 10 static int i; /* Loop counter */ 11 static Backend cur_backend; /* Storage for a handled backend */ 12 static Service cur_service; /* Storage for a handled service */ 13 14 /* Parser debugging related */ 15 // #define PARSER_DEBUG 16 #ifdef PARSER_DEBUG 17 static void pmsg (char const *x) { 18 printf ("P: %s\n", x); 19 } 20 static void psmsg (char const *x, char const *y) { 21 printf ("P: %s %s\n", x, y); 22 } 23 static void pimsg(char const *x, int y) { 24 printf ("P: %s %d\n", x, y); 25 } 26 #else 27 # define pmsg(x) 28 # define psmsg(x,y) 29 # define pimsg(x,y) 30 #endif 31 32 /* Error handler for yyparse() */ 33 static int yyerror (char *msg) { 34 error ("Parse error at line %d, '%s': %s", 35 yylineno + 1, yytext, yyerrmsg); 36 } 37 38 /* Store an encountered string */ 39 static char *laststr; 40 static void setlaststr (char const *what) { 41 free (laststr); 42 laststr = xstrdup (what); 43 } 44 45 /* Store an encountered number */ 46 static int lastnr; 47 static void setlastnr (char const *what) { 48 lastnr = atoi (what); 49 } 50 51 /* Store an encountered 'over' number */ 52 static int lastovernr; 53 static void setlastovernr (char const *what) { 54 lastovernr = atoi(what); 55 } 56 57 /* Store an encountered 'externalhandler' */ 58 static char *lastext; 59 static void setlastext (char const *what) { 60 free (lastext); 61 lastext = xstrdup (what); 62 } 63 64 /* Get the server part from HOSTNAME:PORT in allocated memory */ 65 static char *serverpart (char const *what) { 66 char *ret = xstrdup (what); 67 char *cp; 68 69 if ( (cp = strchr (ret, ':')) ) 70 *cp = 0; 71 return (ret); 72 } 73 74 /* Get the port part from HOSTNAME:PORT */ 75 static int portpart (char const *what) { 76 char *cp; 77 78 if ( (cp = strchr (what, ':')) ) 79 return (atoi (cp + 1)); 80 return (0); 81 } 82 83 /* Add a list of IP filters to the allowlist or the denylist */ 84 static void add_any (char *what, int chain) { 85 char *item; 86 int result; 87 for (item = strtok (what, " "); item; item = strtok (0, " ")) { 88 if (chain) 89 result = ipf_add_allow (&cur_service, item); 90 else 91 result = ipf_add_deny (&cur_service, item); 92 if (result) 93 error ("Bad IP filter specifier '%s' at line %d", 94 item, yylineno + 1); 95 } 96 } 97 static void add_allowfrom (char *what) { 98 add_any (what, 1); 99 } 100 static void add_denyfrom (char *what) { 101 add_any (what, 0); 102 } 103 104 /* Set uid/gid for external commands. */ 105 static void setuseraccount (char *username) { 106 struct passwd *pw; 107 108 if (! (pw = getpwnam (username)) ) 109 error ("Invalid username '%s' at line %d", username, yylineno + 1); 110 cur_service.uid = pw->pw_uid; 111 cur_service.gid = pw->pw_gid; 112 } 113 114 %} 115 116 /* Declarations */ 117 %token SERVICE IDENTIFIER PORT NUMBER BACKEND VERBOSITY SERVER 118 ON OFF DISPATCHMODE ROUNDROBIN REVIVINGINTERVAL SHMKEY WEIGHT 119 ONSTART ONFAIL STRING BACKLOG RANDOM BYDURATION BYSIZE 120 BYCONNECTIONS CONNECTIONTIMEOUT MAXCONNECTIONS BYORDER TRAFFICLOG 121 OVER DECAY BINDTO THROUGHPUTLOG TYPE ANY HTTP 122 STICKYCOOKIE ADDCLIENTHEADER SETCLIENTHEADER APPENDCLIENTHEADER 123 ADDSERVERHEADER SETSERVERHEADER APPENDSERVERHEADER 124 ALLOWFROM DENYFROM ALLOWFILE DENYFILE EXTERNALHANDLER ONEND 125 USERACCOUNT 126 127 %% 128 /* Config file grammar rules */ 129 130 input: 131 element 132 input 133 | 134 element 135 ; 136 137 element: 138 service 139 servicename 140 '{' 141 servicestatements 142 '}' { 143 /* Verify the service description, supply defaults 144 * and so on. 145 */ 146 if (!cur_service.port) 147 error ("Service %s lacks a port", 148 cur_service.name); 149 if (!cur_service.nbackend) 150 error ("Service %s lacks back ends", 151 cur_service.name); 152 153 if (!cur_service.shmkey) 154 cur_service.shmkey = cur_service.port | SHM_MASK; 155 156 if (!cur_service.bind) 157 cur_service.bind = "any"; 158 159 /* Add to the list. */ 160 service = xrealloc (service, ++nservice * sizeof(Service)); 161 service[nservice - 1] = cur_service; 162 memset (&cur_service, 0, sizeof(Service)); 163 } 164 ; 165 166 service: 167 service_expected 168 SERVICE 169 ; 170 171 servicename: 172 servicename_expected 173 IDENTIFIER { 174 psmsg ("service:", yytext); 175 cur_service.name = xstrdup(yytext); 176 } 177 ; 178 179 servicestatements: 180 servicestatements 181 servicestatement 182 | 183 servicestatement 184 ; 185 186 servicestatement: 187 servicebody_expected 188 servicebody 189 ; 190 191 servicebody: 192 portstatement { 193 pimsg ("sevice port:", $1.set[0].v.ival); 194 cur_service.port = $1.set[0].v.ival; 195 free ($1.set); 196 } 197 | 198 bindstatement { 199 psmsg ("service binding:", $1.set[0].v.sval); 200 cur_service.bind = $1.set[0].v.sval; 201 free ($1.set); 202 } 203 | 204 verbositystatement { 205 pimsg ("service verbosity:", $1.set[0].v.ival); 206 cur_service.verbosity = $1.set[0].v.ival; 207 free ($1.set); 208 } 209 | 210 dispatchmodestatement { 211 pimsg ("service dispatch mode:", $1.set[0].v.ival); 212 pimsg ("service dispatch over:", lastovernr); 213 psmsg ("service dispatch exth:", lastext); 214 cur_service.dispatchtype = $1.set[0].v.ival; 215 cur_service.dispatchover = lastovernr; 216 cur_service.dispatchext = lastext; 217 free ($1.set); 218 } 219 | 220 revivingintervalstatement { 221 pimsg ("service revival interval:", $1.set[0].v.ival); 222 cur_service.rev_interval = $1.set[0].v.ival; 223 free ($1.set); 224 } 225 | 226 backlogstatement { 227 pimsg ("service backlog:", $1.set[0].v.ival); 228 cur_service.backlog = $1.set[0].v.ival; 229 free ($1.set); 230 } 231 | 232 shmkeystatement { 233 pimsg ("service shmkey:", $1.set[0].v.ival); 234 cur_service.shmkey = $1.set[0].v.ival; 235 free ($1.set); 236 } 237 | 238 connectiontimeoutstatement { 239 pimsg ("connection timout:", $1.set[0].v.ival); 240 cur_service.connectiontimeout = $1.set[0].v.ival; 241 free ($1.set); 242 } 243 | 244 maxconnectionsstatement { 245 pimsg ("max clients in service:", $1.set[0].v.ival); 246 cur_service.maxconnections = $1.set[0].v.ival; 247 free ($1.set); 248 } 249 | 250 typestatement { 251 pimsg ("service type: ", $1.set[0].v.ival); 252 cur_service.type = $1.set[0].v.ival; 253 free ($1.set); 254 } 255 | 256 allowfromstatement { 257 psmsg ("allow from: ", $1.set[0].v.sval); 258 add_allowfrom ($1.set[0].v.sval); 259 free ($1.set); 260 } 261 | 262 allowfilestatement { 263 psmsg ("allow file: ", $1.set[0].v.sval); 264 cur_service.allowfile = $1.set[0].v.sval; 265 free ($1.set); 266 } 267 | 268 denyfromstatement { 269 psmsg ("deny from: ", $1.set[0].v.sval); 270 add_denyfrom ($1.set[0].v.sval); 271 free ($1.set); 272 } 273 | 274 denyfilestatement { 275 psmsg ("deny file: ", $1.set[0].v.sval); 276 cur_service.denyfile = $1.set[0].v.sval; 277 free ($1.set); 278 } 279 | 280 useraccountstatement { 281 psmsg ("user account: ", $1.set[0].v.sval); 282 setuseraccount ($1.set[0].v.sval); 283 free ($1.set[0].v.sval); 284 free ($1.set); 285 } 286 | 287 backendblock { 288 pimsg ("converting backend statements, count is", $1.n); 289 for (i = 0; i < $1.n; i++) 290 switch ($1.set[i].cf) { 291 case cf_portspec: 292 pimsg ("backend block port:", $1.set[i].v.ival); 293 cur_backend.port = $1.set[i].v.ival; 294 break; 295 case cf_serverspec: 296 psmsg ("backend block server:", $1.set[i].v.sval); 297 cur_backend.server = serverpart ($1.set[i].v.sval); 298 cur_backend.port = portpart ($1.set[i].v.sval); 299 free ($1.set[i].v.sval); 300 break; 301 case cf_verbosityspec: 302 pimsg ("backend block verbosity:", $1.set[i].v.ival); 303 cur_backend.verbosity = $1.set[i].v.ival; 304 break; 305 case cf_onstartspec: 306 psmsg ("backend block onstart:", $1.set[i].v.sval); 307 cur_backend.onstart = $1.set[i].v.sval; 308 break; 309 case cf_onfailspec: 310 psmsg ("backend block onfail:", $1.set[i].v.sval); 311 cur_backend.onfail = $1.set[i].v.sval; 312 break; 313 case cf_onendspec: 314 psmsg ("backend block onend:", $1.set[i].v.sval); 315 cur_backend.onend = $1.set[i].v.sval; 316 break; 317 case cf_dumpspec: 318 psmsg ("backend trafficlog:", $1.set[i].v.sval); 319 cur_backend.dumpfile = $1.set[i].v.sval; 320 break; 321 case cf_thruspec: 322 psmsg ("backend throughputlog:", $1.set[i].v.sval); 323 cur_backend.thruputfile = $1.set[i].v.sval; 324 break; 325 case cf_weightspec: 326 pimsg ("backend weight:", $1.set[i].v.ival); 327 cur_backend.weight = $1.set[i].v.ival; 328 break; 329 case cf_decayspec: 330 pimsg ("backend decay:", $1.set[i].v.ival); 331 if ($1.set[i].v.ival >= 100) 332 error ("Decay specifier %d must be a percentage, " 333 "never more than 99", 334 $1.set[i].v.ival); 335 cur_backend.decay = $1.set[i].v.ival; 336 break; 337 case cf_maxconnectionsspec: 338 pimsg ("backend max clients: ", $1.set[i].v.ival); 339 cur_backend.maxconnections = $1.set[i].v.ival; 340 break; 341 case cf_stickycookiespec: 342 psmsg ("backend sticky cookie:", 343 $1.set[i].v.sval); 344 cur_backend.stickycookie = $1.set[i].v.sval; 345 break; 346 case cf_addclientheaderspec: 347 psmsg ("client header to add:", 348 $1.set[i].v.sval); 349 cur_backend.addclientheader = 350 xrealloc (cur_backend.addclientheader, 351 (cur_backend.naddclientheader + 1) * 352 sizeof(char*)); 353 cur_backend.addclientheader 354 [cur_backend.naddclientheader++] = 355 $1.set[i].v.sval; 356 break; 357 case cf_setclientheaderspec: 358 psmsg ("client header to set:", 359 $1.set[i].v.sval); 360 cur_backend.setclientheader = 361 xrealloc (cur_backend.setclientheader, 362 (cur_backend.nsetclientheader + 1) * 363 sizeof(char*)); 364 cur_backend.setclientheader 365 [cur_backend.nsetclientheader++] = 366 $1.set[i].v.sval; 367 break; 368 case cf_appendclientheaderspec: 369 psmsg ("client header to append:", 370 $1.set[i].v.sval); 371 cur_backend.appendclientheader = 372 xrealloc (cur_backend.appendclientheader, 373 (cur_backend.nappendclientheader + 1) * 374 sizeof(char*)); 375 cur_backend.appendclientheader 376 [cur_backend.nappendclientheader++] = 377 $1.set[i].v.sval; 378 break; 379 case cf_addserverheaderspec: 380 psmsg ("server header to add:", 381 $1.set[i].v.sval); 382 cur_backend.addserverheader = 383 xrealloc (cur_backend.addserverheader, 384 (cur_backend.naddserverheader + 1) * 385 sizeof(char*)); 386 cur_backend.addserverheader 387 [cur_backend.naddserverheader++] = 388 $1.set[i].v.sval; 389 break; 390 case cf_setserverheaderspec: 391 psmsg ("server header to set:", 392 $1.set[i].v.sval); 393 cur_backend.setserverheader = 394 xrealloc (cur_backend.setserverheader, 395 (cur_backend.nsetserverheader + 1) * 396 sizeof(char*)); 397 cur_backend.setserverheader 398 [cur_backend.nsetserverheader++] = 399 $1.set[i].v.sval; 400 break; 401 case cf_appendserverheaderspec: 402 psmsg ("server header to append:", 403 $1.set[i].v.sval); 404 cur_backend.appendserverheader = 405 xrealloc (cur_backend.appendserverheader, 406 (cur_backend.nappendserverheader + 1) * 407 sizeof(char*)); 408 cur_backend.appendserverheader 409 [cur_backend.nappendserverheader++] = 410 $1.set[i].v.sval; 411 break; 412 default: 413 error ("Internal jam, unhandled type %d " 414 "in backend specification", 415 $1.set[i].cf); 416 } 417 free ($1.set); 418 419 /* Verify the backend block, supply defaults, 420 * And so on. 421 */ 422 if (!cur_service.port) 423 error ("Back end %s lacks port", 424 cur_service.port); 425 if (!cur_backend.weight) 426 cur_backend.weight = 1; 427 428 /* Add to the list. */ 429 cur_service.backend = xrealloc (cur_service.backend, 430 ++cur_service.nbackend * 431 sizeof(Backend)); 432 cur_service.backend[cur_service.nbackend - 1] = 433 cur_backend; 434 pimsg ("this was backend defintion", cur_service.nbackend); 435 memset (&cur_backend, 0, sizeof(cur_backend)); 436 } 437 ; 438 439 portstatement: 440 PORT 441 number 442 semicol { 443 pimsg ("port statement:", lastnr); 444 $$.n = 1; 445 $$.set = xmalloc (sizeof(Confset)); 446 $$.set[0].cf = cf_portspec; 447 $$.set[0].v.ival = lastnr; 448 } 449 ; 450 451 bindstatement: 452 BINDTO 453 ipaddress 454 semicol { 455 psmsg ("bindto statement:", laststr); 456 $$.n = 1; 457 $$.set = xmalloc (sizeof(Confset)); 458 $$.set[0].cf = cf_bindspec; 459 $$.set[0].v.sval = xstrdup(laststr); 460 } 461 ; 462 463 ipaddress: 464 ipaddress_expected 465 STRING { 466 setlaststr (laststring); 467 free (laststring); 468 laststring = 0; 469 } 470 ; 471 472 number: 473 number_expected 474 NUMBER { 475 setlastnr (yytext); 476 } 477 ; 478 479 semicol: 480 semicol_expected 481 ';' 482 ; 483 484 verbositystatement: 485 VERBOSITY 486 onoff_expected 487 onoff 488 semicol { 489 pimsg ("verbosity statement:", lastnr); 490 $$.n = 1; 491 $$.set = xmalloc (sizeof(Confset)); 492 $$.set[0].cf = cf_verbosityspec; 493 $$.set[0].v.ival = lastnr; 494 } 495 ; 496 497 onoff: 498 ON { 499 lastnr = 1; 500 } 501 | 502 OFF { 503 lastnr = 0; 504 } 505 ; 506 507 dispatchmodestatement: 508 DISPATCHMODE 509 dispatchmethod 510 dispatchtail 511 semicol { 512 $$ = $2; 513 } 514 ; 515 516 dispatchtail: 517 dispatchover 518 | 519 dispatchext 520 | 521 /* empty */ 522 ; 523 524 dispatchover: 525 OVER 526 overnumber { 527 pimsg ("dispatch mode statement:", lastnr); 528 $$.n = 1; 529 $$.set = xmalloc (sizeof(Confset)); 530 $$.set[0].cf = cf_dispatchspec; 531 $$.set[0].v.ival = lastnr; 532 533 if (lastovernr && 534 (lastnr != ds_bysize && lastnr != ds_byduration)) 535 error ("Service '%s': this dispatch mode " 536 "doesn't support 'over <connections>'", 537 cur_service.name); 538 } 539 ; 540 541 overnumber: 542 number_expected 543 NUMBER { 544 setlastovernr (yytext); 545 } 546 ; 547 548 dispatchext: 549 commandline { 550 psmsg ("external handler:", laststr); 551 if (lastnr != ds_externalhandler) 552 error ("Service %s: this dispatch mode doesn't support " 553 "an external handler", cur_service.name); 554 setlastext (laststr); 555 } 556 ; 557 558 dispatchmethod: 559 dispatchmethod_expected 560 dispatchmethodspec { 561 $$.n = 1; 562 $$.set = xmalloc (sizeof(Confset)); 563 $$.set[0].v.ival = lastnr; 564 } 565 ; 566 567 dispatchmethodspec: 568 ROUNDROBIN { 569 lastnr = ds_roundrobin; 570 } 571 | 572 RANDOM { 573 lastnr = ds_random; 574 } 575 | 576 BYDURATION { 577 lastnr = ds_byduration; 578 } 579 | 580 BYSIZE { 581 lastnr = ds_bysize; 582 } 583 | 584 BYORDER { 585 lastnr = ds_byorder; 586 } 587 | 588 BYCONNECTIONS { 589 lastnr = ds_byconnections; 590 } 591 | 592 EXTERNALHANDLER { 593 lastnr = ds_externalhandler; 594 } 595 ; 596 597 useraccountstatement: 598 USERACCOUNT 599 useraccount 600 semicol { 601 pimsg ("user account statement:", laststr); 602 $$.n = 1; 603 $$.set = xmalloc (sizeof(Confset)); 604 $$.set[0].cf = cf_useraccountspec; 605 $$.set[0].v.sval = xstrdup (laststr); 606 } 607 ; 608 609 useraccount: 610 useraccount_expected 611 STRING { 612 setlaststr (laststring); 613 free (laststring); 614 laststring = 0; 615 } 616 ; 617 618 revivingintervalstatement: 619 REVIVINGINTERVAL 620 number 621 semicol { 622 pimsg ("reviving interval statement:", lastnr); 623 $$.n = 1; 624 $$.set = xmalloc (sizeof(Confset)); 625 $$.set[0].cf = cf_revivespec; 626 $$.set[0].v.ival = lastnr; 627 } 628 ; 629 630 backlogstatement: 631 BACKLOG 632 number 633 semicol { 634 pimsg ("backlog statement:", lastnr); 635 $$.n = 1; 636 $$.set = xmalloc (sizeof(Confset)); 637 $$.set[0].cf = cf_revivespec; 638 $$.set[0].v.ival = lastnr; 639 } 640 ; 641 642 shmkeystatement: 643 SHMKEY 644 number 645 semicol { 646 pimsg ("shmkey statement:", lastnr); 647 $$.n = 1; 648 $$.set = xmalloc (sizeof(Confset)); 649 $$.set[0].cf = cf_shmkeyspec; 650 $$.set[0].v.ival = lastnr; 651 } 652 ; 653 654 connectiontimeoutstatement: 655 CONNECTIONTIMEOUT 656 number 657 semicol { 658 pimsg ("connection timeout statement:", lastnr); 659 $$.n = 1; 660 $$.set = xmalloc (sizeof(Confset)); 661 $$.set[0].cf = cf_connectiontimeoutspec; 662 $$.set[0].v.ival = lastnr; 663 } 664 ; 665 666 maxconnectionsstatement: 667 MAXCONNECTIONS 668 number 669 semicol { 670 pimsg ("max clients statement (service):", lastnr); 671 $$.n = 1; 672 $$.set = xmalloc (sizeof(Confset)); 673 $$.set[0].cf = cf_maxconnectionsspec; 674 $$.set[0].v.ival = lastnr; 675 } 676 ; 677 678 typestatement: 679 TYPE 680 typespec 681 semicol { 682 pimsg ("service type:", lastnr); 683 $$.n = 1; 684 $$.set = xmalloc (sizeof(Confset)); 685 $$.set[0].cf = cf_typespec; 686 $$.set[0].v.ival = lastnr; 687 } 688 ; 689 690 typespec: 691 type_expected 692 typespecifier 693 ; 694 695 typespecifier: 696 ANY { 697 lastnr = type_any; 698 } 699 | 700 HTTP { 701 lastnr = type_http; 702 } 703 ; 704 705 allowfromstatement: 706 ALLOWFROM 707 ipfilters 708 semicol { 709 psmsg ("allow from: ", laststr); 710 $$.n = 1; 711 $$.set = xmalloc (sizeof(Confset)); 712 $$.set[0].cf = cf_allowfromspec; 713 $$.set[0].v.sval = xstrdup(laststr); 714 } 715 ; 716 717 denyfromstatement: 718 DENYFROM 719 ipfilters 720 semicol { 721 psmsg ("allow from: ", laststr); 722 $$.n = 1; 723 $$.set = xmalloc (sizeof(Confset)); 724 $$.set[0].cf = cf_denyfromspec; 725 $$.set[0].v.sval = xstrdup(laststr); 726 } 727 ; 728 729 allowfilestatement: 730 ALLOWFILE 731 filename 732 semicol { 733 psmsg ("allow file: ", laststr); 734 $$.n = 1; 735 $$.set = xmalloc (sizeof(Confset)); 736 $$.set[0].cf = cf_allowfilespec; 737 $$.set[0].v.sval = xstrdup(laststr); 738 } 739 ; 740 741 denyfilestatement: 742 DENYFILE 743 filename 744 semicol { 745 psmsg ("allow file: ", laststr); 746 $$.n = 1; 747 $$.set = xmalloc (sizeof(Confset)); 748 $$.set[0].cf = cf_allowfilespec; 749 $$.set[0].v.sval = xstrdup(laststr); 750 } 751 ; 752 753 ipfilters: 754 ipfilters_expected 755 STRING { 756 setlaststr (laststring); 757 free (laststring); 758 laststring = 0; 759 } 760 ; 761 762 backendblock: 763 BACKEND 764 backendname 765 '{' 766 backenddefinitions 767 '}' { 768 $$ = $4; 769 } 770 ; 771 772 backendname: 773 backendname_expected 774 IDENTIFIER { 775 psmsg ("backend name:", yytext); 776 cur_backend.name = xstrdup (yytext); 777 } 778 ; 779 780 backenddefinitions: 781 backenddefinitions 782 backenddefinition { 783 $1.n++; 784 $1.set = xrealloc ($1.set, $1.n * sizeof(Confset)); 785 $1.set[$1.n - 1] = $2.set[0]; 786 $$ = $1; 787 } 788 | 789 backenddefinition { 790 $$ = $1; 791 } 792 ; 793 794 backenddefinition: 795 backendstatement_expected 796 backendstatement { 797 $$ = $2; 798 } 799 ; 800 801 backendstatement: 802 serverstatement { 803 psmsg ("backend server:", $1.set[0].v.sval); 804 $$ = $1; 805 } 806 | 807 portstatement { 808 pimsg ("backend port:", $1.set[0].v.ival); 809 $$ = $1; 810 } 811 | 812 verbositystatement { 813 pimsg ("backend verbosity:", $1.set[0].v.ival); 814 $$ = $1; 815 } 816 | 817 onstartstatement { 818 psmsg ("backend onstart:", $1.set[0].v.sval); 819 $$ = $1; 820 } 821 | 822 onendstatement { 823 psmsg ("backend onend:", $1.set[0].v.sval); 824 $$ = $1; 825 } 826 | 827 onfailstatement { 828 psmsg ("backend onfail:", $1.set[0].v.sval); 829 $$ = $1; 830 } 831 | 832 dumptrafficstatement { 833 psmsg ("backend trafficlog:", $1.set[0].v.sval); 834 $$ = $1; 835 } 836 | 837 throughputstatement { 838 psmsg ("backend trafficlog:", $1.set[0].v.sval); 839 $$ = $1; 840 } 841 | 842 weightstatement { 843 pimsg ("backend weight:", $1.set[0].v.ival); 844 $$ = $1; 845 } 846 | 847 decaystatement { 848 pimsg ("backend decay:", $1.set[0].v.ival); 849 $$ = $1; 850 } 851 | 852 maxconnectionsstatement { 853 pimsg ("backend maxconnections:", $1.set[0].v.ival); 854 $$ = $1; 855 } 856 | 857 stickycookiestatement { 858 psmsg ("backend sticky cookie:", $1.set[0].v.sval); 859 $$ = $1; 860 } 861 | 862 addclientheaderstatement { 863 psmsg ("addclientheader:", $1.set[0].v.sval); 864 $$ = $1; 865 } 866 | 867 setclientheaderstatement { 868 psmsg ("setclientheader:", $1.set[0].v.sval); 869 $$ = $1; 870 } 871 | 872 appendclientheaderstatement { 873 psmsg ("appendclientheader:", $1.set[0].v.sval); 874 $$ = $1; 875 } 876 | 877 addserverheaderstatement { 878 psmsg ("addserverheader:", $1.set[0].v.sval); 879 $$ = $1; 880 } 881 | 882 setserverheaderstatement { 883 psmsg ("setserverheader:", $1.set[0].v.sval); 884 $$ = $1; 885 } 886 | 887 appendserverheaderstatement { 888 psmsg ("appendserverheader:", $1.set[0].v.sval); 889 $$ = $1; 890 } 891 ; 892 893 serverstatement: 894 SERVER 895 serveraddress_expected 896 serveraddress 897 semicol { 898 psmsg ("server statement:", laststr); 899 $$.n = 1; 900 $$.set = xmalloc (sizeof (Confset)); 901 $$.set[0].cf = cf_serverspec; 902 $$.set[0].v.sval = xstrdup (laststr); 903 } 904 ; 905 906 weightstatement: 907 WEIGHT 908 number 909 semicol { 910 pimsg ("weight statement", lastnr); 911 $$.n = 1; 912 $$.set = xmalloc (sizeof (Confset)); 913 $$.set[0].cf = cf_weightspec; 914 $$.set[0].v.ival = lastnr; 915 } 916 ; 917 918 decaystatement: 919 DECAY 920 number 921 semicol { 922 pimsg ("decay statement", lastnr); 923 $$.n = 1; 924 $$.set = xmalloc (sizeof (Confset)); 925 $$.set[0].cf = cf_decayspec; 926 $$.set[0].v.ival = lastnr; 927 } 928 ; 929 930 serveraddress: 931 STRING { 932 setlaststr (laststring); 933 } 934 ; 935 936 onstartstatement: 937 ONSTART 938 commandline 939 semicol { 940 psmsg ("onstart statement:", laststr); 941 $$.n = 1; 942 $$.set = xmalloc (sizeof (Confset)); 943 $$.set[0].cf = cf_onstartspec; 944 $$.set[0].v.sval = xstrdup (laststr); 945 } 946 ; 947 948 onfailstatement: 949 ONFAIL 950 commandline 951 semicol { 952 psmsg ("onfail statement:", laststr); 953 $$.n = 1; 954 $$.set = xmalloc (sizeof (Confset)); 955 $$.set[0].cf = cf_onfailspec; 956 $$.set[0].v.sval = xstrdup (laststr); 957 } 958 ; 959 960 onendstatement: 961 ONEND 962 commandline 963 semicol { 964 psmsg ("onend statement:", laststr); 965 $$.n = 1; 966 $$.set = xmalloc (sizeof (Confset)); 967 $$.set[0].cf = cf_onendspec; 968 $$.set[0].v.sval = xstrdup (laststr); 969 } 970 ; 971 972 dumptrafficstatement: 973 TRAFFICLOG 974 filename 975 semicol { 976 psmsg ("trafficlog statement:", laststr); 977 $$.n = 1; 978 $$.set = xmalloc (sizeof (Confset)); 979 $$.set[0].cf = cf_dumpspec; 980 $$.set[0].v.sval = xstrdup (laststr); 981 } 982 ; 983 984 throughputstatement: 985 THROUGHPUTLOG 986 filename 987 semicol { 988 psmsg ("throughputlog statement:", laststr); 989 $$.n = 1; 990 $$.set = xmalloc (sizeof (Confset)); 991 $$.set[0].cf = cf_thruspec; 992 $$.set[0].v.sval = xstrdup (laststr); 993 } 994 ; 995 996 commandline: 997 commandline_expected 998 STRING { 999 setlaststr (laststring); 1000 free (laststring); 1001 laststring = 0; 1002 } 1003 ; 1004 1005 filename: 1006 filename_expected 1007 STRING { 1008 setlaststr (laststring); 1009 free (laststring); 1010 laststring = 0; 1011 } 1012 ; 1013 1014 stickycookiestatement: 1015 STICKYCOOKIE 1016 cookiespecifier 1017 semicol { 1018 psmsg ("insertcookie statement:", laststr); 1019 $$.n = 1; 1020 $$.set = xmalloc (sizeof (Confset)); 1021 $$.set[0].cf = cf_stickycookiespec; 1022 $$.set[0].v.sval = xstrdup (laststr); 1023 } 1024 ; 1025 1026 cookiespecifier: 1027 cookie_expected 1028 STRING { 1029 setlaststr (laststring); 1030 free (laststring); 1031 laststring = 0; 1032 } 1033 ; 1034 1035 addclientheaderstatement: 1036 ADDCLIENTHEADER 1037 headerstring 1038 semicol { 1039 psmsg ("addclientheader statement:", laststr); 1040 $$.n = 1; 1041 $$.set = xmalloc (sizeof(Confset)); 1042 $$.set[0].cf = cf_addclientheaderspec; 1043 $$.set[0].v.sval = xstrdup (laststr); 1044 } 1045 ; 1046 1047 setclientheaderstatement: 1048 SETCLIENTHEADER 1049 headerstring 1050 semicol { 1051 psmsg ("setclientheader statement:", laststr); 1052 $$.n = 1; 1053 $$.set = xmalloc (sizeof(Confset)); 1054 $$.set[0].cf = cf_setclientheaderspec; 1055 $$.set[0].v.sval = xstrdup (laststr); 1056 } 1057 ; 1058 1059 appendclientheaderstatement: 1060 APPENDCLIENTHEADER 1061 headerstring 1062 semicol { 1063 psmsg ("appendclientheader statement:", laststr); 1064 $$.n = 1; 1065 $$.set = xmalloc (sizeof(Confset)); 1066 $$.set[0].cf = cf_appendclientheaderspec; 1067 $$.set[0].v.sval = xstrdup (laststr); 1068 } 1069 ; 1070 1071 addserverheaderstatement: 1072 ADDSERVERHEADER 1073 headerstring 1074 semicol { 1075 psmsg ("addserverheader statement:", laststr); 1076 $$.n = 1; 1077 $$.set = xmalloc (sizeof(Confset)); 1078 $$.set[0].cf = cf_addserverheaderspec; 1079 $$.set[0].v.sval = xstrdup (laststr); 1080 } 1081 ; 1082 1083 setserverheaderstatement: 1084 SETSERVERHEADER 1085 headerstring 1086 semicol { 1087 psmsg ("setserverheader statement:", laststr); 1088 $$.n = 1; 1089 $$.set = xmalloc (sizeof(Confset)); 1090 $$.set[0].cf = cf_setserverheaderspec; 1091 $$.set[0].v.sval = xstrdup (laststr); 1092 } 1093 ; 1094 1095 appendserverheaderstatement: 1096 APPENDSERVERHEADER 1097 headerstring 1098 semicol { 1099 psmsg ("appendserverheader statement:", laststr); 1100 $$.n = 1; 1101 $$.set = xmalloc (sizeof(Confset)); 1102 $$.set[0].cf = cf_appendserverheaderspec; 1103 $$.set[0].v.sval = xstrdup (laststr); 1104 } 1105 ; 1106 1107 headerstring: 1108 headerstring_expected 1109 STRING { 1110 setlaststr (laststring); 1111 free (laststring); 1112 laststring = 0; 1113 } 1114 ; 1115 1116 headerstring_expected: { 1117 yyerrmsg = "HTTP header specifier expected"; 1118 } 1119 ; 1120 1121 cookie_expected: { 1122 yyerrmsg = "cookie specifier expected"; 1123 } 1124 ; 1125 1126 number_expected: { 1127 yyerrmsg = "number expected"; 1128 } 1129 ; 1130 1131 serveraddress_expected: { 1132 yyerrmsg = "hostname or IP address expected"; 1133 } 1134 ; 1135 1136 service_expected: { 1137 yyerrmsg = "'service' expected"; 1138 } 1139 ; 1140 1141 backendstatement_expected: { 1142 yyerrmsg = "backend definition statement expected"; 1143 } 1144 ; 1145 1146 servicebody_expected: { 1147 yyerrmsg = "service body statement expected"; 1148 } 1149 ; 1150 1151 semicol_expected: { 1152 yyerrmsg = "semicolon (;) expected"; 1153 } 1154 ; 1155 1156 onoff_expected: { 1157 yyerrmsg = "'on' or 'off' expetcted"; 1158 } 1159 ; 1160 1161 dispatchmethod_expected: { 1162 yyerrmsg = "dispatch method expected"; 1163 } 1164 ; 1165 1166 commandline_expected: { 1167 yyerrmsg = "command line expected"; 1168 } 1169 ; 1170 1171 filename_expected: { 1172 yyerrmsg = "file name expected"; 1173 } 1174 ; 1175 1176 servicename_expected: { 1177 yyerrmsg = "service name (identifier) expected"; 1178 } 1179 ; 1180 1181 backendname_expected: { 1182 yyerrmsg = "backend name (identifier) expected"; 1183 } 1184 ; 1185 1186 ipaddress_expected: { 1187 yyerrmsg = "IP address or 'any' expected"; 1188 } 1189 ; 1190 1191 type_expected: { 1192 yyerrmsg = "Service type expected ('any', 'stickyhttp', ...)"; 1193 } 1194 ; 1195 1196 ipfilters_expected: { 1197 yyerrmsg = "IP filter(s) expected"; 1198 } 1199 ; 1200 1201 useraccount_expected: { 1202 yyerrmsg = "username expected"; 1203 } 1204 ;