X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=history.c;h=2b6dbef64718ea319b318c577c266cdf1425952e;hb=28d2cc2adde3f9ec077a77cf363045a17f116032;hp=8935a3fca72315534aa2bbc88424cf6d687ff06b;hpb=68ced4fb649dd492c3f9af7119d00a4a638a32cb;p=project%2Fuci.git diff --git a/history.c b/history.c index 8935a3f..2b6dbef 100644 --- a/history.c +++ b/history.c @@ -28,7 +28,7 @@ /* record a change that was done to a package */ void -uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value) +uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value) { struct uci_history *h; int size = strlen(section) + 1; @@ -92,17 +92,25 @@ static inline void uci_parse_history_tuple(struct uci_context *ctx, char **buf, { int c = UCI_CMD_CHANGE; - if (**buf == '-') { + switch(**buf) { + case '-': c = UCI_CMD_REMOVE; - *buf += 1; - } else if (**buf == '@') { + break; + case '@': c = UCI_CMD_RENAME; - *buf += 1; - } else if (**buf == '+') { - /* UCI_CMD_ADD is used for anonymous sections */ + break; + case '+': + /* UCI_CMD_ADD is used for anonymous sections or list values */ c = UCI_CMD_ADD; - *buf += 1; + break; + case '|': + c = UCI_CMD_LIST_ADD; + break; } + + if (c != UCI_CMD_CHANGE) + *buf += 1; + if (cmd) *cmd = c; @@ -143,6 +151,9 @@ static void uci_parse_history_line(struct uci_context *ctx, struct uci_package * case UCI_CMD_REMOVE: UCI_INTERNAL(uci_delete, ctx, p, section, option); break; + case UCI_CMD_LIST_ADD: + UCI_INTERNAL(uci_add_list, ctx, p, section, option, value, NULL); + break; case UCI_CMD_ADD: case UCI_CMD_CHANGE: UCI_INTERNAL(uci_set, ctx, p, section, option, value, &e); @@ -239,11 +250,11 @@ static int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool if (filename) free(filename); uci_close_stream(f); - ctx->errno = 0; + ctx->err = 0; return changes; } -static void uci_filter_history(struct uci_context *ctx, const char *name, char *section, char *option) +static void uci_filter_history(struct uci_context *ctx, const char *name, const char *section, const char *option) { struct uci_parse_context *pctx; struct uci_element *e, *tmp; @@ -312,7 +323,7 @@ done: uci_cleanup(ctx); } -int uci_revert(struct uci_context *ctx, struct uci_package **pkg, char *section, char *option) +int uci_revert(struct uci_context *ctx, struct uci_package **pkg, const char *section, const char *option) { struct uci_package *p; char *name = NULL; @@ -340,13 +351,13 @@ int uci_revert(struct uci_context *ctx, struct uci_package **pkg, char *section, UCI_INTERNAL(uci_load, ctx, name, &p); UCI_TRAP_RESTORE(ctx); - ctx->errno = 0; + ctx->err = 0; error: if (name) free(name); - if (ctx->errno) - UCI_THROW(ctx, ctx->errno); + if (ctx->err) + UCI_THROW(ctx, ctx->err); return 0; } @@ -355,6 +366,7 @@ int uci_save(struct uci_context *ctx, struct uci_package *p) FILE *f = NULL; char *filename = NULL; struct uci_element *e, *tmp; + struct stat statbuf; UCI_HANDLE_ERR(ctx); UCI_ASSERT(ctx, p != NULL); @@ -371,32 +383,41 @@ int uci_save(struct uci_context *ctx, struct uci_package *p) if (uci_list_empty(&p->history)) return 0; + if (stat(ctx->savedir, &statbuf) < 0) + mkdir(ctx->savedir, UCI_DIRMODE); + else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) + UCI_THROW(ctx, UCI_ERR_IO); + if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename) UCI_THROW(ctx, UCI_ERR_MEM); - ctx->errno = 0; + ctx->err = 0; UCI_TRAP_SAVE(ctx, done); f = uci_open_stream(ctx, filename, SEEK_END, true, true); UCI_TRAP_RESTORE(ctx); uci_foreach_element_safe(&p->history, tmp, e) { struct uci_history *h = uci_to_history(e); + char *prefix = ""; switch(h->cmd) { case UCI_CMD_REMOVE: - fprintf(f, "-"); + prefix = "-"; break; case UCI_CMD_RENAME: - fprintf(f, "@"); + prefix = "@"; break; case UCI_CMD_ADD: - fprintf(f, "+"); + prefix = "+"; + break; + case UCI_CMD_LIST_ADD: + prefix = "|"; break; default: break; } - fprintf(f, "%s.%s", p->e.name, h->section); + fprintf(f, "%s%s.%s", prefix, p->e.name, h->section); if (e->name) fprintf(f, ".%s", e->name); @@ -411,8 +432,8 @@ done: uci_close_stream(f); if (filename) free(filename); - if (ctx->errno) - UCI_THROW(ctx, ctx->errno); + if (ctx->err) + UCI_THROW(ctx, ctx->err); return 0; }