- Make ctx->savedir sit at the end of ctx->delta_path.
- Add notes to uci_set_savedir() and uci_add_delta_path() to document
the behaviour changes.
int uci_set_savedir(struct uci_context *ctx, const char *dir)
{
char *sdir;
int uci_set_savedir(struct uci_context *ctx, const char *dir)
{
char *sdir;
+ struct uci_element *e, *tmp;
+ bool exists = false;
UCI_HANDLE_ERR(ctx);
UCI_ASSERT(ctx, dir != NULL);
UCI_HANDLE_ERR(ctx);
UCI_ASSERT(ctx, dir != NULL);
+ /* Move dir to the end of ctx->delta_path */
+ uci_foreach_element_safe(&ctx->delta_path, tmp, e) {
+ if (!strcmp(e->name, dir)) {
+ exists = true;
+ uci_list_del(&e->list);
+ break;
+ }
+ }
+ if (!exists)
+ UCI_INTERNAL(uci_add_delta_path, ctx, dir);
+ else
+ uci_list_add(&ctx->delta_path, &e->list);
+
sdir = uci_strdup(ctx, dir);
if (ctx->savedir != uci_savedir)
free(ctx->savedir);
sdir = uci_strdup(ctx, dir);
if (ctx->savedir != uci_savedir)
free(ctx->savedir);
int uci_add_delta_path(struct uci_context *ctx, const char *dir)
{
struct uci_element *e;
int uci_add_delta_path(struct uci_context *ctx, const char *dir)
{
struct uci_element *e;
+ struct uci_list *savedir;
UCI_HANDLE_ERR(ctx);
UCI_ASSERT(ctx, dir != NULL);
UCI_HANDLE_ERR(ctx);
UCI_ASSERT(ctx, dir != NULL);
- if (!strcmp(dir, ctx->savedir))
- return -1;
+
+ /* Duplicate delta path is not allowed */
+ uci_foreach_element(&ctx->delta_path, e) {
+ if (!strcmp(e->name, dir))
+ UCI_THROW(ctx, UCI_ERR_DUPLICATE);
+ }
+
e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
- uci_list_add(&ctx->delta_path, &e->list);
+ /* Keep savedir at the end of ctx->delta_path list */
+ savedir = ctx->delta_path.prev;
+ uci_list_insert(savedir->prev, &e->list);
if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
UCI_THROW(ctx, UCI_ERR_MEM);
if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
UCI_THROW(ctx, UCI_ERR_MEM);
- uci_load_delta_file(ctx, p, filename, NULL, false);
+ changes += uci_load_delta_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);
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, NULL, SEEK_SET, flush, false);
+ UCI_TRAP_RESTORE(ctx);
- changes = uci_load_delta_file(ctx, p, filename, &f, flush);
if (flush && f && (changes > 0)) {
if (flush && f && (changes > 0)) {
if (ftruncate(fileno(f), 0) < 0) {
if (ftruncate(fileno(f), 0) < 0) {
uci_close_stream(f);
UCI_THROW(ctx, UCI_ERR_IO);
}
}
uci_close_stream(f);
UCI_THROW(ctx, UCI_ERR_IO);
}
}
free(filename);
uci_close_stream(f);
ctx->err = 0;
free(filename);
uci_close_stream(f);
ctx->err = 0;
ctx->confdir = (char *) uci_confdir;
ctx->savedir = (char *) uci_savedir;
ctx->confdir = (char *) uci_confdir;
ctx->savedir = (char *) uci_savedir;
+ uci_add_delta_path(ctx, uci_savedir);
uci_list_add(&ctx->backends, &uci_file_backend.e.list);
ctx->backend = &uci_file_backend;
uci_list_add(&ctx->backends, &uci_file_backend.e.list);
ctx->backend = &uci_file_backend;
* uci_set_savedir: override the default delta save directory
* @ctx: uci context
* @dir: directory name
* uci_set_savedir: override the default delta save directory
* @ctx: uci context
* @dir: directory name
+ *
+ * This will also try adding the specified dir to the end of delta pathes.
*/
extern int uci_set_savedir(struct uci_context *ctx, const char *dir);
*/
extern int uci_set_savedir(struct uci_context *ctx, const char *dir);
*
* This function allows you to add directories, which contain 'overlays'
* for the active config, that will never be committed.
*
* This function allows you to add directories, which contain 'overlays'
* for the active config, that will never be committed.
- * Caller of this API should ensure that no duplicate entries (including the
- * default search path, e.g. `UCI_SAVEDIR') should be added.
+ *
+ * Adding a duplicate directory will cause UCI_ERR_DUPLICATE be returned.
*/
extern int uci_add_delta_path(struct uci_context *ctx, const char *dir);
*/
extern int uci_add_delta_path(struct uci_context *ctx, const char *dir);