599105982f2c513f28a2079477e6190dffa2c9cc
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas T√łnnesen(andreto@olsr.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions 
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright 
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright 
15  *   notice, this list of conditions and the following disclaimer in 
16  *   the documentation and/or other materials provided with the 
17  *   distribution.
18  * * Neither the name of olsr.org, olsrd nor the names of its 
19  *   contributors may be used to endorse or promote products derived 
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Visit http://www.olsr.org for more information.
36  *
37  * If you find this software useful feel free to make a donation
38  * to the project. For more information see the website or contact
39  * the copyright holders.
40  *
41  * $Id: oparse.y,v 1.23 2005/01/01 12:13:58 kattemat Exp $
42  */
43
44
45 #include <stddef.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52 #include <string.h>
53
54 #include "olsrd_conf.h"
55
56 #define PARSER_DEBUG 0
57
58 #define YYSTYPE struct conf_token *
59
60 void yyerror(char *);
61 int yylex(void);
62
63 static int ifs_in_curr_cfg = 0;
64
65
66
67 %}
68
69 %token TOK_OPEN
70 %token TOK_CLOSE
71 %token TOK_SEMI
72
73 %token TOK_STRING
74 %token TOK_INTEGER
75 %token TOK_FLOAT
76 %token TOK_BOOLEAN
77
78 %token TOK_IP6TYPE
79
80 %token TOK_DEBUGLEVEL
81 %token TOK_IPVERSION
82 %token TOK_HNA4
83 %token TOK_HNA6
84 %token TOK_PLUGIN
85 %token TOK_INTERFACE
86 %token TOK_NOINT
87 %token TOK_TOS
88 %token TOK_WILLINGNESS
89 %token TOK_IPCCON
90 %token TOK_USEHYST
91 %token TOK_HYSTSCALE
92 %token TOK_HYSTUPPER
93 %token TOK_HYSTLOWER
94 %token TOK_POLLRATE
95 %token TOK_TCREDUNDANCY
96 %token TOK_MPRCOVERAGE
97 %token TOK_LQ_LEVEL
98 %token TOK_LQ_WSIZE
99 %token TOK_CLEAR_SCREEN
100 %token TOK_PLNAME
101 %token TOK_PLPARAM
102
103 %token TOK_HOSTLABEL
104 %token TOK_NETLABEL
105 %token TOK_MAXIPC
106
107 %token TOK_IP4BROADCAST
108 %token TOK_IP6ADDRTYPE
109 %token TOK_IP6MULTISITE
110 %token TOK_IP6MULTIGLOBAL
111 %token TOK_HELLOINT
112 %token TOK_HELLOVAL
113 %token TOK_TCINT
114 %token TOK_TCVAL
115 %token TOK_MIDINT
116 %token TOK_MIDVAL
117 %token TOK_HNAINT
118 %token TOK_HNAVAL
119
120 %token TOK_IP4_ADDR
121 %token TOK_IP6_ADDR
122
123 %token TOK_COMMENT
124
125 %%
126
127 conf:
128           | conf block
129           | conf stmt
130 ;
131
132 stmt:       idebug
133           | iipversion
134           | bnoint
135           | atos
136           | awillingness
137           | busehyst
138           | fhystscale
139           | fhystupper
140           | fhystlower
141           | fpollrate
142           | atcredundancy
143           | amprcoverage
144           | alq_level
145           | alq_wsize
146           | bclear_screen
147           | vcomment
148 ;
149
150 block:      TOK_HNA4 hna4body
151           | TOK_HNA6 hna6body
152           | TOK_IPCCON ipcbody
153           | ifblock ifbody
154           | plblock plbody
155 ;
156
157 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
158 ;
159
160 hna4stmts: | hna4stmts hna4stmt
161 ;
162
163 hna4stmt:  vcomment
164          | ihna4entry
165 ;
166
167 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
168 ;
169
170 hna6stmts: | hna6stmts hna6stmt
171 ;
172
173 hna6stmt:  vcomment
174          | ihna6entry
175 ;
176
177 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
178 ;
179
180 ipcstmts: | ipcstmts ipcstmt
181 ;
182
183 ipcstmt:  vcomment
184           | imaxipc
185           | ipchost
186           | ipcnet
187 ;
188
189 ifblock:   ifstart ifnicks
190 ;
191
192 ifnicks:   | ifnicks ifnick
193 ;
194
195 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
196 ;
197
198 ifstmts:   | ifstmts ifstmt
199 ;
200
201 ifstmt:      vcomment
202              | isetip4br
203              | isetip6addrt
204              | isetip6mults
205              | isetip6multg
206              | isethelloint
207              | isethelloval
208              | isettcint
209              | isettcval
210              | isetmidint
211              | isetmidval
212              | isethnaint
213              | isethnaval
214 ;
215
216 plbody:     TOK_OPEN plstmts TOK_CLOSE
217 ;
218
219 plstmts:   | plstmts plstmt
220 ;
221
222 plstmt:     plparam
223           | vcomment
224 ;
225
226
227 imaxipc: TOK_MAXIPC TOK_INTEGER
228 {
229   cnf->ipc_connections = $2->integer;
230
231   cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
232
233   free($2);
234 }
235 ;
236
237
238 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
239 {
240   struct in_addr in;
241   struct ipc_host *ipch;
242
243   if(PARSER_DEBUG) printf("\tIPC host: %s\n", $2->string);
244   
245   if(inet_aton($2->string, &in) == 0)
246     {
247       fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
248       return -1;
249     }
250
251   ipch = malloc(sizeof(struct ipc_host));
252   ipch->host.v4 = in.s_addr;
253
254   ipch->next = cnf->ipc_hosts;
255   cnf->ipc_hosts = ipch;
256
257   free($2->string);
258   free($2);
259
260 }
261 ;
262
263 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
264 {
265   struct in_addr in1, in2;
266   struct ipc_net *ipcn;
267
268   if(PARSER_DEBUG) printf("\tIPC net: %s/%s\n", $2->string, $3->string);
269   
270   if(inet_aton($2->string, &in1) == 0)
271     {
272       fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
273       return -1;
274     }
275
276   if(inet_aton($3->string, &in2) == 0)
277     {
278       fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
279       return -1;
280     }
281
282   ipcn = malloc(sizeof(struct ipc_net));
283   ipcn->net.v4 = in1.s_addr;
284   ipcn->mask.v4 = in2.s_addr;
285
286   ipcn->next = cnf->ipc_nets;
287   cnf->ipc_nets = ipcn;
288
289   free($2->string);
290   free($2);
291   free($3->string);
292   free($3);
293
294 }
295 ;
296
297 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
298 {
299   struct in_addr in;
300   int ifcnt = ifs_in_curr_cfg;
301   struct olsr_if *ifs = cnf->interfaces;
302
303   if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
304
305   if(inet_aton($2->string, &in) == 0)
306     {
307       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
308       return -1;
309     }
310
311   while(ifcnt)
312     {
313       ifs->cnf->ipv4_broadcast.v4 = in.s_addr;
314
315       ifs = ifs->next;
316       ifcnt--;
317     }
318
319   free($2->string);
320   free($2);
321 }
322 ;
323
324 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
325 {
326   int ifcnt = ifs_in_curr_cfg;
327   struct olsr_if *ifs = cnf->interfaces;
328
329   if($2->boolean)
330     {
331       while(ifcnt)
332         {
333           ifs->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
334           
335           ifs = ifs->next;
336           ifcnt--;
337         }
338     }
339   else
340     {
341       while(ifcnt)
342         {
343           ifs->cnf->ipv6_addrtype = 0;
344           
345           ifs = ifs->next;
346           ifcnt--;
347         }
348     }
349
350   free($2);
351 }
352 ;
353
354 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
355 {
356   struct in6_addr in6;
357   int ifcnt = ifs_in_curr_cfg;
358   struct olsr_if *ifs = cnf->interfaces;
359
360   if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
361
362   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
363     {
364       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
365       return -1;
366     }
367
368   while(ifcnt)
369     {
370       memcpy(&ifs->cnf->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
371       
372       ifs = ifs->next;
373       ifcnt--;
374     }
375
376
377   free($2->string);
378   free($2);
379 }
380 ;
381
382
383 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
384 {
385   struct in6_addr in6;
386   int ifcnt = ifs_in_curr_cfg;
387   struct olsr_if *ifs = cnf->interfaces;
388
389   if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
390
391   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
392     {
393       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
394       return -1;
395     }
396
397   while(ifcnt)
398     {
399       memcpy(&ifs->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
400       
401       ifs = ifs->next;
402       ifcnt--;
403     }
404
405
406   free($2->string);
407   free($2);
408 }
409 ;
410 isethelloint: TOK_HELLOINT TOK_FLOAT
411 {
412   int ifcnt = ifs_in_curr_cfg;
413   struct olsr_if *ifs = cnf->interfaces;
414
415   if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
416
417   while(ifcnt)
418     {
419       ifs->cnf->hello_params.emission_interval = $2->floating;
420       
421       ifs = ifs->next;
422       ifcnt--;
423     }
424
425   free($2);
426 }
427 ;
428 isethelloval: TOK_HELLOVAL TOK_FLOAT
429 {
430   int ifcnt = ifs_in_curr_cfg;
431   struct olsr_if *ifs = cnf->interfaces;
432
433   if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
434
435   while(ifcnt)
436     {
437       ifs->cnf->hello_params.validity_time = $2->floating;
438       
439       ifs = ifs->next;
440       ifcnt--;
441     }
442
443   free($2);
444 }
445 ;
446 isettcint: TOK_TCINT TOK_FLOAT
447 {
448   int ifcnt = ifs_in_curr_cfg;
449   struct olsr_if *ifs = cnf->interfaces;
450
451   if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
452
453   while(ifcnt)
454     {
455       ifs->cnf->tc_params.emission_interval = $2->floating;
456       
457       ifs = ifs->next;
458       ifcnt--;
459     }
460   free($2);
461 }
462 ;
463 isettcval: TOK_TCVAL TOK_FLOAT
464 {
465   int ifcnt = ifs_in_curr_cfg;
466   struct olsr_if *ifs = cnf->interfaces;
467   
468   if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
469   while(ifcnt)
470     {
471       ifs->cnf->tc_params.validity_time = $2->floating;
472       
473       ifs = ifs->next;
474       ifcnt--;
475     }
476
477   free($2);
478 }
479 ;
480 isetmidint: TOK_MIDINT TOK_FLOAT
481 {
482   int ifcnt = ifs_in_curr_cfg;
483   struct olsr_if *ifs = cnf->interfaces;
484
485
486   if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
487   while(ifcnt)
488     {
489       ifs->cnf->mid_params.emission_interval = $2->floating;
490       
491       ifs = ifs->next;
492       ifcnt--;
493     }
494
495   free($2);
496 }
497 ;
498 isetmidval: TOK_MIDVAL TOK_FLOAT
499 {
500   int ifcnt = ifs_in_curr_cfg;
501   struct olsr_if *ifs = cnf->interfaces;
502
503   if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
504   while(ifcnt)
505     {
506       ifs->cnf->mid_params.validity_time = $2->floating;
507       
508       ifs = ifs->next;
509       ifcnt--;
510     }
511
512   free($2);
513 }
514 ;
515 isethnaint: TOK_HNAINT TOK_FLOAT
516 {
517   int ifcnt = ifs_in_curr_cfg;
518   struct olsr_if *ifs = cnf->interfaces;
519   
520   if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
521   while(ifcnt)
522     {
523       ifs->cnf->hna_params.emission_interval = $2->floating;
524       
525       ifs = ifs->next;
526       ifcnt--;
527     }
528
529   free($2);
530 }
531 ;
532 isethnaval: TOK_HNAVAL TOK_FLOAT
533 {
534   int ifcnt = ifs_in_curr_cfg;
535   struct olsr_if *ifs = cnf->interfaces;
536
537   if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
538   while(ifcnt)
539     {
540       ifs->cnf->hna_params.validity_time = $2->floating;
541       
542       ifs = ifs->next;
543       ifcnt--;
544     }
545
546   free($2);
547 }
548 ;
549
550
551 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
552 {
553
554   cnf->debug_level = $2->integer;
555   if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
556   free($2);
557 }
558 ;
559
560
561 iipversion:    TOK_IPVERSION TOK_INTEGER
562 {
563   if($2->integer == 4)
564     cnf->ip_version = AF_INET;
565   else if($2->integer == 6)
566     cnf->ip_version = AF_INET6;
567   else
568     {
569       fprintf(stderr, "IPversion must be 4 or 6!\n");
570       YYABORT;
571     }
572
573   if(PARSER_DEBUG) printf("IpVersion: %d\n", $2->integer);
574   free($2);
575 }
576 ;
577
578
579 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
580 {
581   struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
582   struct in_addr in;
583
584   if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
585
586   if(h == NULL)
587     {
588       fprintf(stderr, "Out of memory(HNA4)\n");
589       YYABORT;
590     }
591
592   if(inet_aton($1->string, &in) == 0)
593     {
594       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
595       return -1;
596     }
597   h->net.v4 = in.s_addr;
598   if(inet_aton($2->string, &in) == 0)
599     {
600       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
601       return -1;
602     }
603   h->netmask.v4 = in.s_addr;
604   /* Queue */
605   h->next = cnf->hna4_entries;
606   cnf->hna4_entries = h;
607
608   free($1->string);
609   free($1);
610   free($2->string);
611   free($2);
612
613 }
614 ;
615
616 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
617 {
618   struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
619   struct in6_addr in6;
620
621   if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
622
623   if(h == NULL)
624     {
625       fprintf(stderr, "Out of memory(HNA6)\n");
626       YYABORT;
627     }
628
629   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
630     {
631       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
632       return -1;
633     }
634   memcpy(&h->net, &in6, sizeof(struct in6_addr));
635
636   if(($2->integer < 0) || ($2->integer > 128))
637     {
638       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
639       return -1;
640     }
641
642   h->prefix_len = $2->integer;
643   /* Queue */
644   h->next = cnf->hna6_entries;
645   cnf->hna6_entries = h;
646
647   free($1->string);
648   free($1);
649   free($2);
650
651 }
652 ;
653
654 ifstart: TOK_INTERFACE
655 {
656   printf("setting ifs_in_curr_cfg = 0\n");
657   ifs_in_curr_cfg = 0;
658
659 }
660 ;
661
662 ifnick: TOK_STRING
663 {
664   struct olsr_if *in = malloc(sizeof(struct olsr_if));
665   
666   if(in == NULL)
667     {
668       fprintf(stderr, "Out of memory(ADD IF)\n");
669       YYABORT;
670     }
671
672   in->cnf = get_default_if_config();
673
674   if(in->cnf == NULL)
675     {
676       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
677       YYABORT;
678     }
679
680   in->name = $1->string;
681
682   /* Queue */
683   in->next = cnf->interfaces;
684   cnf->interfaces = in;
685
686   ifs_in_curr_cfg++;
687
688   free($1);
689 }
690 ;
691
692 bnoint: TOK_NOINT TOK_BOOLEAN
693 {
694   if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
695
696   cnf->allow_no_interfaces = $2->boolean;
697
698   free($2);
699 }
700 ;
701
702 atos: TOK_TOS TOK_INTEGER
703 {
704   if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
705   cnf->tos = $2->integer;
706
707   free($2);
708
709 }
710 ;
711
712 awillingness: TOK_WILLINGNESS TOK_INTEGER
713 {
714   cnf->willingness_auto = OLSR_FALSE;
715
716   if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
717   cnf->willingness = $2->integer;
718
719   free($2);
720
721 }
722 ;
723
724
725
726 busehyst: TOK_USEHYST TOK_BOOLEAN
727 {
728   cnf->use_hysteresis = $2->boolean;
729   if(cnf->use_hysteresis)
730     {
731       if(PARSER_DEBUG) printf("Hysteresis enabled\n");
732     }
733   else
734     {
735       if(PARSER_DEBUG) printf("Hysteresis disabled\n");
736     }
737   free($2);
738
739 }
740 ;
741
742
743 fhystscale: TOK_HYSTSCALE TOK_FLOAT
744 {
745   cnf->hysteresis_param.scaling = $2->floating;
746   if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
747   free($2);
748 }
749 ;
750
751
752 fhystupper: TOK_HYSTUPPER TOK_FLOAT
753 {
754   cnf->hysteresis_param.thr_high = $2->floating;
755   if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
756   free($2);
757 }
758 ;
759
760
761 fhystlower: TOK_HYSTLOWER TOK_FLOAT
762 {
763   cnf->hysteresis_param.thr_low = $2->floating;
764   if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
765   free($2);
766 }
767 ;
768
769 fpollrate: TOK_POLLRATE TOK_FLOAT
770 {
771   if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
772   cnf->pollrate = $2->floating;
773
774   free($2);
775 }
776 ;
777
778
779 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
780 {
781   if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
782   cnf->tc_redundancy = $2->integer;
783   free($2);
784 }
785 ;
786
787 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
788 {
789   if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
790   cnf->mpr_coverage = $2->integer;
791   free($2);
792 }
793 ;
794
795 alq_level: TOK_LQ_LEVEL TOK_INTEGER
796 {
797   if(PARSER_DEBUG) printf("Link quality level %d\n", $2->integer);
798   cnf->lq_level = $2->integer;
799   free($2);
800 }
801 ;
802
803 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
804 {
805   if(PARSER_DEBUG) printf("Link quality window size %d\n", $2->integer);
806   cnf->lq_wsize = $2->integer;
807   free($2);
808 }
809 ;
810
811 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
812 {
813   cnf->clear_screen = $2->boolean;
814
815   if (PARSER_DEBUG)
816     printf("Clear screen %s\n", cnf->clear_screen ? "enabled" : "disabled");
817
818   free($2);
819 }
820 ;
821
822 plblock: TOK_PLUGIN TOK_STRING
823 {
824   struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
825   
826   if(pe == NULL)
827     {
828       fprintf(stderr, "Out of memory(ADD PL)\n");
829       YYABORT;
830     }
831
832   pe->name = $2->string;
833
834   pe->params = NULL;
835   
836   if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
837
838   /* Queue */
839   pe->next = cnf->plugins;
840   cnf->plugins = pe;
841
842   free($2);
843 }
844 ;
845
846 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
847 {
848   struct plugin_param *pp = malloc(sizeof(struct plugin_param));
849   
850   if(pp == NULL)
851     {
852       fprintf(stderr, "Out of memory(ADD PP)\n");
853       YYABORT;
854     }
855   
856   if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
857   
858   pp->key = $2->string;
859   pp->value = $3->string;
860
861   /* Queue */
862   pp->next = cnf->plugins->params;
863   cnf->plugins->params = pp;
864
865   free($2);
866   free($3);
867 }
868 ;
869
870 vcomment:       TOK_COMMENT
871 {
872     //if(PARSER_DEBUG) printf("Comment\n");
873 }
874 ;
875
876
877
878 %%
879
880 void yyerror (char *string)
881 {
882   fprintf(stderr, "Config line %d: %s\n", current_line, string);
883 }