]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/ini.h
Fix get_basename() -- rewrite
[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 *re_value;        /* optional regexp associated */
83    const char *in_values;       /* optional list of values */
84    const char *default_value;   /* optional default value */
85
86    bool found;                  /* if val is set */
87    item_value val;              /* val contains the value */
88 };
89
90 /* When reading a ini file, we limit the number of items that we
91  *  can create
92  */
93 #define MAX_INI_ITEMS 32
94
95 /* Special RestoreObject name used to get user input at restore time */
96 #define INI_RESTORE_OBJECT_NAME    "RestoreOptions"
97
98 /* Can be used to set re_value, in_value, default_value, found and val to 0
99  * G++ looks to allow partial declaration, let see with an other compiler
100  */
101 #define ITEMS_DEFAULT    NULL,NULL,NULL,0,{0}
102
103 /*
104  * Handle simple configuration file such as "ini" files.
105  * key1 = val               # comment
106  * OptPrompt=comment
107  * key2 = val
108  *
109  * For usage example, see ini.c TEST_PROGRAM
110  */
111
112 class ConfigFile
113 {
114 private:
115    LEX *lc;                     /* Lex parser */
116    bool items_allocated;
117
118 public:
119    JCR *jcr;                    /* JCR needed for Jmsg */
120    int version;                 /* Internal version check */
121    int sizeof_ini_items;        /* Extra check when using dynamic loading */
122    struct ini_items *items;     /* Structure of the config file */
123    POOLMEM *out_fname;          /* Can be used to dump config to disk */
124    POOLMEM *edit;               /* Can be used to build result file */
125
126    ConfigFile() {
127       lc = NULL;
128       jcr = NULL;
129       items = NULL;
130       out_fname = NULL;
131
132       version = 1;
133       items_allocated = false;
134       edit = get_pool_memory(PM_FNAME);
135       sizeof_ini_items = sizeof(struct ini_items);
136    }
137
138    ~ConfigFile() {
139       if (lc) {
140          lex_close_file(lc);
141       }
142       if (edit) {
143          free_pool_memory(edit);
144       }
145       if (out_fname) {
146          unlink(out_fname);
147          free_pool_memory(out_fname);
148       }
149       free_items();
150    }
151
152    /* Dump a config string to out_fname */
153    bool dump_string(const char *buf, int32_t len);
154
155    /* JCR needed for Jmsg */
156    void set_jcr(JCR *ajcr) {
157       jcr = ajcr;
158    }
159
160    /* Free malloced items such as char* or alist or items */
161    void free_items();
162
163    /* Clear items member */
164    void clear_items();
165
166    /* Dump the item table to a file (used on plugin side) */
167    bool serialize(const char *fname);
168
169    /* Dump the item table format to a buffer (used on plugin side) 
170     * returns the length of the buffer, -1 if error
171     */
172    int serialize(POOLMEM **buf);
173
174    /* Dump the item table content to a buffer */
175    int dump_results(POOLMEM **buf);
176
177    /* Get item position in items list (useful when dynamic) */
178    int get_item(const char *name);
179
180    /* Register config file structure, if size doesn't match */
181    bool register_items(struct ini_items *aitems, int size) {
182       int i;
183       if (sizeof_ini_items == size) {
184          for (i = 0; aitems[i].name ; i++);
185          items = (struct ini_items*) malloc((i+1) * size); /* NULL terminated */
186          memcpy(items, aitems, (i+1) * size);
187          items_allocated = false; /* we copy only pointers, don't free them */
188          return true;
189       }
190       return false;
191    }
192    
193    /* Parse a ini file with a item list previously registred (plugin side) */
194    bool parse(const char *filename);
195
196    /* Create a item list from a ini file (director side) */
197    bool unserialize(const char *filename);
198 };
199                               
200 /*
201  * Standard global parsers defined in ini.c
202  * When called with lc=NULL, it converts the item value back in inifile->edit
203  * buffer.
204  */
205 bool ini_store_str(LEX *lc, ConfigFile *inifile, ini_items *item);
206 bool ini_store_name(LEX *lc, ConfigFile *inifile, ini_items *item);
207 bool ini_store_alist_str(LEX *lc, ConfigFile *inifile, ini_items *item);
208 bool ini_store_pint64(LEX *lc, ConfigFile *inifile, ini_items *item);
209 bool ini_store_int64(LEX *lc, ConfigFile *inifile, ini_items *item);
210 bool ini_store_pint32(LEX *lc, ConfigFile *inifile, ini_items *item);
211 bool ini_store_int32(LEX *lc, ConfigFile *inifile, ini_items *item);
212 bool ini_store_bool(LEX *lc, ConfigFile *inifile, ini_items *item);
213
214 /* Get handler code from handler @ */
215 const char *ini_get_store_code(INI_ITEM_HANDLER *handler);
216
217 /* Get handler function from handler name */
218 INI_ITEM_HANDLER *ini_get_store_handler(const char *);
219
220 #endif