parse.y revision 219818
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 219818 2011-03-21 08:54:59Z 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; 65219354Spjdstatic int depth0_compression; 66207371Spjdstatic int depth0_timeout; 67211886Spjdstatic char depth0_exec[PATH_MAX]; 68204076Spjd 69204076Spjdstatic char depth1_provname[PATH_MAX]; 70204076Spjdstatic char depth1_localpath[PATH_MAX]; 71204076Spjd 72210883Spjdextern void yyrestart(FILE *); 73210883Spjd 74210883Spjdstatic int 75204076Spjdisitme(const char *name) 76204076Spjd{ 77204076Spjd char buf[MAXHOSTNAMELEN]; 78204076Spjd char *pos; 79204076Spjd size_t bufsize; 80204076Spjd 81204076Spjd /* 82204076Spjd * First check if the give name matches our full hostname. 83204076Spjd */ 84210883Spjd if (gethostname(buf, sizeof(buf)) < 0) { 85210883Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 86210883Spjd return (-1); 87210883Spjd } 88204076Spjd if (strcmp(buf, name) == 0) 89210883Spjd return (1); 90204076Spjd 91204076Spjd /* 92204076Spjd * Now check if it matches first part of the host name. 93204076Spjd */ 94204076Spjd pos = strchr(buf, '.'); 95204076Spjd if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) 96210883Spjd return (1); 97204076Spjd 98204076Spjd /* 99204076Spjd * At the end check if name is equal to our host's UUID. 100204076Spjd */ 101204076Spjd bufsize = sizeof(buf); 102210883Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 103210883Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 104210883Spjd return (-1); 105210883Spjd } 106204076Spjd if (strcasecmp(buf, name) == 0) 107210883Spjd return (1); 108204076Spjd 109204076Spjd /* 110204076Spjd * Looks like this isn't about us. 111204076Spjd */ 112210883Spjd return (0); 113204076Spjd} 114204076Spjd 115216721Spjdstatic int 116216721Spjdnode_names(char **namesp) 117216721Spjd{ 118216721Spjd static char names[MAXHOSTNAMELEN * 3]; 119216721Spjd char buf[MAXHOSTNAMELEN]; 120216721Spjd char *pos; 121216721Spjd size_t bufsize; 122216721Spjd 123216721Spjd if (gethostname(buf, sizeof(buf)) < 0) { 124216721Spjd pjdlog_errno(LOG_ERR, "gethostname() failed"); 125216721Spjd return (-1); 126216721Spjd } 127216721Spjd 128216721Spjd /* First component of the host name. */ 129216721Spjd pos = strchr(buf, '.'); 130216721Spjd if (pos != NULL && pos != buf) { 131216721Spjd (void)strlcpy(names, buf, MIN((size_t)(pos - buf + 1), 132216721Spjd sizeof(names))); 133216721Spjd (void)strlcat(names, ", ", sizeof(names)); 134216721Spjd } 135216721Spjd 136216721Spjd /* Full host name. */ 137216721Spjd (void)strlcat(names, buf, sizeof(names)); 138216721Spjd (void)strlcat(names, ", ", sizeof(names)); 139216721Spjd 140216721Spjd /* Host UUID. */ 141216721Spjd bufsize = sizeof(buf); 142216721Spjd if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { 143216721Spjd pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); 144216721Spjd return (-1); 145216721Spjd } 146216721Spjd (void)strlcat(names, buf, sizeof(names)); 147216721Spjd 148216721Spjd *namesp = names; 149216721Spjd 150216721Spjd return (0); 151216721Spjd} 152216721Spjd 153204076Spjdvoid 154204076Spjdyyerror(const char *str) 155204076Spjd{ 156204076Spjd 157210883Spjd pjdlog_error("Unable to parse configuration file at line %d near '%s': %s", 158204076Spjd lineno, yytext, str); 159204076Spjd} 160204076Spjd 161204076Spjdstruct hastd_config * 162210883Spjdyy_config_parse(const char *config, bool exitonerror) 163204076Spjd{ 164204076Spjd int ret; 165204076Spjd 166204076Spjd curres = NULL; 167204076Spjd mynode = false; 168210883Spjd depth = 0; 169210883Spjd lineno = 0; 170204076Spjd 171207371Spjd depth0_timeout = HAST_TIMEOUT; 172204076Spjd depth0_replication = HAST_REPLICATION_MEMSYNC; 173219351Spjd depth0_checksum = HAST_CHECKSUM_NONE; 174219354Spjd depth0_compression = HAST_COMPRESSION_HOLE; 175204076Spjd strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); 176204076Spjd strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); 177211886Spjd depth0_exec[0] = '\0'; 178204076Spjd 179210883Spjd lconfig = calloc(1, sizeof(*lconfig)); 180210883Spjd if (lconfig == NULL) { 181210883Spjd pjdlog_error("Unable to allocate memory for configuration."); 182210883Spjd if (exitonerror) 183210883Spjd exit(EX_TEMPFAIL); 184210883Spjd return (NULL); 185210883Spjd } 186204076Spjd 187210883Spjd TAILQ_INIT(&lconfig->hc_resources); 188210883Spjd 189204076Spjd yyin = fopen(config, "r"); 190210883Spjd if (yyin == NULL) { 191210883Spjd pjdlog_errno(LOG_ERR, "Unable to open configuration file %s", 192210883Spjd config); 193210883Spjd yy_config_free(lconfig); 194210883Spjd if (exitonerror) 195210883Spjd exit(EX_OSFILE); 196210883Spjd return (NULL); 197210883Spjd } 198210883Spjd yyrestart(yyin); 199204076Spjd ret = yyparse(); 200204076Spjd fclose(yyin); 201204076Spjd if (ret != 0) { 202210883Spjd yy_config_free(lconfig); 203210883Spjd if (exitonerror) 204210883Spjd exit(EX_CONFIG); 205210883Spjd return (NULL); 206204076Spjd } 207204076Spjd 208204076Spjd /* 209204076Spjd * Let's see if everything is set up. 210204076Spjd */ 211210883Spjd if (lconfig->hc_controladdr[0] == '\0') { 212210883Spjd strlcpy(lconfig->hc_controladdr, depth0_control, 213210883Spjd sizeof(lconfig->hc_controladdr)); 214204076Spjd } 215210883Spjd if (lconfig->hc_listenaddr[0] == '\0') { 216210883Spjd strlcpy(lconfig->hc_listenaddr, depth0_listen, 217210883Spjd sizeof(lconfig->hc_listenaddr)); 218204076Spjd } 219210883Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 220204076Spjd assert(curres->hr_provname[0] != '\0'); 221204076Spjd assert(curres->hr_localpath[0] != '\0'); 222204076Spjd assert(curres->hr_remoteaddr[0] != '\0'); 223204076Spjd 224204076Spjd if (curres->hr_replication == -1) { 225204076Spjd /* 226204076Spjd * Replication is not set at resource-level. 227204076Spjd * Use global or default setting. 228204076Spjd */ 229204076Spjd curres->hr_replication = depth0_replication; 230204076Spjd } 231219351Spjd if (curres->hr_checksum == -1) { 232219351Spjd /* 233219351Spjd * Checksum is not set at resource-level. 234219351Spjd * Use global or default setting. 235219351Spjd */ 236219351Spjd curres->hr_checksum = depth0_checksum; 237219351Spjd } 238219354Spjd if (curres->hr_compression == -1) { 239219354Spjd /* 240219354Spjd * Compression is not set at resource-level. 241219354Spjd * Use global or default setting. 242219354Spjd */ 243219354Spjd curres->hr_compression = depth0_compression; 244219354Spjd } 245207371Spjd if (curres->hr_timeout == -1) { 246207371Spjd /* 247207371Spjd * Timeout is not set at resource-level. 248207371Spjd * Use global or default setting. 249207371Spjd */ 250207371Spjd curres->hr_timeout = depth0_timeout; 251207371Spjd } 252211886Spjd if (curres->hr_exec[0] == '\0') { 253211886Spjd /* 254211886Spjd * Exec is not set at resource-level. 255211886Spjd * Use global or default setting. 256211886Spjd */ 257211886Spjd strlcpy(curres->hr_exec, depth0_exec, 258211886Spjd sizeof(curres->hr_exec)); 259211886Spjd } 260204076Spjd } 261204076Spjd 262210883Spjd return (lconfig); 263204076Spjd} 264204076Spjd 265204076Spjdvoid 266204076Spjdyy_config_free(struct hastd_config *config) 267204076Spjd{ 268204076Spjd struct hast_resource *res; 269204076Spjd 270204076Spjd while ((res = TAILQ_FIRST(&config->hc_resources)) != NULL) { 271204076Spjd TAILQ_REMOVE(&config->hc_resources, res, hr_next); 272204076Spjd free(res); 273204076Spjd } 274210883Spjd free(config); 275204076Spjd} 276204076Spjd%} 277204076Spjd 278219354Spjd%token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION 279219818Spjd%token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON 280219354Spjd%token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 HOLE LZF 281204076Spjd%token NUM STR OB CB 282204076Spjd 283204076Spjd%type <num> replication_type 284219351Spjd%type <num> checksum_type 285219354Spjd%type <num> compression_type 286204076Spjd 287204076Spjd%union 288204076Spjd{ 289204076Spjd int num; 290204076Spjd char *str; 291204076Spjd} 292204076Spjd 293204076Spjd%token <num> NUM 294204076Spjd%token <str> STR 295204076Spjd 296204076Spjd%% 297204076Spjd 298204076Spjdstatements: 299204076Spjd | 300204076Spjd statements statement 301204076Spjd ; 302204076Spjd 303204076Spjdstatement: 304204076Spjd control_statement 305204076Spjd | 306204076Spjd listen_statement 307204076Spjd | 308204076Spjd replication_statement 309204076Spjd | 310219351Spjd checksum_statement 311219351Spjd | 312219354Spjd compression_statement 313219354Spjd | 314207371Spjd timeout_statement 315207371Spjd | 316211886Spjd exec_statement 317211886Spjd | 318204076Spjd node_statement 319204076Spjd | 320204076Spjd resource_statement 321204076Spjd ; 322204076Spjd 323204076Spjdcontrol_statement: CONTROL STR 324204076Spjd { 325204076Spjd switch (depth) { 326204076Spjd case 0: 327204076Spjd if (strlcpy(depth0_control, $2, 328204076Spjd sizeof(depth0_control)) >= 329204076Spjd sizeof(depth0_control)) { 330210883Spjd pjdlog_error("control argument is too long."); 331214274Spjd free($2); 332210883Spjd return (1); 333204076Spjd } 334204076Spjd break; 335204076Spjd case 1: 336211883Spjd if (!mynode) 337211883Spjd break; 338211883Spjd if (strlcpy(lconfig->hc_controladdr, $2, 339211883Spjd sizeof(lconfig->hc_controladdr)) >= 340211883Spjd sizeof(lconfig->hc_controladdr)) { 341211883Spjd pjdlog_error("control argument is too long."); 342214274Spjd free($2); 343211883Spjd return (1); 344204076Spjd } 345204076Spjd break; 346204076Spjd default: 347204076Spjd assert(!"control at wrong depth level"); 348204076Spjd } 349214274Spjd free($2); 350204076Spjd } 351204076Spjd ; 352204076Spjd 353204076Spjdlisten_statement: LISTEN STR 354204076Spjd { 355204076Spjd switch (depth) { 356204076Spjd case 0: 357204076Spjd if (strlcpy(depth0_listen, $2, 358204076Spjd sizeof(depth0_listen)) >= 359204076Spjd sizeof(depth0_listen)) { 360210883Spjd pjdlog_error("listen argument is too long."); 361214274Spjd free($2); 362210883Spjd return (1); 363204076Spjd } 364204076Spjd break; 365204076Spjd case 1: 366211883Spjd if (!mynode) 367211883Spjd break; 368211883Spjd if (strlcpy(lconfig->hc_listenaddr, $2, 369211883Spjd sizeof(lconfig->hc_listenaddr)) >= 370211883Spjd sizeof(lconfig->hc_listenaddr)) { 371211883Spjd pjdlog_error("listen argument is too long."); 372214274Spjd free($2); 373211883Spjd return (1); 374204076Spjd } 375204076Spjd break; 376204076Spjd default: 377204076Spjd assert(!"listen at wrong depth level"); 378204076Spjd } 379214274Spjd free($2); 380204076Spjd } 381204076Spjd ; 382204076Spjd 383204076Spjdreplication_statement: REPLICATION replication_type 384204076Spjd { 385204076Spjd switch (depth) { 386204076Spjd case 0: 387204076Spjd depth0_replication = $2; 388204076Spjd break; 389204076Spjd case 1: 390204076Spjd if (curres != NULL) 391204076Spjd curres->hr_replication = $2; 392204076Spjd break; 393204076Spjd default: 394204076Spjd assert(!"replication at wrong depth level"); 395204076Spjd } 396204076Spjd } 397204076Spjd ; 398204076Spjd 399204076Spjdreplication_type: 400204076Spjd FULLSYNC { $$ = HAST_REPLICATION_FULLSYNC; } 401204076Spjd | 402204076Spjd MEMSYNC { $$ = HAST_REPLICATION_MEMSYNC; } 403204076Spjd | 404204076Spjd ASYNC { $$ = HAST_REPLICATION_ASYNC; } 405204076Spjd ; 406204076Spjd 407219351Spjdchecksum_statement: CHECKSUM checksum_type 408219351Spjd { 409219351Spjd switch (depth) { 410219351Spjd case 0: 411219351Spjd depth0_checksum = $2; 412219351Spjd break; 413219351Spjd case 1: 414219351Spjd if (curres != NULL) 415219351Spjd curres->hr_checksum = $2; 416219351Spjd break; 417219351Spjd default: 418219351Spjd assert(!"checksum at wrong depth level"); 419219351Spjd } 420219351Spjd } 421219351Spjd ; 422219351Spjd 423219351Spjdchecksum_type: 424219351Spjd NONE { $$ = HAST_CHECKSUM_NONE; } 425219351Spjd | 426219351Spjd CRC32 { $$ = HAST_CHECKSUM_CRC32; } 427219351Spjd | 428219351Spjd SHA256 { $$ = HAST_CHECKSUM_SHA256; } 429219351Spjd ; 430219351Spjd 431219354Spjdcompression_statement: COMPRESSION compression_type 432219354Spjd { 433219354Spjd switch (depth) { 434219354Spjd case 0: 435219354Spjd depth0_compression = $2; 436219354Spjd break; 437219354Spjd case 1: 438219354Spjd if (curres != NULL) 439219354Spjd curres->hr_compression = $2; 440219354Spjd break; 441219354Spjd default: 442219354Spjd assert(!"compression at wrong depth level"); 443219354Spjd } 444219354Spjd } 445219354Spjd ; 446219354Spjd 447219354Spjdcompression_type: 448219354Spjd NONE { $$ = HAST_COMPRESSION_NONE; } 449219354Spjd | 450219354Spjd HOLE { $$ = HAST_COMPRESSION_HOLE; } 451219354Spjd | 452219354Spjd LZF { $$ = HAST_COMPRESSION_LZF; } 453219354Spjd ; 454219354Spjd 455207371Spjdtimeout_statement: TIMEOUT NUM 456207371Spjd { 457207371Spjd switch (depth) { 458207371Spjd case 0: 459207371Spjd depth0_timeout = $2; 460207371Spjd break; 461207371Spjd case 1: 462207371Spjd if (curres != NULL) 463207371Spjd curres->hr_timeout = $2; 464207371Spjd break; 465207371Spjd default: 466207371Spjd assert(!"timeout at wrong depth level"); 467207371Spjd } 468207371Spjd } 469207371Spjd ; 470207371Spjd 471211886Spjdexec_statement: EXEC STR 472211886Spjd { 473211886Spjd switch (depth) { 474211886Spjd case 0: 475211886Spjd if (strlcpy(depth0_exec, $2, sizeof(depth0_exec)) >= 476211886Spjd sizeof(depth0_exec)) { 477211886Spjd pjdlog_error("Exec path is too long."); 478214274Spjd free($2); 479211886Spjd return (1); 480211886Spjd } 481211886Spjd break; 482211886Spjd case 1: 483211886Spjd if (curres == NULL) 484211886Spjd break; 485211886Spjd if (strlcpy(curres->hr_exec, $2, 486211886Spjd sizeof(curres->hr_exec)) >= 487211886Spjd sizeof(curres->hr_exec)) { 488211886Spjd pjdlog_error("Exec path is too long."); 489214274Spjd free($2); 490211886Spjd return (1); 491211886Spjd } 492211886Spjd break; 493211886Spjd default: 494211886Spjd assert(!"exec at wrong depth level"); 495211886Spjd } 496214274Spjd free($2); 497211886Spjd } 498211886Spjd ; 499211886Spjd 500204076Spjdnode_statement: ON node_start OB node_entries CB 501204076Spjd { 502204076Spjd mynode = false; 503204076Spjd } 504204076Spjd ; 505204076Spjd 506204076Spjdnode_start: STR 507204076Spjd { 508210883Spjd switch (isitme($1)) { 509210883Spjd case -1: 510214274Spjd free($1); 511210883Spjd return (1); 512210883Spjd case 0: 513210883Spjd break; 514210883Spjd case 1: 515204076Spjd mynode = true; 516210883Spjd break; 517210883Spjd default: 518210883Spjd assert(!"invalid isitme() return value"); 519210883Spjd } 520214274Spjd free($1); 521204076Spjd } 522204076Spjd ; 523204076Spjd 524204076Spjdnode_entries: 525204076Spjd | 526204076Spjd node_entries node_entry 527204076Spjd ; 528204076Spjd 529204076Spjdnode_entry: 530204076Spjd control_statement 531204076Spjd | 532204076Spjd listen_statement 533204076Spjd ; 534204076Spjd 535204076Spjdresource_statement: RESOURCE resource_start OB resource_entries CB 536204076Spjd { 537204076Spjd if (curres != NULL) { 538204076Spjd /* 539216721Spjd * There must be section for this node, at least with 540216721Spjd * remote address configuration. 541216721Spjd */ 542216721Spjd if (!hadmynode) { 543216721Spjd char *names; 544216721Spjd 545216721Spjd if (node_names(&names) != 0) 546216721Spjd return (1); 547216721Spjd pjdlog_error("No resource %s configuration for this node (acceptable node names: %s).", 548216721Spjd curres->hr_name, names); 549216721Spjd return (1); 550216721Spjd } 551216721Spjd 552216721Spjd /* 553204076Spjd * Let's see there are some resource-level settings 554204076Spjd * that we can use for node-level settings. 555204076Spjd */ 556204076Spjd if (curres->hr_provname[0] == '\0' && 557204076Spjd depth1_provname[0] != '\0') { 558204076Spjd /* 559204076Spjd * Provider name is not set at node-level, 560204076Spjd * but is set at resource-level, use it. 561204076Spjd */ 562204076Spjd strlcpy(curres->hr_provname, depth1_provname, 563204076Spjd sizeof(curres->hr_provname)); 564204076Spjd } 565204076Spjd if (curres->hr_localpath[0] == '\0' && 566204076Spjd depth1_localpath[0] != '\0') { 567204076Spjd /* 568204076Spjd * Path to local provider is not set at 569204076Spjd * node-level, but is set at resource-level, 570204076Spjd * use it. 571204076Spjd */ 572204076Spjd strlcpy(curres->hr_localpath, depth1_localpath, 573204076Spjd sizeof(curres->hr_localpath)); 574204076Spjd } 575204076Spjd 576204076Spjd /* 577204076Spjd * If provider name is not given, use resource name 578204076Spjd * as provider name. 579204076Spjd */ 580204076Spjd if (curres->hr_provname[0] == '\0') { 581204076Spjd strlcpy(curres->hr_provname, curres->hr_name, 582204076Spjd sizeof(curres->hr_provname)); 583204076Spjd } 584204076Spjd 585204076Spjd /* 586204076Spjd * Remote address has to be configured at this point. 587204076Spjd */ 588204076Spjd if (curres->hr_remoteaddr[0] == '\0') { 589210883Spjd pjdlog_error("Remote address not configured for resource %s.", 590204076Spjd curres->hr_name); 591210883Spjd return (1); 592204076Spjd } 593204076Spjd /* 594204076Spjd * Path to local provider has to be configured at this 595204076Spjd * point. 596204076Spjd */ 597204076Spjd if (curres->hr_localpath[0] == '\0') { 598210883Spjd pjdlog_error("Path to local component not configured for resource %s.", 599204076Spjd curres->hr_name); 600210883Spjd return (1); 601204076Spjd } 602204076Spjd 603204076Spjd /* Put it onto resource list. */ 604210883Spjd TAILQ_INSERT_TAIL(&lconfig->hc_resources, curres, hr_next); 605204076Spjd curres = NULL; 606204076Spjd } 607204076Spjd } 608204076Spjd ; 609204076Spjd 610204076Spjdresource_start: STR 611204076Spjd { 612216722Spjd /* Check if there is no duplicate entry. */ 613216722Spjd TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { 614216722Spjd if (strcmp(curres->hr_name, $1) == 0) { 615216722Spjd pjdlog_error("Resource %s configured more than once.", 616216722Spjd curres->hr_name); 617216722Spjd free($1); 618216722Spjd return (1); 619216722Spjd } 620216722Spjd } 621216722Spjd 622204076Spjd /* 623204076Spjd * Clear those, so we can tell if they were set at 624204076Spjd * resource-level or not. 625204076Spjd */ 626204076Spjd depth1_provname[0] = '\0'; 627204076Spjd depth1_localpath[0] = '\0'; 628216721Spjd hadmynode = false; 629204076Spjd 630204076Spjd curres = calloc(1, sizeof(*curres)); 631204076Spjd if (curres == NULL) { 632210883Spjd pjdlog_error("Unable to allocate memory for resource."); 633214274Spjd free($1); 634210883Spjd return (1); 635204076Spjd } 636204076Spjd if (strlcpy(curres->hr_name, $1, 637204076Spjd sizeof(curres->hr_name)) >= 638204076Spjd sizeof(curres->hr_name)) { 639210883Spjd pjdlog_error("Resource name is too long."); 640214274Spjd free($1); 641210883Spjd return (1); 642204076Spjd } 643214274Spjd free($1); 644204076Spjd curres->hr_role = HAST_ROLE_INIT; 645204076Spjd curres->hr_previous_role = HAST_ROLE_INIT; 646204076Spjd curres->hr_replication = -1; 647219351Spjd curres->hr_checksum = -1; 648219354Spjd curres->hr_compression = -1; 649207371Spjd curres->hr_timeout = -1; 650211886Spjd curres->hr_exec[0] = '\0'; 651204076Spjd curres->hr_provname[0] = '\0'; 652204076Spjd curres->hr_localpath[0] = '\0'; 653204076Spjd curres->hr_localfd = -1; 654204076Spjd curres->hr_remoteaddr[0] = '\0'; 655219818Spjd curres->hr_sourceaddr[0] = '\0'; 656204076Spjd curres->hr_ggateunit = -1; 657204076Spjd } 658204076Spjd ; 659204076Spjd 660204076Spjdresource_entries: 661204076Spjd | 662204076Spjd resource_entries resource_entry 663204076Spjd ; 664204076Spjd 665204076Spjdresource_entry: 666204076Spjd replication_statement 667204076Spjd | 668219351Spjd checksum_statement 669219351Spjd | 670219354Spjd compression_statement 671219354Spjd | 672207371Spjd timeout_statement 673207371Spjd | 674211886Spjd exec_statement 675211886Spjd | 676204076Spjd name_statement 677204076Spjd | 678204076Spjd local_statement 679204076Spjd | 680204076Spjd resource_node_statement 681204076Spjd ; 682204076Spjd 683204076Spjdname_statement: NAME STR 684204076Spjd { 685204076Spjd switch (depth) { 686204076Spjd case 1: 687204076Spjd if (strlcpy(depth1_provname, $2, 688204076Spjd sizeof(depth1_provname)) >= 689204076Spjd sizeof(depth1_provname)) { 690210883Spjd pjdlog_error("name argument is too long."); 691214274Spjd free($2); 692210883Spjd return (1); 693204076Spjd } 694204076Spjd break; 695204076Spjd case 2: 696211883Spjd if (!mynode) 697211883Spjd break; 698211883Spjd assert(curres != NULL); 699211883Spjd if (strlcpy(curres->hr_provname, $2, 700211883Spjd sizeof(curres->hr_provname)) >= 701211883Spjd sizeof(curres->hr_provname)) { 702211883Spjd pjdlog_error("name argument is too long."); 703214274Spjd free($2); 704211883Spjd return (1); 705204076Spjd } 706204076Spjd break; 707204076Spjd default: 708204076Spjd assert(!"name at wrong depth level"); 709204076Spjd } 710214274Spjd free($2); 711204076Spjd } 712204076Spjd ; 713204076Spjd 714204076Spjdlocal_statement: LOCAL STR 715204076Spjd { 716204076Spjd switch (depth) { 717204076Spjd case 1: 718204076Spjd if (strlcpy(depth1_localpath, $2, 719204076Spjd sizeof(depth1_localpath)) >= 720204076Spjd sizeof(depth1_localpath)) { 721210883Spjd pjdlog_error("local argument is too long."); 722214274Spjd free($2); 723210883Spjd return (1); 724204076Spjd } 725204076Spjd break; 726204076Spjd case 2: 727211883Spjd if (!mynode) 728211883Spjd break; 729211883Spjd assert(curres != NULL); 730211883Spjd if (strlcpy(curres->hr_localpath, $2, 731211883Spjd sizeof(curres->hr_localpath)) >= 732211883Spjd sizeof(curres->hr_localpath)) { 733211883Spjd pjdlog_error("local argument is too long."); 734214274Spjd free($2); 735211883Spjd return (1); 736204076Spjd } 737204076Spjd break; 738204076Spjd default: 739204076Spjd assert(!"local at wrong depth level"); 740204076Spjd } 741214274Spjd free($2); 742204076Spjd } 743204076Spjd ; 744204076Spjd 745204076Spjdresource_node_statement:ON resource_node_start OB resource_node_entries CB 746204076Spjd { 747204076Spjd mynode = false; 748204076Spjd } 749204076Spjd ; 750204076Spjd 751204076Spjdresource_node_start: STR 752204076Spjd { 753210883Spjd if (curres != NULL) { 754210883Spjd switch (isitme($1)) { 755210883Spjd case -1: 756214274Spjd free($1); 757210883Spjd return (1); 758210883Spjd case 0: 759210883Spjd break; 760210883Spjd case 1: 761216721Spjd mynode = hadmynode = true; 762210883Spjd break; 763210883Spjd default: 764210883Spjd assert(!"invalid isitme() return value"); 765210883Spjd } 766210883Spjd } 767214274Spjd free($1); 768204076Spjd } 769204076Spjd ; 770204076Spjd 771204076Spjdresource_node_entries: 772204076Spjd | 773204076Spjd resource_node_entries resource_node_entry 774204076Spjd ; 775204076Spjd 776204076Spjdresource_node_entry: 777204076Spjd name_statement 778204076Spjd | 779204076Spjd local_statement 780204076Spjd | 781204076Spjd remote_statement 782219818Spjd | 783219818Spjd source_statement 784204076Spjd ; 785204076Spjd 786204076Spjdremote_statement: REMOTE STR 787204076Spjd { 788204076Spjd assert(depth == 2); 789204076Spjd if (mynode) { 790204076Spjd assert(curres != NULL); 791204076Spjd if (strlcpy(curres->hr_remoteaddr, $2, 792204076Spjd sizeof(curres->hr_remoteaddr)) >= 793204076Spjd sizeof(curres->hr_remoteaddr)) { 794210883Spjd pjdlog_error("remote argument is too long."); 795214274Spjd free($2); 796210883Spjd return (1); 797204076Spjd } 798204076Spjd } 799214274Spjd free($2); 800204076Spjd } 801204076Spjd ; 802219818Spjd 803219818Spjdsource_statement: SOURCE STR 804219818Spjd { 805219818Spjd assert(depth == 2); 806219818Spjd if (mynode) { 807219818Spjd assert(curres != NULL); 808219818Spjd if (strlcpy(curres->hr_sourceaddr, $2, 809219818Spjd sizeof(curres->hr_sourceaddr)) >= 810219818Spjd sizeof(curres->hr_sourceaddr)) { 811219818Spjd pjdlog_error("source argument is too long."); 812219818Spjd free($2); 813219818Spjd return (1); 814219818Spjd } 815219818Spjd } 816219818Spjd free($2); 817219818Spjd } 818219818Spjd ; 819