From: Felix Fietkau Date: Sun, 3 Feb 2008 03:31:34 +0000 (+0100) Subject: add history search path X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=96d35364c9159c96b164369d0d0c5147b0c73a24;p=oweals%2Fuci.git add history search path --- diff --git a/file.c b/file.c index 4e3e828..6052c40 100644 --- 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); diff --git a/libuci.c b/libuci.c index b86c976..569a676 100644 --- 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 --- 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;