From b3a58cffdfbd6bbd12b07164286bd6bae5689cf6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 17 Dec 2013 15:45:56 +0100 Subject: [PATCH 1/7] cfg: Add a cfg_load_config() function This new function can be used to load configuration from memory, instead of a file, which is a boon for writing tests. Signed-off-by: Gergely Nagy --- lib/cfg.c | 23 +++++++++++++++++++++++ lib/cfg.h | 1 + 2 files changed, 24 insertions(+) diff --git a/lib/cfg.c b/lib/cfg.c index ea6d5f143047af..7ede3f9ac76407 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -396,6 +396,29 @@ cfg_dump_processed_config(GString *preprocess_output, gchar *output_filename) } } +gboolean +cfg_load_config(GlobalConfig *self, gchar *config_string, gboolean syntax_only, gchar *preprocess_into) +{ + gint res; + CfgLexer *lexer; + GString *preprocess_output = g_string_sized_new(8192); + + lexer = cfg_lexer_new_buffer(config_string, strlen(config_string)); + lexer->preprocess_output = preprocess_output; + + res = cfg_run_parser(self, lexer, &main_parser, (gpointer *) &self, NULL); + if (preprocess_into) + { + cfg_dump_processed_config(preprocess_output, preprocess_into); + } + g_string_free(preprocess_output, TRUE); + if (res) + { + return TRUE; + } + return FALSE; +} + gboolean cfg_read_config(GlobalConfig *self, const gchar *fname, gboolean syntax_only, gchar *preprocess_into) { diff --git a/lib/cfg.h b/lib/cfg.h index 7ab0f2b07026ee..49a83bbc90a9fe 100644 --- a/lib/cfg.h +++ b/lib/cfg.h @@ -142,6 +142,7 @@ void cfg_load_candidate_modules(GlobalConfig *self); GlobalConfig *cfg_new(gint version); gboolean cfg_run_parser(GlobalConfig *self, CfgLexer *lexer, CfgParser *parser, gpointer *result, gpointer arg); gboolean cfg_read_config(GlobalConfig *cfg, const gchar *fname, gboolean syntax_only, gchar *preprocess_into); +gboolean cfg_load_config(GlobalConfig *self, gchar *config_string, gboolean syntax_only, gchar *preprocess_into); void cfg_free(GlobalConfig *self); gboolean cfg_init(GlobalConfig *cfg); gboolean cfg_deinit(GlobalConfig *cfg); From 29324d9ac73bad952088ba9797c5c6ee5e632e4c Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Wed, 29 Jan 2014 14:19:08 +0100 Subject: [PATCH 2/7] str-format: Moved format_hex_string to str-format and added delimitered version. Added unit tests for simple and delimitered variant. Replaced data_to_hex_string with format_hex_string_with_delimiter. Signed-off-by: Viktor Tusa Signed-off-by: Balazs Scheidler --- lib/misc.c | 15 --------- lib/misc.h | 1 - lib/str-format.c | 29 +++++++++++++++++ lib/str-format.h | 4 +++ lib/tests/Makefile.am | 6 ++++ lib/tests/test_str_format.c | 54 +++++++++++++++++++++++++++++++ modules/afsql/afsql.c | 1 + modules/cryptofuncs/cryptofuncs.c | 2 +- 8 files changed, 95 insertions(+), 17 deletions(-) create mode 100644 lib/tests/test_str_format.c diff --git a/lib/misc.c b/lib/misc.c index dad6731ced2630..f69e8f95d4cb8a 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -186,21 +186,6 @@ find_file_in_path(const gchar *path, const gchar *filename, GFileTest test) return fullname; } -gchar * -format_hex_string(gpointer data, gsize data_len, gchar *result, gsize result_len) -{ - gint i; - gint pos = 0; - guchar *str = (guchar *) data; - - for (i = 0; i < data_len && result_len - pos > 2; i++) - { - g_snprintf(result + pos, 3, "%02x", str[i]); - pos += 2; - } - return result; -} - /** * Find CR or LF characters in the log message. * diff --git a/lib/misc.h b/lib/misc.h index 8ea2be60860f63..7f7b22c7b3b8ff 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -43,7 +43,6 @@ gboolean resolve_user(const char *user, gint *uid); gboolean resolve_group(const char *group, gint *gid); gboolean resolve_user_group(char *arg, gint *uid, gint *gid); -gchar *format_hex_string(gpointer str, gsize str_len, gchar *result, gsize result_len); gchar *find_cr_or_lf(gchar *s, gsize n); gchar *find_file_in_path(const gchar *path, const gchar *filename, GFileTest test); diff --git a/lib/str-format.c b/lib/str-format.c index 7e9feb5fb09997..e597c16275b218 100644 --- a/lib/str-format.c +++ b/lib/str-format.c @@ -221,6 +221,35 @@ format_int32_padded(GString *result, gint field_len, gchar pad_char, gint base, return format_padded_int32(result, field_len, pad_char, 1, base, value); } +gchar * +format_hex_string_with_delimiter(gpointer data, gsize data_len, gchar *result, gsize result_len, gchar delimiter) +{ + gint i; + gint pos = 0; + guchar *str = (guchar *) data; + + for (i = 0; i < data_len && result_len - pos >= 2; i++) + { + if ( (delimiter != 0) && (i < data_len - 1)) + { + g_snprintf(result + pos, 4, "%02x%c", str[i], delimiter); + pos += 3; + } + else + { + g_snprintf(result + pos, 3, "%02x", str[i]); + pos += 2; + } + } + return result; +} + +gchar * +format_hex_string(gpointer data, gsize data_len, gchar *result, gsize result_len) +{ + return format_hex_string_with_delimiter(data, data_len, result, result_len, 0); +}; + /* parse 32 bit ints */ gboolean diff --git a/lib/str-format.h b/lib/str-format.h index 46d35bc87dd45c..8dc852fc89fcde 100644 --- a/lib/str-format.h +++ b/lib/str-format.h @@ -33,6 +33,10 @@ gint format_int32_padded(GString *result, gint field_len, gchar pad_char, gint b gint format_uint64_padded(GString *result, gint field_len, gchar pad_char, gint base, guint64 value); gint format_int64_padded(GString *result, gint field_len, gchar pad_char, gint base, gint64 value); +gchar *format_hex_string(gpointer str, gsize str_len, gchar *result, gsize result_len); +gchar *format_hex_string_with_delimiter(gpointer str, gsize str_len, gchar *result, gsize result_len, gchar delimiter); + + gboolean scan_iso_timestamp(const gchar **buf, gint *left, struct tm *tm); gboolean diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index cb345e652def65..be14822f6a8f90 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am @@ -9,6 +9,7 @@ lib_tests_TESTS = \ lib/tests/test_hostname \ lib/tests/test_rcptid \ lib/tests/test_lexer \ + lib/tests/test_str_format \ lib/tests/test_runid check_PROGRAMS += ${lib_tests_TESTS} @@ -75,6 +76,11 @@ lib_tests_test_runid_CFLAGS = \ lib_tests_test_runid_LDADD = \ $(TEST_LDADD) +lib_tests_test_str_format_CFLAGS = \ + $(TEST_CFLAGS) +lib_tests_test_str_format_LDADD = \ + $(TEST_LDADD) + CLEANFILES += \ test_values.persist \ test_values.persist- \ diff --git a/lib/tests/test_str_format.c b/lib/tests/test_str_format.c new file mode 100644 index 00000000000000..0f520d8ee8c59e --- /dev/null +++ b/lib/tests/test_str_format.c @@ -0,0 +1,54 @@ +#include "str-format.h" +#include "testutils.h" + +void test_format_hex_string__single_byte__perfect() +{ + gchar expected_output[2] = "40"; + gchar output[2]; + gchar input[1] = "@"; + //Act + format_hex_string(input, sizeof(input), output, sizeof(output)); + //Assert + assert_nstring(output, sizeof(output), expected_output, sizeof(expected_output), "format_hex_string output does not match!", NULL); +} + +void test_format_hex_string__two_bytes__perfect() +{ + gchar expected_output[4] = "4041"; + gchar output[4]; + gchar input[2] = "@A"; + //Act + format_hex_string(input, sizeof(input), output, sizeof(output)); + //Assert + assert_nstring(output, sizeof(output), expected_output, sizeof(expected_output), "format_hex_string output does not match with two bytes!", NULL); +} + +void test_format_hex_string_with_delimiter__single_byte__perfect() +{ + gchar expected_output[2] = "40"; + gchar output[2]; + gchar input[1] = "@"; + //Act + format_hex_string_with_delimiter(input, sizeof(input), output, sizeof(output), ' '); + //Assert + assert_nstring(output, sizeof(output), expected_output, sizeof(expected_output), "format_hex_string_with_delimiter output does not match!", NULL); +} + +void test_format_hex_string_with_delimiter__two_bytes__perfect() +{ + gchar expected_output[5] = "40 41"; + gchar output[5]; + gchar input[2] = "@A"; + //Act + format_hex_string_with_delimiter(input, sizeof(input), output, sizeof(output), ' '); + //Assert + assert_nstring(output, sizeof(output), expected_output, sizeof(expected_output), "format_hex_string_with_delimiter output does not match in case of two bytes!", NULL); +} + +int main() +{ + test_format_hex_string__single_byte__perfect(); + test_format_hex_string__two_bytes__perfect(); + test_format_hex_string_with_delimiter__single_byte__perfect(); + test_format_hex_string_with_delimiter__two_bytes__perfect(); +} diff --git a/modules/afsql/afsql.c b/modules/afsql/afsql.c index 783f904878616f..2dd6a8e54dc8c4 100644 --- a/modules/afsql/afsql.c +++ b/modules/afsql/afsql.c @@ -29,6 +29,7 @@ #include "template/templates.h" #include "messages.h" #include "misc.h" +#include "str-format.h" #include "stats/stats-registry.h" #include "apphook.h" #include "timeutils.h" diff --git a/modules/cryptofuncs/cryptofuncs.c b/modules/cryptofuncs/cryptofuncs.c index c6359ce7913605..c9435be64b21eb 100644 --- a/modules/cryptofuncs/cryptofuncs.c +++ b/modules/cryptofuncs/cryptofuncs.c @@ -25,7 +25,7 @@ #include "template/templates.h" #include "cfg.h" #include "uuid.h" -#include "misc.h" +#include "str-format.h" #include "plugin-types.h" #if ENABLE_SSL From 067152623000e42c59651e90b20ce644fb48f9bb Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Sat, 1 Feb 2014 07:58:08 +0100 Subject: [PATCH 3/7] persist-state: Add foreach function on persist-state entries. Signed-off-by: Viktor Tusa Signed-off-by: Balazs Scheidler --- lib/persist-state.c | 35 +++++++++++++++++++++++++++++++++ lib/persist-state.h | 3 +++ tests/unit/test_persist_state.c | 28 +++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/persist-state.c b/lib/persist-state.c index 0a208647ebfc86..8abcc1ac3ede99 100644 --- a/lib/persist-state.c +++ b/lib/persist-state.c @@ -776,6 +776,41 @@ persist_state_remove_entry(PersistState *self, const gchar *key) return TRUE; }; +typedef struct _PersistStateKeysForeachData +{ + PersistStateForeachFunc func; + gpointer userdata; + PersistState* storage; +} PersistStateKeysForeachData; + +static void +_foreach_entry_func(gpointer key, gpointer value, gpointer userdata) +{ + PersistStateKeysForeachData *data = (PersistStateKeysForeachData *) userdata; + PersistEntry *entry = (PersistEntry *) value; + gchar *name = (gchar *) key; + + PersistValueHeader *header = persist_state_map_entry(data->storage, entry->ofs - sizeof(PersistValueHeader)); + gint size = GUINT32_FROM_BE(header->size); + persist_state_unmap_entry(data->storage, entry->ofs); + + gpointer *state = persist_state_map_entry(data->storage, entry->ofs); + data->func(name, size, state, data->userdata); + persist_state_unmap_entry(data->storage, entry->ofs); +} + +void +persist_state_foreach_entry(PersistState *self, PersistStateForeachFunc func, gpointer userdata) +{ + PersistStateKeysForeachData data; + + data.func = func; + data.userdata = userdata; + data.storage = self; + + g_hash_table_foreach(self->keys, _foreach_entry_func, &data); +}; + /* easier to use string based interface */ gchar * persist_state_lookup_string(PersistState *self, const gchar *key, gsize *length, guint8 *version) diff --git a/lib/persist-state.h b/lib/persist-state.h index 12c3c5bcce5744..3b1767c4a457ff 100644 --- a/lib/persist-state.h +++ b/lib/persist-state.h @@ -43,6 +43,9 @@ void persist_state_alloc_string(PersistState *self, const gchar *persist_name, c void persist_state_free_entry(PersistEntryHandle handle); +typedef void (*PersistStateForeachFunc)(gchar* name, gint entry_size, gpointer entry, gpointer userdata); +void persist_state_foreach_entry(PersistState *self, PersistStateForeachFunc func, gpointer userdata); + gboolean persist_state_start(PersistState *self); const gchar *persist_state_get_filename(PersistState *self); diff --git a/tests/unit/test_persist_state.c b/tests/unit/test_persist_state.c index 3e09fd0177fc28..41b4a11bf0268a 100644 --- a/tests/unit/test_persist_state.c +++ b/tests/unit/test_persist_state.c @@ -36,7 +36,32 @@ test_persist_state_remove_entry(void) assert_true(handle == 0, "lookup succeeded after removing entry"); cancel_and_destroy_persist_state(state); -}; +} + +void +_foreach_callback_assertions(gchar* name, gint size, gpointer entry, gpointer userdata) +{ + assert_string((gchar *) userdata, "test_userdata", "Userdata is not passed correctly to foreach func!"); + assert_string(name, "test", "Name of persist entry does not match!"); + TestState *state = (TestState *) entry; + assert_gint(state->value, 3, "Content of state does not match!"); + assert_gint(size, sizeof(TestState), "Size of state does not match!"); +} + +void +test_persist_state_foreach_entry(void) +{ + PersistState *state = clean_and_create_persist_state_for_test("test_persist_foreach.persist"); + + PersistEntryHandle handle = persist_state_alloc_entry(state, "test", sizeof(TestState)); + TestState *test_state = persist_state_map_entry(state, handle); + test_state->value = 3; + persist_state_unmap_entry(state, handle); + + persist_state_foreach_entry(state, _foreach_callback_assertions, "test_userdata"); + + cancel_and_destroy_persist_state(state); +} void test_values(void) @@ -162,6 +187,7 @@ main(int argc, char *argv[]) test_persist_state_remove_entry(); test_persist_state_temp_file_cleanup_on_cancel(); test_persist_state_temp_file_cleanup_on_commit_destroy(); + test_persist_state_foreach_entry(); return 0; } From 7e2db8d379765624e8847aeaecee9a35da9fa3ee Mon Sep 17 00:00:00 2001 From: Viktor Tusa Date: Thu, 16 Jan 2014 14:48:10 +0100 Subject: [PATCH 4/7] persist-state: Add dump and edit mode to persist_state_start. Using edit or dump mode on an invalid file results in an error, when starting persist-state instead of silently creating a new one. In dump mode, the not used entries (in_use = 0) are read as well at load time instead of being purged. Signed-off-by: Viktor Tusa Signed-off-by: Balazs Scheidler --- lib/persist-state.c | 43 +++++++++-- lib/persist-state.h | 2 + tests/unit/test_persist_state.c | 130 ++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 7 deletions(-) diff --git a/lib/persist-state.c b/lib/persist-state.c index 8abcc1ac3ede99..cd240588866d45 100644 --- a/lib/persist-state.c +++ b/lib/persist-state.c @@ -483,7 +483,7 @@ _load_v23(PersistState *self, gint version, SerializeArchive *sa) } static gboolean -_load_v4(PersistState *self) +_load_v4(PersistState *self, gboolean load_all_entries) { gint fd; gint64 file_size; @@ -559,7 +559,7 @@ _load_v4(PersistState *self) } header = (PersistValueHeader *) ((gchar *) map + entry_ofs - sizeof(PersistValueHeader)); - if (header->in_use) + if ((header->in_use) || load_all_entries) { gpointer new_block; PersistEntryHandle new_handle; @@ -628,7 +628,7 @@ _load_v4(PersistState *self) } static gboolean -_load(PersistState *self) +_load(PersistState *self, gboolean all_errors_are_fatal, gboolean load_all_entries) { FILE *persist_file; gboolean success = FALSE; @@ -645,7 +645,7 @@ _load(PersistState *self) if (memcmp(magic, "SLP", 3) != 0) { msg_error("Persistent configuration file is in invalid format, ignoring", NULL); - success = TRUE; + success = all_errors_are_fatal ? FALSE : TRUE; goto close_and_exit; } version = magic[3] - '0'; @@ -655,7 +655,7 @@ _load(PersistState *self) } else if (version == 4) { - success = _load_v4(self); + success = _load_v4(self, load_all_entries); } else { @@ -670,7 +670,16 @@ _load(PersistState *self) } else { - success = TRUE; + if (all_errors_are_fatal) + { + msg_error("Failed to open persist file!", + evt_tag_str("filename", self->commited_filename), + evt_tag_str("error", strerror(errno)), + NULL); + success = FALSE; + } + else + success = TRUE; } return success; } @@ -872,12 +881,32 @@ persist_state_get_filename(PersistState *self) return self->commited_filename; } +gboolean +persist_state_start_dump(PersistState *self) +{ + if (!_create_store(self)) + return FALSE; + if (!_load(self, TRUE, TRUE)) + return FALSE; + return TRUE; +} + +gboolean +persist_state_start_edit(PersistState *self) +{ + if (!_create_store(self)) + return FALSE; + if (!_load(self, FALSE, TRUE)) + return FALSE; + return TRUE; +} + gboolean persist_state_start(PersistState *self) { if (!_create_store(self)) return FALSE; - if (!_load(self)) + if (!_load(self, FALSE, FALSE)) return FALSE; return TRUE; } diff --git a/lib/persist-state.h b/lib/persist-state.h index 3b1767c4a457ff..99b118a7a01907 100644 --- a/lib/persist-state.h +++ b/lib/persist-state.h @@ -47,6 +47,8 @@ typedef void (*PersistStateForeachFunc)(gchar* name, gint entry_size, gpointer e void persist_state_foreach_entry(PersistState *self, PersistStateForeachFunc func, gpointer userdata); gboolean persist_state_start(PersistState *self); +gboolean persist_state_start_edit(PersistState *self); +gboolean persist_state_start_dump(PersistState *self); const gchar *persist_state_get_filename(PersistState *self); diff --git a/tests/unit/test_persist_state.c b/tests/unit/test_persist_state.c index 41b4a11bf0268a..82ed08af84cb03 100644 --- a/tests/unit/test_persist_state.c +++ b/tests/unit/test_persist_state.c @@ -14,6 +14,129 @@ typedef struct _TestState guint32 value; } TestState; +void +test_persist_state_open_success_on_invalid_file(void) +{ + PersistState *state; + int fd; + unlink("test_invalid_magic.persist"); + + fd = open("test_invalid_magic.persist", O_CREAT | O_RDWR, 0777); + write(fd, "aaa", 3); + close(fd); + + state = persist_state_new("test_invalid_magic.persist"); + assert_true(persist_state_start(state), "persist_state_start returned with false!"); + + cancel_and_destroy_persist_state(state); +} + +void +test_persist_state_open_fails_on_invalid_file_with_dump(void) +{ + PersistState *state; + int fd; + unlink("test_invalid_magic.persist"); + + fd = open("test_invalid_magic.persist", O_CREAT | O_RDWR, 0777); + write(fd, "aaa", 3); + close(fd); + + state = persist_state_new("test_invalid_magic.persist"); + assert_false(persist_state_start_dump(state), "persist_state_start_dump returned with success when persist file was invalid!"); + + cancel_and_destroy_persist_state(state); +} + +void +test_persist_state_open_failes_when_file_open_fails(void) +{ + PersistState *state; + unlink("test_invalid_magic.persist"); + + state = persist_state_new("test_invalid_magic.persist"); + + assert_false(persist_state_start_dump(state), "persist_state_start_dump returned with success when persist file open failed!"); + + cancel_and_destroy_persist_state(state); +} + +void +write_test_file_for_test_in_use_handle(gboolean in_use_handle) +{ + PersistState *state = clean_and_create_persist_state_for_test("test_in_use.persist"); + PersistEntryHandle handle = persist_state_alloc_entry(state, "alma", sizeof(TestState)); + TestState *test_state = (TestState*) persist_state_map_entry(state, handle); + test_state->value = 0xDEADBEEF; + persist_state_unmap_entry(state, handle); + + if (!in_use_handle) + persist_state_remove_entry(state, "alma"); + + commit_and_free_persist_state(state); +} + +void +test_persist_state_in_use_handle_is_loaded(void) +{ + PersistState *state; + guint8 version; + gsize size; + PersistEntryHandle handle; + + unlink("test_in_use.persist"); + write_test_file_for_test_in_use_handle(TRUE); + + state = create_persist_state_for_test("test_in_use.persist"); + + handle = persist_state_lookup_entry(state, "alma", &size, &version); + + assert_false(handle == 0, "lookup failed when looking for simple entry with in_use = TRUE!"); + + cancel_and_destroy_persist_state(state); +} + +void +test_persist_state_not_in_use_handle_is_not_loaded(void) +{ + PersistState *state; + guint8 version; + gsize size; + PersistEntryHandle handle; + + unlink("test_in_use.persist"); + write_test_file_for_test_in_use_handle(FALSE); + + state = create_persist_state_for_test("test_in_use.persist"); + + handle = persist_state_lookup_entry(state, "alma", &size, &version); + + assert_true(handle == 0, "lookup succeeded when looking for simple entry with in_use = FALSE!"); + + cancel_and_destroy_persist_state(state); +} + +void +test_persist_state_not_in_use_handle_is_loaded_in_dump_mode(void) +{ + PersistState *state; + guint8 version; + gsize size; + PersistEntryHandle handle; + + unlink("test_in_use.persist"); + write_test_file_for_test_in_use_handle(FALSE); + + state = persist_state_new("test_in_use.persist"); + persist_state_start_dump(state); + + handle = persist_state_lookup_entry(state, "alma", &size, &version); + + assert_false(handle == 0, "lookup failed in dump mode when looking for simple entry with in_use = FALSE!"); + + cancel_and_destroy_persist_state(state); +} + void test_persist_state_remove_entry(void) @@ -188,6 +311,13 @@ main(int argc, char *argv[]) test_persist_state_temp_file_cleanup_on_cancel(); test_persist_state_temp_file_cleanup_on_commit_destroy(); test_persist_state_foreach_entry(); + test_persist_state_open_success_on_invalid_file(); + test_persist_state_open_fails_on_invalid_file_with_dump(); + test_persist_state_open_failes_when_file_open_fails(); + test_persist_state_in_use_handle_is_loaded(); + test_persist_state_not_in_use_handle_is_not_loaded(); + test_persist_state_not_in_use_handle_is_loaded_in_dump_mode(); + test_persist_state_remove_entry(); return 0; } From 04af87eef0a08e2e2b74bd84a7a3c2ab9fc04cc0 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Sat, 1 Feb 2014 07:57:28 +0100 Subject: [PATCH 5/7] persist-state: Add PersistableStatePresenter. PersistableStatePresenter is an interface, which turns *State objects into PresentedPersistableState. Every *State object which has it's own PersistableStatePresenter implementation can represent/load itself into/from a PresentedPersistableState. PresentedPersistableState is an abstract interface, which provides functions to represent basic types in its implementation. Currently it has only one implementation, JsonPresentedPersistableState. Signed-off-by: Viktor Tusa Signed-off-by: Balazs Scheidler --- lib/Makefile.am | 3 + lib/persistable-state-presenter.c | 52 ++++++++++++++ lib/persistable-state-presenter.h | 67 +++++++++++++++++ lib/presented-persistable-state.h | 115 ++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 lib/persistable-state-presenter.c create mode 100644 lib/persistable-state-presenter.h create mode 100644 lib/presented-persistable-state.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 2480f48d5917a2..2cad5b68a1b6c6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -81,11 +81,13 @@ pkginclude_HEADERS += \ lib/parse-number.h \ lib/persist-state.h \ lib/persistable-state-header.h \ + lib/persistable-state-presenter.h \ lib/plugin.h \ lib/plugin-types.h \ lib/poll-events.h \ lib/poll-fd-events.h \ lib/pragma-parser.h \ + lib/presented-persistable-state.h \ lib/reloc.h \ lib/rcptid.h \ lib/run-id.h \ @@ -163,6 +165,7 @@ lib_libsyslog_ng_la_SOURCES = \ lib/poll-events.c \ lib/poll-fd-events.c \ lib/pragma-parser.c \ + lib/persistable-state-presenter.c \ lib/rcptid.c \ lib/reloc.c \ lib/run-id.c \ diff --git a/lib/persistable-state-presenter.c b/lib/persistable-state-presenter.c new file mode 100644 index 00000000000000..b16df521fbbaee --- /dev/null +++ b/lib/persistable-state-presenter.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2013 Viktor Juhasz + * Copyright (c) 2013 Viktor Tusa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ +#include "persistable-state-presenter.h" +#include "misc.h" +#include "logmsg.h" +#include "str-format.h" + +static GHashTable *persist_state_storage = NULL; + +PersistableStatePresenterConstructFunc +persistable_state_presenter_get_constructor_by_prefix(const gchar *prefix) +{ + PersistableStatePresenterConstructFunc result = NULL; + if (persist_state_storage) + { + result = g_hash_table_lookup(persist_state_storage, prefix); + } + return result; +} + +void +persistable_state_presenter_register_constructor(const gchar *prefix, + PersistableStatePresenterConstructFunc handler) +{ + if (!persist_state_storage) + { + persist_state_storage = g_hash_table_new(g_str_hash, g_str_equal); + } + g_hash_table_insert(persist_state_storage, (gpointer) prefix, handler); +} diff --git a/lib/persistable-state-presenter.h b/lib/persistable-state-presenter.h new file mode 100644 index 00000000000000..77218cb1c82df7 --- /dev/null +++ b/lib/persistable-state-presenter.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2013 Viktor Juhasz + * Copyright (c) 2013 Viktor Tusa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ +#ifndef PERSISTABLE_STATE_PRESENTER_H_INCLUDED +#define PERSISTABLE_STATE_PRESENTER_H_INCLUDED + +#include "syslog-ng.h" +#include "persist-state.h" +#include "presented-persistable-state.h" +#include "persistable-state-header.h" + +struct _PersistableStatePresenter { + gboolean (*dump)(PersistableStateHeader *state, PresentedPersistableState *representation); + gboolean (*load)(PersistableStateHeader *state, PresentedPersistableState *representation); + PersistEntryHandle (*alloc)(PersistState *state, const gchar *name); +}; + +typedef struct _PersistableStatePresenter PersistableStatePresenter; + +static inline gboolean +persistable_state_presenter_load(PersistableStatePresenter *self, PersistableStateHeader *state, PresentedPersistableState *representation) +{ + g_assert(self->load != NULL); + return self->load(state, representation); +} + +static inline gboolean +persistable_state_presenter_dump(PersistableStatePresenter *self, PersistableStateHeader *state, PresentedPersistableState *representation) +{ + g_assert(self->dump != NULL); + return self->dump(state, representation); +} + +static inline PersistEntryHandle +persistable_state_presenter_alloc(PersistableStatePresenter *self, PersistState *state, const gchar *name) +{ + g_assert(self->alloc != NULL); + return self->alloc(state, name); +} + +typedef PersistableStatePresenter* (*PersistableStatePresenterConstructFunc)(const gchar *name); + +PersistableStatePresenterConstructFunc persistable_state_presenter_get_constructor_by_prefix(const gchar *prefix); +void persistable_state_presenter_register_constructor(const gchar *prefix, PersistableStatePresenterConstructFunc handler); + +#endif diff --git a/lib/presented-persistable-state.h b/lib/presented-persistable-state.h new file mode 100644 index 00000000000000..997ff2bfad72df --- /dev/null +++ b/lib/presented-persistable-state.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2013 Viktor Juhasz + * Copyright (c) 2013 Viktor Tusa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ +#ifndef PRESENTED_PERSISTABLE_STATE_H_INCLUDED +#define PRESENTED_PERSISTABLE_STATE_H_INCLUDED +#include "syslog-ng.h" + +typedef struct _PresentedPersistableState PresentedPersistableState; + +struct _PresentedPersistableState +{ + void (*add_string)(PresentedPersistableState *self, gchar* name, gchar* value); + void (*add_boolean)(PresentedPersistableState *self, gchar* name, gboolean value); + void (*add_int64)(PresentedPersistableState *self, gchar *name, gint64 value); + void (*add_int)(PresentedPersistableState *self, gchar *name, gint value); + + const gchar* (*get_string)(PresentedPersistableState *self, gchar *name); + gboolean (*get_boolean)(PresentedPersistableState *self, gchar *name); + gint (*get_int)(PresentedPersistableState *self, gchar *name); + gint64 (*get_int64)(PresentedPersistableState *self, gchar *name); + + void (*foreach)(PresentedPersistableState *self, void + (callback)(gchar *name, const gchar *value, gpointer user_data), gpointer user_data); + gboolean (*does_name_exist)(PresentedPersistableState *self, gchar *name); + void (*free)(PresentedPersistableState *self); +}; + +static inline void +presented_persistable_state_add_string(PresentedPersistableState *self, gchar *name, gchar *value) +{ + self->add_string(self, name, value); +} + +static inline void +presented_persistable_state_add_boolean(PresentedPersistableState *self, gchar *name, gboolean value) +{ + self->add_boolean(self, name, value); +} + +static inline void +presented_persistable_state_add_int(PresentedPersistableState *self, gchar *name, gint value) +{ + self->add_int(self, name, value); +} + +static inline void +presented_persistable_state_add_int64(PresentedPersistableState *self, gchar *name, gint64 value) +{ + self->add_int64(self, name, value); +} + +static inline const gchar * +presented_persistable_state_get_string(PresentedPersistableState *self, gchar *name) +{ + return self->get_string(self, name); +} + +static inline gboolean +presented_persistable_state_get_boolean(PresentedPersistableState *self, gchar *name) +{ + return self->get_boolean(self, name); +} + +static inline gint +presented_persistable_state_get_int(PresentedPersistableState *self, gchar *name) +{ + return self->get_int(self, name); +} + +static inline gint64 +presented_persistable_state_get_int64(PresentedPersistableState *self, gchar *name) +{ + return self->get_int64(self, name); +} + +static inline void +presented_persistable_state_foreach(PresentedPersistableState *self, void (callback)(gchar *name, const gchar *value, gpointer user_data), gpointer user_data) +{ + self->foreach(self, callback, user_data); +} + +static inline gboolean +presented_persistable_state_does_name_exist(PresentedPersistableState *self, gchar *name) +{ + return self->does_name_exist(self, name); +} + +static inline void +presented_persistable_state_free(PresentedPersistableState *self) +{ + self->free(self); +} + +#endif From 6d8340afab5b5561b9fe1d7c5dd6071e39f2e233 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Sat, 1 Feb 2014 07:56:21 +0100 Subject: [PATCH 6/7] persist-state: remove tailing semicolons from the end of functions Signed-off-by: Balazs Scheidler --- lib/persist-state.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/persist-state.c b/lib/persist-state.c index cd240588866d45..2aa348bf274f86 100644 --- a/lib/persist-state.c +++ b/lib/persist-state.c @@ -293,7 +293,7 @@ _map_header_of_entry_from_handle(PersistState *self, PersistEntryHandle handle) return NULL; } return header; -}; +} static void _free_value(PersistState *self, PersistEntryHandle handle) @@ -732,7 +732,7 @@ _map_header_of_entry(PersistState *self, const gchar *persist_name, PersistEntry return _map_header_of_entry_from_handle(self, *handle); -}; +} PersistEntryHandle persist_state_alloc_entry(PersistState *self, const gchar *persist_name, gsize alloc_size) @@ -783,7 +783,7 @@ persist_state_remove_entry(PersistState *self, const gchar *key) _free_value(self, handle); return TRUE; -}; +} typedef struct _PersistStateKeysForeachData { @@ -818,7 +818,7 @@ persist_state_foreach_entry(PersistState *self, PersistStateForeachFunc func, gp data.storage = self; g_hash_table_foreach(self->keys, _foreach_entry_func, &data); -}; +} /* easier to use string based interface */ gchar * @@ -944,7 +944,7 @@ _destroy(PersistState *self) g_free(self->temp_filename); g_free(self->commited_filename); g_hash_table_destroy(self->keys); -}; +} static void _init(PersistState* self, gchar* commited_filename, gchar* temp_filename) @@ -957,7 +957,8 @@ _init(PersistState* self, gchar* commited_filename, gchar* temp_filename) self->fd = -1; self->commited_filename = commited_filename; self->temp_filename = temp_filename; -}; +} + /* * This routine should revert to the persist_state_new() state, * e.g. just like the PersistState object wasn't started yet. From 94bf21e4d0a5980496e69b63b06e5e3fa6d17a25 Mon Sep 17 00:00:00 2001 From: Viktor Tusa Date: Fri, 17 Jan 2014 15:59:12 +0100 Subject: [PATCH 7/7] pathutils: Added filesystem path-related utility functions. Signed-off-by: Viktor Tusa Signed-off-by: Balazs Scheidler --- lib/Makefile.am | 2 ++ lib/pathutils.c | 38 ++++++++++++++++++++++++++++++ lib/pathutils.h | 33 ++++++++++++++++++++++++++ lib/plugin.c | 7 +++--- lib/timeutils.c | 3 ++- modules/dbparser/pdbtool/pdbtool.c | 5 ++-- 6 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 lib/pathutils.c create mode 100644 lib/pathutils.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 2cad5b68a1b6c6..da580893e85b50 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -79,6 +79,7 @@ pkginclude_HEADERS += \ lib/msg-format.h \ lib/nvtable.h \ lib/parse-number.h \ + lib/pathutils.h \ lib/persist-state.h \ lib/persistable-state-header.h \ lib/persistable-state-presenter.h \ @@ -160,6 +161,7 @@ lib_libsyslog_ng_la_SOURCES = \ lib/msg-format.c \ lib/nvtable.c \ lib/parse-number.c \ + lib/pathutils.c \ lib/persist-state.c \ lib/plugin.c \ lib/poll-events.c \ diff --git a/lib/pathutils.c b/lib/pathutils.c new file mode 100644 index 00000000000000..182427dff02737 --- /dev/null +++ b/lib/pathutils.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2013 Viktor Juhasz + * Copyright (c) 2013 Viktor Tusa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#include "pathutils.h" + +gboolean +is_file_directory(const char *filename) +{ + return g_file_test(filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR); +}; + +gboolean +is_file_regular(const char *filename) +{ + return g_file_test(filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR); +}; diff --git a/lib/pathutils.h b/lib/pathutils.h new file mode 100644 index 00000000000000..61218a13b0b6bf --- /dev/null +++ b/lib/pathutils.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2013 Viktor Juhasz + * Copyright (c) 2013 Viktor Tusa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#ifndef _PATHUTILS_H +#define _PATHUTILS_H +#include "syslog-ng.h" + +gboolean is_file_regular(const char *filename); +gboolean is_file_directory(const char *filename); + +#endif diff --git a/lib/plugin.c b/lib/plugin.c index 5812ace2982be2..7d3062684f8e17 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -27,6 +27,7 @@ #include "messages.h" #include "cfg-lexer.h" #include "plugin-types.h" +#include "pathutils.h" #include #include @@ -260,7 +261,7 @@ plugin_dlopen_module(const gchar *module_name, const gchar *module_path) while (module_path_dirs && module_path_dirs[i]) { plugin_module_name = g_module_build_path(module_path_dirs[i], module_name); - if (g_file_test(plugin_module_name, G_FILE_TEST_EXISTS)) + if (is_file_regular(plugin_module_name)) break; /* also check if a libtool archive exists (for example in the build directory) */ @@ -273,7 +274,7 @@ plugin_dlopen_module(const gchar *module_name, const gchar *module_path) g_free(plugin_module_name); plugin_module_name = p; } - if (g_file_test(plugin_module_name, G_FILE_TEST_EXISTS)) + if (is_file_regular(plugin_module_name)) break; /* On AIX the modules in .a files */ @@ -286,7 +287,7 @@ plugin_dlopen_module(const gchar *module_name, const gchar *module_path) g_free(plugin_module_name); plugin_module_name = p; } - if (g_file_test(plugin_module_name, G_FILE_TEST_EXISTS)) + if (is_file_regular(plugin_module_name)) break; #endif diff --git a/lib/timeutils.c b/lib/timeutils.c index 0fc0ee0d12a5c4..5eeced8e38a3de 100644 --- a/lib/timeutils.c +++ b/lib/timeutils.c @@ -26,6 +26,7 @@ #include "messages.h" #include "tls-support.h" #include "reloc.h" +#include "pathutils.h" #include #include @@ -83,7 +84,7 @@ get_time_zone_basedir(void) if (!time_zone_basedir) { - for (i = 0; time_zone_path_list[i] != NULL && !g_file_test(get_installation_path_for(time_zone_path_list[i]), G_FILE_TEST_IS_DIR); i++) + for (i = 0; time_zone_path_list[i] != NULL && !is_file_directory(get_installation_path_for(time_zone_path_list[i])); i++) ; time_zone_basedir = time_zone_path_list[i]; } diff --git a/modules/dbparser/pdbtool/pdbtool.c b/modules/dbparser/pdbtool/pdbtool.c index 6af2518fd15c46..af987ff2961d69 100644 --- a/modules/dbparser/pdbtool/pdbtool.c +++ b/modules/dbparser/pdbtool/pdbtool.c @@ -38,6 +38,7 @@ #include "transport/transport-file.h" #include "logproto/logproto-text-server.h" #include "reloc.h" +#include "pathutils.h" #include #include @@ -271,11 +272,11 @@ pdbtool_merge_dir(const gchar *dir, gboolean recursive, GString *merged) { gchar *full_name = g_build_filename(dir, filename, NULL); - if (recursive && g_file_test(full_name, G_FILE_TEST_IS_DIR)) + if (recursive && is_file_directory(full_name)) { ok = pdbtool_merge_dir(full_name, recursive, merged); } - else if (g_file_test(full_name, G_FILE_TEST_IS_REGULAR) && (!merge_glob || g_pattern_match_simple(merge_glob, filename))) + else if (is_file_regular(full_name) && (!merge_glob || g_pattern_match_simple(merge_glob, filename))) { ok = pdbtool_merge_file(full_name, merged); }