config: Allow NULL for internal dict pointer

If the default configuration file is not present, behave as if it
were empty. This allows obmc-console-server to not fail out if no
configuration is provided, but still fail out if a struct config object
couldn't be allocated.

Change-Id: Ic188281f5fc41d94b3175c8009c97f1efb62699a
Fixes: 1e04f449b7f0 ("use iniparser dependency for config file parsing")
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/config.c b/config.c
index 121425f..15c08bc 100644
--- a/config.c
+++ b/config.c
@@ -41,10 +41,14 @@
 
 const char *config_get_value(struct config *config, const char *name)
 {
-	int rc;
 	char buf[CONFIG_MAX_KEY_LENGTH];
-	rc = snprintf(buf, CONFIG_MAX_KEY_LENGTH, ":%s", name);
+	int rc;
 
+	if (!config->dict) {
+		return NULL;
+	}
+
+	rc = snprintf(buf, CONFIG_MAX_KEY_LENGTH, ":%s", name);
 	if (rc < 0) {
 		return NULL;
 	}
@@ -54,7 +58,6 @@
 	}
 
 	const char *value = iniparser_getstring(config->dict, buf, NULL);
-
 	if (value && strlen(value) == 0) {
 		return NULL;
 	}
@@ -65,30 +68,45 @@
 struct config *config_init(const char *filename)
 {
 	struct config *config;
-	int fd;
+	dictionary *dict;
 
 	if (!filename) {
 		filename = config_default_filename;
 	}
 
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		warn("Can't open configuration file %s", filename);
-		return NULL;
-	}
-	close(fd);
+	if (access(filename, R_OK) == 0) {
+		dict = iniparser_load(filename);
+		if (!dict) {
+			/* Assume this is a parse failure */
+			return NULL;
+		}
+	} else {
+		/* If a config file was explicitly specified, then lack of access is always an error */
+		if (filename != config_default_filename) {
+			warn("Failed to open configuration file at '%s'",
+			     filename);
+			return NULL;
+		}
 
-	dictionary *dict = iniparser_load(filename);
+		/* For the default config path, any result other than not-present is an error */
+		if (errno != ENOENT && errno != ENOTDIR) {
+			warn("Failed to open configuration file at '%s'",
+			     filename);
+			return NULL;
+		}
 
-	if (dict == NULL) {
-		return NULL;
+		/* Config not present at default path, pretend its empty */
+		dict = NULL;
 	}
 
 	config = malloc(sizeof(*config));
-	if (config) {
-		config->dict = dict;
+	if (!config) {
+		iniparser_freedict(dict);
+		return NULL;
 	}
 
+	config->dict = dict;
+
 	return config;
 }