From owner-svn-src-all@FreeBSD.ORG Thu Aug 5 19:08:55 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 15518106566B; Thu, 5 Aug 2010 19:08:55 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 02B678FC12; Thu, 5 Aug 2010 19:08:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o75J8sPI078968; Thu, 5 Aug 2010 19:08:54 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o75J8sFW078964; Thu, 5 Aug 2010 19:08:54 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201008051908.o75J8sFW078964@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Thu, 5 Aug 2010 19:08:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210883 - head/sbin/hastd X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Aug 2010 19:08:55 -0000 Author: pjd Date: Thu Aug 5 19:08:54 2010 New Revision: 210883 URL: http://svn.freebsd.org/changeset/base/210883 Log: Prepare configuration parsing code to be called multiple times: - Don't exit on errors if not requested. - Don't keep configuration in global variable, but allocate memory for configuration. - Call yyrestart() before yyparse() so that on error in configuration file we will start from the begining next time and not from the place we left of. MFC after: 1 month Modified: head/sbin/hastd/hast.h head/sbin/hastd/hastd.c head/sbin/hastd/parse.y Modified: head/sbin/hastd/hast.h ============================================================================== --- head/sbin/hastd/hast.h Thu Aug 5 19:04:29 2010 (r210882) +++ head/sbin/hastd/hast.h Thu Aug 5 19:08:54 2010 (r210883) @@ -183,7 +183,7 @@ struct hast_resource { TAILQ_ENTRY(hast_resource) hr_next; }; -struct hastd_config *yy_config_parse(const char *config); +struct hastd_config *yy_config_parse(const char *config, bool exitonerror); void yy_config_free(struct hastd_config *config); void yyerror(const char *); Modified: head/sbin/hastd/hastd.c ============================================================================== --- head/sbin/hastd/hastd.c Thu Aug 5 19:04:29 2010 (r210882) +++ head/sbin/hastd/hastd.c Thu Aug 5 19:08:54 2010 (r210883) @@ -493,7 +493,7 @@ main(int argc, char *argv[]) pjdlog_errno(LOG_WARNING, "Unable to open or create pidfile"); } - cfg = yy_config_parse(cfgpath); + cfg = yy_config_parse(cfgpath, true); assert(cfg != NULL); signal(SIGHUP, sighandler); Modified: head/sbin/hastd/parse.y ============================================================================== --- head/sbin/hastd/parse.y Thu Aug 5 19:04:29 2010 (r210882) +++ head/sbin/hastd/parse.y Thu Aug 5 19:08:54 2010 (r210883) @@ -43,6 +43,8 @@ #include #include +#include + #include "hast.h" extern int depth; @@ -51,7 +53,7 @@ extern int lineno; extern FILE *yyin; extern char *yytext; -static struct hastd_config lconfig; +static struct hastd_config *lconfig; static struct hast_resource *curres; static bool mynode; @@ -63,7 +65,9 @@ static int depth0_timeout; static char depth1_provname[PATH_MAX]; static char depth1_localpath[PATH_MAX]; -static bool +extern void yyrestart(FILE *); + +static int isitme(const char *name) { char buf[MAXHOSTNAMELEN]; @@ -73,78 +77,101 @@ isitme(const char *name) /* * First check if the give name matches our full hostname. */ - if (gethostname(buf, sizeof(buf)) < 0) - err(EX_OSERR, "gethostname() failed"); + if (gethostname(buf, sizeof(buf)) < 0) { + pjdlog_errno(LOG_ERR, "gethostname() failed"); + return (-1); + } if (strcmp(buf, name) == 0) - return (true); + return (1); /* * Now check if it matches first part of the host name. */ pos = strchr(buf, '.'); if (pos != NULL && pos != buf && strncmp(buf, name, pos - buf) == 0) - return (true); + return (1); /* * At the end check if name is equal to our host's UUID. */ bufsize = sizeof(buf); - if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) - err(EX_OSERR, "sysctlbyname(kern.hostuuid) failed"); + if (sysctlbyname("kern.hostuuid", buf, &bufsize, NULL, 0) < 0) { + pjdlog_errno(LOG_ERR, "sysctlbyname(kern.hostuuid) failed"); + return (-1); + } if (strcasecmp(buf, name) == 0) - return (true); + return (1); /* * Looks like this isn't about us. */ - return (false); + return (0); } void yyerror(const char *str) { - fprintf(stderr, "error at line %d near '%s': %s\n", + pjdlog_error("Unable to parse configuration file at line %d near '%s': %s", lineno, yytext, str); } struct hastd_config * -yy_config_parse(const char *config) +yy_config_parse(const char *config, bool exitonerror) { int ret; curres = NULL; mynode = false; + depth = 0; + lineno = 0; depth0_timeout = HAST_TIMEOUT; depth0_replication = HAST_REPLICATION_MEMSYNC; strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); - TAILQ_INIT(&lconfig.hc_resources); + lconfig = calloc(1, sizeof(*lconfig)); + if (lconfig == NULL) { + pjdlog_error("Unable to allocate memory for configuration."); + if (exitonerror) + exit(EX_TEMPFAIL); + return (NULL); + } + + TAILQ_INIT(&lconfig->hc_resources); yyin = fopen(config, "r"); - if (yyin == NULL) - err(EX_OSFILE, "cannot open configuration file %s", config); + if (yyin == NULL) { + pjdlog_errno(LOG_ERR, "Unable to open configuration file %s", + config); + yy_config_free(lconfig); + if (exitonerror) + exit(EX_OSFILE); + return (NULL); + } + yyrestart(yyin); ret = yyparse(); fclose(yyin); if (ret != 0) { - yy_config_free(&lconfig); - exit(EX_CONFIG); + yy_config_free(lconfig); + if (exitonerror) + exit(EX_CONFIG); + return (NULL); } /* * Let's see if everything is set up. */ - if (lconfig.hc_controladdr[0] == '\0') { - strlcpy(lconfig.hc_controladdr, depth0_control, - sizeof(lconfig.hc_controladdr)); - } - if (lconfig.hc_listenaddr[0] == '\0') { - strlcpy(lconfig.hc_listenaddr, depth0_listen, - sizeof(lconfig.hc_listenaddr)); + if (lconfig->hc_controladdr[0] == '\0') { + strlcpy(lconfig->hc_controladdr, depth0_control, + sizeof(lconfig->hc_controladdr)); + } + if (lconfig->hc_listenaddr[0] == '\0') { + strlcpy(lconfig->hc_listenaddr, depth0_listen, + sizeof(lconfig->hc_listenaddr)); } - TAILQ_FOREACH(curres, &lconfig.hc_resources, hr_next) { + TAILQ_FOREACH(curres, &lconfig->hc_resources, hr_next) { assert(curres->hr_provname[0] != '\0'); assert(curres->hr_localpath[0] != '\0'); assert(curres->hr_remoteaddr[0] != '\0'); @@ -165,7 +192,7 @@ yy_config_parse(const char *config) } } - return (&lconfig); + return (lconfig); } void @@ -177,6 +204,7 @@ yy_config_free(struct hastd_config *conf TAILQ_REMOVE(&config->hc_resources, res, hr_next); free(res); } + free(config); } %} @@ -223,16 +251,17 @@ control_statement: CONTROL STR if (strlcpy(depth0_control, $2, sizeof(depth0_control)) >= sizeof(depth0_control)) { - errx(EX_CONFIG, "control argument too long"); + pjdlog_error("control argument is too long."); + return (1); } break; case 1: if (mynode) { - if (strlcpy(lconfig.hc_controladdr, $2, - sizeof(lconfig.hc_controladdr)) >= - sizeof(lconfig.hc_controladdr)) { - errx(EX_CONFIG, - "control argument too long"); + if (strlcpy(lconfig->hc_controladdr, $2, + sizeof(lconfig->hc_controladdr)) >= + sizeof(lconfig->hc_controladdr)) { + pjdlog_error("control argument is too long."); + return (1); } } break; @@ -249,16 +278,17 @@ listen_statement: LISTEN STR if (strlcpy(depth0_listen, $2, sizeof(depth0_listen)) >= sizeof(depth0_listen)) { - errx(EX_CONFIG, "listen argument too long"); + pjdlog_error("listen argument is too long."); + return (1); } break; case 1: if (mynode) { - if (strlcpy(lconfig.hc_listenaddr, $2, - sizeof(lconfig.hc_listenaddr)) >= - sizeof(lconfig.hc_listenaddr)) { - errx(EX_CONFIG, - "listen argument too long"); + if (strlcpy(lconfig->hc_listenaddr, $2, + sizeof(lconfig->hc_listenaddr)) >= + sizeof(lconfig->hc_listenaddr)) { + pjdlog_error("listen argument is too long."); + return (1); } } break; @@ -316,8 +346,17 @@ node_statement: ON node_start OB node_e node_start: STR { - if (isitme($1)) + switch (isitme($1)) { + case -1: + return (1); + case 0: + break; + case 1: mynode = true; + break; + default: + assert(!"invalid isitme() return value"); + } } ; @@ -372,22 +411,22 @@ resource_statement: RESOURCE resource_st * Remote address has to be configured at this point. */ if (curres->hr_remoteaddr[0] == '\0') { - errx(EX_CONFIG, - "remote address not configured for resource %s", + pjdlog_error("Remote address not configured for resource %s.", curres->hr_name); + return (1); } /* * Path to local provider has to be configured at this * point. */ if (curres->hr_localpath[0] == '\0') { - errx(EX_CONFIG, - "path local component not configured for resource %s", + pjdlog_error("Path to local component not configured for resource %s.", curres->hr_name); + return (1); } /* Put it onto resource list. */ - TAILQ_INSERT_TAIL(&lconfig.hc_resources, curres, hr_next); + TAILQ_INSERT_TAIL(&lconfig->hc_resources, curres, hr_next); curres = NULL; } } @@ -404,14 +443,14 @@ resource_start: STR curres = calloc(1, sizeof(*curres)); if (curres == NULL) { - errx(EX_TEMPFAIL, - "cannot allocate memory for resource"); + pjdlog_error("Unable to allocate memory for resource."); + return (1); } if (strlcpy(curres->hr_name, $1, sizeof(curres->hr_name)) >= sizeof(curres->hr_name)) { - errx(EX_CONFIG, - "resource name (%s) too long", $1); + pjdlog_error("Resource name is too long."); + return (1); } curres->hr_role = HAST_ROLE_INIT; curres->hr_previous_role = HAST_ROLE_INIT; @@ -449,7 +488,8 @@ name_statement: NAME STR if (strlcpy(depth1_provname, $2, sizeof(depth1_provname)) >= sizeof(depth1_provname)) { - errx(EX_CONFIG, "name argument too long"); + pjdlog_error("name argument is too long."); + return (1); } break; case 2: @@ -458,8 +498,8 @@ name_statement: NAME STR if (strlcpy(curres->hr_provname, $2, sizeof(curres->hr_provname)) >= sizeof(curres->hr_provname)) { - errx(EX_CONFIG, - "name argument too long"); + pjdlog_error("name argument is too long."); + return (1); } } break; @@ -476,7 +516,8 @@ local_statement: LOCAL STR if (strlcpy(depth1_localpath, $2, sizeof(depth1_localpath)) >= sizeof(depth1_localpath)) { - errx(EX_CONFIG, "local argument too long"); + pjdlog_error("local argument is too long."); + return (1); } break; case 2: @@ -485,8 +526,8 @@ local_statement: LOCAL STR if (strlcpy(curres->hr_localpath, $2, sizeof(curres->hr_localpath)) >= sizeof(curres->hr_localpath)) { - errx(EX_CONFIG, - "local argument too long"); + pjdlog_error("local argument is too long."); + return (1); } } break; @@ -504,8 +545,19 @@ resource_node_statement:ON resource_node resource_node_start: STR { - if (curres != NULL && isitme($1)) - mynode = true; + if (curres != NULL) { + switch (isitme($1)) { + case -1: + return (1); + case 0: + break; + case 1: + mynode = true; + break; + default: + assert(!"invalid isitme() return value"); + } + } } ; @@ -530,7 +582,8 @@ remote_statement: REMOTE STR if (strlcpy(curres->hr_remoteaddr, $2, sizeof(curres->hr_remoteaddr)) >= sizeof(curres->hr_remoteaddr)) { - errx(EX_CONFIG, "remote argument too long"); + pjdlog_error("remote argument is too long."); + return (1); } } }