[settings] Allow for autovivification of settings blocks
[people/mcb30/gpxe.git] / src / include / gpxe / settings.h
1 #ifndef _GPXE_SETTINGS_H
2 #define _GPXE_SETTINGS_H
3
4 /** @file
5  *
6  * Configuration settings
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/tables.h>
12 #include <gpxe/list.h>
13 #include <gpxe/refcnt.h>
14 #include <gpxe/dhcpopts.h>
15
16 struct settings;
17 struct in_addr;
18 union uuid;
19
20 /** A setting */
21 struct setting {
22         /** Name
23          *
24          * This is the human-readable name for the setting.
25          */
26         const char *name;
27         /** Description */
28         const char *description;
29         /** Setting type
30          *
31          * This identifies the type of setting (e.g. string, IPv4
32          * address, etc.).
33          */
34         struct setting_type *type;
35         /** DHCP option number, if applicable */
36         unsigned int tag;
37 };
38
39 /** Declare a configuration setting */
40 #define __setting __table ( struct setting, settings, 01 )
41
42 /** Settings block operations */
43 struct settings_operations {
44         /** Store value of setting
45          *
46          * @v settings          Settings block
47          * @v setting           Setting to store
48          * @v data              Setting data, or NULL to clear setting
49          * @v len               Length of setting data
50          * @ret rc              Return status code
51          */
52         int ( * store ) ( struct settings *settings, struct setting *setting,
53                           const void *data, size_t len );
54         /** Fetch value of setting
55          *
56          * @v settings          Settings block
57          * @v setting           Setting to fetch
58          * @v data              Buffer to fill with setting data
59          * @v len               Length of buffer
60          * @ret len             Length of setting data, or negative error
61          *
62          * The actual length of the setting will be returned even if
63          * the buffer was too small.
64          */
65         int ( * fetch ) ( struct settings *settings, struct setting *setting,
66                           void *data, size_t len );
67 };
68
69 /** A settings block */
70 struct settings {
71         /** Reference counter */
72         struct refcnt *refcnt;
73         /** Name */
74         const char *name;
75         /** Tag magic
76          *
77          * This value will be ORed in to any numerical tags
78          * constructed by parse_setting_name(), and can be used to
79          * avoid e.g. attempting to retrieve the subnet mask from
80          * SMBIOS, or the system UUID from DHCP.
81          */
82         unsigned int tag_magic;
83         /** Parent settings block */
84         struct settings *parent;
85         /** Sibling settings blocks */
86         struct list_head siblings;
87         /** Child settings blocks */
88         struct list_head children;
89         /** Settings block operations */
90         struct settings_operations *op;
91 };
92
93 /**
94  * A setting type
95  *
96  * This represents a type of setting (e.g. string, IPv4 address,
97  * etc.).
98  */
99 struct setting_type {
100         /** Name
101          *
102          * This is the name exposed to the user (e.g. "string").
103          */
104         const char *name;
105         /** Parse and set value of setting
106          *
107          * @v settings          Settings block
108          * @v setting           Setting to store
109          * @v value             Formatted setting data
110          * @ret rc              Return status code
111          */
112         int ( * storef ) ( struct settings *settings, struct setting *setting,
113                            const char *value );
114         /** Fetch and format value of setting
115          *
116          * @v settings          Settings block
117          * @v setting           Setting to fetch
118          * @v buf               Buffer to contain formatted value
119          * @v len               Length of buffer
120          * @ret len             Length of formatted value, or negative error
121          */
122         int ( * fetchf ) ( struct settings *settings, struct setting *setting,
123                            char *buf, size_t len );
124 };
125
126 /** Declare a configuration setting type */
127 #define __setting_type \
128         __table ( struct setting_type, setting_types, 01 )
129
130 /**
131  * A settings applicator
132  *
133  */
134 struct settings_applicator {
135         /** Apply updated settings
136          *
137          * @ret rc              Return status code
138          */
139         int ( * apply ) ( void );
140 };
141
142 /** Declare a settings applicator */
143 #define __settings_applicator \
144         __table ( struct settings_applicator, settings_applicators, 01 )
145
146 /**
147  * A simple settings block
148  *
149  */
150 struct simple_settings {
151         /** Settings block */
152         struct settings settings;
153         /** DHCP options */
154         struct dhcp_options dhcpopts;
155 };
156
157 extern struct settings_operations simple_settings_operations;
158 extern int simple_settings_store ( struct settings *settings,
159                                    struct setting *setting,
160                                    const void *data, size_t len );
161 extern int simple_settings_fetch ( struct settings *settings,
162                                    struct setting *setting,
163                                    void *data, size_t len );
164
165 extern int register_settings ( struct settings *settings,
166                                struct settings *parent );
167 extern void unregister_settings ( struct settings *settings );
168
169 extern int store_setting ( struct settings *settings, struct setting *setting,
170                            const void *data, size_t len );
171 extern int fetch_setting ( struct settings *settings, struct setting *setting,
172                            void *data, size_t len );
173 extern int fetch_setting_len ( struct settings *settings,
174                                struct setting *setting );
175 extern int fetch_string_setting ( struct settings *settings,
176                                   struct setting *setting,
177                                   char *data, size_t len );
178 extern int fetch_string_setting_copy ( struct settings *settings,
179                                        struct setting *setting,
180                                        char **data );
181 extern int fetch_ipv4_setting ( struct settings *settings,
182                                 struct setting *setting, struct in_addr *inp );
183 extern int fetch_int_setting ( struct settings *settings,
184                                struct setting *setting, long *value );
185 extern int fetch_uint_setting ( struct settings *settings,
186                                 struct setting *setting,
187                                 unsigned long *value );
188 extern long fetch_intz_setting ( struct settings *settings,
189                                  struct setting *setting );
190 extern unsigned long fetch_uintz_setting ( struct settings *settings,
191                                            struct setting *setting );
192 extern int fetch_uuid_setting ( struct settings *settings,
193                                 struct setting *setting, union uuid *uuid );
194 extern int setting_cmp ( struct setting *a, struct setting *b );
195
196 extern struct settings * find_settings ( const char *name );
197
198 extern int storef_setting ( struct settings *settings,
199                             struct setting *setting,
200                             const char *value );
201 extern int storef_named_setting ( const char *name, const char *value );
202 extern int fetchf_named_setting ( const char *name, char *buf, size_t len );
203
204 extern struct setting_type setting_type_string __setting_type;
205 extern struct setting_type setting_type_ipv4 __setting_type;
206 extern struct setting_type setting_type_int8 __setting_type;
207 extern struct setting_type setting_type_int16 __setting_type;
208 extern struct setting_type setting_type_int32 __setting_type;
209 extern struct setting_type setting_type_uint8 __setting_type;
210 extern struct setting_type setting_type_uint16 __setting_type;
211 extern struct setting_type setting_type_uint32 __setting_type;
212 extern struct setting_type setting_type_hex __setting_type;
213 extern struct setting_type setting_type_uuid __setting_type;
214
215 extern struct setting ip_setting __setting;
216 extern struct setting netmask_setting __setting;
217 extern struct setting gateway_setting __setting;
218 extern struct setting dns_setting __setting;
219 extern struct setting domain_setting __setting;
220 extern struct setting hostname_setting __setting;
221 extern struct setting filename_setting __setting;
222 extern struct setting root_path_setting __setting;
223 extern struct setting username_setting __setting;
224 extern struct setting password_setting __setting;
225 extern struct setting priority_setting __setting;
226 extern struct setting uuid_setting __setting;
227 extern struct setting next_server_setting __setting;
228 extern struct setting mac_setting __setting;
229 extern struct setting user_class_setting __setting;
230
231 /**
232  * Initialise a settings block
233  *
234  * @v settings          Settings block
235  * @v op                Settings block operations
236  * @v refcnt            Containing object reference counter, or NULL
237  * @v name              Settings block name
238  * @v tag_magic         Tag magic
239  */
240 static inline void settings_init ( struct settings *settings,
241                                    struct settings_operations *op,
242                                    struct refcnt *refcnt,
243                                    const char *name,
244                                    unsigned int tag_magic ) {
245         INIT_LIST_HEAD ( &settings->siblings );
246         INIT_LIST_HEAD ( &settings->children );
247         settings->op = op;
248         settings->refcnt = refcnt;
249         settings->name = name;
250         settings->tag_magic = tag_magic;
251 }
252
253 /**
254  * Initialise a settings block
255  *
256  * @v simple            Simple settings block
257  * @v refcnt            Containing object reference counter, or NULL
258  * @v name              Settings block name
259  */
260 static inline void simple_settings_init ( struct simple_settings *simple,
261                                           struct refcnt *refcnt,
262                                           const char *name ) {
263         settings_init ( &simple->settings, &simple_settings_operations,
264                         refcnt, name, 0 );
265 }
266
267 /**
268  * Delete setting
269  *
270  * @v settings          Settings block
271  * @v setting           Setting to delete
272  * @ret rc              Return status code
273  */
274 static inline int delete_setting ( struct settings *settings,
275                                    struct setting *setting ) {
276         return store_setting ( settings, setting, NULL, 0 );
277 }
278
279 /**
280  * Fetch and format value of setting
281  *
282  * @v settings          Settings block, or NULL to search all blocks
283  * @v setting           Setting to fetch
284  * @v type              Settings type
285  * @v buf               Buffer to contain formatted value
286  * @v len               Length of buffer
287  * @ret len             Length of formatted value, or negative error
288  */
289 static inline int fetchf_setting ( struct settings *settings,
290                                    struct setting *setting,
291                                    char *buf, size_t len ) {
292         return setting->type->fetchf ( settings, setting, buf, len );
293 }
294
295 /**
296  * Delete named setting
297  *
298  * @v name              Name of setting
299  * @ret rc              Return status code
300  */
301 static inline int delete_named_setting ( const char *name ) {
302         return storef_named_setting ( name, NULL );
303 }
304
305 /**
306  * Check existence of setting
307  *
308  * @v settings          Settings block, or NULL to search all blocks
309  * @v setting           Setting to fetch
310  * @ret exists          Setting exists
311  */
312 static inline int setting_exists ( struct settings *settings,
313                                    struct setting *setting ) {
314         return ( fetch_setting_len ( settings, setting ) >= 0 );
315 }
316
317 #endif /* _GPXE_SETTINGS_H */