#ifndef CLIENT_H #define CLIENT_H #include "net.h" struct smtp_reply; struct submission_recipient; struct submission_backend; struct submission_backend_relay; struct client; struct client_state { pool_t pool; enum smtp_server_state state; char *args; struct submission_backend *backend; struct istream *data_input; uoff_t data_size; bool anonymous_allowed:1; }; struct client_extra_capability { const char *capability; const char *params; }; struct submission_client_vfuncs { void (*destroy)(struct client *client); void (*trans_start)(struct client *client, struct smtp_server_transaction *trans); void (*trans_free)(struct client *client, struct smtp_server_transaction *trans); /* Command handlers: These implement the behavior of the various core SMTP commands. SMTP commands are handled asynchronously, which means that the command is not necessarily finished when these handlers end. A command is finished either when 1 is returned or a reply is submitted for it. When a handler returns 0, the command implementation is waiting for an external event and when it returns -1 an error occurred. When 1 is returned, a default success reply is submitted implicitly. Not submitting an error reply when -1 is returned causes an assert fail. See src/lib-smtp/smtp-server.h for details. When overriding these handler vfuncs, the base implementation should usually be called at some point. When it is called immediately, its result can be returned as normal. When the override returns 0, the base implementation would be called at a later time when some external state is achieved. Note that the overriding function then assumes the responsibility to submit the default reply when none is submitted and the base implementation returns 1. */ int (*cmd_helo)(struct client *client, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); int (*cmd_mail)(struct client *client, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_mail *data); int (*cmd_rcpt)(struct client *client, struct smtp_server_cmd_ctx *cmd, struct submission_recipient *srcpt); int (*cmd_rset)(struct client *client, struct smtp_server_cmd_ctx *cmd); int (*cmd_data)(struct client *client, struct smtp_server_cmd_ctx *cmd, struct smtp_server_transaction *trans, struct istream *data_input, uoff_t data_size); int (*cmd_vrfy)(struct client *client, struct smtp_server_cmd_ctx *cmd, const char *param); int (*cmd_noop)(struct client *client, struct smtp_server_cmd_ctx *cmd); int (*cmd_quit)(struct client *client, struct smtp_server_cmd_ctx *cmd); }; struct client { struct client *prev, *next; pool_t pool; struct submission_client_vfuncs v; const struct setting_parser_info *user_set_info; const struct submission_settings *set; struct smtp_server_connection *conn; struct client_state state; ARRAY(struct submission_backend *) pending_backends; ARRAY(struct submission_recipient *) rcpt_to; ARRAY(struct submission_backend *) rcpt_backends; struct mail_storage_service_user *service_user; struct mail_user *user; /* IMAP URLAUTH context (RFC4467) for BURL (RFC4468) */ struct imap_urlauth_context *urlauth_ctx; struct timeout *to_quit; enum smtp_capability backend_capabilities; struct submission_backend *backend_default; struct submission_backend_relay *backend_default_relay; struct submission_backend *backends; unsigned int backends_count; /* Extra (non-standard) capabilities */ ARRAY(struct client_extra_capability) extra_capabilities; /* Module-specific contexts. */ ARRAY(union submission_module_context *) module_contexts; bool standalone:1; bool disconnected:1; bool destroyed:1; bool anvil_sent:1; bool backend_capabilities_configured:1; bool anonymous_allowed:1; }; struct submission_module_register { unsigned int id; }; union submission_module_context { struct submission_client_vfuncs super; struct submission_module_register *reg; }; extern struct submission_module_register submission_module_register; extern struct client *submission_clients; extern unsigned int submission_client_count; struct client * client_create(int fd_in, int fd_out, struct mail_user *user, struct mail_storage_service_user *service_user, const struct submission_settings *set, const char *helo, const struct smtp_proxy_data *proxy_data, const unsigned char *pdata, unsigned int pdata_len, bool no_greeting); void client_destroy(struct client **client, const char *prefix, const char *reason) ATTR_NULL(2, 3); typedef void (*client_input_callback_t)(struct client *context); void client_apply_backend_capabilities(struct client *client); void client_default_backend_started(struct client *client, enum smtp_capability caps); uoff_t client_get_max_mail_size(struct client *client); void client_add_extra_capability(struct client *client, const char *capability, const char *params) ATTR_NULL(2); int client_input_read(struct client *client); int client_handle_input(struct client *client); void clients_destroy_all(void); #endif