- fix segfault in nameif with mactab file (by fixing and shrink config parser)
No binary (build failed)
—
(log yok)
| @@ -995,7 +995,7 @@ typedef struct parser_t { | |
| char *line, *data; | |
| int lineno; | |
| } parser_t; | |
| - | FILE* config_open(parser_t *parser, const char *filename) FAST_FUNC; |
| + | parser_t* config_open(const char *filename) FAST_FUNC; |
| /* TODO: add define magic to collapse ntokens/mintokens/comment into one int param */ | |
| int config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) FAST_FUNC; | |
| void config_close(parser_t *parser) FAST_FUNC; | |
| @@ -31,44 +31,42 @@ Typical usage: | |
| */ | |
| - | FILE* FAST_FUNC config_open(parser_t *parser, const char *filename) |
| + | parser_t* FAST_FUNC config_open(const char *filename) |
| { | |
| - | // empty file configures nothing! |
| + | parser_t *parser = xzalloc(sizeof(parser_t)); |
| + | /* empty file configures nothing */ |
| parser->fp = fopen_or_warn(filename, "r"); | |
| - | if (!parser->fp) |
| - | return parser->fp; |
| - | |
| - | // init parser |
| - | parser->line = NULL; |
| - | parser->lineno = 0; |
| - | |
| - | return parser->fp; |
| + | if (parser->fp) |
| + | return parser; |
| + | config_close (parser); |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | free(parser); |
| + | return NULL; |
| } | |
| - | void FAST_FUNC config_close(parser_t *parser) |
| + | static void config_free_data(parser_t *const parser) |
| { | |
| free(parser->line); | |
| free(parser->data); | |
| + | parser->line = parser->data = NULL; |
| + | } |
| + | void FAST_FUNC config_close(parser_t *parser) |
| + | { |
| + | config_free_data(parser); |
| fclose(parser->fp); | |
| } | |
| - | int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) |
| + | int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char*delims,char comment) |
| { | |
| char *line, *q; | |
| - | int token_num, len; |
| - | int noreduce = (ntokens < 0); // do not treat subsequent delimiters as one delimiter |
| - | |
| - | if (ntokens < 0) |
| + | int ii; |
| + | /* do not treat subsequent delimiters as one delimiter */ |
| + | bool noreduce = (ntokens < 0); |
| + | if (noreduce) |
| ntokens = -ntokens; | |
| - | // nullify tokens |
| memset(tokens, 0, sizeof(void *) * ntokens); | |
| - | |
| - | // free used line |
| - | free(parser->line); |
| - | parser->line = NULL; |
| - | free(parser->data); |
| - | parser->data = NULL; |
| + | config_free_data(parser); |
| while (1) { | |
| int n; | |
| @@ -82,13 +80,13 @@ int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mint | |
| parser->lineno++; | |
| // handle continuations. Tito's code stolen :) | |
| while (1) { | |
| - | len = strlen(line); |
| - | if (!len) |
| - | goto free_and_cont; |
| - | if (line[len - 1] != '\\') |
| + | ii = strlen(line); |
| + | if (!ii) |
| + | goto next_line; |
| + | if (line[ii - 1] != '\\') |
| break; | |
| // multi-line object | |
| - | line[--len] = '\0'; |
| + | line[--ii] = '\0'; |
| //TODO: add xmalloc_fgetline-like iface but with appending to existing str | |
| q = xmalloc_fgetline(parser->fp); | |
| if (q) { | |
| @@ -101,34 +99,35 @@ int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mint | |
| if (comment) { | |
| q = strchrnul(line, comment); | |
| *q = '\0'; | |
| - | len = q - line; |
| + | ii = q - line; |
| } | |
| // skip leading delimiters | |
| n = strspn(line, delims); | |
| if (n) { | |
| - | len -= n; |
| + | ii -= n; |
| strcpy(line, line + n); | |
| } | |
| - | if (len) |
| + | if (ii) |
| break; | |
| - | // skip empty lines |
| - | free_and_cont: |
| + | |
| + | next_line: |
| + | /* skip empty line */ |
| free(line); | |
| } | |
| // non-empty line found, parse and return | |
| // store line | |
| - | parser->line = line = xrealloc(line, len + 1); |
| + | parser->line = line = xrealloc(line, ii + 1); |
| parser->data = xstrdup(line); | |
| // now split line to tokens | |
| //TODO: discard consecutive delimiters? | |
| - | token_num = 0; |
| + | ii = 0; |
| ntokens--; // now it's max allowed token no | |
| while (1) { | |
| // get next token | |
| - | if (token_num == ntokens) |
| + | if (ii == ntokens) |
| break; | |
| q = line + strcspn(line, delims); | |
| if (!*q) | |
| @@ -136,20 +135,20 @@ int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mint | |
| // pin token | |
| *q++ = '\0'; | |
| if (noreduce || *line) { | |
| - | tokens[token_num++] = line; |
| - | //bb_error_msg("L[%d] T[%s]", token_num, line); |
| + | tokens[ii++] = line; |
| + | //bb_info_msg("L[%d] T[%s]\n", ii, line); |
| } | |
| line = q; | |
| - | } |
| + | } |
| // non-empty remainder is also a token, | |
| // so if ntokens <= 1, we just return the whole line | |
| if (noreduce || *line) | |
| - | tokens[token_num++] = line; |
| + | tokens[ii++] = line; |
| - | if (token_num < mintokens) |
| + | if (ii < mintokens) |
| bb_error_msg_and_die("bad line %u: %d tokens found, %d needed", | |
| - | parser->lineno, token_num, mintokens); |
| + | parser->lineno, ii, mintokens); |
| - | return token_num; |
| + | return ii; |
| } | |
| @@ -443,7 +443,7 @@ static void FixDayDow(CronLine *line) | |
| static void SynchronizeFile(const char *fileName) | |
| { | |
| - | struct parser_t parser; |
| + | struct parser_t *parser; |
| struct stat sbuf; | |
| int maxLines; | |
| char *tokens[6]; | |
| @@ -455,12 +455,13 @@ static void SynchronizeFile(const char *fileName) | |
| return; | |
| DeleteFile(fileName); | |
| - | if (!config_open(&parser, fileName)) |
| + | parser = config_open(fileName); |
| + | if (!parser) |
| return; | |
| maxLines = (strcmp(fileName, "root") == 0) ? 65535 : MAXLINES; | |
| - | if (fstat(fileno(parser.fp), &sbuf) == 0 && sbuf.st_uid == DaemonUid) { |
| + | if (fstat(fileno(parser->fp), &sbuf) == 0 && sbuf.st_uid == DaemonUid) { |
| CronFile *file = xzalloc(sizeof(CronFile)); | |
| CronLine **pline; | |
| int n; | |
| @@ -468,11 +469,11 @@ static void SynchronizeFile(const char *fileName) | |
| file->cf_User = xstrdup(fileName); | |
| pline = &file->cf_LineBase; | |
| - | while (--maxLines && (n=config_read(&parser, tokens, 6, 0, " \t", '#')) >= 0) { |
| + | while (--maxLines && (n=config_read(parser, tokens, 6, 0, " \t", '#')) >= 0) { |
| CronLine *line; | |
| if (DebugOpt) { | |
| - | crondlog(LVL5 "user:%s entry:%s", fileName, parser.data); |
| + | crondlog(LVL5 "user:%s entry:%s", fileName, parser->data); |
| } | |
| /* check if line is setting MAILTO= */ | |
| @@ -519,7 +520,7 @@ static void SynchronizeFile(const char *fileName) | |
| crondlog(WARN9 "user %s: too many lines", fileName); | |
| } | |
| } | |
| - | config_close(&parser); |
| + | config_close(parser); |
| } | |
| static void CheckUpdates(void) | |
| @@ -160,12 +160,12 @@ int nameif_main(int argc, char **argv) | |
| prepend_new_eth_table(&clist, ifname, *argv++); | |
| } | |
| } else { | |
| - | struct parser_t parser; |
| - | if (config_open(&parser, fname)) { |
| + | struct parser_t *parser = config_open(fname); |
| + | if (parser) { |
| char *tokens[2]; | |
| - | while (config_read(&parser, tokens, 2, 2, " \t", '#') >= 0) |
| + | while (config_read(parser, tokens, 2, 2, " \t", '#') >= 0) |
| prepend_new_eth_table(&clist, tokens[0], tokens[1]); | |
| - | config_close(&parser); |
| + | config_close(parser); |
| } | |
| } | |
| @@ -94,14 +94,14 @@ static void make_device(char *path, int delete) | |
| type = S_IFBLK; | |
| if (ENABLE_FEATURE_MDEV_CONF) { | |
| - | parser_t parser; |
| + | parser_t *parser = config_open("/etc/mdev.conf"); |
| char *tokens[5]; | |
| /* If we have config file, look up user settings */ | |
| - | if (!config_open(&parser, "/etc/mdev.conf")) |
| + | if (!parser) |
| goto end_parse; | |
| - | while (config_read(&parser, tokens, 4, 3, " \t", '#') >= 0) { |
| + | while (config_read(parser, tokens, 4, 3, " \t", '#') >= 0) { |
| regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; | |
| char *val; | |
| @@ -213,7 +213,7 @@ static void make_device(char *path, int delete) | |
| const char *s2 = strchr(s, *val); | |
| if (!s2) | |
| - | bb_error_msg_and_die("bad line %u", parser.lineno); |
| + | bb_error_msg_and_die("bad line %u", parser->lineno); |
| /* Correlate the position in the "@$*" with the delete | |
| * step so that we get the proper behavior: | |
| @@ -229,7 +229,7 @@ static void make_device(char *path, int delete) | |
| break; /* we found matching line, stop */ | |
| } /* end of "while line is read from /etc/mdev.conf" */ | |
| - | config_close(&parser); |
| + | config_close(parser); |
| } | |
| end_parse: | |