1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* config-parser.c XML-library-agnostic configuration file parser
4 * Copyright (C) 2003 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "config-parser.h"
25 #include <dbus/dbus-list.h>
26 #include <dbus/dbus-internals.h>
48 BusConfigParser *parser;
83 struct BusConfigParser
87 DBusList *stack; /**< stack of Element */
89 char *user; /**< user to run as */
94 push_element (BusConfigParser *parser,
99 e = dbus_new0 (Element, 1);
109 pop_element (BusConfigParser *parser)
113 e = _dbus_list_pop_last (&parser->stack);
119 bus_config_parser_new (void)
121 BusConfigParser *parser;
123 parser = dbus_new0 (BusConfigParser, 1);
127 parser->refcount = 1;
133 bus_config_parser_ref (BusConfigParser *parser)
135 _dbus_assert (parser->refcount > 0);
137 parser->refcount += 1;
141 bus_config_parser_unref (BusConfigParser *parser)
143 _dbus_assert (parser->refcount > 0);
145 parser->refcount -= 1;
147 if (parser->refcount == 0)
149 while (parser->stack != NULL)
150 pop_element (parser);
152 dbus_free (parser->user);
159 bus_config_parser_check_doctype (BusConfigParser *parser,
163 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
165 if (strcmp (doctype, "busconfig") != 0)
167 dbus_set_error (error,
169 "Document has the wrong type %s",
178 bus_config_parser_start_element (BusConfigParser *parser,
179 const char *element_name,
180 const char **attribute_names,
181 const char **attribute_values,
184 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
190 bus_config_parser_end_element (BusConfigParser *parser,
191 const char *element_name,
194 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
200 bus_config_parser_content (BusConfigParser *parser,
201 const DBusString *content,
204 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
210 bus_config_parser_finished (BusConfigParser *parser,
213 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
219 bus_config_parser_get_user (BusConfigParser *parser)
226 #ifdef DBUS_BUILD_TESTS
237 do_load (const DBusString *full_path,
239 dbus_bool_t oom_possible)
241 BusConfigParser *parser;
244 dbus_error_init (&error);
246 parser = bus_config_load (full_path, &error);
249 _DBUS_ASSERT_ERROR_IS_SET (&error);
252 dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
254 _dbus_verbose ("Failed to load valid file due to OOM\n");
255 dbus_error_free (&error);
258 else if (validity == VALID)
260 _dbus_warn ("Failed to load valid file but still had memory: %s\n",
263 dbus_error_free (&error);
268 dbus_error_free (&error);
274 _DBUS_ASSERT_ERROR_IS_CLEAR (&error);
276 bus_config_parser_unref (parser);
278 if (validity == INVALID)
280 _dbus_warn ("Accepted invalid file\n");
289 check_oom_loading (const DBusString *full_path,
294 /* Run once to see about how many mallocs are involved */
296 _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
298 if (!do_load (full_path, validity, FALSE))
301 approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
303 _dbus_verbose ("=================\nabout %d mallocs total\n=================\n",
306 approx_mallocs += 10; /* fudge factor */
308 /* Now run failing each malloc */
310 while (approx_mallocs >= 0)
313 _dbus_set_fail_alloc_counter (approx_mallocs);
315 _dbus_verbose ("\n===\n(will fail malloc %d)\n===\n",
318 if (!do_load (full_path, validity, TRUE))
324 _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
326 _dbus_verbose ("=================\n all iterations passed\n=================\n");
332 process_test_subdir (const DBusString *test_base_dir,
336 DBusString test_directory;
345 if (!_dbus_string_init (&test_directory, _DBUS_INT_MAX))
346 _dbus_assert_not_reached ("didn't allocate test_directory\n");
348 _dbus_string_init_const (&filename, subdir);
350 if (!_dbus_string_copy (test_base_dir, 0,
352 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
354 if (!_dbus_concat_dir_and_file (&test_directory, &filename))
355 _dbus_assert_not_reached ("couldn't allocate full path");
357 _dbus_string_free (&filename);
358 if (!_dbus_string_init (&filename, _DBUS_INT_MAX))
359 _dbus_assert_not_reached ("didn't allocate filename string\n");
361 dbus_error_init (&error);
362 dir = _dbus_directory_open (&test_directory, &error);
366 _dbus_string_get_const_data (&test_directory, &s);
367 _dbus_warn ("Could not open %s: %s\n", s,
369 dbus_error_free (&error);
373 printf ("Testing:\n");
376 while (_dbus_directory_get_next_file (dir, &filename, &error))
378 DBusString full_path;
380 if (!_dbus_string_init (&full_path, _DBUS_INT_MAX))
381 _dbus_assert_not_reached ("couldn't init string");
383 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
384 _dbus_assert_not_reached ("couldn't copy dir to full_path");
386 if (!_dbus_concat_dir_and_file (&full_path, &filename))
387 _dbus_assert_not_reached ("couldn't concat file to dir");
389 if (!_dbus_string_ends_with_c_str (&full_path, ".conf"))
391 const char *filename_c;
392 _dbus_string_get_const_data (&filename, &filename_c);
393 _dbus_verbose ("Skipping non-.conf file %s\n",
395 _dbus_string_free (&full_path);
401 _dbus_string_get_const_data (&filename, &s);
405 _dbus_verbose (" expecting %s\n",
406 validity == VALID ? "valid" :
407 (validity == INVALID ? "invalid" :
408 (validity == UNKNOWN ? "unknown" : "???")));
410 if (!check_oom_loading (&full_path, validity))
411 _dbus_assert_not_reached ("test failed");
413 _dbus_string_free (&full_path);
416 if (dbus_error_is_set (&error))
419 _dbus_string_get_const_data (&test_directory, &s);
420 _dbus_warn ("Could not get next file in %s: %s\n",
422 dbus_error_free (&error);
431 _dbus_directory_close (dir);
432 _dbus_string_free (&test_directory);
433 _dbus_string_free (&filename);
439 bus_config_parser_test (const DBusString *test_data_dir)
441 if (test_data_dir == NULL ||
442 _dbus_string_get_length (test_data_dir) == 0)
444 printf ("No test data\n");
448 if (!process_test_subdir (test_data_dir, "valid-config-files", VALID))
454 #endif /* DBUS_BUILD_TESTS */