bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "lib.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "lib-event-private.h"
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen#include "event-filter.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "array.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "llist.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "str.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "strescape.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include "ioloop.h"
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenenum event_code {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_ALWAYS_LOG_SOURCE = 'a',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_CATEGORY = 'c',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_TV_LAST_SENT = 'l',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_SENDING_NAME = 'n',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_SOURCE = 's',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen EVENT_CODE_FIELD_INTMAX = 'I',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_FIELD_STR = 'S',
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen EVENT_CODE_FIELD_TIMEVAL = 'T',
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen};
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenextern const struct event_passthrough event_passthrough_vfuncs;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event *events = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event *current_global_event = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *event_last_passthrough = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic ARRAY(event_callback_t *) event_handlers;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic ARRAY(event_category_callback_t *) event_category_callbacks;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic ARRAY(struct event_category *) event_registered_categories;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic ARRAY(struct event *) global_event_stack;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic uint64_t event_id_counter = 0;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event *last_passthrough_event(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return container_of(event_last_passthrough,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event, event_passthrough);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic void event_copy_parent_defaults(struct event *event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct event *parent)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->always_log_source = parent->always_log_source;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->passthrough = parent->passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->forced_debug = parent->forced_debug;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#undef event_create
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_create(struct event *parent, const char *source_filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int source_linenum)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen pool_t pool = pool_alloconly_create(MEMPOOL_GROWING"event", 64);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event = p_new(pool, struct event, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->event_passthrough = event_passthrough_vfuncs;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->refcount = 1;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->id = ++event_id_counter;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->pool = pool;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->tv_created = ioloop_timeval;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->source_filename = source_filename;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->source_linenum = source_linenum;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (parent != NULL) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->parent = parent;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_ref(event->parent);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_copy_parent_defaults(event, parent);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen DLLIST_PREPEND(&events, event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#undef event_create_passthrough
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_create_passthrough(struct event *parent, const char *source_filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int source_linenum)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!parent->passthrough) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event_last_passthrough != NULL) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* API is being used in a wrong or dangerous way */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_panic("Can't create multiple passthrough events - finish the earlier with ->event()");
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *event =
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_create(parent, source_filename, source_linenum);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->passthrough = TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* This event only intends to extend the parent event.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Use the parent's creation timestamp. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->tv_created = parent->tv_created;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_last_passthrough = &event->event_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } else {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_last_passthrough = &parent->event_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic bool
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_send_callbacks(struct event *event, enum event_callback_type type,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct failure_context *ctx, const char *fmt, va_list args)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_callback_t *const *callbackp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_handlers, callbackp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen bool ret;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen T_BEGIN {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen ret = (*callbackp)(event, type, ctx, fmt, args);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } T_END;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!ret) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* event sending was stopped */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return FALSE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_ref(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event->refcount > 0);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->refcount++;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainenstatic void event_send_free(struct event *event, ...)
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen{
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen va_list args;
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen /* the args are empty and not used for anything, but there doesn't seem
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen to be any nice and standard way of passing an initialized va_list
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen as a parameter without va_start(). */
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen va_start(args, event);
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen (void)event_send_callbacks(event, EVENT_CALLBACK_TYPE_FREE,
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen NULL, NULL, args);
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen va_end(args);
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen}
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_unref(struct event **_event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *event = *_event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event == NULL)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen *_event = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event->refcount > 0);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (--event->refcount > 0)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event != current_global_event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen if (event->call_free)
ec61c407caf0ade72e3c8ad881cc445653ccfa1fTimo Sirainen event_send_free(event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (last_passthrough_event() == event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_last_passthrough = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event->log_prefix_from_system_pool)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_free(event->log_prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_free(event->sending_name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_unref(&event->parent);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen DLLIST_REMOVE(&events, event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen pool_unref(&event->pool);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *events_get_head(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return events;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_push_global(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (current_global_event != NULL) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&global_event_stack))
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_array_init(&global_event_stack, 4);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_append(&global_event_stack, &current_global_event, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen current_global_event = event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_pop_global(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event != NULL);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event == current_global_event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&global_event_stack) ||
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_count(&global_event_stack) == 0)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen current_global_event = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen else {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int event_count;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *const *events =
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_get(&global_event_stack, &event_count);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_assert(event_count > 0);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen current_global_event = events[event_count-1];
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_delete(&global_event_stack, event_count-1, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return current_global_event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_get_global(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return current_global_event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_log_prefix(struct event *event, const char *prefix, bool append)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event->log_prefix == NULL) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* allocate the first log prefix from the pool */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->log_prefix = p_strdup(event->pool, prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } else {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* log prefix is being updated multiple times -
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen switch to system pool so we don't keep leaking memory */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event->log_prefix_from_system_pool)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_free(event->log_prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen else
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->log_prefix_from_system_pool = TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->log_prefix = i_strdup(prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->log_prefix_replace = !append;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_append_log_prefix(struct event *event, const char *prefix)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_set_log_prefix(event, prefix, TRUE);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_replace_log_prefix(struct event *event, const char *prefix)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_set_log_prefix(event, prefix, FALSE);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_name(struct event *event, const char *name)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_free(event->sending_name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->sending_name = i_strdup(name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_source(struct event *event, const char *filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int linenum, bool literal_fname)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->source_filename = literal_fname ? filename :
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen p_strdup(event->pool, filename);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->source_linenum = linenum;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_set_always_log_source(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->always_log_source = TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_category *event_category_find_registered(const char *name)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const *catp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_registered_categories, catp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (strcmp((*catp)->name, name) == 0)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return *catp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_category *const *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_registered_categories(unsigned int *count_r)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return array_get(&event_registered_categories, count_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic void event_category_register(struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_callback_t *const *callbackp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (category->registered)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* register parent categories first */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (category->parent != NULL)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_register(category->parent);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen category->registered = TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_append(&event_registered_categories, &category, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_category_callbacks, callbackp) T_BEGIN {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*callbackp)(category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } T_END;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic bool
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_category(struct event *event, const struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const *categoryp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event->categories, categoryp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (*categoryp == category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return TRUE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return FALSE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_categories(struct event *event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const *categories)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&event->categories))
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen p_array_init(&event->categories, event->pool, 4);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen for (unsigned int i = 0; categories[i] != NULL; i++) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_register(categories[i]);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!event_find_category(event, categories[i]))
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_append(&event->categories, &categories[i], 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_category(struct event *event, struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const categories[] = { category, NULL };
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_add_categories(event, categories);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_field_int(struct event *event, const char *key)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&event->fields))
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach_modifiable(&event->fields, field) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (strcmp(field->key, key) == 0)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_field(struct event *event, const char *key)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct event_field *field = event_find_field_int(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (field != NULL || event->parent == NULL)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_find_field(event->parent, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst char *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_field_str(struct event *event, const char *key)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = event_find_field(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (field == NULL)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen switch (field->value_type) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen case EVENT_FIELD_VALUE_TYPE_STR:
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return field->value.str;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen case EVENT_FIELD_VALUE_TYPE_INTMAX:
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return dec2str(field->value.intmax);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen case EVENT_FIELD_VALUE_TYPE_TIMEVAL:
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return t_strdup_printf("%"PRIdTIME_T".%u",
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value.timeval.tv_sec,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (unsigned int)field->value.timeval.tv_usec);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_unreached();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_field(struct event *event, const char *key)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = event_find_field_int(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (field == NULL) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&event->fields))
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen p_array_init(&event->fields, event->pool, 8);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = array_append_space(&event->fields);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->key = p_strdup(event->pool, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_str(struct event *event, const char *key, const char *value)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = event_get_field(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_STR;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_zero(&field->value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value.str = p_strdup(event->pool, value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_int(struct event *event, const char *key, intmax_t num)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = event_get_field(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_INTMAX;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_zero(&field->value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value.intmax = num;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_timeval(struct event *event, const char *key,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct timeval *tv)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_field *field;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field = event_get_field(event, key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_TIMEVAL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_zero(&field->value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen field->value.timeval = *tv;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_fields(struct event *event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct event_add_field *fields)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen for (unsigned int i = 0; fields[i].key != NULL; i++) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (fields[i].value != NULL)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_str(event, fields[i].key, fields[i].value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen else if (fields[i].value_timeval.tv_sec != 0)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_timeval(event, fields[i].key, &fields[i].value_timeval);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen else
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_int(event, fields[i].key, fields[i].value_intmax);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_get_parent(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event->parent;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_get_create_time(struct event *event, struct timeval *tv_r)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen *tv_r = event->tv_created;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenbool event_get_last_send_time(struct event *event, struct timeval *tv_r)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen *tv_r = event->tv_last_sent;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return tv_r->tv_sec != 0;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_fields(struct event *event, unsigned int *count_r)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&event->fields)) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen *count_r = 0;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return array_get(&event->fields, count_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_category *const *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_categories(struct event *event, unsigned int *count_r)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!array_is_created(&event->categories)) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen *count_r = 0;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return array_get(&event->categories, count_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainenvoid event_send(struct event *event, struct failure_context *ctx,
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen const char *fmt, ...)
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen{
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen va_list args;
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen va_start(args, fmt);
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen event_vsend(event, ctx, fmt, args);
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen va_end(args);
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen}
ddd5a0932db39f7336123f5089fdd77f6a38bce6Timo Sirainen
68f5234e8c0a79b72546e1b1013aae4b86f394a4Timo Sirainenvoid event_vsend(struct event *event, struct failure_context *ctx,
68f5234e8c0a79b72546e1b1013aae4b86f394a4Timo Sirainen const char *fmt, va_list args)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->tv_last_sent = ioloop_timeval;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event_send_callbacks(event, EVENT_CALLBACK_TYPE_EVENT,
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen ctx, fmt, args)) {
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen if (ctx->type != LOG_TYPE_DEBUG ||
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen event->sending_debug_log)
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen i_log_typev(ctx, fmt, args);
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_send_abort(event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_send_abort(struct event *event)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* if the event is sent again, it needs a new name */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_free(event->sending_name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (event->passthrough)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_unref(&event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenstatic void
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenevent_export_field_value(string_t *dest, const struct event_field *field)
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen{
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen switch (field->value_type) {
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_FIELD_VALUE_TYPE_STR:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, EVENT_CODE_FIELD_STR);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, field->key);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen str_append_tabescaped(dest, field->value.str);
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen break;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_FIELD_VALUE_TYPE_INTMAX:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen str_append_c(dest, EVENT_CODE_FIELD_INTMAX);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, field->key);
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen str_printfa(dest, "\t%jd", field->value.intmax);
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen break;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_FIELD_VALUE_TYPE_TIMEVAL:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen str_append_c(dest, EVENT_CODE_FIELD_TIMEVAL);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, field->key);
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen str_printfa(dest, "\t%"PRIdTIME_T"\t%u",
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen field->value.timeval.tv_sec,
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen (unsigned int)field->value.timeval.tv_usec);
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen}
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenvoid event_export(const struct event *event, string_t *dest)
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen{
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen /* required fields: */
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_printfa(dest, "%"PRIdTIME_T"\t%u",
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event->tv_created.tv_sec,
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen (unsigned int)event->tv_created.tv_usec);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen /* optional fields: */
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (event->source_filename != NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, EVENT_CODE_SOURCE);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, event->source_filename);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_printfa(dest, "\t%u", event->source_linenum);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (event->always_log_source) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, EVENT_CODE_ALWAYS_LOG_SOURCE);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (event->tv_last_sent.tv_sec != 0) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_printfa(dest, "\t%c%"PRIdTIME_T"\t%u",
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen EVENT_CODE_TV_LAST_SENT,
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event->tv_last_sent.tv_sec,
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen (unsigned int)event->tv_last_sent.tv_usec);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (event->sending_name != NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, EVENT_CODE_SENDING_NAME);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, event->sending_name);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (array_is_created(&event->categories)) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen struct event_category *const *catp;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen array_foreach(&event->categories, catp) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, EVENT_CODE_CATEGORY);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_tabescaped(dest, (*catp)->name);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (array_is_created(&event->fields)) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen const struct event_field *field;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen array_foreach(&event->fields, field) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen str_append_c(dest, '\t');
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event_export_field_value(dest, field);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen}
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenbool event_import(struct event *event, const char *str, const char **error_r)
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen{
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return event_import_unescaped(event, t_strsplit_tabescaped(str), error_r);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen}
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenstatic bool event_import_tv(const char *arg_secs, const char *arg_usecs,
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen struct timeval *tv_r, const char **error_r)
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen{
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen unsigned int usecs;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (str_to_time(arg_secs, &tv_r->tv_sec) < 0) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Invalid timeval seconds parameter";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (arg_usecs == NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Timeval missing microseconds parameter";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (str_to_uint(arg_usecs, &usecs) < 0 || usecs >= 1000000) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Invalid timeval microseconds parameter";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen tv_r->tv_usec = usecs;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return TRUE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen}
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainenbool event_import_unescaped(struct event *event, const char *const *args,
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen const char **error_r)
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen{
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen const char *error;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen /* required fields: */
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (args[0] == NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Missing required fields";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (!event_import_tv(args[0], args[1], &event->tv_created, &error)) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = t_strdup_printf("Invalid tv_created: %s", error);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args += 2;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen /* optional fields: */
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen while (*args != NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen const char *arg = *args;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen enum event_code code = arg[0];
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen arg++;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen switch (code) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_ALWAYS_LOG_SOURCE:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event->always_log_source = TRUE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_CATEGORY: {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen struct event_category *category =
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event_category_find_registered(arg);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (category == NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = t_strdup_printf("Unregistered category: '%s'", arg);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (!array_is_created(&event->categories))
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen p_array_init(&event->categories, event->pool, 4);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen array_append(&event->categories, &category, 1);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_TV_LAST_SENT:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (!event_import_tv(arg, args[1], &event->tv_last_sent, &error)) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = t_strdup_printf("Invalid tv_last_sent: %s", error);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args++;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_SENDING_NAME:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen i_free(event->sending_name);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event->sending_name = i_strdup(arg);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_SOURCE:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event->source_filename = p_strdup(event->pool, arg);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (args[1] == NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Source line number missing";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (str_to_uint(args[1], &event->source_linenum) < 0) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Invalid Source line number";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args++;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_CODE_FIELD_INTMAX:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_FIELD_STR:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_CODE_FIELD_TIMEVAL: {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen struct event_field *field =
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen event_get_field(event, arg);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen if (args[1] == NULL) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = "Field value is missing";
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args++;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen i_zero(&field->value);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen switch (code) {
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_CODE_FIELD_INTMAX:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_INTMAX;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen if (str_to_intmax(*args, &field->value.intmax) < 0) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = t_strdup_printf(
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen "Invalid field value '%s' number for '%s'",
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *args, field->key);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen case EVENT_CODE_FIELD_STR:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_STR;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen field->value.str = p_strdup(event->pool, *args);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen case EVENT_CODE_FIELD_TIMEVAL:
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen field->value_type = EVENT_FIELD_VALUE_TYPE_TIMEVAL;
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen if (!event_import_tv(args[0], args[1],
918384d458981e7db4aadc283212eb19912d5709Timo Sirainen &field->value.timeval, &error)) {
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen *error_r = t_strdup_printf(
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen "Field '%s' value '%s': %s",
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen field->key, args[1], error);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return FALSE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args++;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen default:
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen i_unreached();
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen break;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen args++;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen }
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return TRUE;
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen}
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_register_callback(event_callback_t *callback)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_append(&event_handlers, &callback, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_unregister_callback(event_callback_t *callback)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_callback_t *const *callbackp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_handlers, callbackp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (*callbackp == callback) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_delete(&event_handlers,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach_idx(&event_handlers, callbackp), 1);
53ea4ad7b37e6c78a834151cdc30374316da4e34Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_unreached();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_category_register_callback(event_category_callback_t *callback)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_append(&event_category_callbacks, &callback, 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_category_unregister_callback(event_category_callback_t *callback)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_callback_t *const *callbackp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_category_callbacks, callbackp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (*callbackp == callback) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_delete(&event_category_callbacks,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach_idx(&event_category_callbacks, callbackp), 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_unreached();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic void event_category_remove_from_array(struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const *catp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_registered_categories, catp) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (*catp == category) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_delete(&event_registered_categories,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach_idx(&event_registered_categories, catp), 1);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_unreached();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_category_unregister(struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_callback_t *const *callbackp;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen if (!category->registered) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* it was never registered in the first place - ignore */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen category->registered = FALSE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_category_remove_from_array(category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_foreach(&event_category_callbacks, callbackp) T_BEGIN {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*callbackp)(category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } T_END;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_set_append_log_prefix(const char *prefix)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_set_append_log_prefix(last_passthrough_event(), prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_replace_log_prefix(const char *prefix)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_replace_log_prefix(last_passthrough_event(), prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_set_name(const char *name)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_set_name(last_passthrough_event(), name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_set_source(const char *filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int linenum, bool literal_fname)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_set_source(last_passthrough_event(), filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen linenum, literal_fname);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_set_always_log_source(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_set_always_log_source(last_passthrough_event());
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_categories(struct event_category *const *categories)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_categories(last_passthrough_event(), categories);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_category(struct event_category *category)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_category(last_passthrough_event(), category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_fields(const struct event_add_field *fields)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_fields(last_passthrough_event(), fields);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_str(const char *key, const char *value)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_str(last_passthrough_event(), key, value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_int(const char *key, intmax_t num)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_int(last_passthrough_event(), key, num);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_passthrough_add_timeval(const char *key, const struct timeval *tv)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_timeval(last_passthrough_event(), key, tv);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event_last_passthrough;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic struct event *event_passthrough_event(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *event = last_passthrough_event();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_last_passthrough = NULL;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen return event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst struct event_passthrough event_passthrough_vfuncs = {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_set_append_log_prefix,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_replace_log_prefix,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_set_name,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_set_source,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_set_always_log_source,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_categories,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_category,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_fields,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_str,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_int,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_add_timeval,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_passthrough_event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid lib_event_init(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_array_init(&event_handlers, 4);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_array_init(&event_category_callbacks, 4);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_array_init(&event_registered_categories, 16);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid lib_event_deinit(void)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen{
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen event_unset_global_debug_log_filter();
c6ab22366939966e59492b29fd42a350d54331f0Timo Sirainen event_unset_global_debug_send_filter();
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen for (struct event *event = events; event != NULL; event = event->next) {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen i_warning("Event %p leaked (parent=%p): %s:%u",
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event, event->parent,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event->source_filename, event->source_linenum);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen }
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_free(&event_handlers);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_free(&event_category_callbacks);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen array_free(&event_registered_categories);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen}