parse.y revision 219351
1204076Spjd%{ 2204076Spjd/*- 3204076Spjd * Copyright (c) 2009-2010 The FreeBSD Foundation 4219351Spjd * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net> 5204076Spjd * All rights reserved. 6204076Spjd * 7204076Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from 8204076Spjd * the FreeBSD Foundation. 9204076Spjd * 10204076Spjd * Redistribution and use in source and binary forms, with or without 11204076Spjd * modification, are permitted provided that the following conditions 12204076Spjd * are met: 13204076Spjd * 1. Redistributions of source code must retain the above copyright 14204076Spjd * notice, this list of conditions and the following disclaimer. 15204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 16204076Spjd * notice, this list of conditions and the following disclaimer in the 17204076Spjd * documentation and/or other materials provided with the distribution. 18204076Spjd * 19204076Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 20204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 23204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29204076Spjd * SUCH DAMAGE. 30204076Spjd * 31204076Spjd * $FreeBSD: head/sbin/hastd/parse.y 219351 2011-03-06 22:56:14Z pjd $ 32204076Spjd */ 33204076Spjd 34204076Spjd#include <sys/param.h> /* MAXHOSTNAMELEN */ 35204076Spjd#include <sys/queue.h> 36204076Spjd#include <sys/sysctl.h> 37204076Spjd 38204076Spjd#include <arpa/inet.h> 39204076Spjd 40204076Spjd#include <assert.h> 41204076Spjd#include <err.h> 42204076Spjd#include <stdio.h> 43204076Spjd#include <string.h> 44204076Spjd#include <sysexits.h> 45204076Spjd#include <unistd.h> 46204076Spjd 47210883Spjd#include <pjdlog.h> 48210883Spjd 49204076Spjd#include "hast.h" 50204076Spjd 51204076Spjdextern int depth; 52204076Spjdextern int lineno; 53204076Spjd 54204076Spjdextern FILE *yyin; 55204076Spjdextern char *yytext; 56204076Spjd 57210883Spjdstatic struct hastd_config *lconfig; 58204076Spjdstatic struct hast_resource *curres; 59216721Spjdstatic bool mynode, hadmynode; 60204076Spjd 61204076Spjdstatic char depth0_control[HAST_ADDRSIZE]; 62204076Spjdstatic char depth0_listen[HAST_ADDRSIZE]; 63204076Spjdstatic int depth0_replication; 64219351Spjdstatic int depth0_checksum; 65207371Spjdstatic int depth0_timeout; 66211886Spjdstatic char depth0_exec[PATH_MAX]; 67204076Spjd 68204076Spjdstatic char depth1_provname[PATH_MAX]; 69204076Spjdstatic char depth1_localpath[PATH_MAX]; 70204076Spjd 71210883Spjdextern void yyrestart(FILE *); 72210883Spjd 73210883Spjdstatic int 74204076Spjdisitme(const char *name) 75204076Spjd{ 76204076Spjd char buf[MAXHOSTNAMELEN]; 77204076Spjd char *pos; 78204076Spjd size_t bufsize; 79204076Spjd 80204076Spjd /* 81204076Spjd * First check if the give name matches our full hostname. 82204076Spjd */ 83210883Spjd if (gethostname(buf, sizeof(buf)) < 0) { 84210883Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 85210883Spjd return (-1); 86210883Spjd } 87204076Spjd if (strcmp(buf, name) == 0) 88210883Spjd return (1); 89204076Spjd 90204076Spjd /* 91204076Spjd * Now check if it matches first part of the host name. 92204076Spjd */ 93204076Spjd pos = strchr(buf, '.'); 94204076Spjd if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) 95210883Spjd return (1); 96204076Spjd 97204076Spjd /* 98204076Spjd * At the end check if name is equal to our host's UUID. 99204076Spjd */ 100204076Spjd bufsize = sizeof(buf); 101210883Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 102210883Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 103210883Spjd return (-1); 104210883Spjd } 105204076Spjd if (strcasecmp(buf, name) == 0) 106210883Spjd return (1); 107204076Spjd 108204076Spjd /* 109204076Spjd * Looks like this isn't about us. 110204076Spjd */ 111210883Spjd return (0); 112204076Spjd} 113204076Spjd 114216721Spjdstatic int 115216721Spjdnode_names(char **namesp) 116216721Spjd{ 117216721Spjd static char names[MAXHOSTNAMELEN * 3]; 118216721Spjd char buf[MAXHOSTNAMELEN]; 119216721Spjd char *pos; 120216721Spjd size_t bufsize; 121216721Spjd 122216721Spjd if (gethostname(buf, sizeof(buf)) < 0) { 123216721Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 124216721Spjd return (-1); 125216721Spjd } 126216721Spjd 127216721Spjd /* First component of the host name. */ 128216721Spjd pos = strchr(buf, '.'); 129216721Spjd if (pos != NULL && pos != buf) { 130216721Spjd (void)strlcpy(names, buf, MIN((size_t)(pos - buf + 1), 131216721Spjd sizeof(names))); 132216721Spjd (void)strlcat(names, ", ", sizeof(names)); 133216721Spjd } 134216721Spjd 135216721Spjd /* Full host name. */ 136216721Spjd (void)strlcat(names, buf, sizeof(names)); 137216721Spjd (void)strlcat(names, ", ", sizeof(names)); 138216721Spjd 139216721Spjd /* Host UUID. */ 140216721Spjd bufsize = sizeof(buf); 141216721Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 142216721Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 143216721Spjd return (-1); 144216721Spjd } 145216721Spjd (void)strlcat(names, buf, sizeof(names)); 146216721Spjd 147216721Spjd *namesp = names; 148216721Spjd 149216721Spjd return (0); 150216721Spjd} 151216721Spjd 152204076Spjdvoid 153204076Spjdyyerror(const char *str) 154204076Spjd{ 155204076Spjd 156210883Spjd pjdlog_error("Unable to parse configuration file at line %d near '%s': %s", 157204076Spjd lineno, yytext, str); 158204076Spjd} 159204076Spjd 160204076Spjdstruct hastd_config * 161210883Spjdyy_config_parse(const char *config, bool exitonerror) 162204076Spjd{ 163204076Spjd int ret; 164204076Spjd 165204076Spjd curres = NULL; 166204076Spjd mynode = false; 167210883Spjd depth = 0; 168210883Spjd lineno = 0; 169204076Spjd 170207371Spjd depth0_timeout = HAST_TIMEOUT; 171204076Spjd depth0_replication = HAST_REPLICATION_MEMSYNC; 172219351Spjd depth0_checksum = HAST_CHECKSUM_NONE; 173204076Spjd strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); 174204076Spjd strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); 175211886Spjd depth0_exec[0] = '\0'; 176204076Spjd 177210883Spjd lconfig = calloc(1, sizeof(*lconfig)); 178210883Spjd if (lconfig == NULL) { 179210883Spjd pjdlog_error("Unable to allocate memory for configuration."); 180210883Spjd if (exitonerror) 181210883Spjd exit(EX_TEMPFAIL); 182210883Spjd return (NULL); 183210883Spjd } 184204076Spjd 185210883Spjd TAILQ_INIT(&lconfig->hc_resources); 186210883Spjd 187204076Spjd yyin = fopen(config, "r"); 188210883Spjd if (yyin == NULL) { 189210883Spjd pjdlog_errno(LOG_ERR, "Unable to open configuration file %s", 190210883Spjd config); 191210883Spjd yy_config_free(lconfig); 192210883Spjd if (exitonerror) 193210883Spjd exit(EX_OSFILE); 194210883Spjd return (NULL); 195210883Spjd } 196210883Spjd yyrestart(yyin); 197204076Spjd ret = yyparse(); 198204076Spjd fclose(yyin); 199204076Spjd if (ret != 0) { 200210883Spjd yy_config_free(lconfig); 201210883Spjd if (exitonerror) 202210883Spjd exit(EX_CONFIG); 203210883Spjd return (NULL); 204204076Spjd } 205204076Spjd 206204076Spjd /* 207204076Spjd * Let's see if everything is set up. 208204076Spjd */ 209210883Spjd if (lconfig->hc_controladdr[0] == '\0') { 210210883Spjd strlcpy(lconfig->hc_controladdr, depth0_control, 211210883Spjd sizeof(lconfig->hc_controladdr)); 212204076Spjd } 213210883Spjd if (lconfig->hc_listenaddr[0] == '\0') { 214210883Spjd strlcpy(lconfig->hc_listenaddr, depth0_listen, 215210883Spjd sizeof(lconfig->hc_listenaddr)); 216204076Spjd } 217210883Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 218204076Spjd assert(curres->hr_provname[0] != '\0'); 219204076Spjd assert(curres->hr_localpath[0] != '\0'); 220204076Spjd assert(curres->hr_remoteaddr[0] != '\0'); 221204076Spjd 222204076Spjd if (curres->hr_replication == -1) { 223204076Spjd /* 224204076Spjd * Replication is not set at resource-level. 225204076Spjd * Use global or default setting. 226204076Spjd */ 227204076Spjd curres->hr_replication = depth0_replication; 228204076Spjd } 229219351Spjd if (curres->hr_checksum == -1) { 230219351Spjd /* 231219351Spjd * Checksum is not set at resource-level. 232219351Spjd * Use global or default setting. 233219351Spjd */ 234219351Spjd curres->hr_checksum = depth0_checksum; 235219351Spjd } 236207371Spjd if (curres->hr_timeout == -1) { 237207371Spjd /* 238207371Spjd * Timeout is not set at resource-level. 239207371Spjd * Use global or default setting. 240207371Spjd */ 241207371Spjd curres->hr_timeout = depth0_timeout; 242207371Spjd } 243211886Spjd if (curres->hr_exec[0] == '\0') { 244211886Spjd /* 245211886Spjd * Exec is not set at resource-level. 246211886Spjd * Use global or default setting. 247211886Spjd */ 248211886Spjd strlcpy(curres->hr_exec, depth0_exec, 249211886Spjd sizeof(curres->hr_exec)); 250211886Spjd } 251204076Spjd } 252204076Spjd 253210883Spjd return (lconfig); 254204076Spjd} 255204076Spjd 256204076Spjdvoid 257204076Spjdyy_config_free(struct hastd_config *config) 258204076Spjd{ 259204076Spjd struct hast_resource *res; 260204076Spjd 261204076Spjd while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) { 262204076Spjd TAILQ_REMOVE(&config->hc_resources, res, hr_next); 263204076Spjd free(res); 264204076Spjd } 265210883Spjd free(config); 266204076Spjd} 267204076Spjd%} 268204076Spjd 269219351Spjd%token CONTROL LISTEN PORT REPLICATION CHECKSUM 270219351Spjd%token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON 271219351Spjd%token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 272204076Spjd%token NUM STR OB CB 273204076Spjd 274204076Spjd%type <num> replication_type 275219351Spjd%type <num> checksum_type 276204076Spjd 277204076Spjd%union 278204076Spjd{ 279204076Spjd int num; 280204076Spjd char *str; 281204076Spjd} 282204076Spjd 283204076Spjd%token <num> NUM 284204076Spjd%token <str> STR 285204076Spjd 286204076Spjd%% 287204076Spjd 288204076Spjdstatements: 289204076Spjd | 290204076Spjd statements statement 291204076Spjd ; 292204076Spjd 293204076Spjdstatement: 294204076Spjd control_statement 295204076Spjd | 296204076Spjd listen_statement 297204076Spjd | 298204076Spjd replication_statement 299204076Spjd | 300219351Spjd checksum_statement 301219351Spjd | 302207371Spjd timeout_statement 303207371Spjd | 304211886Spjd exec_statement 305211886Spjd | 306204076Spjd node_statement 307204076Spjd | 308204076Spjd resource_statement 309204076Spjd ; 310204076Spjd 311204076Spjdcontrol_statement: CONTROL STR 312204076Spjd { 313204076Spjd switch (depth) { 314204076Spjd case 0: 315204076Spjd if (strlcpy(depth0_control, $2, 316204076Spjd sizeof(depth0_control)) >= 317204076Spjd sizeof(depth0_control)) { 318210883Spjd pjdlog_error("control argument is too long."); 319214274Spjd free($2); 320210883Spjd return (1); 321204076Spjd } 322204076Spjd break; 323204076Spjd case 1: 324211883Spjd if (!mynode) 325211883Spjd break; 326211883Spjd if (strlcpy(lconfig->hc_controladdr, $2, 327211883Spjd sizeof(lconfig->hc_controladdr)) >= 328211883Spjd sizeof(lconfig->hc_controladdr)) { 329211883Spjd pjdlog_error("control argument is too long."); 330214274Spjd free($2); 331211883Spjd return (1); 332204076Spjd } 333204076Spjd break; 334204076Spjd default: 335204076Spjd assert(!"control at wrong depth level"); 336204076Spjd } 337214274Spjd free($2); 338204076Spjd } 339204076Spjd ; 340204076Spjd 341204076Spjdlisten_statement: LISTEN STR 342204076Spjd { 343204076Spjd switch (depth) { 344204076Spjd case 0: 345204076Spjd if (strlcpy(depth0_listen, $2, 346204076Spjd sizeof(depth0_listen)) >= 347204076Spjd sizeof(depth0_listen)) { 348210883Spjd pjdlog_error("listen argument is too long."); 349214274Spjd free($2); 350210883Spjd return (1); 351204076Spjd } 352204076Spjd break; 353204076Spjd case 1: 354211883Spjd if (!mynode) 355211883Spjd break; 356211883Spjd if (strlcpy(lconfig->hc_listenaddr, $2, 357211883Spjd sizeof(lconfig->hc_listenaddr)) >= 358211883Spjd sizeof(lconfig->hc_listenaddr)) { 359211883Spjd pjdlog_error("listen argument is too long."); 360214274Spjd free($2); 361211883Spjd return (1); 362204076Spjd } 363204076Spjd break; 364204076Spjd default: 365204076Spjd assert(!"listen at wrong depth level"); 366204076Spjd } 367214274Spjd free($2); 368204076Spjd } 369204076Spjd ; 370204076Spjd 371204076Spjdreplication_statement: REPLICATION replication_type 372204076Spjd { 373204076Spjd switch (depth) { 374204076Spjd case 0: 375204076Spjd depth0_replication = $2; 376204076Spjd break; 377204076Spjd case 1: 378204076Spjd if (curres != NULL) 379204076Spjd curres->hr_replication = $2; 380204076Spjd break; 381204076Spjd default: 382204076Spjd assert(!"replication at wrong depth level"); 383204076Spjd } 384204076Spjd } 385204076Spjd ; 386204076Spjd 387204076Spjdreplication_type: 388204076Spjd FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } 389204076Spjd | 390204076Spjd MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } 391204076Spjd | 392204076Spjd ASYNC { $$ = HAST_REPLICATION_ASYNC; } 393204076Spjd ; 394204076Spjd 395219351Spjdchecksum_statement: CHECKSUM checksum_type 396219351Spjd { 397219351Spjd switch (depth) { 398219351Spjd case 0: 399219351Spjd depth0_checksum = $2; 400219351Spjd break; 401219351Spjd case 1: 402219351Spjd if (curres != NULL) 403219351Spjd curres->hr_checksum = $2; 404219351Spjd break; 405219351Spjd default: 406219351Spjd assert(!"checksum at wrong depth level"); 407219351Spjd } 408219351Spjd } 409219351Spjd ; 410219351Spjd 411219351Spjdchecksum_type: 412219351Spjd NONE { $$ = HAST_CHECKSUM_NONE; } 413219351Spjd | 414219351Spjd CRC32 { $$ = HAST_CHECKSUM_CRC32; } 415219351Spjd | 416219351Spjd SHA256 { $$ = HAST_CHECKSUM_SHA256; } 417219351Spjd ; 418219351Spjd 419207371Spjdtimeout_statement: TIMEOUT NUM 420207371Spjd { 421207371Spjd switch (depth) { 422207371Spjd case 0: 423207371Spjd depth0_timeout = $2; 424207371Spjd break; 425207371Spjd case 1: 426207371Spjd if (curres != NULL) 427207371Spjd curres->hr_timeout = $2; 428207371Spjd break; 429207371Spjd default: 430207371Spjd assert(!"timeout at wrong depth level"); 431207371Spjd } 432207371Spjd } 433207371Spjd ; 434207371Spjd 435211886Spjdexec_statement: EXEC STR 436211886Spjd { 437211886Spjd switch (depth) { 438211886Spjd case 0: 439211886Spjd if (strlcpy(depth0_exec, $2, sizeof(depth0_exec)) >= 440211886Spjd sizeof(depth0_exec)) { 441211886Spjd pjdlog_error("Exec path is too long."); 442214274Spjd free($2); 443211886Spjd return (1); 444211886Spjd } 445211886Spjd break; 446211886Spjd case 1: 447211886Spjd if (curres == NULL) 448211886Spjd break; 449211886Spjd if (strlcpy(curres->hr_exec, $2, 450211886Spjd sizeof(curres->hr_exec)) >= 451211886Spjd sizeof(curres->hr_exec)) { 452211886Spjd pjdlog_error("Exec path is too long."); 453214274Spjd free($2); 454211886Spjd return (1); 455211886Spjd } 456211886Spjd break; 457211886Spjd default: 458211886Spjd assert(!"exec at wrong depth level"); 459211886Spjd } 460214274Spjd free($2); 461211886Spjd } 462211886Spjd ; 463211886Spjd 464204076Spjdnode_statement: ON node_start OB node_entries CB 465204076Spjd { 466204076Spjd mynode = false; 467204076Spjd } 468204076Spjd ; 469204076Spjd 470204076Spjdnode_start: STR 471204076Spjd { 472210883Spjd switch (isitme($1)) { 473210883Spjd case -1: 474214274Spjd free($1); 475210883Spjd return (1); 476210883Spjd case 0: 477210883Spjd break; 478210883Spjd case 1: 479204076Spjd mynode = true; 480210883Spjd break; 481210883Spjd default: 482210883Spjd assert(!"invalid isitme() return value"); 483210883Spjd } 484214274Spjd free($1); 485204076Spjd } 486204076Spjd ; 487204076Spjd 488204076Spjdnode_entries: 489204076Spjd | 490204076Spjd node_entries node_entry 491204076Spjd ; 492204076Spjd 493204076Spjdnode_entry: 494204076Spjd control_statement 495204076Spjd | 496204076Spjd listen_statement 497204076Spjd ; 498204076Spjd 499204076Spjdresource_statement: RESOURCE resource_start OB resource_entries CB 500204076Spjd { 501204076Spjd if (curres != NULL) { 502204076Spjd /* 503216721Spjd * There must be section for this node, at least with 504216721Spjd * remote address configuration. 505216721Spjd */ 506216721Spjd if (!hadmynode) { 507216721Spjd char *names; 508216721Spjd 509216721Spjd if (node_names(&names) != 0) 510216721Spjd return (1); 511216721Spjd pjdlog_error("No resource %s configuration for this node (acceptable node names: %s).", 512216721Spjd curres->hr_name, names); 513216721Spjd return (1); 514216721Spjd } 515216721Spjd 516216721Spjd /* 517204076Spjd * Let's see there are some resource-level settings 518204076Spjd * that we can use for node-level settings. 519204076Spjd */ 520204076Spjd if (curres->hr_provname[0] == '\0' && 521204076Spjd depth1_provname[0] != '\0') { 522204076Spjd /* 523204076Spjd * Provider name is not set at node-level, 524204076Spjd * but is set at resource-level, use it. 525204076Spjd */ 526204076Spjd strlcpy(curres->hr_provname, depth1_provname, 527204076Spjd sizeof(curres->hr_provname)); 528204076Spjd } 529204076Spjd if (curres->hr_localpath[0] == '\0' && 530204076Spjd depth1_localpath[0] != '\0') { 531204076Spjd /* 532204076Spjd * Path to local provider is not set at 533204076Spjd * node-level, but is set at resource-level, 534204076Spjd * use it. 535204076Spjd */ 536204076Spjd strlcpy(curres->hr_localpath, depth1_localpath, 537204076Spjd sizeof(curres->hr_localpath)); 538204076Spjd } 539204076Spjd 540204076Spjd /* 541204076Spjd * If provider name is not given, use resource name 542204076Spjd * as provider name. 543204076Spjd */ 544204076Spjd if (curres->hr_provname[0] == '\0') { 545204076Spjd strlcpy(curres->hr_provname, curres->hr_name, 546204076Spjd sizeof(curres->hr_provname)); 547204076Spjd } 548204076Spjd 549204076Spjd /* 550204076Spjd * Remote address has to be configured at this point. 551204076Spjd */ 552204076Spjd if (curres->hr_remoteaddr[0] == '\0') { 553210883Spjd pjdlog_error("Remote address not configured for resource %s.", 554204076Spjd curres->hr_name); 555210883Spjd return (1); 556204076Spjd } 557204076Spjd /* 558204076Spjd * Path to local provider has to be configured at this 559204076Spjd * point. 560204076Spjd */ 561204076Spjd if (curres->hr_localpath[0] == '\0') { 562210883Spjd pjdlog_error("Path to local component not configured for resource %s.", 563204076Spjd curres->hr_name); 564210883Spjd return (1); 565204076Spjd } 566204076Spjd 567204076Spjd /* Put it onto resource list. */ 568210883Spjd TAILQ_INSERT_TAIL(&lconfig->hc_resources, curres, hr_next); 569204076Spjd curres = NULL; 570204076Spjd } 571204076Spjd } 572204076Spjd ; 573204076Spjd 574204076Spjdresource_start: STR 575204076Spjd { 576216722Spjd /* Check if there is no duplicate entry. */ 577216722Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 578216722Spjd if (strcmp(curres->hr_name, $1) == 0) { 579216722Spjd pjdlog_error("Resource %s configured more than once.", 580216722Spjd curres->hr_name); 581216722Spjd free($1); 582216722Spjd return (1); 583216722Spjd } 584216722Spjd } 585216722Spjd 586204076Spjd /* 587204076Spjd * Clear those, so we can tell if they were set at 588204076Spjd * resource-level or not. 589204076Spjd */ 590204076Spjd depth1_provname[0] = '\0'; 591204076Spjd depth1_localpath[0] = '\0'; 592216721Spjd hadmynode = false; 593204076Spjd 594204076Spjd curres = calloc(1, sizeof(*curres)); 595204076Spjd if (curres == NULL) { 596210883Spjd pjdlog_error("Unable to allocate memory for resource."); 597214274Spjd free($1); 598210883Spjd return (1); 599204076Spjd } 600204076Spjd if (strlcpy(curres->hr_name, $1, 601204076Spjd sizeof(curres->hr_name)) >= 602204076Spjd sizeof(curres->hr_name)) { 603210883Spjd pjdlog_error("Resource name is too long."); 604214274Spjd free($1); 605210883Spjd return (1); 606204076Spjd } 607214274Spjd free($1); 608204076Spjd curres->hr_role = HAST_ROLE_INIT; 609204076Spjd curres->hr_previous_role = HAST_ROLE_INIT; 610204076Spjd curres->hr_replication = -1; 611219351Spjd curres->hr_checksum = -1; 612207371Spjd curres->hr_timeout = -1; 613211886Spjd curres->hr_exec[0] = '\0'; 614204076Spjd curres->hr_provname[0] = '\0'; 615204076Spjd curres->hr_localpath[0] = '\0'; 616204076Spjd curres->hr_localfd = -1; 617204076Spjd curres->hr_remoteaddr[0] = '\0'; 618204076Spjd curres->hr_ggateunit = -1; 619204076Spjd } 620204076Spjd ; 621204076Spjd 622204076Spjdresource_entries: 623204076Spjd | 624204076Spjd resource_entries resource_entry 625204076Spjd ; 626204076Spjd 627204076Spjdresource_entry: 628204076Spjd replication_statement 629204076Spjd | 630219351Spjd checksum_statement 631219351Spjd | 632207371Spjd timeout_statement 633207371Spjd | 634211886Spjd exec_statement 635211886Spjd | 636204076Spjd name_statement 637204076Spjd | 638204076Spjd local_statement 639204076Spjd | 640204076Spjd resource_node_statement 641204076Spjd ; 642204076Spjd 643204076Spjdname_statement: NAME STR 644204076Spjd { 645204076Spjd switch (depth) { 646204076Spjd case 1: 647204076Spjd if (strlcpy(depth1_provname, $2, 648204076Spjd sizeof(depth1_provname)) >= 649204076Spjd sizeof(depth1_provname)) { 650210883Spjd pjdlog_error("name argument is too long."); 651214274Spjd free($2); 652210883Spjd return (1); 653204076Spjd } 654204076Spjd break; 655204076Spjd case 2: 656211883Spjd if (!mynode) 657211883Spjd break; 658211883Spjd assert(curres != NULL); 659211883Spjd if (strlcpy(curres->hr_provname, $2, 660211883Spjd sizeof(curres->hr_provname)) >= 661211883Spjd sizeof(curres->hr_provname)) { 662211883Spjd pjdlog_error("name argument is too long."); 663214274Spjd free($2); 664211883Spjd return (1); 665204076Spjd } 666204076Spjd break; 667204076Spjd default: 668204076Spjd assert(!"name at wrong depth level"); 669204076Spjd } 670214274Spjd free($2); 671204076Spjd } 672204076Spjd ; 673204076Spjd 674204076Spjdlocal_statement: LOCAL STR 675204076Spjd { 676204076Spjd switch (depth) { 677204076Spjd case 1: 678204076Spjd if (strlcpy(depth1_localpath, $2, 679204076Spjd sizeof(depth1_localpath)) >= 680204076Spjd sizeof(depth1_localpath)) { 681210883Spjd pjdlog_error("local argument is too long."); 682214274Spjd free($2); 683210883Spjd return (1); 684204076Spjd } 685204076Spjd break; 686204076Spjd case 2: 687211883Spjd if (!mynode) 688211883Spjd break; 689211883Spjd assert(curres != NULL); 690211883Spjd if (strlcpy(curres->hr_localpath, $2, 691211883Spjd sizeof(curres->hr_localpath)) >= 692211883Spjd sizeof(curres->hr_localpath)) { 693211883Spjd pjdlog_error("local argument is too long."); 694214274Spjd free($2); 695211883Spjd return (1); 696204076Spjd } 697204076Spjd break; 698204076Spjd default: 699204076Spjd assert(!"local at wrong depth level"); 700204076Spjd } 701214274Spjd free($2); 702204076Spjd } 703204076Spjd ; 704204076Spjd 705204076Spjdresource_node_statement:ON resource_node_start OB resource_node_entries CB 706204076Spjd { 707204076Spjd mynode = false; 708204076Spjd } 709204076Spjd ; 710204076Spjd 711204076Spjdresource_node_start: STR 712204076Spjd { 713210883Spjd if (curres != NULL) { 714210883Spjd switch (isitme($1)) { 715210883Spjd case -1: 716214274Spjd free($1); 717210883Spjd return (1); 718210883Spjd case 0: 719210883Spjd break; 720210883Spjd case 1: 721216721Spjd mynode = hadmynode = true; 722210883Spjd break; 723210883Spjd default: 724210883Spjd assert(!"invalid isitme() return value"); 725210883Spjd } 726210883Spjd } 727214274Spjd free($1); 728204076Spjd } 729204076Spjd ; 730204076Spjd 731204076Spjdresource_node_entries: 732204076Spjd | 733204076Spjd resource_node_entries resource_node_entry 734204076Spjd ; 735204076Spjd 736204076Spjdresource_node_entry: 737204076Spjd name_statement 738204076Spjd | 739204076Spjd local_statement 740204076Spjd | 741204076Spjd remote_statement 742204076Spjd ; 743204076Spjd 744204076Spjdremote_statement: REMOTE STR 745204076Spjd { 746204076Spjd assert(depth == 2); 747204076Spjd if (mynode) { 748204076Spjd assert(curres != NULL); 749204076Spjd if (strlcpy(curres->hr_remoteaddr, $2, 750204076Spjd sizeof(curres->hr_remoteaddr)) >= 751204076Spjd sizeof(curres->hr_remoteaddr)) { 752210883Spjd pjdlog_error("remote argument is too long."); 753214274Spjd free($2); 754210883Spjd return (1); 755204076Spjd } 756204076Spjd } 757214274Spjd free($2); 758204076Spjd } 759204076Spjd ; 760