#ifndef SUBMISSION_BACKEND_H #define SUBMISSION_BACKEND_H struct submission_recipient; struct submission_backend; union submission_backend_module_context; struct submission_backend_vfuncs { void (*destroy)(struct submission_backend *backend); void (*start)(struct submission_backend *backend); void (*ready)(struct submission_backend *backend, enum smtp_capability caps); void (*fail)(struct submission_backend *backend, const char *enh_code, const char *reason); void (*client_input_pre)(struct submission_backend *backend); void (*client_input_post)(struct submission_backend *backend); uoff_t (*get_max_mail_size)(struct submission_backend *backend); void (*trans_start)(struct submission_backend *backend, struct smtp_server_transaction *trans, const struct smtp_address *path, const struct smtp_params_mail *params); void (*trans_free)(struct submission_backend *backend, 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. Also note that only the default backend actually triggers all of these command callbacks. Secondary backends only get called for transaction commands and only when that backend is tied to the transaction somehow; e.g., as the primary transaction backend or when it is tied to one of the approved recipients. */ int (*cmd_helo)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); int (*cmd_mail)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_mail *data); int (*cmd_rcpt)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct submission_recipient *srcpt); int (*cmd_rset)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); int (*cmd_data)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_transaction *trans, struct istream *data_input, uoff_t data_size); int (*cmd_vrfy)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, const char *param); int (*cmd_noop)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); int (*cmd_quit)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); }; struct submission_backend { pool_t pool; struct client *client; struct submission_backend *prev, *next; struct submission_backend_vfuncs v; struct istream *data_input; uoff_t data_size; char *fail_enh_code; char *fail_reason; /* Module-specific contexts. */ ARRAY(union submission_backend_module_context *) module_contexts; bool started:1; bool ready:1; bool trans_started:1; }; struct submission_backend_module_register { unsigned int id; }; union submission_backend_module_context { struct submission_backend_module_register *reg; }; extern struct submission_backend_module_register submission_backend_module_register; void submission_backend_init(struct submission_backend *backend, pool_t pool, struct client *client, const struct submission_backend_vfuncs *vfunc); void submission_backends_destroy_all(struct client *client); void submission_backend_start(struct submission_backend *backend); void submission_backend_started(struct submission_backend *backend, enum smtp_capability caps); void submission_backend_fail(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, const char *enh_code, const char *reason) ATTR_NULL(2); void submission_backends_client_input_pre(struct client *client); void submission_backends_client_input_post(struct client *client); uoff_t submission_backend_get_max_mail_size(struct submission_backend *backend); void submission_backend_trans_start(struct submission_backend *backend, struct smtp_server_transaction *trans); void submission_backends_trans_start(struct client *client, struct smtp_server_transaction *trans); void submission_backends_trans_free(struct client *client, struct smtp_server_transaction *trans); void submission_backend_helo_reply_submit(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); int submission_backend_cmd_helo(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); int submission_backend_cmd_mail(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_mail *data); int submission_backend_cmd_rcpt(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct submission_recipient *srcpt); int submission_backend_cmd_rset(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); int submission_backends_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 submission_backend_cmd_vrfy(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, const char *param); int submission_backend_cmd_noop(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); int submission_backend_cmd_quit(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd); #endif