lib-event.c revision b8a1347a9ea2cecf0d16f24748c2600fea8c7158
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern const struct event_passthrough event_passthrough_vfuncs;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic struct event *current_global_event = NULL;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic struct event_passthrough *event_last_passthrough = NULL;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic ARRAY(event_callback_t *) event_handlers;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic ARRAY(event_category_callback_t *) event_category_callbacks;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic ARRAY(struct event_category *) event_registered_categories;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic ARRAY(struct event *) global_event_stack;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstatic struct event *last_passthrough_event(void)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void event_copy_parent_defaults(struct event *event,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen event->always_log_source = parent->always_log_source;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstruct event *event_create(struct event *parent, const char *source_filename,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen pool_t pool = pool_alloconly_create(MEMPOOL_GROWING"event", 64);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen event->event_passthrough = event_passthrough_vfuncs;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenevent_create_passthrough(struct event *parent, const char *source_filename,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen /* API is being used in a wrong or dangerous way */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen i_panic("Can't create multiple passthrough events - finish the earlier with ->event()");
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen event_create(parent, source_filename, source_linenum);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen /* This event only intends to extend the parent event.
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen Use the parent's creation timestamp. */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen event_last_passthrough = &event->event_passthrough;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen event_last_passthrough = &parent->event_passthrough;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_send_callbacks(struct event *event, enum event_callback_type type,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct failure_context *ctx, const char *fmt, va_list args)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen ret = (*callbackp)(event, type, ctx, fmt, args);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen /* event sending was stopped */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen (void)event_send_callbacks(event, EVENT_CALLBACK_TYPE_FREE,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstruct event *event_push_global(struct event *event)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen array_append(&global_event_stack, ¤t_global_event, 1);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstruct event *event_pop_global(struct event *event)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen array_delete(&global_event_stack, event_count-1, 1);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic struct event *
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_set_log_prefix(struct event *event, const char *prefix, bool append)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* allocate the first log prefix from the pool */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen event->log_prefix = p_strdup(event->pool, prefix);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* log prefix is being updated multiple times -
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen switch to system pool so we don't keep leaking memory */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_set_append_log_prefix(struct event *event, const char *prefix)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return event_set_log_prefix(event, prefix, TRUE);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstruct event *event_replace_log_prefix(struct event *event, const char *prefix)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return event_set_log_prefix(event, prefix, FALSE);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_set_name(struct event *event, const char *name)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_set_source(struct event *event, const char *filename,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen event->source_filename = literal_fname ? filename :
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstruct event *event_set_always_log_source(struct event *event)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstruct event_category *event_category_find_registered(const char *name)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen array_foreach(&event_registered_categories, catp) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_get_registered_categories(unsigned int *count_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return array_get(&event_registered_categories, count_r);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void event_category_register(struct event_category *category)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* register parent categories first */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen array_append(&event_registered_categories, &category, 1);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen array_foreach(&event_category_callbacks, callbackp) T_BEGIN {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_find_category(struct event *event, const struct event_category *category)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen array_foreach(&event->categories, categoryp) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen p_array_init(&event->categories, event->pool, 4);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen for (unsigned int i = 0; categories[i] != NULL; i++) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (!event_find_category(event, categories[i]))
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen array_append(&event->categories, &categories[i], 1);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_add_category(struct event *event, struct event_category *category)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct event_category *const categories[] = { category, NULL };
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return event_add_categories(event, categories);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstatic struct event_field *
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenevent_find_field_int(struct event *event, const char *key)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen array_foreach_modifiable(&event->fields, field) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenevent_find_field(struct event *event, const char *key)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const struct event_field *field = event_find_field_int(event, key);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_find_field_str(struct event *event, const char *key)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic struct event_field *
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_get_field(struct event *event, const char *key)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenevent_add_str(struct event *event, const char *key, const char *value)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_STR;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen field->value.str = p_strdup(event->pool, value);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_add_int(struct event *event, const char *key, intmax_t num)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_INTMAX;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_add_timeval(struct event *event, const char *key,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_TIMEVAL;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen for (unsigned int i = 0; fields[i].key != NULL; i++) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen event_add_str(event, fields[i].key, fields[i].value);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen event_add_timeval(event, fields[i].key, &fields[i].value_timeval);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen event_add_int(event, fields[i].key, fields[i].value_intmax);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstruct event *event_get_parent(struct event *event)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenvoid event_get_create_time(struct event *event, struct timeval *tv_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenbool event_get_last_send_time(struct event *event, struct timeval *tv_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenevent_get_fields(struct event *event, unsigned int *count_r)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenevent_get_categories(struct event *event, unsigned int *count_r)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return array_get(&event->categories, count_r);
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainenvoid event_send(struct event *event, struct failure_context *ctx,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (event_send_callbacks(event, EVENT_CALLBACK_TYPE_EVENT,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* if the event is sent again, it needs a new name */
i_unreached();
i_unreached();
i_unreached();
} T_END;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
static struct event_passthrough *
return event_last_passthrough;
return event;
void lib_event_init(void)
void lib_event_deinit(void)