return 0;
}
-int uci_add_backend(struct uci_context *ctx, struct uci_backend *b)
+#ifdef UCI_PLUGIN_SUPPORT
+
+__plugin int uci_add_backend(struct uci_context *ctx, struct uci_backend *b)
{
struct uci_element *e;
UCI_HANDLE_ERR(ctx);
+
e = uci_lookup_list(&ctx->backends, b->e.name);
if (e)
UCI_THROW(ctx, UCI_ERR_DUPLICATE);
- uci_list_add(&ctx->backends, &b->e.list);
+ e = uci_malloc(ctx, sizeof(struct uci_backend));
+ memcpy(e, b, sizeof(struct uci_backend));
+
+ uci_list_add(&ctx->backends, &e->list);
return 0;
}
+__plugin int uci_del_backend(struct uci_context *ctx, struct uci_backend *b)
+{
+ struct uci_element *e, *tmp;
+
+ UCI_HANDLE_ERR(ctx);
+
+ e = uci_lookup_list(&ctx->backends, b->e.name);
+ if (!e || uci_to_backend(e)->ptr != b->ptr)
+ UCI_THROW(ctx, UCI_ERR_NOTFOUND);
+ b = uci_to_backend(e);
+
+ if (ctx->backend && ctx->backend->ptr == b->ptr)
+ ctx->backend = &uci_file_backend;
+
+ uci_foreach_element_safe(&ctx->root, tmp, e) {
+ struct uci_package *p = uci_to_package(e);
+
+ if (!p->backend)
+ continue;
+
+ if (p->backend->ptr == b->ptr)
+ UCI_INTERNAL(uci_unload, ctx, p);
+ }
+
+ uci_list_del(&b->e.list);
+ free(b);
+
+ return 0;
+}
+
+#endif
+
int uci_set_backend(struct uci_context *ctx, const char *name)
{
struct uci_element *e;
uci_free_element(&s->e);
}
-static struct uci_package *
+__plugin struct uci_package *
uci_alloc_package(struct uci_context *ctx, const char *name)
{
struct uci_package *p;
char **(*list_configs)(struct uci_context *ctx);
struct uci_package *(*load)(struct uci_context *ctx, const char *name);
void (*commit)(struct uci_context *ctx, struct uci_package **p, bool overwrite);
+
+ /* private: */
+ const void *ptr;
+ void *priv;
};
struct uci_context
char *value;
};
-#define UCI_BACKEND(_var, _name, ...) \
-struct uci_backend _var = { \
- .e.list = { \
- .next = &_var.e.list, \
- .prev = &_var.e.list, \
- }, \
- .e.name = _name, \
- .e.type = UCI_TYPE_BACKEND, \
- __VA_ARGS__ \
-}
-
/* linked list handling */
#ifndef offsetof
#ifndef __UCI_INTERNAL_H
#define __UCI_INTERNAL_H
+#define __public
+#ifdef UCI_PLUGIN_SUPPORT
+#define __plugin extern
+#else
+#define __plugin static
+#endif
+
struct uci_parse_context
{
/* error context */
int bufsz;
};
-int uci_add_backend(struct uci_context *ctx, struct uci_backend *b);
-void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value);
-void uci_free_history(struct uci_history *h);
+__plugin void *uci_malloc(struct uci_context *ctx, size_t size);
+__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size);
+__plugin char *uci_strdup(struct uci_context *ctx, const char *str);
+__plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value);
+__plugin void uci_free_history(struct uci_history *h);
+__plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
+
+#ifdef UCI_PLUGIN_SUPPORT
+/**
+ * uci_add_backend: add an extra backend
+ * @ctx: uci context
+ * @name: name of the backend
+ *
+ * The default backend is "file", which uses /etc/config for config storage
+ */
+__plugin int uci_add_backend(struct uci_context *ctx, struct uci_backend *b);
+
+/**
+ * uci_add_backend: add an extra backend
+ * @ctx: uci context
+ * @name: name of the backend
+ *
+ * The default backend is "file", which uses /etc/config for config storage
+ */
+__plugin int uci_del_backend(struct uci_context *ctx, struct uci_backend *b);
+#endif
+
+#define UCI_BACKEND(_var, _name, ...) \
+struct uci_backend _var = { \
+ .e.list = { \
+ .next = &_var.e.list, \
+ .prev = &_var.e.list, \
+ }, \
+ .e.name = _name, \
+ .e.type = UCI_TYPE_BACKEND, \
+ .ptr = &_var, \
+ __VA_ARGS__ \
+}
+
/*
* functions for debug and error handling, for internal use only
#define LINEBUF 32
#define LINEBUF_MAX 4096
-static void *uci_malloc(struct uci_context *ctx, size_t size)
+__plugin void *uci_malloc(struct uci_context *ctx, size_t size)
{
void *ptr;
return ptr;
}
-static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
+__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
{
ptr = realloc(ptr, size);
if (!ptr)
return ptr;
}
-static char *uci_strdup(struct uci_context *ctx, const char *str)
+__plugin char *uci_strdup(struct uci_context *ctx, const char *str)
{
char *ptr;