From 94790fef4a846ef2bed9bf1825c4c2b0ca7b8566 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 2 Apr 2003 21:43:29 +0000 Subject: [PATCH] 2003-04-02 Havoc Pennington * dbus/dbus-sysdeps.c (_dbus_file_get_contents): include filenames in error messages (_dbus_string_get_dirname): new (_dbus_sysdeps_test): new (_dbus_directory_open): include dirnames in error messages * bus/config-parser.c: interpret and and relative to config file location if the given filename is not absolute. * dbus/dbus-string.c (_dbus_string_find_byte_backward): new --- ChangeLog | 14 + bus/config-loader-expat.c | 20 +- bus/config-parser.c | 157 +++++++++-- bus/config-parser.h | 2 +- dbus/dbus-string.c | 56 ++++ dbus/dbus-string.h | 351 +++++++++++------------- dbus/dbus-sysdeps.c | 172 +++++++++++- dbus/dbus-sysdeps.h | 3 + dbus/dbus-test.c | 6 + dbus/dbus-test.h | 1 + test/data/valid-config-files/basic.d/basic.conf | 13 + 11 files changed, 573 insertions(+), 222 deletions(-) create mode 100644 test/data/valid-config-files/basic.d/basic.conf diff --git a/ChangeLog b/ChangeLog index 6a819e9..e72e8a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2003-04-02 Havoc Pennington + * dbus/dbus-sysdeps.c (_dbus_file_get_contents): include filenames + in error messages + (_dbus_string_get_dirname): new + (_dbus_sysdeps_test): new + (_dbus_directory_open): include dirnames in error messages + + * bus/config-parser.c: interpret and and + relative to config file location if the given + filename is not absolute. + + * dbus/dbus-string.c (_dbus_string_find_byte_backward): new + +2003-04-02 Havoc Pennington + * bus/connection.c (bus_transaction_send_error_reply): set sender service for the error, and unref the reply on success diff --git a/bus/config-loader-expat.c b/bus/config-loader-expat.c index 9e6de5e..372a886 100644 --- a/bus/config-loader-expat.c +++ b/bus/config-loader-expat.c @@ -170,7 +170,8 @@ bus_config_load (const DBusString *file, const char *filename; BusConfigParser *parser; ExpatParseContext context; - + DBusString dirname; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); parser = NULL; @@ -186,6 +187,13 @@ bus_config_load (const DBusString *file, return NULL; } + if (!_dbus_string_init (&dirname)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&context.content); + return NULL; + } + expat = XML_ParserCreate_MM ("UTF-8", &memsuite, NULL); if (expat == NULL) { @@ -193,7 +201,13 @@ bus_config_load (const DBusString *file, goto failed; } - parser = bus_config_parser_new (); + if (!_dbus_string_get_dirname (file, &dirname)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed; + } + + parser = bus_config_parser_new (&dirname); if (parser == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); @@ -258,6 +272,7 @@ bus_config_load (const DBusString *file, if (!bus_config_parser_finished (parser, error)) goto failed; + _dbus_string_free (&dirname); _dbus_string_free (&context.content); XML_ParserFree (expat); @@ -267,6 +282,7 @@ bus_config_load (const DBusString *file, failed: _DBUS_ASSERT_ERROR_IS_SET (error); + _dbus_string_free (&dirname); _dbus_string_free (&context.content); if (expat) XML_ParserFree (expat); diff --git a/bus/config-parser.c b/bus/config-parser.c index 77b68ca..9e16e4f 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -22,6 +22,7 @@ */ #include "config-parser.h" #include "test.h" +#include "utils.h" #include #include #include @@ -82,6 +83,8 @@ struct BusConfigParser { int refcount; + DBusString basedir; /**< Directory we resolve paths relative to */ + DBusList *stack; /**< stack of Element */ char *user; /**< user to run as */ @@ -226,7 +229,7 @@ merge_included (BusConfigParser *parser, } BusConfigParser* -bus_config_parser_new (void) +bus_config_parser_new (const DBusString *basedir) { BusConfigParser *parser; @@ -234,6 +237,19 @@ bus_config_parser_new (void) if (parser == NULL) return NULL; + if (!_dbus_string_init (&parser->basedir)) + { + dbus_free (parser); + return NULL; + } + + if (!_dbus_string_copy (basedir, 0, &parser->basedir, 0)) + { + _dbus_string_free (&parser->basedir); + dbus_free (parser); + return NULL; + } + parser->refcount = 1; return parser; @@ -272,6 +288,8 @@ bus_config_parser_unref (BusConfigParser *parser) NULL); _dbus_list_clear (&parser->service_dirs); + + _dbus_string_free (&parser->basedir); dbus_free (parser); } @@ -760,6 +778,27 @@ all_whitespace (const DBusString *str) } static dbus_bool_t +make_full_path (const DBusString *basedir, + const DBusString *filename, + DBusString *full_path) +{ + if (_dbus_path_is_absolute (filename)) + { + return _dbus_string_copy (filename, 0, full_path, 0); + } + else + { + if (!_dbus_string_copy (basedir, 0, full_path, 0)) + return FALSE; + + if (!_dbus_concat_dir_and_file (full_path, filename)) + return FALSE; + + return TRUE; + } +} + +static dbus_bool_t include_file (BusConfigParser *parser, const DBusString *filename, dbus_bool_t ignore_missing, @@ -817,35 +856,52 @@ include_dir (BusConfigParser *parser, if (!_dbus_string_init (&filename)) { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + BUS_SET_OOM (error); return FALSE; } retval = FALSE; dir = _dbus_directory_open (dirname, error); - - /* FIXME this is just so the tests pass for now, it needs to come out - * once I implement make-dirname-relative-to-currently-parsed-files-dir - */ - if (dir == NULL) - { - if (error) - dbus_error_free (error); - _dbus_string_free (&filename); - return TRUE; - } if (dir == NULL) goto failed; - + + dbus_error_init (&tmp_error); while (_dbus_directory_get_next_file (dir, &filename, &tmp_error)) { - if (_dbus_string_ends_with_c_str (&filename, ".conf")) + DBusString full_path; + + if (!_dbus_string_init (&full_path)) + { + BUS_SET_OOM (error); + goto failed; + } + + if (!_dbus_string_copy (dirname, 0, &full_path, 0)) + { + BUS_SET_OOM (error); + _dbus_string_free (&full_path); + goto failed; + } + + if (!_dbus_concat_dir_and_file (&full_path, &filename)) + { + BUS_SET_OOM (error); + _dbus_string_free (&full_path); + goto failed; + } + + if (_dbus_string_ends_with_c_str (&full_path, ".conf")) { - if (!include_file (parser, &filename, TRUE, error)) - goto failed; + if (!include_file (parser, &full_path, TRUE, error)) + { + _dbus_string_free (&full_path); + goto failed; + } } + + _dbus_string_free (&full_path); } if (dbus_error_is_set (&tmp_error)) @@ -921,20 +977,52 @@ bus_config_parser_content (BusConfigParser *parser, case ELEMENT_INCLUDE: { + DBusString full_path; + e->had_content = TRUE; - if (!include_file (parser, content, + if (!_dbus_string_init (&full_path)) + goto nomem; + + if (!make_full_path (&parser->basedir, content, &full_path)) + { + _dbus_string_free (&full_path); + goto nomem; + } + + if (!include_file (parser, &full_path, e->d.include.ignore_missing, error)) - return FALSE; + { + _dbus_string_free (&full_path); + return FALSE; + } + + _dbus_string_free (&full_path); } break; case ELEMENT_INCLUDEDIR: { + DBusString full_path; + e->had_content = TRUE; + + if (!_dbus_string_init (&full_path)) + goto nomem; - if (!include_dir (parser, content, error)) - return FALSE; + if (!make_full_path (&parser->basedir, content, &full_path)) + { + _dbus_string_free (&full_path); + goto nomem; + } + + if (!include_dir (parser, &full_path, error)) + { + _dbus_string_free (&full_path); + return FALSE; + } + + _dbus_string_free (&full_path); } break; @@ -991,18 +1079,33 @@ bus_config_parser_content (BusConfigParser *parser, case ELEMENT_SERVICEDIR: { char *s; - - e->had_content = TRUE; + DBusString full_path; - if (!_dbus_string_copy_data (content, &s)) + e->had_content = TRUE; + + if (!_dbus_string_init (&full_path)) goto nomem; + + if (!make_full_path (&parser->basedir, content, &full_path)) + { + _dbus_string_free (&full_path); + goto nomem; + } + + if (!_dbus_string_copy_data (&full_path, &s)) + { + _dbus_string_free (&full_path); + goto nomem; + } - if (!_dbus_list_append (&parser->service_dirs, - s)) + if (!_dbus_list_append (&parser->service_dirs, s)) { + _dbus_string_free (&full_path); dbus_free (s); goto nomem; } + + _dbus_string_free (&full_path); } break; } @@ -1011,7 +1114,7 @@ bus_config_parser_content (BusConfigParser *parser, return TRUE; nomem: - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + BUS_SET_OOM (error); return FALSE; } diff --git a/bus/config-parser.h b/bus/config-parser.h index d06cde0..9b433f0 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -34,7 +34,7 @@ typedef struct BusConfigParser BusConfigParser; -BusConfigParser* bus_config_parser_new (void); +BusConfigParser* bus_config_parser_new (const DBusString *basedir); void bus_config_parser_ref (BusConfigParser *parser); void bus_config_parser_unref (BusConfigParser *parser); dbus_bool_t bus_config_parser_check_doctype (BusConfigParser *parser, diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 305b488..dd5781f 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1449,6 +1449,42 @@ _dbus_string_find_to (const DBusString *str, } /** + * Find the given byte scanning backward from the given start. + * Sets *found to -1 if the byte is not found. + * + * @param str the string + * @param byte the byte to find + * @param found return location for where it was found + * @returns #TRUE if found + */ +dbus_bool_t +_dbus_string_find_byte_backward (const DBusString *str, + int start, + unsigned char byte, + int *found) +{ + int i; + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (start <= real->len); + _dbus_assert (start >= 0); + _dbus_assert (found != NULL); + + i = start - 1; + while (i >= 0) + { + if (real->str[i] == byte) + break; + + --i; + } + + if (found) + *found = i; + + return i >= 0; +} + +/** * Finds a blank (space or tab) in the string. Returns #TRUE * if found, #FALSE otherwise. If a blank is not found sets * *found to the length of the string. @@ -3145,6 +3181,26 @@ _dbus_string_test (void) if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) + _dbus_assert_not_reached ("Did not find 'H'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) + _dbus_assert_not_reached ("Did not find 'o'"); + _dbus_assert (i == _dbus_string_get_length (&str) - 1); + + if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) + _dbus_assert_not_reached ("Did find 'o'"); + _dbus_assert (i == -1); + + if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) + _dbus_assert_not_reached ("Did find 'e'"); + _dbus_assert (i == -1); + + if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) + _dbus_assert_not_reached ("Didn't find 'e'"); + _dbus_assert (i == 1); _dbus_string_free (&str); diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index ba0fcf8..065c9ca 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -45,192 +45,173 @@ struct DBusString unsigned int dummy8 : 3; /**< placeholder */ }; -dbus_bool_t _dbus_string_init (DBusString *str); -void _dbus_string_init_const (DBusString *str, - const char *value); -void _dbus_string_init_const_len (DBusString *str, - const char *value, - int len); -void _dbus_string_free (DBusString *str); -void _dbus_string_lock (DBusString *str); +dbus_bool_t _dbus_string_init (DBusString *str); +void _dbus_string_init_const (DBusString *str, + const char *value); +void _dbus_string_init_const_len (DBusString *str, + const char *value, + int len); +void _dbus_string_free (DBusString *str); +void _dbus_string_lock (DBusString *str); +char* _dbus_string_get_data (DBusString *str); +const char* _dbus_string_get_const_data (const DBusString *str); +char* _dbus_string_get_data_len (DBusString *str, + int start, + int len); +const char* _dbus_string_get_const_data_len (const DBusString *str, + int start, + int len); +void _dbus_string_set_byte (DBusString *str, + int i, + unsigned char byte); +unsigned char _dbus_string_get_byte (const DBusString *str, + int start); +dbus_bool_t _dbus_string_insert_byte (DBusString *str, + int i, + unsigned char byte); +dbus_bool_t _dbus_string_steal_data (DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_steal_data_len (DBusString *str, + char **data_return, + int start, + int len); +dbus_bool_t _dbus_string_copy_data (const DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len); +int _dbus_string_get_length (const DBusString *str); +dbus_bool_t _dbus_string_lengthen (DBusString *str, + int additional_length); +void _dbus_string_shorten (DBusString *str, + int length_to_remove); +dbus_bool_t _dbus_string_set_length (DBusString *str, + int length); +dbus_bool_t _dbus_string_align_length (DBusString *str, + int alignment); +dbus_bool_t _dbus_string_append (DBusString *str, + const char *buffer); +dbus_bool_t _dbus_string_append_len (DBusString *str, + const char *buffer, + int len); +dbus_bool_t _dbus_string_append_int (DBusString *str, + long value); +dbus_bool_t _dbus_string_append_uint (DBusString *str, + unsigned long value); +dbus_bool_t _dbus_string_append_double (DBusString *str, + double value); +dbus_bool_t _dbus_string_append_byte (DBusString *str, + unsigned char byte); +dbus_bool_t _dbus_string_append_unichar (DBusString *str, + dbus_unichar_t ch); +void _dbus_string_delete (DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_move (DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_move_len (DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_replace_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int replace_at, + int replace_len); +void _dbus_string_get_unichar (const DBusString *str, + int start, + dbus_unichar_t *ch_return, + int *end_return); +dbus_bool_t _dbus_string_parse_int (const DBusString *str, + int start, + long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_uint (const DBusString *str, + int start, + unsigned long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_double (const DBusString *str, + int start, + double *value, + int *end_return); +dbus_bool_t _dbus_string_find (const DBusString *str, + int start, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_to (const DBusString *str, + int start, + int end, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_byte_backward (const DBusString *str, + int start, + unsigned char byte, + int *found); +dbus_bool_t _dbus_string_find_blank (const DBusString *str, + int start, + int *found); +void _dbus_string_skip_blank (const DBusString *str, + int start, + int *end); +void _dbus_string_skip_white (const DBusString *str, + int start, + int *end); +dbus_bool_t _dbus_string_equal (const DBusString *a, + const DBusString *b); +dbus_bool_t _dbus_string_equal_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_equal_len (const DBusString *a, + const DBusString *b, + int len); +dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_pop_line (DBusString *source, + DBusString *dest); +void _dbus_string_delete_first_word (DBusString *str); +void _dbus_string_delete_leading_blanks (DBusString *str); +dbus_bool_t _dbus_string_base64_encode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_base64_decode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_hex_encode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_hex_decode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_validate_ascii (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_nul (const DBusString *str, + int start, + int len); +void _dbus_string_zero (DBusString *str); -char* _dbus_string_get_data (DBusString *str); -const char* _dbus_string_get_const_data (const DBusString *str); -char* _dbus_string_get_data_len (DBusString *str, - int start, - int len); -const char* _dbus_string_get_const_data_len (const DBusString *str, - int start, - int len); -void _dbus_string_set_byte (DBusString *str, - int i, - unsigned char byte); -unsigned char _dbus_string_get_byte (const DBusString *str, - int start); -dbus_bool_t _dbus_string_insert_byte (DBusString *str, - int i, - unsigned char byte); -dbus_bool_t _dbus_string_steal_data (DBusString *str, - char **data_return); -dbus_bool_t _dbus_string_steal_data_len (DBusString *str, - char **data_return, - int start, - int len); -dbus_bool_t _dbus_string_copy_data (const DBusString *str, - char **data_return); -dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, - char **data_return, - int start, - int len); - -int _dbus_string_get_length (const DBusString *str); - -dbus_bool_t _dbus_string_lengthen (DBusString *str, - int additional_length); -void _dbus_string_shorten (DBusString *str, - int length_to_remove); -dbus_bool_t _dbus_string_set_length (DBusString *str, - int length); -dbus_bool_t _dbus_string_align_length (DBusString *str, - int alignment); - -dbus_bool_t _dbus_string_append (DBusString *str, - const char *buffer); -dbus_bool_t _dbus_string_append_len (DBusString *str, - const char *buffer, - int len); -dbus_bool_t _dbus_string_append_int (DBusString *str, - long value); -dbus_bool_t _dbus_string_append_uint (DBusString *str, - unsigned long value); -dbus_bool_t _dbus_string_append_double (DBusString *str, - double value); -dbus_bool_t _dbus_string_append_byte (DBusString *str, - unsigned char byte); -dbus_bool_t _dbus_string_append_unichar (DBusString *str, - dbus_unichar_t ch); - - -void _dbus_string_delete (DBusString *str, - int start, - int len); -dbus_bool_t _dbus_string_move (DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_copy (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_move_len (DBusString *source, - int start, - int len, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_copy_len (const DBusString *source, - int start, - int len, - DBusString *dest, - int insert_at); - -dbus_bool_t _dbus_string_replace_len (const DBusString *source, - int start, - int len, - DBusString *dest, - int replace_at, - int replace_len); - -void _dbus_string_get_unichar (const DBusString *str, - int start, - dbus_unichar_t *ch_return, - int *end_return); - -dbus_bool_t _dbus_string_parse_int (const DBusString *str, - int start, - long *value_return, - int *end_return); -dbus_bool_t _dbus_string_parse_uint (const DBusString *str, - int start, - unsigned long *value_return, - int *end_return); -dbus_bool_t _dbus_string_parse_double (const DBusString *str, - int start, - double *value, - int *end_return); - -dbus_bool_t _dbus_string_find (const DBusString *str, - int start, - const char *substr, - int *found); - -dbus_bool_t _dbus_string_find_to (const DBusString *str, - int start, - int end, - const char *substr, - int *found); -dbus_bool_t _dbus_string_find_blank (const DBusString *str, - int start, - int *found); - -void _dbus_string_skip_blank (const DBusString *str, - int start, - int *end); - -void _dbus_string_skip_white (const DBusString *str, - int start, - int *end); - -dbus_bool_t _dbus_string_equal (const DBusString *a, - const DBusString *b); - -dbus_bool_t _dbus_string_equal_c_str (const DBusString *a, - const char *c_str); - -dbus_bool_t _dbus_string_equal_len (const DBusString *a, - const DBusString *b, - int len); - -dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a, - const char *c_str); -dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a, - const char *c_str); - -dbus_bool_t _dbus_string_pop_line (DBusString *source, - DBusString *dest); -void _dbus_string_delete_first_word (DBusString *str); -void _dbus_string_delete_leading_blanks (DBusString *str); - - -dbus_bool_t _dbus_string_base64_encode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_base64_decode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_hex_encode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_hex_decode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); - -dbus_bool_t _dbus_string_validate_ascii (const DBusString *str, - int start, - int len); - -dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str, - int start, - int len); - -dbus_bool_t _dbus_string_validate_nul (const DBusString *str, - int start, - int len); - -void _dbus_string_zero (DBusString *str); DBUS_END_DECLS; diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 8aa9181..4798aa7 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -24,6 +24,7 @@ #include "dbus-internals.h" #include "dbus-sysdeps.h" #include "dbus-threads.h" +#include "dbus-test.h" #include #include #include @@ -1890,14 +1891,18 @@ _dbus_file_get_contents (DBusString *str, if (fd < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to open \"%s\": %s", + filename_c, + _dbus_strerror (errno)); return FALSE; } if (fstat (fd, &sb) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to stat \"%s\": %s", + filename_c, + _dbus_strerror (errno)); _dbus_verbose ("fstat() failed: %s", _dbus_strerror (errno)); @@ -1910,8 +1915,8 @@ _dbus_file_get_contents (DBusString *str, if (sb.st_size > _DBUS_ONE_MEGABYTE) { dbus_set_error (error, DBUS_ERROR_FAILED, - "File size %lu is too large.\n", - (unsigned long) sb.st_size); + "File size %lu of \"%s\" is too large.", + filename_c, (unsigned long) sb.st_size); close (fd); return FALSE; } @@ -1929,7 +1934,9 @@ _dbus_file_get_contents (DBusString *str, if (bytes_read <= 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Error reading \"%s\": %s", + filename_c, + _dbus_strerror (errno)); _dbus_verbose ("read() failed: %s", _dbus_strerror (errno)); @@ -1949,7 +1956,8 @@ _dbus_file_get_contents (DBusString *str, { _dbus_verbose ("Can only open regular files at the moment.\n"); dbus_set_error (error, DBUS_ERROR_FAILED, - "Not a regular file"); + "\"%s\" is not a regular file", + filename_c); close (fd); return FALSE; } @@ -2231,6 +2239,9 @@ _dbus_create_directory (const DBusString *filename, /** * Appends the given filename to the given directory. * + * @todo it might be cute to collapse multiple '/' such as "foo//" + * concat "//bar" + * * @param dir the directory name * @param next_component the filename * @returns #TRUE on success @@ -2265,6 +2276,69 @@ _dbus_concat_dir_and_file (DBusString *dir, _dbus_string_get_length (dir)); } +/** + * Get the directory name from a complete filename + * @param filename the filename + * @param dirname string to append directory name to + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_string_get_dirname (const DBusString *filename, + DBusString *dirname) +{ + int sep; + + _dbus_assert (filename != dirname); + _dbus_assert (filename != NULL); + _dbus_assert (dirname != NULL); + + /* Ignore any separators on the end */ + sep = _dbus_string_get_length (filename); + if (sep == 0) + return _dbus_string_append (dirname, "."); /* empty string passed in */ + + while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') + --sep; + + _dbus_assert (sep >= 0); + + if (sep == 0) + return _dbus_string_append (dirname, "/"); + + /* Now find the previous separator */ + _dbus_string_find_byte_backward (filename, sep, '/', &sep); + if (sep < 0) + return _dbus_string_append (dirname, "."); + + /* skip multiple separators */ + while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') + --sep; + + _dbus_assert (sep >= 0); + + if (sep == 0 && + _dbus_string_get_byte (filename, 0) == '/') + return _dbus_string_append (dirname, "/"); + else + return _dbus_string_copy_len (filename, 0, sep - 0, + dirname, _dbus_string_get_length (dirname)); +} + +/** + * Checks whether the filename is an absolute path + * + * @param filename the filename + * @returns #TRUE if an absolute path + */ +dbus_bool_t +_dbus_path_is_absolute (const DBusString *filename) +{ + if (_dbus_string_get_length (filename) > 0) + return _dbus_string_get_byte (filename, 0) == '/'; + else + return FALSE; +} + struct DBusDirIter { DIR *d; @@ -2294,7 +2368,9 @@ _dbus_directory_open (const DBusString *filename, if (d == NULL) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to read directory \"%s\": %s", + filename_c, + _dbus_strerror (errno)); return NULL; } iter = dbus_new0 (DBusDirIter, 1); @@ -3207,4 +3283,86 @@ _dbus_change_identity (unsigned long uid, return TRUE; } +#ifdef DBUS_BUILD_TESTS +#include +static void +check_dirname (const char *filename, + const char *dirname) +{ + DBusString f, d; + + _dbus_string_init_const (&f, filename); + + if (!_dbus_string_init (&d)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_get_dirname (&f, &d)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_equal_c_str (&d, dirname)) + { + _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n", + filename, + _dbus_string_get_const_data (&d), + dirname); + exit (1); + } + + _dbus_string_free (&d); +} + +static void +check_path_absolute (const char *path, + dbus_bool_t expected) +{ + DBusString p; + + _dbus_string_init_const (&p, path); + + if (_dbus_path_is_absolute (&p) != expected) + { + _dbus_warn ("For path \"%s\" expected absolute = %d got %d\n", + path, expected, _dbus_path_is_absolute (&p)); + exit (1); + } +} + +/** + * Unit test for dbus-sysdeps.c. + * + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_sysdeps_test (void) +{ + check_dirname ("foo", "."); + check_dirname ("foo/bar", "foo"); + check_dirname ("foo//bar", "foo"); + check_dirname ("foo///bar", "foo"); + check_dirname ("foo/bar/", "foo"); + check_dirname ("foo//bar/", "foo"); + check_dirname ("foo///bar/", "foo"); + check_dirname ("foo/bar//", "foo"); + check_dirname ("foo//bar////", "foo"); + check_dirname ("foo///bar///////", "foo"); + check_dirname ("/foo", "/"); + check_dirname ("////foo", "/"); + check_dirname ("/foo/bar", "/foo"); + check_dirname ("/foo//bar", "/foo"); + check_dirname ("/foo///bar", "/foo"); + check_dirname ("/", "/"); + check_dirname ("///", "/"); + check_dirname ("", "."); + + check_path_absolute ("/", TRUE); + check_path_absolute ("/foo", TRUE); + check_path_absolute ("", FALSE); + check_path_absolute ("foo", FALSE); + check_path_absolute ("foo/bar", FALSE); + + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ + /** @} end of sysdeps */ + diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 6a6a965..113db5e 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -163,6 +163,9 @@ dbus_bool_t _dbus_create_directory (const DBusString *filename, dbus_bool_t _dbus_concat_dir_and_file (DBusString *dir, const DBusString *next_component); +dbus_bool_t _dbus_string_get_dirname (const DBusString *filename, + DBusString *dirname); +dbus_bool_t _dbus_path_is_absolute (const DBusString *filename); typedef struct DBusDirIter DBusDirIter; diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index b9cf64c..0b0893a 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -78,6 +78,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir) die ("strings"); check_memleaks (); + + printf ("%s: running sysdeps tests\n", "dbus-test"); + if (!_dbus_sysdeps_test ()) + die ("sysdeps"); + + check_memleaks (); printf ("%s: running data slot tests\n", "dbus-test"); if (!_dbus_data_slot_test ()) diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index e4cb52d..0615448 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -48,6 +48,7 @@ dbus_bool_t _dbus_md5_test (void); dbus_bool_t _dbus_sha_test (const char *test_data_dir); dbus_bool_t _dbus_keyring_test (void); dbus_bool_t _dbus_data_slot_test (void); +dbus_bool_t _dbus_sysdeps_test (void); void dbus_internal_do_not_use_run_tests (const char *test_data_dir); dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename, diff --git a/test/data/valid-config-files/basic.d/basic.conf b/test/data/valid-config-files/basic.d/basic.conf new file mode 100644 index 0000000..d109d71 --- /dev/null +++ b/test/data/valid-config-files/basic.d/basic.conf @@ -0,0 +1,13 @@ + + + mybususer + unix:path=/foo/bar + tcp:port=1234 + basic.d + /usr/share/foo + nonexistent.conf + + + + -- 2.7.4