b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#ifndef LIB_EVENT_H
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#define LIB_EVENT_H
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* event.h name is probably a bit too generic, so lets avoid using it. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#include <sys/time.h>
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Hierarchical category of events. Each event can belong to multiple
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen categories. For example [ lib-storage/maildir, syscall/io ]. The categories
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen are expected to live as long as they're used in events. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_category {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *parent;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char *name;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* TRUE after an event with this category is sent the first time */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen bool registered;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenenum event_field_value_type {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen EVENT_FIELD_VALUE_TYPE_STR,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen EVENT_FIELD_VALUE_TYPE_INTMAX,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen EVENT_FIELD_VALUE_TYPE_TIMEVAL,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_field {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char *key;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen enum event_field_value_type value_type;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char *str;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen intmax_t intmax;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct timeval timeval;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen } value;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_add_field {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char *key;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* The first non-0/NULL value is used. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char *value;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen intmax_t value_intmax;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct timeval value_timeval;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_passthrough {
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* wrappers to event_set_*() and event_add_*() for passthrough events,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen so these can be chained like:
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_create_passthrough(parent)->name("name")->...->event() */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*append_log_prefix)(const char *prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*replace_log_prefix)(const char *prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*set_name)(const char *name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*set_source)(const char *filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int linenum, bool literal_fname);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*set_always_log_source)(void);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_categories)(struct event_category *const *categories);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_category)(struct event_category *category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_fields)(const struct event_add_field *fields);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_str)(const char *key, const char *value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_int)(const char *key, intmax_t num);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen (*add_timeval)(const char *key, const struct timeval *tv);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event *(*event)(void);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen};
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create a new empty event under the parent event, or NULL for root event. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_create(struct event *parent, const char *source_filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int source_linenum);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#define event_create(parent) \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_create((parent), __FILE__, __LINE__)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* This is a temporary "passthrough" event. Its main purpose is to make it
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen easier to create temporary events as part of the event parameter in
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen e_error(), e_warning(), e_info() or e_debug(). These passthrough events are
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen automatically freed when the e_*() call is finished. Because this makes the
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen freeing less obvious, it should be avoided outside e_*()'s event parameter.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen The passthrough events also change the API to be more convenient towards
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen being used in a parameter. Instead of having to use e.g.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_add_str(event_set_name(event_create(parent), "name"), "key", "value")
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen the event_passthrough API can be a bit more readable as:
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_create_passthrough(parent)->set_name("name")->
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen add_str("key", "value")->event(). The passthrough event is converted to
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen a normal event at the end with the event() call. Note that this API works
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen by modifying the last created passthrough event, so it's not possible to
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen have multiple passthrough events created in parallel. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_passthrough *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_create_passthrough(struct event *parent, const char *source_filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int source_linenum);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#define event_create_passthrough(parent) \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen event_create_passthrough((parent), __FILE__, __LINE__)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Reference the event. Returns the event parameter. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_ref(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Unreference the event. If the reference count drops to 0, the event is
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen freed. The current global event's refcount must not drop to 0. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_unref(struct event **event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set the event to be the global default event used by i_error(), etc.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Returns the event parameter. The event must be explicitly popped before
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen it's freed.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen The global event stack is also an alternative nonpermanent hierarchy for
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen events. For example the global event can be "IMAP command SELECT", which
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen can be used for filtering events that happen while the SELECT command is
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen being executed. However, for the created struct mailbox the parent event
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen should be the mail_user, not the SELECT command. Otherwise everything else
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen that happens afterwards to the selected mailbox would also count towards
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen SELECT. This means that events shouldn't be using the current global event
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen as their parent event. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_push_global(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Pop the global event. Assert-crash if the current global event isn't the
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen given event parameter. Returns the new global event. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_pop_global(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns the current global event. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_get_global(void);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set the appended log prefix string for this event. All the parent events'
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen log prefixes will be concatenated together when logging. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_append_log_prefix(struct event *event, const char *prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Replace the full log prefix string for this event. The parent events' log
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen prefixes won't be used. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_replace_log_prefix(struct event *event, const char *prefix);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set the event's name. The name is specific to a single sending of an event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen and it'll be automatically cleared once the event is sent. This should
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen typically be used only in a parameter to e_debug(), etc. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_name(struct event *event, const char *name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set the source filename:linenum to the event. If literal_fname==TRUE,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen it's assumed that __FILE__ has been used and the pointer is stored directly,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen otherwise the filename is strdup()ed. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_set_source(struct event *event, const char *filename,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int linenum, bool literal_fname);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Always include the source path:line in the log replies. This is
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen especially useful when logging about unexpected syscall failures, because
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen it allow quickly finding which of the otherwise identical syscalls in the
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen code generated the error. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_set_always_log_source(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Add NULL-terminated list of categories to the event. The categories pointer
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen doesn't need to stay valid afterwards, but the event_category structs
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen themselves must be. Returns the event parameter. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_categories(struct event *event,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen struct event_category *const *categories);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Add a single category to the event. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_category(struct event *event, struct event_category *category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Add key=value field to the event. If a key already exists, it's replaced.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Child events automatically inherit key=values from their parents at the
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen time the event is sent. So changing a key in parent will change the values
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen in the child events as well. Returns the event parameter. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_str(struct event *event, const char *key, const char *value);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_int(struct event *event, const char *key, intmax_t num);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_timeval(struct event *event, const char *key,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const struct timeval *tv);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Same as event_add_str/int(), but do it via event_field struct. The fields
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen terminates with key=NULL. Returns the event parameter. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_add_fields(struct event *event, const struct event_add_field *fields);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns the parent event, or NULL if it doesn't exist. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event *event_get_parent(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Get the event's creation time. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_get_create_time(struct event *event, struct timeval *tv_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Get the time when the event was last sent. Returns TRUE if time was
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen returned, FALSE if event has never been sent. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenbool event_get_last_send_time(struct event *event, struct timeval *tv_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns field for a given key, or NULL if it doesn't exist. If the key
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen isn't found from the event itself, find it from parent events. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_field(struct event *event, const char *key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns the given key's value as string, or NULL if it doesn't exist.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen If the field isn't stored as a string, the result is allocated from
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen data stack. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst char *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_find_field_str(struct event *event, const char *key);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns all key=value fields that the event has.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Parent events' fields aren't returned. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst struct event_field *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_fields(struct event *event, unsigned int *count_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Return all categories that the event has.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Parent events' categories aren't returned. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct event_category *const *
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenevent_get_categories(struct event *event, unsigned int *count_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Export the event into a tabescaped string, so its fields are separated
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen with TABs and there are no NUL, CR or LF characters. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_export(const struct event *event, string_t *dest);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Import event. The string is expected to be generated by event_export().
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen All the used categories must already be registered.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Returns TRUE on success, FALSE on invalid string. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenbool event_import(struct event *event, const char *str, const char **error_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Same as event_import(), but string is already split into an array
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen of strings via *_strsplit_tabescaped(). */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenbool event_import_unescaped(struct event *event, const char *const *args,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen const char **error_r);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* The event wasn't sent after all - free everything related to it.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Most importantly this frees any passthrough events. Typically this shouldn't
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen need to be called. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_send_abort(struct event *event);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Explicitly register an event category. It must not be in use by any events
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen at this point. This is normally necessary only when unloading an plugin
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen that has registered an event category. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid event_category_unregister(struct event_category *category);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid lib_event_init(void);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid lib_event_deinit(void);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#endif