diff -Naur libreswan-3.15-orig/include/ipsecconf/confread.h libreswan-3.15/include/ipsecconf/confread.h
--- libreswan-3.15-orig/include/ipsecconf/confread.h 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/include/ipsecconf/confread.h 2015-09-03 11:43:09.630000000 -0400
@@ -132,7 +132,7 @@
extern struct starter_config *confread_load(const char *file,
err_t *perr,
bool resolvip,
- char *ctlbase,
+ const char *ctlbase,
bool setuponly);
extern struct starter_conn *alloc_add_conn(struct starter_config *cfg,
char *name);
diff -Naur libreswan-3.15-orig/include/ipsecconf/keywords.h libreswan-3.15/include/ipsecconf/keywords.h
--- libreswan-3.15-orig/include/ipsecconf/keywords.h 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/include/ipsecconf/keywords.h 2015-09-03 11:43:10.538000000 -0400
@@ -305,8 +305,7 @@
struct kw_list {
struct kw_list *next;
struct keyword keyword;
- char *string;
- double decimal;
+ char *string;
unsigned int number;
};
diff -Naur libreswan-3.15-orig/lib/libipsecconf/confread.c libreswan-3.15/lib/libipsecconf/confread.c
--- libreswan-3.15-orig/lib/libipsecconf/confread.c 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/lib/libipsecconf/confread.c 2015-09-03 11:42:22.941000000 -0400
@@ -1418,7 +1418,7 @@
struct starter_config *confread_load(const char *file,
err_t *perr,
bool resolvip,
- char *ctlbase,
+ const char *ctlbase,
bool setuponly)
{
struct starter_config *cfg = NULL;
diff -Naur libreswan-3.15-orig/lib/libipsecconf/confwrite.c libreswan-3.15/lib/libipsecconf/confwrite.c
--- libreswan-3.15-orig/lib/libipsecconf/confwrite.c 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/lib/libipsecconf/confwrite.c 2015-09-03 11:42:22.941000000 -0400
@@ -412,9 +412,9 @@
int alsoplace = 0;
- fprintf(out, "\t#also = ");
+ fprintf(out, "\t#also =");
while (conn->alsos[alsoplace] != NULL) {
- fprintf(out, "%s ", conn->alsos[alsoplace]);
+ fprintf(out, " %s", conn->alsos[alsoplace]);
alsoplace++;
}
fprintf(out, "\n");
diff -Naur libreswan-3.15-orig/lib/libipsecconf/Makefile libreswan-3.15/lib/libipsecconf/Makefile
--- libreswan-3.15-orig/lib/libipsecconf/Makefile 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/lib/libipsecconf/Makefile 2015-09-03 11:42:22.941000000 -0400
@@ -38,21 +38,45 @@
# since all the $(OBJS) indirectly depend on the header anyway.
$(OBJS): parser.tab.h
-# Use UNIX basename to strip off the directory. Use grep to workaround flex < 2.5.35
+# Use UNIX basename to strip off the directory.
+# Use sed to work around two bugs:
+#
+# - flex < 2.5.35 generates an extern that isn't good
+#
+# - flex on RHEL 7 generates code that provokes GCC to warn
+# about comparing a signed value with an unsigned value
+# (Combination of a new GCC and an old flex).
+# Adding one cast makes RHEL 6's GCC unhappy, so we add two.
+# On RHEL 6, i is int and _yybytes_len is int.
+# On RHEL 7, i is int and _yybytes_len is yy_size_t
+# On Fedora 21, i is yy_size_t and _yybytes_len is yy_size_t
+# On some architectures, yy_size_t is wider than int;
+# which makes a mixed comparison OK.
+#
+# Avoid sed -i which somehow causes unwritable files
+# on fedora 20 with 9p filesystem mount.
+# Avoid creating the target file until it is done.
lex.yy.c: parser.l
- cd $(builddir) && $(LEX) -t $(srcdir)/$$(basename $<) | grep -v '^extern int isatty' > $@
+ cd $(builddir) && \
+ $(LEX) -o $@.$$$$ $(srcdir)/$$(basename $<) && \
+ sed -e 's/for ( i = 0; i < _yybytes_len; ++i )$$/for ( i = 0; (yy_size_t)i < (yy_size_t)_yybytes_len; ++i )/' \
+ -e '/^extern int isatty.*$$/d' $@.$$$$ >SEDTMP$$$$ && \
+ rm $@.$$$$ && \
+ mv SEDTMP$$$$ $@
# Use wild card rule so that GNU Make knows that both are output from
# a single recipe.
# - sed command for workaround for older bison vs GCC warning
# - avoid sed -i which somehow causes unwritable files
# on fedora 20 with 9p filesystem mount
+# - avoid creating the target file until it is done
%.tab.h %.tab.c: %.y
cd $(builddir) && \
- $(BISON) ${BISONOSFLAGS} -v -d $(srcdir)/$$(basename $<) && \
+ $(BISON) ${BISONOSFLAGS} -v --defines=$$(basename $< .y).tab.h -o $$(basename $< .y).tab.c$$$$ $(srcdir)/$$(basename $<) && \
sed -e '/^ *#/s/if YYENABLE_NLS/if defined(YYENABLE_NLS) \&\& YYENABLE_NLS/' \
-e '/^ *#/s/if YYLTYPE_IS_TRIVIAL/if defined(YYLTYPE_IS_TRIVIAL) \&\& YYLTYPE_IS_TRIVIAL/' \
- $$(basename $< .y).tab.c >SEDTMP$$$$ && \
+ $$(basename $< .y).tab.c$$$$ >SEDTMP$$$$ && \
+ rm $$(basename $< .y).tab.c$$$$ && \
mv SEDTMP$$$$ $$(basename $< .y).tab.c
clean: parser-clean
diff -Naur libreswan-3.15-orig/lib/libipsecconf/parser.l libreswan-3.15/lib/libipsecconf/parser.l
--- libreswan-3.15-orig/lib/libipsecconf/parser.l 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/lib/libipsecconf/parser.l 2015-09-03 11:42:22.942000000 -0400
@@ -373,7 +373,17 @@
<INITIAL,USERDEF>[0-9]+ {
/* process a number */
- yylval.num = strtoul(yytext, NULL, 10);
+ unsigned long val = (errno = 0, strtoul(yytext, NULL, 10));
+
+ if (errno != 0 || val > UINT_MAX) {
+ char ebuf[128];
+
+ snprintf(ebuf, sizeof(ebuf),
+ "number too large: %s",
+ yytext);
+ yyerror(ebuf);
+ }
+ yylval.num = val;
BEGIN INITIAL;
return INTEGER;
}
diff -Naur libreswan-3.15-orig/lib/libipsecconf/parser.y libreswan-3.15/lib/libipsecconf/parser.y
--- libreswan-3.15-orig/lib/libipsecconf/parser.y 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/lib/libipsecconf/parser.y 2015-09-03 11:42:22.942000000 -0400
@@ -26,7 +26,7 @@
#include <assert.h>
#include <limits.h>
#include <unistd.h>
-
+#include <errno.h>
#define YYDEBUG 1
#include "ipsecconf/keywords.h"
@@ -41,16 +41,15 @@
* Bison
*/
static char parser_errstring[ERRSTRING_LEN+1];
-static struct kw_list *alloc_kwlist(void);
-static struct starter_comments *alloc_comment(void);
/**
* Static Globals
*/
-static int _save_errors_;
-static struct config_parsed *_parser_cfg;
-static struct kw_list **_parser_kw, *_parser_kw_last;
-static struct starter_comments_list *_parser_comments;
+static bool save_errors;
+static struct config_parsed *parser_cfg;
+static struct kw_list **parser_kw, *parser_kw_last;
+static void new_parser_kw(struct keyword *keyword, char *string, unsigned int number); /* forward */
+static struct starter_comments_list *parser_comments;
/**
* Functions
@@ -60,7 +59,7 @@
%union {
char *s;
- unsigned int num;
+ unsigned int num;
struct keyword k;
}
%token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN INCLUDE VERSION
@@ -72,6 +71,8 @@
%token <k> BOOLWORD
%token <k> PERCENTWORD
%token <k> COMMENT
+
+%type <num> duration
%%
/*
@@ -84,8 +85,8 @@
/* we have configs shipped with version 2 (INTEGER) and with version 2.0 (STRING, now NUMBER/float was removed */
versionstmt: /* NULL */
- | VERSION STRING EOL blanklines
- | VERSION INTEGER EOL blanklines
+ | VERSION STRING EOL blanklines
+ | VERSION INTEGER EOL blanklines
;
blanklines: /* NULL */
@@ -98,40 +99,40 @@
section_or_include:
CONFIG SETUP EOL {
- _parser_kw = &(_parser_cfg->config_setup);
- _parser_kw_last = NULL;
- _parser_comments = &_parser_cfg->comments;
+ parser_kw = &parser_cfg->config_setup;
+ parser_kw_last = NULL;
+ parser_comments = &parser_cfg->comments;
if (yydebug)
fprintf(stderr, "\nconfig setup read\n");
} kw_sections
| CONN STRING EOL {
- struct section_list *section;
- section = (struct section_list *)malloc(sizeof(struct section_list));
- if (section != NULL) {
+ struct section_list *section = malloc(sizeof(struct section_list));
+
+ if (section == NULL) {
+ parser_kw = NULL;
+ parser_kw_last = NULL;
+ yyerror("can't allocate memory in section_or_include/conn");
+ } else {
section->name = $2;
section->kw = NULL;
- TAILQ_INSERT_TAIL(&_parser_cfg->sections, section, link);
+ TAILQ_INSERT_TAIL(&parser_cfg->sections, section, link);
- /* setup keyword section to record values */
- _parser_kw = &(section->kw);
- _parser_kw_last = NULL;
+ /* setup keyword section to record values */
+ parser_kw = §ion->kw;
+ parser_kw_last = NULL;
/* and comments */
TAILQ_INIT(§ion->comments);
- _parser_comments = §ion->comments;
+ parser_comments = §ion->comments;
- if(yydebug)
+ if (yydebug)
fprintf(stderr, "\nread conn %s\n", section->name);
- } else {
- _parser_kw = NULL;
- _parser_kw_last = NULL;
- yyerror("can't allocate memory in section_or_include/conn");
}
} kw_sections
| INCLUDE STRING EOL {
- parser_y_include($2);
+ parser_y_include($2);
}
;
@@ -144,198 +145,174 @@
statement_kw:
KEYWORD EQUAL KEYWORD {
- struct kw_list *new;
+ struct keyword kw = $1;
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- struct keyword kw;
- /* because the third argument was also a keyword, we dig up the string representation. */
- const char *value = $3.keydef->keyname;
-
- kw = $1;
- new->keyword = kw;
-
- switch(kw.keydef->type) {
- case kt_list:
- new->number = parser_enum_list(kw.keydef, value, TRUE);
- break;
- case kt_enum:
- new->number = parser_enum_list(kw.keydef, value, FALSE);
- break;
- case kt_rsakey:
- case kt_loose_enum:
- new->number = parser_loose_enum(&new->keyword, value);
- break;
- case kt_string:
- case kt_appendstring:
- case kt_appendlist:
- case kt_filename:
- case kt_dirname:
- case kt_ipaddr:
- case kt_bitstring:
- case kt_idtype:
- case kt_range:
- case kt_subnet:
- new->string = strdup(value);
- break;
-
- case kt_bool:
- case kt_invertbool:
- case kt_number:
- case kt_time:
- case kt_percent:
+ /* because the third argument was also a keyword, we dig up the string representation. */
+ const char *value = $3.keydef->keyname;
+
+ char *string = NULL; /* neutral placeholding value */
+ unsigned int number = 0; /* neutral placeholding value */
+
+ switch(kw.keydef->type) {
+ case kt_list:
+ number = parser_enum_list(kw.keydef, value, TRUE);
+ break;
+ case kt_enum:
+ number = parser_enum_list(kw.keydef, value, FALSE);
+ break;
+ case kt_rsakey:
+ case kt_loose_enum:
+ number = parser_loose_enum(&kw, value);
+ break;
+ case kt_string:
+ case kt_appendstring:
+ case kt_appendlist:
+ case kt_filename:
+ case kt_dirname:
+ case kt_ipaddr:
+ case kt_bitstring:
+ case kt_idtype:
+ case kt_range:
+ case kt_subnet:
+ string = strdup(value);
+ break;
+
+ case kt_bool:
+ case kt_invertbool:
+ case kt_number:
+ case kt_time:
+ case kt_percent:
yyerror("keyword value is a keyword, but type not a string");
assert(kw.keydef->type != kt_bool);
break;
- case kt_comment:
- break;
+ case kt_comment:
+ break;
- case kt_obsolete:
- case kt_obsolete_quiet:
- break;
- }
- new->next = NULL;
-
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (*_parser_kw == NULL)
- *_parser_kw = new;
+ case kt_obsolete:
+ case kt_obsolete_quiet:
+ break;
}
+
+ new_parser_kw(&kw, string, number);
}
| COMMENT EQUAL STRING {
- struct starter_comments *new;
+ struct starter_comments *new =
+ malloc(sizeof(struct starter_comments));
- new = alloc_comment();
if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
+ yyerror("can't allocate memory in statement_kw");
} else {
- new->x_comment = strdup($1.string);
- new->commentvalue = strdup($3);
- TAILQ_INSERT_TAIL(_parser_comments, new, link);
+ new->x_comment = strdup($1.string);
+ new->commentvalue = strdup($3);
+ TAILQ_INSERT_TAIL(parser_comments, new, link);
}
}
| KEYWORD EQUAL STRING {
- struct kw_list *new;
+ struct keyword kw = $1;
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- struct keyword kw;
+ char *string = NULL; /* neutral placeholding value */
+ unsigned int number = 0; /* neutral placeholding value */
- kw = $1;
- new->keyword = kw;
+ switch(kw.keydef->type) {
+ case kt_list:
+ number = parser_enum_list(kw.keydef, $3, TRUE);
+ break;
+ case kt_enum:
+ number = parser_enum_list(kw.keydef, $3, FALSE);
+ break;
+ case kt_rsakey:
+ case kt_loose_enum:
+ number = parser_loose_enum(&kw, $3);
+ break;
+ case kt_string:
+ case kt_appendstring:
+ case kt_appendlist:
+ case kt_filename:
+ case kt_dirname:
+ case kt_ipaddr:
+ case kt_bitstring:
+ case kt_idtype:
+ case kt_range:
+ case kt_subnet:
+ string = $3;
+ break;
- switch(kw.keydef->type) {
- case kt_list:
- new->number = parser_enum_list(kw.keydef, $3, TRUE);
- break;
- case kt_enum:
- new->number = parser_enum_list(kw.keydef, $3, FALSE);
- break;
- case kt_rsakey:
- case kt_loose_enum:
- new->number = parser_loose_enum(&new->keyword, $3);
- break;
- case kt_string:
- case kt_appendstring:
- case kt_appendlist:
- case kt_filename:
- case kt_dirname:
- case kt_ipaddr:
- case kt_bitstring:
- case kt_idtype:
- case kt_range:
- case kt_subnet:
- new->string = $3;
- break;
-
- case kt_bool:
- case kt_invertbool:
- case kt_number:
- case kt_time:
- case kt_percent:
+ case kt_bool:
+ case kt_invertbool:
+ case kt_number:
+ case kt_time:
+ case kt_percent:
yyerror("valid keyword, but value is not a number");
- assert(!(kw.keydef->type == kt_bool));
+ assert(kw.keydef->type != kt_bool);
+ break;
+ case kt_comment:
+ break;
+ case kt_obsolete:
+ case kt_obsolete_quiet:
break;
- case kt_comment:
- break;
- case kt_obsolete:
- case kt_obsolete_quiet:
- break;
- }
- new->next = NULL;
-
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw) *_parser_kw = new;
}
+
+ new_parser_kw(&kw, string, number);
}
| BOOLWORD EQUAL BOOL {
- struct kw_list *new;
-
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- new->keyword = $1;
- new->number = $<num>3; /* Should not be necessary! */
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw) *_parser_kw = new;
- }
+ new_parser_kw(&$1, NULL, $<num>3);
}
| KEYWORD EQUAL INTEGER {
- struct kw_list *new;
-
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- new->keyword = $1;
- new->number = $<num>3; /* Should not be necessary! */
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw) *_parser_kw = new;
- }
+ new_parser_kw(&$1, NULL, $<num>3);
}
- | TIMEWORD EQUAL STRING {
- struct kw_list *new;
- char *endptr, *str;
- unsigned int val;
+ | TIMEWORD EQUAL duration {
+ new_parser_kw(&$1, NULL, $3);
+ }
+ | PERCENTWORD EQUAL STRING {
struct keyword kw = $1;
- bool fail;
- char buf[80];
-
-
- fail = FALSE;
-
- str = $3;
-
- val = strtoul(str, &endptr, 10);
-
- if(endptr == str) {
- snprintf(buf, sizeof(buf), "bad duration value %s=%s", kw.keydef->keyname, str);
- yyerror(buf);
- fail = TRUE;
+ const char *const str = $3;
+ /*const*/ char *endptr;
+ char buf[80];
+ unsigned long val = (errno = 0, strtoul(str, &endptr, 10));
+
+ if (endptr == str) {
+ snprintf(buf, sizeof(buf),
+ "malformed percentage %s=%s",
+ kw.keydef->keyname, str);
+ yyerror(buf);
+ } else if (*endptr != '%' || endptr[1] != '\0') {
+ snprintf(buf, sizeof(buf),
+ "bad percentage multiplier \"%s\" on %s",
+ endptr, str);
+ yyerror(buf);
+ } else if (errno != 0 || val > UINT_MAX) {
+ snprintf(buf, sizeof(buf),
+ "percentage way too large \"%s\"", str);
+ yyerror(buf);
+ } else {
+ new_parser_kw(&kw, NULL, (unsigned int)val);
}
+ }
+ | KEYWORD EQUAL BOOL {
+ new_parser_kw(&$1, NULL, $<num>3);
+ }
+ | KEYWORD EQUAL { /* this is meaningless, we ignore it */ }
+ ;
- if(!fail)
- {
+duration:
+ INTEGER {
+ $$ = $1;
+ }
+ | STRING {
+ const char *const str = $1;
+ /*const*/ char *endptr;
+ char buf[80];
+
+ unsigned long val = (errno = 0, strtoul(str, &endptr, 10));
+ int strtoul_errno = errno;
+
+ if (endptr == str) {
+ snprintf(buf, sizeof(buf), "bad duration value \"%s\"", str);
+ yyerror(buf);
+ } else {
+ bool bad_suffix = FALSE;
unsigned scale;
if (*endptr == '\0') {
@@ -350,194 +327,87 @@
case 'd': scale = secs_per_day; break;
case 'w': scale = 7*secs_per_day; break;
default:
- snprintf(buf, sizeof(buf),
- "bad duration multiplier '%c' on %s",
- *endptr, str);
- yyerror(buf);
- fail=TRUE;
+ bad_suffix = TRUE;
}
} else {
+ bad_suffix = TRUE;
+ }
+
+ if (bad_suffix) {
snprintf(buf, sizeof(buf),
"bad duration multiplier \"%s\" on %s",
endptr, str);
yyerror(buf);
- fail=TRUE;
- }
-
- if (!fail) {
- if (UINT_MAX / scale < val) {
- snprintf(buf, sizeof(buf),
- "overflow scaling %s",
- str);
- yyerror(buf);
- fail=TRUE;
- } else {
- val *= scale;
- }
+ } else if (strtoul_errno != 0 || UINT_MAX / scale < val) {
+ snprintf(buf, sizeof(buf),
+ "duration too large: \"%s\" is more than %u seconds",
+ str, UINT_MAX);
+ yyerror(buf);
+ } else {
+ $$ = val * scale;
}
- }
-
- if(!fail)
- {
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- new->keyword = $1;
- new->number = val;
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (*_parser_kw == NULL)
- *_parser_kw = new;
- }
- }
- }
- | PERCENTWORD EQUAL STRING {
- struct kw_list *new;
- char *endptr, *str;
- struct keyword kw = $1;
- unsigned int val;
- bool fail;
- char buf[80];
-
-
- fail = FALSE;
-
- str = $3;
-
- val = strtoul(str, &endptr, 10);
-
- if(endptr == str) {
- snprintf(buf, sizeof(buf), "bad percent value %s=%s", kw.keydef->keyname, str);
- yyerror(buf);
- fail = TRUE;
-
- }
-
- if(!fail)
- {
- if ((*endptr == '%') && (endptr[1] == '\0')) { }
- else {
- snprintf(buf, sizeof(buf), "bad percentage multiplier '%c' on %s", *endptr, str);
- yyerror(buf);
- fail=TRUE;
- }
- }
-
- if(!fail)
- {
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new == NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- new->keyword = $1;
- new->number = val;
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (*_parser_kw == NULL)
- *_parser_kw = new;
- }
- }
- }
- | KEYWORD EQUAL BOOL {
- struct kw_list *new;
-
- assert(_parser_kw != NULL);
- new = alloc_kwlist();
- if (new != NULL) {
- yyerror("can't allocate memory in statement_kw");
- } else {
- new->keyword = $1;
- new->number = $<num>3; /* Should not be necessary! */
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (*_parser_kw == NULL)
- *_parser_kw = new;
}
- }
- | KEYWORD EQUAL { /* this is meaningless, we ignore it */ }
- ;
-
+ };
%%
void yyerror(const char *s)
{
- if (_save_errors_)
+ if (save_errors)
parser_y_error(parser_errstring, ERRSTRING_LEN, s);
}
struct config_parsed *parser_load_conf(const char *file, err_t *perr)
{
- struct config_parsed *cfg=NULL;
- int err = 0;
- FILE *f;
-
- zero(&parser_errstring);
+ parser_errstring[0] = '\0';
if (perr != NULL)
*perr = NULL;
- cfg = (struct config_parsed *)malloc(sizeof(struct config_parsed));
- if (cfg == NULL)
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
- err++;
- goto end;
+ struct config_parsed *cfg = malloc(sizeof(struct config_parsed));
+
+ if (cfg == NULL) {
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
+ goto err;
}
zero(cfg); /* ??? pointer fields may not be NULLed */
- if (strncmp(file, "-", sizeof("-")) == 0) {
- f = fdopen(STDIN_FILENO, "r");
- }
- else {
- f = fopen(file, "r");
- }
- if (!f)
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'",
- file);
- err++;
- goto end;
+
+ FILE *f = streq(file, "-") ?
+ fdopen(STDIN_FILENO, "r") : fopen(file, "r");
+
+ if (f == NULL) {
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'",
+ file);
+ goto err;
}
yyin = f;
parser_y_init(file, f);
- _save_errors_=1;
+ save_errors = TRUE;
TAILQ_INIT(&cfg->sections);
TAILQ_INIT(&cfg->comments);
- _parser_cfg = cfg;
+ parser_cfg = cfg;
- if (yyparse()!=0) {
- if (parser_errstring[0]=='\0') {
- snprintf(parser_errstring, ERRSTRING_LEN,
- "Unknown error...");
- }
- _save_errors_=0;
- while (yyparse()!=0);
- err++;
- goto end;
- }
- if (parser_errstring[0]!='\0') {
- err++;
- goto end;
- }
- /**
- * Config valid
- */
-end:
- if (err) {
- if (perr) *perr = (err_t)strdup(parser_errstring);
- if (cfg) parser_free_conf (cfg);
- cfg = NULL;
+ if (yyparse() != 0) {
+ if (parser_errstring[0] == '\0') {
+ snprintf(parser_errstring, ERRSTRING_LEN,
+ "Unknown error...");
+ }
+ save_errors = FALSE;
+ do {} while (yyparse() != 0);
+ } else if (parser_errstring[0] == '\0') {
+ /**
+ * Config valid
+ */
+ return cfg;
}
+ /* falls through on error */
+
+err:
+ if (perr != NULL)
+ *perr = (err_t)strdup(parser_errstring);
+ if (cfg != NULL)
+ parser_free_conf(cfg);
- return cfg;
+ return NULL;
}
static void parser_free_kwlist(struct kw_list *list)
@@ -546,7 +416,7 @@
struct kw_list *elt = list;
list = list->next;
- if (elt->string)
+ if (elt->string != NULL)
free(elt->string);
free(elt);
}
@@ -554,16 +424,18 @@
void parser_free_conf(struct config_parsed *cfg)
{
- struct section_list *seci, *sec;
- if (cfg) {
+ if (cfg != NULL) {
+ struct section_list *seci;
+
parser_free_kwlist(cfg->config_setup);
- for(seci = cfg->sections.tqh_first; seci != NULL; )
- {
- sec = seci;
+ for (seci = cfg->sections.tqh_first; seci != NULL; ) {
+ struct section_list *sec = seci;
+
seci = seci->link.tqe_next;
- if (sec->name) free(sec->name);
+ if (sec->name != NULL)
+ free(sec->name);
parser_free_kwlist(sec->kw);
free(sec);
}
@@ -572,20 +444,32 @@
}
}
-static struct kw_list *alloc_kwlist(void)
+static void new_parser_kw(struct keyword *keyword, char *string, unsigned int number)
{
- struct kw_list *new;
-
- new = (struct kw_list *)malloc(sizeof(struct kw_list));
- zero(new); /* ??? pointer members might not be set to NULL */
- return new;
-}
+ struct kw_list *new = malloc(sizeof(struct kw_list));
-static struct starter_comments *alloc_comment(void)
-{
- struct starter_comments *new;
+ if (new == NULL) {
+ yyerror("cannot allocate memory for a kw_list");
+ } else {
+ /*
+ * fill the values into new
+ * (either string or number might have a placeholder value
+ */
+ new->keyword = *keyword;
+ new->string = string;
+ new->number = number;
+ new->next = NULL;
+
+ /* link the new kw_list into the list */
+
+ if (*parser_kw == NULL)
+ *parser_kw = new; /* first in (some) list */
+
+ /* connect to previous last on list */
+ if (parser_kw_last != NULL)
+ parser_kw_last->next = new;
- new = (struct starter_comments *)malloc(sizeof(struct starter_comments));
- zero(new); /* ??? pointer members might not be set to NULL */
- return new;
+ /* new is new last on list */
+ parser_kw_last = new;
+ }
}