Deleted Added
full compact
parse.y (207371) parse.y (210883)
1%{
2/*-
3 * Copyright (c) 2009-2010 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Pawel Jakub Dawidek under sponsorship from
7 * the FreeBSD Foundation.
8 *

--- 13 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
1%{
2/*-
3 * Copyright (c) 2009-2010 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Pawel Jakub Dawidek under sponsorship from
7 * the FreeBSD Foundation.
8 *

--- 13 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD: head/sbin/hastd/parse.y 207371 2010-04-29 15:36:32Z pjd $
30 * $FreeBSD: head/sbin/hastd/parse.y 210883 2010-08-05 19:08:54Z pjd $
31 */
32
33#include <sys/param.h> /* MAXHOSTNAMELEN */
34#include <sys/queue.h>
35#include <sys/sysctl.h>
36
37#include <arpa/inet.h>
38
39#include <assert.h>
40#include <err.h>
41#include <stdio.h>
42#include <string.h>
43#include <sysexits.h>
44#include <unistd.h>
45
31 */
32
33#include <sys/param.h> /* MAXHOSTNAMELEN */
34#include <sys/queue.h>
35#include <sys/sysctl.h>
36
37#include <arpa/inet.h>
38
39#include <assert.h>
40#include <err.h>
41#include <stdio.h>
42#include <string.h>
43#include <sysexits.h>
44#include <unistd.h>
45
46#include <pjdlog.h>
47
46#include "hast.h"
47
48extern int depth;
49extern int lineno;
50
51extern FILE *yyin;
52extern char *yytext;
53
48#include "hast.h"
49
50extern int depth;
51extern int lineno;
52
53extern FILE *yyin;
54extern char *yytext;
55
54static struct hastd_config lconfig;
56static struct hastd_config *lconfig;
55static struct hast_resource *curres;
56static bool mynode;
57
58static char depth0_control[HAST_ADDRSIZE];
59static char depth0_listen[HAST_ADDRSIZE];
60static int depth0_replication;
61static int depth0_timeout;
62
63static char depth1_provname[PATH_MAX];
64static char depth1_localpath[PATH_MAX];
65
57static struct hast_resource *curres;
58static bool mynode;
59
60static char depth0_control[HAST_ADDRSIZE];
61static char depth0_listen[HAST_ADDRSIZE];
62static int depth0_replication;
63static int depth0_timeout;
64
65static char depth1_provname[PATH_MAX];
66static char depth1_localpath[PATH_MAX];
67
66static bool
68extern void yyrestart(FILE *);
69
70static int
67isitme(const char *name)
68{
69 char buf[MAXHOSTNAMELEN];
70 char *pos;
71 size_t bufsize;
72
73 /*
74 * First check if the give name matches our full hostname.
75 */
71isitme(const char *name)
72{
73 char buf[MAXHOSTNAMELEN];
74 char *pos;
75 size_t bufsize;
76
77 /*
78 * First check if the give name matches our full hostname.
79 */
76 if (gethostname(buf, sizeof(buf)) < 0)
77 err(EX_OSERR, "gethostname() failed");
80 if (gethostname(buf, sizeof(buf)) < 0) {
81 pjdlog_errno(LOG_ERR, "gethostname() failed");
82 return (-1);
83 }
78 if (strcmp(buf, name) == 0)
84 if (strcmp(buf, name) == 0)
79 return (true);
85 return (1);
80
81 /*
82 * Now check if it matches first part of the host name.
83 */
84 pos = strchr(buf, '.');
85 if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0)
86
87 /*
88 * Now check if it matches first part of the host name.
89 */
90 pos = strchr(buf, '.');
91 if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0)
86 return (true);
92 return (1);
87
88 /*
89 * At the end check if name is equal to our host's UUID.
90 */
91 bufsize = sizeof(buf);
93
94 /*
95 * At the end check if name is equal to our host's UUID.
96 */
97 bufsize = sizeof(buf);
92 if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0)
93 err(EX_OSERR, "sysctlbyname(kern.hostuuid) failed");
98 if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) {
99 pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed");
100 return (-1);
101 }
94 if (strcasecmp(buf, name) == 0)
102 if (strcasecmp(buf, name) == 0)
95 return (true);
103 return (1);
96
97 /*
98 * Looks like this isn't about us.
99 */
104
105 /*
106 * Looks like this isn't about us.
107 */
100 return (false);
108 return (0);
101}
102
103void
104yyerror(const char *str)
105{
106
109}
110
111void
112yyerror(const char *str)
113{
114
107 fprintf(stderr, "error at line %d near '%s': %s\n",
115 pjdlog_error("Unable to parse configuration file at line %d near '%s': %s",
108 lineno, yytext, str);
109}
110
111struct hastd_config *
116 lineno, yytext, str);
117}
118
119struct hastd_config *
112yy_config_parse(const char *config)
120yy_config_parse(const char *config, bool exitonerror)
113{
114 int ret;
115
116 curres = NULL;
117 mynode = false;
121{
122 int ret;
123
124 curres = NULL;
125 mynode = false;
126 depth = 0;
127 lineno = 0;
118
119 depth0_timeout = HAST_TIMEOUT;
120 depth0_replication = HAST_REPLICATION_MEMSYNC;
121 strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
122 strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
123
128
129 depth0_timeout = HAST_TIMEOUT;
130 depth0_replication = HAST_REPLICATION_MEMSYNC;
131 strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
132 strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
133
124 TAILQ_INIT(&lconfig.hc_resources);
134 lconfig = calloc(1, sizeof(*lconfig));
135 if (lconfig == NULL) {
136 pjdlog_error("Unable to allocate memory for configuration.");
137 if (exitonerror)
138 exit(EX_TEMPFAIL);
139 return (NULL);
140 }
125
141
142 TAILQ_INIT(&lconfig->hc_resources);
143
126 yyin = fopen(config, "r");
144 yyin = fopen(config, "r");
127 if (yyin == NULL)
128 err(EX_OSFILE, "cannot open configuration file %s", config);
145 if (yyin == NULL) {
146 pjdlog_errno(LOG_ERR, "Unable to open configuration file %s",
147 config);
148 yy_config_free(lconfig);
149 if (exitonerror)
150 exit(EX_OSFILE);
151 return (NULL);
152 }
153 yyrestart(yyin);
129 ret = yyparse();
130 fclose(yyin);
131 if (ret != 0) {
154 ret = yyparse();
155 fclose(yyin);
156 if (ret != 0) {
132 yy_config_free(&lconfig);
133 exit(EX_CONFIG);
157 yy_config_free(lconfig);
158 if (exitonerror)
159 exit(EX_CONFIG);
160 return (NULL);
134 }
135
136 /*
137 * Let's see if everything is set up.
138 */
161 }
162
163 /*
164 * Let's see if everything is set up.
165 */
139 if (lconfig.hc_controladdr[0] == '\0') {
140 strlcpy(lconfig.hc_controladdr, depth0_control,
141 sizeof(lconfig.hc_controladdr));
166 if (lconfig->hc_controladdr[0] == '\0') {
167 strlcpy(lconfig->hc_controladdr, depth0_control,
168 sizeof(lconfig->hc_controladdr));
142 }
169 }
143 if (lconfig.hc_listenaddr[0] == '\0') {
144 strlcpy(lconfig.hc_listenaddr, depth0_listen,
145 sizeof(lconfig.hc_listenaddr));
170 if (lconfig->hc_listenaddr[0] == '\0') {
171 strlcpy(lconfig->hc_listenaddr, depth0_listen,
172 sizeof(lconfig->hc_listenaddr));
146 }
173 }
147 TAILQ_FOREACH(curres, &lconfig.hc_resources, hr_next) {
174 TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) {
148 assert(curres->hr_provname[0] != '\0');
149 assert(curres->hr_localpath[0] != '\0');
150 assert(curres->hr_remoteaddr[0] != '\0');
151
152 if (curres->hr_replication == -1) {
153 /*
154 * Replication is not set at resource-level.
155 * Use global or default setting.

--- 4 unchanged lines hidden (view full) ---

160 /*
161 * Timeout is not set at resource-level.
162 * Use global or default setting.
163 */
164 curres->hr_timeout = depth0_timeout;
165 }
166 }
167
175 assert(curres->hr_provname[0] != '\0');
176 assert(curres->hr_localpath[0] != '\0');
177 assert(curres->hr_remoteaddr[0] != '\0');
178
179 if (curres->hr_replication == -1) {
180 /*
181 * Replication is not set at resource-level.
182 * Use global or default setting.

--- 4 unchanged lines hidden (view full) ---

187 /*
188 * Timeout is not set at resource-level.
189 * Use global or default setting.
190 */
191 curres->hr_timeout = depth0_timeout;
192 }
193 }
194
168 return (&lconfig);
195 return (lconfig);
169}
170
171void
172yy_config_free(struct hastd_config *config)
173{
174 struct hast_resource *res;
175
176 while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) {
177 TAILQ_REMOVE(&config->hc_resources, res, hr_next);
178 free(res);
179 }
196}
197
198void
199yy_config_free(struct hastd_config *config)
200{
201 struct hast_resource *res;
202
203 while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) {
204 TAILQ_REMOVE(&config->hc_resources, res, hr_next);
205 free(res);
206 }
207 free(config);
180}
181%}
182
183%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
184%token FULLSYNC MEMSYNC ASYNC
185%token NUM STR OB CB
186
187%type <num> replication_type

