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 @@ [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 #include #include - +#include #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 BOOLWORD %token PERCENTWORD %token COMMENT + +%type 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 = $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, $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 = $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, $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, $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 = $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; + } }