add history search path
authorFelix Fietkau <nbd@openwrt.org>
Sun, 3 Feb 2008 03:31:34 +0000 (04:31 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 3 Feb 2008 03:31:34 +0000 (04:31 +0100)
file.c
libuci.c
uci.h

diff --git a/file.c b/file.c
index 4e3e828..6052c40 100644 (file)
--- a/file.c
+++ b/file.c
@@ -744,24 +744,43 @@ error:
        uci_file_cleanup(ctx);
 }
 
+static void uci_load_history_file(struct uci_context *ctx, struct uci_package *p, char *filename, FILE **f, bool flush)
+{
+       FILE *stream = NULL;
+
+       UCI_TRAP_SAVE(ctx, done);
+       stream = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
+       if (p)
+               uci_parse_history(ctx, stream, p);
+       UCI_TRAP_RESTORE(ctx);
+done:
+       if (f)
+               *f = stream;
+       else if (stream)
+               uci_close_stream(stream);
+}
+
 static void uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush)
 {
+       struct uci_element *e;
        char *filename = NULL;
        FILE *f = NULL;
 
        if (!p->confdir)
                return;
 
+       uci_foreach_element(&ctx->history_path, e) {
+               if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
+                       UCI_THROW(ctx, UCI_ERR_MEM);
+
+               uci_load_history_file(ctx, p, filename, NULL, false);
+               free(filename);
+       }
+
        if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
                UCI_THROW(ctx, UCI_ERR_MEM);
 
-       UCI_TRAP_SAVE(ctx, done);
-       f = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
-       if (p)
-               uci_parse_history(ctx, f, p);
-       UCI_TRAP_RESTORE(ctx);
-
-done:
+       uci_load_history_file(ctx, p, filename, &f, flush);
        if (flush && f) {
                rewind(f);
                ftruncate(fileno(f), 0);
index b86c976..569a676 100644 (file)
--- a/libuci.c
+++ b/libuci.c
@@ -51,6 +51,7 @@ struct uci_context *uci_alloc_context(void)
        ctx = (struct uci_context *) malloc(sizeof(struct uci_context));
        memset(ctx, 0, sizeof(struct uci_context));
        uci_list_init(&ctx->root);
+       uci_list_init(&ctx->history_path);
        ctx->flags = UCI_FLAG_STRICT;
 
        ctx->confdir = (char *) uci_confdir;
@@ -74,6 +75,9 @@ void uci_free_context(struct uci_context *ctx)
                struct uci_package *p = uci_to_package(e);
                uci_free_package(&p);
        }
+       uci_foreach_element_safe(&ctx->history_path, tmp, e) {
+               uci_free_element(e);
+       }
        free(ctx);
        UCI_TRAP_RESTORE(ctx);
 
@@ -81,21 +85,43 @@ ignore:
        return;
 }
 
-int uci_set_confdir(struct uci_context *ctx, char *dir)
+int uci_add_history_path(struct uci_context *ctx, const char *dir)
+{
+       struct uci_element *e;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, dir != NULL);
+       e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
+       uci_list_add(&ctx->history_path, &e->list);
+
+       return 0;
+}
+
+int uci_set_confdir(struct uci_context *ctx, const char *dir)
 {
-       dir = uci_strdup(ctx, dir);
+       char *cdir;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, dir != NULL);
+
+       cdir = uci_strdup(ctx, dir);
        if (ctx->confdir != uci_confdir)
                free(ctx->confdir);
-       ctx->confdir = dir;
+       ctx->confdir = cdir;
        return 0;
 }
 
-int uci_set_savedir(struct uci_context *ctx, char *dir)
+int uci_set_savedir(struct uci_context *ctx, const char *dir)
 {
-       dir = uci_strdup(ctx, dir);
+       char *sdir;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, dir != NULL);
+
+       sdir = uci_strdup(ctx, dir);
        if (ctx->savedir != uci_savedir)
                free(ctx->savedir);
-       ctx->savedir = dir;
+       ctx->savedir = sdir;
        return 0;
 }
 
diff --git a/uci.h b/uci.h
index 2a1b73b..ce68dbb 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -232,22 +232,29 @@ extern int uci_list_configs(struct uci_context *ctx, char ***list);
  * @ctx: uci context
  * @dir: directory name
  */
-extern int uci_set_savedir(struct uci_context *ctx, char *dir);
+extern int uci_set_savedir(struct uci_context *ctx, const char *dir);
 
 /** 
  * uci_set_savedir: override the default config storage directory
  * @ctx: uci context
  * @dir: directory name
  */
-extern int uci_set_confdir(struct uci_context *ctx, char *dir);
+extern int uci_set_confdir(struct uci_context *ctx, const char *dir);
 
+/**
+ * uci_add_history_path: add a directory to the search path for change history files
+ * @ctx: uci context
+ * @dir: directory name
+ */
+extern int uci_add_history_path(struct uci_context *ctx, const char *dir);
 
 /* UCI data structures */
 enum uci_type {
        UCI_TYPE_HISTORY = 0,
        UCI_TYPE_PACKAGE = 1,
        UCI_TYPE_SECTION = 2,
-       UCI_TYPE_OPTION = 3
+       UCI_TYPE_OPTION = 3,
+       UCI_TYPE_PATH = 4
 };
 
 enum uci_flags {
@@ -277,6 +284,9 @@ struct uci_context
        char *confdir;
        char *savedir;
 
+       /* search path for history files */
+       struct uci_list history_path;
+
        /* private: */
        int errno;
        const char *func;