diff -Naur busybox.orig/networking/httpd.c busybox/networking/httpd.c
--- busybox.orig/networking/httpd.c	2008-09-04 19:43:36 +0000
+++ busybox/networking/httpd.c	2008-10-04 12:48:59 +0000
@@ -482,7 +482,8 @@
 #define FIND_FROM_HTTPD_ROOT 3
 static void parse_conf(const char *path, int flag)
 {
-	FILE *f;
+	parser_t *parser;
+	char *token[3];
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
 	Htaccess *prev;
 #endif
@@ -492,9 +493,7 @@
 	Htaccess *cur;
 #endif
 	const char *filename = configFile;
-	char buf[160];
 	char *p, *p0;
-	char *after_colon;
 	Htaccess_IP *pip;
 
 	/* discard old rules */
@@ -522,7 +521,7 @@
 		sprintf((char *)filename, "%s/%s", path, httpd_conf);
 	}
 
-	while ((f = fopen_for_read(filename)) == NULL) {
+	while ((parser = config_open2(filename, fopen_for_read)) == NULL) {
 		if (flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) {
 			/* config file not found, no changes to config */
 			return;
@@ -537,24 +536,13 @@
 	prev = g_auth;
 #endif
 	/* This could stand some work */
-	while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) {
-		after_colon = NULL;
-		for (p = p0; *p0 != '\0' && *p0 != '#'; p0++) {
-			if (!isspace(*p0)) {
-				*p++ = *p0;
-				if (*p0 == ':' && after_colon == NULL)
-					after_colon = p;
-			}
-		}
-		*p = '\0';
+	while (config_read(parser, token, 3, 2, "#:", PARSE_NORMAL | PARSE_KEEP_COPY)) {
+		p0 = token[0];
 
-		/* test for empty or strange line */
-		if (after_colon == NULL || *after_colon == '\0')
-			continue;
-		p0 = buf;
+		// [adAD]:from # ip address allow/deny, * for wildcard
 		if (*p0 == 'd' || *p0 == 'a')
 			*p0 -= 0x20; /* a/d -> A/D */
-		if (*after_colon == '*') {
+		if (*token[1] == '*') {
 			if (*p0 == 'D') {
 				/* memorize "deny all" */
 				flg_deny_all = 1;
@@ -566,7 +554,7 @@
 		if (*p0 == 'A' || *p0 == 'D') {
 			/* storing current config IP line */
 			pip = xzalloc(sizeof(Htaccess_IP));
-			if (scan_ip_mask(after_colon, &(pip->ip), &(pip->mask))) {
+			if (scan_ip_mask(token[1], &(pip->ip), &(pip->mask))) {
 				/* IP{/mask} syntax error detected, protect all */
 				*p0 = 'D';
 				pip->mask = 0;
@@ -591,20 +579,22 @@
 		}
 
 #if ENABLE_FEATURE_HTTPD_ERROR_PAGES
+		// Ennn:error.html  # error page for status nnn
 		if (flag == FIRST_PARSE && *p0 == 'E') {
 			unsigned i;
 			int status = atoi(++p0); /* error status code */
 			if (status < HTTP_CONTINUE) {
-				bb_error_msg("config error '%s' in '%s'", buf, filename);
+				// N.B. May be better to report the erroneous line?
+				bb_error_msg("config error '%s' in '%s'", parser->data, filename);
 				continue;
 			}
 			/* then error page; find matching status */
 			for (i = 0; i < ARRAY_SIZE(http_response_type); i++) {
 				if (http_response_type[i] == status) {
 					/* We chdir to home_httpd, thus no need to
-					 * concat_path_file(home_httpd, after_colon)
+					 * concat_path_file(home_httpd, token[1])
 					 * here */
-					http_error_page[i] = xstrdup(after_colon);
+					http_error_page[i] = xstrdup(token[1]);
 					break;
 				}
 			}
@@ -613,29 +603,26 @@
 #endif
 
 #if ENABLE_FEATURE_HTTPD_PROXY
+		// P:/url:[http://]hostname[:port]/new/path # reverse proxy
 		if (flag == FIRST_PARSE && *p0 == 'P') {
-			/* P:/url:[http://]hostname[:port]/new/path */
 			char *url_from, *host_port, *url_to;
 			Htaccess_Proxy *proxy_entry;
 
-			url_from = after_colon;
-			host_port = strchr(after_colon, ':');
-			if (host_port == NULL) {
-				bb_error_msg("config error '%s' in '%s'", buf, filename);
+			url_from = token[1];
+			host_port = token[2];
+			if (!host_port) {
+ conferr:
+				// N.B. May be better to report the erroneous line?
+				bb_error_msg("config error '%s' in '%s'", parser->data, filename);
 				continue;
 			}
-			*host_port++ = '\0';
 			if (strncmp(host_port, "http://", 7) == 0)
 				host_port += 7;
-			if (*host_port == '\0') {
-				bb_error_msg("config error '%s' in '%s'", buf, filename);
-				continue;
-			}
+			if (*host_port == '\0')
+				goto conferr;
 			url_to = strchr(host_port, '/');
-			if (url_to == NULL) {
-				bb_error_msg("config error '%s' in '%s'", buf, filename);
-				continue;
-			}
+			if (url_to == NULL)
+				goto conferr;
 			*url_to = '\0';
 			proxy_entry = xzalloc(sizeof(Htaccess_Proxy));
 			proxy_entry->url_from = xstrdup(url_from);
@@ -649,12 +636,13 @@
 #endif
 
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
+		// /cgi-bin:foo:bar  # Require user foo, pwd bar on urls starting with /cgi-bin/
 		if (*p0 == '/') {
 			/* make full path from httpd root / current_path / config_line_path */
 			const char *tp = (flag == SUBDIR_PARSE ? path : "");
-			p0 = xmalloc(strlen(tp) + (after_colon - buf) + 2 + strlen(after_colon));
-			after_colon[-1] = '\0';
-			sprintf(p0, "/%s%s", tp, buf);
+			// concat_path_file instead?
+			p0 = xmalloc(strlen(tp) + 2 + strlen(token[0]));
+			sprintf(p0, "/%s%s", tp, token[0]);
 
 			/* looks like bb_simplify_path... */
 			tp = p = p0;
@@ -683,18 +671,16 @@
 			if ((p == p0) || (*p != '/')) { /* not a trailing slash */
 				++p;                    /* so keep last character */
 			}
-			*p = ':';
-			strcpy(p + 1, after_colon);
 		}
 #endif
 		if (*p0 == 'I') {
-			index_page = xstrdup(after_colon);
+			index_page = xstrdup(token[1]);
 			continue;
 		}
 
 		/* Do not allow jumping around using H in subdir's configs */
 		if (flag == FIRST_PARSE && *p0 == 'H') {
-			home_httpd = xstrdup(after_colon);
+			home_httpd = xstrdup(token[1]);
 			xchdir(home_httpd);
 			continue;
 		}
@@ -709,8 +695,7 @@
 		if (*p0 == '/') /* was malloced - see above */
 			free(p0);
 #endif
-		cur->after_colon = strchr(cur->before_colon, ':');
-		*cur->after_colon++ = '\0';
+		cur->after_colon = xstrdup(token[1]);
 #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES
 		if (cur->before_colon[0] == '.') {
 			/* .mime line: prepend to mime_a list */
@@ -761,8 +746,8 @@
 		}
 #endif /* BASIC_AUTH */
 #endif /* BASIC_AUTH || MIME_TYPES || SCRIPT_INTERPR */
-	 } /* while (fgets) */
-	 fclose(f);
+	} /* while (config_read) */
+	config_close(parser);
 }
 
 #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
