add proper history tracking for delete
[project/uci.git] / file.c
diff --git a/file.c b/file.c
index 0e5992c..7a57612 100644 (file)
--- a/file.c
+++ b/file.c
@@ -580,7 +580,7 @@ static void uci_parse_history_line(struct uci_context *ctx, struct uci_package *
        }
 
        UCI_INTERNAL(uci_parse_tuple, ctx, buf, &package, &section, &option, &value);
-       if (!package || !section || !value)
+       if (!package || !section || (!delete && !value))
                goto error;
        if (strcmp(package, p->e.name) != 0)
                goto error;
@@ -588,10 +588,13 @@ static void uci_parse_history_line(struct uci_context *ctx, struct uci_package *
                goto error;
        if (option && !uci_validate_name(option))
                goto error;
-       if (!delete)
-               UCI_INTERNAL(uci_set, ctx, package, section, option, value);
-       return;
 
+       if (delete)
+               UCI_INTERNAL(uci_del, ctx, p, section, option);
+       else
+               UCI_INTERNAL(uci_set, ctx, p, section, option, value);
+
+       return;
 error:
        UCI_THROW(ctx, UCI_ERR_PARSE);
 }
@@ -621,7 +624,7 @@ static void uci_parse_history(struct uci_context *ctx, FILE *stream, struct uci_
 
 static void uci_load_history(struct uci_context *ctx, struct uci_package *p)
 {
-       char *filename;
+       char *filename = NULL;
        FILE *f = NULL;
 
        if (!p->confdir)
@@ -634,6 +637,8 @@ static void uci_load_history(struct uci_context *ctx, struct uci_package *p)
        uci_parse_history(ctx, f, p);
        UCI_TRAP_RESTORE(ctx);
 done:
+       if (filename)
+               free(filename);
        uci_close_stream(f);
        ctx->errno = 0;
 }
@@ -722,12 +727,18 @@ int uci_save(struct uci_context *ctx, struct uci_package *p)
 
        uci_foreach_element_safe(&p->history, tmp, e) {
                struct uci_history *h = uci_to_history(e);
+
                if (h->cmd == UCI_CMD_REMOVE)
                        fprintf(f, "-");
+
                fprintf(f, "%s.%s", p->e.name, h->section);
                if (e->name)
                        fprintf(f, ".%s", e->name);
-               fprintf(f, "=%s\n", h->value);
+
+               if (h->cmd == UCI_CMD_REMOVE)
+                       fprintf(f, "\n");
+               else
+                       fprintf(f, "=%s\n", h->value);
                uci_list_del(&e->list);
        }
 
@@ -802,11 +813,7 @@ char **uci_list_configs(struct uci_context *ctx)
                size += strlen(p) + 1;
        }
 
-       configs = malloc(size);
-       if (!configs)
-               return NULL;
-
-       memset(configs, 0, size);
+       configs = uci_malloc(ctx, size);
        buf = (char *) &configs[globbuf.gl_pathc + 1];
        for(i = 0; i < globbuf.gl_pathc; i++) {
                char *p;