From bd8dcb97354bc29050e5aefe957c651bf2fedd07 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 3 Apr 2012 01:27:27 +0200 Subject: Keep list of strings allocated by the lexer --- src/config.c | 11 ++++++++++- src/config.l | 14 +++++++------- src/config.y | 35 ++++++++++++++++------------------- src/fastd.h | 21 +++++++++++++++++++++ src/types.h | 2 ++ 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/config.c b/src/config.c index 964c2d6..7c1b62f 100644 --- a/src/config.c +++ b/src/config.c @@ -183,13 +183,22 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen else token = START_CONFIG; + fastd_config_str *strings = NULL; + while(fastd_config_push_parse(ps, token, &token_val, &loc, ctx, conf, filename, depth+1) == YYPUSH_MORE) { token = fastd_config_yylex(&token_val, &loc, scanner); if (token < 0) - exit_error(ctx, "config error: %s at %s:%i:%i", token_val.str, filename, loc.first_line, loc.first_column); + exit_error(ctx, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column); + + if (token == TOK_STRING) { + token_val.str->next = strings; + strings = token_val.str; + } } + fastd_config_str_free(strings); + fastd_config_pstate_delete(ps); fastd_config_yylex_destroy(scanner); diff --git a/src/config.l b/src/config.l index f2a9002..546bd8d 100644 --- a/src/config.l +++ b/src/config.l @@ -88,7 +88,7 @@ no { UPDATE_LOCATION; return TOK_NO; } UPDATE_LOCATION; if (!inet_pton(AF_INET, yytext, &yylval->addr)) { - yylval->str = "invalid address"; + yylval->error = "invalid address"; return -1; } @@ -116,7 +116,7 @@ no { UPDATE_LOCATION; return TOK_NO; } yytext[i-esc] = yytext[i]; } yytext[yyleng-esc-1] = 0; - yylval->str = strdup(yytext); + yylval->str = fastd_config_str_dup(yytext); BEGIN(INITIAL); yylloc->last_column++; return TOK_STRING; @@ -127,7 +127,7 @@ no { UPDATE_LOCATION; return TOK_NO; } [0-9a-fA-F:]+ { yylloc->last_column += yyleng; if (!inet_pton(AF_INET6, yytext, &yylval->addr6)) { - yylval->str = "invalid address"; + yylval->error = "invalid address"; return -1; } } @@ -144,12 +144,12 @@ no { UPDATE_LOCATION; return TOK_NO; } . { yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column+1; - yylval->str = "invalid character"; + yylval->error = "invalid character"; return -1; } <> { return 0; } -<> { yylval->str = "unterminated block comment"; return -1; } -<> { yylval->str = "unterminated string"; return -1; } -<> { yylval->str = "unterminated address"; return -1; } +<> { yylval->error = "unterminated block comment"; return -1; } +<> { yylval->error = "unterminated string"; return -1; } +<> { yylval->error = "unterminated address"; return -1; } %% diff --git a/src/config.y b/src/config.y index be30ab0..cbb58c7 100644 --- a/src/config.y +++ b/src/config.y @@ -43,7 +43,8 @@ %union { int num; - char* str; + fastd_config_str *str; + char *error; bool boolean; struct in_addr addr; struct in6_addr addr6; @@ -144,7 +145,7 @@ log_level: TOK_FATAL { conf->loglevel = LOG_FATAL; } | TOK_DEBUG { conf->loglevel = LOG_DEBUG; } ; -interface: TOK_STRING { free(conf->ifname); conf->ifname = $1; } +interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1->str); } ; bind: TOK_ADDR maybe_port { @@ -173,34 +174,32 @@ mode: TOK_TAP { conf->mode = MODE_TAP; } ; protocol: TOK_STRING { - if (!strcmp($1, "null")) + if (!strcmp($1->str, "null")) conf->protocol = &fastd_protocol_null; #ifdef WITH_PROTOCOL_ECFXP - else if (!strcmp($1, "ecfxp")) + else if (!strcmp($1->str, "ecfxp")) conf->protocol = &fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; #endif else - exit_error(ctx, "config error: invalid protocol `%s'", $1); - - free($1); + exit_error(ctx, "config error: invalid protocol `%s'", $1->str); } ; -secret: TOK_STRING { free(conf->secret); conf->secret = $1; } +secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); } ; on_up: TOK_STRING { free(conf->on_up); free(conf->on_up_dir); - conf->on_up = $1; + conf->on_up = strdup($1->str); conf->on_up_dir = get_current_dir_name(); } ; peer: maybe_string { fastd_peer_config_new(ctx, conf); - conf->peers->name = $1; + conf->peers->name = strdup($1->str); } ; @@ -225,10 +224,10 @@ peer_address: TOK_ADDR ':' port { } ; -peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = $1; } +peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = strdup($1->str); } ; -peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1, true, depth); free($1); } +peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1->str, true, depth); } ; @@ -238,16 +237,14 @@ peer_to_peer: boolean { conf->peer_to_peer = $1; } include: TOK_PEER TOK_STRING maybe_as { fastd_peer_config_new(ctx, conf); - conf->peers->name = $3; + conf->peers->name = strdup($3->str); - fastd_read_config(ctx, conf, $2, true, depth); - free($2); + fastd_read_config(ctx, conf, $2->str, true, depth); } | TOK_PEERS TOK_FROM TOK_STRING { - fastd_read_config_dir(ctx, conf, $3, depth); - free($3); + fastd_read_config_dir(ctx, conf, $3->str, depth); } - | TOK_STRING { fastd_read_config(ctx, conf, $1, false, depth); free($1); } + | TOK_STRING { fastd_read_config(ctx, conf, $1->str, false, depth); } ; @@ -269,7 +266,7 @@ boolean: TOK_YES { $$ = true; } port: TOK_INTEGER { if ($1 < 0 || $1 > 65635) - exit_error(ctx, "invalid port %i", $1); + exit_error(ctx, "config error: invalid port %i", $1); $$ = htons($1); } ; diff --git a/src/fastd.h b/src/fastd.h index 5e62fb0..f402be8 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -132,6 +132,11 @@ struct _fastd_context { unsigned int randseed; }; +struct _fastd_config_str { + fastd_config_str *next; + char str[]; +}; + void fastd_printf(const fastd_context *ctx, const char *format, ...); void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *dir, int depth); @@ -225,6 +230,22 @@ static inline size_t fastd_max_packet_size(const fastd_context *ctx) { } } +static inline fastd_config_str* fastd_config_str_dup(const char *str) { + fastd_config_str *ret = malloc(sizeof(fastd_config_str) + strlen(str) + 1); + ret->next = NULL; + strcpy(ret->str, str); + + return ret; +} + +static inline void fastd_config_str_free(fastd_config_str *str) { + while(str) { + fastd_config_str *next = str->next; + free(str); + str = next; + } +} + static inline bool timespec_after(const struct timespec *tp1, const struct timespec *tp2) { return (tp1->tv_sec > tp2->tv_sec || (tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec)); diff --git a/src/types.h b/src/types.h index 684fe4a..390b145 100644 --- a/src/types.h +++ b/src/types.h @@ -69,6 +69,8 @@ typedef struct _fastd_protocol fastd_protocol; typedef struct _fastd_handshake fastd_handshake; +typedef struct _fastd_config_str fastd_config_str; + /* May be defined by the protocol however it likes */ typedef struct _fastd_protocol_config fastd_protocol_config; typedef struct _fastd_protocol_peer_config fastd_protocol_peer_config; -- cgit v1.2.3