4d45aa86f1e2f2f37bde8231dd3bbd24dd724715
[silc.git] / lib / silcutil / silcconfig.h
1 /*
2
3   silcconfig.h
4
5   Author: Giovanni Giacobbi <giovanni@giacobbi.net>
6
7   Copyright (C) 2002 - 2003 Giovanni Giacobbi
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 /****h* silcutil/SILC Config Interface
22  *
23  * DESCRIPTION
24  *
25  * The SILC Config util library is based on two main objects, SilcConfigFile
26  * (or File object) and SilcConfigEntity (or Entity).  The File objects are
27  * structs directly corresponding to the real files in the filesystem, while
28  * Entities are a little more abstract.
29  *
30  * An Entity is composed by delimited area on a File object (it can take the
31  * whole File object or just part of it), plus a group of known options.
32  * In order to parse this file, first you need to create a File object with
33  * the silc_config_open() function, and then you need to create the Entity
34  * with the silc_config_init() function.
35  *
36  * Now you can use the newly created Entity to register a group of expected
37  * known options and sub-blocks, and then you can call the main parsing loop
38  * with the silc_config_main() function. When silc_config_main() will 
39  * return, if some error encoured the object file will point to the file 
40  * that caused this error (this can be different from the originally 
41  * opened file if it contained `Include' directives).  If no errors 
42  * encoured then the File objects will still point to the original file.
43  *
44  * While silc_config_main() will take care of destroying Entities before
45  * returning, you need to take care that the File object you created is freed
46  * with the silc_config_close() function.
47  *
48  * The SILC Config library won't take care about storing the values contained
49  * in the config file.  You must take care about it with the callback
50  * functions.
51  *
52  * The config file syntax is pretty straightforward.  All lines starting
53  * with `#' will be skipped, while sub-blocks are delimited by braces (see
54  * the example below).
55  *
56  * Options with argument must have the `=' character between the option
57  * name and the value.  Simple words and numbers does not require quoting.
58  * There is a special built-in directive "Include" which allows you to include
59  * another config file in the point the directive is.  You can also Include
60  * inside a sub-block body, in this case when parsing the included config file
61  * it will be assumed that we are within this block, and the included file
62  * won't be allowed to close his root block.
63  *
64  * Example:
65  *
66  *    cipher {
67  *       name = aes-256-cbc;
68  *       module = "aes.sim.so";
69  *       key_length = 32;       # usually the default is just fine
70  *       block_length = 16;
71  *    };
72  *    Include "/etc/silc/hash_funcs.conf";
73  *
74  ***/
75
76 #ifndef SILCCONFIG_H
77 #define SILCCONFIG_H
78
79 /****d* silcutil/SilcConfigAPI/SilcConfigErrno
80  *
81  * NAME
82  *
83  *    enum { ... } - describe a SILC Config error
84  *
85  * DESCRIPTION
86  *
87  *    The virtual integer `errno' is returned by the silc_config_main()
88  *    function and indicates what went wrong.
89  *    You can convert it to the corresponding error string with the function
90  *    silc_config_strerror().
91  *
92  * SOURCE
93  */
94 enum {
95   SILC_CONFIG_OK,               /* OK */
96   SILC_CONFIG_ESILENT,          /* Error defined by callback function */
97   SILC_CONFIG_EPRINTLINE,       /* Error defined by callback function */
98   SILC_CONFIG_EGENERIC,         /* Invalid syntax */
99   SILC_CONFIG_EINTERNAL,        /* Internal Error (caused by developer) */
100   SILC_CONFIG_ECANTOPEN,        /* Can't open specified file */
101   SILC_CONFIG_EOPENBRACE,       /* Expected open-brace '{' */
102   SILC_CONFIG_ECLOSEBRACE,      /* Missing close-brace '}' */
103   SILC_CONFIG_ETYPE,            /* Invalid data type */
104   SILC_CONFIG_EBADOPTION,       /* Unknown option */
105   SILC_CONFIG_EINVALIDTEXT,     /* Invalid text */
106   SILC_CONFIG_EDOUBLE,          /* Double option specification */
107   SILC_CONFIG_EEXPECTED,        /* Expected data but not found */
108   SILC_CONFIG_EEXPECTEDEQUAL,   /* Expected '=' */
109   SILC_CONFIG_EUNEXPECTED,      /* Unexpected data */
110   SILC_CONFIG_EMISSFIELDS,      /* Missing mandatory fields */
111   SILC_CONFIG_EMISSCOLON,       /* Missing ';' */
112 };
113 /***/
114
115 /****d* silcutil/SilcConfigAPI/SilcConfigType
116  *
117  * NAME
118  *
119  *    typedef enum { ... } SilcConfigType;
120  *
121  * DESCRIPTION
122  *
123  *    This identifies the parameter type that an option has. This parameter
124  *    is very important because the callback's *val pointer points to a
125  *    memory location containing the previously specified data type.
126  *    For example, if you specified an option with an integer parameter
127  *    callback's *val will be a pointer to an integer.
128  *
129  * SOURCE
130  */
131 typedef enum {
132   SILC_CONFIG_ARG_TOGGLE,       /* TOGGLE on,off; yes,no; true, false; */
133   SILC_CONFIG_ARG_INT,          /* callback wants an integer */
134   SILC_CONFIG_ARG_STR,          /* callback expects \0-terminated str */
135   SILC_CONFIG_ARG_STRE,         /* same as above, but can also be empty */
136   SILC_CONFIG_ARG_BLOCK,        /* this is a sub-block */
137   SILC_CONFIG_ARG_SIZE,         /* like int, but accepts suffixes kMG */
138   SILC_CONFIG_ARG_NONE,         /* does not expect any args */
139 } SilcConfigType;
140 /***/
141
142 /****f* silcutil/SilcConfigAPI/SilcConfigCallback
143  *
144  * SYNOPSIS
145  *
146  *    typedef int (*SilcConfigCallback)(SilcConfigType type, const char *name,
147  *                                      SilcUInt32 line, void *val,
148  *                                      void *context);
149  * DESCRIPTION
150  *
151  *    This is the callback prototype for the options handler.  The pointer
152  *    `val' points to a location of type described by `type'.  `name' points
153  *    to a null-terminated string with the name of the option which triggered
154  *    this callback, that is stated at line `line'.  `context' is the
155  *    user-specified context provided when this option was registered.
156  *
157  ***/
158 typedef int (*SilcConfigCallback)(SilcConfigType type, const char *name,
159                                   SilcUInt32 line, void *val, void *context);
160
161 /****s* silcutil/SilcConfigAPI/SilcConfigTable
162  *
163  * SYNOPSIS
164  *
165  *    typedef struct { ... } SilcConfigTable;
166  *
167  * DESCRIPTION
168  *
169  *    SILC Config table defines an easy and quick way of registering options
170  *    in an entity. The function silc_config_register_table() will take as
171  *    argument a SilcConfigTable array terminated by a NULL struct, it is
172  *    important thus, that the `name' field of the terminating struct is set
173  *    to NULL.
174  *
175  *    char *name
176  *
177  *       The option name lowercase. The matching is always case-insensitive,
178  *       but for convention the option specification must always be lowercase.
179  *
180  *    SilcConfigType type
181  *
182  *       This specifies what kind of parameter this option expects.  The
183  *       special cases SILC_CONFIG_ARG_BLOCK tells SILC Config that this is
184  *       not a normal option but the name of a sub-block of the current
185  *       block (there is no limit to the number of nested blocks allowed).
186  *
187  *    SilcConfigCallback callback
188  *
189  *       Normally this is the value handler of the current option. If this
190  *       field is set to NULL then the value is silently discarded. Useful
191  *       for example to support deprecated options.
192  *
193  *    SilcConfigTable *subtable
194  *
195  *       If the `type' field is set to SILC_CONFIG_ARG_BLOCK, then this field
196  *       must point to a valid sub-table NULL-terminated array. If `type' is
197  *       something else, this valued is unused.
198  *
199  ***/
200 typedef struct SilcConfigTableStruct {
201   char *name;
202   SilcConfigType type;
203   SilcConfigCallback callback;
204   const struct SilcConfigTableStruct *subtable;
205 } SilcConfigTable;
206
207 /****s* silcutil/SilcConfigAPI/SilcConfigFile
208  *
209  * SYNOPSIS
210  *
211  *    typedef struct SilcConfigFileObject SilcConfigFile;
212  *
213  * DESCRIPTION
214  *
215  *    A File object holds the data contained in a previously loaded file by
216  *    the silc_config_open() function.
217  *    This is an internally allocated struct and must be used only with the
218  *    helper functions.
219  *
220  ***/
221 typedef struct SilcConfigFileObject SilcConfigFile;
222
223 /****s* silcutil/SilcConfigAPI/SilcConfigEntity
224  *
225  * SYNOPSIS
226  *
227  *    typedef struct SilcConfigEntityObject *SilcConfigEntity;
228  *
229  * DESCRIPTION
230  *
231  *    The SILC Config is based on config entities.  An entity contains the
232  *    SilcConfigFile object we are parsing and the registered options.
233  *
234  ***/
235 typedef struct SilcConfigEntityObject *SilcConfigEntity;
236
237 /* Macros */
238
239 /****d* silcutil/SilcConfigAPI/SILC_CONFIG_CALLBACK
240  *
241  * NAME
242  *
243  *    #define SILC_CONFIG_CALLBACK ...
244  *
245  * DESCRIPTION
246  *
247  *    Generic macro to define SilcConfigCallback functions. This defines a
248  *    static function with name `func' as a config callback function.
249  *
250  * SOURCE
251  */
252 #define SILC_CONFIG_CALLBACK(func)                              \
253 static int func(SilcConfigType type, const char *name,          \
254                 SilcUInt32 line, void *val, void *context)
255 /***/
256
257 /* Prototypes */
258
259 /****f* silcutil/SilcConfigAPI/silc_config_open
260  *
261  * SYNOPSIS
262  *
263  *    SilcConfigFile *silc_config_open(char *configfile);
264  *
265  * DESCRIPTION
266  *
267  *    Tries to open the config file `configfile' and returns a valid File
268  *    object on success, or NULL on failure.
269  *    An File object created this way must be destroyed with the function
270  *    silc_config_close().
271  *
272  ***/
273 SilcConfigFile *silc_config_open(const char *configfile);
274
275 /****f* silcutil/SilcConfigAPI/silc_config_close
276  *
277  * SYNOPSIS
278  *
279  *    void silc_config_close(SilcConfigFile *file);
280  *
281  * DESCRIPTION
282  *
283  *    Closes and frees the File object `file', which must have been returned
284  *    by a previous call to silc_config_open().  Otherwise, or if
285  *    this function has already been called before for the same File object,
286  *    undefined behaviour occurs.
287  *    If `file' is NULL, no operation is performed.
288  *
289  ***/
290 void silc_config_close(SilcConfigFile *file);
291
292 /****f* silcutil/SilcConfigAPI/silc_config_init
293  *
294  * SYNOPSIS
295  *
296  *    SilcConfigEntity silc_config_init(SilcConfigFile *file);
297  *
298  * DESCRIPTION
299  *
300  *    Creates an Entity pointing to the valid File object `file', which must
301  *    be returned by a previous call to silc_config_open(), otherwise NULL
302  *    is returned.
303  *    Entities will be automatically destroyed after the call to the
304  *    silc_config_main() function, because of this no uninit functions are
305  *    provided.
306  *
307  ***/
308 SilcConfigEntity silc_config_init(SilcConfigFile *file);
309
310 /****f* silcutil/SilcConfigAPI/silc_config_strerror
311  *
312  * SYNOPSIS
313  *
314  *    char *silc_config_strerror(int errnum);
315  *
316  * DESCRIPTION
317  *
318  *    The silc_config_strerror() function returns a string describing the
319  *    error code passed in the argument `errnum'.
320  *
321  ***/
322 char *silc_config_strerror(int errnum);
323
324 /****f* silcutil/SilcConfigAPI/silc_config_get_filename
325  *
326  * SYNOPSIS
327  *
328  *    char *silc_config_get_filename(SilcConfigFile *file);
329  *
330  * DESCRIPTION
331  *
332  *    Returns the original filename of the object file.
333  *    The returned pointer points to internally allocated storage and must
334  *    not be freed, modified or stored.
335  *
336  ***/
337 char *silc_config_get_filename(SilcConfigFile *file);
338
339 /****f* silcutil/SilcConfigAPI/silc_config_get_line
340  *
341  * SYNOPSIS
342  *
343  *    SilcUInt32 silc_config_get_line(SilcConfigFile *file);
344  *
345  * DESCRIPTION
346  *
347  *    Returns the current line that file parsing arrived at.
348  *
349  ***/
350 SilcUInt32 silc_config_get_line(SilcConfigFile *file);
351
352 /****f* silcutil/SilcConfigAPI/silc_config_read_line
353  *
354  * SYNOPSIS
355  *
356  *    char *silc_config_read_line(SilcConfigFile *file, SilcUInt32 line);
357  *
358  * DESCRIPTION
359  *
360  *    Returns a dynamically allocated null-terminated buffer containing the
361  *    line `line' of `file'.
362  *    The returned pointer must be freed when it's not needed any longer.
363  *
364  * SEE ALSO
365  *    silc_config_read_current_line
366  *
367  ***/
368 char *silc_config_read_line(SilcConfigFile *file, SilcUInt32 line);
369
370 /****f* silcutil/SilcConfigAPI/silc_config_read_current_line
371  *
372  * SYNOPSIS
373  *
374  *    char *silc_config_read_current_line(SilcConfigFile *file);
375  *
376  * DESCRIPTION
377  *
378  *    Returns a dynamically allocated buffer containing the line that the
379  *    parser stopped at.  This is a convenience function for
380  *    silc_config_read_line.
381  *    The returned pointer must be freed when it's not needed any longer.
382  *
383  ***/
384 char *silc_config_read_current_line(SilcConfigFile *file);
385
386 /****f* silcutil/SilcConfigAPI/silc_config_register
387  *
388  * SYNOPSIS
389  *
390  *    bool silc_config_register(SilcConfigEntity ent, const char *name,
391  *                              SilcConfigType type, SilcConfigCallback cb,
392  *                              const SilcConfigTable *subtable,
393  *                              void *context);
394  *
395  * DESCRIPTION
396  *
397  *    Register option `name' in the entity `ent'. If `cb' is not NULL, it
398  *    will be called with the *val pointer pointing to an internally
399  *    allocated storage of type described by `type'.
400  *    If `type' is SILC_CONFIG_ARG_BLOCK, then `subtable' must be a valid
401  *    pointer to a SilcConfigTable array specifying the options in the
402  *    sub-block.
403  *    If the option `name' was already registered in this sub-block or it
404  *    matches the reserved word "Include", then this function returns FALSE,
405  *    otherwise it returns TRUE.
406  *
407  * SEE ALSO
408  *    silc_config_register_table
409  *
410  ***/
411 bool silc_config_register(SilcConfigEntity ent, const char *name,
412                           SilcConfigType type, SilcConfigCallback cb,
413                           const SilcConfigTable *subtable, void *context);
414
415 /****f* silcutil/SilcConfigAPI/silc_config_register_table
416  *
417  * SYNOPSIS
418  *
419  *    bool silc_config_register_table(SilcConfigEntity ent,
420  *                                    const SilcConfigTable table[],
421  *                                    void *context);
422  *
423  * DESCRIPTION
424  *
425  *    Register the tableset of options `table' automatically in the entity
426  *    `ent'.  If defined in the table, the callback functions will be called
427  *    all with the same context `context'.
428  *    The `table' array must be terminated with an entry with the name field
429  *    set to NULL.
430  *    If the table contains invalid data this function returns FALSE, otherwise
431  *    it returns TRUE.  If a calling to this function failed, you must destroy
432  *    and recreate the entity before retrying, as it's impossible to detect
433  *    the point at the function stopped the registering process.
434  *
435  * SEE ALSO
436  *    SilcConfigTable
437  *
438  ***/
439 bool silc_config_register_table(SilcConfigEntity ent,
440                                 const SilcConfigTable table[], void *context);
441
442 /****f* silcutil/SilcConfigAPI/silc_config_main
443  *
444  * SYNOPSIS
445  *
446  *    int silc_config_main(SilcConfigEntity ent);
447  *
448  * DESCRIPTION
449  *
450  *    Enter the main parsing loop. When this function returns the parsing
451  *    is finished in the current block (and sub-blocks).
452  *    When this function exits, the entity is already destroyed, because
453  *    of this you should set it to NULL right after the function call.
454  *
455  ***/
456 int silc_config_main(SilcConfigEntity ent);
457
458 #endif  /* !SILCCONFIG_H */