--- 30 unchanged lines hidden (view full) ---

218
219control_statement: CONTROL STR
220 {
221 switch (depth) {
222 case 0:
223 if (strlcpy(depth0_control, $2,
224 sizeof(depth0_control)) >=
225 sizeof(depth0_control)) {
208}
209%}
210
211%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
212%token FULLSYNC MEMSYNC ASYNC
213%token NUM STR OB CB
214
215%type <num> replication_type

--- 30 unchanged lines hidden (view full) ---

246
247control_statement: CONTROL STR
248 {
249 switch (depth) {
250 case 0:
251 if (strlcpy(depth0_control, $2,
252 sizeof(depth0_control)) >=
253 sizeof(depth0_control)) {
226 errx(EX_CONFIG, "control argument too long");
254 pjdlog_error("control argument is too long.");
255 return (1);
227 }
228 break;
229 case 1:
230 if (mynode) {
256 }
257 break;
258 case 1:
259 if (mynode) {
231 if (strlcpy(lconfig.hc_controladdr, $2,
232 sizeof(lconfig.hc_controladdr)) >=
233 sizeof(lconfig.hc_controladdr)) {
234 errx(EX_CONFIG,
235 "control argument too long");
260 if (strlcpy(lconfig->hc_controladdr, $2,
261 sizeof(lconfig->hc_controladdr)) >=
262 sizeof(lconfig->hc_controladdr)) {
263 pjdlog_error("control argument is too long.");
264 return (1);
236 }
237 }
238 break;
239 default:
240 assert(!"control at wrong depth level");
241 }
242 }
243 ;
244
245listen_statement: LISTEN STR
246 {
247 switch (depth) {
248 case 0:
249 if (strlcpy(depth0_listen, $2,
250 sizeof(depth0_listen)) >=
251 sizeof(depth0_listen)) {
265 }
266 }
267 break;
268 default:
269 assert(!"control at wrong depth level");
270 }
271 }
272 ;
273
274listen_statement: LISTEN STR
275 {
276 switch (depth) {
277 case 0:
278 if (strlcpy(depth0_listen, $2,
279 sizeof(depth0_listen)) >=
280 sizeof(depth0_listen)) {
252 errx(EX_CONFIG, "listen argument too long");
281 pjdlog_error("listen argument is too long.");
282 return (1);
253 }
254 break;
255 case 1:
256 if (mynode) {
283 }
284 break;
285 case 1:
286 if (mynode) {
257 if (strlcpy(lconfig.hc_listenaddr, $2,
258 sizeof(lconfig.hc_listenaddr)) >=
259 sizeof(lconfig.hc_listenaddr)) {
260 errx(EX_CONFIG,
261 "listen argument too long");
287 if (strlcpy(lconfig->hc_listenaddr, $2,
288 sizeof(lconfig->hc_listenaddr)) >=
289 sizeof(lconfig->hc_listenaddr)) {
290 pjdlog_error("listen argument is too long.");
291 return (1);
262 }
263 }
264 break;
265 default:
266 assert(!"listen at wrong depth level");
267 }
268 }
269 ;

--- 41 unchanged lines hidden (view full) ---

311node_statement: ON node_start OB node_entries CB
312 {
313 mynode = false;
314 }
315 ;
316
317node_start: STR
318 {
292 }
293 }
294 break;
295 default:
296 assert(!"listen at wrong depth level");
297 }
298 }
299 ;

