Added bounds checking for config file parsing
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * OLSR ad-hoc routing table management protocol config parser
5  * Copyright (C) 2004 Andreas T√łnnesen (andreto@olsr.org)
6  *
7  * This file is part of the olsr.org OLSR daemon.
8  *
9  * olsr.org is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * olsr.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with olsr.org; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  * 
23  * 
24  * $Id: oparse.y,v 1.17 2004/11/20 18:46:03 kattemat Exp $
25  *
26  */
27
28
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <string.h>
37
38 #include "olsrd_conf.h"
39
40 #define PARSER_DEBUG 0
41
42 #define YYSTYPE struct conf_token *
43
44 void yyerror(char *);
45 int yylex(void);
46
47
48
49
50
51 %}
52
53 %token TOK_OPEN
54 %token TOK_CLOSE
55 %token TOK_SEMI
56
57 %token TOK_STRING
58 %token TOK_INTEGER
59 %token TOK_FLOAT
60 %token TOK_BOOLEAN
61
62 %token TOK_IP6TYPE
63
64 %token TOK_DEBUGLEVEL
65 %token TOK_IPVERSION
66 %token TOK_HNA4
67 %token TOK_HNA6
68 %token TOK_PLUGIN
69 %token TOK_INTERFACE
70 %token TOK_NOINT
71 %token TOK_TOS
72 %token TOK_WILLINGNESS
73 %token TOK_IPCCON
74 %token TOK_USEHYST
75 %token TOK_HYSTSCALE
76 %token TOK_HYSTUPPER
77 %token TOK_HYSTLOWER
78 %token TOK_POLLRATE
79 %token TOK_TCREDUNDANCY
80 %token TOK_MPRCOVERAGE
81 %token TOK_LQ_LEVEL
82 %token TOK_LQ_WSIZE
83 %token TOK_CLEAR_SCREEN
84 %token TOK_PLNAME
85 %token TOK_PLPARAM
86
87 %token TOK_HOSTLABEL
88 %token TOK_NETLABEL
89 %token TOK_MAXIPC
90
91 %token TOK_IP4BROADCAST
92 %token TOK_IP6ADDRTYPE
93 %token TOK_IP6MULTISITE
94 %token TOK_IP6MULTIGLOBAL
95 %token TOK_HELLOINT
96 %token TOK_HELLOVAL
97 %token TOK_TCINT
98 %token TOK_TCVAL
99 %token TOK_MIDINT
100 %token TOK_MIDVAL
101 %token TOK_HNAINT
102 %token TOK_HNAVAL
103
104 %token TOK_IP4_ADDR
105 %token TOK_IP6_ADDR
106
107 %token TOK_COMMENT
108
109 %%
110
111 conf:
112           | conf block
113           | conf stmt
114 ;
115
116 stmt:       idebug
117           | iipversion
118           | bnoint
119           | atos
120           | awillingness
121           | busehyst
122           | fhystscale
123           | fhystupper
124           | fhystlower
125           | fpollrate
126           | atcredundancy
127           | amprcoverage
128           | alq_level
129           | alq_wsize
130           | bclear_screen
131           | vcomment
132 ;
133
134 block:      TOK_HNA4 hna4body
135           | TOK_HNA6 hna6body
136           | TOK_IPCCON ipcbody
137           | ifblock ifbody
138           | plblock plbody
139 ;
140
141 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
142 ;
143
144 hna4stmts: | hna4stmts hna4stmt
145 ;
146
147 hna4stmt:  vcomment
148          | ihna4entry
149 ;
150
151 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
152 ;
153
154 hna6stmts: | hna6stmts hna6stmt
155 ;
156
157 hna6stmt:  vcomment
158          | ihna6entry
159 ;
160
161 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
162 ;
163
164 ipcstmts: | ipcstmts ipcstmt
165 ;
166
167 ipcstmt:  vcomment
168           | imaxipc
169           | ipchost
170           | ipcnet
171 ;
172
173 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
174 ;
175
176 ifstmts:   | ifstmts ifstmt
177 ;
178
179 ifstmt:      vcomment
180              | isetip4br
181              | isetip6addrt
182              | isetip6mults
183              | isetip6multg
184              | isethelloint
185              | isethelloval
186              | isettcint
187              | isettcval
188              | isetmidint
189              | isetmidval
190              | isethnaint
191              | isethnaval
192 ;
193
194 plbody:     TOK_OPEN plstmts TOK_CLOSE
195 ;
196
197 plstmts:   | plstmts plstmt
198 ;
199
200 plstmt:     plparam
201           | vcomment
202 ;
203
204
205 imaxipc: TOK_MAXIPC TOK_INTEGER
206 {
207   cnf->ipc_connections = $2->integer;
208
209   cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
210
211   free($2);
212 }
213 ;
214
215
216 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
217 {
218   struct in_addr in;
219   struct ipc_host *ipch;
220
221   if(PARSER_DEBUG) printf("\tIPC host: %s\n", $2->string);
222   
223   if(inet_aton($2->string, &in) == 0)
224     {
225       fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
226       exit(EXIT_FAILURE);
227     }
228
229   ipch = malloc(sizeof(struct ipc_host));
230   ipch->host.v4 = in.s_addr;
231
232   ipch->next = cnf->ipc_hosts;
233   cnf->ipc_hosts = ipch;
234
235   free($2->string);
236   free($2);
237
238 }
239 ;
240
241 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
242 {
243   struct in_addr in1, in2;
244   struct ipc_net *ipcn;
245
246   if(PARSER_DEBUG) printf("\tIPC net: %s/%s\n", $2->string, $3->string);
247   
248   if(inet_aton($2->string, &in1) == 0)
249     {
250       fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
251       exit(EXIT_FAILURE);
252     }
253
254   if(inet_aton($3->string, &in2) == 0)
255     {
256       fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
257       exit(EXIT_FAILURE);
258     }
259
260   ipcn = malloc(sizeof(struct ipc_net));
261   ipcn->net.v4 = in1.s_addr;
262   ipcn->mask.v4 = in2.s_addr;
263
264   ipcn->next = cnf->ipc_nets;
265   cnf->ipc_nets = ipcn;
266
267   free($2->string);
268   free($2);
269   free($3->string);
270   free($3);
271
272 }
273 ;
274
275 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
276 {
277   struct in_addr in;
278
279   if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
280
281   if(inet_aton($2->string, &in) == 0)
282     {
283       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
284       exit(EXIT_FAILURE);
285     }
286
287   cnf->interfaces->cnf->ipv4_broadcast.v4 = in.s_addr;
288
289   free($2->string);
290   free($2);
291 }
292 ;
293
294 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
295 {
296   if($2->boolean)
297     cnf->interfaces->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
298   else
299     cnf->interfaces->cnf->ipv6_addrtype = 0;
300
301   free($2);
302 }
303 ;
304
305 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
306 {
307   struct in6_addr in6;
308
309   if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
310
311   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
312     {
313       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
314       exit(EXIT_FAILURE);
315     }
316   memcpy(&cnf->interfaces->cnf->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
317
318
319   free($2->string);
320   free($2);
321 }
322 ;
323
324
325 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
326 {
327   struct in6_addr in6;
328
329   if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
330
331   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
332     {
333       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
334       exit(EXIT_FAILURE);
335     }
336   memcpy(&cnf->interfaces->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
337
338
339   free($2->string);
340   free($2);
341 }
342 ;
343 isethelloint: TOK_HELLOINT TOK_FLOAT
344 {
345     if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
346     if($2->floating < MIN_INTERVAL)
347       {
348         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
349         exit(EXIT_FAILURE);
350       }
351     cnf->interfaces->cnf->hello_params.emission_interval = $2->floating;
352     free($2);
353 }
354 ;
355 isethelloval: TOK_HELLOVAL TOK_FLOAT
356 {
357     if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
358     if($2->floating < MIN_INTERVAL)
359       {
360         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
361         exit(EXIT_FAILURE);
362       }
363     cnf->interfaces->cnf->hello_params.validity_time = $2->floating;
364     free($2);
365 }
366 ;
367 isettcint: TOK_TCINT TOK_FLOAT
368 {
369     if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
370     if($2->floating < MIN_INTERVAL)
371       {
372         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
373         exit(EXIT_FAILURE);
374       }
375     cnf->interfaces->cnf->tc_params.emission_interval = $2->floating;
376     free($2);
377 }
378 ;
379 isettcval: TOK_TCVAL TOK_FLOAT
380 {
381     if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
382     if($2->floating < MIN_INTERVAL)
383       {
384         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
385         exit(EXIT_FAILURE);
386       }
387     cnf->interfaces->cnf->tc_params.validity_time = $2->floating;
388     free($2);
389 }
390 ;
391 isetmidint: TOK_MIDINT TOK_FLOAT
392 {
393     if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
394     if($2->floating < MIN_INTERVAL)
395       {
396         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
397         exit(EXIT_FAILURE);
398       }
399     cnf->interfaces->cnf->mid_params.emission_interval = $2->floating;
400     free($2);
401 }
402 ;
403 isetmidval: TOK_MIDVAL TOK_FLOAT
404 {
405     if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
406     if($2->floating < MIN_INTERVAL)
407       {
408         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
409         exit(EXIT_FAILURE);
410       }
411     cnf->interfaces->cnf->mid_params.validity_time = $2->floating;
412     free($2);
413 }
414 ;
415 isethnaint: TOK_HNAINT TOK_FLOAT
416 {
417     if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
418     if($2->floating < MIN_INTERVAL)
419       {
420         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
421         exit(EXIT_FAILURE);
422       }
423     cnf->interfaces->cnf->hna_params.emission_interval = $2->floating;
424     free($2);
425 }
426 ;
427 isethnaval: TOK_HNAVAL TOK_FLOAT
428 {
429     if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
430     if($2->floating < MIN_INTERVAL)
431       {
432         fprintf(stderr, "%0.2f is not allowed\n", $2->floating);
433         exit(EXIT_FAILURE);
434       }
435     cnf->interfaces->cnf->hna_params.validity_time = $2->floating;
436     free($2);
437 }
438 ;
439
440
441 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
442 {
443
444   cnf->debug_level = $2->integer;
445   if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
446     if($2->integer < MIN_DEBUGLVL ||
447        $2->integer > MAX_DEBUGLVL)
448       {
449         fprintf(stderr, "Debuglevel %d is not allowed\n", $2->integer);
450         exit(EXIT_FAILURE);
451       }
452
453   free($2);
454 }
455 ;
456
457
458 iipversion:    TOK_IPVERSION TOK_INTEGER
459 {
460   if($2->integer == 4)
461     cnf->ip_version = AF_INET;
462   else if($2->integer == 6)
463     cnf->ip_version = AF_INET6;
464   else
465     {
466       fprintf(stderr, "IPversion must be 4 or 6!\n");
467       YYABORT;
468     }
469
470   if(PARSER_DEBUG) printf("IpVersion: %d\n", $2->integer);
471   free($2);
472 }
473 ;
474
475
476 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
477 {
478   struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
479   struct in_addr in;
480
481   if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
482
483   if(h == NULL)
484     {
485       fprintf(stderr, "Out of memory(HNA4)\n");
486       YYABORT;
487     }
488
489   if(inet_aton($1->string, &in) == 0)
490     {
491       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
492       exit(EXIT_FAILURE);
493     }
494   h->net.v4 = in.s_addr;
495   if(inet_aton($2->string, &in) == 0)
496     {
497       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
498       exit(EXIT_FAILURE);
499     }
500   h->netmask.v4 = in.s_addr;
501   /* Queue */
502   h->next = cnf->hna4_entries;
503   cnf->hna4_entries = h;
504
505   free($1->string);
506   free($1);
507   free($2->string);
508   free($2);
509
510 }
511
512 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
513 {
514   struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
515   struct in6_addr in6;
516
517   if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
518
519   if(h == NULL)
520     {
521       fprintf(stderr, "Out of memory(HNA6)\n");
522       YYABORT;
523     }
524
525   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
526     {
527       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
528       exit(EXIT_FAILURE);
529     }
530   memcpy(&h->net, &in6, sizeof(struct in6_addr));
531
532   if(($2->integer < 0) || ($2->integer > 128))
533     {
534       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
535       exit(EXIT_FAILURE);
536     }
537
538   h->prefix_len = $2->integer;
539   /* Queue */
540   h->next = cnf->hna6_entries;
541   cnf->hna6_entries = h;
542
543   free($1->string);
544   free($1);
545   free($2);
546
547 }
548
549 ifblock: TOK_INTERFACE TOK_STRING
550 {
551   struct olsr_if *in = malloc(sizeof(struct olsr_if));
552   
553   if(in == NULL)
554     {
555       fprintf(stderr, "Out of memory(ADD IF)\n");
556       YYABORT;
557     }
558
559   in->cnf = get_default_if_config();
560
561   if(in->cnf == NULL)
562     {
563       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
564       YYABORT;
565     }
566
567   in->name = $2->string;
568
569   /* Queue */
570   in->next = cnf->interfaces;
571   cnf->interfaces = in;
572
573   free($2);
574 }
575
576 bnoint: TOK_NOINT TOK_BOOLEAN
577 {
578   if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
579
580   cnf->allow_no_interfaces = $2->boolean;
581
582   free($2);
583 }
584 ;
585
586 atos: TOK_TOS TOK_INTEGER
587 {
588   if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
589     if($2->integer < MIN_TOS ||
590        $2->integer > MAX_TOS)
591       {
592         fprintf(stderr, "%d is not allowed\n", $2->integer);
593         exit(EXIT_FAILURE);
594       }
595
596   cnf->tos = $2->integer;
597
598   free($2);
599
600 }
601 ;
602
603 awillingness: TOK_WILLINGNESS TOK_INTEGER
604 {
605   cnf->willingness_auto = OLSR_FALSE;
606
607   if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
608     if($2->integer < MIN_WILLINGNESS ||
609        $2->integer > MAX_WILLINGNESS)
610       {
611         fprintf(stderr, "willingness %d is not allowed\n", $2->integer);
612         exit(EXIT_FAILURE);
613       }
614   cnf->willingness = $2->integer;
615
616   free($2);
617
618 }
619 ;
620
621
622
623 busehyst: TOK_USEHYST TOK_BOOLEAN
624 {
625   cnf->use_hysteresis = $2->boolean;
626   if(cnf->use_hysteresis)
627     {
628       if(PARSER_DEBUG) printf("Hysteresis enabled\n");
629     }
630   else
631     {
632       if(PARSER_DEBUG) printf("Hysteresis disabled\n");
633     }
634   free($2);
635
636 }
637 ;
638
639
640 fhystscale: TOK_HYSTSCALE TOK_FLOAT
641 {
642   cnf->hysteresis_param.scaling = $2->floating;
643   if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
644     if($2->floating < MIN_HYST_PARAM ||
645        $2->floating > MAX_HYST_PARAM)
646       {
647         fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", $2->floating);
648         exit(EXIT_FAILURE);
649       }
650
651   free($2);
652 }
653 ;
654
655
656 fhystupper: TOK_HYSTUPPER TOK_FLOAT
657 {
658   cnf->hysteresis_param.thr_high = $2->floating;
659   if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
660     if($2->floating < MIN_HYST_PARAM ||
661        $2->floating > MAX_HYST_PARAM)
662       {
663         fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", $2->floating);
664         exit(EXIT_FAILURE);
665       }
666   free($2);
667 }
668 ;
669
670
671 fhystlower: TOK_HYSTLOWER TOK_FLOAT
672 {
673   cnf->hysteresis_param.thr_low = $2->floating;
674   if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
675     if($2->floating < MIN_HYST_PARAM ||
676        $2->floating > MAX_HYST_PARAM)
677       {
678         fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", $2->floating);
679         exit(EXIT_FAILURE);
680       }
681   free($2);
682 }
683 ;
684
685 fpollrate: TOK_POLLRATE TOK_FLOAT
686 {
687   if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
688     if($2->floating < MIN_POLLRATE ||
689        $2->floating > MAX_POLLRATE)
690       {
691         fprintf(stderr, "Pollrate %0.2f is not allowed\n", $2->floating);
692         exit(EXIT_FAILURE);
693       }
694   cnf->pollrate = $2->floating;
695
696   free($2);
697 }
698 ;
699
700
701 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
702 {
703   if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
704   if($2->integer < MIN_TC_REDUNDANCY ||
705      $2->integer > MAX_TC_REDUNDANCY)
706     {
707       fprintf(stderr, "TC redundancy %d is not allowed\n", $2->integer);
708       exit(EXIT_FAILURE);
709     }
710
711   cnf->tc_redundancy = $2->integer;
712
713   free($2);
714
715 }
716 ;
717
718 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
719 {
720   if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
721     if($2->integer < MIN_MPR_COVERAGE ||
722        $2->integer > MAX_MPR_COVERAGE)
723       {
724         fprintf(stderr, "MPR coverage %d is not allowed\n", $2->integer);
725         exit(EXIT_FAILURE);
726       }
727
728   cnf->mpr_coverage = $2->integer;
729
730   free($2);
731 }
732 ;
733
734 alq_level: TOK_LQ_LEVEL TOK_INTEGER
735 {
736   if(PARSER_DEBUG) printf("Link quality level %d\n", $2->integer);
737   cnf->lq_level = $2->integer;
738
739   free($2);
740 }
741 ;
742
743 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
744 {
745   if(PARSER_DEBUG) printf("Link quality window size %d\n", $2->integer);
746   cnf->lq_wsize = $2->integer;
747
748   free($2);
749 }
750 ;
751
752 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
753 {
754   cnf->clear_screen = $2->boolean;
755
756   if (PARSER_DEBUG)
757     printf("Clear screen %s\n", cnf->clear_screen ? "enabled" : "disabled");
758
759   free($2);
760 }
761 ;
762
763 plblock: TOK_PLUGIN TOK_STRING
764 {
765   struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
766   
767   if(pe == NULL)
768     {
769       fprintf(stderr, "Out of memory(ADD PL)\n");
770       YYABORT;
771     }
772
773   pe->name = $2->string;
774
775   pe->params = NULL;
776   
777   if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
778
779   /* Queue */
780   pe->next = cnf->plugins;
781   cnf->plugins = pe;
782
783   free($2);
784 }
785 ;
786
787 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
788 {
789   struct plugin_param *pp = malloc(sizeof(struct plugin_param));
790   
791   if(pp == NULL)
792     {
793       fprintf(stderr, "Out of memory(ADD PP)\n");
794       YYABORT;
795     }
796   
797   if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
798   
799   pp->key = $2->string;
800   pp->value = $3->string;
801
802   /* Queue */
803   pp->next = cnf->plugins->params;
804   cnf->plugins->params = pp;
805
806   free($2);
807   free($3);
808 }
809 ;
810
811 vcomment:       TOK_COMMENT
812 {
813     //if(PARSER_DEBUG) printf("Comment\n");
814 }
815 ;
816
817
818
819 %%
820
821 void yyerror (char *string)
822 {
823   fprintf(stderr, "Config line %d: %s\n", current_line, string);
824 }