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