2 * libuci - Library for the Unified Configuration Interface
3 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
5 * this program is free software; you can redistribute it and/or modify
6 * it under the terms of the gnu lesser general public license version 2.1
7 * as published by the free software foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 /* initialize a list head/item */
18 static inline void uci_list_init(struct uci_list
*ptr
)
24 /* inserts a new list entry between two consecutive entries */
25 static inline void __uci_list_add(struct uci_list
*prev
, struct uci_list
*next
, struct uci_list
*ptr
)
33 /* inserts a new list entry at the tail of the list */
34 static inline void uci_list_add(struct uci_list
*head
, struct uci_list
*ptr
)
36 /* NB: head->prev points at the tail */
37 __uci_list_add(head
->prev
, head
, ptr
);
40 static inline void uci_list_del(struct uci_list
*ptr
)
42 struct uci_list
*next
, *prev
;
51 static void uci_drop_option(struct uci_option
*option
)
62 static struct uci_option
*uci_add_option(struct uci_section
*section
, const char *name
, const char *value
)
64 struct uci_config
*cfg
= section
->config
;
65 struct uci_context
*ctx
= cfg
->ctx
;
66 struct uci_option
*option
= NULL
;
68 UCI_TRAP_SAVE(ctx
, error
);
69 option
= (struct uci_option
*) uci_malloc(ctx
, sizeof(struct uci_option
));
70 option
->name
= uci_strdup(ctx
, name
);
71 option
->value
= uci_strdup(ctx
, value
);
72 uci_list_add(§ion
->options
, &option
->list
);
73 UCI_TRAP_RESTORE(ctx
);
77 uci_drop_option(option
);
78 UCI_THROW(ctx
, ctx
->errno
);
82 static void uci_drop_section(struct uci_section
*section
)
84 struct uci_option
*opt
;
89 uci_foreach_entry(option
, §ion
->options
, opt
) {
90 uci_list_del(&opt
->list
);
101 static struct uci_section
*uci_add_section(struct uci_config
*cfg
, const char *type
, const char *name
)
103 struct uci_section
*section
= NULL
;
104 struct uci_context
*ctx
= cfg
->ctx
;
106 UCI_TRAP_SAVE(ctx
, error
);
107 section
= (struct uci_section
*) uci_malloc(ctx
, sizeof(struct uci_section
));
108 section
->config
= cfg
;
109 uci_list_init(§ion
->list
);
110 uci_list_init(§ion
->options
);
111 section
->type
= uci_strdup(ctx
, type
);
113 section
->name
= uci_strdup(ctx
, name
);
114 uci_list_add(&cfg
->sections
, §ion
->list
);
115 UCI_TRAP_RESTORE(ctx
);
120 uci_drop_section(section
);
121 UCI_THROW(ctx
, ctx
->errno
);
125 static void uci_drop_config(struct uci_config
*cfg
)
127 struct uci_section
*s
;
132 uci_foreach_entry(section
, &cfg
->sections
, s
) {
133 uci_list_del(&s
->list
);
143 static struct uci_config
*uci_alloc_config(struct uci_context
*ctx
, const char *name
)
145 struct uci_config
*cfg
= NULL
;
147 UCI_TRAP_SAVE(ctx
, error
);
148 cfg
= (struct uci_config
*) uci_malloc(ctx
, sizeof(struct uci_config
));
149 uci_list_init(&cfg
->list
);
150 uci_list_init(&cfg
->sections
);
151 cfg
->name
= uci_strdup(ctx
, name
);
153 UCI_TRAP_RESTORE(ctx
);
157 uci_drop_config(cfg
);
158 UCI_THROW(ctx
, ctx
->errno
);
162 int uci_unload(struct uci_context
*ctx
, const char *name
)
164 struct uci_config
*cfg
;
167 UCI_ASSERT(ctx
, name
!= NULL
);
169 uci_foreach_entry(config
, &ctx
->root
, cfg
) {
170 if (!strcmp(cfg
->name
, name
))
173 UCI_THROW(ctx
, UCI_ERR_NOTFOUND
);
176 uci_list_del(&cfg
->list
);
177 uci_drop_config(cfg
);
182 static inline char *get_filename(char *path
)
186 p
= strrchr(path
, '/');
193 char **uci_list_configs()
200 if (glob(UCI_CONFDIR
"/*", GLOB_MARK
, NULL
, &globbuf
) != 0)
203 size
= sizeof(char *) * (globbuf
.gl_pathc
+ 1);
204 for(i
= 0; i
< globbuf
.gl_pathc
; i
++) {
207 p
= get_filename(globbuf
.gl_pathv
[i
]);
211 size
+= strlen(p
) + 1;
214 configs
= malloc(size
);
218 memset(configs
, 0, size
);
219 buf
= (char *) &configs
[globbuf
.gl_pathc
+ 1];
220 for(i
= 0; i
< globbuf
.gl_pathc
; i
++) {
223 p
= get_filename(globbuf
.gl_pathv
[i
]);
229 buf
+= strlen(buf
) + 1;