1 /*
2  * conf.c
3  * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4  * All rights reserved.
5  *
6  * $Id: conf.c,v 1.20 2015/03/14 06:11:31 marc Exp marc $
7  *
8  */
9 
10 #include "headers.h"
11 
12 static const char rcsid[] __attribute__ ((used)) = "$Id: conf.c,v 1.20 2015/03/14 06:11:31 marc Exp marc $";
13 
parse_decls(struct sym * sym)14 void parse_decls(struct sym *sym)
15 {
16     /* Top level of parser */
17     while (1)
18 	switch (sym->code) {
19 	case S_closebra:
20 	case S_eof:
21 	    return;
22 	    case_CC_Tokens;
23 #ifdef WITH_SSL
24 	case S_ssl:
25 	case S_tls:
26 	    sym_get(sym);
27 	    switch (sym->code) {
28 	    case S_certfile:
29 		sym_get(sym);
30 		parse(sym, S_equal);
31 		strset(&ssl_cert, sym->buf);
32 		sym_get(sym);
33 		continue;
34 	    case S_keyfile:
35 		sym_get(sym);
36 		parse(sym, S_equal);
37 		strset(&ssl_key, sym->buf);
38 		sym_get(sym);
39 		continue;
40 	    case S_passphrase:
41 		sym_get(sym);
42 		parse(sym, S_equal);
43 		strset(&ssl_pass, sym->buf);
44 		sym_get(sym);
45 		continue;
46 	    default:
47 		parse_error_expect(sym, S_certfile, S_keyfile, S_passphrase, S_unknown);
48 	    }
49 #endif
50 	case S_rebalance:
51 	    sym_get(sym);
52 	    parse(sym, S_equal);
53 	    rebalance = parse_int(sym);
54 	    continue;
55 	case S_idle:
56 	    sym_get(sym);
57 	    parse(sym, S_timeout);
58 	    parse(sym, S_equal);
59 	    conntimeout = (u_long) parse_int(sym);
60 	    continue;
61 	case S_retire:
62 	    sym_get(sym);
63 	    parse(sym, S_limit);
64 	    parse(sym, S_equal);
65 	    id_max = (u_long) parse_int(sym);
66 	    continue;
67 	case S_remote:
68 	    {
69 		char *ad = NULL, *po = NULL;
70 		int protocol = 0;
71 		int weight = 1;
72 		uint16_t p;
73 
74 		sym_get(sym);
75 		parse(sym, S_equal);
76 		parse(sym, S_openbra);
77 		while (sym->code != S_closebra && sym->code != S_eof) {
78 		    switch (sym->code) {
79 		    case S_address:
80 			sym_get(sym);
81 			parse(sym, S_equal);
82 			strset(&ad, sym->buf);
83 			sym_get(sym);
84 			continue;
85 		    case S_port:
86 			sym_get(sym);
87 			parse(sym, S_equal);
88 			strset(&po, sym->buf);
89 			sym_get(sym);
90 			continue;
91 		    case S_protocol:
92 			sym_get(sym);
93 			parse(sym, S_equal);
94 			switch (sym->code) {
95 			case S_TCP:
96 			    protocol = IPPROTO_TCP;
97 			    break;
98 #ifdef IPPROTO_SCTP
99 			case S_SCTP:
100 			    protocol = IPPROTO_SCTP;
101 			    break;
102 #endif
103 			default:
104 			    parse_error_expect(sym, S_TCP,
105 #ifdef IPPROTO_SCTP
106 					       S_SCTP,
107 #endif
108 					       S_unknown);
109 			}
110 			sym_get(sym);
111 			break;
112 
113 		    case S_weight:
114 			sym_get(sym);
115 			parse(sym, S_equal);
116 			weight = parse_int(sym);
117 			continue;
118 		    default:
119 			parse_error_expect(sym, S_address, S_port, S_protocol, S_weight, S_unknown);
120 		    }
121 		}
122 		parse(sym, S_closebra);
123 
124 		con_arr = Xrealloc(con_arr, (con_arr_len + 1) * sizeof(struct connect_address_s));
125 
126 		memset(&con_arr[con_arr_len], 0, sizeof(struct connect_address_s));
127 
128 		if (service_to_port(&p, po, SOCK_STREAM))
129 		    parse_error(sym, "Expected an service or port, but got '%s'", sym->buf);
130 
131 		if (su_pton_p(&con_arr[con_arr_len].sa, ad, p))
132 		    parse_error(sym, "Expected an IP address, but got '%s'", sym->buf);
133 
134 		con_arr[con_arr_len].protocol = protocol;
135 		con_arr[con_arr_len].weight = weight;
136 		if (con_arr[con_arr_len].weight < 1)
137 		    con_arr[con_arr_len].weight = 1;
138 		con_arr_len++;
139 		Xfree(&ad);
140 		Xfree(&po);
141 		continue;
142 	    }
143 	case S_local:
144 	    sym_get(sym);
145 	    parse(sym, S_address);
146 	    parse(sym, S_equal);
147 	    if (!lcladdr)
148 		lcladdr = Xcalloc(1, sizeof(sockaddr_union));
149 	    if (su_pton(lcladdr, sym->buf))
150 		parse_error(sym, "Expected an IP address, but got '%s'", sym->buf);
151 
152 	    sym_get(sym);
153 	    continue;
154 
155 	default:
156 	    parse_error(sym, "'%s' unexpected", sym->buf);
157 	}
158 }
159