diff --git a/sslh-conf.c b/sslh-conf.c
index df022e5..44ae20d 100644
--- a/sslh-conf.c
+++ b/sslh-conf.c
@@ -1,5 +1,5 @@
 /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct)
- * on Wed Nov 28 23:38:56 2018. */
+ * on Mon Dec  3 10:48:52 2018. */
 
 
 
@@ -169,7 +169,7 @@ static int config_listen_parser(
 	return 1;
 }
 
-int config_parser(
+static int config_parser(
         config_setting_t* cfg, 
         struct config_item* config, 
         const char** errmsg) 
@@ -293,6 +293,26 @@ int config_parser(
 	return 1;
 }
 
+/* Public parser API: returns 0 on failure, 1 on success */
+int config_parse_file(const char* filename, struct config_item* cfg, const char**errmsg)
+{
+    config_t c;
+
+    config_init(&c);
+    if (config_read_file(&c, filename) == CONFIG_FALSE) {
+        if (config_error_line(&c) != 0) {
+           asprintf(errmsg, "%s:%d:%s", 
+                    filename,
+                    config_error_line(&c),
+                    config_error_text(&c));
+           return 0;
+        }
+        asprintf(errmsg, "%s:%s", filename, config_error_text(&c));
+        return 0;
+    }
+    return config_parser(config_lookup(&c, "/"), cfg, errmsg);
+}
+
 static void indent(int depth) 
 {
     int i;
diff --git a/sslh-conf.h b/sslh-conf.h
index 8cf787a..28efd4b 100644
--- a/sslh-conf.h
+++ b/sslh-conf.h
@@ -1,5 +1,5 @@
 /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct)
- * on Wed Nov 28 23:38:56 2018. */
+ * on Mon Dec  3 10:48:52 2018. */
 
  
 #ifndef C2S_CONFIG_H
@@ -26,11 +26,11 @@ struct config_protocols_item {
 	int	fork;
 	int	log_level;
 	int	keepalive;
-	int sni_hostnames_len;
+	size_t	sni_hostnames_len;
 	const char** sni_hostnames;
-	int alpn_protocols_len;
+	size_t	alpn_protocols_len;
 	const char** alpn_protocols;
-	int regex_patterns_len;
+	size_t	regex_patterns_len;
 	const char** regex_patterns;
 	T_PROBE*	probe;
 	struct addrinfo*	saddr;
@@ -52,14 +52,14 @@ struct config_item {
 	const char*	chroot;
 	const char*	syslog_facility;
 	const char*	on_timeout;
-	int listen_len;
+	size_t	listen_len;
 	struct config_listen_item* listen;
-	int protocols_len;
+	size_t	protocols_len;
 	struct config_protocols_item* protocols;
 };
 
-int config_parser(
-        config_setting_t* cfg, 
+int config_parse_file(
+        const char* filename,
         struct config_item* config, 
         const char** errmsg);
 
diff --git a/sslh-main.c b/sslh-main.c
index 9a8543e..80a2927 100644
--- a/sslh-main.c
+++ b/sslh-main.c
@@ -475,32 +475,13 @@ static int config_protocols(config_t *config, struct proto **prots)
 #ifdef LIBCONFIG
 static int config_parse(char *filename, struct addrinfo **listen, struct config_protocols_item **prots)
 {
-    config_t config;
     int res;
-    const char*err;
+    const char* err;
 
-    config_init(&config);
-    if (config_read_file(&config, filename) == CONFIG_FALSE) {
-        /* If it's a parse error then there will be a line number for the failure
-         * an I/O error (such as non-existent file) will have the error line as 0
-         */
-        if (config_error_line(&config) != 0) {
-            fprintf(stderr, "%s:%d:%s\n", 
-                    filename,
-                    config_error_line(&config),
-                    config_error_text(&config));
-            exit(1);
-        }
-        fprintf(stderr, "%s:%s\n", 
-                filename,
-                config_error_text(&config));
+    if (!config_parse_file(filename, &cfg, &err)) {
+        fprintf(stderr, err);
         return 1;
     }
-    res = config_parser(config_lookup(&config, "/"), &cfg, &err);
-    if (!res) {
-        fprintf(stderr, "%s\n", err);
-        exit(1);
-    }
 
     config_resolve_listen(listen);
     config_protocols();