]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/ini.h
Backport from BEE
[bacula/bacula] / bacula / src / lib / ini.h
1 /*
2    Copyright (C) 2011-2011 Bacula Systems(R) SA
3
4    The main author of Bacula is Kern Sibbald, with contributions from
5    many others, a complete list can be found in the file AUTHORS.
6    This program is Free Software; you can modify it under the terms of
7    version three of the GNU Affero General Public License as published by the
8    Free Software Foundation, which is listed in the file LICENSE.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU Affero General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA.
19
20    Bacula® is a registered trademark of Kern Sibbald.
21    Bacula Systems(R) is a trademark of Bacula Systems SA.
22    Bacula Enterprise(TM) is a trademark of Bacula Systems SA.
23
24    The licensor of Bacula Enterprise(TM) is Bacula Systems(R) SA,
25    Rue Galilee 5, 1400 Yverdon-les-Bains, Switzerland.
26 */
27
28 #ifndef INI_H
29 #define INI_H
30
31 /*
32  * Plugin has a internal C structure that describes the configuration:
33  * struct ini_items[]
34  *
35  * The ConfigFile object can generate a text file that describes the C
36  * structure. This text format is saved as RestoreObject in the catalog.
37  *
38  *   struct ini_items[]  -> register_items()  -> serialize() -> RestoreObject R1
39  *
40  * On the Director side, at the restore time, we can analyse this text to
41  * get the C structure.
42  *
43  * RestoreObject R1 -> write to disk -> unserialize() -> struct ini_items[]
44  *
45  * Once done, we can ask questions to the user at the restore time and fill
46  * the C struct with answers. The Director can send back as a RestoreObject
47  * the result of the questionnaire.
48  *
49  * struct ini_items[] -> UAContext -> dump_result() -> FD as RestoreObject R2
50  *
51  * On the Plugin side, it can get back the C structure and use it.
52  * RestoreObject R2 -> parse() -> struct ini_items[]
53  */
54
55 class ConfigFile;
56 struct ini_items;
57
58 /* Used to store result */
59 typedef union {
60    char    *strval;
61    char    nameval[MAX_NAME_LENGTH];
62    int64_t int64val;
63    int32_t int32val;
64    alist   *alistval;
65    bool    boolval;
66 } item_value;
67
68 /* These functions are used to convert a string to the appropriate value */
69 typedef
70 bool (INI_ITEM_HANDLER)(LEX *lc, ConfigFile *inifile,
71                         struct ini_items *item);
72
73 /* If no items are registred at the scan time, we detect this list from
74  * the file itself
75  */
76 struct ini_items {
77    const char *name;            /* keyword name */
78    INI_ITEM_HANDLER *handler;   /* type accepted */
79    const char *comment;         /* comment associated, used in prompt */
80
81    int required;                /* optional required or not */
82    const char *default_value;   /* optional default value */
83
84    const char *re_value;        /* optional regexp associated */
85    const char *in_values;       /* optional list of values */
86
87    bool found;                  /* if val is set */
88    item_value val;              /* val contains the value */
89 };
90
91 /* When reading a ini file, we limit the number of items that we
92  *  can create
93  */
94 #define MAX_INI_ITEMS 32
95
96 /* Special RestoreObject name used to get user input at restore time */
97 #define INI_RESTORE_OBJECT_NAME    "RestoreOptions"
98
99 /* Can be used to set re_value, in_value, default_value, found and val to 0
100  * G++ looks to allow partial declaration, let see with an other compiler
101  */
102 #define ITEMS_DEFAULT    NULL,NULL,NULL,0,{0}
103
104 /*
105  * Handle simple configuration file such as "ini" files.
106  * key1 = val               # comment
107  * OptPrompt=comment
108  * key2 = val
109  *
110  * For usage example, see ini.c TEST_PROGRAM
111  */
112
113 class ConfigFile
114 {
115 private:
116    LEX *lc;                     /* Lex parser */
117    bool items_allocated;
118
119 public:
120    JCR *jcr;                    /* JCR needed for Jmsg */
121    int version;                 /* Internal version check */
122    int sizeof_ini_items;        /* Extra check when using dynamic loading */
123    bool unlink_temp_file;       /* Unlink temp file when destroying object */
124    struct ini_items *items;     /* Structure of the config file */
125    POOLMEM *out_fname;          /* Can be used to dump config to disk */
126    POOLMEM *edit;               /* Can be used to build result file */
127    char *plugin_name;           /* Used to store owner of this ConfigFile */
128
129    ConfigFile() {
130       lc = NULL;
131       jcr = NULL;
132       items = NULL;
133       out_fname = NULL;
134       plugin_name = NULL;
135
136       version = 1;
137       items_allocated = false;
138       unlink_temp_file = true;
139       edit = get_pool_memory(PM_FNAME);
140       edit[0] = 0;
141       sizeof_ini_items = sizeof(struct ini_items);
142    }
143
144    ~ConfigFile() {
145       if (lc) {
146          lex_close_file(lc);
147       }
148       if (edit) {
149          free_pool_memory(edit);
150       }
151       if (out_fname) {
152          if (unlink_temp_file) {
153             unlink(out_fname);
154          }
155          free_pool_memory(out_fname);
156       }
157       if (plugin_name) {
158          free(plugin_name);
159       }
160       clear_items();
161       free_items();
162    }
163
164    /* Dump a config string to out_fname */
165    bool dump_string(const char *buf, int32_t len);
166
167    void set_plugin_name(char *n) {
168       if (plugin_name) {
169          free(plugin_name);
170       }
171       plugin_name = bstrdup(n);
172    }
173
174    /* JCR needed for Jmsg */
175    void set_jcr(JCR *ajcr) {
176       jcr = ajcr;
177    }
178
179    void set_unlink_temp_file(bool val) {
180       unlink_temp_file = val;
181    }
182
183    /* Free malloced items such as char* or alist or items */
184    void free_items();
185
186    /* Clear items member */
187    void clear_items();
188
189    /* Dump the item table to a file (used on plugin side) */
190    bool serialize(const char *fname);
191
192    /* Dump the item table format to a buffer (used on plugin side)
193     * returns the length of the buffer, -1 if error
194     */
195    int serialize(POOLMEM **buf);
196
197    /* Dump the item table content to a buffer */
198    int dump_results(POOLMEM **buf);
199
200    /* Get item position in items list (useful when dynamic) */
201    int get_item(const char *name);
202
203    /* Register config file structure, if size doesn't match */
204    bool register_items(struct ini_items *aitems, int size) {
205       int i;
206       if (sizeof_ini_items == size) {
207          for (i = 0; aitems[i].name ; i++);
208          items = (struct ini_items*) malloc((i+1) * size); /* NULL terminated */
209          memcpy(items, aitems, (i+1) * size);
210          items_allocated = false; /* we copy only pointers, don't free them */
211          return true;
212       }
213       return false;
214    }
215
216    /* Parse a ini file with a item list previously registred (plugin side) */
217    bool parse(const char *filename);
218
219    /* Create a item list from a ini file (director side) */
220    bool unserialize(const char *filename);
221
222    /* Get Menu for an entry */
223    char *get_menu(int index, POOLMEM **dest);
224
225    /* Check if an entry is a part of a menu */
226    bool is_in_menu(int index, const char *menu);
227 };
228
229 /*
230  * Standard global parsers defined in ini.c
231  * When called with lc=NULL, it converts the item value back in inifile->edit
232  * buffer.
233  */
234 bool ini_store_str(LEX *lc, ConfigFile *inifile, ini_items *item);
235 bool ini_store_name(LEX *lc, ConfigFile *inifile, ini_items *item);
236 bool ini_store_alist_str(LEX *lc, ConfigFile *inifile, ini_items *item);
237 bool ini_store_pint64(LEX *lc, ConfigFile *inifile, ini_items *item);
238 bool ini_store_int64(LEX *lc, ConfigFile *inifile, ini_items *item);
239 bool ini_store_pint32(LEX *lc, ConfigFile *inifile, ini_items *item);
240 bool ini_store_int32(LEX *lc, ConfigFile *inifile, ini_items *item);
241 bool ini_store_bool(LEX *lc, ConfigFile *inifile, ini_items *item);
242
243 /* Get handler code from handler @ */
244 const char *ini_get_store_code(INI_ITEM_HANDLER *handler);
245
246 /* Get handler function from handler name */
247 INI_ITEM_HANDLER *ini_get_store_handler(const char *);
248
249 #endif