}
switch(cmd) {
case CMD_COMMIT:
- if (uci_commit(ctx, &p) != UCI_OK)
+ if (uci_commit(ctx, &p, false) != UCI_OK)
uci_perror(ctx, appname);
break;
case CMD_EXPORT:
package = NULL;
}
ret = uci_import(ctx, input, name, &package, (name != NULL));
- if ((ret == UCI_OK) && (flags & CLI_FLAG_MERGE)) {
- ret = uci_save(ctx, package);
+ if (ret == UCI_OK) {
+ if (flags & CLI_FLAG_MERGE) {
+ ret = uci_save(ctx, package);
+ } else {
+ struct uci_element *e;
+ /* loop through all config sections and overwrite existing data */
+ uci_foreach_element(&ctx->root, e) {
+ struct uci_package *p = uci_to_package(e);
+ ret = uci_commit(ctx, &p, true);
+ }
+ }
}
if (ret != UCI_OK) {
UCI_TRAP_SAVE(ctx, done);
f = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
- uci_parse_history(ctx, f, p);
+ if (p)
+ uci_parse_history(ctx, f, p);
UCI_TRAP_RESTORE(ctx);
done:
}
+static char *uci_config_path(struct uci_context *ctx, const char *name)
+{
+ char *filename;
+
+ if (strchr(name, '/'))
+ UCI_THROW(ctx, UCI_ERR_INVAL);
+ filename = uci_malloc(ctx, strlen(name) + sizeof(UCI_CONFDIR) + 2);
+ sprintf(filename, UCI_CONFDIR "/%s", name);
+
+ return filename;
+}
+
int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package)
{
char *filename;
break;
default:
/* config in /etc/config */
- if (strchr(name, '/'))
- UCI_THROW(ctx, UCI_ERR_INVAL);
- filename = uci_malloc(ctx, strlen(name) + sizeof(UCI_CONFDIR) + 2);
- sprintf(filename, UCI_CONFDIR "/%s", name);
+ filename = uci_config_path(ctx, name);
confdir = true;
break;
}
* does not modify the uci_package pointer
*/
if (!p->confdir)
- return uci_commit(ctx, &p);
+ return uci_commit(ctx, &p, false);
if (uci_list_empty(&p->history))
return 0;
return 0;
}
-int uci_commit(struct uci_context *ctx, struct uci_package **package)
+int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overwrite)
{
struct uci_package *p;
FILE *f = NULL;
p = *package;
UCI_ASSERT(ctx, p != NULL);
- UCI_ASSERT(ctx, p->path != NULL);
+ if (!p->path) {
+ if (overwrite)
+ p->path = uci_config_path(ctx, p->e.name);
+ else
+ UCI_THROW(ctx, UCI_ERR_INVAL);
+ }
+
/* open the config file for writing now, so that it is locked */
f = uci_open_stream(ctx, p->path, SEEK_SET, true, true);
/* flush unsaved changes and reload from history file */
UCI_TRAP_SAVE(ctx, done);
if (p->confdir) {
- name = uci_strdup(ctx, p->e.name);
- path = uci_strdup(ctx, p->path);
- if (!uci_list_empty(&p->history))
- UCI_INTERNAL(uci_save, ctx, p);
- uci_free_package(&p);
- uci_file_cleanup(ctx);
- UCI_INTERNAL(uci_import, ctx, f, name, &p, true);
-
- p->path = path;
- p->confdir = true;
- *package = p;
-
- /* freed together with the uci_package */
- path = NULL;
-
- /* check for updated history, just in case */
- uci_load_history(ctx, p, true);
+ if (!overwrite) {
+ name = uci_strdup(ctx, p->e.name);
+ path = uci_strdup(ctx, p->path);
+ if (!uci_list_empty(&p->history))
+ UCI_INTERNAL(uci_save, ctx, p);
+ uci_free_package(&p);
+ uci_file_cleanup(ctx);
+ UCI_INTERNAL(uci_import, ctx, f, name, &p, true);
+
+ p->path = path;
+ p->confdir = true;
+ *package = p;
+
+ /* freed together with the uci_package */
+ path = NULL;
+
+ /* check for updated history, just in case */
+ uci_load_history(ctx, p, true);
+ } else {
+ /* flush history */
+ uci_load_history(ctx, NULL, true);
+ }
}
rewind(f);