1 /* -------------------------------------------------------------------------
2 * parse.l - htun config parser
3 * Copyright (C) 2002 Moshe Jacobson <moshe@runslinux.net>,
4 * Ola Nordström <ola@triblock.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * -------------------------------------------------------------------------
21 /* $Id: parse.l,v 2.24 2003/01/24 01:20:50 jehsom Exp $ */
26 #include "y.tab.h" /* the generated yacc file */
28 extern config_data_t *config;
29 extern char *linehead, *textpoint;
33 comment [\t ]*[#|;].*\n
35 ip (([0-2]){0,1}([0-9]){1,2}\.){3}([0-2]){0,1}([0-9]){1,2}
37 file ((\/)|(\.\/))[a-zA-Z0-9\.\/]+
47 /* now we get the builtin push/pop state */
50 %s PRE_CLI PRE_SRV PRE_OPTIONS OPT
51 %x SRV CLI IP_S NUM_S ANS_S PORT_S FILE_S IPR IFN RDH USER_S PASS_S
54 <*>\n { linehead = yytext+1; } REJECT;
55 <*>. { textpoint = yytext; if(!linehead) linehead = textpoint; } REJECT;
56 <*>{space} { return SPACE; }
57 <*>{comment} { return NEWLINE; }
58 <*>(\n) { return NEWLINE; }
60 <PRE_CLI>(\{) { yy_push_state(CLI); return LEFT_BRACE;}
61 <PRE_SRV>(\{) { yy_push_state(SRV); return LEFT_BRACE;}
62 <PRE_OPTIONS>(\{) { yy_push_state(OPT); return LEFT_BRACE;}
64 <ANS_S>{ans} { yy_pop_state(); yylval.name = yytext; return ANSWER; }
66 <IP_S>{text} { yy_pop_state(); yylval.name = yytext; return IP; }
68 <NUM_S>{num} { yy_pop_state(); yylval.name = yytext; return NUM; }
70 <PORT_S>{port} { yy_pop_state(); yylval.name = yytext; return PORT; }
72 <FILE_S>{file} { yy_pop_state(); yylval.name = yytext; return FNAME; }
74 <IFN>{text} { yy_pop_state(); yylval.name = yytext; return IFNAME; }
76 <RDH>{text} { yy_pop_state(); yylval.name = yytext; return TEXT; }
78 <IPR>{ip}\/{range} { yy_pop_state(); yylval.name = yytext; return RANGE; }
80 <USER_S>{user} { yy_pop_state(); yylval.name = yytext; return USER; }
82 <PASS_S>{pass} { yy_pop_state(); yylval.name = yytext; return PASS; }
85 (\}) { BEGIN 0; return RIGHT_BRACE; }
86 (do_routing) { yy_push_state(ANS_S); return DO_ROUTING; }
87 (protocol) { yy_push_state(NUM_S); return PROTOCOL; }
89 (proxy_ip) { yy_push_state(IP_S); return PROXY_IP; }
90 (proxy_port) { yy_push_state(PORT_S); return PROXY_PORT; }
91 (proxy_user) { yy_push_state(USER_S); return PROXY_USER; }
92 (proxy_pass) { yy_push_state(PASS_S); return PROXY_PASS; }
94 (server_ip) { yy_push_state(IP_S); return SERVER_IP; }
95 (server_port) { yy_push_state(PORT_S); return SERVER_PORT; }
96 (secondary_server_port) { yy_push_state(PORT_S); return SERVER_PORT_2; }
98 (if_name) { yy_push_state(IFN); return ETHDEV; }
99 (iprange) { yy_push_state(IPR); return IP_RANGE; }
101 (connect_tries) { yy_push_state(NUM_S); return CON_T; }
102 (reconnect_tries) { yy_push_state(NUM_S); return RECON_T; }
103 (reconnect_sleep_sec) { yy_push_state(NUM_S); return RECON_SLEEP; }
105 (channel_2_idle_allow) { yy_push_state(NUM_S); return CHAN2_IDLE; }
106 (min_poll_interval_msec) { yy_push_state(NUM_S); return MIN_POLL_INTERVAL_MSEC; }
107 (max_poll_interval) { yy_push_state(NUM_S); return MAX_POLL_INTERVAL; }
108 (poll_backoff_rate) { yy_push_state(NUM_S); return POLL_BACKOFF_RATE; }
109 (ack_wait) { yy_push_state(NUM_S); return ACKWAIT; }
113 (\}) { BEGIN 0; return RIGHT_BRACE; }
114 (iprange) { yy_push_state(IPR); return IP_RANGE; }
116 /* Aliases. It's obvious it's a server port when it's in the server * section! */
117 ((server_)?port) { yy_push_state(PORT_S); return SERVER_PORT; }
119 /* Aliases. It's obvious it's a server port when it's in the server * section! */
120 (secondary_(server_)?port) { yy_push_state(PORT_S); return SERVER_PORT_2; }
122 (max_clients) { yy_push_state(NUM_S); return MAX_CLIENTS; }
123 (redirect_host) { yy_push_state(RDH); return REDIR_HOST; }
124 (redirect_port) { yy_push_state(PORT_S); return REDIR_PORT; }
126 (max_pending) { yy_push_state(NUM_S); return MAX_PENDING; }
127 (idle_disconnect) { yy_push_state(NUM_S); return IDLE_DISCONNECT; }
128 (clidata_timeout) { yy_push_state(NUM_S); return CLIDATA_TIMEOUT; }
129 (min_nack_delay) { yy_push_state(NUM_S); return MIN_NACK_DELAY; }
130 (packet_count_threshold) { yy_push_state(NUM_S); return PKT_COUNT_THRESHOLD; }
131 (packet_max_interval) { yy_push_state(NUM_S); return PKT_MAX_INTERVAL; }
132 (max_response_delay) { yy_push_state(NUM_S); return MAX_RESPONSE_DELAY; }
136 (daemonize) { yy_push_state(ANS_S); return DEMONIZE; }
137 (debug) { yy_push_state(ANS_S); return TEST; }
138 (tunfile) { yy_push_state(FILE_S); return TUN_FILE; }
139 (logfile) { yy_push_state(FILE_S); return LOG_FILE; }
140 (\}) { BEGIN 0; yylval.name = ""; return RIGHT_BRACE; }
143 (client) { yy_push_state(PRE_CLI); return CLIENT; }
144 (server) { yy_push_state(PRE_SRV); return SERVER; }
145 (options) { yy_push_state(PRE_OPTIONS); return OPTION; }
147 <*>(.) { return ERROR; }
151 config_data_t *read_config( const char *configfile )
153 FILE *fin = fopen( configfile, "r" );
156 fprintf(stderr, "Unable to open config file \"%s\"\n", configfile );
162 if((config = calloc(1, sizeof(config_data_t))) == NULL) {
163 fprintf(stderr, "Fatal: unable to malloc() space for config data.\n");
166 config->is_server = -1;
168 strncpy(config->cfgfile, configfile, PATH_MAX);
169 config->cfgfile[PATH_MAX-1] = '\0';
173 if( config->is_server == -1 ) {
174 fprintf(stderr, "Error \"server\" or \"client\" not declared in config file.\n");