allow accessing files outside of /etc/config
[project/uci.git] / uci.h
1 /*
2  * libuci - Library for the Unified Configuration Interface
3  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
4  *
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
8  *
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.
13  */
14
15 #ifndef __LIBUCI_H
16 #define __LIBUCI_H
17
18 /*
19  * you can use these defines to enable debugging behavior for
20  * apps compiled against libuci:
21  *
22  * #define UCI_DEBUG_TYPECAST:
23  *   enable uci_element typecast checking at run time
24  *
25  */
26
27 #ifdef DEBUG_ALL
28 #define UCI_DEBUG
29 #define UCI_DEBUG_TYPECAST
30 #endif
31
32 #include <stdbool.h>
33 #include <setjmp.h>
34 #include <stdio.h>
35
36 #define UCI_CONFDIR "/etc/config"
37
38 enum
39 {
40         UCI_OK = 0,
41         UCI_ERR_MEM,
42         UCI_ERR_INVAL,
43         UCI_ERR_NOTFOUND,
44         UCI_ERR_IO,
45         UCI_ERR_PARSE,
46         UCI_ERR_UNKNOWN,
47         UCI_ERR_LAST
48 };
49
50 struct uci_list;
51 struct uci_list
52 {
53         struct uci_list *next;
54         struct uci_list *prev;
55 };
56
57 struct uci_element;
58 struct uci_package;
59 struct uci_section;
60 struct uci_option;
61 struct uci_history;
62 struct uci_parse_context;
63
64
65 /**
66  * uci_alloc_context: Allocate a new uci context
67  */
68 extern struct uci_context *uci_alloc_context(void);
69
70 /**
71  * uci_free_context: Free the uci context including all of its data
72  */
73 extern void uci_free_context(struct uci_context *ctx);
74
75 /**
76  * uci_perror: Print the last uci error that occured
77  * @ctx: uci context
78  * @str: string to print before the error message
79  */
80 extern void uci_perror(struct uci_context *ctx, const char *str);
81
82 /**
83  * uci_import: Import uci config data from a stream
84  * @ctx: uci context
85  * @stream: file stream to import from
86  * @name: (optional) assume the config has the given name
87  * @package: (optional) store the last parsed config package in this variable
88  *
89  * the name parameter is for config files that don't explicitly use the 'package <...>' keyword
90  */
91 extern int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package);
92
93 /**
94  * uci_export: Export one or all uci config packages
95  * @ctx: uci context
96  * @stream: output stream
97  * @package: (optional) uci config package to export
98  */
99 extern int uci_export(struct uci_context *ctx, FILE *stream, struct uci_package *package);
100
101 /**
102  * uci_load: Parse an uci config file and store it in the uci context
103  *
104  * @ctx: uci context
105  * @name: name of the config file (relative to the config directory)
106  * @package: store the loaded config package in this variable
107  */
108 extern int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package);
109
110 /**
111  * uci_unload: Unload a config file from the uci context
112  *
113  * @ctx: uci context
114  * @package: pointer to the uci_package struct
115  */
116 extern int uci_unload(struct uci_context *ctx, struct uci_package *p);
117
118 /**
119  * uci_cleanup: Clean up after an error
120  *
121  * @ctx: uci context
122  */
123 extern int uci_cleanup(struct uci_context *ctx);
124
125 /**
126  * uci_lookup: Look up an uci element
127  *
128  * @ctx: uci context
129  * @res: where to store the result
130  * @package: uci_package struct 
131  * @section: config section (optional)
132  * @option: option to search for (optional)
133  *
134  * If section is omitted, then a pointer to the config package is returned
135  * If option is omitted, then a pointer to the config section is returned
136  */
137 extern int uci_lookup(struct uci_context *ctx, struct uci_element **res, struct uci_package *package, char *section, char *option);
138
139 /**
140  * uci_set_element_value: Replace an element's value with a new one
141  * @ctx: uci context
142  * @element: pointer to an uci_element struct pointer
143  * @value: new value
144  * 
145  * Only valid for uci_option and uci_section. Will replace the type string
146  * when used with an uci_section
147  */
148 extern int uci_set_element_value(struct uci_context *ctx, struct uci_element **element, char *value);
149
150 /**
151  * uci_set: Set an element's value; create the element if necessary
152  * @ctx: uci context
153  * @package: package name
154  * @section: section name
155  * @option: option name
156  * @value: value (option) or type (section)
157  */
158 extern int uci_set(struct uci_context *ctx, char *package, char *section, char *option, char *value);
159
160 /**
161  * uci_list_configs: List available uci config files
162  *
163  * @ctx: uci context
164  */
165 extern char **uci_list_configs(struct uci_context *ctx);
166
167 /* UCI data structures */
168 enum uci_type {
169         UCI_TYPE_PACKAGE = 0,
170         UCI_TYPE_SECTION = 1,
171         UCI_TYPE_OPTION = 2
172 };
173
174 struct uci_element
175 {
176         struct uci_list list;
177         enum uci_type type;
178         char *name;
179 };
180
181 struct uci_context
182 {
183         /* list of config packages */
184         struct uci_list root;
185
186         /* parser context, use for error handling only */
187         struct uci_parse_context *pctx;
188
189         /* private: */
190         int errno;
191         const char *func;
192         jmp_buf trap;
193         char *buf;
194         int bufsz;
195 };
196
197 struct uci_parse_context
198 {
199         /* error context */
200         const char *reason;
201         int line;
202         int byte;
203
204         /* private: */
205         struct uci_package *package;
206         struct uci_section *section;
207         FILE *file;
208         const char *name;
209         char *buf;
210         int bufsz;
211 };
212
213 struct uci_package
214 {
215         struct uci_element e;
216         struct uci_list sections;
217         struct uci_context *ctx;
218         bool confdir;
219         char *path;
220
221         /* private: */
222         int n_section;
223         struct uci_list history;
224 };
225
226 struct uci_section
227 {
228         struct uci_element e;
229         struct uci_list options;
230         struct uci_package *package;
231         char *type;
232 };
233
234 struct uci_option
235 {
236         struct uci_element e;
237         struct uci_section *section;
238         char *value;
239 };
240
241 enum uci_command {
242         UCI_CMD_ADD,
243         UCI_CMD_REMOVE,
244         UCI_CMD_CHANGE
245 };
246
247 struct uci_history
248 {
249         struct uci_list list;
250         enum uci_command cmd;
251         char *section;
252         char *option;
253         char *value;
254 };
255
256 /* linked list handling */
257 #ifndef offsetof
258 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
259 #endif
260
261 /**
262  * container_of - cast a member of a structure out to the containing structure
263  * @ptr:    the pointer to the member.
264  * @type:   the type of the container struct this is embedded in.
265  * @member: the name of the member within the struct.
266  */
267 #define container_of(ptr, type, member) \
268         ((type *) ((char *)ptr - offsetof(type,member)))
269
270
271 /**
272  * uci_list_entry: casts an uci_list pointer to the containing struct.
273  * @_type: config, section or option
274  * @_ptr: pointer to the uci_list struct
275  */
276 #define element_to(type, ptr) \
277         container_of(ptr, struct uci_ ## type, e)
278
279 #define list_to_element(ptr) \
280         container_of(ptr, struct uci_element, list)
281
282 /**
283  * uci_foreach_entry: loop through a list of uci elements
284  * @_list: pointer to the uci_list struct
285  * @_ptr: iteration variable, struct uci_element
286  *
287  * use like a for loop, e.g:
288  *   uci_foreach(&list, p) {
289  *      ...
290  *   }
291  */
292 #define uci_foreach_element(_list, _ptr)                \
293         for(_ptr = list_to_element((_list)->next);      \
294                 &_ptr->list != (_list);                 \
295                 _ptr = list_to_element(_ptr->list.next))
296
297 /**
298  * uci_foreach_entry_safe: like uci_foreach_safe, but safe for deletion
299  * @_list: pointer to the uci_list struct
300  * @_tmp: temporary variable, struct uci_element *
301  * @_ptr: iteration variable, struct uci_element *
302  *
303  * use like a for loop, e.g:
304  *   uci_foreach(&list, p) {
305  *      ...
306  *   }
307  */
308 #define uci_foreach_element_safe(_list, _tmp, _ptr)             \
309         for(_ptr = list_to_element((_list)->next),              \
310                 _tmp = list_to_element(_ptr->list.next);        \
311                 &_ptr->list != (_list);                 \
312                 _ptr = _tmp, _tmp = list_to_element(_ptr->list.next))
313
314 /**
315  * uci_list_empty: returns true if a list is empty
316  * @list: list head
317  */
318 #define uci_list_empty(list) ((list)->next == (list))
319
320 /* wrappers for dynamic type handling */
321 #define uci_type_package UCI_TYPE_PACKAGE
322 #define uci_type_section UCI_TYPE_SECTION
323 #define uci_type_option UCI_TYPE_OPTION
324
325 /* element typecasting */
326 #ifdef UCI_DEBUG_TYPECAST
327 static const char *uci_typestr[] = {
328         [uci_type_package] = "package",
329         [uci_type_section] = "section",
330         [uci_type_option] = "option"
331 };
332
333 static void uci_typecast_error(int from, int to)
334 {
335         fprintf(stderr, "Invalid typecast from '%s' to '%s'\n", uci_typestr[from], uci_typestr[to]);
336 }
337
338 #define BUILD_CAST(_type) \
339         static inline struct uci_ ## _type *uci_to_ ## _type (struct uci_element *e) \
340         { \
341                 if (e->type != uci_type_ ## _type) { \
342                         uci_typecast_error(e->type, uci_type_ ## _type); \
343                 } \
344                 return (struct uci_ ## _type *) e; \
345         }
346
347 BUILD_CAST(package)
348 BUILD_CAST(section)
349 BUILD_CAST(option)
350
351 #else
352 #define uci_to_package(ptr) container_of(ptr, struct uci_package, e)
353 #define uci_to_section(ptr) container_of(ptr, struct uci_section, e)
354 #define uci_to_option(ptr)  container_of(ptr, struct uci_option, e)
355 #endif
356
357 /**
358  * uci_alloc_element: allocate a generic uci_element, reserve a buffer and typecast
359  * @ctx: uci context
360  * @type: {package,section,option}
361  * @name: string containing the name of the element
362  * @datasize: additional buffer size to reserve at the end of the struct
363  */
364 #define uci_alloc_element(ctx, type, name, datasize) \
365         uci_to_ ## type (uci_alloc_generic(ctx, uci_type_ ## type, name, sizeof(struct uci_ ## type) + datasize))
366
367 #define uci_dataptr(ptr) \
368         (((char *) ptr) + sizeof(*ptr))
369
370 #endif