- fix segfault in nameif with mactab file
  (by fixing and shrink config parser)

function                                             old     new   delta
config_free_data                                       -      37     +37
config_open                                           43      48      +5
pack_gzip                                           1658    1660      +2
nameif_main                                          527     525      -2
SynchronizeFile                                      629     623      -6
make_device                                         1184    1176      -8
config_close                                          31      18     -13
config_read                                          431     393     -38
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/5 up/down: 44/-67)            Total: -23 bytes

diff --git a/libbb/parse_config.c b/libbb/parse_config.c
index f070992..70f933f 100644
--- a/libbb/parse_config.c
+++ b/libbb/parse_config.c
@@ -31,44 +31,42 @@
 
 */
 
-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 @@
 		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 @@
 		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 @@
 		// 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;
 }