diff options
author | Max Krasnyansky <maxk@qualcomm.com> | 2002-03-08 21:12:35 +0000 |
---|---|---|
committer | Max Krasnyansky <maxk@qualcomm.com> | 2002-03-08 21:12:35 +0000 |
commit | c98b2f82a4e532ca61592b08e3ad60749eb9f8d7 (patch) | |
tree | 19a3df72d2cd6a8d64b7d98473261c7e07e306a0 /hcid/parser.y |
Initial revision
Diffstat (limited to 'hcid/parser.y')
-rw-r--r-- | hcid/parser.y | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/hcid/parser.y b/hcid/parser.y new file mode 100644 index 00000000..e8be6c99 --- /dev/null +++ b/hcid/parser.y @@ -0,0 +1,272 @@ +%{ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <stdarg.h> + +#include <sys/socket.h> +#include <asm/types.h> + +#include <bluetooth.h> +#include <hci.h> +#include <hci_lib.h> + +#include "hcid.h" +#include "kword.h" + +int cfg_error(const char *fmt, ...); + +int yyparse(void); +int yylex(void); +int yyerror(char *s); + +%} + +%union { + char *str; + long num; +} + +%token K_OPTIONS K_DEVICE +%token K_AUTOINIT K_SECURITY +%token K_PTYPE K_NAME K_CLASS K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN +%token K_PINHELP +%token K_YES K_NO + +%token <str> WORD PATH STRING LIST +%token <num> NUM + +%type <num> bool pkt_type link_mode link_policy sec_mode +%type <str> dev_name + +%% +config: statement | config statement; +statement: + K_OPTIONS hcid_options + + | K_DEVICE device_options + + | WORD { + cfg_error("Invalid statement '%s'", $1); + } + | error { + yyclearin; yyerrok; + } + ; + +hcid_options: '{' hcid_opts '}' +hcid_opts: | hcid_opt ';' | error ';' | hcid_opts hcid_opt ';'; +hcid_opt: + K_AUTOINIT bool { + hcid.auto_init = $2; + } + + | K_SECURITY sec_mode { + hcid.security = $2; + } + + | K_PINHELP PATH { + if (hcid.pin_helper) + free(hcid.pin_helper); + hcid.pin_helper = strdup($2); + } + + | WORD { + cfg_error("Unknown option '%s'", $1); + } + ; + +sec_mode: + WORD { + int opt = find_keyword(sec_param, $1); + if (opt < 0) { + cfg_error("Unknown security mode '%s'", $1); + $$ = 0; + } else + $$ = opt; + } + + | K_NO { $$ = HCID_SEC_NONE; } + ; + +device_options: '{' device_opts '}' +device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; +device_opt: + K_PTYPE pkt_type { + devi.pkt_type = $2; + } + + | K_LM link_mode { + devi.link_mode = $2; + } + + | K_LP link_policy { + devi.link_policy = $2; + } + + | K_NAME dev_name { + if (devi.name) + free(devi.name); + devi.name = $2; + } + + | K_CLASS NUM { + devi.class = $2; + } + + | K_AUTH bool { + devi.auth = $2; + } + + | K_ENCRYPT bool { + devi.encrypt = $2; + } + + | K_ISCAN bool { + if ($2) + devi.scan |= SCAN_INQUIRY; + else + devi.scan &= ~SCAN_INQUIRY; + } + + | K_PSCAN bool { + if ($2) + devi.scan |= SCAN_PAGE; + else + devi.scan &= ~SCAN_PAGE; + } + + | WORD { + cfg_error("Unknown option '%s'",$1); + YYABORT; + } + ; + +dev_name: + WORD { + $$ = strdup($1); + } + + | STRING { + $$ = strdup($1); + } + ; + +pkt_type: + WORD { + int opt; + if (!hci_strtoptype($1, &opt)) + cfg_error("Unknown packet type '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtoptype($1, &opt)) + cfg_error("Unknown packet type '%s'", $1); + $$ = opt; + } + ; + +link_mode: + WORD { + int opt; + if (!hci_strtolm($1, &opt)) + cfg_error("Unknown link mode '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtolm($1, &opt)) + cfg_error("Unknown link mode '%s'", $1); + $$ = opt; + } + ; + +link_policy: + WORD { + int opt; + if (!hci_strtolp($1, &opt)) + cfg_error("Unknown link policy '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtolp($1, &opt)) + cfg_error("Unknown link policy '%s'", $1); + $$ = opt; + } + ; + +bool: K_YES { $$ = 1; } | K_NO { $$ = 0; }; + +%% + +int yyerror(char *s) +{ + syslog(LOG_ERR, "%s line %d\n", s, lineno); + return 0; +} + +int cfg_error(const char *fmt, ...) +{ + char buf[255]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf,sizeof(buf),fmt,ap); + va_end(ap); + + yyerror(buf); + return 0; +} + +/* + * Read config file. + */ +int read_config(char *file) +{ + extern FILE *yyin; + + if( !(yyin = fopen(file,"r")) ){ + syslog(LOG_ERR,"Can not open %s", file); + return -1; + } + + lineno = 1; + yyparse(); + + fclose(yyin); + + return 0; +} |