]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/gnome2-console/console_conf.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / gnome2-console / console_conf.c
1 /*
2  *   Main configuration file parser for Bacula User Agent
3  *    some parts may be split into separate files such as
4  *    the schedule configuration (sch_config.c).
5  *
6  *   Note, the configuration file parser consists of three parts
7  *
8  *   1. The generic lexical scanner in lib/lex.c and lib/lex.h
9  *
10  *   2. The generic config  scanner in lib/parse_config.c and
11  *      lib/parse_config.h.
12  *      These files contain the parser code, some utility
13  *      routines, and the common store routines (name, int,
14  *      string).
15  *
16  *   3. The daemon specific file, which contains the Resource
17  *      definitions as well as any specific store routines
18  *      for the resource records.
19  *
20  *     Kern Sibbald, January MM, September MM
21  *
22  *     Version $Id$
23  */
24 /*
25    Copyright (C) 2000-2005 Kern Sibbald
26
27    This program is free software; you can redistribute it and/or
28    modify it under the terms of the GNU General Public License
29    version 2 as amended with additional clauses defined in the
30    file LICENSE in the main source directory.
31
32    This program is distributed in the hope that it will be useful,
33    but WITHOUT ANY WARRANTY; without even the implied warranty of
34    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
35    the file LICENSE for additional details.
36
37  */
38
39 #include "bacula.h"
40 #include "console_conf.h"
41
42 /* Define the first and last resource ID record
43  * types. Note, these should be unique for each
44  * daemon though not a requirement.
45  */
46 int r_first = R_FIRST;
47 int r_last  = R_LAST;
48 static RES *sres_head[R_LAST - R_FIRST + 1];
49 RES **res_head = sres_head;
50
51 /* Forward referenced subroutines */
52
53
54 /* We build the current resource here as we are
55  * scanning the resource configuration definition,
56  * then move it to allocated memory when the resource
57  * scan is complete.
58  */
59 URES res_all;
60 int  res_all_size = sizeof(res_all);
61
62 /* Definition of records permitted within each
63  * resource with the routine to process the record
64  * information.
65  */
66 static RES_ITEM dir_items[] = {
67    {"name",        store_name,     ITEM(dir_res.hdr.name), 0, ITEM_REQUIRED, 0},
68    {"description", store_str,      ITEM(dir_res.hdr.desc), 0, 0, 0},
69    {"dirport",     store_int,      ITEM(dir_res.DIRport),  0, ITEM_DEFAULT, 9101},
70    {"address",     store_str,      ITEM(dir_res.address),  0, ITEM_REQUIRED, 0},
71    {"password",    store_password, ITEM(dir_res.password), 0, 0, 0},
72    {"tlsenable",      store_yesno,     ITEM(dir_res.tls_enable), 1, 0, 0},
73    {"tlsrequire",     store_yesno,     ITEM(dir_res.tls_require), 1, 0, 0},
74    {"tlscacertificatefile", store_dir, ITEM(dir_res.tls_ca_certfile), 0, 0, 0},
75    {"tlscacertificatedir", store_dir,  ITEM(dir_res.tls_ca_certdir), 0, 0, 0},
76    {"tlscertificate", store_dir,       ITEM(dir_res.tls_certfile), 0, 0, 0},
77    {"tlskey",         store_dir,       ITEM(dir_res.tls_keyfile), 0, 0, 0},
78    {NULL, NULL, NULL, 0, 0, 0}
79 };
80
81 static RES_ITEM con_items[] = {
82    {"name",        store_name,     ITEM(con_res.hdr.name), 0, ITEM_REQUIRED, 0},
83    {"description", store_str,      ITEM(con_res.hdr.desc), 0, 0, 0},
84    {"password",    store_password, ITEM(con_res.password), 0, ITEM_REQUIRED, 0},
85    {"tlsenable",      store_yesno,     ITEM(con_res.tls_enable), 1, 0, 0},
86    {"tlsrequire",     store_yesno,     ITEM(con_res.tls_require), 1, 0, 0},
87    {"tlscacertificatefile", store_dir, ITEM(con_res.tls_ca_certfile), 0, 0, 0},
88    {"tlscacertificatedir", store_dir,  ITEM(con_res.tls_ca_certdir), 0, 0, 0},
89    {"tlscertificate", store_dir,       ITEM(con_res.tls_certfile), 0, 0, 0},
90    {"tlskey",         store_dir,       ITEM(con_res.tls_keyfile), 0, 0, 0},
91    {NULL, NULL, NULL, 0, 0, 0}
92 };
93
94 static RES_ITEM con_font_items[] = {
95    {"name",        store_name,     ITEM(con_font.hdr.name), 0, ITEM_REQUIRED, 0},
96    {"description", store_str,      ITEM(con_font.hdr.desc), 0, 0, 0},
97    {"font",        store_str,      ITEM(con_font.fontface), 0, 0, 0},
98    {"requiressl",  store_yesno,    ITEM(con_font.require_ssl), 1, ITEM_DEFAULT, 0},
99    {NULL, NULL, NULL, 0, 0, 0}
100 };
101
102
103 /*
104  * This is the master resource definition.
105  * It must have one item for each of the resources.
106  */
107 RES_TABLE resources[] = {
108    {"director",      dir_items,   R_DIRECTOR},
109    {"console",       con_items,   R_CONSOLE},
110    {"consolefont",   con_font_items, R_CONSOLE_FONT},
111    {NULL,            NULL,        0}
112 };
113
114
115 /* Dump contents of resource */
116 void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock)
117 {
118    URES *res = (URES *)reshdr;
119    bool recurse = true;
120
121    if (res == NULL) {
122       printf(_("No record for %d %s\n"), type, res_to_str(type));
123       return;
124    }
125    if (type < 0) {                    /* no recursion */
126       type = - type;
127       recurse = false;
128    }
129    switch (type) {
130    case R_DIRECTOR:
131       printf(_("Director: name=%s address=%s DIRport=%d\n"), reshdr->name,
132               res->dir_res.address, res->dir_res.DIRport);
133       break;
134    case R_CONSOLE:
135       printf(_("Console: name=%s\n"), reshdr->name);
136       break;
137    case R_CONSOLE_FONT:
138       printf(_("ConsoleFont: name=%s font face=%s\n"),
139              reshdr->name, NPRT(res->con_font.fontface));
140       break;
141    default:
142       printf(_("Unknown resource type %d\n"), type);
143    }
144    if (recurse && res->dir_res.hdr.next) {
145       dump_resource(type, res->dir_res.hdr.next, sendit, sock);
146    }
147 }
148
149 /*
150  * Free memory of resource.
151  * NB, we don't need to worry about freeing any references
152  * to other resources as they will be freed when that
153  * resource chain is traversed.  Mainly we worry about freeing
154  * allocated strings (names).
155  */
156 void free_resource(RES *sres, int type)
157 {
158    RES *nres;
159    URES *res = (URES *)sres;
160
161    if (res == NULL)
162       return;
163
164    /* common stuff -- free the resource name */
165    nres = (RES *)res->dir_res.hdr.next;
166    if (res->dir_res.hdr.name) {
167       free(res->dir_res.hdr.name);
168    }
169    if (res->dir_res.hdr.desc) {
170       free(res->dir_res.hdr.desc);
171    }
172
173    switch (type) {
174    case R_DIRECTOR:
175       if (res->dir_res.address) {
176          free(res->dir_res.address);
177       }
178       if (res->dir_res.tls_ctx) { 
179          free_tls_context(res->dir_res.tls_ctx);
180       }
181       if (res->dir_res.tls_ca_certfile) {
182          free(res->dir_res.tls_ca_certfile);
183       }
184       if (res->dir_res.tls_ca_certdir) {
185          free(res->dir_res.tls_ca_certdir);
186       }
187       if (res->dir_res.tls_certfile) {
188          free(res->dir_res.tls_certfile);
189       }
190       if (res->dir_res.tls_keyfile) {
191          free(res->dir_res.tls_keyfile);
192       }
193       break;
194    case R_CONSOLE:
195       if (res->con_res.password) {
196          free(res->con_res.password);
197       }
198       if (res->con_res.tls_ctx) { 
199          free_tls_context(res->con_res.tls_ctx);
200       }
201       if (res->con_res.tls_ca_certfile) {
202          free(res->con_res.tls_ca_certfile);
203       }
204       if (res->con_res.tls_ca_certdir) {
205          free(res->con_res.tls_ca_certdir);
206       }
207       if (res->con_res.tls_certfile) {
208          free(res->con_res.tls_certfile);
209       }
210       if (res->con_res.tls_keyfile) {
211          free(res->con_res.tls_keyfile);
212       }
213       break;
214    case R_CONSOLE_FONT:
215       if (res->con_font.fontface) {
216          free(res->con_font.fontface);
217       }
218       break;
219    default:
220       printf(_("Unknown resource type %d\n"), type);
221    }
222    /* Common stuff again -- free the resource, recurse to next one */
223    free(res);
224    if (nres) {
225       free_resource(nres, type);
226    }
227 }
228
229 /* Save the new resource by chaining it into the head list for
230  * the resource. If this is pass 2, we update any resource
231  * pointers (currently only in the Job resource).
232  */
233 void save_resource(int type, RES_ITEM *items, int pass)
234 {
235    URES *res;
236    int rindex = type - r_first;
237    int i, size = 0;
238    int error = 0;
239
240    /*
241     * Ensure that all required items are present
242     */
243    for (i=0; items[i].name; i++) {
244       if (items[i].flags & ITEM_REQUIRED) {
245             if (!bit_is_set(i, res_all.dir_res.hdr.item_present)) {
246                Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
247                  items[i].name, resources[rindex]);
248              }
249       }
250    }
251
252    /* During pass 2, we looked up pointers to all the resources
253     * referrenced in the current resource, , now we
254     * must copy their address from the static record to the allocated
255     * record.
256     */
257    if (pass == 2) {
258       switch (type) {
259       /* Resources not containing a resource */
260       case R_DIRECTOR:
261          break;
262
263       case R_CONSOLE:
264       case R_CONSOLE_FONT:
265          break;
266
267       default:
268          Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
269          error = 1;
270          break;
271       }
272       /* Note, the resoure name was already saved during pass 1,
273        * so here, we can just release it.
274        */
275       if (res_all.dir_res.hdr.name) {
276          free(res_all.dir_res.hdr.name);
277          res_all.dir_res.hdr.name = NULL;
278       }
279       if (res_all.dir_res.hdr.desc) {
280          free(res_all.dir_res.hdr.desc);
281          res_all.dir_res.hdr.desc = NULL;
282       }
283       return;
284    }
285
286    /* The following code is only executed during pass 1 */
287    switch (type) {
288    case R_DIRECTOR:
289       size = sizeof(DIRRES);
290       break;
291    case R_CONSOLE_FONT:
292       size = sizeof(CONFONTRES);
293       break;
294    case R_CONSOLE:
295       size = sizeof(CONRES);
296       break;
297    default:
298       printf(_("Unknown resource type %d\n"), type);
299       error = 1;
300       break;
301    }
302    /* Common */
303    if (!error) {
304       res = (URES *)malloc(size);
305       memcpy(res, &res_all, size);
306       if (!res_head[rindex]) {
307          res_head[rindex] = (RES *)res; /* store first entry */
308       } else {
309          RES *next;
310          /* Add new res to end of chain */
311          for (next=res_head[rindex]; next->next; next=next->next) {
312             if (strcmp(next->name, res->dir_res.hdr.name) == 0) {
313                Emsg2(M_ERROR_TERM, 0,
314                   _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
315                   resources[rindex].name, res->dir_res.hdr.name);
316             }
317          }
318          next->next = (RES *)res;
319          Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
320                res->dir_res.hdr.name);
321       }
322    }
323 }