diff -Naur busybox.orig/include/libbb.h busybox/include/libbb.h
--- busybox.orig/include/libbb.h	2008-07-06 09:04:14 +0000
+++ busybox/include/libbb.h	2008-07-07 22:52:04 +0000
@@ -974,6 +974,7 @@
 int bb_ask_confirmation(void) FAST_FUNC;
 
 extern int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
+extern char **parse_config(const char *filename, int ntokens, void **data) FAST_FUNC;
 
 /* Concatenate path and filename to new allocated buffer.
  * Add "/" only as needed (no duplicate "//" are produced).
diff -Naur busybox.orig/libbb/Kbuild busybox/libbb/Kbuild
--- busybox.orig/libbb/Kbuild	2008-07-01 20:50:48 +0000
+++ busybox/libbb/Kbuild	2008-07-07 20:00:28 +0000
@@ -62,6 +62,7 @@
 lib-y += mtab_file.o
 lib-y += obscure.o
 lib-y += parse_mode.o
+lib-y += parse_config.o
 lib-y += perror_msg.o
 lib-y += perror_msg_and_die.o
 lib-y += perror_nomsg.o
diff -Naur busybox.orig/libbb/parse_config.c busybox/libbb/parse_config.c
--- busybox.orig/libbb/parse_config.c	1970-01-01 00:00:00 +0000
+++ busybox/libbb/parse_config.c	2008-07-07 23:27:40 +0000
@@ -0,0 +1,115 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * config file parser helper
+ *
+ * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+
+static void FAST_FUNC replace(char *s, char what, char with)
+{
+	while (*s) {
+		if (what == *s)
+			*s = with;
+		++s;
+	}
+}
+
+static char *next_field(char *s)
+{
+	// TODO: quoted tokens?
+	char *end = skip_non_whitespace(s);
+	s = skip_whitespace(end);
+	*end = '\0';
+	if (*s == '\0')
+		s = NULL;
+	return s;
+}
+
+/*
+
+Typical usage:
+
+----- CUT -----
+void *data;
+char **token = parse_config(filename, 128, &data); // 128 tokens at most
+
+while (*token) {
+	bb_error_msg("LINE---------");
+	while (*token) {
+		bb_error_msg("TOKEN [%s]", *token);
+		token++;
+	}
+	token++;
+}
+
+free(token);
+free(data);
+----- CUT -----
+
+*/
+
+// returns newly allocated array of tokens. MUST be freed by caller
+// N.B. array uses REFERENCES to, not copies of strings read to 'data' so free 'data' after all config is used
+char FAST_FUNC **parse_config(
+	const char *filename,	// name of config file to parse
+	int ntokens,		// required amount of tokens, remainder to be returned verbatim
+				// just set to big number
+	void **data		// OUT: config file image. MUST be freed by caller after config is used
+)
+{
+	char *line, *s, *p;
+
+	// empty array of tokens
+	//char **tokens = xzalloc(sizeof(char *));
+
+	// prepare room for 128 lines
+	// FIXME: realloc when pinning!
+	char **tokens = xzalloc(128 * sizeof(char *) *
+		(ntokens /* required tokens */ + 1 /* end-of-tokens-on-this-line marker*/));
+	char **token = tokens;
+
+	// empty file configures nothing!
+	*data = xmalloc_xopen_read_close(filename, NULL);
+	if (!*data)
+		return tokens;
+
+	// first convert 0x5c 0x0a (backslashes at the very end of line) to 0x20 0x20 (spaces)
+	for (s = *data; (s = strchr(s, '\\')) != NULL; ++s)
+		if ('\n' == s[1]) {
+			s[0] = s[1] = ' ';
+		}
+
+	// now split to lines
+	s = *data;
+	while (1) {
+		int token_num = 0;
+		line = strtok(s, "\n"); // N.B. s != NULL only the first time
+		if (!line)
+			break;
+		// comments mean EOLs
+		replace(line, '#', '\0');
+		// skip comments and empty lines
+		line = skip_whitespace(line);
+		if (!line)
+			continue;
+		// now split line to tokens
+		s = line;
+		while (s) {
+			// get next token
+			p = (++token_num < ntokens) ? next_field(s) : NULL;
+			// pin token
+			// FIXME: realloc!!!
+//bb_error_msg("L[%d:%d] T[%s]", line_num, token_num, s);
+			*token++ = s;
+			s = p;
+ 		}
+		token++; // xzmalloc guarantees NULL
+ 	}
+	//*token++ = NULL; // xzmalloc guarantees NULL
+
+	return tokens;
+}