--- 41 unchanged lines hidden (view full) ---

341node_statement: ON node_start OB node_entries CB
342 {
343 mynode = false;
344 }
345 ;
346
347node_start: STR
348 {
319 if (isitme($1))
349 switch (isitme($1)) {
350 case -1:
351 return (1);
352 case 0:
353 break;
354 case 1:
320 mynode = true;
355 mynode = true;
356 break;
357 default:
358 assert(!"invalid isitme() return value");
359 }
321 }
322 ;
323
324node_entries:
325 |
326 node_entries node_entry
327 ;
328

--- 38 unchanged lines hidden (view full) ---

367 strlcpy(curres->hr_provname, curres->hr_name,
368 sizeof(curres->hr_provname));
369 }
370
371 /*
372 * Remote address has to be configured at this point.
373 */
374 if (curres->hr_remoteaddr[0] == '\0') {
360 }
361 ;
362
363node_entries:
364 |
365 node_entries node_entry
366 ;
367

--- 38 unchanged lines hidden (view full) ---

406 strlcpy(curres->hr_provname, curres->hr_name,
407 sizeof(curres->hr_provname));
408 }
409
410 /*
411 * Remote address has to be configured at this point.
412 */
413 if (curres->hr_remoteaddr[0] == '\0') {
375 errx(EX_CONFIG,
376 "remote address not configured for resource %s",
414 pjdlog_error("Remote address not configured for resource %s.",
377 curres->hr_name);
415 curres->hr_name);
416 return (1);
378 }
379 /*
380 * Path to local provider has to be configured at this
381 * point.
382 */
383 if (curres->hr_localpath[0] == '\0') {
417 }
418 /*
419 * Path to local provider has to be configured at this
420 * point.
421 */
422 if (curres->hr_localpath[0] == '\0') {
384 errx(EX_CONFIG,
385 "path local component not configured for resource %s",
423 pjdlog_error("Path to local component not configured for resource %s.",
386 curres->hr_name);
424 curres->hr_name);
425 return (1);
387 }
388
389 /* Put it onto resource list. */
426 }
427
428 /* Put it onto resource list. */
390 TAILQ_INSERT_TAIL(&lconfig.hc_resources, curres, hr_next);
429 TAILQ_INSERT_TAIL(&lconfig->hc_resources, curres, hr_next);
391 curres = NULL;
392 }
393 }
394 ;
395
396resource_start: STR
397 {
398 /*
399 * Clear those, so we can tell if they were set at
400 * resource-level or not.
401 */
402 depth1_provname[0] = '\0';
403 depth1_localpath[0] = '\0';
404
405 curres = calloc(1, sizeof(*curres));
406 if (curres == NULL) {
430 curres = NULL;
431 }
432 }
433 ;
434
435resource_start: STR
436 {
437 /*
438 * Clear those, so we can tell if they were set at
439 * resource-level or not.
440 */
441 depth1_provname[0] = '\0';
442 depth1_localpath[0] = '\0';
443
444 curres = calloc(1, sizeof(*curres));
445 if (curres == NULL) {
407 errx(EX_TEMPFAIL,
408 "cannot allocate memory for resource");
446 pjdlog_error("Unable to allocate memory for resource.");
447 return (1);
409 }
410 if (strlcpy(curres->hr_name, $1,
411 sizeof(curres->hr_name)) >=
412 sizeof(curres->hr_name)) {
448 }
449 if (strlcpy(curres->hr_name, $1,
450 sizeof(curres->hr_name)) >=
451 sizeof(curres->hr_name)) {
413 errx(EX_CONFIG,
414 "resource name (%s) too long", $1);
452 pjdlog_error("Resource name is too long.");
453 return (1);
415 }
416 curres->hr_role = HAST_ROLE_INIT;
417 curres->hr_previous_role = HAST_ROLE_INIT;
418 curres->hr_replication = -1;
419 curres->hr_timeout = -1;
420 curres->hr_provname[0] = '\0';
421 curres->hr_localpath[0] = '\0';
422 curres->hr_localfd = -1;

--- 21 unchanged lines hidden (view full) ---

444
445name_statement: NAME STR
446 {
447 switch (depth) {
448 case 1:
449 if (strlcpy(depth1_provname, $2,
450 sizeof(depth1_provname)) >=
451 sizeof(depth1_provname)) {
454 }
455 curres->hr_role = HAST_ROLE_INIT;
456 curres->hr_previous_role = HAST_ROLE_INIT;
457 curres->hr_replication = -1;
458 curres->hr_timeout = -1;
459 curres->hr_provname[0] = '\0';
460 curres->hr_localpath[0] = '\0';
461 curres->hr_localfd = -1;

--- 21 unchanged lines hidden (view full) ---

483
484name_statement: NAME STR
485 {
486 switch (depth) {
487 case 1:
488 if (strlcpy(depth1_provname, $2,
489 sizeof(depth1_provname)) >=
490 sizeof(depth1_provname)) {
452 errx(EX_CONFIG, "name argument too long");
491 pjdlog_error("name argument is too long.");
492 return (1);
453 }
454 break;
455 case 2:
456 if (mynode) {
457 assert(curres != NULL);
458 if (strlcpy(curres->hr_provname, $2,
459 sizeof(curres->hr_provname)) >=
460 sizeof(curres->hr_provname)) {
493 }
494 break;
495 case 2:
496 if (mynode) {
497 assert(curres != NULL);
498 if (strlcpy(curres->hr_provname, $2,
499 sizeof(curres->hr_provname)) >=
500 sizeof(curres->hr_provname)) {
461 errx(EX_CONFIG,
462 "name argument too long");
501 pjdlog_error("name argument is too long.");
502 return (1);
463 }
464 }
465 break;
466 default:
467 assert(!"name at wrong depth level");
468 }
469 }
470 ;
471
472local_statement: LOCAL STR
473 {
474 switch (depth) {
475 case 1:
476 if (strlcpy(depth1_localpath, $2,
477 sizeof(depth1_localpath)) >=
478 sizeof(depth1_localpath)) {
503 }
504 }
505 break;
506 default:
507 assert(!"name at wrong depth level");
508 }
509 }
510 ;
511
512local_statement: LOCAL STR
513 {
514 switch (depth) {
515 case 1:
516 if (strlcpy(depth1_localpath, $2,
517 sizeof(depth1_localpath)) >=
518 sizeof(depth1_localpath)) {
479 errx(EX_CONFIG, "local argument too long");
519 pjdlog_error("local argument is too long.");
520 return (1);
480 }
481 break;
482 case 2:
483 if (mynode) {
484 assert(curres != NULL);
485 if (strlcpy(curres->hr_localpath, $2,
486 sizeof(curres->hr_localpath)) >=
487 sizeof(curres->hr_localpath)) {
521 }
522 break;
523 case 2:
524 if (mynode) {
525 assert(curres != NULL);
526 if (strlcpy(curres->hr_localpath, $2,
527 sizeof(curres->hr_localpath)) >=
528 sizeof(curres->hr_localpath)) {
488 errx(EX_CONFIG,
489 "local argument too long");
529 pjdlog_error("local argument is too long.");
530 return (1);
490 }
491 }
492 break;
493 default:
494 assert(!"local at wrong depth level");
495 }
496 }
497 ;
498
499resource_node_statement:ON resource_node_start OB resource_node_entries CB
500 {
501 mynode = false;
502 }
503 ;
504
505resource_node_start: STR
506 {
531 }
532 }
533 break;
534 default:
535 assert(!"local at wrong depth level");
536 }
537 }
538 ;
539
540resource_node_statement:ON resource_node_start OB resource_node_entries CB
541 {
542 mynode = false;
543 }
544 ;
545
546resource_node_start: STR
547 {
507 if (curres != NULL && isitme($1))
508 mynode = true;
548 if (curres != NULL) {
549 switch (isitme($1)) {
550 case -1:
551 return (1);
552 case 0:
553 break;
554 case 1:
555 mynode = true;
556 break;
557 default:
558 assert(!"invalid isitme() return value");
559 }
560 }
509 }
510 ;
511
512resource_node_entries:
513 |
514 resource_node_entries resource_node_entry
515 ;
516

--- 8 unchanged lines hidden (view full) ---

525remote_statement: REMOTE STR
526 {
527 assert(depth == 2);
528 if (mynode) {
529 assert(curres != NULL);
530 if (strlcpy(curres->hr_remoteaddr, $2,
531 sizeof(curres->hr_remoteaddr)) >=
532 sizeof(curres->hr_remoteaddr)) {
561 }
562 ;
563
564resource_node_entries:
565 |
566 resource_node_entries resource_node_entry
567 ;
568

--- 8 unchanged lines hidden (view full) ---

577remote_statement: REMOTE STR
578 {
579 assert(depth == 2);
580 if (mynode) {
581 assert(curres != NULL);
582 if (strlcpy(curres->hr_remoteaddr, $2,
583 sizeof(curres->hr_remoteaddr)) >=
584 sizeof(curres->hr_remoteaddr)) {
533 errx(EX_CONFIG, "remote argument too long");
585 pjdlog_error("remote argument is too long.");
586 return (1);
534 }
535 }
536 }
537 ;
587 }
588 }
589 }
590 ;