parse.y revision 216722
1204076Spjd%{ 2204076Spjd/*- 3204076Spjd * Copyright (c) 2009-2010 The FreeBSD Foundation 4204076Spjd * All rights reserved. 5204076Spjd * 6204076Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from 7204076Spjd * the FreeBSD Foundation. 8204076Spjd * 9204076Spjd * Redistribution and use in source and binary forms, with or without 10204076Spjd * modification, are permitted provided that the following conditions 11204076Spjd * are met: 12204076Spjd * 1. Redistributions of source code must retain the above copyright 13204076Spjd * notice, this list of conditions and the following disclaimer. 14204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 15204076Spjd * notice, this list of conditions and the following disclaimer in the 16204076Spjd * documentation and/or other materials provided with the distribution. 17204076Spjd * 18204076Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 22204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28204076Spjd * SUCH DAMAGE. 29204076Spjd * 30204076Spjd * $FreeBSD: head/sbin/hastd/parse.y 216722 2010-12-26 19:08:41Z pjd $ 31204076Spjd */ 32204076Spjd 33204076Spjd#include <sys/param.h> /* MAXHOSTNAMELEN */ 34204076Spjd#include <sys/queue.h> 35204076Spjd#include <sys/sysctl.h> 36204076Spjd 37204076Spjd#include <arpa/inet.h> 38204076Spjd 39204076Spjd#include <assert.h> 40204076Spjd#include <err.h> 41204076Spjd#include <stdio.h> 42204076Spjd#include <string.h> 43204076Spjd#include <sysexits.h> 44204076Spjd#include <unistd.h> 45204076Spjd 46210883Spjd#include <pjdlog.h> 47210883Spjd 48204076Spjd#include "hast.h" 49204076Spjd 50204076Spjdextern int depth; 51204076Spjdextern int lineno; 52204076Spjd 53204076Spjdextern FILE *yyin; 54204076Spjdextern char *yytext; 55204076Spjd 56210883Spjdstatic struct hastd_config *lconfig; 57204076Spjdstatic struct hast_resource *curres; 58216721Spjdstatic bool mynode, hadmynode; 59204076Spjd 60204076Spjdstatic char depth0_control[HAST_ADDRSIZE]; 61204076Spjdstatic char depth0_listen[HAST_ADDRSIZE]; 62204076Spjdstatic int depth0_replication; 63207371Spjdstatic int depth0_timeout; 64211886Spjdstatic char depth0_exec[PATH_MAX]; 65204076Spjd 66204076Spjdstatic char depth1_provname[PATH_MAX]; 67204076Spjdstatic char depth1_localpath[PATH_MAX]; 68204076Spjd 69210883Spjdextern void yyrestart(FILE *); 70210883Spjd 71210883Spjdstatic int 72204076Spjdisitme(const char *name) 73204076Spjd{ 74204076Spjd char buf[MAXHOSTNAMELEN]; 75204076Spjd char *pos; 76204076Spjd size_t bufsize; 77204076Spjd 78204076Spjd /* 79204076Spjd * First check if the give name matches our full hostname. 80204076Spjd */ 81210883Spjd if (gethostname(buf, sizeof(buf)) < 0) { 82210883Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 83210883Spjd return (-1); 84210883Spjd } 85204076Spjd if (strcmp(buf, name) == 0) 86210883Spjd return (1); 87204076Spjd 88204076Spjd /* 89204076Spjd * Now check if it matches first part of the host name. 90204076Spjd */ 91204076Spjd pos = strchr(buf, '.'); 92204076Spjd if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) 93210883Spjd return (1); 94204076Spjd 95204076Spjd /* 96204076Spjd * At the end check if name is equal to our host's UUID. 97204076Spjd */ 98204076Spjd bufsize = sizeof(buf); 99210883Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 100210883Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 101210883Spjd return (-1); 102210883Spjd } 103204076Spjd if (strcasecmp(buf, name) == 0) 104210883Spjd return (1); 105204076Spjd 106204076Spjd /* 107204076Spjd * Looks like this isn't about us. 108204076Spjd */ 109210883Spjd return (0); 110204076Spjd} 111204076Spjd 112216721Spjdstatic int 113216721Spjdnode_names(char **namesp) 114216721Spjd{ 115216721Spjd static char names[MAXHOSTNAMELEN * 3]; 116216721Spjd char buf[MAXHOSTNAMELEN]; 117216721Spjd char *pos; 118216721Spjd size_t bufsize; 119216721Spjd 120216721Spjd if (gethostname(buf, sizeof(buf)) < 0) { 121216721Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 122216721Spjd return (-1); 123216721Spjd } 124216721Spjd 125216721Spjd /* First component of the host name. */ 126216721Spjd pos = strchr(buf, '.'); 127216721Spjd if (pos != NULL && pos != buf) { 128216721Spjd (void)strlcpy(names, buf, MIN((size_t)(pos - buf + 1), 129216721Spjd sizeof(names))); 130216721Spjd (void)strlcat(names, ", ", sizeof(names)); 131216721Spjd } 132216721Spjd 133216721Spjd /* Full host name. */ 134216721Spjd (void)strlcat(names, buf, sizeof(names)); 135216721Spjd (void)strlcat(names, ", ", sizeof(names)); 136216721Spjd 137216721Spjd /* Host UUID. */ 138216721Spjd bufsize = sizeof(buf); 139216721Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 140216721Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 141216721Spjd return (-1); 142216721Spjd } 143216721Spjd (void)strlcat(names, buf, sizeof(names)); 144216721Spjd 145216721Spjd *namesp = names; 146216721Spjd 147216721Spjd return (0); 148216721Spjd} 149216721Spjd 150204076Spjdvoid 151204076Spjdyyerror(const char *str) 152204076Spjd{ 153204076Spjd 154210883Spjd pjdlog_error("Unable to parse configuration file at line %d near '%s': %s", 155204076Spjd lineno, yytext, str); 156204076Spjd} 157204076Spjd 158204076Spjdstruct hastd_config * 159210883Spjdyy_config_parse(const char *config, bool exitonerror) 160204076Spjd{ 161204076Spjd int ret; 162204076Spjd 163204076Spjd curres = NULL; 164204076Spjd mynode = false; 165210883Spjd depth = 0; 166210883Spjd lineno = 0; 167204076Spjd 168207371Spjd depth0_timeout = HAST_TIMEOUT; 169204076Spjd depth0_replication = HAST_REPLICATION_MEMSYNC; 170204076Spjd strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); 171204076Spjd strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); 172211886Spjd depth0_exec[0] = '\0'; 173204076Spjd 174210883Spjd lconfig = calloc(1, sizeof(*lconfig)); 175210883Spjd if (lconfig == NULL) { 176210883Spjd pjdlog_error("Unable to allocate memory for configuration."); 177210883Spjd if (exitonerror) 178210883Spjd exit(EX_TEMPFAIL); 179210883Spjd return (NULL); 180210883Spjd } 181204076Spjd 182210883Spjd TAILQ_INIT(&lconfig->hc_resources); 183210883Spjd 184204076Spjd yyin = fopen(config, "r"); 185210883Spjd if (yyin == NULL) { 186210883Spjd pjdlog_errno(LOG_ERR, "Unable to open configuration file %s", 187210883Spjd config); 188210883Spjd yy_config_free(lconfig); 189210883Spjd if (exitonerror) 190210883Spjd exit(EX_OSFILE); 191210883Spjd return (NULL); 192210883Spjd } 193210883Spjd yyrestart(yyin); 194204076Spjd ret = yyparse(); 195204076Spjd fclose(yyin); 196204076Spjd if (ret != 0) { 197210883Spjd yy_config_free(lconfig); 198210883Spjd if (exitonerror) 199210883Spjd exit(EX_CONFIG); 200210883Spjd return (NULL); 201204076Spjd } 202204076Spjd 203204076Spjd /* 204204076Spjd * Let's see if everything is set up. 205204076Spjd */ 206210883Spjd if (lconfig->hc_controladdr[0] == '\0') { 207210883Spjd strlcpy(lconfig->hc_controladdr, depth0_control, 208210883Spjd sizeof(lconfig->hc_controladdr)); 209204076Spjd } 210210883Spjd if (lconfig->hc_listenaddr[0] == '\0') { 211210883Spjd strlcpy(lconfig->hc_listenaddr, depth0_listen, 212210883Spjd sizeof(lconfig->hc_listenaddr)); 213204076Spjd } 214210883Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 215204076Spjd assert(curres->hr_provname[0] != '\0'); 216204076Spjd assert(curres->hr_localpath[0] != '\0'); 217204076Spjd assert(curres->hr_remoteaddr[0] != '\0'); 218204076Spjd 219204076Spjd if (curres->hr_replication == -1) { 220204076Spjd /* 221204076Spjd * Replication is not set at resource-level. 222204076Spjd * Use global or default setting. 223204076Spjd */ 224204076Spjd curres->hr_replication = depth0_replication; 225204076Spjd } 226207371Spjd if (curres->hr_timeout == -1) { 227207371Spjd /* 228207371Spjd * Timeout is not set at resource-level. 229207371Spjd * Use global or default setting. 230207371Spjd */ 231207371Spjd curres->hr_timeout = depth0_timeout; 232207371Spjd } 233211886Spjd if (curres->hr_exec[0] == '\0') { 234211886Spjd /* 235211886Spjd * Exec is not set at resource-level. 236211886Spjd * Use global or default setting. 237211886Spjd */ 238211886Spjd strlcpy(curres->hr_exec, depth0_exec, 239211886Spjd sizeof(curres->hr_exec)); 240211886Spjd } 241204076Spjd } 242204076Spjd 243210883Spjd return (lconfig); 244204076Spjd} 245204076Spjd 246204076Spjdvoid 247204076Spjdyy_config_free(struct hastd_config *config) 248204076Spjd{ 249204076Spjd struct hast_resource *res; 250204076Spjd 251204076Spjd while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) { 252204076Spjd TAILQ_REMOVE(&config->hc_resources, res, hr_next); 253204076Spjd free(res); 254204076Spjd } 255210883Spjd free(config); 256204076Spjd} 257204076Spjd%} 258204076Spjd 259211886Spjd%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON 260204076Spjd%token FULLSYNC MEMSYNC ASYNC 261204076Spjd%token NUM STR OB CB 262204076Spjd 263204076Spjd%type <num> replication_type 264204076Spjd 265204076Spjd%union 266204076Spjd{ 267204076Spjd int num; 268204076Spjd char *str; 269204076Spjd} 270204076Spjd 271204076Spjd%token <num> NUM 272204076Spjd%token <str> STR 273204076Spjd 274204076Spjd%% 275204076Spjd 276204076Spjdstatements: 277204076Spjd | 278204076Spjd statements statement 279204076Spjd ; 280204076Spjd 281204076Spjdstatement: 282204076Spjd control_statement 283204076Spjd | 284204076Spjd listen_statement 285204076Spjd | 286204076Spjd replication_statement 287204076Spjd | 288207371Spjd timeout_statement 289207371Spjd | 290211886Spjd exec_statement 291211886Spjd | 292204076Spjd node_statement 293204076Spjd | 294204076Spjd resource_statement 295204076Spjd ; 296204076Spjd 297204076Spjdcontrol_statement: CONTROL STR 298204076Spjd { 299204076Spjd switch (depth) { 300204076Spjd case 0: 301204076Spjd if (strlcpy(depth0_control, $2, 302204076Spjd sizeof(depth0_control)) >= 303204076Spjd sizeof(depth0_control)) { 304210883Spjd pjdlog_error("control argument is too long."); 305214274Spjd free($2); 306210883Spjd return (1); 307204076Spjd } 308204076Spjd break; 309204076Spjd case 1: 310211883Spjd if (!mynode) 311211883Spjd break; 312211883Spjd if (strlcpy(lconfig->hc_controladdr, $2, 313211883Spjd sizeof(lconfig->hc_controladdr)) >= 314211883Spjd sizeof(lconfig->hc_controladdr)) { 315211883Spjd pjdlog_error("control argument is too long."); 316214274Spjd free($2); 317211883Spjd return (1); 318204076Spjd } 319204076Spjd break; 320204076Spjd default: 321204076Spjd assert(!"control at wrong depth level"); 322204076Spjd } 323214274Spjd free($2); 324204076Spjd } 325204076Spjd ; 326204076Spjd 327204076Spjdlisten_statement: LISTEN STR 328204076Spjd { 329204076Spjd switch (depth) { 330204076Spjd case 0: 331204076Spjd if (strlcpy(depth0_listen, $2, 332204076Spjd sizeof(depth0_listen)) >= 333204076Spjd sizeof(depth0_listen)) { 334210883Spjd pjdlog_error("listen argument is too long."); 335214274Spjd free($2); 336210883Spjd return (1); 337204076Spjd } 338204076Spjd break; 339204076Spjd case 1: 340211883Spjd if (!mynode) 341211883Spjd break; 342211883Spjd if (strlcpy(lconfig->hc_listenaddr, $2, 343211883Spjd sizeof(lconfig->hc_listenaddr)) >= 344211883Spjd sizeof(lconfig->hc_listenaddr)) { 345211883Spjd pjdlog_error("listen argument is too long."); 346214274Spjd free($2); 347211883Spjd return (1); 348204076Spjd } 349204076Spjd break; 350204076Spjd default: 351204076Spjd assert(!"listen at wrong depth level"); 352204076Spjd } 353214274Spjd free($2); 354204076Spjd } 355204076Spjd ; 356204076Spjd 357204076Spjdreplication_statement: REPLICATION replication_type 358204076Spjd { 359204076Spjd switch (depth) { 360204076Spjd case 0: 361204076Spjd depth0_replication = $2; 362204076Spjd break; 363204076Spjd case 1: 364204076Spjd if (curres != NULL) 365204076Spjd curres->hr_replication = $2; 366204076Spjd break; 367204076Spjd default: 368204076Spjd assert(!"replication at wrong depth level"); 369204076Spjd } 370204076Spjd } 371204076Spjd ; 372204076Spjd 373204076Spjdreplication_type: 374204076Spjd FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } 375204076Spjd | 376204076Spjd MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } 377204076Spjd | 378204076Spjd ASYNC { $$ = HAST_REPLICATION_ASYNC; } 379204076Spjd ; 380204076Spjd 381207371Spjdtimeout_statement: TIMEOUT NUM 382207371Spjd { 383207371Spjd switch (depth) { 384207371Spjd case 0: 385207371Spjd depth0_timeout = $2; 386207371Spjd break; 387207371Spjd case 1: 388207371Spjd if (curres != NULL) 389207371Spjd curres->hr_timeout = $2; 390207371Spjd break; 391207371Spjd default: 392207371Spjd assert(!"timeout at wrong depth level"); 393207371Spjd } 394207371Spjd } 395207371Spjd ; 396207371Spjd 397211886Spjdexec_statement: EXEC STR 398211886Spjd { 399211886Spjd switch (depth) { 400211886Spjd case 0: 401211886Spjd if (strlcpy(depth0_exec, $2, sizeof(depth0_exec)) >= 402211886Spjd sizeof(depth0_exec)) { 403211886Spjd pjdlog_error("Exec path is too long."); 404214274Spjd free($2); 405211886Spjd return (1); 406211886Spjd } 407211886Spjd break; 408211886Spjd case 1: 409211886Spjd if (curres == NULL) 410211886Spjd break; 411211886Spjd if (strlcpy(curres->hr_exec, $2, 412211886Spjd sizeof(curres->hr_exec)) >= 413211886Spjd sizeof(curres->hr_exec)) { 414211886Spjd pjdlog_error("Exec path is too long."); 415214274Spjd free($2); 416211886Spjd return (1); 417211886Spjd } 418211886Spjd break; 419211886Spjd default: 420211886Spjd assert(!"exec at wrong depth level"); 421211886Spjd } 422214274Spjd free($2); 423211886Spjd } 424211886Spjd ; 425211886Spjd 426204076Spjdnode_statement: ON node_start OB node_entries CB 427204076Spjd { 428204076Spjd mynode = false; 429204076Spjd } 430204076Spjd ; 431204076Spjd 432204076Spjdnode_start: STR 433204076Spjd { 434210883Spjd switch (isitme($1)) { 435210883Spjd case -1: 436214274Spjd free($1); 437210883Spjd return (1); 438210883Spjd case 0: 439210883Spjd break; 440210883Spjd case 1: 441204076Spjd mynode = true; 442210883Spjd break; 443210883Spjd default: 444210883Spjd assert(!"invalid isitme() return value"); 445210883Spjd } 446214274Spjd free($1); 447204076Spjd } 448204076Spjd ; 449204076Spjd 450204076Spjdnode_entries: 451204076Spjd | 452204076Spjd node_entries node_entry 453204076Spjd ; 454204076Spjd 455204076Spjdnode_entry: 456204076Spjd control_statement 457204076Spjd | 458204076Spjd listen_statement 459204076Spjd ; 460204076Spjd 461204076Spjdresource_statement: RESOURCE resource_start OB resource_entries CB 462204076Spjd { 463204076Spjd if (curres != NULL) { 464204076Spjd /* 465216721Spjd * There must be section for this node, at least with 466216721Spjd * remote address configuration. 467216721Spjd */ 468216721Spjd if (!hadmynode) { 469216721Spjd char *names; 470216721Spjd 471216721Spjd if (node_names(&names) != 0) 472216721Spjd return (1); 473216721Spjd pjdlog_error("No resource %s configuration for this node (acceptable node names: %s).", 474216721Spjd curres->hr_name, names); 475216721Spjd return (1); 476216721Spjd } 477216721Spjd 478216721Spjd /* 479204076Spjd * Let's see there are some resource-level settings 480204076Spjd * that we can use for node-level settings. 481204076Spjd */ 482204076Spjd if (curres->hr_provname[0] == '\0' && 483204076Spjd depth1_provname[0] != '\0') { 484204076Spjd /* 485204076Spjd * Provider name is not set at node-level, 486204076Spjd * but is set at resource-level, use it. 487204076Spjd */ 488204076Spjd strlcpy(curres->hr_provname, depth1_provname, 489204076Spjd sizeof(curres->hr_provname)); 490204076Spjd } 491204076Spjd if (curres->hr_localpath[0] == '\0' && 492204076Spjd depth1_localpath[0] != '\0') { 493204076Spjd /* 494204076Spjd * Path to local provider is not set at 495204076Spjd * node-level, but is set at resource-level, 496204076Spjd * use it. 497204076Spjd */ 498204076Spjd strlcpy(curres->hr_localpath, depth1_localpath, 499204076Spjd sizeof(curres->hr_localpath)); 500204076Spjd } 501204076Spjd 502204076Spjd /* 503204076Spjd * If provider name is not given, use resource name 504204076Spjd * as provider name. 505204076Spjd */ 506204076Spjd if (curres->hr_provname[0] == '\0') { 507204076Spjd strlcpy(curres->hr_provname, curres->hr_name, 508204076Spjd sizeof(curres->hr_provname)); 509204076Spjd } 510204076Spjd 511204076Spjd /* 512204076Spjd * Remote address has to be configured at this point. 513204076Spjd */ 514204076Spjd if (curres->hr_remoteaddr[0] == '\0') { 515210883Spjd pjdlog_error("Remote address not configured for resource %s.", 516204076Spjd curres->hr_name); 517210883Spjd return (1); 518204076Spjd } 519204076Spjd /* 520204076Spjd * Path to local provider has to be configured at this 521204076Spjd * point. 522204076Spjd */ 523204076Spjd if (curres->hr_localpath[0] == '\0') { 524210883Spjd pjdlog_error("Path to local component not configured for resource %s.", 525204076Spjd curres->hr_name); 526210883Spjd return (1); 527204076Spjd } 528204076Spjd 529204076Spjd /* Put it onto resource list. */ 530210883Spjd TAILQ_INSERT_TAIL(&lconfig->hc_resources, curres, hr_next); 531204076Spjd curres = NULL; 532204076Spjd } 533204076Spjd } 534204076Spjd ; 535204076Spjd 536204076Spjdresource_start: STR 537204076Spjd { 538216722Spjd /* Check if there is no duplicate entry. */ 539216722Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 540216722Spjd if (strcmp(curres->hr_name, $1) == 0) { 541216722Spjd pjdlog_error("Resource %s configured more than once.", 542216722Spjd curres->hr_name); 543216722Spjd free($1); 544216722Spjd return (1); 545216722Spjd } 546216722Spjd } 547216722Spjd 548204076Spjd /* 549204076Spjd * Clear those, so we can tell if they were set at 550204076Spjd * resource-level or not. 551204076Spjd */ 552204076Spjd depth1_provname[0] = '\0'; 553204076Spjd depth1_localpath[0] = '\0'; 554216721Spjd hadmynode = false; 555204076Spjd 556204076Spjd curres = calloc(1, sizeof(*curres)); 557204076Spjd if (curres == NULL) { 558210883Spjd pjdlog_error("Unable to allocate memory for resource."); 559214274Spjd free($1); 560210883Spjd return (1); 561204076Spjd } 562204076Spjd if (strlcpy(curres->hr_name, $1, 563204076Spjd sizeof(curres->hr_name)) >= 564204076Spjd sizeof(curres->hr_name)) { 565210883Spjd pjdlog_error("Resource name is too long."); 566214274Spjd free($1); 567210883Spjd return (1); 568204076Spjd } 569214274Spjd free($1); 570204076Spjd curres->hr_role = HAST_ROLE_INIT; 571204076Spjd curres->hr_previous_role = HAST_ROLE_INIT; 572204076Spjd curres->hr_replication = -1; 573207371Spjd curres->hr_timeout = -1; 574211886Spjd curres->hr_exec[0] = '\0'; 575204076Spjd curres->hr_provname[0] = '\0'; 576204076Spjd curres->hr_localpath[0] = '\0'; 577204076Spjd curres->hr_localfd = -1; 578204076Spjd curres->hr_remoteaddr[0] = '\0'; 579204076Spjd curres->hr_ggateunit = -1; 580204076Spjd } 581204076Spjd ; 582204076Spjd 583204076Spjdresource_entries: 584204076Spjd | 585204076Spjd resource_entries resource_entry 586204076Spjd ; 587204076Spjd 588204076Spjdresource_entry: 589204076Spjd replication_statement 590204076Spjd | 591207371Spjd timeout_statement 592207371Spjd | 593211886Spjd exec_statement 594211886Spjd | 595204076Spjd name_statement 596204076Spjd | 597204076Spjd local_statement 598204076Spjd | 599204076Spjd resource_node_statement 600204076Spjd ; 601204076Spjd 602204076Spjdname_statement: NAME STR 603204076Spjd { 604204076Spjd switch (depth) { 605204076Spjd case 1: 606204076Spjd if (strlcpy(depth1_provname, $2, 607204076Spjd sizeof(depth1_provname)) >= 608204076Spjd sizeof(depth1_provname)) { 609210883Spjd pjdlog_error("name argument is too long."); 610214274Spjd free($2); 611210883Spjd return (1); 612204076Spjd } 613204076Spjd break; 614204076Spjd case 2: 615211883Spjd if (!mynode) 616211883Spjd break; 617211883Spjd assert(curres != NULL); 618211883Spjd if (strlcpy(curres->hr_provname, $2, 619211883Spjd sizeof(curres->hr_provname)) >= 620211883Spjd sizeof(curres->hr_provname)) { 621211883Spjd pjdlog_error("name argument is too long."); 622214274Spjd free($2); 623211883Spjd return (1); 624204076Spjd } 625204076Spjd break; 626204076Spjd default: 627204076Spjd assert(!"name at wrong depth level"); 628204076Spjd } 629214274Spjd free($2); 630204076Spjd } 631204076Spjd ; 632204076Spjd 633204076Spjdlocal_statement: LOCAL STR 634204076Spjd { 635204076Spjd switch (depth) { 636204076Spjd case 1: 637204076Spjd if (strlcpy(depth1_localpath, $2, 638204076Spjd sizeof(depth1_localpath)) >= 639204076Spjd sizeof(depth1_localpath)) { 640210883Spjd pjdlog_error("local argument is too long."); 641214274Spjd free($2); 642210883Spjd return (1); 643204076Spjd } 644204076Spjd break; 645204076Spjd case 2: 646211883Spjd if (!mynode) 647211883Spjd break; 648211883Spjd assert(curres != NULL); 649211883Spjd if (strlcpy(curres->hr_localpath, $2, 650211883Spjd sizeof(curres->hr_localpath)) >= 651211883Spjd sizeof(curres->hr_localpath)) { 652211883Spjd pjdlog_error("local argument is too long."); 653214274Spjd free($2); 654211883Spjd return (1); 655204076Spjd } 656204076Spjd break; 657204076Spjd default: 658204076Spjd assert(!"local at wrong depth level"); 659204076Spjd } 660214274Spjd free($2); 661204076Spjd } 662204076Spjd ; 663204076Spjd 664204076Spjdresource_node_statement:ON resource_node_start OB resource_node_entries CB 665204076Spjd { 666204076Spjd mynode = false; 667204076Spjd } 668204076Spjd ; 669204076Spjd 670204076Spjdresource_node_start: STR 671204076Spjd { 672210883Spjd if (curres != NULL) { 673210883Spjd switch (isitme($1)) { 674210883Spjd case -1: 675214274Spjd free($1); 676210883Spjd return (1); 677210883Spjd case 0: 678210883Spjd break; 679210883Spjd case 1: 680216721Spjd mynode = hadmynode = true; 681210883Spjd break; 682210883Spjd default: 683210883Spjd assert(!"invalid isitme() return value"); 684210883Spjd } 685210883Spjd } 686214274Spjd free($1); 687204076Spjd } 688204076Spjd ; 689204076Spjd 690204076Spjdresource_node_entries: 691204076Spjd | 692204076Spjd resource_node_entries resource_node_entry 693204076Spjd ; 694204076Spjd 695204076Spjdresource_node_entry: 696204076Spjd name_statement 697204076Spjd | 698204076Spjd local_statement 699204076Spjd | 700204076Spjd remote_statement 701204076Spjd ; 702204076Spjd 703204076Spjdremote_statement: REMOTE STR 704204076Spjd { 705204076Spjd assert(depth == 2); 706204076Spjd if (mynode) { 707204076Spjd assert(curres != NULL); 708204076Spjd if (strlcpy(curres->hr_remoteaddr, $2, 709204076Spjd sizeof(curres->hr_remoteaddr)) >= 710204076Spjd sizeof(curres->hr_remoteaddr)) { 711210883Spjd pjdlog_error("remote argument is too long."); 712214274Spjd free($2); 713210883Spjd return (1); 714204076Spjd } 715204076Spjd } 716214274Spjd free($2); 717204076Spjd } 718204076Spjd ; 719