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 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 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 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 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 204076 2010-02-18 23:16:19Z pjd $
| 30 * $FreeBSD: head/sbin/hastd/parse.y 207371 2010-04-29 15:36:32Z 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 46#include "hast.h" 47 48extern int depth; 49extern int lineno; 50 51extern FILE *yyin; 52extern char *yytext; 53 54static 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;
| 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 "hast.h" 47 48extern int depth; 49extern int lineno; 50 51extern FILE *yyin; 52extern char *yytext; 53 54static 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;
|
61 62static char depth1_provname[PATH_MAX]; 63static char depth1_localpath[PATH_MAX]; 64 65static bool 66isitme(const char *name) 67{ 68 char buf[MAXHOSTNAMELEN]; 69 char *pos; 70 size_t bufsize; 71 72 /* 73 * First check if the give name matches our full hostname. 74 */ 75 if (gethostname(buf, sizeof(buf)) < 0) 76 err(EX_OSERR, "gethostname() failed"); 77 if (strcmp(buf, name) == 0) 78 return (true); 79 80 /* 81 * Now check if it matches first part of the host name. 82 */ 83 pos = strchr(buf, '.'); 84 if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) 85 return (true); 86 87 /* 88 * At the end check if name is equal to our host's UUID. 89 */ 90 bufsize = sizeof(buf); 91 if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) 92 err(EX_OSERR, "sysctlbyname(kern.hostuuid) failed"); 93 if (strcasecmp(buf, name) == 0) 94 return (true); 95 96 /* 97 * Looks like this isn't about us. 98 */ 99 return (false); 100} 101 102void 103yyerror(const char *str) 104{ 105 106 fprintf(stderr, "error at line %d near '%s': %s\n", 107 lineno, yytext, str); 108} 109 110struct hastd_config * 111yy_config_parse(const char *config) 112{ 113 int ret; 114 115 curres = NULL; 116 mynode = false; 117
| 62 63static char depth1_provname[PATH_MAX]; 64static char depth1_localpath[PATH_MAX]; 65 66static bool 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 */ 76 if (gethostname(buf, sizeof(buf)) < 0) 77 err(EX_OSERR, "gethostname() failed"); 78 if (strcmp(buf, name) == 0) 79 return (true); 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 return (true); 87 88 /* 89 * At the end check if name is equal to our host's UUID. 90 */ 91 bufsize = sizeof(buf); 92 if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) 93 err(EX_OSERR, "sysctlbyname(kern.hostuuid) failed"); 94 if (strcasecmp(buf, name) == 0) 95 return (true); 96 97 /* 98 * Looks like this isn't about us. 99 */ 100 return (false); 101} 102 103void 104yyerror(const char *str) 105{ 106 107 fprintf(stderr, "error at line %d near '%s': %s\n", 108 lineno, yytext, str); 109} 110 111struct hastd_config * 112yy_config_parse(const char *config) 113{ 114 int ret; 115 116 curres = NULL; 117 mynode = false; 118
|
| 119 depth0_timeout = HAST_TIMEOUT;
|
118 depth0_replication = HAST_REPLICATION_MEMSYNC; 119 strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); 120 strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); 121 122 TAILQ_INIT(&lconfig.hc_resources); 123 124 yyin = fopen(config, "r"); 125 if (yyin == NULL) 126 err(EX_OSFILE, "cannot open configuration file %s", config); 127 ret = yyparse(); 128 fclose(yyin); 129 if (ret != 0) { 130 yy_config_free(&lconfig); 131 exit(EX_CONFIG); 132 } 133 134 /* 135 * Let's see if everything is set up. 136 */ 137 if (lconfig.hc_controladdr[0] == '\0') { 138 strlcpy(lconfig.hc_controladdr, depth0_control, 139 sizeof(lconfig.hc_controladdr)); 140 } 141 if (lconfig.hc_listenaddr[0] == '\0') { 142 strlcpy(lconfig.hc_listenaddr, depth0_listen, 143 sizeof(lconfig.hc_listenaddr)); 144 } 145 TAILQ_FOREACH(curres, &lconfig.hc_resources, hr_next) { 146 assert(curres->hr_provname[0] != '\0'); 147 assert(curres->hr_localpath[0] != '\0'); 148 assert(curres->hr_remoteaddr[0] != '\0'); 149 150 if (curres->hr_replication == -1) { 151 /* 152 * Replication is not set at resource-level. 153 * Use global or default setting. 154 */ 155 curres->hr_replication = depth0_replication; 156 }
| 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 124 TAILQ_INIT(&lconfig.hc_resources); 125 126 yyin = fopen(config, "r"); 127 if (yyin == NULL) 128 err(EX_OSFILE, "cannot open configuration file %s", config); 129 ret = yyparse(); 130 fclose(yyin); 131 if (ret != 0) { 132 yy_config_free(&lconfig); 133 exit(EX_CONFIG); 134 } 135 136 /* 137 * Let's see if everything is set up. 138 */ 139 if (lconfig.hc_controladdr[0] == '\0') { 140 strlcpy(lconfig.hc_controladdr, depth0_control, 141 sizeof(lconfig.hc_controladdr)); 142 } 143 if (lconfig.hc_listenaddr[0] == '\0') { 144 strlcpy(lconfig.hc_listenaddr, depth0_listen, 145 sizeof(lconfig.hc_listenaddr)); 146 } 147 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. 156 */ 157 curres->hr_replication = depth0_replication; 158 }
|
| 159 if (curres->hr_timeout == -1) { 160 /* 161 * Timeout is not set at resource-level. 162 * Use global or default setting. 163 */ 164 curres->hr_timeout = depth0_timeout; 165 }
|
157 } 158 159 return (&lconfig); 160} 161 162void 163yy_config_free(struct hastd_config *config) 164{ 165 struct hast_resource *res; 166 167 while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) { 168 TAILQ_REMOVE(&config->hc_resources, res, hr_next); 169 free(res); 170 } 171} 172%} 173
| 166 } 167 168 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 } 180} 181%} 182
|
174%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
| 183%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
|
175%token FULLSYNC MEMSYNC ASYNC 176%token NUM STR OB CB 177 178%type <num> replication_type 179 180%union 181{ 182 int num; 183 char *str; 184} 185 186%token <num> NUM 187%token <str> STR 188 189%% 190 191statements: 192 | 193 statements statement 194 ; 195 196statement: 197 control_statement 198 | 199 listen_statement 200 | 201 replication_statement 202 |
| 184%token FULLSYNC MEMSYNC ASYNC 185%token NUM STR OB CB 186 187%type <num> replication_type 188 189%union 190{ 191 int num; 192 char *str; 193} 194 195%token <num> NUM 196%token <str> STR 197 198%% 199 200statements: 201 | 202 statements statement 203 ; 204 205statement: 206 control_statement 207 | 208 listen_statement 209 | 210 replication_statement 211 |
|
| 212 timeout_statement 213 |
|
203 node_statement 204 | 205 resource_statement 206 ; 207 208control_statement: CONTROL STR 209 { 210 switch (depth) { 211 case 0: 212 if (strlcpy(depth0_control, $2, 213 sizeof(depth0_control)) >= 214 sizeof(depth0_control)) { 215 errx(EX_CONFIG, "control argument too long"); 216 } 217 break; 218 case 1: 219 if (mynode) { 220 if (strlcpy(lconfig.hc_controladdr, $2, 221 sizeof(lconfig.hc_controladdr)) >= 222 sizeof(lconfig.hc_controladdr)) { 223 errx(EX_CONFIG, 224 "control argument too long"); 225 } 226 } 227 break; 228 default: 229 assert(!"control at wrong depth level"); 230 } 231 } 232 ; 233 234listen_statement: LISTEN STR 235 { 236 switch (depth) { 237 case 0: 238 if (strlcpy(depth0_listen, $2, 239 sizeof(depth0_listen)) >= 240 sizeof(depth0_listen)) { 241 errx(EX_CONFIG, "listen argument too long"); 242 } 243 break; 244 case 1: 245 if (mynode) { 246 if (strlcpy(lconfig.hc_listenaddr, $2, 247 sizeof(lconfig.hc_listenaddr)) >= 248 sizeof(lconfig.hc_listenaddr)) { 249 errx(EX_CONFIG, 250 "listen argument too long"); 251 } 252 } 253 break; 254 default: 255 assert(!"listen at wrong depth level"); 256 } 257 } 258 ; 259 260replication_statement: REPLICATION replication_type 261 { 262 switch (depth) { 263 case 0: 264 depth0_replication = $2; 265 break; 266 case 1: 267 if (curres != NULL) 268 curres->hr_replication = $2; 269 break; 270 default: 271 assert(!"replication at wrong depth level"); 272 } 273 } 274 ; 275 276replication_type: 277 FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } 278 | 279 MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } 280 | 281 ASYNC { $$ = HAST_REPLICATION_ASYNC; } 282 ; 283
| 214 node_statement 215 | 216 resource_statement 217 ; 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)) { 226 errx(EX_CONFIG, "control argument too long"); 227 } 228 break; 229 case 1: 230 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"); 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)) { 252 errx(EX_CONFIG, "listen argument too long"); 253 } 254 break; 255 case 1: 256 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"); 262 } 263 } 264 break; 265 default: 266 assert(!"listen at wrong depth level"); 267 } 268 } 269 ; 270 271replication_statement: REPLICATION replication_type 272 { 273 switch (depth) { 274 case 0: 275 depth0_replication = $2; 276 break; 277 case 1: 278 if (curres != NULL) 279 curres->hr_replication = $2; 280 break; 281 default: 282 assert(!"replication at wrong depth level"); 283 } 284 } 285 ; 286 287replication_type: 288 FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } 289 | 290 MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } 291 | 292 ASYNC { $$ = HAST_REPLICATION_ASYNC; } 293 ; 294
|
| 295timeout_statement: TIMEOUT NUM 296 { 297 switch (depth) { 298 case 0: 299 depth0_timeout = $2; 300 break; 301 case 1: 302 if (curres != NULL) 303 curres->hr_timeout = $2; 304 break; 305 default: 306 assert(!"timeout at wrong depth level"); 307 } 308 } 309 ; 310
|
284node_statement: ON node_start OB node_entries CB 285 { 286 mynode = false; 287 } 288 ; 289 290node_start: STR 291 { 292 if (isitme($1)) 293 mynode = true; 294 } 295 ; 296 297node_entries: 298 | 299 node_entries node_entry 300 ; 301 302node_entry: 303 control_statement 304 | 305 listen_statement 306 ; 307 308resource_statement: RESOURCE resource_start OB resource_entries CB 309 { 310 if (curres != NULL) { 311 /* 312 * Let's see there are some resource-level settings 313 * that we can use for node-level settings. 314 */ 315 if (curres->hr_provname[0] == '\0' && 316 depth1_provname[0] != '\0') { 317 /* 318 * Provider name is not set at node-level, 319 * but is set at resource-level, use it. 320 */ 321 strlcpy(curres->hr_provname, depth1_provname, 322 sizeof(curres->hr_provname)); 323 } 324 if (curres->hr_localpath[0] == '\0' && 325 depth1_localpath[0] != '\0') { 326 /* 327 * Path to local provider is not set at 328 * node-level, but is set at resource-level, 329 * use it. 330 */ 331 strlcpy(curres->hr_localpath, depth1_localpath, 332 sizeof(curres->hr_localpath)); 333 } 334 335 /* 336 * If provider name is not given, use resource name 337 * as provider name. 338 */ 339 if (curres->hr_provname[0] == '\0') { 340 strlcpy(curres->hr_provname, curres->hr_name, 341 sizeof(curres->hr_provname)); 342 } 343 344 /* 345 * Remote address has to be configured at this point. 346 */ 347 if (curres->hr_remoteaddr[0] == '\0') { 348 errx(EX_CONFIG, 349 "remote address not configured for resource %s", 350 curres->hr_name); 351 } 352 /* 353 * Path to local provider has to be configured at this 354 * point. 355 */ 356 if (curres->hr_localpath[0] == '\0') { 357 errx(EX_CONFIG, 358 "path local component not configured for resource %s", 359 curres->hr_name); 360 } 361 362 /* Put it onto resource list. */ 363 TAILQ_INSERT_TAIL(&lconfig.hc_resources, curres, hr_next); 364 curres = NULL; 365 } 366 } 367 ; 368 369resource_start: STR 370 { 371 /* 372 * Clear those, so we can tell if they were set at 373 * resource-level or not. 374 */ 375 depth1_provname[0] = '\0'; 376 depth1_localpath[0] = '\0'; 377 378 curres = calloc(1, sizeof(*curres)); 379 if (curres == NULL) { 380 errx(EX_TEMPFAIL, 381 "cannot allocate memory for resource"); 382 } 383 if (strlcpy(curres->hr_name, $1, 384 sizeof(curres->hr_name)) >= 385 sizeof(curres->hr_name)) { 386 errx(EX_CONFIG, 387 "resource name (%s) too long", $1); 388 } 389 curres->hr_role = HAST_ROLE_INIT; 390 curres->hr_previous_role = HAST_ROLE_INIT; 391 curres->hr_replication = -1;
| 311node_statement: ON node_start OB node_entries CB 312 { 313 mynode = false; 314 } 315 ; 316 317node_start: STR 318 { 319 if (isitme($1)) 320 mynode = true; 321 } 322 ; 323 324node_entries: 325 | 326 node_entries node_entry 327 ; 328 329node_entry: 330 control_statement 331 | 332 listen_statement 333 ; 334 335resource_statement: RESOURCE resource_start OB resource_entries CB 336 { 337 if (curres != NULL) { 338 /* 339 * Let's see there are some resource-level settings 340 * that we can use for node-level settings. 341 */ 342 if (curres->hr_provname[0] == '\0' && 343 depth1_provname[0] != '\0') { 344 /* 345 * Provider name is not set at node-level, 346 * but is set at resource-level, use it. 347 */ 348 strlcpy(curres->hr_provname, depth1_provname, 349 sizeof(curres->hr_provname)); 350 } 351 if (curres->hr_localpath[0] == '\0' && 352 depth1_localpath[0] != '\0') { 353 /* 354 * Path to local provider is not set at 355 * node-level, but is set at resource-level, 356 * use it. 357 */ 358 strlcpy(curres->hr_localpath, depth1_localpath, 359 sizeof(curres->hr_localpath)); 360 } 361 362 /* 363 * If provider name is not given, use resource name 364 * as provider name. 365 */ 366 if (curres->hr_provname[0] == '\0') { 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') { 375 errx(EX_CONFIG, 376 "remote address not configured for resource %s", 377 curres->hr_name); 378 } 379 /* 380 * Path to local provider has to be configured at this 381 * point. 382 */ 383 if (curres->hr_localpath[0] == '\0') { 384 errx(EX_CONFIG, 385 "path local component not configured for resource %s", 386 curres->hr_name); 387 } 388 389 /* Put it onto resource list. */ 390 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) { 407 errx(EX_TEMPFAIL, 408 "cannot allocate memory for resource"); 409 } 410 if (strlcpy(curres->hr_name, $1, 411 sizeof(curres->hr_name)) >= 412 sizeof(curres->hr_name)) { 413 errx(EX_CONFIG, 414 "resource name (%s) too long", $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;
|
392 curres->hr_provname[0] = '\0'; 393 curres->hr_localpath[0] = '\0'; 394 curres->hr_localfd = -1; 395 curres->hr_remoteaddr[0] = '\0'; 396 curres->hr_ggateunit = -1; 397 } 398 ; 399 400resource_entries: 401 | 402 resource_entries resource_entry 403 ; 404 405resource_entry: 406 replication_statement 407 |
| 420 curres->hr_provname[0] = '\0'; 421 curres->hr_localpath[0] = '\0'; 422 curres->hr_localfd = -1; 423 curres->hr_remoteaddr[0] = '\0'; 424 curres->hr_ggateunit = -1; 425 } 426 ; 427 428resource_entries: 429 | 430 resource_entries resource_entry 431 ; 432 433resource_entry: 434 replication_statement 435 |
|
| 436 timeout_statement 437 |
|
408 name_statement 409 | 410 local_statement 411 | 412 resource_node_statement 413 ; 414 415name_statement: NAME STR 416 { 417 switch (depth) { 418 case 1: 419 if (strlcpy(depth1_provname, $2, 420 sizeof(depth1_provname)) >= 421 sizeof(depth1_provname)) { 422 errx(EX_CONFIG, "name argument too long"); 423 } 424 break; 425 case 2: 426 if (mynode) { 427 assert(curres != NULL); 428 if (strlcpy(curres->hr_provname, $2, 429 sizeof(curres->hr_provname)) >= 430 sizeof(curres->hr_provname)) { 431 errx(EX_CONFIG, 432 "name argument too long"); 433 } 434 } 435 break; 436 default: 437 assert(!"name at wrong depth level"); 438 } 439 } 440 ; 441 442local_statement: LOCAL STR 443 { 444 switch (depth) { 445 case 1: 446 if (strlcpy(depth1_localpath, $2, 447 sizeof(depth1_localpath)) >= 448 sizeof(depth1_localpath)) { 449 errx(EX_CONFIG, "local argument too long"); 450 } 451 break; 452 case 2: 453 if (mynode) { 454 assert(curres != NULL); 455 if (strlcpy(curres->hr_localpath, $2, 456 sizeof(curres->hr_localpath)) >= 457 sizeof(curres->hr_localpath)) { 458 errx(EX_CONFIG, 459 "local argument too long"); 460 } 461 } 462 break; 463 default: 464 assert(!"local at wrong depth level"); 465 } 466 } 467 ; 468 469resource_node_statement:ON resource_node_start OB resource_node_entries CB 470 { 471 mynode = false; 472 } 473 ; 474 475resource_node_start: STR 476 { 477 if (curres != NULL && isitme($1)) 478 mynode = true; 479 } 480 ; 481 482resource_node_entries: 483 | 484 resource_node_entries resource_node_entry 485 ; 486 487resource_node_entry: 488 name_statement 489 | 490 local_statement 491 | 492 remote_statement 493 ; 494 495remote_statement: REMOTE STR 496 { 497 assert(depth == 2); 498 if (mynode) { 499 assert(curres != NULL); 500 if (strlcpy(curres->hr_remoteaddr, $2, 501 sizeof(curres->hr_remoteaddr)) >= 502 sizeof(curres->hr_remoteaddr)) { 503 errx(EX_CONFIG, "remote argument too long"); 504 } 505 } 506 } 507 ;
| 438 name_statement 439 | 440 local_statement 441 | 442 resource_node_statement 443 ; 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)) { 452 errx(EX_CONFIG, "name argument too long"); 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)) { 461 errx(EX_CONFIG, 462 "name argument too long"); 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)) { 479 errx(EX_CONFIG, "local argument too long"); 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)) { 488 errx(EX_CONFIG, 489 "local argument too long"); 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 { 507 if (curres != NULL && isitme($1)) 508 mynode = true; 509 } 510 ; 511 512resource_node_entries: 513 | 514 resource_node_entries resource_node_entry 515 ; 516 517resource_node_entry: 518 name_statement 519 | 520 local_statement 521 | 522 remote_statement 523 ; 524 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)) { 533 errx(EX_CONFIG, "remote argument too long"); 534 } 535 } 536 } 537 ;
|