Browse Source

better config file handling

Felix Fietkau 16 years ago
parent
commit
f57d582f15
5 changed files with 33 additions and 11 deletions
  1. 2 2
      Makefile
  2. 2 1
      libuci.c
  3. 22 4
      parse.c
  4. 2 2
      test.c
  5. 5 2
      uci.h

+ 2 - 2
Makefile

@@ -5,8 +5,8 @@ all: parsetest
 parsetest: libuci.o test.o
 	$(CC) $(CFLAGS) -o $@ $^
 
-libuci.o: libuci.c parse.c libuci.h list.c err.h
-test.o: test.c libuci.h
+libuci.o: libuci.c parse.c uci.h list.c err.h
+test.o: test.c uci.h
 
 clean:
 	rm -f parsetest *.o

+ 2 - 1
libuci.c

@@ -21,7 +21,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include "libuci.h"
+#include "uci.h"
 
 #define DEBUG
 #include "err.h"
@@ -31,6 +31,7 @@ static const char *uci_errstr[] = {
 	[UCI_ERR_MEM] =      "Out of memory",
 	[UCI_ERR_INVAL] =    "Invalid argument",
 	[UCI_ERR_NOTFOUND] = "Entry not found",
+	[UCI_ERR_IO] =       "I/O error",
 	[UCI_ERR_PARSE] =    "Parse error",
 	[UCI_ERR_UNKNOWN] =  "Unknown error",
 };

+ 22 - 4
parse.c

@@ -16,6 +16,7 @@
  * This file contains the code for parsing uci config files
  */
 
+#include <sys/stat.h>
 #include <ctype.h>
 
 #define LINEBUF	128
@@ -267,9 +268,11 @@ static void uci_parse_line(struct uci_context *ctx)
 	}
 }
 
-int uci_parse(struct uci_context *ctx, const char *name)
+int uci_load(struct uci_context *ctx, const char *name)
 {
 	struct uci_parse_context *pctx;
+	struct stat statbuf;
+	char *filename;
 
 	UCI_HANDLE_ERR(ctx);
 	UCI_ASSERT(ctx, name != NULL);
@@ -280,11 +283,26 @@ int uci_parse(struct uci_context *ctx, const char *name)
 	pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context));
 	ctx->pctx = pctx;
 
-	/* TODO: use /etc/config/ */
-	pctx->file = fopen(name, "r");
-	if (!pctx->file)
+	switch (name[0]) {
+	case '.':
+	case '/':
+		/* absolute/relative path outside of /etc/config */
+		filename = (char *) name;
+		break;
+	default:
+		filename = uci_malloc(ctx, strlen(name) + sizeof(UCI_CONFDIR) + 2);
+		sprintf(filename, UCI_CONFDIR "/%s", name);
+		break;
+	}
+
+	if ((stat(filename, &statbuf) < 0) ||
+		((statbuf.st_mode &  S_IFMT) != S_IFREG))
 		UCI_THROW(ctx, UCI_ERR_NOTFOUND);
 
+	pctx->file = fopen(filename, "r");
+	if (!pctx->file)
+		UCI_THROW(ctx, UCI_ERR_IO);
+
 	pctx->cfg = uci_alloc_file(ctx, name);
 
 	while (!feof(pctx->file)) {

+ 2 - 2
test.c

@@ -10,7 +10,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include "libuci.h"
+#include "uci.h"
 
 int main(int argc, char **argv)
 {
@@ -21,7 +21,7 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	if (uci_parse(ctx, argv[1])) {
+	if (uci_load(ctx, argv[1])) {
 		uci_perror(ctx, "uci_parse");
 		return 1;
 	}

+ 5 - 2
libuci.h → uci.h

@@ -18,12 +18,15 @@
 #include <setjmp.h>
 #include <stdio.h>
 
+#define UCI_CONFDIR "/etc/config"
+
 enum
 {
 	UCI_OK = 0,
 	UCI_ERR_MEM,
 	UCI_ERR_INVAL,
 	UCI_ERR_NOTFOUND,
+	UCI_ERR_IO,
 	UCI_ERR_PARSE,
 	UCI_ERR_UNKNOWN,
 	UCI_ERR_LAST
@@ -54,12 +57,12 @@ extern struct uci_context *uci_alloc(void);
 extern void uci_perror(struct uci_context *ctx, const char *str);
 
 /**
- * uci_parse: Parse an uci config file and store it in the uci context
+ * uci_load: Parse an uci config file and store it in the uci context
  *
  * @ctx: uci context
  * @name: name of the config file (relative to the config directory)
  */
-int uci_parse(struct uci_context *ctx, const char *name);
+int uci_load(struct uci_context *ctx, const char *name);
 
 /**
  * uci_cleanup: Clean up after an error